On 2018/01/02 20:20, Liran Alon wrote:
In case APICv is active (relevant to our case), __apic_accept_irq()
handles APIC_DM_FIXED by calling deliver_posted_interrupt() which will
set a bit in PIR instead of setting a bit in LAPIC IRR.
Therefore, in case APICv is active, the bits that are set in LAPIC IRR
are bits which were synced from PIR to IRR by some previous call of
vmx_sync_pir_to_irr(). (Not considering the case of some user-mode API
setting them manually).
Therefore, the only new injectable interrupts we can encounter in
vmx_sync_pir_to_irr() are vectors coming from the PIR.
It is also not possible for the guest to block interrupt vector X
while still being able to accept vector Y if Y<X. Therefore, it is
enough to just check if max vector from PIR > max vector from IRR
before the sync.
It is true that VID will inject the vector in RVI to the guest if
possible on VMEntry. RVI is set by vmx_sync_pir_to_irr() to either the
max value from PIR or the max value from IRR. If the max value from
IRR > max value from PIR,
I agree with you on all of above points, ...
then the vector to be injected to guest was already evaluated if it
should exit to L1 by check_nested_events() and therefore we don't need
to call kvm_vcpu_exiting_guest_mode() again.
...
:( my bad.. I missed the VPPR..
.e.g. in this case:
'vector of PIR' < 'vector of previos IRR'
then the 'vector of PIR' also have a chance to be synced to RVI, but
hardware does not recognize
'vector of PIR' until next VMEntry as RVI[7:4] <= VPPR[7:4] (VPPR is
from the last EOI
virtualization of 'vector of previos IRR')
even L2 -> L0 -> L2, L0 code helps to check it as your description..
so you are right.
Quan
Alibaba Cloud