brintos

brintos / linux-shallow public Read only

0
0
Text · 18.3 KiB · e32dd59 Raw
696 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Test for s390x CMMA migration4 *5 * Copyright IBM Corp. 20236 *7 * Authors:8 *  Nico Boehr <nrb@linux.ibm.com>9 */10#include <fcntl.h>11#include <stdio.h>12#include <stdlib.h>13#include <string.h>14#include <sys/ioctl.h>15 16#include "test_util.h"17#include "kvm_util.h"18#include "kselftest.h"19#include "ucall_common.h"20#include "processor.h"21 22#define MAIN_PAGE_COUNT 51223 24#define TEST_DATA_PAGE_COUNT 51225#define TEST_DATA_MEMSLOT 126#define TEST_DATA_START_GFN PAGE_SIZE27 28#define TEST_DATA_TWO_PAGE_COUNT 25629#define TEST_DATA_TWO_MEMSLOT 230#define TEST_DATA_TWO_START_GFN (2 * PAGE_SIZE)31 32static char cmma_value_buf[MAIN_PAGE_COUNT + TEST_DATA_PAGE_COUNT];33 34/**35 * Dirty CMMA attributes of exactly one page in the TEST_DATA memslot,36 * so use_cmma goes on and the CMMA related ioctls do something.37 */38static void guest_do_one_essa(void)39{40	asm volatile(41		/* load TEST_DATA_START_GFN into r1 */42		"	llilf 1,%[start_gfn]\n"43		/* calculate the address from the gfn */44		"	sllg 1,1,12(0)\n"45		/* set the first page in TEST_DATA memslot to STABLE */46		"	.insn rrf,0xb9ab0000,2,1,1,0\n"47		/* hypercall */48		"	diag 0,0,0x501\n"49		"0:	j 0b"50		:51		: [start_gfn] "L"(TEST_DATA_START_GFN)52		: "r1", "r2", "memory", "cc"53	);54}55 56/**57 * Touch CMMA attributes of all pages in TEST_DATA memslot. Set them to stable58 * state.59 */60static void guest_dirty_test_data(void)61{62	asm volatile(63		/* r1 = TEST_DATA_START_GFN */64		"	xgr 1,1\n"65		"	llilf 1,%[start_gfn]\n"66		/* r5 = TEST_DATA_PAGE_COUNT */67		"	lghi 5,%[page_count]\n"68		/* r5 += r1 */69		"2:	agfr 5,1\n"70		/* r2 = r1 << PAGE_SHIFT */71		"1:	sllg 2,1,12(0)\n"72		/* essa(r4, r2, SET_STABLE) */73		"	.insn rrf,0xb9ab0000,4,2,1,0\n"74		/* i++ */75		"	agfi 1,1\n"76		/* if r1 < r5 goto 1 */77		"	cgrjl 1,5,1b\n"78		/* hypercall */79		"	diag 0,0,0x501\n"80		"0:	j 0b"81		:82		: [start_gfn] "L"(TEST_DATA_START_GFN),83		  [page_count] "L"(TEST_DATA_PAGE_COUNT)84		:85			/* the counter in our loop over the pages */86			"r1",87			/* the calculated page physical address */88			"r2",89			/* ESSA output register */90			"r4",91			/* last page */92			"r5",93			"cc", "memory"94	);95}96 97static void create_main_memslot(struct kvm_vm *vm)98{99	int i;100 101	vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, 0, 0, MAIN_PAGE_COUNT, 0);102	/* set the array of memslots to zero like __vm_create does */103	for (i = 0; i < NR_MEM_REGIONS; i++)104		vm->memslots[i] = 0;105}106 107static void create_test_memslot(struct kvm_vm *vm)108{109	vm_userspace_mem_region_add(vm,110				    VM_MEM_SRC_ANONYMOUS,111				    TEST_DATA_START_GFN << vm->page_shift,112				    TEST_DATA_MEMSLOT,113				    TEST_DATA_PAGE_COUNT,114				    0115				   );116	vm->memslots[MEM_REGION_TEST_DATA] = TEST_DATA_MEMSLOT;117}118 119static void create_memslots(struct kvm_vm *vm)120{121	/*122	 * Our VM has the following memory layout:123	 * +------+---------------------------+124	 * | GFN  | Memslot                   |125	 * +------+---------------------------+126	 * | 0    |                           |127	 * | ...  | MAIN (Code, Stack, ...)   |128	 * | 511  |                           |129	 * +------+---------------------------+130	 * | 4096 |                           |131	 * | ...  | TEST_DATA                 |132	 * | 4607 |                           |133	 * +------+---------------------------+134	 */135	create_main_memslot(vm);136	create_test_memslot(vm);137}138 139static void finish_vm_setup(struct kvm_vm *vm)140{141	struct userspace_mem_region *slot0;142 143	kvm_vm_elf_load(vm, program_invocation_name);144 145	slot0 = memslot2region(vm, 0);146	ucall_init(vm, slot0->region.guest_phys_addr + slot0->region.memory_size);147 148	kvm_arch_vm_post_create(vm);149}150 151static struct kvm_vm *create_vm_two_memslots(void)152{153	struct kvm_vm *vm;154 155	vm = vm_create_barebones();156 157	create_memslots(vm);158 159	finish_vm_setup(vm);160 161	return vm;162}163 164static void enable_cmma(struct kvm_vm *vm)165{166	int r;167 168	r = __kvm_device_attr_set(vm->fd, KVM_S390_VM_MEM_CTRL, KVM_S390_VM_MEM_ENABLE_CMMA, NULL);169	TEST_ASSERT(!r, "enabling cmma failed r=%d errno=%d", r, errno);170}171 172static void enable_dirty_tracking(struct kvm_vm *vm)173{174	vm_mem_region_set_flags(vm, 0, KVM_MEM_LOG_DIRTY_PAGES);175	vm_mem_region_set_flags(vm, TEST_DATA_MEMSLOT, KVM_MEM_LOG_DIRTY_PAGES);176}177 178static int __enable_migration_mode(struct kvm_vm *vm)179{180	return __kvm_device_attr_set(vm->fd,181				     KVM_S390_VM_MIGRATION,182				     KVM_S390_VM_MIGRATION_START,183				     NULL184				    );185}186 187static void enable_migration_mode(struct kvm_vm *vm)188{189	int r = __enable_migration_mode(vm);190 191	TEST_ASSERT(!r, "enabling migration mode failed r=%d errno=%d", r, errno);192}193 194static bool is_migration_mode_on(struct kvm_vm *vm)195{196	u64 out;197	int r;198 199	r = __kvm_device_attr_get(vm->fd,200				  KVM_S390_VM_MIGRATION,201				  KVM_S390_VM_MIGRATION_STATUS,202				  &out203				 );204	TEST_ASSERT(!r, "getting migration mode status failed r=%d errno=%d", r, errno);205	return out;206}207 208static int vm_get_cmma_bits(struct kvm_vm *vm, u64 flags, int *errno_out)209{210	struct kvm_s390_cmma_log args;211	int rc;212 213	errno = 0;214 215	args = (struct kvm_s390_cmma_log){216		.start_gfn = 0,217		.count = sizeof(cmma_value_buf),218		.flags = flags,219		.values = (__u64)&cmma_value_buf[0]220	};221	rc = __vm_ioctl(vm, KVM_S390_GET_CMMA_BITS, &args);222 223	*errno_out = errno;224	return rc;225}226 227static void test_get_cmma_basic(void)228{229	struct kvm_vm *vm = create_vm_two_memslots();230	struct kvm_vcpu *vcpu;231	int rc, errno_out;232 233	/* GET_CMMA_BITS without CMMA enabled should fail */234	rc = vm_get_cmma_bits(vm, 0, &errno_out);235	TEST_ASSERT_EQ(rc, -1);236	TEST_ASSERT_EQ(errno_out, ENXIO);237 238	enable_cmma(vm);239	vcpu = vm_vcpu_add(vm, 1, guest_do_one_essa);240 241	vcpu_run(vcpu);242 243	/* GET_CMMA_BITS without migration mode and without peeking should fail */244	rc = vm_get_cmma_bits(vm, 0, &errno_out);245	TEST_ASSERT_EQ(rc, -1);246	TEST_ASSERT_EQ(errno_out, EINVAL);247 248	/* GET_CMMA_BITS without migration mode and with peeking should work */249	rc = vm_get_cmma_bits(vm, KVM_S390_CMMA_PEEK, &errno_out);250	TEST_ASSERT_EQ(rc, 0);251	TEST_ASSERT_EQ(errno_out, 0);252 253	enable_dirty_tracking(vm);254	enable_migration_mode(vm);255 256	/* GET_CMMA_BITS with invalid flags */257	rc = vm_get_cmma_bits(vm, 0xfeedc0fe, &errno_out);258	TEST_ASSERT_EQ(rc, -1);259	TEST_ASSERT_EQ(errno_out, EINVAL);260 261	kvm_vm_free(vm);262}263 264static void assert_exit_was_hypercall(struct kvm_vcpu *vcpu)265{266	TEST_ASSERT_EQ(vcpu->run->exit_reason, 13);267	TEST_ASSERT_EQ(vcpu->run->s390_sieic.icptcode, 4);268	TEST_ASSERT_EQ(vcpu->run->s390_sieic.ipa, 0x8300);269	TEST_ASSERT_EQ(vcpu->run->s390_sieic.ipb, 0x5010000);270}271 272static void test_migration_mode(void)273{274	struct kvm_vm *vm = vm_create_barebones();275	struct kvm_vcpu *vcpu;276	u64 orig_psw;277	int rc;278 279	/* enabling migration mode on a VM without memory should fail */280	rc = __enable_migration_mode(vm);281	TEST_ASSERT_EQ(rc, -1);282	TEST_ASSERT_EQ(errno, EINVAL);283	TEST_ASSERT(!is_migration_mode_on(vm), "migration mode should still be off");284	errno = 0;285 286	create_memslots(vm);287	finish_vm_setup(vm);288 289	enable_cmma(vm);290	vcpu = vm_vcpu_add(vm, 1, guest_do_one_essa);291	orig_psw = vcpu->run->psw_addr;292 293	/*294	 * Execute one essa instruction in the guest. Otherwise the guest will295	 * not have use_cmm enabled and GET_CMMA_BITS will return no pages.296	 */297	vcpu_run(vcpu);298	assert_exit_was_hypercall(vcpu);299 300	/* migration mode when memslots have dirty tracking off should fail */301	rc = __enable_migration_mode(vm);302	TEST_ASSERT_EQ(rc, -1);303	TEST_ASSERT_EQ(errno, EINVAL);304	TEST_ASSERT(!is_migration_mode_on(vm), "migration mode should still be off");305	errno = 0;306 307	/* enable dirty tracking */308	enable_dirty_tracking(vm);309 310	/* enabling migration mode should work now */311	rc = __enable_migration_mode(vm);312	TEST_ASSERT_EQ(rc, 0);313	TEST_ASSERT(is_migration_mode_on(vm), "migration mode should be on");314	errno = 0;315 316	/* execute another ESSA instruction to see this goes fine */317	vcpu->run->psw_addr = orig_psw;318	vcpu_run(vcpu);319	assert_exit_was_hypercall(vcpu);320 321	/*322	 * With migration mode on, create a new memslot with dirty tracking off.323	 * This should turn off migration mode.324	 */325	TEST_ASSERT(is_migration_mode_on(vm), "migration mode should be on");326	vm_userspace_mem_region_add(vm,327				    VM_MEM_SRC_ANONYMOUS,328				    TEST_DATA_TWO_START_GFN << vm->page_shift,329				    TEST_DATA_TWO_MEMSLOT,330				    TEST_DATA_TWO_PAGE_COUNT,331				    0332				   );333	TEST_ASSERT(!is_migration_mode_on(vm),334		    "creating memslot without dirty tracking turns off migration mode"335		   );336 337	/* ESSA instructions should still execute fine */338	vcpu->run->psw_addr = orig_psw;339	vcpu_run(vcpu);340	assert_exit_was_hypercall(vcpu);341 342	/*343	 * Turn on dirty tracking on the new memslot.344	 * It should be possible to turn migration mode back on again.345	 */346	vm_mem_region_set_flags(vm, TEST_DATA_TWO_MEMSLOT, KVM_MEM_LOG_DIRTY_PAGES);347	rc = __enable_migration_mode(vm);348	TEST_ASSERT_EQ(rc, 0);349	TEST_ASSERT(is_migration_mode_on(vm), "migration mode should be on");350	errno = 0;351 352	/*353	 * Turn off dirty tracking again, this time with just a flag change.354	 * Again, migration mode should turn off.355	 */356	TEST_ASSERT(is_migration_mode_on(vm), "migration mode should be on");357	vm_mem_region_set_flags(vm, TEST_DATA_TWO_MEMSLOT, 0);358	TEST_ASSERT(!is_migration_mode_on(vm),359		    "disabling dirty tracking should turn off migration mode"360		   );361 362	/* ESSA instructions should still execute fine */363	vcpu->run->psw_addr = orig_psw;364	vcpu_run(vcpu);365	assert_exit_was_hypercall(vcpu);366 367	kvm_vm_free(vm);368}369 370/**371 * Given a VM with the MAIN and TEST_DATA memslot, assert that both slots have372 * CMMA attributes of all pages in both memslots and nothing more dirty.373 * This has the useful side effect of ensuring nothing is CMMA dirty after this374 * function.375 */376static void assert_all_slots_cmma_dirty(struct kvm_vm *vm)377{378	struct kvm_s390_cmma_log args;379 380	/*381	 * First iteration - everything should be dirty.382	 * Start at the main memslot...383	 */384	args = (struct kvm_s390_cmma_log){385		.start_gfn = 0,386		.count = sizeof(cmma_value_buf),387		.flags = 0,388		.values = (__u64)&cmma_value_buf[0]389	};390	memset(cmma_value_buf, 0xff, sizeof(cmma_value_buf));391	vm_ioctl(vm, KVM_S390_GET_CMMA_BITS, &args);392	TEST_ASSERT_EQ(args.count, MAIN_PAGE_COUNT);393	TEST_ASSERT_EQ(args.remaining, TEST_DATA_PAGE_COUNT);394	TEST_ASSERT_EQ(args.start_gfn, 0);395 396	/* ...and then - after a hole - the TEST_DATA memslot should follow */397	args = (struct kvm_s390_cmma_log){398		.start_gfn = MAIN_PAGE_COUNT,399		.count = sizeof(cmma_value_buf),400		.flags = 0,401		.values = (__u64)&cmma_value_buf[0]402	};403	memset(cmma_value_buf, 0xff, sizeof(cmma_value_buf));404	vm_ioctl(vm, KVM_S390_GET_CMMA_BITS, &args);405	TEST_ASSERT_EQ(args.count, TEST_DATA_PAGE_COUNT);406	TEST_ASSERT_EQ(args.start_gfn, TEST_DATA_START_GFN);407	TEST_ASSERT_EQ(args.remaining, 0);408 409	/* ...and nothing else should be there */410	args = (struct kvm_s390_cmma_log){411		.start_gfn = TEST_DATA_START_GFN + TEST_DATA_PAGE_COUNT,412		.count = sizeof(cmma_value_buf),413		.flags = 0,414		.values = (__u64)&cmma_value_buf[0]415	};416	memset(cmma_value_buf, 0xff, sizeof(cmma_value_buf));417	vm_ioctl(vm, KVM_S390_GET_CMMA_BITS, &args);418	TEST_ASSERT_EQ(args.count, 0);419	TEST_ASSERT_EQ(args.start_gfn, 0);420	TEST_ASSERT_EQ(args.remaining, 0);421}422 423/**424 * Given a VM, assert no pages are CMMA dirty.425 */426static void assert_no_pages_cmma_dirty(struct kvm_vm *vm)427{428	struct kvm_s390_cmma_log args;429 430	/* If we start from GFN 0 again, nothing should be dirty. */431	args = (struct kvm_s390_cmma_log){432		.start_gfn = 0,433		.count = sizeof(cmma_value_buf),434		.flags = 0,435		.values = (__u64)&cmma_value_buf[0]436	};437	memset(cmma_value_buf, 0xff, sizeof(cmma_value_buf));438	vm_ioctl(vm, KVM_S390_GET_CMMA_BITS, &args);439	if (args.count || args.remaining || args.start_gfn)440		TEST_FAIL("pages are still dirty start_gfn=0x%llx count=%u remaining=%llu",441			  args.start_gfn,442			  args.count,443			  args.remaining444			 );445}446 447static void test_get_inital_dirty(void)448{449	struct kvm_vm *vm = create_vm_two_memslots();450	struct kvm_vcpu *vcpu;451 452	enable_cmma(vm);453	vcpu = vm_vcpu_add(vm, 1, guest_do_one_essa);454 455	/*456	 * Execute one essa instruction in the guest. Otherwise the guest will457	 * not have use_cmm enabled and GET_CMMA_BITS will return no pages.458	 */459	vcpu_run(vcpu);460	assert_exit_was_hypercall(vcpu);461 462	enable_dirty_tracking(vm);463	enable_migration_mode(vm);464 465	assert_all_slots_cmma_dirty(vm);466 467	/* Start from the beginning again and make sure nothing else is dirty */468	assert_no_pages_cmma_dirty(vm);469 470	kvm_vm_free(vm);471}472 473static void query_cmma_range(struct kvm_vm *vm,474			     u64 start_gfn, u64 gfn_count,475			     struct kvm_s390_cmma_log *res_out)476{477	*res_out = (struct kvm_s390_cmma_log){478		.start_gfn = start_gfn,479		.count = gfn_count,480		.flags = 0,481		.values = (__u64)&cmma_value_buf[0]482	};483	memset(cmma_value_buf, 0xff, sizeof(cmma_value_buf));484	vm_ioctl(vm, KVM_S390_GET_CMMA_BITS, res_out);485}486 487/**488 * Assert the given cmma_log struct that was executed by query_cmma_range()489 * indicates the first dirty gfn is at first_dirty_gfn and contains exactly490 * dirty_gfn_count CMMA values.491 */492static void assert_cmma_dirty(u64 first_dirty_gfn,493			      u64 dirty_gfn_count,494			      const struct kvm_s390_cmma_log *res)495{496	TEST_ASSERT_EQ(res->start_gfn, first_dirty_gfn);497	TEST_ASSERT_EQ(res->count, dirty_gfn_count);498	for (size_t i = 0; i < dirty_gfn_count; i++)499		TEST_ASSERT_EQ(cmma_value_buf[0], 0x0); /* stable state */500	TEST_ASSERT_EQ(cmma_value_buf[dirty_gfn_count], 0xff); /* not touched */501}502 503static void test_get_skip_holes(void)504{505	size_t gfn_offset;506	struct kvm_vm *vm = create_vm_two_memslots();507	struct kvm_s390_cmma_log log;508	struct kvm_vcpu *vcpu;509	u64 orig_psw;510 511	enable_cmma(vm);512	vcpu = vm_vcpu_add(vm, 1, guest_dirty_test_data);513 514	orig_psw = vcpu->run->psw_addr;515 516	/*517	 * Execute some essa instructions in the guest. Otherwise the guest will518	 * not have use_cmm enabled and GET_CMMA_BITS will return no pages.519	 */520	vcpu_run(vcpu);521	assert_exit_was_hypercall(vcpu);522 523	enable_dirty_tracking(vm);524	enable_migration_mode(vm);525 526	/* un-dirty all pages */527	assert_all_slots_cmma_dirty(vm);528 529	/* Then, dirty just the TEST_DATA memslot */530	vcpu->run->psw_addr = orig_psw;531	vcpu_run(vcpu);532 533	gfn_offset = TEST_DATA_START_GFN;534	/**535	 * Query CMMA attributes of one page, starting at page 0. Since the536	 * main memslot was not touched by the VM, this should yield the first537	 * page of the TEST_DATA memslot.538	 * The dirty bitmap should now look like this:539	 * 0: not dirty540	 * [0x1, 0x200): dirty541	 */542	query_cmma_range(vm, 0, 1, &log);543	assert_cmma_dirty(gfn_offset, 1, &log);544	gfn_offset++;545 546	/**547	 * Query CMMA attributes of 32 (0x20) pages past the end of the TEST_DATA548	 * memslot. This should wrap back to the beginning of the TEST_DATA549	 * memslot, page 1.550	 * The dirty bitmap should now look like this:551	 * [0, 0x21): not dirty552	 * [0x21, 0x200): dirty553	 */554	query_cmma_range(vm, TEST_DATA_START_GFN + TEST_DATA_PAGE_COUNT, 0x20, &log);555	assert_cmma_dirty(gfn_offset, 0x20, &log);556	gfn_offset += 0x20;557 558	/* Skip 32 pages */559	gfn_offset += 0x20;560 561	/**562	 * After skipping 32 pages, query the next 32 (0x20) pages.563	 * The dirty bitmap should now look like this:564	 * [0, 0x21): not dirty565	 * [0x21, 0x41): dirty566	 * [0x41, 0x61): not dirty567	 * [0x61, 0x200): dirty568	 */569	query_cmma_range(vm, gfn_offset, 0x20, &log);570	assert_cmma_dirty(gfn_offset, 0x20, &log);571	gfn_offset += 0x20;572 573	/**574	 * Query 1 page from the beginning of the TEST_DATA memslot. This should575	 * yield page 0x21.576	 * The dirty bitmap should now look like this:577	 * [0, 0x22): not dirty578	 * [0x22, 0x41): dirty579	 * [0x41, 0x61): not dirty580	 * [0x61, 0x200): dirty581	 */582	query_cmma_range(vm, TEST_DATA_START_GFN, 1, &log);583	assert_cmma_dirty(TEST_DATA_START_GFN + 0x21, 1, &log);584	gfn_offset++;585 586	/**587	 * Query 15 (0xF) pages from page 0x23 in TEST_DATA memslot.588	 * This should yield pages [0x23, 0x33).589	 * The dirty bitmap should now look like this:590	 * [0, 0x22): not dirty591	 * 0x22: dirty592	 * [0x23, 0x33): not dirty593	 * [0x33, 0x41): dirty594	 * [0x41, 0x61): not dirty595	 * [0x61, 0x200): dirty596	 */597	gfn_offset = TEST_DATA_START_GFN + 0x23;598	query_cmma_range(vm, gfn_offset, 15, &log);599	assert_cmma_dirty(gfn_offset, 15, &log);600 601	/**602	 * Query 17 (0x11) pages from page 0x22 in TEST_DATA memslot.603	 * This should yield page [0x22, 0x33)604	 * The dirty bitmap should now look like this:605	 * [0, 0x33): not dirty606	 * [0x33, 0x41): dirty607	 * [0x41, 0x61): not dirty608	 * [0x61, 0x200): dirty609	 */610	gfn_offset = TEST_DATA_START_GFN + 0x22;611	query_cmma_range(vm, gfn_offset, 17, &log);612	assert_cmma_dirty(gfn_offset, 17, &log);613 614	/**615	 * Query 25 (0x19) pages from page 0x40 in TEST_DATA memslot.616	 * This should yield page 0x40 and nothing more, since there are more617	 * than 16 non-dirty pages after page 0x40.618	 * The dirty bitmap should now look like this:619	 * [0, 0x33): not dirty620	 * [0x33, 0x40): dirty621	 * [0x40, 0x61): not dirty622	 * [0x61, 0x200): dirty623	 */624	gfn_offset = TEST_DATA_START_GFN + 0x40;625	query_cmma_range(vm, gfn_offset, 25, &log);626	assert_cmma_dirty(gfn_offset, 1, &log);627 628	/**629	 * Query pages [0x33, 0x40).630	 * The dirty bitmap should now look like this:631	 * [0, 0x61): not dirty632	 * [0x61, 0x200): dirty633	 */634	gfn_offset = TEST_DATA_START_GFN + 0x33;635	query_cmma_range(vm, gfn_offset, 0x40 - 0x33, &log);636	assert_cmma_dirty(gfn_offset, 0x40 - 0x33, &log);637 638	/**639	 * Query the remaining pages [0x61, 0x200).640	 */641	gfn_offset = TEST_DATA_START_GFN;642	query_cmma_range(vm, gfn_offset, TEST_DATA_PAGE_COUNT - 0x61, &log);643	assert_cmma_dirty(TEST_DATA_START_GFN + 0x61, TEST_DATA_PAGE_COUNT - 0x61, &log);644 645	assert_no_pages_cmma_dirty(vm);646}647 648struct testdef {649	const char *name;650	void (*test)(void);651} testlist[] = {652	{ "migration mode and dirty tracking", test_migration_mode },653	{ "GET_CMMA_BITS: basic calls", test_get_cmma_basic },654	{ "GET_CMMA_BITS: all pages are dirty initally", test_get_inital_dirty },655	{ "GET_CMMA_BITS: holes are skipped", test_get_skip_holes },656};657 658/**659 * The kernel may support CMMA, but the machine may not (i.e. if running as660 * guest-3).661 *662 * In this case, the CMMA capabilities are all there, but the CMMA-related663 * ioctls fail. To find out whether the machine supports CMMA, create a664 * temporary VM and then query the CMMA feature of the VM.665 */666static int machine_has_cmma(void)667{668	struct kvm_vm *vm = vm_create_barebones();669	int r;670 671	r = !__kvm_has_device_attr(vm->fd, KVM_S390_VM_MEM_CTRL, KVM_S390_VM_MEM_ENABLE_CMMA);672	kvm_vm_free(vm);673 674	return r;675}676 677int main(int argc, char *argv[])678{679	int idx;680 681	TEST_REQUIRE(kvm_has_cap(KVM_CAP_SYNC_REGS));682	TEST_REQUIRE(kvm_has_cap(KVM_CAP_S390_CMMA_MIGRATION));683	TEST_REQUIRE(machine_has_cmma());684 685	ksft_print_header();686 687	ksft_set_plan(ARRAY_SIZE(testlist));688 689	for (idx = 0; idx < ARRAY_SIZE(testlist); idx++) {690		testlist[idx].test();691		ksft_test_result_pass("%s\n", testlist[idx].name);692	}693 694	ksft_finished();	/* Print results and exit() accordingly */695}696