If L1 uses EPT and VPID, vmcs02->vpid is set to vmcs12->vpid because L2 TLB entries are separated from L1 TLB entries by having different EPTP tags and therefore we don't need a special vpid02 to separate them. Thus, we can avoid flush TLB on L1->L2 VMEntry 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 | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 98faba65c24a..bf25317495da 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -12241,18 +12241,16 @@ static int prepare_vmcs02(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12, decache_tsc_multiplier(vmx); if (enable_vpid) { - /* - * There is no direct mapping between vpid02 and vpid12, the - * vpid02 is per-vCPU for L0 and reused while the value of - * vpid12 is changed w/ one invvpid during nested vmentry. - * The vpid12 is allocated by L1 for L2, so it will not - * influence global bitmap(for vpid01 and vpid02 allocation) - * even if spawn a lot of nested vCPUs. - */ - if (nested_cpu_has_vpid(vmcs12) && vmx->nested.vpid02) { - if (vmcs12->virtual_processor_id != vmx->nested.last_vpid) { - vmx->nested.last_vpid = vmcs12->virtual_processor_id; - __vmx_flush_tlb(vcpu, vmx->nested.vpid02, true); + if (nested_cpu_has_vpid(vmcs12)) { + if (!nested_cpu_has_ept(vmcs12)) { + if (vmx->nested.vpid02) { + if (vmcs12->virtual_processor_id != vmx->nested.last_vpid) { + vmx->nested.last_vpid = vmcs12->virtual_processor_id; + __vmx_flush_tlb(vcpu, vmx->nested.vpid02, true); + } + } else { + vmx_flush_tlb(vcpu, true); + } } } else { /* -- 2.16.1