Messages in this thread | | | Subject | Re: [PATCH v3 05/12] KVM: x86/mmu: allow APICv memslot to be partially enabled | From | Paolo Bonzini <> | Date | Tue, 3 Aug 2021 11:12:33 +0200 |
| |
On 02/08/21 20:33, Maxim Levitsky wrote: > on AMD, APIC virtualization needs to dynamicaly inhibit the AVIC in a > response to some events, and this is problematic and not efficient to do by > enabling/disabling the memslot that covers APIC's mmio range. > Plus due to SRCU locking, it makes it more complex to request AVIC inhibition. > > Instead, the APIC memslot will be always enabled, but the MMU code > will not install a SPTE for it, when arch.apic_access_memslot_enabled == false > and instead jump straight to emulating the access. > > When inhibiting the AVIC, this SPTE will be zapped. > > This code is based on a suggestion from Sean Christopherson: > https://lkml.org/lkml/2021/7/19/2970 > > Suggested-by: Sean Christopherson <seanjc@google.com> > Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com> > --- > arch/x86/kvm/mmu/mmu.c | 23 ++++++++++++++++++----- > 1 file changed, 18 insertions(+), 5 deletions(-) > > diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c > index 6f77f6efd43c..965b562da893 100644 > --- a/arch/x86/kvm/mmu/mmu.c > +++ b/arch/x86/kvm/mmu/mmu.c > @@ -3857,11 +3857,24 @@ static bool kvm_faultin_pfn(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn, > if (slot && (slot->flags & KVM_MEMSLOT_INVALID)) > goto out_retry; > > - /* Don't expose private memslots to L2. */ > - if (is_guest_mode(vcpu) && !kvm_is_visible_memslot(slot)) { > - *pfn = KVM_PFN_NOSLOT; > - *writable = false; > - return false; > + if (!kvm_is_visible_memslot(slot)) { > + /* Don't expose private memslots to L2. */ > + if (is_guest_mode(vcpu)) { > + *pfn = KVM_PFN_NOSLOT; > + *writable = false; > + return false; > + } > + /* > + * If the APIC access page exists but is disabled, go directly > + * to emulation without caching the MMIO access or creating a > + * MMIO SPTE. That way the cache doesn't need to be purged > + * when the AVIC is re-enabled. > + */ > + if (slot && slot->id == APIC_ACCESS_PAGE_PRIVATE_MEMSLOT && > + !vcpu->kvm->arch.apic_access_memslot_enabled) {
In addition to using apicv_inhibit_reasons, I would change the subject to "allow APICv memslot to be enabled but invisible". Otherwise looks good.
Paolo
> + *r = RET_PF_EMULATE; > + return true; > + } > } > > async = false; >
| |