xref: /aosp_15_r20/external/ltp/testcases/kernel/kvm/lib_host.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later
2*49cdfc7eSAndroid Build Coastguard Worker /*
3*49cdfc7eSAndroid Build Coastguard Worker  * Copyright (C) 2021 SUSE LLC <[email protected]>
4*49cdfc7eSAndroid Build Coastguard Worker  *
5*49cdfc7eSAndroid Build Coastguard Worker  * KVM host library for setting up and running virtual machine tests.
6*49cdfc7eSAndroid Build Coastguard Worker  */
7*49cdfc7eSAndroid Build Coastguard Worker 
8*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
9*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
10*49cdfc7eSAndroid Build Coastguard Worker 
11*49cdfc7eSAndroid Build Coastguard Worker #define TST_NO_DEFAULT_MAIN
12*49cdfc7eSAndroid Build Coastguard Worker #include "tst_test.h"
13*49cdfc7eSAndroid Build Coastguard Worker #include "tst_clocks.h"
14*49cdfc7eSAndroid Build Coastguard Worker #include "tst_timer.h"
15*49cdfc7eSAndroid Build Coastguard Worker #include "kvm_host.h"
16*49cdfc7eSAndroid Build Coastguard Worker 
17*49cdfc7eSAndroid Build Coastguard Worker static struct tst_kvm_instance test_vm = { .vm_fd = -1 };
18*49cdfc7eSAndroid Build Coastguard Worker 
19*49cdfc7eSAndroid Build Coastguard Worker const unsigned char tst_kvm_reset_code[VM_RESET_CODE_SIZE] = {
20*49cdfc7eSAndroid Build Coastguard Worker 	0xea, 0x00, 0x10, 0x00, 0x00	/* JMP 0x1000 */
21*49cdfc7eSAndroid Build Coastguard Worker };
22*49cdfc7eSAndroid Build Coastguard Worker 
tst_kvm_validate_result(int value)23*49cdfc7eSAndroid Build Coastguard Worker void tst_kvm_validate_result(int value)
24*49cdfc7eSAndroid Build Coastguard Worker {
25*49cdfc7eSAndroid Build Coastguard Worker 	int ttype, valid_result[] = {TPASS, TFAIL, TBROK, TWARN, TINFO, TCONF};
26*49cdfc7eSAndroid Build Coastguard Worker 	size_t i;
27*49cdfc7eSAndroid Build Coastguard Worker 
28*49cdfc7eSAndroid Build Coastguard Worker 	if (value == KVM_TNONE)
29*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK, "KVM test did not return any result");
30*49cdfc7eSAndroid Build Coastguard Worker 
31*49cdfc7eSAndroid Build Coastguard Worker 	ttype = TTYPE_RESULT(value);
32*49cdfc7eSAndroid Build Coastguard Worker 
33*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < ARRAY_SIZE(valid_result); i++) {
34*49cdfc7eSAndroid Build Coastguard Worker 		if (ttype == valid_result[i])
35*49cdfc7eSAndroid Build Coastguard Worker 			return;
36*49cdfc7eSAndroid Build Coastguard Worker 	}
37*49cdfc7eSAndroid Build Coastguard Worker 
38*49cdfc7eSAndroid Build Coastguard Worker 	tst_brk(TBROK, "KVM test returned invalid result value %d", value);
39*49cdfc7eSAndroid Build Coastguard Worker }
40*49cdfc7eSAndroid Build Coastguard Worker 
tst_kvm_get_phys_address(const struct tst_kvm_instance * inst,uint64_t addr)41*49cdfc7eSAndroid Build Coastguard Worker uint64_t tst_kvm_get_phys_address(const struct tst_kvm_instance *inst,
42*49cdfc7eSAndroid Build Coastguard Worker 	uint64_t addr)
43*49cdfc7eSAndroid Build Coastguard Worker {
44*49cdfc7eSAndroid Build Coastguard Worker 	struct kvm_translation trans = { .linear_address = addr };
45*49cdfc7eSAndroid Build Coastguard Worker 
46*49cdfc7eSAndroid Build Coastguard Worker 	TEST(ioctl(inst->vcpu_fd, KVM_TRANSLATE, &trans));
47*49cdfc7eSAndroid Build Coastguard Worker 
48*49cdfc7eSAndroid Build Coastguard Worker 	/* ioctl(KVM_TRANSLATE) is not implemented for this arch */
49*49cdfc7eSAndroid Build Coastguard Worker 	if (TST_RET == -1 && TST_ERR == EINVAL)
50*49cdfc7eSAndroid Build Coastguard Worker 		return addr;
51*49cdfc7eSAndroid Build Coastguard Worker 
52*49cdfc7eSAndroid Build Coastguard Worker 	if (TST_RET == -1)
53*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK | TTERRNO, "ioctl(KVM_TRANSLATE) failed");
54*49cdfc7eSAndroid Build Coastguard Worker 
55*49cdfc7eSAndroid Build Coastguard Worker 	if (TST_RET) {
56*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK | TTERRNO,
57*49cdfc7eSAndroid Build Coastguard Worker 			"Invalid ioctl(KVM_TRANSLATE) return value");
58*49cdfc7eSAndroid Build Coastguard Worker 	}
59*49cdfc7eSAndroid Build Coastguard Worker 
60*49cdfc7eSAndroid Build Coastguard Worker 	return trans.valid ? trans.physical_address : 0;
61*49cdfc7eSAndroid Build Coastguard Worker }
62*49cdfc7eSAndroid Build Coastguard Worker 
tst_kvm_find_phys_memslot(const struct tst_kvm_instance * inst,uint64_t paddr)63*49cdfc7eSAndroid Build Coastguard Worker int tst_kvm_find_phys_memslot(const struct tst_kvm_instance *inst,
64*49cdfc7eSAndroid Build Coastguard Worker 	uint64_t paddr)
65*49cdfc7eSAndroid Build Coastguard Worker {
66*49cdfc7eSAndroid Build Coastguard Worker 	int i;
67*49cdfc7eSAndroid Build Coastguard Worker 	uint64_t base;
68*49cdfc7eSAndroid Build Coastguard Worker 
69*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < MAX_KVM_MEMSLOTS; i++) {
70*49cdfc7eSAndroid Build Coastguard Worker 		if (!inst->ram[i].userspace_addr)
71*49cdfc7eSAndroid Build Coastguard Worker 			continue;
72*49cdfc7eSAndroid Build Coastguard Worker 
73*49cdfc7eSAndroid Build Coastguard Worker 		base = inst->ram[i].guest_phys_addr;
74*49cdfc7eSAndroid Build Coastguard Worker 
75*49cdfc7eSAndroid Build Coastguard Worker 		if (paddr >= base && paddr - base < inst->ram[i].memory_size)
76*49cdfc7eSAndroid Build Coastguard Worker 			return i;
77*49cdfc7eSAndroid Build Coastguard Worker 	}
78*49cdfc7eSAndroid Build Coastguard Worker 
79*49cdfc7eSAndroid Build Coastguard Worker 	return -1;
80*49cdfc7eSAndroid Build Coastguard Worker }
81*49cdfc7eSAndroid Build Coastguard Worker 
tst_kvm_find_memslot(const struct tst_kvm_instance * inst,uint64_t addr)82*49cdfc7eSAndroid Build Coastguard Worker int tst_kvm_find_memslot(const struct tst_kvm_instance *inst, uint64_t addr)
83*49cdfc7eSAndroid Build Coastguard Worker {
84*49cdfc7eSAndroid Build Coastguard Worker 	addr = tst_kvm_get_phys_address(inst, addr);
85*49cdfc7eSAndroid Build Coastguard Worker 
86*49cdfc7eSAndroid Build Coastguard Worker 	if (!addr)
87*49cdfc7eSAndroid Build Coastguard Worker 		return -1;
88*49cdfc7eSAndroid Build Coastguard Worker 
89*49cdfc7eSAndroid Build Coastguard Worker 	return tst_kvm_find_phys_memslot(inst, addr);
90*49cdfc7eSAndroid Build Coastguard Worker }
91*49cdfc7eSAndroid Build Coastguard Worker 
tst_kvm_get_memptr(const struct tst_kvm_instance * inst,uint64_t addr)92*49cdfc7eSAndroid Build Coastguard Worker void *tst_kvm_get_memptr(const struct tst_kvm_instance *inst, uint64_t addr)
93*49cdfc7eSAndroid Build Coastguard Worker {
94*49cdfc7eSAndroid Build Coastguard Worker 	int slot;
95*49cdfc7eSAndroid Build Coastguard Worker 	char *ret;
96*49cdfc7eSAndroid Build Coastguard Worker 
97*49cdfc7eSAndroid Build Coastguard Worker 	addr = tst_kvm_get_phys_address(inst, addr);
98*49cdfc7eSAndroid Build Coastguard Worker 
99*49cdfc7eSAndroid Build Coastguard Worker 	if (!addr)
100*49cdfc7eSAndroid Build Coastguard Worker 		return NULL;
101*49cdfc7eSAndroid Build Coastguard Worker 
102*49cdfc7eSAndroid Build Coastguard Worker 	slot = tst_kvm_find_phys_memslot(inst, addr);
103*49cdfc7eSAndroid Build Coastguard Worker 
104*49cdfc7eSAndroid Build Coastguard Worker 	if (slot < 0)
105*49cdfc7eSAndroid Build Coastguard Worker 		return NULL;
106*49cdfc7eSAndroid Build Coastguard Worker 
107*49cdfc7eSAndroid Build Coastguard Worker 	ret = (char *)(uintptr_t)inst->ram[slot].userspace_addr;
108*49cdfc7eSAndroid Build Coastguard Worker 	return ret + (addr - inst->ram[slot].guest_phys_addr);
109*49cdfc7eSAndroid Build Coastguard Worker }
110*49cdfc7eSAndroid Build Coastguard Worker 
tst_kvm_print_result(const struct tst_kvm_instance * inst)111*49cdfc7eSAndroid Build Coastguard Worker void tst_kvm_print_result(const struct tst_kvm_instance *inst)
112*49cdfc7eSAndroid Build Coastguard Worker {
113*49cdfc7eSAndroid Build Coastguard Worker 	int ttype;
114*49cdfc7eSAndroid Build Coastguard Worker 	const struct tst_kvm_result *result = inst->result;
115*49cdfc7eSAndroid Build Coastguard Worker 	const char *file;
116*49cdfc7eSAndroid Build Coastguard Worker 
117*49cdfc7eSAndroid Build Coastguard Worker 	tst_kvm_validate_result(result->result);
118*49cdfc7eSAndroid Build Coastguard Worker 	ttype = TTYPE_RESULT(result->result);
119*49cdfc7eSAndroid Build Coastguard Worker 	file = tst_kvm_get_memptr(inst, result->file_addr);
120*49cdfc7eSAndroid Build Coastguard Worker 
121*49cdfc7eSAndroid Build Coastguard Worker 	if (ttype == TBROK)
122*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk_(file, result->lineno, ttype, "%s", result->message);
123*49cdfc7eSAndroid Build Coastguard Worker 	else
124*49cdfc7eSAndroid Build Coastguard Worker 		tst_res_(file, result->lineno, ttype, "%s", result->message);
125*49cdfc7eSAndroid Build Coastguard Worker }
126*49cdfc7eSAndroid Build Coastguard Worker 
tst_kvm_alloc_memory(struct tst_kvm_instance * inst,unsigned int slot,uint64_t baseaddr,size_t size,unsigned int flags)127*49cdfc7eSAndroid Build Coastguard Worker void *tst_kvm_alloc_memory(struct tst_kvm_instance *inst, unsigned int slot,
128*49cdfc7eSAndroid Build Coastguard Worker 	uint64_t baseaddr, size_t size, unsigned int flags)
129*49cdfc7eSAndroid Build Coastguard Worker {
130*49cdfc7eSAndroid Build Coastguard Worker 	size_t pagesize, offset;
131*49cdfc7eSAndroid Build Coastguard Worker 	char *ret;
132*49cdfc7eSAndroid Build Coastguard Worker 	struct kvm_userspace_memory_region memslot = {
133*49cdfc7eSAndroid Build Coastguard Worker 		.slot = slot,
134*49cdfc7eSAndroid Build Coastguard Worker 		.flags = flags
135*49cdfc7eSAndroid Build Coastguard Worker 	};
136*49cdfc7eSAndroid Build Coastguard Worker 
137*49cdfc7eSAndroid Build Coastguard Worker 	if (slot >= MAX_KVM_MEMSLOTS)
138*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK, "Invalid KVM memory slot %u", slot);
139*49cdfc7eSAndroid Build Coastguard Worker 
140*49cdfc7eSAndroid Build Coastguard Worker 	pagesize = SAFE_SYSCONF(_SC_PAGESIZE);
141*49cdfc7eSAndroid Build Coastguard Worker 	offset = baseaddr % pagesize;
142*49cdfc7eSAndroid Build Coastguard Worker 	size = LTP_ALIGN(size + offset, pagesize);
143*49cdfc7eSAndroid Build Coastguard Worker 	ret = tst_alloc(size);
144*49cdfc7eSAndroid Build Coastguard Worker 
145*49cdfc7eSAndroid Build Coastguard Worker 	memslot.guest_phys_addr = baseaddr - offset;
146*49cdfc7eSAndroid Build Coastguard Worker 	memslot.memory_size = size;
147*49cdfc7eSAndroid Build Coastguard Worker 	memslot.userspace_addr = (uintptr_t)ret;
148*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_IOCTL(inst->vm_fd, KVM_SET_USER_MEMORY_REGION, &memslot);
149*49cdfc7eSAndroid Build Coastguard Worker 	inst->ram[slot] = memslot;
150*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
151*49cdfc7eSAndroid Build Coastguard Worker }
152*49cdfc7eSAndroid Build Coastguard Worker 
tst_kvm_get_cpuid(int sysfd)153*49cdfc7eSAndroid Build Coastguard Worker struct kvm_cpuid2 *tst_kvm_get_cpuid(int sysfd)
154*49cdfc7eSAndroid Build Coastguard Worker {
155*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int count;
156*49cdfc7eSAndroid Build Coastguard Worker 	int result;
157*49cdfc7eSAndroid Build Coastguard Worker 	struct kvm_cpuid2 *ret;
158*49cdfc7eSAndroid Build Coastguard Worker 
159*49cdfc7eSAndroid Build Coastguard Worker 	if (!SAFE_IOCTL(sysfd, KVM_CHECK_EXTENSION, KVM_CAP_EXT_CPUID))
160*49cdfc7eSAndroid Build Coastguard Worker 		return NULL;
161*49cdfc7eSAndroid Build Coastguard Worker 
162*49cdfc7eSAndroid Build Coastguard Worker 	for (count = 8; count < 1 << 30; count *= 2) {
163*49cdfc7eSAndroid Build Coastguard Worker 		ret = SAFE_MALLOC(sizeof(struct kvm_cpuid2) +
164*49cdfc7eSAndroid Build Coastguard Worker 			count * sizeof(struct kvm_cpuid_entry2));
165*49cdfc7eSAndroid Build Coastguard Worker 		ret->nent = count;
166*49cdfc7eSAndroid Build Coastguard Worker 		errno = 0;
167*49cdfc7eSAndroid Build Coastguard Worker 		result = ioctl(sysfd, KVM_GET_SUPPORTED_CPUID, ret);
168*49cdfc7eSAndroid Build Coastguard Worker 
169*49cdfc7eSAndroid Build Coastguard Worker 		if (!result)
170*49cdfc7eSAndroid Build Coastguard Worker 			return ret;
171*49cdfc7eSAndroid Build Coastguard Worker 
172*49cdfc7eSAndroid Build Coastguard Worker 		free(ret);
173*49cdfc7eSAndroid Build Coastguard Worker 
174*49cdfc7eSAndroid Build Coastguard Worker 		if (errno != E2BIG)
175*49cdfc7eSAndroid Build Coastguard Worker 			break;
176*49cdfc7eSAndroid Build Coastguard Worker 	}
177*49cdfc7eSAndroid Build Coastguard Worker 
178*49cdfc7eSAndroid Build Coastguard Worker 	tst_brk(TBROK | TERRNO, "ioctl(KVM_GET_SUPPORTED_CPUID) failed");
179*49cdfc7eSAndroid Build Coastguard Worker 	return NULL;
180*49cdfc7eSAndroid Build Coastguard Worker }
181*49cdfc7eSAndroid Build Coastguard Worker 
tst_kvm_create_instance(struct tst_kvm_instance * inst,size_t ram_size)182*49cdfc7eSAndroid Build Coastguard Worker void tst_kvm_create_instance(struct tst_kvm_instance *inst, size_t ram_size)
183*49cdfc7eSAndroid Build Coastguard Worker {
184*49cdfc7eSAndroid Build Coastguard Worker 	int sys_fd;
185*49cdfc7eSAndroid Build Coastguard Worker 	size_t pagesize, result_pageaddr = KVM_RESULT_BASEADDR;
186*49cdfc7eSAndroid Build Coastguard Worker 	char *buf, *reset_ptr;
187*49cdfc7eSAndroid Build Coastguard Worker 	struct kvm_cpuid2 *cpuid_data;
188*49cdfc7eSAndroid Build Coastguard Worker 	const size_t payload_size = kvm_payload_end - kvm_payload_start;
189*49cdfc7eSAndroid Build Coastguard Worker 
190*49cdfc7eSAndroid Build Coastguard Worker 	memset(inst, 0, sizeof(struct tst_kvm_instance));
191*49cdfc7eSAndroid Build Coastguard Worker 	inst->vm_fd = -1;
192*49cdfc7eSAndroid Build Coastguard Worker 	inst->vcpu_fd = -1;
193*49cdfc7eSAndroid Build Coastguard Worker 	inst->vcpu_info = MAP_FAILED;
194*49cdfc7eSAndroid Build Coastguard Worker 
195*49cdfc7eSAndroid Build Coastguard Worker 	pagesize = SAFE_SYSCONF(_SC_PAGESIZE);
196*49cdfc7eSAndroid Build Coastguard Worker 	result_pageaddr -= result_pageaddr % pagesize;
197*49cdfc7eSAndroid Build Coastguard Worker 
198*49cdfc7eSAndroid Build Coastguard Worker 	if (payload_size + MIN_FREE_RAM > ram_size - VM_KERNEL_BASEADDR) {
199*49cdfc7eSAndroid Build Coastguard Worker 		ram_size = payload_size + MIN_FREE_RAM + VM_KERNEL_BASEADDR;
200*49cdfc7eSAndroid Build Coastguard Worker 		ram_size = LTP_ALIGN(ram_size, 1024 * 1024);
201*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TWARN, "RAM size increased to %zu bytes", ram_size);
202*49cdfc7eSAndroid Build Coastguard Worker 	}
203*49cdfc7eSAndroid Build Coastguard Worker 
204*49cdfc7eSAndroid Build Coastguard Worker 	if (ram_size > result_pageaddr) {
205*49cdfc7eSAndroid Build Coastguard Worker 		ram_size = result_pageaddr;
206*49cdfc7eSAndroid Build Coastguard Worker 		tst_res(TWARN, "RAM size truncated to %zu bytes", ram_size);
207*49cdfc7eSAndroid Build Coastguard Worker 	}
208*49cdfc7eSAndroid Build Coastguard Worker 
209*49cdfc7eSAndroid Build Coastguard Worker 	sys_fd = SAFE_OPEN("/dev/kvm", O_RDWR);
210*49cdfc7eSAndroid Build Coastguard Worker 	inst->vcpu_info_size = SAFE_IOCTL(sys_fd, KVM_GET_VCPU_MMAP_SIZE, 0);
211*49cdfc7eSAndroid Build Coastguard Worker 	inst->vm_fd = SAFE_IOCTL(sys_fd, KVM_CREATE_VM, 0);
212*49cdfc7eSAndroid Build Coastguard Worker 	cpuid_data = tst_kvm_get_cpuid(sys_fd);
213*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_CLOSE(sys_fd);
214*49cdfc7eSAndroid Build Coastguard Worker 
215*49cdfc7eSAndroid Build Coastguard Worker 	inst->vcpu_fd = SAFE_IOCTL(inst->vm_fd, KVM_CREATE_VCPU, 0);
216*49cdfc7eSAndroid Build Coastguard Worker 
217*49cdfc7eSAndroid Build Coastguard Worker 	if (cpuid_data) {
218*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_IOCTL(inst->vcpu_fd, KVM_SET_CPUID2, cpuid_data);
219*49cdfc7eSAndroid Build Coastguard Worker 		free(cpuid_data);
220*49cdfc7eSAndroid Build Coastguard Worker 	}
221*49cdfc7eSAndroid Build Coastguard Worker 
222*49cdfc7eSAndroid Build Coastguard Worker 	inst->vcpu_info = SAFE_MMAP(NULL, inst->vcpu_info_size,
223*49cdfc7eSAndroid Build Coastguard Worker 		PROT_READ | PROT_WRITE, MAP_SHARED, inst->vcpu_fd, 0);
224*49cdfc7eSAndroid Build Coastguard Worker 
225*49cdfc7eSAndroid Build Coastguard Worker 	buf = tst_kvm_alloc_memory(inst, 0, 0, ram_size, 0);
226*49cdfc7eSAndroid Build Coastguard Worker 	memcpy(buf + VM_KERNEL_BASEADDR, kvm_payload_start, payload_size);
227*49cdfc7eSAndroid Build Coastguard Worker 	buf = tst_kvm_alloc_memory(inst, 1, KVM_RESULT_BASEADDR,
228*49cdfc7eSAndroid Build Coastguard Worker 		KVM_RESULT_SIZE, 0);
229*49cdfc7eSAndroid Build Coastguard Worker 	memset(buf, 0, KVM_RESULT_SIZE);
230*49cdfc7eSAndroid Build Coastguard Worker 
231*49cdfc7eSAndroid Build Coastguard Worker 	reset_ptr = buf + (VM_RESET_BASEADDR % pagesize);
232*49cdfc7eSAndroid Build Coastguard Worker 	memcpy(reset_ptr, tst_kvm_reset_code, sizeof(tst_kvm_reset_code));
233*49cdfc7eSAndroid Build Coastguard Worker 	inst->result = (struct tst_kvm_result *)(buf +
234*49cdfc7eSAndroid Build Coastguard Worker 		(KVM_RESULT_BASEADDR % pagesize));
235*49cdfc7eSAndroid Build Coastguard Worker 	inst->result->result = KVM_TNONE;
236*49cdfc7eSAndroid Build Coastguard Worker 	inst->result->message[0] = '\0';
237*49cdfc7eSAndroid Build Coastguard Worker }
238*49cdfc7eSAndroid Build Coastguard Worker 
tst_kvm_run_instance(struct tst_kvm_instance * inst,int exp_errno)239*49cdfc7eSAndroid Build Coastguard Worker int tst_kvm_run_instance(struct tst_kvm_instance *inst, int exp_errno)
240*49cdfc7eSAndroid Build Coastguard Worker {
241*49cdfc7eSAndroid Build Coastguard Worker 	struct kvm_regs regs;
242*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
243*49cdfc7eSAndroid Build Coastguard Worker 
244*49cdfc7eSAndroid Build Coastguard Worker 	while (1) {
245*49cdfc7eSAndroid Build Coastguard Worker 		inst->result->result = KVM_TNONE;
246*49cdfc7eSAndroid Build Coastguard Worker 		inst->result->message[0] = '\0';
247*49cdfc7eSAndroid Build Coastguard Worker 		errno = 0;
248*49cdfc7eSAndroid Build Coastguard Worker 		ret = ioctl(inst->vcpu_fd, KVM_RUN, 0);
249*49cdfc7eSAndroid Build Coastguard Worker 
250*49cdfc7eSAndroid Build Coastguard Worker 		if (ret == -1) {
251*49cdfc7eSAndroid Build Coastguard Worker 			if (errno == exp_errno)
252*49cdfc7eSAndroid Build Coastguard Worker 				return ret;
253*49cdfc7eSAndroid Build Coastguard Worker 
254*49cdfc7eSAndroid Build Coastguard Worker 			tst_brk(TBROK | TERRNO, "ioctl(KVM_RUN) failed");
255*49cdfc7eSAndroid Build Coastguard Worker 		}
256*49cdfc7eSAndroid Build Coastguard Worker 
257*49cdfc7eSAndroid Build Coastguard Worker 		if (ret < 0) {
258*49cdfc7eSAndroid Build Coastguard Worker 			tst_brk(TBROK | TERRNO,
259*49cdfc7eSAndroid Build Coastguard Worker 				"Invalid ioctl(KVM_RUN) return value %d", ret);
260*49cdfc7eSAndroid Build Coastguard Worker 		}
261*49cdfc7eSAndroid Build Coastguard Worker 
262*49cdfc7eSAndroid Build Coastguard Worker 		if (inst->vcpu_info->exit_reason != KVM_EXIT_HLT) {
263*49cdfc7eSAndroid Build Coastguard Worker 			SAFE_IOCTL(inst->vcpu_fd, KVM_GET_REGS, &regs);
264*49cdfc7eSAndroid Build Coastguard Worker 			tst_brk(TBROK,
265*49cdfc7eSAndroid Build Coastguard Worker 				"Unexpected VM exit, RIP=0x%llx, reason=%u",
266*49cdfc7eSAndroid Build Coastguard Worker 				regs.rip, inst->vcpu_info->exit_reason);
267*49cdfc7eSAndroid Build Coastguard Worker 		}
268*49cdfc7eSAndroid Build Coastguard Worker 
269*49cdfc7eSAndroid Build Coastguard Worker 		if (inst->result->result == KVM_TEXIT)
270*49cdfc7eSAndroid Build Coastguard Worker 			break;
271*49cdfc7eSAndroid Build Coastguard Worker 
272*49cdfc7eSAndroid Build Coastguard Worker 		tst_kvm_print_result(inst);
273*49cdfc7eSAndroid Build Coastguard Worker 	}
274*49cdfc7eSAndroid Build Coastguard Worker 
275*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
276*49cdfc7eSAndroid Build Coastguard Worker }
277*49cdfc7eSAndroid Build Coastguard Worker 
tst_kvm_destroy_instance(struct tst_kvm_instance * inst)278*49cdfc7eSAndroid Build Coastguard Worker void tst_kvm_destroy_instance(struct tst_kvm_instance *inst)
279*49cdfc7eSAndroid Build Coastguard Worker {
280*49cdfc7eSAndroid Build Coastguard Worker 	if (inst->vm_fd < 0)
281*49cdfc7eSAndroid Build Coastguard Worker 		return;
282*49cdfc7eSAndroid Build Coastguard Worker 
283*49cdfc7eSAndroid Build Coastguard Worker 	if (inst->vcpu_info != MAP_FAILED)
284*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_MUNMAP(inst->vcpu_info, inst->vcpu_info_size);
285*49cdfc7eSAndroid Build Coastguard Worker 
286*49cdfc7eSAndroid Build Coastguard Worker 	if (inst->vcpu_fd >= 0)
287*49cdfc7eSAndroid Build Coastguard Worker 		SAFE_CLOSE(inst->vcpu_fd);
288*49cdfc7eSAndroid Build Coastguard Worker 
289*49cdfc7eSAndroid Build Coastguard Worker 	SAFE_CLOSE(inst->vm_fd);
290*49cdfc7eSAndroid Build Coastguard Worker 	memset(inst->ram, 0, sizeof(inst->ram));
291*49cdfc7eSAndroid Build Coastguard Worker }
292*49cdfc7eSAndroid Build Coastguard Worker 
tst_kvm_wait_guest(struct tst_kvm_instance * inst,int timeout_ms)293*49cdfc7eSAndroid Build Coastguard Worker int tst_kvm_wait_guest(struct tst_kvm_instance *inst, int timeout_ms)
294*49cdfc7eSAndroid Build Coastguard Worker {
295*49cdfc7eSAndroid Build Coastguard Worker 	volatile struct tst_kvm_result *result = inst->result;
296*49cdfc7eSAndroid Build Coastguard Worker 	int32_t res;
297*49cdfc7eSAndroid Build Coastguard Worker 	struct timespec start, now;
298*49cdfc7eSAndroid Build Coastguard Worker 
299*49cdfc7eSAndroid Build Coastguard Worker 	if (timeout_ms >= 0)
300*49cdfc7eSAndroid Build Coastguard Worker 		tst_clock_gettime(CLOCK_MONOTONIC, &start);
301*49cdfc7eSAndroid Build Coastguard Worker 
302*49cdfc7eSAndroid Build Coastguard Worker 	while ((res = result->result) != KVM_TSYNC) {
303*49cdfc7eSAndroid Build Coastguard Worker 		if (res == KVM_TEXIT)
304*49cdfc7eSAndroid Build Coastguard Worker 			return res;
305*49cdfc7eSAndroid Build Coastguard Worker 
306*49cdfc7eSAndroid Build Coastguard Worker 		if (timeout_ms >= 0) {
307*49cdfc7eSAndroid Build Coastguard Worker 			tst_clock_gettime(CLOCK_MONOTONIC, &now);
308*49cdfc7eSAndroid Build Coastguard Worker 
309*49cdfc7eSAndroid Build Coastguard Worker 			if (tst_timespec_diff_ms(now, start) >= timeout_ms)
310*49cdfc7eSAndroid Build Coastguard Worker 				return -1;
311*49cdfc7eSAndroid Build Coastguard Worker 		}
312*49cdfc7eSAndroid Build Coastguard Worker 
313*49cdfc7eSAndroid Build Coastguard Worker 		usleep(1000);
314*49cdfc7eSAndroid Build Coastguard Worker 	}
315*49cdfc7eSAndroid Build Coastguard Worker 
316*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
317*49cdfc7eSAndroid Build Coastguard Worker }
318*49cdfc7eSAndroid Build Coastguard Worker 
tst_kvm_clear_guest_signal(struct tst_kvm_instance * inst)319*49cdfc7eSAndroid Build Coastguard Worker void tst_kvm_clear_guest_signal(struct tst_kvm_instance *inst)
320*49cdfc7eSAndroid Build Coastguard Worker {
321*49cdfc7eSAndroid Build Coastguard Worker 	inst->result->result = KVM_TNONE;
322*49cdfc7eSAndroid Build Coastguard Worker }
323*49cdfc7eSAndroid Build Coastguard Worker 
tst_kvm_setup(void)324*49cdfc7eSAndroid Build Coastguard Worker void tst_kvm_setup(void)
325*49cdfc7eSAndroid Build Coastguard Worker {
326*49cdfc7eSAndroid Build Coastguard Worker 
327*49cdfc7eSAndroid Build Coastguard Worker }
328*49cdfc7eSAndroid Build Coastguard Worker 
tst_kvm_run(void)329*49cdfc7eSAndroid Build Coastguard Worker void tst_kvm_run(void)
330*49cdfc7eSAndroid Build Coastguard Worker {
331*49cdfc7eSAndroid Build Coastguard Worker 	tst_kvm_create_instance(&test_vm, DEFAULT_RAM_SIZE);
332*49cdfc7eSAndroid Build Coastguard Worker 	tst_kvm_run_instance(&test_vm, 0);
333*49cdfc7eSAndroid Build Coastguard Worker 	tst_kvm_destroy_instance(&test_vm);
334*49cdfc7eSAndroid Build Coastguard Worker 	tst_free_all();
335*49cdfc7eSAndroid Build Coastguard Worker }
336*49cdfc7eSAndroid Build Coastguard Worker 
tst_kvm_cleanup(void)337*49cdfc7eSAndroid Build Coastguard Worker void tst_kvm_cleanup(void)
338*49cdfc7eSAndroid Build Coastguard Worker {
339*49cdfc7eSAndroid Build Coastguard Worker 	tst_kvm_destroy_instance(&test_vm);
340*49cdfc7eSAndroid Build Coastguard Worker }
341