linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org
Cc: seanjc@google.com
Subject: [PATCH v2 18/18] KVM: x86: do not unload MMU roots on all role changes
Date: Thu, 17 Feb 2022 16:03:40 -0500	[thread overview]
Message-ID: <20220217210340.312449-19-pbonzini@redhat.com> (raw)
In-Reply-To: <20220217210340.312449-1-pbonzini@redhat.com>

kvm_mmu_reset_context is called on all role changes and right now it
calls kvm_mmu_unload.  With the legacy MMU this is a relatively cheap
operation; the previous PGDs remains in the hash table and is picked
up immediately on the next page fault.  With the TDP MMU, however, the
roots are thrown away for good and a full rebuild of the page tables is
necessary, which is many times more expensive.

Fortunately, throwing away the roots is not necessary except when
the manual says a TLB flush is required:

- changing CR0.PG from 1 to 0 (because it flushes the TLB according to
  the x86 architecture specification)

- changing CPUID (which changes the interpretation of page tables in
  ways not reflected by the role).

- changing CR4.SMEP from 0 to 1 (not doing so actually breaks access.c)

Except for these cases, once the MMU has updated the CPU/MMU roles
and metadata it is enough to force-reload the current value of CR3.
KVM will look up the cached roots for an entry with the right role and
PGD, and only if the cache misses a new root will be created.

Measuring with vmexit.flat from kvm-unit-tests shows the following
improvement:

             TDP         legacy       shadow
   before    46754       5096         5150
   after     4879        4875         5006

which is for very small page tables.  The impact is however much larger
when running as an L1 hypervisor, because the new page tables cause
extra work for L0 to shadow them.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 arch/x86/kvm/mmu/mmu.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index c44b5114f947..913cc7229bf4 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -5043,8 +5043,8 @@ EXPORT_SYMBOL_GPL(kvm_init_mmu);
 void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu)
 {
 	/*
-	 * Invalidate all MMU roles to force them to reinitialize as CPUID
-	 * information is factored into reserved bit calculations.
+	 * Invalidate all MMU roles and roots to force them to reinitialize,
+	 * as CPUID information is factored into reserved bit calculations.
 	 *
 	 * Correctly handling multiple vCPU models with respect to paging and
 	 * physical address properties) in a single VM would require tracking
@@ -5057,6 +5057,7 @@ void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu)
 	vcpu->arch.root_mmu.mmu_role.ext.valid = 0;
 	vcpu->arch.guest_mmu.mmu_role.ext.valid = 0;
 	vcpu->arch.nested_mmu.mmu_role.ext.valid = 0;
+	kvm_mmu_unload(vcpu);
 	kvm_mmu_reset_context(vcpu);
 
 	/*
@@ -5068,8 +5069,8 @@ void kvm_mmu_after_set_cpuid(struct kvm_vcpu *vcpu)
 
 void kvm_mmu_reset_context(struct kvm_vcpu *vcpu)
 {
-	kvm_mmu_unload(vcpu);
 	kvm_init_mmu(vcpu);
+	kvm_make_request(KVM_REQ_MMU_UPDATE_ROOT, vcpu);
 }
 EXPORT_SYMBOL_GPL(kvm_mmu_reset_context);
 
-- 
2.31.1


  parent reply	other threads:[~2022-02-17 21:04 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-17 21:03 [PATCH v2 00/18] KVM: MMU: do not unload MMU roots on all role changes Paolo Bonzini
2022-02-17 21:03 ` [PATCH v2 01/18] KVM: x86: host-initiated EFER.LME write affects the MMU Paolo Bonzini
2022-02-18 17:08   ` Sean Christopherson
2022-02-18 17:26     ` Paolo Bonzini
2022-02-23 13:40   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 02/18] KVM: x86: do not deliver asynchronous page faults if CR0.PG=0 Paolo Bonzini
2022-02-18 17:12   ` Sean Christopherson
2022-02-23 14:07   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 03/18] KVM: x86/mmu: WARN if PAE roots linger after kvm_mmu_unload Paolo Bonzini
2022-02-18 17:14   ` Sean Christopherson
2022-02-18 17:23     ` Paolo Bonzini
2022-02-23 14:11       ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 04/18] KVM: x86/mmu: avoid NULL-pointer dereference on page freeing bugs Paolo Bonzini
2022-02-18 17:15   ` Sean Christopherson
2022-02-23 14:12   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 05/18] KVM: x86/mmu: use struct kvm_mmu_root_info for mmu->root Paolo Bonzini
2022-02-23 14:39   ` Maxim Levitsky
2022-02-23 15:42     ` Sean Christopherson
2022-02-17 21:03 ` [PATCH v2 06/18] KVM: x86/mmu: do not consult levels when freeing roots Paolo Bonzini
2022-02-18 17:27   ` Sean Christopherson
2022-02-23 14:59   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 07/18] KVM: x86/mmu: Do not use guest root level in audit Paolo Bonzini
2022-02-18 18:37   ` Sean Christopherson
2022-02-18 18:46     ` Paolo Bonzini
2022-02-23 15:02       ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 08/18] KVM: x86/mmu: do not pass vcpu to root freeing functions Paolo Bonzini
2022-02-18 18:39   ` Sean Christopherson
2022-02-23 15:16   ` Maxim Levitsky
2022-02-23 15:48     ` Sean Christopherson
2022-02-17 21:03 ` [PATCH v2 09/18] KVM: x86/mmu: look for a cached PGD when going from 32-bit to 64-bit Paolo Bonzini
2022-02-18 18:08   ` Sean Christopherson
2022-02-23 16:01   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 10/18] KVM: x86/mmu: load new PGD after the shadow MMU is initialized Paolo Bonzini
2022-02-18 23:59   ` Sean Christopherson
2022-02-23 16:20   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 11/18] KVM: x86/mmu: Always use current mmu's role when loading new PGD Paolo Bonzini
2022-02-18 23:59   ` Sean Christopherson
2022-02-23 16:23   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 12/18] KVM: x86/mmu: clear MMIO cache when unloading the MMU Paolo Bonzini
2022-02-18 23:59   ` Sean Christopherson
2022-02-23 16:32   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 13/18] KVM: x86: reset and reinitialize the MMU in __set_sregs_common Paolo Bonzini
2022-02-19  0:22   ` Sean Christopherson
2022-02-23 16:48   ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 14/18] KVM: x86/mmu: avoid indirect call for get_cr3 Paolo Bonzini
2022-02-18 20:30   ` Sean Christopherson
2022-02-19 10:03     ` Paolo Bonzini
2022-02-24 11:02   ` Maxim Levitsky
2022-02-24 15:12     ` Sean Christopherson
2022-02-24 15:14       ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 15/18] KVM: x86/mmu: rename kvm_mmu_new_pgd, introduce variant that calls get_guest_pgd Paolo Bonzini
2022-02-18  9:39   ` Paolo Bonzini
2022-02-18 21:00     ` Sean Christopherson
2022-02-24 15:41       ` Maxim Levitsky
2022-02-25 17:40         ` Sean Christopherson
2022-02-17 21:03 ` [PATCH v2 16/18] KVM: x86: introduce KVM_REQ_MMU_UPDATE_ROOT Paolo Bonzini
2022-02-18 21:45   ` Sean Christopherson
2022-02-19  7:54     ` Paolo Bonzini
2022-02-22 16:06       ` Sean Christopherson
2022-02-24 15:50       ` Maxim Levitsky
2022-02-17 21:03 ` [PATCH v2 17/18] KVM: x86: flush TLB separately from MMU reset Paolo Bonzini
2022-02-18 23:57   ` Sean Christopherson
2022-02-21 15:01     ` Paolo Bonzini
2022-02-24 16:11   ` Maxim Levitsky
2022-02-17 21:03 ` Paolo Bonzini [this message]
2022-02-24 16:25   ` [PATCH v2 18/18] KVM: x86: do not unload MMU roots on all role changes Maxim Levitsky

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=20220217210340.312449-19-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).