linux/arch/x86/kvm
Wanpeng Li c5a6d5f7fa KVM: nVMX: Fix the NMI IDT-vectoring handling
Run kvm-unit-tests/eventinj.flat in L1:

Sending NMI to self
After NMI to self
FAIL: NMI

This test scenario is to test whether VMM can handle NMI IDT-vectoring info correctly.

At the beginning, L2 writes LAPIC to send a self NMI, the EPT page tables on both L1
and L0 are empty so:

- The L2 accesses memory can generate EPT violation which can be intercepted by L0.

  The EPT violation vmexit occurred during delivery of this NMI, and the NMI info is
  recorded in vmcs02's IDT-vectoring info.

- L0 walks L1's EPT12 and L0 sees the mapping is invalid, it injects the EPT violation into L1.

  The vmcs02's IDT-vectoring info is reflected to vmcs12's IDT-vectoring info since
  it is a nested vmexit.

- L1 receives the EPT violation, then fixes its EPT12.
- L1 executes VMRESUME to resume L2 which generates vmexit and causes L1 exits to L0.
- L0 emulates VMRESUME which is called from L1, then return to L2.

  L0 merges the requirement of vmcs12's IDT-vectoring info and injects it to L2 through
  vmcs02.

- The L2 re-executes the fault instruction and cause EPT violation again.
- Since the L1's EPT12 is valid, L0 can fix its EPT02
- L0 resume L2

  The EPT violation vmexit occurred during delivery of this NMI again, and the NMI info
  is recorded in vmcs02's IDT-vectoring info. L0 should inject the NMI through vmentry
  event injection since it is caused by EPT02's EPT violation.

However, vmx_inject_nmi() refuses to inject NMI from IDT-vectoring info if vCPU is in
guest mode, this patch fix it by permitting to inject NMI from IDT-vectoring if it is
the L0's responsibility to inject NMI from IDT-vectoring info to L2.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Radim Krčmář <rkrcmar@redhat.com>
Cc: Jan Kiszka <jan.kiszka@siemens.com>
Cc: Bandan Das <bsd@redhat.com>
Signed-off-by: Wanpeng Li <wanpeng.li@hotmail.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
2016-09-23 01:08:15 +02:00
..
assigned-dev.c KVM: x86: use list_for_each_entry* 2016-02-23 15:40:54 +01:00
assigned-dev.h KVM: x86: move device assignment out of kvm_host.h 2014-11-24 16:53:50 +01:00
cpuid.c KVM: x86: Expose more Intel AVX512 feature to guest 2016-08-19 17:51:40 +02:00
cpuid.h Revert "KVM: x86: add pcommit support" 2016-07-23 11:04:23 -07:00
debugfs.c kvm: x86: export TSC information to user-space 2016-09-16 16:57:48 +02:00
emulate.c x86/kvm: Audit and remove any unnecessary uses of module.h 2016-07-14 15:07:00 +02:00
hyperv.c KVM: x86: Hyper-V tsc page setup 2016-09-20 09:26:20 +02:00
hyperv.h KVM: x86: Hyper-V tsc page setup 2016-09-20 09:26:20 +02:00
i8254.c KVM: x86: protect KVM_CREATE_PIT/KVM_CREATE_PIT2 with kvm->lock 2016-06-03 15:28:19 +02:00
i8254.h KVM: i8254: turn kvm_kpit_state.reinject into atomic_t 2016-03-04 09:30:25 +01:00
i8259.c KVM: x86: clean/fix memory barriers in irqchip_in_kernel 2015-07-30 16:02:56 +02:00
ioapic.c KVM: x86: Rename kvm_apic_get_reg to kvm_lapic_get_reg 2016-05-18 18:04:25 +02:00
ioapic.h kvm: x86: Track irq vectors in ioapic->rtc_status.dest_map 2016-03-03 14:36:18 +01:00
iommu.c - ARM: GICv3 ITS emulation and various fixes. Removal of the old 2016-08-02 16:11:27 -04:00
irq_comm.c KVM: x86: add KVM_CAP_X2APIC_API 2016-07-14 09:03:57 +02:00
irq.c x86/kvm: Audit and remove any unnecessary uses of module.h 2016-07-14 15:07:00 +02:00
irq.h KVM: Move kvm_setup_default/empty_irq_routing declaration in arch specific header 2016-07-22 18:52:00 +01:00
Kconfig KVM: remove kvm_vcpu_compatible 2016-06-16 00:05:00 +02:00
kvm_cache_regs.h KVM, pkeys: add pkeys support for permission_fault 2016-03-22 16:23:37 +01:00
lapic.c KVM: lapic: don't recalculate apic map table twice when enabling LAPIC 2016-08-19 17:51:40 +02:00
lapic.h KVM: x86: use hardware-compatible format for APIC ID register 2016-07-14 09:03:54 +02:00
Makefile kvm: add stubs for arch specific debugfs support 2016-09-16 16:57:47 +02:00
mmu_audit.c kvm: rename pfn_t to kvm_pfn_t 2016-01-15 17:56:32 -08:00
mmu.c mmu: don't pass *kvm to spte_write_protect and spte_*_dirty 2016-08-19 17:51:40 +02:00
mmu.h kvm: mmu: remove is_present_gpte() 2016-07-14 09:02:47 +02:00
mmutrace.h tracing: Rename ftrace_event.h to trace_events.h 2015-05-13 14:05:12 -04:00
mtrr.c KVM: MTRR: fix kvm_mtrr_check_gfn_range_consistency page fault 2016-07-05 16:14:43 +02:00
page_track.c KVM: page_track: fix access to NULL slot 2016-03-22 17:27:28 +01:00
paging_tmpl.h kvm: mmu: track read permission explicitly for shadow EPT page tables 2016-07-14 09:03:50 +02:00
pmu_amd.c KVM: x86/vPMU: Fix unnecessary signed extension for AMD PERFCTRn 2015-08-11 15:19:41 +02:00
pmu_intel.c KVM: x86: Fix typos 2016-06-14 11:16:28 +02:00
pmu.c KVM: x86: consolidate different ways to test for in-kernel LAPIC 2016-02-09 16:57:45 +01:00
pmu.h KVM: x86/vPMU: Define kvm_pmu_ops to support vPMU function dispatch 2015-06-23 14:12:14 +02:00
svm.c kvm: svm: fix unsigned compare less than zero comparison 2016-09-20 09:26:30 +02:00
trace.h KVM: x86: support using the vmx preemption timer for tsc deadline timer 2016-06-16 10:07:48 +02:00
tss.h
vmx.c KVM: nVMX: Fix the NMI IDT-vectoring handling 2016-09-23 01:08:15 +02:00
x86.c KVM: x86: Hyper-V tsc page setup 2016-09-20 09:26:20 +02:00
x86.h KVM: x86: introduce get_kvmclock_ns 2016-09-20 09:26:15 +02:00