* [PATCH 1/3] KVM: x86/mmu: Decrease indentation in logic to sync new indirect shadow page
2024-08-02 20:38 [PATCH 0/3] KVM: x86/mmu: Misc shadow paging cleanups Sean Christopherson
@ 2024-08-02 20:38 ` Sean Christopherson
2024-08-02 20:38 ` [PATCH 2/3] KVM: x86/mmu: Drop pointless "return" wrapper label in FNAME(fetch) Sean Christopherson
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Sean Christopherson @ 2024-08-02 20:38 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel
Combine the back-to-back if-statements for synchronizing children when
linking a new indirect shadow page in order to decrease the indentation,
and to make it easier to "see" the logic in its entirety.
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/mmu/paging_tmpl.h | 40 ++++++++++++++++------------------
1 file changed, 19 insertions(+), 21 deletions(-)
diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h
index 69941cebb3a8..0e97e080a997 100644
--- a/arch/x86/kvm/mmu/paging_tmpl.h
+++ b/arch/x86/kvm/mmu/paging_tmpl.h
@@ -674,27 +674,25 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault,
sp = kvm_mmu_get_child_sp(vcpu, it.sptep, table_gfn,
false, access);
- if (sp != ERR_PTR(-EEXIST)) {
- /*
- * We must synchronize the pagetable before linking it
- * because the guest doesn't need to flush tlb when
- * the gpte is changed from non-present to present.
- * Otherwise, the guest may use the wrong mapping.
- *
- * For PG_LEVEL_4K, kvm_mmu_get_page() has already
- * synchronized it transiently via kvm_sync_page().
- *
- * For higher level pagetable, we synchronize it via
- * the slower mmu_sync_children(). If it needs to
- * break, some progress has been made; return
- * RET_PF_RETRY and retry on the next #PF.
- * KVM_REQ_MMU_SYNC is not necessary but it
- * expedites the process.
- */
- if (sp->unsync_children &&
- mmu_sync_children(vcpu, sp, false))
- return RET_PF_RETRY;
- }
+ /*
+ * Synchronize the new page before linking it, as the CPU (KVM)
+ * is architecturally disallowed from inserting non-present
+ * entries into the TLB, i.e. the guest isn't required to flush
+ * the TLB when changing the gPTE from non-present to present.
+ *
+ * For PG_LEVEL_4K, kvm_mmu_find_shadow_page() has already
+ * synchronized the page via kvm_sync_page().
+ *
+ * For higher level pages, which cannot be unsync themselves
+ * but can have unsync children, synchronize via the slower
+ * mmu_sync_children(). If KVM needs to drop mmu_lock due to
+ * contention or to reschedule, instruct the caller to retry
+ * the #PF (mmu_sync_children() ensures forward progress will
+ * be made).
+ */
+ if (sp != ERR_PTR(-EEXIST) && sp->unsync_children &&
+ mmu_sync_children(vcpu, sp, false))
+ return RET_PF_RETRY;
/*
* Verify that the gpte in the page we've just write
--
2.46.0.rc2.264.g509ed76dc8-goog
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 2/3] KVM: x86/mmu: Drop pointless "return" wrapper label in FNAME(fetch)
2024-08-02 20:38 [PATCH 0/3] KVM: x86/mmu: Misc shadow paging cleanups Sean Christopherson
2024-08-02 20:38 ` [PATCH 1/3] KVM: x86/mmu: Decrease indentation in logic to sync new indirect shadow page Sean Christopherson
@ 2024-08-02 20:38 ` Sean Christopherson
2024-08-02 20:39 ` [PATCH 3/3] KVM: x86/mmu: Reword a misleading comment about checking gpte_changed() Sean Christopherson
2024-08-31 0:20 ` [PATCH 0/3] KVM: x86/mmu: Misc shadow paging cleanups Sean Christopherson
3 siblings, 0 replies; 5+ messages in thread
From: Sean Christopherson @ 2024-08-02 20:38 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel
Drop the pointless and poorly named "out_gpte_changed" label, in
FNAME(fetch), and instead return RET_PF_RETRY directly.
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/mmu/paging_tmpl.h | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h
index 0e97e080a997..480c54122991 100644
--- a/arch/x86/kvm/mmu/paging_tmpl.h
+++ b/arch/x86/kvm/mmu/paging_tmpl.h
@@ -646,10 +646,10 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault,
* really care if it changes underneath us after this point).
*/
if (FNAME(gpte_changed)(vcpu, gw, top_level))
- goto out_gpte_changed;
+ return RET_PF_RETRY;
if (WARN_ON_ONCE(!VALID_PAGE(vcpu->arch.mmu->root.hpa)))
- goto out_gpte_changed;
+ return RET_PF_RETRY;
/*
* Load a new root and retry the faulting instruction in the extremely
@@ -659,7 +659,7 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault,
*/
if (unlikely(kvm_mmu_is_dummy_root(vcpu->arch.mmu->root.hpa))) {
kvm_make_request(KVM_REQ_MMU_FREE_OBSOLETE_ROOTS, vcpu);
- goto out_gpte_changed;
+ return RET_PF_RETRY;
}
for_each_shadow_entry(vcpu, fault->addr, it) {
@@ -699,7 +699,7 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault,
* protected is still there.
*/
if (FNAME(gpte_changed)(vcpu, gw, it.level - 1))
- goto out_gpte_changed;
+ return RET_PF_RETRY;
if (sp != ERR_PTR(-EEXIST))
link_shadow_page(vcpu, it.sptep, sp);
@@ -753,9 +753,6 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault,
FNAME(pte_prefetch)(vcpu, gw, it.sptep);
return ret;
-
-out_gpte_changed:
- return RET_PF_RETRY;
}
/*
--
2.46.0.rc2.264.g509ed76dc8-goog
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 3/3] KVM: x86/mmu: Reword a misleading comment about checking gpte_changed()
2024-08-02 20:38 [PATCH 0/3] KVM: x86/mmu: Misc shadow paging cleanups Sean Christopherson
2024-08-02 20:38 ` [PATCH 1/3] KVM: x86/mmu: Decrease indentation in logic to sync new indirect shadow page Sean Christopherson
2024-08-02 20:38 ` [PATCH 2/3] KVM: x86/mmu: Drop pointless "return" wrapper label in FNAME(fetch) Sean Christopherson
@ 2024-08-02 20:39 ` Sean Christopherson
2024-08-31 0:20 ` [PATCH 0/3] KVM: x86/mmu: Misc shadow paging cleanups Sean Christopherson
3 siblings, 0 replies; 5+ messages in thread
From: Sean Christopherson @ 2024-08-02 20:39 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel
Rewrite the comment in FNAME(fetch) to explain why KVM needs to check that
the gPTE is still fresh before continuing the shadow page walk, even if
KVM already has a linked shadow page for the gPTE in question.
No functional change intended.
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/kvm/mmu/paging_tmpl.h | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/mmu/paging_tmpl.h b/arch/x86/kvm/mmu/paging_tmpl.h
index 480c54122991..405bd7ceee2a 100644
--- a/arch/x86/kvm/mmu/paging_tmpl.h
+++ b/arch/x86/kvm/mmu/paging_tmpl.h
@@ -695,8 +695,14 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault,
return RET_PF_RETRY;
/*
- * Verify that the gpte in the page we've just write
- * protected is still there.
+ * Verify that the gpte in the page, which is now either
+ * write-protected or unsync, wasn't modified between the fault
+ * and acquiring mmu_lock. This needs to be done even when
+ * reusing an existing shadow page to ensure the information
+ * gathered by the walker matches the information stored in the
+ * shadow page (which could have been modified by a different
+ * vCPU even if the page was already linked). Holding mmu_lock
+ * prevents the shadow page from changing after this point.
*/
if (FNAME(gpte_changed)(vcpu, gw, it.level - 1))
return RET_PF_RETRY;
--
2.46.0.rc2.264.g509ed76dc8-goog
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 0/3] KVM: x86/mmu: Misc shadow paging cleanups
2024-08-02 20:38 [PATCH 0/3] KVM: x86/mmu: Misc shadow paging cleanups Sean Christopherson
` (2 preceding siblings ...)
2024-08-02 20:39 ` [PATCH 3/3] KVM: x86/mmu: Reword a misleading comment about checking gpte_changed() Sean Christopherson
@ 2024-08-31 0:20 ` Sean Christopherson
3 siblings, 0 replies; 5+ messages in thread
From: Sean Christopherson @ 2024-08-31 0:20 UTC (permalink / raw)
To: Sean Christopherson, Paolo Bonzini; +Cc: kvm, linux-kernel
On Fri, 02 Aug 2024 13:38:57 -0700, Sean Christopherson wrote:
> A handful of loosely related shadow paging cleanups I unearthed. I believe
> I wrote them when reviewing eager page splitting?
>
> Sean Christopherson (3):
> KVM: x86/mmu: Decrease indentation in logic to sync new indirect
> shadow page
> KVM: x86/mmu: Drop pointless "return" wrapper label in FNAME(fetch)
> KVM: x86/mmu: Reword a misleading comment about checking
> gpte_changed()
>
> [...]
Applied to kvm-x86 mmu, thanks!
[1/3] KVM: x86/mmu: Decrease indentation in logic to sync new indirect shadow page
https://github.com/kvm-x86/linux/commit/174b6e4a25ea
[2/3] KVM: x86/mmu: Drop pointless "return" wrapper label in FNAME(fetch)
https://github.com/kvm-x86/linux/commit/7d67b03e6fff
[3/3] KVM: x86/mmu: Reword a misleading comment about checking gpte_changed()
https://github.com/kvm-x86/linux/commit/1dc9cc1c4c23
--
https://github.com/kvm-x86/linux/tree/next
^ permalink raw reply [flat|nested] 5+ messages in thread