diff options
Diffstat (limited to 'tools')
19 files changed, 477 insertions, 154 deletions
| diff --git a/tools/testing/selftests/kvm/arm64/arch_timer_edge_cases.c b/tools/testing/selftests/kvm/arm64/arch_timer_edge_cases.c index 91906414a474..993c9e38e729 100644 --- a/tools/testing/selftests/kvm/arm64/arch_timer_edge_cases.c +++ b/tools/testing/selftests/kvm/arm64/arch_timer_edge_cases.c @@ -1020,7 +1020,7 @@ static void set_counter_defaults(void)  {  	const uint64_t MIN_ROLLOVER_SECS = 40ULL * 365 * 24 * 3600;  	uint64_t freq = read_sysreg(CNTFRQ_EL0); -	uint64_t width = ilog2(MIN_ROLLOVER_SECS * freq); +	int width = ilog2(MIN_ROLLOVER_SECS * freq);  	width = clamp(width, 56, 64);  	CVAL_MAX = GENMASK_ULL(width - 1, 0); diff --git a/tools/testing/selftests/kvm/arm64/external_aborts.c b/tools/testing/selftests/kvm/arm64/external_aborts.c index 592b26ded779..d8fe17a6cc59 100644 --- a/tools/testing/selftests/kvm/arm64/external_aborts.c +++ b/tools/testing/selftests/kvm/arm64/external_aborts.c @@ -359,6 +359,44 @@ static void test_mmio_ease(void)  	kvm_vm_free(vm);  } +static void test_serror_amo_guest(void) +{ +	/* +	 * The ISB is entirely unnecessary (and highlights how FEAT_NV2 is borked) +	 * since the write is redirected to memory. But don't write (intentionally) +	 * broken code! +	 */ +	sysreg_clear_set(hcr_el2, HCR_EL2_AMO | HCR_EL2_TGE, 0); +	isb(); + +	GUEST_SYNC(0); +	GUEST_ASSERT(read_sysreg(isr_el1) & ISR_EL1_A); + +	/* +	 * KVM treats the effective value of AMO as 1 when +	 * HCR_EL2.{E2H,TGE} = {1, 0}, meaning the SError will be taken when +	 * unmasked. +	 */ +	local_serror_enable(); +	isb(); +	local_serror_disable(); + +	GUEST_FAIL("Should've taken pending SError exception"); +} + +static void test_serror_amo(void) +{ +	struct kvm_vcpu *vcpu; +	struct kvm_vm *vm = vm_create_with_dabt_handler(&vcpu, test_serror_amo_guest, +							unexpected_dabt_handler); + +	vm_install_exception_handler(vm, VECTOR_ERROR_CURRENT, expect_serror_handler); +	vcpu_run_expect_sync(vcpu); +	vcpu_inject_serror(vcpu); +	vcpu_run_expect_done(vcpu); +	kvm_vm_free(vm); +} +  int main(void)  {  	test_mmio_abort(); @@ -369,4 +407,9 @@ int main(void)  	test_serror_emulated();  	test_mmio_ease();  	test_s1ptw_abort(); + +	if (!test_supports_el2()) +		return 0; + +	test_serror_amo();  } diff --git a/tools/testing/selftests/kvm/arm64/get-reg-list.c b/tools/testing/selftests/kvm/arm64/get-reg-list.c index 011fad95dd02..c9b84eeaab6b 100644 --- a/tools/testing/selftests/kvm/arm64/get-reg-list.c +++ b/tools/testing/selftests/kvm/arm64/get-reg-list.c @@ -65,6 +65,9 @@ static struct feature_id_reg feat_id_regs[] = {  	REG_FEAT(SCTLR2_EL1,	ID_AA64MMFR3_EL1, SCTLRX, IMP),  	REG_FEAT(VDISR_EL2,	ID_AA64PFR0_EL1, RAS, IMP),  	REG_FEAT(VSESR_EL2,	ID_AA64PFR0_EL1, RAS, IMP), +	REG_FEAT(VNCR_EL2,	ID_AA64MMFR4_EL1, NV_frac, NV2_ONLY), +	REG_FEAT(CNTHV_CTL_EL2, ID_AA64MMFR1_EL1, VH, IMP), +	REG_FEAT(CNTHV_CVAL_EL2,ID_AA64MMFR1_EL1, VH, IMP),  };  bool filter_reg(__u64 reg) @@ -345,9 +348,20 @@ static __u64 base_regs[] = {  	KVM_REG_ARM_FW_FEAT_BMAP_REG(1),	/* KVM_REG_ARM_STD_HYP_BMAP */  	KVM_REG_ARM_FW_FEAT_BMAP_REG(2),	/* KVM_REG_ARM_VENDOR_HYP_BMAP */  	KVM_REG_ARM_FW_FEAT_BMAP_REG(3),	/* KVM_REG_ARM_VENDOR_HYP_BMAP_2 */ -	ARM64_SYS_REG(3, 3, 14, 3, 1),	/* CNTV_CTL_EL0 */ -	ARM64_SYS_REG(3, 3, 14, 3, 2),	/* CNTV_CVAL_EL0 */ -	ARM64_SYS_REG(3, 3, 14, 0, 2), + +	/* +	 * EL0 Virtual Timer Registers +	 * +	 * WARNING: +	 * KVM_REG_ARM_TIMER_CVAL and KVM_REG_ARM_TIMER_CNT are not defined +	 * with the appropriate register encodings.  Their values have been +	 * accidentally swapped.  As this is set API, the definitions here +	 * must be used, rather than ones derived from the encodings. +	 */ +	KVM_ARM64_SYS_REG(SYS_CNTV_CTL_EL0), +	KVM_REG_ARM_TIMER_CVAL, +	KVM_REG_ARM_TIMER_CNT, +  	ARM64_SYS_REG(3, 0, 0, 0, 0),	/* MIDR_EL1 */  	ARM64_SYS_REG(3, 0, 0, 0, 6),	/* REVIDR_EL1 */  	ARM64_SYS_REG(3, 1, 0, 0, 1),	/* CLIDR_EL1 */ @@ -755,6 +769,10 @@ static __u64 el2_regs[] = {  	SYS_REG(VSESR_EL2),  }; +static __u64 el2_e2h0_regs[] = { +	/* Empty */ +}; +  #define BASE_SUBLIST \  	{ "base", .regs = base_regs, .regs_n = ARRAY_SIZE(base_regs), }  #define VREGS_SUBLIST \ @@ -789,6 +807,15 @@ static __u64 el2_regs[] = {  		.regs		= el2_regs,			\  		.regs_n		= ARRAY_SIZE(el2_regs),		\  	} +#define EL2_E2H0_SUBLIST					\ +	EL2_SUBLIST,						\ +	{							\ +		.name 		= "EL2 E2H0",			\ +		.capability	= KVM_CAP_ARM_EL2_E2H0,		\ +		.feature	= KVM_ARM_VCPU_HAS_EL2_E2H0,	\ +		.regs		= el2_e2h0_regs,		\ +		.regs_n		= ARRAY_SIZE(el2_e2h0_regs),	\ +	}  static struct vcpu_reg_list vregs_config = {  	.sublists = { @@ -897,6 +924,65 @@ static struct vcpu_reg_list el2_pauth_pmu_config = {  	},  }; +static struct vcpu_reg_list el2_e2h0_vregs_config = { +	.sublists = { +	BASE_SUBLIST, +	EL2_E2H0_SUBLIST, +	VREGS_SUBLIST, +	{0}, +	}, +}; + +static struct vcpu_reg_list el2_e2h0_vregs_pmu_config = { +	.sublists = { +	BASE_SUBLIST, +	EL2_E2H0_SUBLIST, +	VREGS_SUBLIST, +	PMU_SUBLIST, +	{0}, +	}, +}; + +static struct vcpu_reg_list el2_e2h0_sve_config = { +	.sublists = { +	BASE_SUBLIST, +	EL2_E2H0_SUBLIST, +	SVE_SUBLIST, +	{0}, +	}, +}; + +static struct vcpu_reg_list el2_e2h0_sve_pmu_config = { +	.sublists = { +	BASE_SUBLIST, +	EL2_E2H0_SUBLIST, +	SVE_SUBLIST, +	PMU_SUBLIST, +	{0}, +	}, +}; + +static struct vcpu_reg_list el2_e2h0_pauth_config = { +	.sublists = { +	BASE_SUBLIST, +	EL2_E2H0_SUBLIST, +	VREGS_SUBLIST, +	PAUTH_SUBLIST, +	{0}, +	}, +}; + +static struct vcpu_reg_list el2_e2h0_pauth_pmu_config = { +	.sublists = { +	BASE_SUBLIST, +	EL2_E2H0_SUBLIST, +	VREGS_SUBLIST, +	PAUTH_SUBLIST, +	PMU_SUBLIST, +	{0}, +	}, +}; +  struct vcpu_reg_list *vcpu_configs[] = {  	&vregs_config,  	&vregs_pmu_config, @@ -911,5 +997,12 @@ struct vcpu_reg_list *vcpu_configs[] = {  	&el2_sve_pmu_config,  	&el2_pauth_config,  	&el2_pauth_pmu_config, + +	&el2_e2h0_vregs_config, +	&el2_e2h0_vregs_pmu_config, +	&el2_e2h0_sve_config, +	&el2_e2h0_sve_pmu_config, +	&el2_e2h0_pauth_config, +	&el2_e2h0_pauth_pmu_config,  };  int vcpu_configs_n = ARRAY_SIZE(vcpu_configs); diff --git a/tools/testing/selftests/kvm/arm64/set_id_regs.c b/tools/testing/selftests/kvm/arm64/set_id_regs.c index 8ff1e853f7f8..5e24f77868b5 100644 --- a/tools/testing/selftests/kvm/arm64/set_id_regs.c +++ b/tools/testing/selftests/kvm/arm64/set_id_regs.c @@ -249,11 +249,14 @@ static void guest_code(void)  	GUEST_REG_SYNC(SYS_ID_AA64ISAR2_EL1);  	GUEST_REG_SYNC(SYS_ID_AA64ISAR3_EL1);  	GUEST_REG_SYNC(SYS_ID_AA64PFR0_EL1); +	GUEST_REG_SYNC(SYS_ID_AA64PFR1_EL1);  	GUEST_REG_SYNC(SYS_ID_AA64MMFR0_EL1);  	GUEST_REG_SYNC(SYS_ID_AA64MMFR1_EL1);  	GUEST_REG_SYNC(SYS_ID_AA64MMFR2_EL1);  	GUEST_REG_SYNC(SYS_ID_AA64MMFR3_EL1);  	GUEST_REG_SYNC(SYS_ID_AA64ZFR0_EL1); +	GUEST_REG_SYNC(SYS_MPIDR_EL1); +	GUEST_REG_SYNC(SYS_CLIDR_EL1);  	GUEST_REG_SYNC(SYS_CTR_EL0);  	GUEST_REG_SYNC(SYS_MIDR_EL1);  	GUEST_REG_SYNC(SYS_REVIDR_EL1); diff --git a/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c b/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c index 87922a89b134..687d04463983 100644 --- a/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c +++ b/tools/testing/selftests/kvm/arm64/vgic_lpi_stress.c @@ -123,6 +123,7 @@ static void guest_setup_gic(void)  static void guest_code(size_t nr_lpis)  {  	guest_setup_gic(); +	local_irq_enable();  	GUEST_SYNC(0); @@ -331,7 +332,7 @@ static void setup_vm(void)  {  	int i; -	vcpus = malloc(test_data.nr_cpus * sizeof(struct kvm_vcpu)); +	vcpus = malloc(test_data.nr_cpus * sizeof(struct kvm_vcpu *));  	TEST_ASSERT(vcpus, "Failed to allocate vCPU array");  	vm = vm_create_with_vcpus(test_data.nr_cpus, guest_code, vcpus); diff --git a/tools/testing/selftests/kvm/guest_memfd_test.c b/tools/testing/selftests/kvm/guest_memfd_test.c index b3ca6737f304..e7d9aeb418d3 100644 --- a/tools/testing/selftests/kvm/guest_memfd_test.c +++ b/tools/testing/selftests/kvm/guest_memfd_test.c @@ -14,8 +14,6 @@  #include <linux/bitmap.h>  #include <linux/falloc.h>  #include <linux/sizes.h> -#include <setjmp.h> -#include <signal.h>  #include <sys/mman.h>  #include <sys/types.h>  #include <sys/stat.h> @@ -24,7 +22,9 @@  #include "test_util.h"  #include "ucall_common.h" -static void test_file_read_write(int fd) +static size_t page_size; + +static void test_file_read_write(int fd, size_t total_size)  {  	char buf[64]; @@ -38,18 +38,22 @@ static void test_file_read_write(int fd)  		    "pwrite on a guest_mem fd should fail");  } -static void test_mmap_supported(int fd, size_t page_size, size_t total_size) +static void test_mmap_cow(int fd, size_t size) +{ +	void *mem; + +	mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); +	TEST_ASSERT(mem == MAP_FAILED, "Copy-on-write not allowed by guest_memfd."); +} + +static void test_mmap_supported(int fd, size_t total_size)  {  	const char val = 0xaa;  	char *mem;  	size_t i;  	int ret; -	mem = mmap(NULL, total_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); -	TEST_ASSERT(mem == MAP_FAILED, "Copy-on-write not allowed by guest_memfd."); - -	mem = mmap(NULL, total_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); -	TEST_ASSERT(mem != MAP_FAILED, "mmap() for guest_memfd should succeed."); +	mem = kvm_mmap(total_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd);  	memset(mem, val, total_size);  	for (i = 0; i < total_size; i++) @@ -68,45 +72,37 @@ static void test_mmap_supported(int fd, size_t page_size, size_t total_size)  	for (i = 0; i < total_size; i++)  		TEST_ASSERT_EQ(READ_ONCE(mem[i]), val); -	ret = munmap(mem, total_size); -	TEST_ASSERT(!ret, "munmap() should succeed."); -} - -static sigjmp_buf jmpbuf; -void fault_sigbus_handler(int signum) -{ -	siglongjmp(jmpbuf, 1); +	kvm_munmap(mem, total_size);  } -static void test_fault_overflow(int fd, size_t page_size, size_t total_size) +static void test_fault_sigbus(int fd, size_t accessible_size, size_t map_size)  { -	struct sigaction sa_old, sa_new = { -		.sa_handler = fault_sigbus_handler, -	}; -	size_t map_size = total_size * 4;  	const char val = 0xaa;  	char *mem;  	size_t i; -	int ret; -	mem = mmap(NULL, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); -	TEST_ASSERT(mem != MAP_FAILED, "mmap() for guest_memfd should succeed."); +	mem = kvm_mmap(map_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd); -	sigaction(SIGBUS, &sa_new, &sa_old); -	if (sigsetjmp(jmpbuf, 1) == 0) { -		memset(mem, 0xaa, map_size); -		TEST_ASSERT(false, "memset() should have triggered SIGBUS."); -	} -	sigaction(SIGBUS, &sa_old, NULL); +	TEST_EXPECT_SIGBUS(memset(mem, val, map_size)); +	TEST_EXPECT_SIGBUS((void)READ_ONCE(mem[accessible_size])); -	for (i = 0; i < total_size; i++) +	for (i = 0; i < accessible_size; i++)  		TEST_ASSERT_EQ(READ_ONCE(mem[i]), val); -	ret = munmap(mem, map_size); -	TEST_ASSERT(!ret, "munmap() should succeed."); +	kvm_munmap(mem, map_size); +} + +static void test_fault_overflow(int fd, size_t total_size) +{ +	test_fault_sigbus(fd, total_size, total_size * 4); +} + +static void test_fault_private(int fd, size_t total_size) +{ +	test_fault_sigbus(fd, 0, total_size);  } -static void test_mmap_not_supported(int fd, size_t page_size, size_t total_size) +static void test_mmap_not_supported(int fd, size_t total_size)  {  	char *mem; @@ -117,7 +113,7 @@ static void test_mmap_not_supported(int fd, size_t page_size, size_t total_size)  	TEST_ASSERT_EQ(mem, MAP_FAILED);  } -static void test_file_size(int fd, size_t page_size, size_t total_size) +static void test_file_size(int fd, size_t total_size)  {  	struct stat sb;  	int ret; @@ -128,7 +124,7 @@ static void test_file_size(int fd, size_t page_size, size_t total_size)  	TEST_ASSERT_EQ(sb.st_blksize, page_size);  } -static void test_fallocate(int fd, size_t page_size, size_t total_size) +static void test_fallocate(int fd, size_t total_size)  {  	int ret; @@ -165,7 +161,7 @@ static void test_fallocate(int fd, size_t page_size, size_t total_size)  	TEST_ASSERT(!ret, "fallocate to restore punched hole should succeed");  } -static void test_invalid_punch_hole(int fd, size_t page_size, size_t total_size) +static void test_invalid_punch_hole(int fd, size_t total_size)  {  	struct {  		off_t offset; @@ -196,8 +192,7 @@ static void test_invalid_punch_hole(int fd, size_t page_size, size_t total_size)  }  static void test_create_guest_memfd_invalid_sizes(struct kvm_vm *vm, -						  uint64_t guest_memfd_flags, -						  size_t page_size) +						  uint64_t guest_memfd_flags)  {  	size_t size;  	int fd; @@ -214,7 +209,6 @@ static void test_create_guest_memfd_multiple(struct kvm_vm *vm)  {  	int fd1, fd2, ret;  	struct stat st1, st2; -	size_t page_size = getpagesize();  	fd1 = __vm_create_guest_memfd(vm, page_size, 0);  	TEST_ASSERT(fd1 != -1, "memfd creation should succeed"); @@ -239,9 +233,9 @@ static void test_create_guest_memfd_multiple(struct kvm_vm *vm)  	close(fd1);  } -static void test_guest_memfd_flags(struct kvm_vm *vm, uint64_t valid_flags) +static void test_guest_memfd_flags(struct kvm_vm *vm)  { -	size_t page_size = getpagesize(); +	uint64_t valid_flags = vm_check_cap(vm, KVM_CAP_GUEST_MEMFD_FLAGS);  	uint64_t flag;  	int fd; @@ -260,43 +254,57 @@ static void test_guest_memfd_flags(struct kvm_vm *vm, uint64_t valid_flags)  	}  } -static void test_guest_memfd(unsigned long vm_type) +#define gmem_test(__test, __vm, __flags)				\ +do {									\ +	int fd = vm_create_guest_memfd(__vm, page_size * 4, __flags);	\ +									\ +	test_##__test(fd, page_size * 4);				\ +	close(fd);							\ +} while (0) + +static void __test_guest_memfd(struct kvm_vm *vm, uint64_t flags)  { -	uint64_t flags = 0; -	struct kvm_vm *vm; -	size_t total_size; -	size_t page_size; -	int fd; +	test_create_guest_memfd_multiple(vm); +	test_create_guest_memfd_invalid_sizes(vm, flags); -	page_size = getpagesize(); -	total_size = page_size * 4; +	gmem_test(file_read_write, vm, flags); -	vm = vm_create_barebones_type(vm_type); +	if (flags & GUEST_MEMFD_FLAG_MMAP) { +		if (flags & GUEST_MEMFD_FLAG_INIT_SHARED) { +			gmem_test(mmap_supported, vm, flags); +			gmem_test(fault_overflow, vm, flags); +		} else { +			gmem_test(fault_private, vm, flags); +		} -	if (vm_check_cap(vm, KVM_CAP_GUEST_MEMFD_MMAP)) -		flags |= GUEST_MEMFD_FLAG_MMAP; +		gmem_test(mmap_cow, vm, flags); +	} else { +		gmem_test(mmap_not_supported, vm, flags); +	} -	test_create_guest_memfd_multiple(vm); -	test_create_guest_memfd_invalid_sizes(vm, flags, page_size); +	gmem_test(file_size, vm, flags); +	gmem_test(fallocate, vm, flags); +	gmem_test(invalid_punch_hole, vm, flags); +} -	fd = vm_create_guest_memfd(vm, total_size, flags); +static void test_guest_memfd(unsigned long vm_type) +{ +	struct kvm_vm *vm = vm_create_barebones_type(vm_type); +	uint64_t flags; -	test_file_read_write(fd); +	test_guest_memfd_flags(vm); -	if (flags & GUEST_MEMFD_FLAG_MMAP) { -		test_mmap_supported(fd, page_size, total_size); -		test_fault_overflow(fd, page_size, total_size); -	} else { -		test_mmap_not_supported(fd, page_size, total_size); -	} +	__test_guest_memfd(vm, 0); -	test_file_size(fd, page_size, total_size); -	test_fallocate(fd, page_size, total_size); -	test_invalid_punch_hole(fd, page_size, total_size); +	flags = vm_check_cap(vm, KVM_CAP_GUEST_MEMFD_FLAGS); +	if (flags & GUEST_MEMFD_FLAG_MMAP) +		__test_guest_memfd(vm, GUEST_MEMFD_FLAG_MMAP); -	test_guest_memfd_flags(vm, flags); +	/* 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); -	close(fd);  	kvm_vm_free(vm);  } @@ -328,22 +336,26 @@ static void test_guest_memfd_guest(void)  	size_t size;  	int fd, i; -	if (!kvm_has_cap(KVM_CAP_GUEST_MEMFD_MMAP)) +	if (!kvm_check_cap(KVM_CAP_GUEST_MEMFD_FLAGS))  		return;  	vm = __vm_create_shape_with_one_vcpu(VM_SHAPE_DEFAULT, &vcpu, 1, guest_code); -	TEST_ASSERT(vm_check_cap(vm, KVM_CAP_GUEST_MEMFD_MMAP), -		    "Default VM type should always support guest_memfd mmap()"); +	TEST_ASSERT(vm_check_cap(vm, KVM_CAP_GUEST_MEMFD_FLAGS) & GUEST_MEMFD_FLAG_MMAP, +		    "Default VM type should support MMAP, supported flags = 0x%x", +		    vm_check_cap(vm, KVM_CAP_GUEST_MEMFD_FLAGS)); +	TEST_ASSERT(vm_check_cap(vm, KVM_CAP_GUEST_MEMFD_FLAGS) & GUEST_MEMFD_FLAG_INIT_SHARED, +		    "Default VM type should support INIT_SHARED, supported flags = 0x%x", +		    vm_check_cap(vm, KVM_CAP_GUEST_MEMFD_FLAGS));  	size = vm->page_size; -	fd = vm_create_guest_memfd(vm, size, GUEST_MEMFD_FLAG_MMAP); +	fd = vm_create_guest_memfd(vm, size, GUEST_MEMFD_FLAG_MMAP | +					     GUEST_MEMFD_FLAG_INIT_SHARED);  	vm_set_user_memory_region2(vm, slot, KVM_MEM_GUEST_MEMFD, gpa, size, NULL, fd, 0); -	mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); -	TEST_ASSERT(mem != MAP_FAILED, "mmap() on guest_memfd failed"); +	mem = kvm_mmap(size, PROT_READ | PROT_WRITE, MAP_SHARED, fd);  	memset(mem, 0xaa, size); -	munmap(mem, size); +	kvm_munmap(mem, size);  	virt_pg_map(vm, gpa, gpa);  	vcpu_args_set(vcpu, 2, gpa, size); @@ -351,8 +363,7 @@ static void test_guest_memfd_guest(void)  	TEST_ASSERT_EQ(get_ucall(vcpu, NULL), UCALL_DONE); -	mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); -	TEST_ASSERT(mem != MAP_FAILED, "mmap() on guest_memfd failed"); +	mem = kvm_mmap(size, PROT_READ | PROT_WRITE, MAP_SHARED, fd);  	for (i = 0; i < size; i++)  		TEST_ASSERT_EQ(mem[i], 0xff); @@ -366,6 +377,8 @@ int main(int argc, char *argv[])  	TEST_REQUIRE(kvm_has_cap(KVM_CAP_GUEST_MEMFD)); +	page_size = getpagesize(); +  	/*  	 * Not all architectures support KVM_CAP_VM_TYPES. However, those that  	 * support guest_memfd have that support for the default VM type. diff --git a/tools/testing/selftests/kvm/include/arm64/processor.h b/tools/testing/selftests/kvm/include/arm64/processor.h index 6f481475c135..ff928716574d 100644 --- a/tools/testing/selftests/kvm/include/arm64/processor.h +++ b/tools/testing/selftests/kvm/include/arm64/processor.h @@ -305,7 +305,17 @@ void test_wants_mte(void);  void test_disable_default_vgic(void);  bool vm_supports_el2(struct kvm_vm *vm); -static bool vcpu_has_el2(struct kvm_vcpu *vcpu) + +static inline bool test_supports_el2(void) +{ +	struct kvm_vm *vm = vm_create(1); +	bool supported = vm_supports_el2(vm); + +	kvm_vm_free(vm); +	return supported; +} + +static inline bool vcpu_has_el2(struct kvm_vcpu *vcpu)  {  	return vcpu->init.features[0] & BIT(KVM_ARM_VCPU_HAS_EL2);  } diff --git a/tools/testing/selftests/kvm/include/kvm_util.h b/tools/testing/selftests/kvm/include/kvm_util.h index 26cc30290e76..d3f3e455c031 100644 --- a/tools/testing/selftests/kvm/include/kvm_util.h +++ b/tools/testing/selftests/kvm/include/kvm_util.h @@ -286,6 +286,31 @@ static inline bool kvm_has_cap(long cap)  #define __KVM_SYSCALL_ERROR(_name, _ret) \  	"%s failed, rc: %i errno: %i (%s)", (_name), (_ret), errno, strerror(errno) +static inline void *__kvm_mmap(size_t size, int prot, int flags, int fd, +			       off_t offset) +{ +	void *mem; + +	mem = mmap(NULL, size, prot, flags, fd, offset); +	TEST_ASSERT(mem != MAP_FAILED, __KVM_SYSCALL_ERROR("mmap()", +		    (int)(unsigned long)MAP_FAILED)); + +	return mem; +} + +static inline void *kvm_mmap(size_t size, int prot, int flags, int fd) +{ +	return __kvm_mmap(size, prot, flags, fd, 0); +} + +static inline void kvm_munmap(void *mem, size_t size) +{ +	int ret; + +	ret = munmap(mem, size); +	TEST_ASSERT(!ret, __KVM_SYSCALL_ERROR("munmap()", ret)); +} +  /*   * Use the "inner", double-underscore macro when reporting errors from within   * other macros so that the name of ioctl() and not its literal numeric value @@ -1273,4 +1298,6 @@ bool vm_is_gpa_protected(struct kvm_vm *vm, vm_paddr_t paddr);  uint32_t guest_get_vcpuid(void); +bool kvm_arch_has_default_irqchip(void); +  #endif /* SELFTEST_KVM_UTIL_H */ diff --git a/tools/testing/selftests/kvm/include/test_util.h b/tools/testing/selftests/kvm/include/test_util.h index c6ef895fbd9a..b4872ba8ed12 100644 --- a/tools/testing/selftests/kvm/include/test_util.h +++ b/tools/testing/selftests/kvm/include/test_util.h @@ -8,6 +8,8 @@  #ifndef SELFTEST_KVM_TEST_UTIL_H  #define SELFTEST_KVM_TEST_UTIL_H +#include <setjmp.h> +#include <signal.h>  #include <stdlib.h>  #include <stdarg.h>  #include <stdbool.h> @@ -78,6 +80,23 @@ do {									\  	__builtin_unreachable(); \  } while (0) +extern sigjmp_buf expect_sigbus_jmpbuf; +void expect_sigbus_handler(int signum); + +#define TEST_EXPECT_SIGBUS(action)						\ +do {										\ +	struct sigaction sa_old, sa_new = {					\ +		.sa_handler = expect_sigbus_handler,				\ +	};									\ +										\ +	sigaction(SIGBUS, &sa_new, &sa_old);					\ +	if (sigsetjmp(expect_sigbus_jmpbuf, 1) == 0) {				\ +		action;								\ +		TEST_FAIL("'%s' should have triggered SIGBUS", #action);	\ +	}									\ +	sigaction(SIGBUS, &sa_old, NULL);					\ +} while (0) +  size_t parse_size(const char *size);  int64_t timespec_to_ns(struct timespec ts); diff --git a/tools/testing/selftests/kvm/irqfd_test.c b/tools/testing/selftests/kvm/irqfd_test.c index 7c301b4c7005..5d7590d01868 100644 --- a/tools/testing/selftests/kvm/irqfd_test.c +++ b/tools/testing/selftests/kvm/irqfd_test.c @@ -89,11 +89,19 @@ static void juggle_eventfd_primary(struct kvm_vm *vm, int eventfd)  int main(int argc, char *argv[])  {  	pthread_t racing_thread; +	struct kvm_vcpu *unused;  	int r, i; -	/* Create "full" VMs, as KVM_IRQFD requires an in-kernel IRQ chip. */ -	vm1 = vm_create(1); -	vm2 = vm_create(1); +	TEST_REQUIRE(kvm_arch_has_default_irqchip()); + +	/* +	 * Create "full" VMs, as KVM_IRQFD requires an in-kernel IRQ chip. Also +	 * create an unused vCPU as certain architectures (like arm64) need to +	 * complete IRQ chip initialization after all possible vCPUs for a VM +	 * have been created. +	 */ +	vm1 = vm_create_with_one_vcpu(&unused, NULL); +	vm2 = vm_create_with_one_vcpu(&unused, NULL);  	WRITE_ONCE(__eventfd, kvm_new_eventfd()); diff --git a/tools/testing/selftests/kvm/lib/arm64/processor.c b/tools/testing/selftests/kvm/lib/arm64/processor.c index 369a4c87dd8f..54f6d17c78f7 100644 --- a/tools/testing/selftests/kvm/lib/arm64/processor.c +++ b/tools/testing/selftests/kvm/lib/arm64/processor.c @@ -725,3 +725,8 @@ void kvm_arch_vm_release(struct kvm_vm *vm)  	if (vm->arch.has_gic)  		close(vm->arch.gic_fd);  } + +bool kvm_arch_has_default_irqchip(void) +{ +	return request_vgic && kvm_supports_vgic_v3(); +} diff --git a/tools/testing/selftests/kvm/lib/kvm_util.c b/tools/testing/selftests/kvm/lib/kvm_util.c index 6743fbd9bd67..1a93d6361671 100644 --- a/tools/testing/selftests/kvm/lib/kvm_util.c +++ b/tools/testing/selftests/kvm/lib/kvm_util.c @@ -741,13 +741,11 @@ static void vm_vcpu_rm(struct kvm_vm *vm, struct kvm_vcpu *vcpu)  	int ret;  	if (vcpu->dirty_gfns) { -		ret = munmap(vcpu->dirty_gfns, vm->dirty_ring_size); -		TEST_ASSERT(!ret, __KVM_SYSCALL_ERROR("munmap()", ret)); +		kvm_munmap(vcpu->dirty_gfns, vm->dirty_ring_size);  		vcpu->dirty_gfns = NULL;  	} -	ret = munmap(vcpu->run, vcpu_mmap_sz()); -	TEST_ASSERT(!ret, __KVM_SYSCALL_ERROR("munmap()", ret)); +	kvm_munmap(vcpu->run, vcpu_mmap_sz());  	ret = close(vcpu->fd);  	TEST_ASSERT(!ret,  __KVM_SYSCALL_ERROR("close()", ret)); @@ -783,20 +781,16 @@ void kvm_vm_release(struct kvm_vm *vmp)  static void __vm_mem_region_delete(struct kvm_vm *vm,  				   struct userspace_mem_region *region)  { -	int ret; -  	rb_erase(®ion->gpa_node, &vm->regions.gpa_tree);  	rb_erase(®ion->hva_node, &vm->regions.hva_tree);  	hash_del(®ion->slot_node);  	sparsebit_free(®ion->unused_phy_pages);  	sparsebit_free(®ion->protected_phy_pages); -	ret = munmap(region->mmap_start, region->mmap_size); -	TEST_ASSERT(!ret, __KVM_SYSCALL_ERROR("munmap()", ret)); +	kvm_munmap(region->mmap_start, region->mmap_size);  	if (region->fd >= 0) {  		/* There's an extra map when using shared memory. */ -		ret = munmap(region->mmap_alias, region->mmap_size); -		TEST_ASSERT(!ret, __KVM_SYSCALL_ERROR("munmap()", ret)); +		kvm_munmap(region->mmap_alias, region->mmap_size);  		close(region->fd);  	}  	if (region->region.guest_memfd >= 0) @@ -1053,12 +1047,9 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type,  		region->fd = kvm_memfd_alloc(region->mmap_size,  					     src_type == VM_MEM_SRC_SHARED_HUGETLB); -	region->mmap_start = mmap(NULL, region->mmap_size, -				  PROT_READ | PROT_WRITE, -				  vm_mem_backing_src_alias(src_type)->flag, -				  region->fd, 0); -	TEST_ASSERT(region->mmap_start != MAP_FAILED, -		    __KVM_SYSCALL_ERROR("mmap()", (int)(unsigned long)MAP_FAILED)); +	region->mmap_start = kvm_mmap(region->mmap_size, PROT_READ | PROT_WRITE, +				      vm_mem_backing_src_alias(src_type)->flag, +				      region->fd);  	TEST_ASSERT(!is_backing_src_hugetlb(src_type) ||  		    region->mmap_start == align_ptr_up(region->mmap_start, backing_src_pagesz), @@ -1129,12 +1120,10 @@ void vm_mem_add(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type,  	/* If shared memory, create an alias. */  	if (region->fd >= 0) { -		region->mmap_alias = mmap(NULL, region->mmap_size, -					  PROT_READ | PROT_WRITE, -					  vm_mem_backing_src_alias(src_type)->flag, -					  region->fd, 0); -		TEST_ASSERT(region->mmap_alias != MAP_FAILED, -			    __KVM_SYSCALL_ERROR("mmap()",  (int)(unsigned long)MAP_FAILED)); +		region->mmap_alias = kvm_mmap(region->mmap_size, +					      PROT_READ | PROT_WRITE, +					      vm_mem_backing_src_alias(src_type)->flag, +					      region->fd);  		/* Align host alias address */  		region->host_alias = align_ptr_up(region->mmap_alias, alignment); @@ -1344,10 +1333,8 @@ struct kvm_vcpu *__vm_vcpu_add(struct kvm_vm *vm, uint32_t vcpu_id)  	TEST_ASSERT(vcpu_mmap_sz() >= sizeof(*vcpu->run), "vcpu mmap size "  		"smaller than expected, vcpu_mmap_sz: %zi expected_min: %zi",  		vcpu_mmap_sz(), sizeof(*vcpu->run)); -	vcpu->run = (struct kvm_run *) mmap(NULL, vcpu_mmap_sz(), -		PROT_READ | PROT_WRITE, MAP_SHARED, vcpu->fd, 0); -	TEST_ASSERT(vcpu->run != MAP_FAILED, -		    __KVM_SYSCALL_ERROR("mmap()", (int)(unsigned long)MAP_FAILED)); +	vcpu->run = kvm_mmap(vcpu_mmap_sz(), PROT_READ | PROT_WRITE, +			     MAP_SHARED, vcpu->fd);  	if (kvm_has_cap(KVM_CAP_BINARY_STATS_FD))  		vcpu->stats.fd = vcpu_get_stats_fd(vcpu); @@ -1794,9 +1781,8 @@ void *vcpu_map_dirty_ring(struct kvm_vcpu *vcpu)  			    page_size * KVM_DIRTY_LOG_PAGE_OFFSET);  		TEST_ASSERT(addr == MAP_FAILED, "Dirty ring mapped exec"); -		addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, vcpu->fd, -			    page_size * KVM_DIRTY_LOG_PAGE_OFFSET); -		TEST_ASSERT(addr != MAP_FAILED, "Dirty ring map failed"); +		addr = __kvm_mmap(size, PROT_READ | PROT_WRITE, MAP_SHARED, vcpu->fd, +				  page_size * KVM_DIRTY_LOG_PAGE_OFFSET);  		vcpu->dirty_gfns = addr;  		vcpu->dirty_gfns_count = size / sizeof(struct kvm_dirty_gfn); @@ -2344,3 +2330,8 @@ bool vm_is_gpa_protected(struct kvm_vm *vm, vm_paddr_t paddr)  	pg = paddr >> vm->page_shift;  	return sparsebit_is_set(region->protected_phy_pages, pg);  } + +__weak bool kvm_arch_has_default_irqchip(void) +{ +	return false; +} diff --git a/tools/testing/selftests/kvm/lib/s390/processor.c b/tools/testing/selftests/kvm/lib/s390/processor.c index 20cfe970e3e3..8ceeb17c819a 100644 --- a/tools/testing/selftests/kvm/lib/s390/processor.c +++ b/tools/testing/selftests/kvm/lib/s390/processor.c @@ -221,3 +221,8 @@ void vcpu_arch_dump(FILE *stream, struct kvm_vcpu *vcpu, uint8_t indent)  void assert_on_unhandled_exception(struct kvm_vcpu *vcpu)  {  } + +bool kvm_arch_has_default_irqchip(void) +{ +	return true; +} diff --git a/tools/testing/selftests/kvm/lib/test_util.c b/tools/testing/selftests/kvm/lib/test_util.c index 03eb99af9b8d..8a1848586a85 100644 --- a/tools/testing/selftests/kvm/lib/test_util.c +++ b/tools/testing/selftests/kvm/lib/test_util.c @@ -18,6 +18,13 @@  #include "test_util.h" +sigjmp_buf expect_sigbus_jmpbuf; + +void __attribute__((used)) expect_sigbus_handler(int signum) +{ +	siglongjmp(expect_sigbus_jmpbuf, 1); +} +  /*   * Random number generator that is usable from guest code. This is the   * Park-Miller LCG using standard constants. diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c index c748cd9b2eef..b418502c5ecc 100644 --- a/tools/testing/selftests/kvm/lib/x86/processor.c +++ b/tools/testing/selftests/kvm/lib/x86/processor.c @@ -1318,3 +1318,8 @@ bool sys_clocksource_is_based_on_tsc(void)  	return ret;  } + +bool kvm_arch_has_default_irqchip(void) +{ +	return true; +} diff --git a/tools/testing/selftests/kvm/mmu_stress_test.c b/tools/testing/selftests/kvm/mmu_stress_test.c index 6a437d2be9fa..37b7e6524533 100644 --- a/tools/testing/selftests/kvm/mmu_stress_test.c +++ b/tools/testing/selftests/kvm/mmu_stress_test.c @@ -339,8 +339,7 @@ int main(int argc, char *argv[])  	TEST_ASSERT(max_gpa > (4 * slot_size), "MAXPHYADDR <4gb ");  	fd = kvm_memfd_alloc(slot_size, hugepages); -	mem = mmap(NULL, slot_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); -	TEST_ASSERT(mem != MAP_FAILED, "mmap() failed"); +	mem = kvm_mmap(slot_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd);  	TEST_ASSERT(!madvise(mem, slot_size, MADV_NOHUGEPAGE), "madvise() failed"); @@ -413,7 +412,7 @@ int main(int argc, char *argv[])  	for (slot = (slot - 1) & ~1ull; slot >= first_slot; slot -= 2)  		vm_set_user_memory_region(vm, slot, 0, 0, 0, NULL); -	munmap(mem, slot_size / 2); +	kvm_munmap(mem, slot_size / 2);  	/* Sanity check that the vCPUs actually ran. */  	for (i = 0; i < nr_vcpus; i++) diff --git a/tools/testing/selftests/kvm/pre_fault_memory_test.c b/tools/testing/selftests/kvm/pre_fault_memory_test.c index 0350a8896a2f..f04768c1d2e4 100644 --- a/tools/testing/selftests/kvm/pre_fault_memory_test.c +++ b/tools/testing/selftests/kvm/pre_fault_memory_test.c @@ -10,6 +10,7 @@  #include <test_util.h>  #include <kvm_util.h>  #include <processor.h> +#include <pthread.h>  /* Arbitrarily chosen values */  #define TEST_SIZE		(SZ_2M + PAGE_SIZE) @@ -30,18 +31,66 @@ static void guest_code(uint64_t base_gpa)  	GUEST_DONE();  } -static void pre_fault_memory(struct kvm_vcpu *vcpu, u64 gpa, u64 size, -			     u64 left) +struct slot_worker_data { +	struct kvm_vm *vm; +	u64 gpa; +	uint32_t flags; +	bool worker_ready; +	bool prefault_ready; +	bool recreate_slot; +}; + +static void *delete_slot_worker(void *__data) +{ +	struct slot_worker_data *data = __data; +	struct kvm_vm *vm = data->vm; + +	WRITE_ONCE(data->worker_ready, true); + +	while (!READ_ONCE(data->prefault_ready)) +		cpu_relax(); + +	vm_mem_region_delete(vm, TEST_SLOT); + +	while (!READ_ONCE(data->recreate_slot)) +		cpu_relax(); + +	vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, data->gpa, +				    TEST_SLOT, TEST_NPAGES, data->flags); + +	return NULL; +} + +static void pre_fault_memory(struct kvm_vcpu *vcpu, u64 base_gpa, u64 offset, +			     u64 size, u64 expected_left, bool private)  {  	struct kvm_pre_fault_memory range = { -		.gpa = gpa, +		.gpa = base_gpa + offset,  		.size = size,  		.flags = 0,  	}; -	u64 prev; +	struct slot_worker_data data = { +		.vm = vcpu->vm, +		.gpa = base_gpa, +		.flags = private ? KVM_MEM_GUEST_MEMFD : 0, +	}; +	bool slot_recreated = false; +	pthread_t slot_worker;  	int ret, save_errno; +	u64 prev; + +	/* +	 * Concurrently delete (and recreate) the slot to test KVM's handling +	 * of a racing memslot deletion with prefaulting. +	 */ +	pthread_create(&slot_worker, NULL, delete_slot_worker, &data); -	do { +	while (!READ_ONCE(data.worker_ready)) +		cpu_relax(); + +	WRITE_ONCE(data.prefault_ready, true); + +	for (;;) {  		prev = range.size;  		ret = __vcpu_ioctl(vcpu, KVM_PRE_FAULT_MEMORY, &range);  		save_errno = errno; @@ -49,18 +98,65 @@ static void pre_fault_memory(struct kvm_vcpu *vcpu, u64 gpa, u64 size,  			    "%sexpecting range.size to change on %s",  			    ret < 0 ? "not " : "",  			    ret < 0 ? "failure" : "success"); -	} while (ret >= 0 ? range.size : save_errno == EINTR); -	TEST_ASSERT(range.size == left, -		    "Completed with %lld bytes left, expected %" PRId64, -		    range.size, left); +		/* +		 * Immediately retry prefaulting if KVM was interrupted by an +		 * unrelated signal/event. +		 */ +		if (ret < 0 && save_errno == EINTR) +			continue; + +		/* +		 * Tell the worker to recreate the slot in order to complete +		 * prefaulting (if prefault didn't already succeed before the +		 * slot was deleted) and/or to prepare for the next testcase. +		 * Wait for the worker to exit so that the next invocation of +		 * prefaulting is guaranteed to complete (assuming no KVM bugs). +		 */ +		if (!slot_recreated) { +			WRITE_ONCE(data.recreate_slot, true); +			pthread_join(slot_worker, NULL); +			slot_recreated = true; + +			/* +			 * Retry prefaulting to get a stable result, i.e. to +			 * avoid seeing random EAGAIN failures.  Don't retry if +			 * prefaulting already succeeded, as KVM disallows +			 * prefaulting with size=0, i.e. blindly retrying would +			 * result in test failures due to EINVAL.  KVM should +			 * always return success if all bytes are prefaulted, +			 * i.e. there is no need to guard against EAGAIN being +			 * returned. +			 */ +			if (range.size) +				continue; +		} + +		/* +		 * All done if there are no remaining bytes to prefault, or if +		 * prefaulting failed (EINTR was handled above, and EAGAIN due +		 * to prefaulting a memslot that's being actively deleted should +		 * be impossible since the memslot has already been recreated). +		 */ +		if (!range.size || ret < 0) +			break; +	} -	if (left == 0) -		__TEST_ASSERT_VM_VCPU_IOCTL(!ret, "KVM_PRE_FAULT_MEMORY", ret, vcpu->vm); +	TEST_ASSERT(range.size == expected_left, +		    "Completed with %llu bytes left, expected %lu", +		    range.size, expected_left); + +	/* +	 * Assert success if prefaulting the entire range should succeed, i.e. +	 * complete with no bytes remaining.  Otherwise prefaulting should have +	 * failed due to ENOENT (due to RET_PF_EMULATE for emulated MMIO when +	 * no memslot exists). +	 */ +	if (!expected_left) +		TEST_ASSERT_VM_VCPU_IOCTL(!ret, KVM_PRE_FAULT_MEMORY, ret, vcpu->vm);  	else -		/* No memory slot causes RET_PF_EMULATE. it results in -ENOENT. */ -		__TEST_ASSERT_VM_VCPU_IOCTL(ret && save_errno == ENOENT, -					    "KVM_PRE_FAULT_MEMORY", ret, vcpu->vm); +		TEST_ASSERT_VM_VCPU_IOCTL(ret && save_errno == ENOENT, +					  KVM_PRE_FAULT_MEMORY, ret, vcpu->vm);  }  static void __test_pre_fault_memory(unsigned long vm_type, bool private) @@ -97,9 +193,10 @@ static void __test_pre_fault_memory(unsigned long vm_type, bool private)  	if (private)  		vm_mem_set_private(vm, guest_test_phys_mem, TEST_SIZE); -	pre_fault_memory(vcpu, guest_test_phys_mem, SZ_2M, 0); -	pre_fault_memory(vcpu, guest_test_phys_mem + SZ_2M, PAGE_SIZE * 2, PAGE_SIZE); -	pre_fault_memory(vcpu, guest_test_phys_mem + TEST_SIZE, PAGE_SIZE, PAGE_SIZE); + +	pre_fault_memory(vcpu, guest_test_phys_mem, 0, SZ_2M, 0, private); +	pre_fault_memory(vcpu, guest_test_phys_mem, SZ_2M, PAGE_SIZE * 2, PAGE_SIZE, private); +	pre_fault_memory(vcpu, guest_test_phys_mem, TEST_SIZE, PAGE_SIZE, PAGE_SIZE, private);  	vcpu_args_set(vcpu, 1, guest_test_virt_mem);  	vcpu_run(vcpu); diff --git a/tools/testing/selftests/kvm/s390/ucontrol_test.c b/tools/testing/selftests/kvm/s390/ucontrol_test.c index d265b34c54be..50bc1c38225a 100644 --- a/tools/testing/selftests/kvm/s390/ucontrol_test.c +++ b/tools/testing/selftests/kvm/s390/ucontrol_test.c @@ -142,19 +142,17 @@ FIXTURE_SETUP(uc_kvm)  	self->kvm_run_size = ioctl(self->kvm_fd, KVM_GET_VCPU_MMAP_SIZE, NULL);  	ASSERT_GE(self->kvm_run_size, sizeof(struct kvm_run))  		  TH_LOG(KVM_IOCTL_ERROR(KVM_GET_VCPU_MMAP_SIZE, self->kvm_run_size)); -	self->run = (struct kvm_run *)mmap(NULL, self->kvm_run_size, -		    PROT_READ | PROT_WRITE, MAP_SHARED, self->vcpu_fd, 0); -	ASSERT_NE(self->run, MAP_FAILED); +	self->run = kvm_mmap(self->kvm_run_size, PROT_READ | PROT_WRITE, +			     MAP_SHARED, self->vcpu_fd);  	/**  	 * For virtual cpus that have been created with S390 user controlled  	 * virtual machines, the resulting vcpu fd can be memory mapped at page  	 * offset KVM_S390_SIE_PAGE_OFFSET in order to obtain a memory map of  	 * the virtual cpu's hardware control block.  	 */ -	self->sie_block = (struct kvm_s390_sie_block *)mmap(NULL, PAGE_SIZE, -			  PROT_READ | PROT_WRITE, MAP_SHARED, -			  self->vcpu_fd, KVM_S390_SIE_PAGE_OFFSET << PAGE_SHIFT); -	ASSERT_NE(self->sie_block, MAP_FAILED); +	self->sie_block = __kvm_mmap(PAGE_SIZE, PROT_READ | PROT_WRITE, +				     MAP_SHARED, self->vcpu_fd, +				     KVM_S390_SIE_PAGE_OFFSET << PAGE_SHIFT);  	TH_LOG("VM created %p %p", self->run, self->sie_block); @@ -186,8 +184,8 @@ FIXTURE_SETUP(uc_kvm)  FIXTURE_TEARDOWN(uc_kvm)  { -	munmap(self->sie_block, PAGE_SIZE); -	munmap(self->run, self->kvm_run_size); +	kvm_munmap(self->sie_block, PAGE_SIZE); +	kvm_munmap(self->run, self->kvm_run_size);  	close(self->vcpu_fd);  	close(self->vm_fd);  	close(self->kvm_fd); diff --git a/tools/testing/selftests/kvm/set_memory_region_test.c b/tools/testing/selftests/kvm/set_memory_region_test.c index ce3ac0fd6dfb..7fe427ff9b38 100644 --- a/tools/testing/selftests/kvm/set_memory_region_test.c +++ b/tools/testing/selftests/kvm/set_memory_region_test.c @@ -433,10 +433,10 @@ static void test_add_max_memory_regions(void)  	pr_info("Adding slots 0..%i, each memory region with %dK size\n",  		(max_mem_slots - 1), MEM_REGION_SIZE >> 10); -	mem = mmap(NULL, (size_t)max_mem_slots * MEM_REGION_SIZE + alignment, -		   PROT_READ | PROT_WRITE, -		   MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0); -	TEST_ASSERT(mem != MAP_FAILED, "Failed to mmap() host"); + +	mem = kvm_mmap((size_t)max_mem_slots * MEM_REGION_SIZE + alignment, +		       PROT_READ | PROT_WRITE, +		       MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1);  	mem_aligned = (void *)(((size_t) mem + alignment - 1) & ~(alignment - 1));  	for (slot = 0; slot < max_mem_slots; slot++) @@ -446,9 +446,8 @@ static void test_add_max_memory_regions(void)  					  mem_aligned + (uint64_t)slot * MEM_REGION_SIZE);  	/* Check it cannot be added memory slots beyond the limit */ -	mem_extra = mmap(NULL, MEM_REGION_SIZE, PROT_READ | PROT_WRITE, -			 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -	TEST_ASSERT(mem_extra != MAP_FAILED, "Failed to mmap() host"); +	mem_extra = kvm_mmap(MEM_REGION_SIZE, PROT_READ | PROT_WRITE, +			     MAP_PRIVATE | MAP_ANONYMOUS, -1);  	ret = __vm_set_user_memory_region(vm, max_mem_slots, 0,  					  (uint64_t)max_mem_slots * MEM_REGION_SIZE, @@ -456,8 +455,8 @@ static void test_add_max_memory_regions(void)  	TEST_ASSERT(ret == -1 && errno == EINVAL,  		    "Adding one more memory slot should fail with EINVAL"); -	munmap(mem, (size_t)max_mem_slots * MEM_REGION_SIZE + alignment); -	munmap(mem_extra, MEM_REGION_SIZE); +	kvm_munmap(mem, (size_t)max_mem_slots * MEM_REGION_SIZE + alignment); +	kvm_munmap(mem_extra, MEM_REGION_SIZE);  	kvm_vm_free(vm);  } | 
