linux/arch/x86/kvm
Nadav Har'El 51cfe38ea5 KVM: nVMX: Fix warning-causing idt-vectoring-info behavior
When L0 wishes to inject an interrupt while L2 is running, it emulates an exit
to L1 with EXIT_REASON_EXTERNAL_INTERRUPT. This was explained in the original
nVMX patch 23, titled "Correct handling of interrupt injection".

Unfortunately, it is possible (though rare) that at this point there is valid
idt_vectoring_info in vmcs02. For example, L1 injected some interrupt to L2,
and when L2 tried to run this interrupt's handler, it got a page fault - so
it returns the original interrupt vector in idt_vectoring_info. The problem
is that if this is the case, we cannot exit to L1 with EXTERNAL_INTERRUPT
like we wished to, because the VMX spec guarantees that idt_vectoring_info
and exit_reason_external_interrupt can never happen together. This is not
just specified in the spec - a KVM L1 actually prints a kernel warning
"unexpected, valid vectoring info" if we violate this guarantee, and some
users noticed these warnings in L1's logs.

In order to better emulate a processor, which would never return the external
interrupt and the idt-vectoring-info together, we need to separate the two
injection steps: First, complete L1's injection into L2 (i.e., enter L2,
injecting to it the idt-vectoring-info); Second, after entry into L2 succeeds
and it exits back to L0, exit to L1 with the EXIT_REASON_EXTERNAL_INTERRUPT.
Most of this is already in the code - the only change we need is to remain
in L2 (and not exit to L1) in this case.

Note that the previous patch ensures (by using KVM_REQ_IMMEDIATE_EXIT) that
although we do enter L2 first, it will exit immediately after processing its
injection, allowing us to promptly inject to L1.

Note how we test vmcs12->idt_vectoring_info_field; This isn't really the
vmcs12 value (we haven't exited to L1 yet, so vmcs12 hasn't been updated),
but rather the place we save, at the end of vmx_vcpu_run, the vmcs02 value
of this field. This was explained in patch 25 ("Correct handling of idt
vectoring info") of the original nVMX patch series.

Thanks to Dave Allan and to Federico Simoncelli for reporting this bug,
to Abel Gordon for helping me figure out the solution, and to Avi Kivity
for helping to improve it.

Signed-off-by: Nadav Har'El <nyh@il.ibm.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
2011-12-27 11:16:45 +02:00
..
emulate.c KVM: x86 emulator: convert push %sreg/pop %sreg to direct decode 2011-09-25 19:52:58 +03:00
i8254.c KVM: x86: Prevent starting PIT timers in the absence of irqchip support 2011-12-25 17:13:18 +02:00
i8254.h KVM: remove useless function declaration kvm_inject_pit_timer_irqs() 2011-05-11 07:57:09 -04:00
i8259.c KVM: Clean up and extend rate-limited output 2011-09-25 19:52:43 +03:00
irq.c KVM: fix typo in copyright notice 2010-10-24 10:53:14 +02:00
irq.h KVM: Intelligent device lookup on I/O bus 2011-09-25 19:17:59 +03:00
Kconfig KVM: uses TASKSTATS, depends on NET 2011-08-16 19:00:41 +03:00
kvm_cache_regs.h KVM: MMU: Do not unconditionally read PDPTE from guest memory 2011-09-25 19:18:01 +03:00
kvm_timer.h KVM: emulate lapic tsc deadline timer for guest 2011-10-05 15:34:56 +02:00
lapic.c KVM: emulate lapic tsc deadline timer for guest 2011-10-05 15:34:56 +02:00
lapic.h KVM: emulate lapic tsc deadline timer for guest 2011-10-05 15:34:56 +02:00
Makefile KVM: x86: Makefile clean up 2011-01-12 11:29:08 +02:00
mmu_audit.c KVM: Clean up and extend rate-limited output 2011-09-25 19:52:43 +03:00
mmu.c KVM: MMU: Do not unconditionally read PDPTE from guest memory 2011-09-25 19:18:01 +03:00
mmu.h KVM: MMU: mmio page fault support 2011-07-24 11:50:40 +03:00
mmutrace.h KVM: MMU: trace mmio page fault 2011-07-24 11:50:41 +03:00
paging_tmpl.h KVM: MMU: Fix SMEP failure during fetch 2011-09-25 19:18:02 +03:00
svm.c KVM: SVM: Keep intercepting task switching with NPT enabled 2011-10-30 12:24:10 +02:00
timer.c atomic: use <linux/atomic.h> 2011-07-26 16:49:47 -07:00
trace.h KVM: Use __print_symbolic() for vmexit tracepoints 2011-09-25 19:17:59 +03:00
tss.h KVM: x86: hardware task switching support 2008-04-27 12:00:39 +03:00
vmx.c KVM: nVMX: Fix warning-causing idt-vectoring-info behavior 2011-12-27 11:16:45 +02:00
x86.c KVM: nVMX: Add KVM_REQ_IMMEDIATE_EXIT 2011-12-27 11:16:43 +02:00
x86.h KVM: MMU: cache mmio info on page fault path 2011-07-24 11:50:26 +03:00