On Fri, 19 Jun 2026 at 01:32, Ackerley Tng via B4 Relay <[email protected]> wrote: > > From: Sean Christopherson <[email protected]> > > Add helper functions to kvm_util.h to support calling ioctls, specifically > KVM_SET_MEMORY_ATTRIBUTES2, on a guest_memfd file descriptor. > > Introduce gmem_ioctl() and __gmem_ioctl() macros, modeled after the > existing vm_ioctl() helpers, to provide a standard way to call ioctls > on a guest_memfd. > > Add gmem_set_memory_attributes() and its derivatives (gmem_set_private(), > gmem_set_shared()) to set memory attributes on a guest_memfd region. > Also provide "__" variants that return the ioctl error code instead of > aborting the test. These helpers will be used by upcoming guest_memfd > tests. > > To avoid code duplication, factor out the check for supported memory > attributes into a new macro, TEST_ASSERT_SUPPORTED_ATTRIBUTES, and use > it in both the existing vm_set_memory_attributes() and the new > gmem_set_memory_attributes() helpers. > > Signed-off-by: Sean Christopherson <[email protected]> > Signed-off-by: Ackerley Tng <[email protected]>
Reviewed-by: Fuad Tabba <[email protected]> Cheers, /fuad > --- > tools/testing/selftests/kvm/include/kvm_util.h | 94 > +++++++++++++++++++++++--- > 1 file changed, 86 insertions(+), 8 deletions(-) > > diff --git a/tools/testing/selftests/kvm/include/kvm_util.h > b/tools/testing/selftests/kvm/include/kvm_util.h > index 0cacf3698b259..323d06b5699ec 100644 > --- a/tools/testing/selftests/kvm/include/kvm_util.h > +++ b/tools/testing/selftests/kvm/include/kvm_util.h > @@ -392,6 +392,16 @@ static __always_inline void static_assert_is_vcpu(struct > kvm_vcpu *vcpu) { } > __TEST_ASSERT_VM_VCPU_IOCTL(!ret, #cmd, ret, (vcpu)->vm); \ > }) > > +#define __gmem_ioctl(gmem_fd, cmd, arg) \ > + kvm_do_ioctl(gmem_fd, cmd, arg) > + > +#define gmem_ioctl(gmem_fd, cmd, arg) \ > +({ \ > + int ret = __gmem_ioctl(gmem_fd, cmd, arg); \ > + \ > + TEST_ASSERT(!ret, __KVM_IOCTL_ERROR(#cmd, ret)); \ > +}) > + > /* > * Looks up and returns the value corresponding to the capability > * (KVM_CAP_*) given by cap. > @@ -418,8 +428,16 @@ static inline void vm_enable_cap(struct kvm_vm *vm, u32 > cap, u64 arg0) > vm_ioctl(vm, KVM_ENABLE_CAP, &enable_cap); > } > > +/* > + * KVM_SET_MEMORY_ATTRIBUTES{,2} overwrites _all_ attributes. These > + * flows need significant enhancements to support multiple attributes. > + */ > +#define TEST_ASSERT_SUPPORTED_ATTRIBUTES(attributes) > \ > + TEST_ASSERT(!(attributes) || (attributes) == > KVM_MEMORY_ATTRIBUTE_PRIVATE, \ > + "Update me to support multiple attributes!") > + > static inline void vm_set_memory_attributes(struct kvm_vm *vm, gpa_t gpa, > - u64 size, u64 attributes) > + size_t size, u64 attributes) > { > struct kvm_memory_attributes attr = { > .attributes = attributes, > @@ -428,17 +446,11 @@ static inline void vm_set_memory_attributes(struct > kvm_vm *vm, gpa_t gpa, > .flags = 0, > }; > > - /* > - * KVM_SET_MEMORY_ATTRIBUTES overwrites _all_ attributes. These flows > - * need significant enhancements to support multiple attributes. > - */ > - TEST_ASSERT(!attributes || attributes == KVM_MEMORY_ATTRIBUTE_PRIVATE, > - "Update me to support multiple attributes!"); > + TEST_ASSERT_SUPPORTED_ATTRIBUTES(attributes); > > vm_ioctl(vm, KVM_SET_MEMORY_ATTRIBUTES, &attr); > } > > - > static inline void vm_mem_set_private(struct kvm_vm *vm, gpa_t gpa, > u64 size) > { > @@ -451,6 +463,72 @@ static inline void vm_mem_set_shared(struct kvm_vm *vm, > gpa_t gpa, > vm_set_memory_attributes(vm, gpa, size, 0); > } > > +static inline int __gmem_set_memory_attributes(int fd, u64 offset, > + size_t size, u64 attributes, > + u64 *error_offset) > +{ > + struct kvm_memory_attributes2 attr = { > + .attributes = attributes, > + .offset = offset, > + .size = size, > + .flags = 0, > + .error_offset = 0, > + }; > + int r; > + > + r = __gmem_ioctl(fd, KVM_SET_MEMORY_ATTRIBUTES2, &attr); > + > + /* Copy error_offset regardless of r so caller can check. */ > + if (error_offset) > + *error_offset = attr.error_offset; > + > + return r; > +} > + > +static inline int __gmem_set_private(int fd, u64 offset, size_t size, > + u64 *error_offset) > +{ > + return __gmem_set_memory_attributes(fd, offset, size, > + KVM_MEMORY_ATTRIBUTE_PRIVATE, > + error_offset); > +} > + > +static inline int __gmem_set_shared(int fd, u64 offset, size_t size, > + u64 *error_offset) > +{ > + return __gmem_set_memory_attributes(fd, offset, size, 0, > + error_offset); > +} > + > +static inline void gmem_set_memory_attributes(int fd, u64 offset, > + size_t size, u64 attributes) > +{ > + struct kvm_memory_attributes2 attr = { > + .attributes = attributes, > + .offset = offset, > + .size = size, > + .flags = 0, > + }; > + > + TEST_ASSERT_SUPPORTED_ATTRIBUTES(attributes); > + > + __TEST_REQUIRE(kvm_check_cap(KVM_CAP_GUEST_MEMFD_MEMORY_ATTRIBUTES) > > 0, > + "No valid attributes for guest_memfd ioctl!"); > + > + gmem_ioctl(fd, KVM_SET_MEMORY_ATTRIBUTES2, &attr); > +} > + > +static inline void gmem_set_private(int fd, u64 offset, size_t size) > +{ > + gmem_set_memory_attributes(fd, offset, size, > + KVM_MEMORY_ATTRIBUTE_PRIVATE); > +} > + > +static inline void gmem_set_shared(int fd, u64 offset, size_t size) > +{ > + gmem_set_memory_attributes(fd, offset, size, 0); > +} > + > void vm_guest_mem_fallocate(struct kvm_vm *vm, gpa_t gpa, u64 size, > bool punch_hole); > > > -- > 2.55.0.rc0.738.g0c8ab3ebcc-goog > >
