[PATCH 2/4] KVM: nVMX: Do not flush TLB on L2->L1 VMExit if L1 uses VPID and EPT

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If L1 uses VPID, it expects TLB to not be flushed on L2->L1 VMExit.
However, code currently flushes TLB nonetheless if we didn't allocate
a vpid02 for L2. As in this case,
vmcs02->vpid == vmcs01->vpid == vmx->vpid.

But, if L1 uses EPT, TLB entires populated by L2 are tagged with EPTP02
while TLB entries populated by L1 are tagged with EPTP01.
Therefore, we can also avoid TLB flush if L1 uses VPID and EPT.

Reviewed-by: Mihai Carabas <mihai.carabas@xxxxxxxxxx>
Reviewed-by: Darren Kenny <darren.kenny@xxxxxxxxxx>
Reviewed-by: Nikita Leshchenko <nikita.leshchenko@xxxxxxxxxx>
Signed-off-by: Liran Alon <liran.alon@xxxxxxxxxx>
---
 arch/x86/kvm/vmx.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 7dcf5e96039d..b97e0c5ccb46 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -13132,20 +13132,26 @@ static void load_vmcs12_host_state(struct kvm_vcpu *vcpu,
 	 * If vmcs01 don't use VPID, CPU flushes TLB on every
 	 * VMEntry/VMExit. Thus, no need to flush TLB.
 	 *
-	 * If vmcs12 uses VPID, TLB entries populated by L2 are
-	 * tagged with vmx->nested.vpid02 while L1 entries are tagged
-	 * with vmx->vpid. Thus, no need to flush TLB.
+	 * If vmcs12 uses VPID then:
+	 * (*) If vmcs12 uses EPT, TLB entries populated by L2 are tagged
+	 * with EPTP02 which is different than EPTP01 which is used to tag
+	 * TLB entries populated by L1. Therefore, no need to flush TLB.
+	 * (*) Otherwise, TLB entries populated by L2 are tagged with
+	 * vmcs02->vpid02 which is either vmx->nested.vpid02 or vmx->vpid.
+	 * Because vmx->nested.vpid02 is different than vmx->vpid used to
+	 * tag L1 TLB entries, no need to flush TLB in case we have
+	 * vmx->nested.vpid02. Otherwise, both L1 and L2 TLB entries are
+	 * tagged with vmx->vpid and therefore we must flush TLB.
 	 *
-	 * Therefore, flush TLB only in case vmcs01 uses VPID and
-	 * vmcs12 don't use VPID as in this case L1 & L2 TLB entries
-	 * are both tagged with vmx->vpid.
+	 * If vmcs12 don't use VPID, we must flush TLB.
 	 *
 	 * If vmcs12 uses EPT, we need to execute this flush on EPTP01
 	 * and therefore we request the TLB flush to happen only after VMCS EPTP
 	 * has been set by KVM_REQ_LOAD_CR3.
 	 */
 	if (enable_vpid &&
-		!(nested_cpu_has_vpid(vmcs12) && to_vmx(vcpu)->nested.vpid02)) {
+		(!nested_cpu_has_vpid(vmcs12) ||
+		(!nested_cpu_has_ept(vmcs12) && !to_vmx(vcpu)->nested.vpid02))) {
 		kvm_make_request(KVM_REQ_TLB_FLUSH, vcpu);
 	}
 
-- 
2.16.1




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux