On Thu, Aug 13, 2026 at 04:20:05PM -0700, Sean Christopherson wrote:
> On Thu, Aug 13, 2026, Rick P Edgecombe wrote:
> > On Thu, 2026-08-13 at 11:51 -0700, Ackerley Tng wrote:
> > > "Edgecombe, Rick P" <[email protected]> writes:
> > >
> > > > On Tue, 2026-08-11 at 10:35 -0700, Ackerley Tng wrote:
> > > > > > > Would like to see what Sean thinks of this. Either way, is it
> > > > > > > okay to
> > > > > > > follow up after conversions lands?
> > > > > > Let's see what Sean thinks of this :)
> > > > > > I raised this because the issue was encountered by one TDX's stress
> > > > > > selftest.
> > > > >
> > > > > Which stress selftest is this? I can try running this on my side too.
> > > >
> > > > We have some selftests that are built on the basic TDX selftests. One
> > > > just
> > > > hammers the MMU stuff with a bunch of zaps and also weird stuff from
> > > > the guest.
> > > > It was eventually too much work to try to keep the internal
> > > > enhancements rebased
> > >
> > > Would like all the comments we can get on TDX selftests v14 [1]!
> >
> > I think we had a few. Let me try to round up some more folks.
> >
> > >
> > > > nicely so we actually just run an old branch's TDX selftests against
> > > > newer
> > > > kernels. So the branch is a bit of a pile, and not really suitable for
> > > > sharing.
> > > > We plan to clean it and upstream it when the path clears. So it would
> > > > really
> > > > help to get those basic ones upstream. We remain happy to help, so
> > > > please let us
> > > > know.
> > >
> > > I guess at this point I'm hoping y'all and Sean are okay that this
> > > conversions series merges, and we let this stress test failure be
> > > handled later. I'll be around to fix things :)
> > >
> > > I'd say the line of sight to fixing this would be when the KVM MMU only
> > > gets PFNs (and no pages at all) from guest_memfd.
> >
> > Hmm, I think we shouldn't upstream a uABI that we don't have line of sight
> > to
> > making robust. So it would be good to settle this thread at least.
>
> This isn't uABI. You're talking about hitting a race condition between one
> task
Hmm. Perhaps it is not a uABI issue, since users are allowed to retry. However,
it is hard to convince me that it makes sense to require users to retry a
private-to-shared conversion before a GFN has ever been mapped, given that a
retry is not required when the GFN is currently in use by the guest.
> converting a page and another faulting in the same page. An NMI, SMI, or IRQ
> at
> just the right/wrong time, especially on a preemptible kernel, could lead to
> the
> same test failures, even if KVM drops the refcount "immediately".
Could you elaborate on how an NMI, SMI, or IRQ at just the right/wrong time
could lead to the same test failures?
Do you mean they can cause a fault to be retried? Our test failure is an EAGAIN
returned from a private-to-shared conversion before the page has even been
mapped as private.
> That said, I am 100% in favor of not handing the caller a struct page. Now
> that
> the TDX APIs no longer require one, it's more than feasible. But, we
> absolutely
> shouldn't just nullify the pointer, we should drop the param entirely. Not
> just
> because it's cleaner, but because it also forces an audit of the callers to
> see
> if they subtly require a refcount (spoiler alert).
Yeah, I also considered dropping the param entirely and was terrified by the
lines of changes :)
If you are in favor of not handing the caller a struct page, the following
changes should also be required on top of your change.
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 8ef16ccf26ce..d5aa197d2cbf 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1613,7 +1613,6 @@ static int gmem_abort(const struct kvm_s2_fault_desc
*s2fd)
enum kvm_pgtable_prot prot = KVM_PGTABLE_PROT_R;
struct kvm_pgtable *pgt = s2fd->vcpu->arch.hw_mmu->pgt;
unsigned long mmu_seq;
- struct page *page;
struct kvm *kvm = s2fd->vcpu->kvm;
void *memcache = NULL;
kvm_pfn_t pfn;
@@ -1681,7 +1680,6 @@ static int gmem_abort(const struct kvm_s2_fault_desc
*s2fd)
}
out_unlock:
- kvm_release_faultin_page(kvm, page, !!ret, prot & KVM_PGTABLE_PROT_W);
kvm_fault_unlock(kvm);
if ((prot & KVM_PGTABLE_PROT_W) && !ret)
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index c982a6454fc9..43523bb17621 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -1360,7 +1360,7 @@ static int kvm_translate_vncr(struct kvm_vcpu *vcpu, bool
*is_gmem)
bool write_fault, writable;
unsigned long mmu_seq;
struct vncr_tlb *vt;
- struct page *page;
+ struct page *page = NULL;
u64 va, pfn, gfn;
int ret;
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 3d3eb8387cd0..c5ba2c8cad74 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -4017,7 +4017,6 @@ static void __sev_snp_reload_vmsa(struct kvm_vcpu *vcpu,
gpa_t gpa)
struct kvm *kvm = vcpu->kvm;
gfn_t gfn = gpa_to_gfn(gpa);
unsigned long mmu_seq;
- struct page *page;
kvm_pfn_t pfn;
lockdep_assert_held(&svm->sev_es.snp_vmsa_mutex);
@@ -4077,8 +4076,6 @@ static void __sev_snp_reload_vmsa(struct kvm_vcpu *vcpu,
gpa_t gpa)
else
svm->vmcb->control.vmsa_pa = pfn_to_hpa(pfn);
read_unlock(&kvm->mmu_lock);
-
- kvm_release_page_clean(page);
}
/*
> The lone holdout at this point is sev_handle_rmp_fault(), which could end up
> PSMASH-ing a PFN that has since been freed by KVM. Assuming holding mmu_lock
> while doing RMP operations is ok, something like the below? Completely
> untested.
Tested successfully after applying the above fix and the typo correction.
@@ -5073,7 +5070,7 @@ void sev_handle_rmp_fault(struct kvm_vcpu *vcpu, gpa_t
gpa, u64 error_code)
if (rmp_level == PG_LEVEL_4K)
goto out;
- scoped_guard(read_lock)(&kvm->mmu_lock) {
+ scoped_guard(read_lock, &kvm->mmu_lock) {
if (mmu_invalidate_retry_gfn(kvm, mmu_seq, gfn))
goto out;
> As for in-place conversion, this is not a blocker.
Sorry. I didn't intend to block in-place conversion.
I encountered this issue during testing, so reported it.