[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CALMp9eQoGsO8KvugXP631tL0kWbrcwMrPR_ErLa9c9-OCg7GaA@mail.gmail.com>
Date: Wed, 15 Jan 2025 21:27:44 -0800
From: Jim Mattson <jmattson@...gle.com>
To: Yosry Ahmed <yosryahmed@...gle.com>
Cc: Sean Christopherson <seanjc@...gle.com>, Paolo Bonzini <pbonzini@...hat.com>, kvm@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH] KVM: nVMX: Always use TLB_FLUSH_GUEST for nested VM-Enter/VM-Exit
On Wed, Jan 15, 2025 at 7:50 PM Yosry Ahmed <yosryahmed@...gle.com> wrote:
>
> nested_vmx_transition_tlb_flush() uses KVM_REQ_TLB_FLUSH_CURRENT to
> flush the TLB if VPID is enabled for both L1 and L2, but they still
> share the TLB tag. This happens if EPT is disabled and KVM fails to
> allocate a VPID for L2, so both the EPTP and VPID are shared between L1
> and L2.
Nit: Combined and guest-physical TLB tags are based on EPTRTA (the new
acronym for EP4TA), not EPTP. But, in any case, with EPT disabled,
there are no combined or guest-physical mappings. There are only
linear mappings.
> Interestingly, nested_vmx_transition_tlb_flush() uses
> KVM_REQ_TLB_FLUSH_GUEST to flush the TLB for all other cases where a
> flush is required.
>
> Taking a close look at vmx_flush_tlb_guest() and
> vmx_flush_tlb_current(), the main differences are:
> (a) vmx_flush_tlb_current() is a noop if the KVM MMU is invalid.
> (b) vmx_flush_tlb_current() uses INVEPT if EPT is enabled (instead of
> INVVPID) to flush the guest-physical mappings as well as combined
> mappings.
>
> The check in (a) is seemingly an optimization, and there should not be
> any TLB entries for L1 anyway if the KVM MMU is invalid. Not having this
> check in vmx_flush_tlb_guest() is not a fundamental difference, and it
> can be added there separately if needed.
>
> The difference in (b) is irrelevant in this case, because EPT being
> enabled for L1 means that its TLB tags are tagged with EPTP and cannot
> be used by L2 (regardless of whether or not EPT is enabled for L2).
The difference is also irrelevant because, as you concluded in the
first paragraph, EPT is disabled in the final block of
nested_vmx_transition_tlb_flush().
> Use KVM_REQ_TLB_FLUSH_GUEST in this case in
> nested_vmx_transition_tlb_flush() for consistency. This arguably makes
> more sense conceptually too -- L1 and L2 cannot share the TLB tag for
> guest-physical translations, so only flushing linear and combined
> translations (i.e. guest-generated translations) is needed.
And, as I mentioned above, with EPT disabled, there are no combined or
guest-physical mappings.
> Signed-off-by: Yosry Ahmed <yosryahmed@...gle.com>
I think the reasoning in the commit message can be cleared up a bit, but...
Reviewed-by: Jim Mattson <mattson@...gle.com>
> ---
>
> I tested this by running all selftests that have "nested" in their name
> (and not svm). I was tempted to run KVM-unit-tests in an L1 guest but I
> convinced myself it's prompted by the change :)
>
> ---
> arch/x86/kvm/vmx/nested.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
> index aa78b6f38dfef..2ed454186e59c 100644
> --- a/arch/x86/kvm/vmx/nested.c
> +++ b/arch/x86/kvm/vmx/nested.c
> @@ -1241,7 +1241,7 @@ static void nested_vmx_transition_tlb_flush(struct kvm_vcpu *vcpu,
> * as the effective ASID is common to both L1 and L2.
> */
> if (!nested_has_guest_tlb_tag(vcpu))
> - kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu);
> + kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
> }
>
> static bool is_bitwise_subset(u64 superset, u64 subset, u64 mask)
> --
> 2.48.0.rc2.279.g1de40edade-goog
>
>
Powered by blists - more mailing lists