From: Sean Christopherson <seanjc@google.com>
To: Sean Christopherson <seanjc@google.com>,
Paolo Bonzini <pbonzini@redhat.com>
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
"Hyunwoo Kim" <imv4bel@gmail.com>,
"Tom Lendacky" <thomas.lendacky@amd.com>,
"Michael Roth" <michael.roth@amd.com>,
"Jörg Rödel" <joro@8bytes.org>, "Fuad Tabba" <tabba@google.com>,
"Ackerley Tng" <ackerleytng@google.com>
Subject: [PATCH v2 4/9] KVM: Rework .gmem_invalidate() into .gmem_free_folio()
Date: Fri, 26 Jun 2026 16:14:11 -0700 [thread overview]
Message-ID: <20260626231416.3943216-5-seanjc@google.com> (raw)
In-Reply-To: <20260626231416.3943216-1-seanjc@google.com>
Rename .gmem_invalidate() to .gmem_free_folio() as the hook is called when
a folio is freed, which is far too late and lack sufficient information for
KVM to actually invalidate its usage of the memory. Drop guest_memfd's
trampoline and just wire up .free_folio() directly to the arch callback so
that the chain of events is clear and obvious.
Opportunistically guard kvm_x86_ops.gmem_free_folio with an ifdef to
ensure the callback will actually be called, e.g. so that non-SEV code
doesn't try to wire up a callback without enabling
CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE.
No functional change intended.
Cc: stable@vger.kernel.org # 6.12.x
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
arch/x86/include/asm/kvm-x86-ops.h | 4 +++-
arch/x86/include/asm/kvm_host.h | 4 +++-
arch/x86/kvm/svm/sev.c | 4 +++-
arch/x86/kvm/svm/svm.c | 4 +++-
arch/x86/kvm/svm/svm.h | 3 +--
arch/x86/kvm/x86.c | 4 ++--
include/linux/kvm_host.h | 2 +-
virt/kvm/guest_memfd.c | 13 +------------
8 files changed, 17 insertions(+), 21 deletions(-)
diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h
index 83dc5086138b..e36eba952705 100644
--- a/arch/x86/include/asm/kvm-x86-ops.h
+++ b/arch/x86/include/asm/kvm-x86-ops.h
@@ -147,7 +147,9 @@ KVM_X86_OP_OPTIONAL(get_untagged_addr)
KVM_X86_OP_OPTIONAL(alloc_apic_backing_page)
KVM_X86_OP_OPTIONAL_RET0(gmem_prepare)
KVM_X86_OP_OPTIONAL_RET0(gmem_max_mapping_level)
-KVM_X86_OP_OPTIONAL(gmem_invalidate)
+#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE
+KVM_X86_OP_OPTIONAL(gmem_free_folio)
+#endif
#endif
#undef KVM_X86_OP
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index b517257a6315..dd542c7a7376 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1901,7 +1901,9 @@ struct kvm_x86_ops {
gva_t (*get_untagged_addr)(struct kvm_vcpu *vcpu, gva_t gva, unsigned int flags);
void *(*alloc_apic_backing_page)(struct kvm_vcpu *vcpu);
int (*gmem_prepare)(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, int max_order);
- void (*gmem_invalidate)(kvm_pfn_t start, kvm_pfn_t end);
+#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE
+ void (*gmem_free_folio)(struct folio *folio);
+#endif
int (*gmem_max_mapping_level)(struct kvm *kvm, kvm_pfn_t pfn, bool is_private);
};
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 30792adcfc8e..3d90aa723dc2 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -5136,8 +5136,10 @@ int sev_gmem_prepare(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, int max_order)
return 0;
}
-void sev_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end)
+void sev_gmem_free_folio(struct folio *folio)
{
+ kvm_pfn_t start = page_to_pfn(folio_page(folio, 0));
+ kvm_pfn_t end = start + (1ul << folio_order(folio));
kvm_pfn_t pfn;
if (!cc_platform_has(CC_ATTR_HOST_SEV_SNP))
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index ef69a51ab27f..6f1823e820a4 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -5460,9 +5460,11 @@ struct kvm_x86_ops svm_x86_ops __initdata = {
.vcpu_get_apicv_inhibit_reasons = avic_vcpu_get_apicv_inhibit_reasons,
.alloc_apic_backing_page = svm_alloc_apic_backing_page,
+#ifdef CONFIG_KVM_AMD_SEV
.gmem_prepare = sev_gmem_prepare,
- .gmem_invalidate = sev_gmem_invalidate,
+ .gmem_free_folio = sev_gmem_free_folio,
.gmem_max_mapping_level = sev_gmem_max_mapping_level,
+#endif
};
/*
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index d077783c287e..2f8215810a08 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -1009,7 +1009,7 @@ int sev_dev_get_attr(u32 group, u64 attr, u64 *val);
extern unsigned int max_sev_asid;
void sev_handle_rmp_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u64 error_code);
int sev_gmem_prepare(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, int max_order);
-void sev_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end);
+void sev_gmem_free_folio(struct folio *folio);
int sev_gmem_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn, bool is_private);
struct vmcb_save_area *sev_decrypt_vmsa(struct kvm_vcpu *vcpu);
void sev_free_decrypted_vmsa(struct kvm_vcpu *vcpu, struct vmcb_save_area *vmsa);
@@ -1039,7 +1039,6 @@ static inline int sev_gmem_prepare(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, in
{
return 0;
}
-static inline void sev_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end) {}
static inline int sev_gmem_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn, bool is_private)
{
return 0;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 0626e835e9eb..adc1e1b244c7 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -10592,9 +10592,9 @@ int kvm_arch_gmem_prepare(struct kvm *kvm, gfn_t gfn, kvm_pfn_t pfn, int max_ord
#endif
#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE
-void kvm_arch_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end)
+void kvm_arch_gmem_free_folio(struct folio *folio)
{
- kvm_x86_call(gmem_invalidate)(start, end);
+ kvm_x86_call(gmem_free_folio)(folio);
}
#endif
#endif
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index ab8cfaec82d3..e5b47a5e4cea 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -2607,7 +2607,7 @@ long kvm_gmem_populate(struct kvm *kvm, gfn_t start_gfn, void __user *src,
#endif
#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE
-void kvm_arch_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end);
+void kvm_arch_gmem_free_folio(struct folio *folio);
#endif
#ifdef CONFIG_KVM_GENERIC_PRE_FAULT_MEMORY
diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c
index 86690683b2fe..1618acc3ca64 100644
--- a/virt/kvm/guest_memfd.c
+++ b/virt/kvm/guest_memfd.c
@@ -523,23 +523,12 @@ static int kvm_gmem_error_folio(struct address_space *mapping, struct folio *fol
return MF_DELAYED;
}
-#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE
-static void kvm_gmem_free_folio(struct folio *folio)
-{
- struct page *page = folio_page(folio, 0);
- kvm_pfn_t pfn = page_to_pfn(page);
- int order = folio_order(folio);
-
- kvm_arch_gmem_invalidate(pfn, pfn + (1ul << order));
-}
-#endif
-
static const struct address_space_operations kvm_gmem_aops = {
.dirty_folio = noop_dirty_folio,
.migrate_folio = kvm_gmem_migrate_folio,
.error_remove_folio = kvm_gmem_error_folio,
#ifdef CONFIG_HAVE_KVM_ARCH_GMEM_INVALIDATE
- .free_folio = kvm_gmem_free_folio,
+ .free_folio = kvm_arch_gmem_free_folio,
#endif
};
--
2.55.0.rc0.799.gd6f94ed593-goog
next prev parent reply other threads:[~2026-06-26 23:14 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-26 23:14 [PATCH v2 0/9] KVM: SEV: Fix RMP #PF due freeing in-use VMSA Sean Christopherson
2026-06-26 23:14 ` [PATCH v2 1/9] KVM: SEV: Track the GPA of the guest-controlled VMSA used for SNP guests Sean Christopherson
2026-06-26 23:14 ` [PATCH v2 2/9] KVM: SEV: Extract loading of guest-provided VMSA to a separate helper Sean Christopherson
2026-06-26 23:14 ` [PATCH v2 3/9] KVM: SEV: Mark vCPU RUNNABLE after AP_CREATE, even if VMSA is unusable Sean Christopherson
2026-06-26 23:14 ` Sean Christopherson [this message]
2026-06-29 21:50 ` [PATCH v2 4/9] KVM: Rework .gmem_invalidate() into .gmem_free_folio() Ackerley Tng
2026-06-29 22:02 ` Sean Christopherson
2026-06-30 0:09 ` Ackerley Tng
2026-06-30 0:18 ` Sean Christopherson
2026-06-26 23:14 ` [PATCH v2 5/9] KVM: x86/mmu: Fold kvm_mmu_zap_memslot() into kvm_arch_flush_shadow_memslot() Sean Christopherson
2026-06-26 23:14 ` [PATCH v2 6/9] KVM: x86/mmu: Split kvm_mmu_zap_all_fast() into "front" and "back" halves Sean Christopherson
2026-06-26 23:29 ` sashiko-bot
2026-06-26 23:14 ` [PATCH v2 7/9] KVM: SEV: Forcefully invalidate SNP VMSA if its backing gmem page is zapped Sean Christopherson
2026-06-26 23:39 ` sashiko-bot
2026-06-29 21:59 ` Ackerley Tng
2026-06-29 23:49 ` Sean Christopherson
2026-06-26 23:14 ` [PATCH v2 8/9] KVM: x86: Guard .gmem_prepare() declarations with HAVE_KVM_GMEM_PREPARE=y Sean Christopherson
2026-06-26 23:14 ` [PATCH v2 9/9] KVM: SEV: Mark vCPU has having guest-provided VMSA even if its invalid 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=20260626231416.3943216-5-seanjc@google.com \
--to=seanjc@google.com \
--cc=ackerleytng@google.com \
--cc=imv4bel@gmail.com \
--cc=joro@8bytes.org \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=michael.roth@amd.com \
--cc=pbonzini@redhat.com \
--cc=tabba@google.com \
--cc=thomas.lendacky@amd.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.