[PATCH 12/31] KVM: adjust for presence of more than one attribute
From: Paolo Bonzini
Date: Fri Sep 18 2026 - 10:02:37 EST
Remove or adjust code that assumed that the only valid attribute was
KVM_MEMORY_ATTRIBUTE_PRIVATE, in preparation for the introduction of RWX
memory attributes.
In particular, the optimization in kvm_range_has_memory_attributes
simply is not valid if attrs == 0 but some of the attributes are being
ignored. The WARNs in arch/x86/kvm/mmu/mmu.c are just a duplicate of
checking kvm_supported_mem_attributes() during the ioctl, so drop it.
Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
arch/x86/kvm/mmu/mmu.c | 9 +--------
virt/kvm/kvm_main.c | 6 ++++--
2 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index ba462c671f7d..77d9c62d2a07 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -8140,9 +8140,6 @@ bool kvm_arch_pre_set_memory_attributes(struct kvm *kvm,
* Zapping SPTEs in this case ensures KVM will reassess whether or not
* a hugepage can be used for affected ranges.
*/
- if (WARN_ON_ONCE(!kvm_arch_has_private_mem(kvm)))
- return false;
-
if (WARN_ON_ONCE(range->end <= range->start))
return false;
@@ -8218,11 +8215,7 @@ bool kvm_arch_post_set_memory_attributes(struct kvm *kvm,
* can't map memory PRIVATE. KVM mustn't create a SHARED hugepage over
* a range that has PRIVATE GFNs, and conversely converting a range to
* SHARED may now allow hugepages.
- */
- if (WARN_ON_ONCE(!kvm_arch_has_private_mem(kvm)))
- return false;
-
- /*
+ *
* The sequence matters here: upper levels consume the result of lower
* level's scanning.
*/
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 9d1836382d19..85fdd33c51ab 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2436,10 +2436,12 @@ bool kvm_range_has_memory_attributes(struct kvm *kvm, gfn_t start, gfn_t end,
unsigned long mask, unsigned long attrs)
{
XA_STATE(xas, &kvm->mem_attr_array, start);
+ unsigned long supported_attrs;
unsigned long index;
void *entry;
- mask &= kvm_supported_mem_attributes(kvm);
+ supported_attrs = kvm_supported_mem_attributes(kvm);
+ mask &= supported_attrs;
if (attrs & ~mask)
return false;
@@ -2447,7 +2449,7 @@ bool kvm_range_has_memory_attributes(struct kvm *kvm, gfn_t start, gfn_t end,
return (kvm_get_memory_attributes(kvm, start) & mask) == attrs;
guard(rcu)();
- if (!attrs)
+ if (!attrs && mask == supported_attrs)
return !xas_find(&xas, end - 1);
for (index = start; index < end; index++) {
--
2.52.0