KVM: nVMX: Flush linear and combined mappings on VPID02 related flushes
All VPID12s used on a given L1 vCPU is translated to a single VPID02 (vmx->nested.vpid02 or vmx->vpid). Therefore, on L1->L2 VMEntry, we need to invalidate linear and combined mappings tagged by VPID02 in case L1 uses VPID and vmcs12->vpid was changed since last L1->L2 VMEntry. However, current code invalidates the wrong mappings as it calls __vmx_flush_tlb() with invalidate_gpa parameter set to true which will result in invalidating combined and guest-physical mappings tagged with active EPTP which is EPTP01. Similarly, INVVPID emulation have the exact same issue. Fix both issues by just setting invalidate_gpa parameter to false which will result in invalidating linear and combined mappings tagged with given VPID02 as required. Reviewed-by: Nikita Leshenko <nikita.leshchenko@oracle.com> Reviewed-by: Mark Kanda <mark.kanda@oracle.com> Signed-off-by: Liran Alon <liran.alon@oracle.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
committed by
Paolo Bonzini
parent
3d5bdae8b1
commit
327c072187
@ -9074,7 +9074,7 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)
|
|||||||
__invvpid(VMX_VPID_EXTENT_INDIVIDUAL_ADDR,
|
__invvpid(VMX_VPID_EXTENT_INDIVIDUAL_ADDR,
|
||||||
vpid02, operand.gla);
|
vpid02, operand.gla);
|
||||||
} else
|
} else
|
||||||
__vmx_flush_tlb(vcpu, vpid02, true);
|
__vmx_flush_tlb(vcpu, vpid02, false);
|
||||||
break;
|
break;
|
||||||
case VMX_VPID_EXTENT_SINGLE_CONTEXT:
|
case VMX_VPID_EXTENT_SINGLE_CONTEXT:
|
||||||
case VMX_VPID_EXTENT_SINGLE_NON_GLOBAL:
|
case VMX_VPID_EXTENT_SINGLE_NON_GLOBAL:
|
||||||
@ -9083,10 +9083,10 @@ static int handle_invvpid(struct kvm_vcpu *vcpu)
|
|||||||
VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
|
VMXERR_INVALID_OPERAND_TO_INVEPT_INVVPID);
|
||||||
return kvm_skip_emulated_instruction(vcpu);
|
return kvm_skip_emulated_instruction(vcpu);
|
||||||
}
|
}
|
||||||
__vmx_flush_tlb(vcpu, vpid02, true);
|
__vmx_flush_tlb(vcpu, vpid02, false);
|
||||||
break;
|
break;
|
||||||
case VMX_VPID_EXTENT_ALL_CONTEXT:
|
case VMX_VPID_EXTENT_ALL_CONTEXT:
|
||||||
__vmx_flush_tlb(vcpu, vpid02, true);
|
__vmx_flush_tlb(vcpu, vpid02, false);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
WARN_ON_ONCE(1);
|
WARN_ON_ONCE(1);
|
||||||
@ -12295,7 +12295,7 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12,
|
|||||||
if (nested_cpu_has_vpid(vmcs12) && vmx->nested.vpid02) {
|
if (nested_cpu_has_vpid(vmcs12) && vmx->nested.vpid02) {
|
||||||
if (vmcs12->virtual_processor_id != vmx->nested.last_vpid) {
|
if (vmcs12->virtual_processor_id != vmx->nested.last_vpid) {
|
||||||
vmx->nested.last_vpid = vmcs12->virtual_processor_id;
|
vmx->nested.last_vpid = vmcs12->virtual_processor_id;
|
||||||
__vmx_flush_tlb(vcpu, vmx->nested.vpid02, true);
|
__vmx_flush_tlb(vcpu, vmx->nested.vpid02, false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user