tools/testing/selftests/kvm/guest_memfd_test.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/kvm/guest_memfd_test.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/kvm/guest_memfd_test.c
Extension
.c
Size
17423 bytes
Lines
582
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

if (flag & valid_flags) {
			TEST_ASSERT(fd >= 0,
				    "guest_memfd() with flag '0x%lx' should succeed",
				    flag);
			close(fd);
		} else {
			TEST_ASSERT(fd < 0 && errno == EINVAL,
				    "guest_memfd() with flag '0x%lx' should fail with EINVAL",
				    flag);
		}
	}
}

#define ____gmem_test(__test, __vm, __flags, __gmem_size, args...)	\
do {									\
	int fd = vm_create_guest_memfd(__vm, __gmem_size, __flags);	\
									\
	test_##__test(args);						\
	close(fd);							\
} while (0)

#define __gmem_test(__test, __vm, __flags, __gmem_size)			\
	____gmem_test(__test, __vm, __flags, __gmem_size, fd, __gmem_size)

#define gmem_test(__test, __vm, __flags)				\
	__gmem_test(__test, __vm, __flags, page_size * 4)

#define __gmem_test_vm(__test, __vm, __flags, __gmem_size)		\
	____gmem_test(__test, __vm, __flags, __gmem_size, __vm, fd, __gmem_size)

#define gmem_test_vm(__test, __vm, __flags)				\
	__gmem_test_vm(__test, __vm, __flags, page_size * 4)

static void __test_guest_memfd(struct kvm_vm *vm, u64 flags)
{
	test_create_guest_memfd_multiple(vm);
	test_create_guest_memfd_invalid_sizes(vm, flags);

	gmem_test(file_read_write, vm, flags);

	if (flags & GUEST_MEMFD_FLAG_MMAP) {
		if (flags & GUEST_MEMFD_FLAG_INIT_SHARED) {
			size_t pmd_size = get_trans_hugepagesz();

			gmem_test(mmap_supported, vm, flags);
			gmem_test(fault_overflow, vm, flags);
			gmem_test(numa_allocation, vm, flags);
			__gmem_test(collapse, vm, flags, pmd_size);
		} else {
			gmem_test(fault_private, vm, flags);
		}

		gmem_test(mmap_cow, vm, flags);
		gmem_test(mbind, vm, flags);
	} else {
		gmem_test(mmap_not_supported, vm, flags);
	}

	gmem_test(file_size, vm, flags);
	gmem_test(fallocate, vm, flags);
	gmem_test(invalid_punch_hole, vm, flags);
	gmem_test_vm(invalid_binding, vm, flags);
}

static void test_guest_memfd(unsigned long vm_type)
{
	struct kvm_vm *vm = vm_create_barebones_type(vm_type);
	u64 flags;

	test_guest_memfd_flags(vm);

	__test_guest_memfd(vm, 0);

	flags = vm_check_cap(vm, KVM_CAP_GUEST_MEMFD_FLAGS);
	if (flags & GUEST_MEMFD_FLAG_MMAP)
		__test_guest_memfd(vm, GUEST_MEMFD_FLAG_MMAP);

	/* MMAP should always be supported if INIT_SHARED is supported. */
	if (flags & GUEST_MEMFD_FLAG_INIT_SHARED)
		__test_guest_memfd(vm, GUEST_MEMFD_FLAG_MMAP |
				       GUEST_MEMFD_FLAG_INIT_SHARED);

	kvm_vm_free(vm);
}

static void guest_code(u8 *mem, u64 size)
{
	size_t i;

	for (i = 0; i < size; i++)

Annotation

Implementation Notes