[PATCH RFC v4 38/44] KVM: selftests: Provide common function to set memory attributes

Ackerley Tng
2026-03-26T22:25:56Z

From: Sean Christopherson <seanjc@google.com>

Introduce vm_mem_set_memory_attributes(), which handles setting of memory
attributes for a range of guest physical addresses, regardless of whether
the attributes should be set via guest_memfd or via the memory attributes
at the VM level.

Refactor existing vm_mem_set_{shared,private} functions to use the new
function.

Update existing caller of vm_mem_set_private().

Signed-off-by: Sean Christopherson <seanjc@google.com>
Co-developed-by: Ackerley Tng <ackerleytng@google.com>
Signed-off-by: Ackerley Tng <ackerleytng@google.com>
---
tools/testing/selftests/kvm/guest_memfd_test.c | 2 +-
tools/testing/selftests/kvm/include/kvm_util.h | 47 ++++++++++++++++------
tools/testing/selftests/kvm/lib/x86/sev.c | 2 +-
.../testing/selftests/kvm/pre_fault_memory_test.c | 2 +-
.../selftests/kvm/x86/private_mem_kvm_exits_test.c | 4 +-
5 files changed, 40 insertions(+), 17 deletions(-)

diff --git a/tools/testing/selftests/kvm/guest_memfd_test.c b/tools/testing/selftests/kvm/guest_memfd_test.c
index 10b57fd4fa9ba..ff8c0c56399dd 100644
--- a/tools/testing/selftests/kvm/guest_memfd_test.c
+++ b/tools/testing/selftests/kvm/guest_memfd_test.c
@@ -506,7 +506,7 @@ static void test_guest_private_mem(void)
fd, 0, 0);

virt_map(vm, gpa, gpa, npages);
- vm_mem_set_private(vm, gpa, page_size);
+ vm_mem_set_private(vm, gpa, page_size, 0);

vcpu_args_set(vcpu, 1, gpa);
vcpu_run(vcpu);
diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h
index 3434f3df028b0..d975cc3047a2d 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -456,18 +456,6 @@ static inline void vm_set_memory_attributes(struct kvm_vm *vm, uint64_t gpa,
vm_ioctl(vm, KVM_SET_MEMORY_ATTRIBUTES2, &attr);
}

-static inline void vm_mem_set_private(struct kvm_vm *vm, uint64_t gpa,
- uint64_t size)
-{
- vm_set_memory_attributes(vm, gpa, size, KVM_MEMORY_ATTRIBUTE_PRIVATE);
-}
-
-static inline void vm_mem_set_shared(struct kvm_vm *vm, uint64_t gpa,
- uint64_t size)
-{
- vm_set_memory_attributes(vm, gpa, size, 0);
-}
-
static inline int __gmem_set_memory_attributes(int fd, loff_t offset,
uint64_t size,
uint64_t attributes,
@@ -536,6 +524,41 @@ static inline void gmem_set_shared(int fd, loff_t offset, uint64_t size, u64 fla
gmem_set_memory_attributes(fd, offset, size, 0, flags);
}

+static inline void vm_mem_set_memory_attributes(struct kvm_vm *vm, uint64_t gpa,
+ uint64_t size, uint64_t attrs,
+ u64 flags)
+{
+ if (kvm_has_gmem_attributes) {
+ uint64_t end = gpa + size;
+ uint64_t addr, len;
+ off_t fd_offset;
+ int fd;
+
+ for (addr = gpa; addr < end; addr += len) {
+ fd = kvm_gpa_to_guest_memfd(vm, addr, &fd_offset, &len);
+ len = min(end - addr, len);
+
+ gmem_set_memory_attributes(fd, fd_offset, len, attrs, flags);
+ }
+ } else {
+ TEST_ASSERT(!flags, "Flags are not supported.");
+ vm_set_memory_attributes(vm, gpa, size, attrs);
+ }
+}
+
+static inline void vm_mem_set_private(struct kvm_vm *vm, uint64_t gpa,
+ uint64_t size, u64 flags)
+{
+ vm_mem_set_memory_attributes(vm, gpa, size,
+ KVM_MEMORY_ATTRIBUTE_PRIVATE, flags);
+}
+
+static inline void vm_mem_set_shared(struct kvm_vm *vm, uint64_t gpa,
+ uint64_t size, u64 flags)
+{
+ vm_mem_set_memory_attributes(vm, gpa, size, 0, flags);
+}
+
void vm_guest_mem_fallocate(struct kvm_vm *vm, uint64_t gpa, uint64_t size,
bool punch_hole);

diff --git a/tools/testing/selftests/kvm/lib/x86/sev.c b/tools/testing/selftests/kvm/lib/x86/sev.c
index c3a9838f4806a..d3a7241e5fc13 100644
--- a/tools/testing/selftests/kvm/lib/x86/sev.c
+++ b/tools/testing/selftests/kvm/lib/x86/sev.c
@@ -33,7 +33,7 @@ static void encrypt_region(struct kvm_vm *vm, struct userspace_mem_region *regio
const uint64_t offset = (i - lowest_page_in_region) * vm->page_size;

if (private)
- vm_mem_set_private(vm, gpa_base + offset, size);
+ vm_mem_set_private(vm, gpa_base + offset, size, 0);

if (is_sev_snp_vm(vm))
snp_launch_update_data(vm, gpa_base + offset,
diff --git a/tools/testing/selftests/kvm/pre_fault_memory_test.c b/tools/testing/selftests/kvm/pre_fault_memory_test.c
index 93e603d91311c..3b2c4179d42ee 100644
--- a/tools/testing/selftests/kvm/pre_fault_memory_test.c
+++ b/tools/testing/selftests/kvm/pre_fault_memory_test.c
@@ -188,7 +188,7 @@ static void __test_pre_fault_memory(unsigned long vm_type, bool private)
virt_map(vm, gva, gpa, TEST_NPAGES);

if (private)
- vm_mem_set_private(vm, gpa, TEST_SIZE);
+ vm_mem_set_private(vm, gpa, TEST_SIZE, 0);

pre_fault_memory(vcpu, gpa, 0, SZ_2M, 0, private);
pre_fault_memory(vcpu, gpa, SZ_2M, PAGE_SIZE * 2, PAGE_SIZE, private);
diff --git a/tools/testing/selftests/kvm/x86/private_mem_kvm_exits_test.c b/tools/testing/selftests/kvm/x86/private_mem_kvm_exits_test.c
index 13e72fcec8dd2..cbcb5d6d04436 100644
--- a/tools/testing/selftests/kvm/x86/private_mem_kvm_exits_test.c
+++ b/tools/testing/selftests/kvm/x86/private_mem_kvm_exits_test.c
@@ -63,7 +63,7 @@ static void test_private_access_memslot_deleted(void)
virt_map(vm, EXITS_TEST_GVA, EXITS_TEST_GPA, EXITS_TEST_NPAGES);

/* Request to access page privately */
- vm_mem_set_private(vm, EXITS_TEST_GPA, EXITS_TEST_SIZE);
+ vm_mem_set_private(vm, EXITS_TEST_GPA, EXITS_TEST_SIZE, 0);

pthread_create(&vm_thread, NULL,
(void *(*)(void *))run_vcpu_get_exit_reason,
@@ -99,7 +99,7 @@ static void test_private_access_memslot_not_private(void)
virt_map(vm, EXITS_TEST_GVA, EXITS_TEST_GPA, EXITS_TEST_NPAGES);

/* Request to access page privately */
- vm_mem_set_private(vm, EXITS_TEST_GPA, EXITS_TEST_SIZE);
+ vm_mem_set_private(vm, EXITS_TEST_GPA, EXITS_TEST_SIZE, 0);

exit_reason = run_vcpu_get_exit_reason(vcpu);

--
2.53.0.1018.g2bb0e51243-goog