linux_dsm_epyc7002/arch/x86/kvm
Peter Shier 43fea4e425 KVM: nVMX: Update VMCS02 when L2 PAE PDPTE updates detected
When L2 uses PAE, L0 intercepts of L2 writes to CR0/CR3/CR4 call
load_pdptrs to read the possibly updated PDPTEs from the guest
physical address referenced by CR3.  It loads them into
vcpu->arch.walk_mmu->pdptrs and sets VCPU_EXREG_PDPTR in
vcpu->arch.regs_dirty.

At the subsequent assumed reentry into L2, the mmu will call
vmx_load_mmu_pgd which calls ept_load_pdptrs. ept_load_pdptrs sees
VCPU_EXREG_PDPTR set in vcpu->arch.regs_dirty and loads
VMCS02.GUEST_PDPTRn from vcpu->arch.walk_mmu->pdptrs[]. This all works
if the L2 CRn write intercept always resumes L2.

The resume path calls vmx_check_nested_events which checks for
exceptions, MTF, and expired VMX preemption timers. If
vmx_check_nested_events finds any of these conditions pending it will
reflect the corresponding exit into L1. Live migration at this point
would also cause a missed immediate reentry into L2.

After L1 exits, vmx_vcpu_run calls vmx_register_cache_reset which
clears VCPU_EXREG_PDPTR in vcpu->arch.regs_dirty.  When L2 next
resumes, ept_load_pdptrs finds VCPU_EXREG_PDPTR clear in
vcpu->arch.regs_dirty and does not load VMCS02.GUEST_PDPTRn from
vcpu->arch.walk_mmu->pdptrs[]. prepare_vmcs02 will then load
VMCS02.GUEST_PDPTRn from vmcs12->pdptr0/1/2/3 which contain the stale
values stored at last L2 exit. A repro of this bug showed L2 entering
triple fault immediately due to the bad VMCS02.GUEST_PDPTRn values.

When L2 is in PAE paging mode add a call to ept_load_pdptrs before
leaving L2. This will update VMCS02.GUEST_PDPTRn if they are dirty in
vcpu->arch.walk_mmu->pdptrs[].

Tested:
kvm-unit-tests with new directed test: vmx_mtf_pdpte_test.
Verified that test fails without the fix.

Also ran Google internal VMM with an Ubuntu 16.04 4.4.0-83 guest running a
custom hypervisor with a 32-bit Windows XP L2 guest using PAE. Prior to fix
would repro readily. Ran 14 simultaneous L2s for 140 iterations with no
failures.

Signed-off-by: Peter Shier <pshier@google.com>
Reviewed-by: Jim Mattson <jmattson@google.com>
Message-Id: <20200820230545.2411347-1-pshier@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2020-09-11 13:15:09 -04:00
..
mmu KVM: Pass MMU notifier range flags to kvm_unmap_hva_range() 2020-08-21 18:03:47 -04:00
svm s390: implement diag318 2020-08-06 12:59:31 -07:00
vmx KVM: nVMX: Update VMCS02 when L2 PAE PDPTE updates detected 2020-09-11 13:15:09 -04:00
cpuid.c x86: Expose SERIALIZE for supported cpuid 2020-08-09 13:08:54 -04:00
cpuid.h KVM: x86: Extract kvm_update_cpuid_runtime() from kvm_update_cpuid() 2020-07-09 06:53:49 -04:00
debugfs.c KVM: let kvm_destroy_vm_debugfs clean up vCPU debugfs directories 2020-06-04 11:00:54 -04:00
emulate.c KVM: x86: emulate reserved nops from 0f/18 to 0f/1f 2020-06-05 11:16:15 -04:00
hyperv.c x86/kvm/hyper-v: Synic default SCONTROL MSR needs to be enabled 2020-08-10 13:22:10 -04:00
hyperv.h x86/kvm/hyper-v: Add support for synthetic debugger interface 2020-06-01 04:26:11 -04:00
i8254.c kvm: i8254: remove redundant assignment to pointer s 2020-06-11 12:35:18 -04:00
i8254.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
i8259.c KVM: x86: Refactor picdev_write() to prevent Spectre-v1/L1TF attacks 2020-01-27 19:59:37 +01:00
ioapic.c kvm: ioapic: Restrict lazy EOI update to edge-triggered interrupts 2020-05-04 12:29:05 -04:00
ioapic.h kvm/x86: Remove redundant function implementations 2020-05-27 13:11:10 -04:00
irq_comm.c KVM: x86: don't notify userspace IOAPIC on edge-triggered interrupt EOI 2020-02-21 18:04:57 +01:00
irq.c KVM: nSVM: extract svm_set_gif 2020-06-01 04:26:01 -04:00
irq.h kvm/x86: Remove redundant function implementations 2020-05-27 13:11:10 -04:00
Kconfig x86/kvm: Use generic xfer to guest work function 2020-07-24 15:05:01 +02:00
kvm_cache_regs.h KVM: x86: Mark CR4.TSD as being possibly owned by the guest 2020-07-03 12:16:28 -04:00
kvm_emulate.h ARM: 2020-04-02 15:13:15 -07:00
lapic.c s390: implement diag318 2020-08-06 12:59:31 -07:00
lapic.h KVM: x86: introduce kvm_can_use_hv_timer 2020-05-15 12:26:21 -04:00
Makefile kvm: Disable objtool frame pointer checking for vmenter.S 2020-04-20 17:11:19 -04:00
mmu.h KVM: x86: Pull the PGD's level from the MMU instead of recalculating it 2020-07-30 18:16:47 -04:00
mtrr.c KVM: x86: Protect MSR-based index computations in fixed_msr_to_seg_unit() from Spectre-v1/L1TF attacks 2020-01-27 19:59:39 +01:00
pmu.c KVM/x86: pmu: Fix #GP condition check for RDPMC emulation 2020-07-09 07:08:37 -04:00
pmu.h kvm: x86: limit the maximum number of vPMU fixed counters to 3 2020-07-08 16:21:59 -04:00
trace.h x86/kvm/hyper-v: Add support for synthetic debugger interface 2020-06-01 04:26:11 -04:00
tss.h License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
x86.c KVM/arm64 fixes for Linux 5.9, take #1 2020-09-11 13:12:11 -04:00
x86.h KVM: x86: Add helper functions for illegal GPA checking and page fault injection 2020-07-10 13:07:28 -04:00