From: Junaid Shahid <junaids@xxxxxxxxxx> Free all L2 (guest_mmu) roots when emulating INVVPID for L1 and EPT is disabled, as outstanding changes to the page tables managed by L1 need to be recognized. Similar to handle_invpcid() and handle_invept(), rely on kvm_mmu_free_roots() to do a remote TLB flush if necessary, e.g. if L1 has never entered L2 then there is nothing to be done. Fixes: 5c614b3583e7b ("KVM: nVMX: nested VPID emulation") Signed-off-by: Junaid Shahid <junaids@xxxxxxxxxx> [sean: ported to upstream KVM, reworded the comment and changelog] Signed-off-by: Sean Christopherson <sean.j.christopherson@xxxxxxxxx> --- arch/x86/kvm/vmx/nested.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 9624cea4ed9f..50bb7d8862aa 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -5250,6 +5250,17 @@ static int handle_invvpid(struct kvm_vcpu *vcpu) return kvm_skip_emulated_instruction(vcpu); } + /* + * Sync L2's shadow page tables if EPT is disabled, L1 is effectively + * invalidating linear mappings for L2 (tagged with L2's VPID). Sync + * all roots as VPIDs are not tracked in the MMU role. + * + * TODO: sync only the affected SPTEs for INVDIVIDUAL_ADDR. + */ + if (!enable_ept) + kvm_mmu_free_roots(vcpu, &vcpu->arch.guest_mmu, + KVM_MMU_ROOTS_ALL); + return nested_vmx_succeed(vcpu); } -- 2.24.1