From: Yosry Ahmed <yosry.ahmed@linux.dev>
To: Maxim Levitsky <mlevitsk@redhat.com>
Cc: Sean Christopherson <seanjc@google.com>,
Paolo Bonzini <pbonzini@redhat.com>,
kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH 01/13] KVM: nSVM: Track the ASID per-VMCB
Date: Mon, 3 Mar 2025 19:31:50 +0000 [thread overview]
Message-ID: <Z8YDpocIkdUn8LCU@google.com> (raw)
In-Reply-To: <7addde721e3f67bfa8ec5c9671f51d131f84bc6b.camel@redhat.com>
On Fri, Feb 28, 2025 at 08:23:48PM -0500, Maxim Levitsky wrote:
> On Wed, 2025-02-05 at 18:23 +0000, Yosry Ahmed wrote:
> > The ASID is currently tracked per-vCPU, because the same ASID is used by
> > L1 and L2. That ASID is flushed on every transition between L1 and L2.
> >
> > Track the ASID separately for each VMCB (similar to the
> > asid_generation), giving L2 a separate ASID. This is in preparation for
> > doing fine-grained TLB flushes on nested transitions instead of
> > unconditional full flushes.
> >
> > The ASIDs are still not fully maintained (e.g. a remote flush will only
> > flush the current ASID), so keep the TLB flush on every transition until
> > this is sorted out.
> >
> > L1's ASID will be flushed on KVM_REQ_TLB_FLUSH_GUEST if it is the
> > active context, so remove the TODO in nested_svm_transition_tlb_flush()
> > about it.
> >
> > Signed-off-by: Yosry Ahmed <yosry.ahmed@linux.dev>
> > ---
> > arch/x86/kvm/svm/nested.c | 1 -
> > arch/x86/kvm/svm/sev.c | 2 +-
> > arch/x86/kvm/svm/svm.c | 12 +++++++-----
> > arch/x86/kvm/svm/svm.h | 2 +-
> > 4 files changed, 9 insertions(+), 8 deletions(-)
> >
> > diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
> > index 04c375bf1ac2a..bbe4f3ac9f250 100644
> > --- a/arch/x86/kvm/svm/nested.c
> > +++ b/arch/x86/kvm/svm/nested.c
> > @@ -495,7 +495,6 @@ static void nested_svm_transition_tlb_flush(struct kvm_vcpu *vcpu)
> > * - Honor L1's request to flush an ASID on nested VMRUN
> > * - Sync nested NPT MMU on VMRUN that flushes L2's ASID[*]
> > * - Don't crush a pending TLB flush in vmcb02 on nested VMRUN
> > - * - Flush L1's ASID on KVM_REQ_TLB_FLUSH_GUEST
> > *
> > * [*] Unlike nested EPT, SVM's ASID management can invalidate nested
> > * NPT guest-physical mappings on VMRUN.
> > diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
> > index 799f8494b599c..b0adfd0537d00 100644
> > --- a/arch/x86/kvm/svm/sev.c
> > +++ b/arch/x86/kvm/svm/sev.c
> > @@ -3468,7 +3468,7 @@ void pre_sev_run(struct vcpu_svm *svm, int cpu)
> > unsigned int asid = sev_get_asid(svm->vcpu.kvm);
> >
> > /* Assign the asid allocated with this SEV guest */
> > - svm->asid = asid;
> > + svm->current_vmcb->asid = asid;
> >
> > /*
> > * Flush guest TLB:
> > diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> > index 7640a84e554a6..08340ae57777b 100644
> > --- a/arch/x86/kvm/svm/svm.c
> > +++ b/arch/x86/kvm/svm/svm.c
> > @@ -1335,8 +1335,10 @@ static void init_vmcb(struct kvm_vcpu *vcpu)
> > save->g_pat = vcpu->arch.pat;
> > save->cr3 = 0;
> > }
> > - svm->current_vmcb->asid_generation = 0;
> > - svm->asid = 0;
> > + svm->vmcb01.asid_generation = 0;
> > + svm->vmcb01.asid = 0;
> > + svm->nested.vmcb02.asid_generation = 0;
> > + svm->nested.vmcb02.asid = 0;
> >
> > svm->nested.vmcb12_gpa = INVALID_GPA;
> > svm->nested.last_vmcb12_gpa = INVALID_GPA;
> > @@ -1988,7 +1990,7 @@ static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd)
> > }
> >
> > svm->current_vmcb->asid_generation = sd->asid_generation;
> > - svm->asid = sd->next_asid++;
> > + svm->current_vmcb->asid = sd->next_asid++;
> > }
> >
> > static void svm_set_dr6(struct vcpu_svm *svm, unsigned long value)
> > @@ -4235,8 +4237,8 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct kvm_vcpu *vcpu,
> >
> > sync_lapic_to_cr8(vcpu);
> >
> > - if (unlikely(svm->asid != svm->vmcb->control.asid)) {
> > - svm->vmcb->control.asid = svm->asid;
> > + if (unlikely(svm->current_vmcb->asid != svm->vmcb->control.asid)) {
> > + svm->vmcb->control.asid = svm->current_vmcb->asid;
> > vmcb_mark_dirty(svm->vmcb, VMCB_ASID);
> > }
> > svm->vmcb->save.cr2 = vcpu->arch.cr2;
> > diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
> > index 9d7cdb8fbf872..ebbb0b1a64676 100644
> > --- a/arch/x86/kvm/svm/svm.h
> > +++ b/arch/x86/kvm/svm/svm.h
> > @@ -133,6 +133,7 @@ struct kvm_vmcb_info {
> > unsigned long pa;
> > int cpu;
> > uint64_t asid_generation;
> > + u32 asid;
> > };
> >
> > struct vmcb_save_area_cached {
> > @@ -247,7 +248,6 @@ struct vcpu_svm {
> > struct vmcb *vmcb;
> > struct kvm_vmcb_info vmcb01;
> > struct kvm_vmcb_info *current_vmcb;
> > - u32 asid;
> > u32 sysenter_esp_hi;
> > u32 sysenter_eip_hi;
> > uint64_t tsc_aux;
>
> Hi,
>
Hi,
Thanks for taking a look!
>
> I think it should be possible to eliminate separate ASID field (current_vmcb->asid/svm->asid)
> completely and instead just use the value stored in the vmcb.
>
> When there is a need to update it, KVM can also set the corresponding dirty bit
> as done in svm_vcpu_run (new_asid also already does this when the asid generation increases)
>
> Also KVM already sets the tlb_ctl directly in the vmcb.
>
> What do you think?
Yeah I think we can do that, although if we go with Sean's suggestion of
a per VM or a per vCPU ASID, this will change anyway. If we use a per
vCPU ASID, I think it would be nice to have it directly in svm->asid and
svm->nested.asid02 to be consistent with VMX.
I will see how the code turns out to be after taking Sean's suggestion
and go from there.
next prev parent reply other threads:[~2025-03-03 19:31 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-05 18:23 [RFC PATCH 00/13] Optimize nSVM TLB flushes Yosry Ahmed
2025-02-05 18:23 ` [RFC PATCH 01/13] KVM: nSVM: Track the ASID per-VMCB Yosry Ahmed
2025-03-01 0:03 ` Sean Christopherson
2025-03-03 17:51 ` Jim Mattson
2025-03-03 18:53 ` Sean Christopherson
2025-03-03 19:18 ` Yosry Ahmed
2025-03-01 1:23 ` Maxim Levitsky
2025-03-03 19:31 ` Yosry Ahmed [this message]
2025-02-05 18:23 ` [RFC PATCH 02/13] KVM: nSVM: Rework svm_flush_tlb_asid() to operate on a given VMCB Yosry Ahmed
2025-03-01 1:29 ` Maxim Levitsky
2025-03-03 21:58 ` Yosry Ahmed
2025-03-05 2:52 ` Maxim Levitsky
2025-02-05 18:23 ` [RFC PATCH 03/13] KVM: nSVM: Split nested_svm_transition_tlb_flush() into entry/exit fns Yosry Ahmed
2025-03-01 1:34 ` Maxim Levitsky
2025-02-05 18:23 ` [RFC PATCH 04/13] KVM: SVM: Introduce helpers for updating TLB_CONTROL Yosry Ahmed
2025-03-01 1:37 ` Maxim Levitsky
2025-02-05 18:23 ` [RFC PATCH 05/13] KVM: x86/mmu: rename __kvm_mmu_invalidate_addr() Yosry Ahmed
2025-02-05 18:23 ` [RFC PATCH 06/13] KVM: x86/mmu: Allow skipping the gva flush in kvm_mmu_invalidate_addr() Yosry Ahmed
2025-02-05 18:23 ` [RFC PATCH 07/13] KVM: nSVM: Handle INVLPGA interception correctly Yosry Ahmed
2025-03-01 1:55 ` Maxim Levitsky
2025-03-03 22:05 ` Yosry Ahmed
2025-03-05 2:54 ` Maxim Levitsky
2025-03-05 6:20 ` Yosry Ahmed
2025-02-05 18:23 ` [RFC PATCH 08/13] KVM: nSVM: Flush both L1 and L2 ASIDs on KVM_REQ_TLB_FLUSH Yosry Ahmed
2025-03-01 1:58 ` Maxim Levitsky
2025-03-03 22:06 ` Yosry Ahmed
2025-02-05 18:23 ` [RFC PATCH 09/13] KVM: nSVM: Handle nested TLB flush requests through TLB_CONTROL Yosry Ahmed
2025-02-05 21:45 ` Yosry Ahmed
2025-03-01 2:06 ` Maxim Levitsky
2025-03-03 22:10 ` Yosry Ahmed
2025-03-05 2:57 ` Maxim Levitsky
2025-02-05 18:23 ` [RFC PATCH 10/13] KVM: nSVM: Flush the TLB if L1 changes L2's ASID Yosry Ahmed
2025-03-01 2:13 ` Maxim Levitsky
2025-02-05 18:24 ` [RFC PATCH 11/13] KVM: nSVM: Do not reset TLB_CONTROL in VMCB02 on nested entry Yosry Ahmed
2025-03-01 2:17 ` Maxim Levitsky
2025-03-03 22:14 ` Yosry Ahmed
2025-03-05 3:01 ` Maxim Levitsky
2025-03-05 6:34 ` Yosry Ahmed
2025-02-05 18:24 ` [RFC PATCH 12/13] KVM: nSVM: Service local TLB flushes before nested transitions Yosry Ahmed
2025-03-01 2:20 ` Maxim Levitsky
2025-03-03 22:18 ` Yosry Ahmed
2025-03-05 3:03 ` Maxim Levitsky
2025-03-05 6:37 ` Yosry Ahmed
2025-02-05 18:24 ` [RFC PATCH 13/13] KVM: nSVM: Stop bombing the TLB on " Yosry Ahmed
2025-03-01 2:21 ` Maxim Levitsky
2025-03-03 22:21 ` Yosry Ahmed
2025-03-05 3:14 ` Maxim Levitsky
2025-03-05 6:45 ` Yosry Ahmed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Z8YDpocIkdUn8LCU@google.com \
--to=yosry.ahmed@linux.dev \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mlevitsk@redhat.com \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.