From: Sean Christopherson <seanjc@google.com>
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 <seanjc@google.com>
---
.../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