From: Maxim Levitsky <mlevitsk@redhat.com>
To: Sean Christopherson <seanjc@google.com>,
Paolo Bonzini <pbonzini@redhat.com>
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
Alejandro Jimenez <alejandro.j.jimenez@oracle.com>,
Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>,
Li RongQing <lirongqing@baidu.com>
Subject: Re: [PATCH v4 10/32] KVM: x86: Move APIC access page helper to common x86 code
Date: Thu, 08 Dec 2022 23:55:18 +0200 [thread overview]
Message-ID: <b358ea43c7647c4ec4678932d1912845a2b29f1b.camel@redhat.com> (raw)
In-Reply-To: <20221001005915.2041642-11-seanjc@google.com>
On Sat, 2022-10-01 at 00:58 +0000, Sean Christopherson wrote:
> Move the APIC access page allocation helper function to common x86 code,
> the allocation routine is virtually identical between APICv (VMX) and
> AVIC (SVM). Keep APICv's gfn_to_page() + put_page() sequence, which
> verifies that a backing page can be allocated, i.e. that the system isn't
> under heavy memory pressure. Forcing the backing page to be populated
> isn't strictly necessary, but skipping the effective prefetch only delays
> the inevitable.
Just a note on the way we deal with that dummy page differs between APICv and AVIC
a bit:
On APICv we need physical address of the dummy page, since APICv
has physical address of this page in VMCB, and when guest "accesses"
only then APICv specific handling is invoked.
Since we don't want to pin it, we have a mmu notifier telling us where
it is currently and we update the vmcb each time it moves.
If the page is swapped out, mmu notifier will call us, and we will
pretty much swap it back in on next VM entry, in 'vmx_set_apic_access_page_addr'
I hope that this code doesn't have races, I never looked at depth at it.
On AVIC on the other hand we don't force the page to be mapped at all, since
AVIC stores in the vmcb the virtual address of the page and only checkes that
'something' is mapped there.
If we get nothing mapped there, AVIC will not intercept, we will get normal
NPT fault and hopefully swap that page in.
Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com>
Best regards,
Maxim Levitsky
>
> Signed-off-by: Sean Christopherson <seanjc@google.com>
> ---
> arch/x86/kvm/lapic.c | 35 +++++++++++++++++++++++++++++++++++
> arch/x86/kvm/lapic.h | 1 +
> arch/x86/kvm/svm/avic.c | 41 +++++++----------------------------------
> arch/x86/kvm/vmx/vmx.c | 35 +----------------------------------
> 4 files changed, 44 insertions(+), 68 deletions(-)
>
> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
> index 316b61b56cca..80e8b1cc6dc2 100644
> --- a/arch/x86/kvm/lapic.c
> +++ b/arch/x86/kvm/lapic.c
> @@ -2436,6 +2436,41 @@ void kvm_apic_update_apicv(struct kvm_vcpu *vcpu)
> }
> EXPORT_SYMBOL_GPL(kvm_apic_update_apicv);
>
> +int kvm_alloc_apic_access_page(struct kvm *kvm)
> +{
> + struct page *page;
> + void __user *hva;
> + int ret = 0;
> +
> + mutex_lock(&kvm->slots_lock);
> + if (kvm->arch.apic_access_memslot_enabled)
> + goto out;
> +
> + hva = __x86_set_memory_region(kvm, APIC_ACCESS_PAGE_PRIVATE_MEMSLOT,
> + APIC_DEFAULT_PHYS_BASE, PAGE_SIZE);
> + if (IS_ERR(hva)) {
> + ret = PTR_ERR(hva);
> + goto out;
> + }
> +
> + page = gfn_to_page(kvm, APIC_DEFAULT_PHYS_BASE >> PAGE_SHIFT);
> + if (is_error_page(page)) {
> + ret = -EFAULT;
> + goto out;
> + }
> +
> + /*
> + * Do not pin the page in memory, so that memory hot-unplug
> + * is able to migrate it.
> + */
> + put_page(page);
> + kvm->arch.apic_access_memslot_enabled = true;
> +out:
> + mutex_unlock(&kvm->slots_lock);
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(kvm_alloc_apic_access_page);
> +
> void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event)
> {
> struct kvm_lapic *apic = vcpu->arch.apic;
> diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h
> index a5ac4a5a5179..0587a8282cb3 100644
> --- a/arch/x86/kvm/lapic.h
> +++ b/arch/x86/kvm/lapic.h
> @@ -112,6 +112,7 @@ int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq,
> struct dest_map *dest_map);
> int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type);
> void kvm_apic_update_apicv(struct kvm_vcpu *vcpu);
> +int kvm_alloc_apic_access_page(struct kvm *kvm);
>
> bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src,
> struct kvm_lapic_irq *irq, int *r, struct dest_map *dest_map);
> diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c
> index 97ad0661f963..ec28ba4c5f1b 100644
> --- a/arch/x86/kvm/svm/avic.c
> +++ b/arch/x86/kvm/svm/avic.c
> @@ -256,39 +256,6 @@ static u64 *avic_get_physical_id_entry(struct kvm_vcpu *vcpu,
> return &avic_physical_id_table[index];
> }
>
> -/*
> - * Note:
> - * AVIC hardware walks the nested page table to check permissions,
> - * but does not use the SPA address specified in the leaf page
> - * table entry since it uses address in the AVIC_BACKING_PAGE pointer
> - * field of the VMCB. Therefore, we set up the
> - * APIC_ACCESS_PAGE_PRIVATE_MEMSLOT (4KB) here.
> - */
> -static int avic_alloc_access_page(struct kvm *kvm)
> -{
> - void __user *ret;
> - int r = 0;
> -
> - mutex_lock(&kvm->slots_lock);
> -
> - if (kvm->arch.apic_access_memslot_enabled)
> - goto out;
> -
> - ret = __x86_set_memory_region(kvm,
> - APIC_ACCESS_PAGE_PRIVATE_MEMSLOT,
> - APIC_DEFAULT_PHYS_BASE,
> - PAGE_SIZE);
> - if (IS_ERR(ret)) {
> - r = PTR_ERR(ret);
> - goto out;
> - }
> -
> - kvm->arch.apic_access_memslot_enabled = true;
> -out:
> - mutex_unlock(&kvm->slots_lock);
> - return r;
> -}
> -
> static int avic_init_backing_page(struct kvm_vcpu *vcpu)
> {
> u64 *entry, new_entry;
> @@ -305,7 +272,13 @@ static int avic_init_backing_page(struct kvm_vcpu *vcpu)
> if (kvm_apicv_activated(vcpu->kvm)) {
> int ret;
>
> - ret = avic_alloc_access_page(vcpu->kvm);
> + /*
> + * Note, AVIC hardware walks the nested page table to check
> + * permissions, but does not use the SPA address specified in
> + * the leaf SPTE since it uses address in the AVIC_BACKING_PAGE
> + * pointer field of the VMCB.
> + */
> + ret = kvm_alloc_apic_access_page(vcpu->kvm);
> if (ret)
> return ret;
> }
> diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
> index 9dba04b6b019..974d9a366d5d 100644
> --- a/arch/x86/kvm/vmx/vmx.c
> +++ b/arch/x86/kvm/vmx/vmx.c
> @@ -3771,39 +3771,6 @@ static void seg_setup(int seg)
> vmcs_write32(sf->ar_bytes, ar);
> }
>
> -static int alloc_apic_access_page(struct kvm *kvm)
> -{
> - struct page *page;
> - void __user *hva;
> - int ret = 0;
> -
> - mutex_lock(&kvm->slots_lock);
> - if (kvm->arch.apic_access_memslot_enabled)
> - goto out;
> - hva = __x86_set_memory_region(kvm, APIC_ACCESS_PAGE_PRIVATE_MEMSLOT,
> - APIC_DEFAULT_PHYS_BASE, PAGE_SIZE);
> - if (IS_ERR(hva)) {
> - ret = PTR_ERR(hva);
> - goto out;
> - }
> -
> - page = gfn_to_page(kvm, APIC_DEFAULT_PHYS_BASE >> PAGE_SHIFT);
> - if (is_error_page(page)) {
> - ret = -EFAULT;
> - goto out;
> - }
> -
> - /*
> - * Do not pin the page in memory, so that memory hot-unplug
> - * is able to migrate it.
> - */
> - put_page(page);
> - kvm->arch.apic_access_memslot_enabled = true;
> -out:
> - mutex_unlock(&kvm->slots_lock);
> - return ret;
> -}
> -
> int allocate_vpid(void)
> {
> int vpid;
> @@ -7348,7 +7315,7 @@ static int vmx_vcpu_create(struct kvm_vcpu *vcpu)
> vmx->loaded_vmcs = &vmx->vmcs01;
>
> if (cpu_need_virtualize_apic_accesses(vcpu)) {
> - err = alloc_apic_access_page(vcpu->kvm);
> + err = kvm_alloc_apic_access_page(vcpu->kvm);
> if (err)
> goto free_vmcs;
> }
next prev parent reply other threads:[~2022-12-08 21:56 UTC|newest]
Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-01 0:58 [PATCH v4 00/32] KVM: x86: AVIC and local APIC fixes+cleanups Sean Christopherson
2022-10-01 0:58 ` [PATCH v4 01/32] KVM: x86: Blindly get current x2APIC reg value on "nodecode write" traps Sean Christopherson
2022-12-08 21:47 ` Maxim Levitsky
2022-10-01 0:58 ` [PATCH v4 02/32] KVM: x86: Purge "highest ISR" cache when updating APICv state Sean Christopherson
2022-12-08 21:47 ` Maxim Levitsky
2022-10-01 0:58 ` [PATCH v4 03/32] KVM: SVM: Flush the "current" TLB when activating AVIC Sean Christopherson
[not found] ` <b9f336f17eec6bfbb8429700e0f135d19813c576.camel@redhat.com>
2022-12-08 21:52 ` Maxim Levitsky
2022-12-09 0:40 ` Sean Christopherson
2022-12-08 22:02 ` Maxim Levitsky
2022-10-01 0:58 ` [PATCH v4 04/32] KVM: SVM: Process ICR on AVIC IPI delivery failure due to invalid target Sean Christopherson
2022-10-01 0:58 ` [PATCH v4 05/32] KVM: x86: Don't inhibit APICv/AVIC on xAPIC ID "change" if APIC is disabled Sean Christopherson
2022-12-08 21:53 ` Maxim Levitsky
2022-10-01 0:58 ` [PATCH v4 06/32] KVM: x86: Track xAPIC ID only on userspace SET, _after_ vAPIC is updated Sean Christopherson
2022-12-08 21:53 ` Maxim Levitsky
2022-10-01 0:58 ` [PATCH v4 07/32] KVM: x86: Don't inhibit APICv/AVIC if xAPIC ID mismatch is due to 32-bit ID Sean Christopherson
2022-12-08 21:53 ` Maxim Levitsky
2022-10-01 0:58 ` [PATCH v4 08/32] KVM: SVM: Don't put/load AVIC when setting virtual APIC mode Sean Christopherson
2022-12-08 21:53 ` Maxim Levitsky
2022-10-01 0:58 ` [PATCH v4 09/32] KVM: x86: Handle APICv updates for APIC "mode" changes via request Sean Christopherson
2022-12-08 21:54 ` Maxim Levitsky
2022-10-01 0:58 ` [PATCH v4 10/32] KVM: x86: Move APIC access page helper to common x86 code Sean Christopherson
2022-12-08 21:55 ` Maxim Levitsky [this message]
2022-10-01 0:58 ` [PATCH v4 11/32] KVM: x86: Inhibit APIC memslot if x2APIC and AVIC are enabled Sean Christopherson
2022-12-08 21:56 ` Maxim Levitsky
2022-12-16 19:03 ` Sean Christopherson
2022-12-16 19:40 ` Sean Christopherson
2022-12-27 11:25 ` Paolo Bonzini
2023-01-03 16:30 ` Sean Christopherson
2022-10-01 0:58 ` [PATCH v4 12/32] KVM: SVM: Replace "avic_mode" enum with "x2avic_enabled" boolean Sean Christopherson
2022-10-01 0:58 ` [PATCH v4 13/32] KVM: SVM: Compute dest based on sender's x2APIC status for AVIC kick Sean Christopherson
2022-10-01 0:58 ` [PATCH v4 14/32] KVM: SVM: Fix x2APIC Logical ID calculation for avic_kick_target_vcpus_fast Sean Christopherson
2022-10-01 0:58 ` [PATCH v4 15/32] Revert "KVM: SVM: Use target APIC ID to complete x2AVIC IRQs when possible" Sean Christopherson
2022-12-08 21:56 ` Maxim Levitsky
2022-10-01 0:58 ` [PATCH v4 16/32] KVM: SVM: Document that vCPU ID == APIC ID in AVIC kick fastpatch Sean Christopherson
2022-10-01 0:59 ` [PATCH v4 17/32] KVM: SVM: Add helper to perform final AVIC "kick" of single vCPU Sean Christopherson
2022-10-01 0:59 ` [PATCH v4 18/32] KVM: x86: Explicitly skip optimized logical map setup if vCPU's LDR==0 Sean Christopherson
2022-12-08 21:56 ` Maxim Levitsky
2022-10-01 0:59 ` [PATCH v4 19/32] KVM: x86: Explicitly track all possibilities for APIC map's logical modes Sean Christopherson
2022-12-08 21:57 ` Maxim Levitsky
2022-12-16 18:39 ` Sean Christopherson
2022-12-16 23:34 ` Sean Christopherson
2022-12-27 11:30 ` Paolo Bonzini
2022-10-01 0:59 ` [PATCH v4 20/32] KVM: x86: Skip redundant x2APIC logical mode optimized cluster setup Sean Christopherson
2022-12-08 21:57 ` Maxim Levitsky
2022-10-01 0:59 ` [PATCH v4 21/32] KVM: x86: Disable APIC logical map if logical ID covers multiple MDAs Sean Christopherson
2022-10-01 0:59 ` [PATCH v4 22/32] KVM: x86: Disable APIC logical map if vCPUs are aliased in logical mode Sean Christopherson
2022-10-01 0:59 ` [PATCH v4 23/32] KVM: x86: Honor architectural behavior for aliased 8-bit APIC IDs Sean Christopherson
2022-12-08 21:58 ` Maxim Levitsky
2022-10-01 0:59 ` [PATCH v4 24/32] KVM: x86: Inhibit APICv/AVIC if the optimized physical map is disabled Sean Christopherson
2022-12-08 21:58 ` Maxim Levitsky
2022-12-09 0:56 ` Sean Christopherson
2022-10-01 0:59 ` [PATCH v4 25/32] KVM: SVM: Inhibit AVIC if vCPUs are aliased in logical mode Sean Christopherson
2022-12-08 21:58 ` Maxim Levitsky
2022-10-01 0:59 ` [PATCH v4 26/32] KVM: SVM: Always update local APIC on writes to logical dest register Sean Christopherson
2022-12-08 21:58 ` Maxim Levitsky
2022-10-01 0:59 ` [PATCH v4 27/32] KVM: SVM: Update svm->ldr_reg cache even if LDR is "bad" Sean Christopherson
2022-12-08 21:59 ` Maxim Levitsky
2022-12-09 0:49 ` Sean Christopherson
2022-10-01 0:59 ` [PATCH v4 28/32] KVM: SVM: Require logical ID to be power-of-2 for AVIC entry Sean Christopherson
2022-12-08 22:00 ` Maxim Levitsky
2022-12-29 8:27 ` mlevitsk
2023-01-04 10:08 ` Maxim Levitsky
2023-01-04 18:02 ` Sean Christopherson
2023-01-04 18:34 ` Maxim Levitsky
2022-10-01 0:59 ` [PATCH v4 29/32] KVM: SVM: Handle multiple logical targets in AVIC kick fastpath Sean Christopherson
2022-12-08 22:00 ` Maxim Levitsky
2022-10-01 0:59 ` [PATCH v4 30/32] KVM: SVM: Ignore writes to Remote Read Data on AVIC write traps Sean Christopherson
2022-10-01 0:59 ` [PATCH v4 31/32] Revert "KVM: SVM: Do not throw warning when calling avic_vcpu_load on a running vcpu" Sean Christopherson
2022-12-08 22:01 ` Maxim Levitsky
2022-10-01 0:59 ` [PATCH v4 32/32] KVM: x86: Track required APICv inhibits with variable, not callback Sean Christopherson
2022-12-08 22:03 ` Maxim Levitsky
2022-12-27 11:22 ` [PATCH v4 00/32] KVM: x86: AVIC and local APIC fixes+cleanups Paolo Bonzini
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=b358ea43c7647c4ec4678932d1912845a2b29f1b.camel@redhat.com \
--to=mlevitsk@redhat.com \
--cc=alejandro.j.jimenez@oracle.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lirongqing@baidu.com \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
--cc=suravee.suthikulpanit@amd.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®