From: Paolo Bonzini <pbonzini@redhat.com>
To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org
Cc: dmatlack@google.com, seanjc@google.com
Subject: [PATCH v2 25/25] KVM: x86/mmu: extract initialization of the page walking data
Date: Mon, 21 Feb 2022 11:22:43 -0500 [thread overview]
Message-ID: <20220221162243.683208-26-pbonzini@redhat.com> (raw)
In-Reply-To: <20220221162243.683208-1-pbonzini@redhat.com>
struct kvm_mmu consists logically of two parts: a page walker that
operates based on the CPU mode, and the shadow page table builder
that operates based on the MMU role; the latter does not exist
on vcpu->arch.nested_mmu.
The callbacks are also logically separated; of those that are not
constant, gva_to_gpa belongs to the page walker and everything else
belongs to the shadow page table builder. This is visible in the
duplicated code to initialize gva_to_gpa in *_init_context (for
shadow paging and nested NPT), in init_kvm_tdp_mmu (for non-nested
TDP), and in init_kvm_nested_mmu. The guest paging metadata also
belongs to the page walker and is duplicated in the same way.
Extract this duplicated code to a new function. The new function
is basically the same as init_kvm_nested_mmu, since the nested MMU
has only the page walker part. The only difference is that it
uses the CPU mode rather than the VCPU directly, which is more
in line with the rest of the MMU code.
Shadow EPT does not use the new function, since it has its own
gva_to_gpa callback and a different set of reserved bits.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
arch/x86/kvm/mmu/mmu.c | 87 ++++++++++++++----------------------------
1 file changed, 28 insertions(+), 59 deletions(-)
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 27cb6ba5a3b0..659f014190d2 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -4070,7 +4070,6 @@ int kvm_tdp_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
static void nonpaging_init_context(struct kvm_mmu *context)
{
context->page_fault = nonpaging_page_fault;
- context->gva_to_gpa = nonpaging_gva_to_gpa;
context->sync_page = nonpaging_sync_page;
context->invlpg = NULL;
}
@@ -4651,7 +4650,6 @@ static void reset_guest_paging_metadata(struct kvm_vcpu *vcpu,
static void paging64_init_context(struct kvm_mmu *context)
{
context->page_fault = paging64_page_fault;
- context->gva_to_gpa = paging64_gva_to_gpa;
context->sync_page = paging64_sync_page;
context->invlpg = paging64_invlpg;
}
@@ -4659,7 +4657,6 @@ static void paging64_init_context(struct kvm_mmu *context)
static void paging32_init_context(struct kvm_mmu *context)
{
context->page_fault = paging32_page_fault;
- context->gva_to_gpa = paging32_gva_to_gpa;
context->sync_page = paging32_sync_page;
context->invlpg = paging32_invlpg;
}
@@ -4700,6 +4697,24 @@ kvm_calc_cpu_mode(struct kvm_vcpu *vcpu, const struct kvm_mmu_role_regs *regs)
return role;
}
+static void kvm_vcpu_init_walker(struct kvm_vcpu *vcpu,
+ struct kvm_mmu *mmu,
+ union kvm_mmu_paging_mode new_mode)
+{
+ if (new_mode.as_u64 == mmu->cpu_mode.as_u64)
+ return;
+
+ mmu->cpu_mode.as_u64 = new_mode.as_u64;
+ if (!is_cr0_pg(mmu))
+ mmu->gva_to_gpa = nonpaging_gva_to_gpa;
+ else if (is_cr4_pae(mmu))
+ mmu->gva_to_gpa = paging64_gva_to_gpa;
+ else
+ mmu->gva_to_gpa = paging32_gva_to_gpa;
+
+ reset_guest_paging_metadata(vcpu, mmu);
+}
+
static inline int kvm_mmu_get_tdp_level(struct kvm_vcpu *vcpu)
{
/* tdp_root_level is architecture forced level, use it if nonzero */
@@ -4735,36 +4750,17 @@ kvm_calc_tdp_mmu_root_page_role(struct kvm_vcpu *vcpu,
static void init_kvm_tdp_mmu(struct kvm_vcpu *vcpu, union kvm_mmu_paging_mode cpu_mode)
{
struct kvm_mmu *context = &vcpu->arch.root_mmu;
- union kvm_mmu_page_role root_role = kvm_calc_tdp_mmu_root_page_role(vcpu, cpu_mode);
- if (cpu_mode.as_u64 == context->cpu_mode.as_u64 &&
- root_role.word == context->root_role.word)
- return;
-
- context->cpu_mode.as_u64 = cpu_mode.as_u64;
- context->root_role.word = root_role.word;
-
- if (!is_cr0_pg(context))
- context->gva_to_gpa = nonpaging_gva_to_gpa;
- else if (is_cr4_pae(context))
- context->gva_to_gpa = paging64_gva_to_gpa;
- else
- context->gva_to_gpa = paging32_gva_to_gpa;
-
- reset_guest_paging_metadata(vcpu, context);
+ context->root_role = kvm_calc_tdp_mmu_root_page_role(vcpu, cpu_mode);
}
static void shadow_mmu_init_context(struct kvm_vcpu *vcpu, struct kvm_mmu *context,
- union kvm_mmu_paging_mode cpu_mode,
union kvm_mmu_page_role root_role)
{
- if (cpu_mode.as_u64 == context->cpu_mode.as_u64 &&
- root_role.word == context->root_role.word)
+ if (root_role.word == context->root_role.word)
return;
- context->cpu_mode.as_u64 = cpu_mode.as_u64;
context->root_role.word = root_role.word;
-
if (!is_cr0_pg(context))
nonpaging_init_context(context);
else if (is_cr4_pae(context))
@@ -4772,7 +4768,6 @@ static void shadow_mmu_init_context(struct kvm_vcpu *vcpu, struct kvm_mmu *conte
else
paging32_init_context(context);
- reset_guest_paging_metadata(vcpu, context);
reset_shadow_zero_bits_mask(vcpu, context);
}
@@ -4795,8 +4790,7 @@ static void init_kvm_softmmu(struct kvm_vcpu *vcpu,
* MMU contexts.
*/
root_role.efer_nx = true;
-
- shadow_mmu_init_context(vcpu, context, cpu_mode, root_role);
+ shadow_mmu_init_context(vcpu, context, root_role);
}
void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, unsigned long cr0,
@@ -4811,10 +4805,12 @@ void kvm_init_shadow_npt_mmu(struct kvm_vcpu *vcpu, unsigned long cr0,
union kvm_mmu_paging_mode cpu_mode = kvm_calc_cpu_mode(vcpu, ®s);
union kvm_mmu_page_role root_role;
+ kvm_vcpu_init_walker(vcpu, context, cpu_mode);
+
root_role = cpu_mode.base;
root_role.level = kvm_mmu_get_tdp_level(vcpu);
- shadow_mmu_init_context(vcpu, context, cpu_mode, root_role);
+ shadow_mmu_init_context(vcpu, context, root_role);
kvm_mmu_new_pgd(vcpu, nested_cr3);
}
EXPORT_SYMBOL_GPL(kvm_init_shadow_npt_mmu);
@@ -4873,43 +4869,16 @@ void kvm_init_shadow_ept_mmu(struct kvm_vcpu *vcpu, bool execonly,
}
EXPORT_SYMBOL_GPL(kvm_init_shadow_ept_mmu);
-static void init_kvm_nested_mmu(struct kvm_vcpu *vcpu, union kvm_mmu_paging_mode new_mode)
-{
- struct kvm_mmu *g_context = &vcpu->arch.nested_mmu;
-
- if (new_mode.as_u64 == g_context->cpu_mode.as_u64)
- return;
-
- g_context->cpu_mode.as_u64 = new_mode.as_u64;
-
- /*
- * Note that arch.mmu->gva_to_gpa translates l2_gpa to l1_gpa using
- * L1's nested page tables (e.g. EPT12). The nested translation
- * of l2_gva to l1_gpa is done by arch.nested_mmu.gva_to_gpa using
- * L2's page tables as the first level of translation and L1's
- * nested page tables as the second level of translation. Basically
- * the gva_to_gpa functions between mmu and nested_mmu are swapped.
- */
- if (!is_paging(vcpu))
- g_context->gva_to_gpa = nonpaging_gva_to_gpa;
- else if (is_long_mode(vcpu))
- g_context->gva_to_gpa = paging64_gva_to_gpa;
- else if (is_pae(vcpu))
- g_context->gva_to_gpa = paging64_gva_to_gpa;
- else
- g_context->gva_to_gpa = paging32_gva_to_gpa;
-
- reset_guest_paging_metadata(vcpu, g_context);
-}
-
void kvm_init_mmu(struct kvm_vcpu *vcpu)
{
struct kvm_mmu_role_regs regs = vcpu_to_role_regs(vcpu);
union kvm_mmu_paging_mode cpu_mode = kvm_calc_cpu_mode(vcpu, ®s);
+ kvm_vcpu_init_walker(vcpu, vcpu->arch.walk_mmu, cpu_mode);
if (mmu_is_nested(vcpu))
- init_kvm_nested_mmu(vcpu, cpu_mode);
- else if (tdp_enabled)
+ return;
+
+ if (tdp_enabled)
init_kvm_tdp_mmu(vcpu, cpu_mode);
else
init_kvm_softmmu(vcpu, cpu_mode);
--
2.31.1
next prev parent reply other threads:[~2022-02-21 16:24 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-21 16:22 [PATCH v2 00/25] KVM MMU refactoring part 2: role changes Paolo Bonzini
2022-02-21 16:22 ` [PATCH v2 01/25] KVM: x86/mmu: avoid indirect call for get_cr3 Paolo Bonzini
2022-03-08 16:16 ` Sean Christopherson
2022-03-08 16:21 ` Paolo Bonzini
2022-03-08 16:32 ` Sean Christopherson
2022-03-08 16:43 ` Paolo Bonzini
2022-03-08 16:53 ` Sean Christopherson
2022-03-08 17:14 ` Paolo Bonzini
2022-02-21 16:22 ` [PATCH v2 02/25] KVM: x86/mmu: nested EPT cannot be used in SMM Paolo Bonzini
2022-03-08 16:18 ` Sean Christopherson
2022-02-21 16:22 ` [PATCH v2 03/25] KVM: x86/mmu: constify uses of struct kvm_mmu_role_regs Paolo Bonzini
2022-03-08 16:22 ` Sean Christopherson
2022-02-21 16:22 ` [PATCH v2 04/25] KVM: x86/mmu: pull computation of kvm_mmu_role_regs to kvm_init_mmu Paolo Bonzini
2022-02-21 16:22 ` [PATCH v2 05/25] KVM: x86/mmu: rephrase unclear comment Paolo Bonzini
2022-03-08 16:39 ` Sean Christopherson
2022-02-21 16:22 ` [PATCH v2 06/25] KVM: nVMX/nSVM: do not monkey-patch inject_page_fault callback Paolo Bonzini
2022-03-08 17:13 ` Sean Christopherson
2022-03-08 20:34 ` Sean Christopherson
2022-02-21 16:22 ` [PATCH v2 07/25] KVM: x86/mmu: remove "bool base_only" arguments Paolo Bonzini
2022-03-08 17:15 ` Sean Christopherson
2022-02-21 16:22 ` [PATCH v2 08/25] KVM: x86/mmu: split cpu_mode from mmu_role Paolo Bonzini
2022-03-08 17:36 ` Sean Christopherson
2022-03-08 17:49 ` Paolo Bonzini
2022-03-08 18:55 ` Sean Christopherson
2022-03-09 9:58 ` Paolo Bonzini
2022-03-09 15:38 ` Sean Christopherson
2022-03-09 15:40 ` Paolo Bonzini
2022-02-21 16:22 ` [PATCH v2 09/25] KVM: x86/mmu: do not recompute root level from kvm_mmu_role_regs Paolo Bonzini
2022-03-08 17:41 ` Sean Christopherson
2022-02-21 16:22 ` [PATCH v2 10/25] KVM: x86/mmu: remove ept_ad field Paolo Bonzini
2022-03-08 17:42 ` Sean Christopherson
2022-02-21 16:22 ` [PATCH v2 11/25] KVM: x86/mmu: remove kvm_calc_shadow_root_page_role_common Paolo Bonzini
2022-03-08 17:48 ` Sean Christopherson
2022-03-08 17:50 ` Paolo Bonzini
2022-03-08 18:17 ` Sean Christopherson
2022-03-08 18:18 ` Paolo Bonzini
2022-02-21 16:22 ` [PATCH v2 12/25] KVM: x86/mmu: cleanup computation of MMU roles for two-dimensional paging Paolo Bonzini
2022-03-08 18:11 ` Sean Christopherson
2022-03-08 18:24 ` Paolo Bonzini
2022-03-08 18:44 ` Sean Christopherson
2022-03-08 18:38 ` Sean Christopherson
2022-02-21 16:22 ` [PATCH v2 13/25] KVM: x86/mmu: cleanup computation of MMU roles for shadow paging Paolo Bonzini
2022-02-21 16:22 ` [PATCH v2 14/25] KVM: x86/mmu: store shadow EFER.NX in the MMU role Paolo Bonzini
2022-02-21 16:22 ` [PATCH v2 15/25] KVM: x86/mmu: remove extended bits from mmu_role, rename field Paolo Bonzini
2022-03-08 19:02 ` Sean Christopherson
2022-02-21 16:22 ` [PATCH v2 16/25] KVM: x86/mmu: rename kvm_mmu_role union Paolo Bonzini
2022-03-08 19:15 ` Sean Christopherson
2022-02-21 16:22 ` [PATCH v2 17/25] KVM: x86/mmu: remove redundant bits from extended role Paolo Bonzini
2022-02-21 16:22 ` [PATCH v2 18/25] KVM: x86/mmu: remove valid " Paolo Bonzini
2022-02-21 16:22 ` [PATCH v2 19/25] KVM: x86/mmu: simplify and/or inline computation of shadow MMU roles Paolo Bonzini
2022-03-08 19:35 ` Sean Christopherson
2022-03-08 19:41 ` Sean Christopherson
2022-03-09 10:33 ` Paolo Bonzini
2022-02-21 16:22 ` [PATCH v2 20/25] KVM: x86/mmu: pull CPU mode computation to kvm_init_mmu Paolo Bonzini
2022-03-08 19:45 ` Sean Christopherson
2022-02-21 16:22 ` [PATCH v2 21/25] KVM: x86/mmu: replace shadow_root_level with root_role.level Paolo Bonzini
2022-03-08 19:48 ` Sean Christopherson
2022-02-21 16:22 ` [PATCH v2 22/25] KVM: x86/mmu: replace root_level with cpu_mode.base.level Paolo Bonzini
2022-03-08 19:49 ` Sean Christopherson
2022-02-21 16:22 ` [PATCH v2 23/25] KVM: x86/mmu: replace direct_map with root_role.direct Paolo Bonzini
2022-03-08 19:52 ` Sean Christopherson
2022-02-21 16:22 ` [PATCH v2 24/25] KVM: x86/mmu: initialize constant-value fields just once Paolo Bonzini
2022-03-08 20:58 ` Sean Christopherson
2022-03-09 10:34 ` Paolo Bonzini
2022-02-21 16:22 ` Paolo Bonzini [this message]
2022-03-08 20:02 ` [PATCH v2 25/25] KVM: x86/mmu: extract initialization of the page walking data Sean Christopherson
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=20220221162243.683208-26-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=dmatlack@google.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
all inboxes | Powered by JetHome®