[PATCH 16/24] KVM: pfncache: Fail to refresh if it contains memory protections

From: Paolo Bonzini

Date: Thu Jul 16 2026 - 14:20:17 EST


From: Nicolas Saenz Julienne <nsaenz@xxxxxxxxxx>

Track the memory attributes generation as part of pfncache's data,
invalidate the cached information if the generation changes, and fail to
refresh the cache if restrictive memory attributes are found within the
GPA range.

Similar to how pfncache disallows caching gfns mapped within read-only
memory slots, gfns marked as read-only by memory attributes will also
fail to initialize. Unsurprisingly, the same behaviour applies to gfns
mapped as non-accessible (NR/NW), while non-executable mappings are fine.

Signed-off-by: Nicolas Saenz Julienne <nsaenz@xxxxxxxxxx>
Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
virt/kvm/pfncache.c | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/virt/kvm/pfncache.c b/virt/kvm/pfncache.c
index 46ffae69fe77..39935740136d 100644
--- a/virt/kvm/pfncache.c
+++ b/virt/kvm/pfncache.c
@@ -298,7 +298,18 @@ static int __kvm_gpc_refresh(struct gfn_to_pfn_cache *gpc, gpa_t gpa, unsigned l
gpc->gpa != gpa || kvm_is_error_hva(gpc->uhva)) {
gfn_t gfn = gpa_to_gfn(gpa);

+ /*
+ * RW memory attributes are incompatible with GPC. The
+ * RW protection check has to happen after storing the
+ * generation number.
+ */
gpc->attrs_generation = kvm_mem_attributes_generation(kvm);
+ if (kvm_range_has_rw_memory_protections(kvm, gfn, gfn + 1)) {
+ gpc->uhva = KVM_HVA_ERR_BAD;
+ ret = -EFAULT;
+ goto out;
+ }
+
gpc->gpa = gpa;
gpc->slots_generation = slots->generation;
gpc->memslot = __gfn_to_memslot(slots, gfn);
--
2.52.0