From: David Matlack <dmatlack@google.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: Sean Christopherson <seanjc@google.com>,
Borislav Petkov <bp@suse.de>,
"Paul E. McKenney" <paulmck@kernel.org>,
Kees Cook <keescook@chromium.org>,
Peter Zijlstra <peterz@infradead.org>,
Andrew Morton <akpm@linux-foundation.org>,
Randy Dunlap <rdunlap@infradead.org>,
Damien Le Moal <damien.lemoal@opensource.wdc.com>,
kvm@vger.kernel.org, David Matlack <dmatlack@google.com>
Subject: [PATCH 5/9] KVM: x86/mmu: Separate TDP and non-paging fault handling
Date: Mon, 15 Aug 2022 16:01:06 -0700 [thread overview]
Message-ID: <20220815230110.2266741-6-dmatlack@google.com> (raw)
In-Reply-To: <20220815230110.2266741-1-dmatlack@google.com>
Separate the page fault handling for TDP faults and non-paging faults.
This creates some duplicate code in the short term, but makes each
routine simpler to read by eliminating branches and enables future
cleanups by allowing the two paths to diverge.
Signed-off-by: David Matlack <dmatlack@google.com>
---
arch/x86/kvm/mmu/mmu.c | 77 +++++++++++++++++++++++++++---------------
1 file changed, 50 insertions(+), 27 deletions(-)
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index 3e03407f1321..182f9f417e4e 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -4209,11 +4209,15 @@ static bool is_page_fault_stale(struct kvm_vcpu *vcpu,
mmu_notifier_retry_hva(vcpu->kvm, fault->mmu_seq, fault->hva);
}
-static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
+static int nonpaging_page_fault(struct kvm_vcpu *vcpu,
+ struct kvm_page_fault *fault)
{
- bool is_tdp_mmu_fault = is_tdp_mmu(vcpu->arch.mmu);
int r;
+ pgprintk("%s: gva %lx error %x\n", __func__, fault->addr, fault->error_code);
+
+ /* This path builds a PAE pagetable, we can map 2mb pages at maximum. */
+ fault->max_level = PG_LEVEL_2M;
fault->gfn = fault->addr >> PAGE_SHIFT;
fault->slot = kvm_vcpu_gfn_to_memslot(vcpu, fault->gfn);
@@ -4237,11 +4241,7 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
return r;
r = RET_PF_RETRY;
-
- if (is_tdp_mmu_fault)
- read_lock(&vcpu->kvm->mmu_lock);
- else
- write_lock(&vcpu->kvm->mmu_lock);
+ write_lock(&vcpu->kvm->mmu_lock);
if (is_page_fault_stale(vcpu, fault))
goto out_unlock;
@@ -4250,30 +4250,14 @@ static int direct_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
if (r)
goto out_unlock;
- if (is_tdp_mmu_fault)
- r = kvm_tdp_mmu_map(vcpu, fault);
- else
- r = nonpaging_map(vcpu, fault);
+ r = nonpaging_map(vcpu, fault);
out_unlock:
- if (is_tdp_mmu_fault)
- read_unlock(&vcpu->kvm->mmu_lock);
- else
- write_unlock(&vcpu->kvm->mmu_lock);
+ write_unlock(&vcpu->kvm->mmu_lock);
kvm_release_pfn_clean(fault->pfn);
return r;
}
-static int nonpaging_page_fault(struct kvm_vcpu *vcpu,
- struct kvm_page_fault *fault)
-{
- pgprintk("%s: gva %lx error %x\n", __func__, fault->addr, fault->error_code);
-
- /* This path builds a PAE pagetable, we can map 2mb pages at maximum. */
- fault->max_level = PG_LEVEL_2M;
- return direct_page_fault(vcpu, fault);
-}
-
int kvm_handle_page_fault(struct kvm_vcpu *vcpu, u64 error_code,
u64 fault_address, char *insn, int insn_len)
{
@@ -4309,6 +4293,11 @@ EXPORT_SYMBOL_GPL(kvm_handle_page_fault);
int kvm_tdp_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
{
+ int r;
+
+ fault->gfn = fault->addr >> PAGE_SHIFT;
+ fault->slot = kvm_vcpu_gfn_to_memslot(vcpu, fault->gfn);
+
/*
* If the guest's MTRRs may be used to compute the "real" memtype,
* restrict the mapping level to ensure KVM uses a consistent memtype
@@ -4324,14 +4313,48 @@ int kvm_tdp_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
if (shadow_memtype_mask && kvm_arch_has_noncoherent_dma(vcpu->kvm)) {
for ( ; fault->max_level > PG_LEVEL_4K; --fault->max_level) {
int page_num = KVM_PAGES_PER_HPAGE(fault->max_level);
- gfn_t base = (fault->addr >> PAGE_SHIFT) & ~(page_num - 1);
+ gfn_t base = fault->gfn & ~(page_num - 1);
if (kvm_mtrr_check_gfn_range_consistency(vcpu, base, page_num))
break;
}
}
- return direct_page_fault(vcpu, fault);
+ if (page_fault_handle_page_track(vcpu, fault))
+ return RET_PF_EMULATE;
+
+ r = fast_page_fault(vcpu, fault);
+ if (r != RET_PF_INVALID)
+ return r;
+
+ r = mmu_topup_memory_caches(vcpu, false);
+ if (r)
+ return r;
+
+ r = kvm_faultin_pfn(vcpu, fault);
+ if (r != RET_PF_CONTINUE)
+ return r;
+
+ r = handle_abnormal_pfn(vcpu, fault, ACC_ALL);
+ if (r != RET_PF_CONTINUE)
+ return r;
+
+ r = RET_PF_RETRY;
+ read_lock(&vcpu->kvm->mmu_lock);
+
+ if (is_page_fault_stale(vcpu, fault))
+ goto out_unlock;
+
+ r = make_mmu_pages_available(vcpu);
+ if (r)
+ goto out_unlock;
+
+ r = kvm_tdp_mmu_map(vcpu, fault);
+
+out_unlock:
+ read_unlock(&vcpu->kvm->mmu_lock);
+ kvm_release_pfn_clean(fault->pfn);
+ return r;
}
static void nonpaging_init_context(struct kvm_mmu *context)
--
2.37.1.595.g718a3a8f04-goog
next prev parent reply other threads:[~2022-08-16 2:39 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-15 23:01 [PATCH 0/9] KVM: x86/mmu: Always enable the TDP MMU when TDP is enabled David Matlack
2022-08-15 23:01 ` [PATCH 1/9] " David Matlack
2022-08-17 10:05 ` Paolo Bonzini
2022-08-17 16:49 ` David Matlack
2022-08-17 16:53 ` Paolo Bonzini
2022-08-17 17:46 ` David Matlack
2022-08-15 23:01 ` [PATCH 2/9] KVM: x86/mmu: Drop kvm->arch.tdp_mmu_enabled David Matlack
2022-08-24 14:21 ` kernel test robot
2022-08-15 23:01 ` [PATCH 3/9] KVM: x86/mmu: Consolidate mmu_seq calculations in kvm_faultin_pfn() David Matlack
2022-08-15 23:01 ` [PATCH 4/9] KVM: x86/mmu: Rename __direct_map() to nonpaging_map() David Matlack
2022-08-15 23:01 ` David Matlack [this message]
2022-08-24 17:06 ` [PATCH 5/9] KVM: x86/mmu: Separate TDP and non-paging fault handling kernel test robot
2022-08-15 23:01 ` [PATCH 6/9] KVM: x86/mmu: Stop needlessly making MMU pages available for TDP MMU faults David Matlack
2022-08-15 23:01 ` [PATCH 7/9] KVM: x86/mmu: Handle "error PFNs" in kvm_faultin_pfn() David Matlack
2022-08-15 23:01 ` [PATCH 8/9] KVM: x86/mmu: Avoid memslot lookup during KVM_PFN_ERR_HWPOISON handling David Matlack
2022-08-15 23:01 ` [PATCH 9/9] KVM: x86/mmu: Try to handle no-slot faults during kvm_faultin_pfn() David Matlack
2022-08-15 23:09 ` David Matlack
2022-08-16 8:16 ` [PATCH 0/9] KVM: x86/mmu: Always enable the TDP MMU when TDP is enabled Peter Zijlstra
2022-08-16 16:30 ` David Matlack
2022-08-17 8:53 ` Peter Zijlstra
2022-08-17 10:01 ` Huang, Kai
2022-08-17 16:42 ` David Matlack
2022-08-17 23:36 ` Huang, Kai
2022-08-16 22:54 ` David Matlack
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=20220815230110.2266741-6-dmatlack@google.com \
--to=dmatlack@google.com \
--cc=akpm@linux-foundation.org \
--cc=bp@suse.de \
--cc=damien.lemoal@opensource.wdc.com \
--cc=keescook@chromium.org \
--cc=kvm@vger.kernel.org \
--cc=paulmck@kernel.org \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=rdunlap@infradead.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