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]>
---
 .../testing/selftests/kvm/include/kvm_util.h  | 87 +++++++++++++++++--
 1 file changed, 79 insertions(+), 8 deletions(-)

diff --git a/tools/testing/selftests/kvm/include/kvm_util.h 
b/tools/testing/selftests/kvm/include/kvm_util.h
index 019ffcec4510f..dd26a41106fae 100644
--- a/tools/testing/selftests/kvm/include/kvm_util.h
+++ b/tools/testing/selftests/kvm/include/kvm_util.h
@@ -310,6 +310,16 @@ static inline bool kvm_has_cap(long cap)
        TEST_ASSERT(!ret, __KVM_IOCTL_ERROR(#cmd, ret));        \
 })
 
+#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));        \
+})
+
 static __always_inline void static_assert_is_vm(struct kvm_vm *vm) { }
 
 #define __vm_ioctl(vm, cmd, arg)                               \
@@ -398,6 +408,14 @@ static inline void vm_enable_cap(struct kvm_vm *vm, 
uint32_t cap, uint64_t arg0)
        __TEST_REQUIRE(kvm_has_cap(KVM_CAP_MEMORY_ATTRIBUTES2),         \
                       "KVM selftests now require KVM_SET_MEMORY_ATTRIBUTES2")
 
+/*
+ * KVM_SET_MEMORY_ATTRIBUTES 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, uint64_t gpa,
                                            uint64_t size, uint64_t attributes)
 {
@@ -409,18 +427,11 @@ static inline void vm_set_memory_attributes(struct kvm_vm 
*vm, uint64_t gpa,
        };
 
        TEST_REQUIRE_SET_MEMORY_ATTRIBUTES2();
-
-       /*
-        * KVM_SET_MEMORY_ATTRIBUTES2 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_ATTRIBUTES2, &attr);
 }
 
-
 static inline void vm_mem_set_private(struct kvm_vm *vm, uint64_t gpa,
                                      uint64_t size)
 {
@@ -433,6 +444,66 @@ static inline void vm_mem_set_shared(struct kvm_vm *vm, 
uint64_t gpa,
        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,
+                                              loff_t *error_offset)
+{
+       struct kvm_memory_attributes2 attr = {
+               .attributes = attributes,
+               .offset = offset,
+               .size = size,
+               .flags = 0,
+       };
+       int r;
+
+       TEST_ASSERT_SUPPORTED_ATTRIBUTES(attributes);
+
+       r = __gmem_ioctl(fd, KVM_SET_MEMORY_ATTRIBUTES2, &attr);
+       if (r)
+               *error_offset = attr.error_offset;
+       return r;
+}
+
+static inline int __gmem_set_private(int fd, loff_t offset, uint64_t size,
+                                    loff_t *error_offset)
+{
+       return __gmem_set_memory_attributes(fd, offset, size,
+                                           KVM_MEMORY_ATTRIBUTE_PRIVATE,
+                                           error_offset);
+}
+
+static inline int __gmem_set_shared(int fd, loff_t offset, uint64_t size,
+                                   loff_t *error_offset)
+{
+       return __gmem_set_memory_attributes(fd, offset, size, 0, error_offset);
+}
+
+static inline void gmem_set_memory_attributes(int fd, loff_t offset,
+                                             uint64_t size, uint64_t 
attributes)
+{
+       struct kvm_memory_attributes2 attr = {
+               .attributes = attributes,
+               .offset = offset,
+               .size = size,
+               .flags = 0,
+       };
+
+       TEST_ASSERT_SUPPORTED_ATTRIBUTES(attributes);
+
+       gmem_ioctl(fd, KVM_SET_MEMORY_ATTRIBUTES2, &attr);
+}
+
+static inline void gmem_set_private(int fd, loff_t offset, uint64_t size)
+{
+       gmem_set_memory_attributes(fd, offset, size, 
KVM_MEMORY_ATTRIBUTE_PRIVATE);
+}
+
+static inline void gmem_set_shared(int fd, loff_t offset, uint64_t size)
+{
+       gmem_set_memory_attributes(fd, offset, size, 0);
+}
+
 void vm_guest_mem_fallocate(struct kvm_vm *vm, uint64_t gpa, uint64_t size,
                            bool punch_hole);
 
-- 
2.51.0.858.gf9c4a03a3a-goog


Reply via email to