xref: /aosp_15_r20/external/ltp/testcases/kernel/kvm/lib_guest.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  * Minimal testing library for KVM tests
6*49cdfc7eSAndroid Build Coastguard Worker  */
7*49cdfc7eSAndroid Build Coastguard Worker 
8*49cdfc7eSAndroid Build Coastguard Worker #include "kvm_test.h"
9*49cdfc7eSAndroid Build Coastguard Worker 
10*49cdfc7eSAndroid Build Coastguard Worker extern char kvm_heap_begin[];
11*49cdfc7eSAndroid Build Coastguard Worker 
12*49cdfc7eSAndroid Build Coastguard Worker static struct tst_kvm_result *const test_result =
13*49cdfc7eSAndroid Build Coastguard Worker 	(struct tst_kvm_result *)KVM_RESULT_BASEADDR;
14*49cdfc7eSAndroid Build Coastguard Worker 
15*49cdfc7eSAndroid Build Coastguard Worker static char *heap_end = kvm_heap_begin;
16*49cdfc7eSAndroid Build Coastguard Worker 
17*49cdfc7eSAndroid Build Coastguard Worker static struct tst_intr_handler {
18*49cdfc7eSAndroid Build Coastguard Worker 	tst_interrupt_callback callback;
19*49cdfc7eSAndroid Build Coastguard Worker 	void *userdata;
20*49cdfc7eSAndroid Build Coastguard Worker } intr_handlers[INTERRUPT_COUNT];
21*49cdfc7eSAndroid Build Coastguard Worker 
memset(void * dest,int val,size_t size)22*49cdfc7eSAndroid Build Coastguard Worker void *memset(void *dest, int val, size_t size)
23*49cdfc7eSAndroid Build Coastguard Worker {
24*49cdfc7eSAndroid Build Coastguard Worker 	char *ptr = dest;
25*49cdfc7eSAndroid Build Coastguard Worker 
26*49cdfc7eSAndroid Build Coastguard Worker 	while (size--)
27*49cdfc7eSAndroid Build Coastguard Worker 		*ptr++ = val;
28*49cdfc7eSAndroid Build Coastguard Worker 
29*49cdfc7eSAndroid Build Coastguard Worker 	return dest;
30*49cdfc7eSAndroid Build Coastguard Worker }
31*49cdfc7eSAndroid Build Coastguard Worker 
memzero(void * dest,size_t size)32*49cdfc7eSAndroid Build Coastguard Worker void *memzero(void *dest, size_t size)
33*49cdfc7eSAndroid Build Coastguard Worker {
34*49cdfc7eSAndroid Build Coastguard Worker 	return memset(dest, 0, size);
35*49cdfc7eSAndroid Build Coastguard Worker }
36*49cdfc7eSAndroid Build Coastguard Worker 
memcpy(void * dest,const void * src,size_t size)37*49cdfc7eSAndroid Build Coastguard Worker void *memcpy(void *dest, const void *src, size_t size)
38*49cdfc7eSAndroid Build Coastguard Worker {
39*49cdfc7eSAndroid Build Coastguard Worker 	char *dptr = dest;
40*49cdfc7eSAndroid Build Coastguard Worker 	const char *sptr = src;
41*49cdfc7eSAndroid Build Coastguard Worker 
42*49cdfc7eSAndroid Build Coastguard Worker 	while (size--)
43*49cdfc7eSAndroid Build Coastguard Worker 		*dptr++ = *sptr++;
44*49cdfc7eSAndroid Build Coastguard Worker 
45*49cdfc7eSAndroid Build Coastguard Worker 	return dest;
46*49cdfc7eSAndroid Build Coastguard Worker }
47*49cdfc7eSAndroid Build Coastguard Worker 
strcpy(char * dest,const char * src)48*49cdfc7eSAndroid Build Coastguard Worker char *strcpy(char *dest, const char *src)
49*49cdfc7eSAndroid Build Coastguard Worker {
50*49cdfc7eSAndroid Build Coastguard Worker 	char *ret = dest;
51*49cdfc7eSAndroid Build Coastguard Worker 
52*49cdfc7eSAndroid Build Coastguard Worker 	while ((*dest++ = *src++))
53*49cdfc7eSAndroid Build Coastguard Worker 		;
54*49cdfc7eSAndroid Build Coastguard Worker 
55*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
56*49cdfc7eSAndroid Build Coastguard Worker }
57*49cdfc7eSAndroid Build Coastguard Worker 
strcat(char * dest,const char * src)58*49cdfc7eSAndroid Build Coastguard Worker char *strcat(char *dest, const char *src)
59*49cdfc7eSAndroid Build Coastguard Worker {
60*49cdfc7eSAndroid Build Coastguard Worker 	char *ret = dest;
61*49cdfc7eSAndroid Build Coastguard Worker 
62*49cdfc7eSAndroid Build Coastguard Worker 	for (; *dest; dest++)
63*49cdfc7eSAndroid Build Coastguard Worker 		;
64*49cdfc7eSAndroid Build Coastguard Worker 
65*49cdfc7eSAndroid Build Coastguard Worker 	strcpy(dest, src);
66*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
67*49cdfc7eSAndroid Build Coastguard Worker }
68*49cdfc7eSAndroid Build Coastguard Worker 
strlen(const char * str)69*49cdfc7eSAndroid Build Coastguard Worker size_t strlen(const char *str)
70*49cdfc7eSAndroid Build Coastguard Worker {
71*49cdfc7eSAndroid Build Coastguard Worker 	size_t ret;
72*49cdfc7eSAndroid Build Coastguard Worker 
73*49cdfc7eSAndroid Build Coastguard Worker 	for (ret = 0; str[ret]; ret++)
74*49cdfc7eSAndroid Build Coastguard Worker 		;
75*49cdfc7eSAndroid Build Coastguard Worker 
76*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
77*49cdfc7eSAndroid Build Coastguard Worker }
78*49cdfc7eSAndroid Build Coastguard Worker 
strchr(const char * s,int c)79*49cdfc7eSAndroid Build Coastguard Worker char *strchr(const char *s, int c)
80*49cdfc7eSAndroid Build Coastguard Worker {
81*49cdfc7eSAndroid Build Coastguard Worker 	for (; *s; s++) {
82*49cdfc7eSAndroid Build Coastguard Worker 		if (*s == c)
83*49cdfc7eSAndroid Build Coastguard Worker 			return (char *)s;
84*49cdfc7eSAndroid Build Coastguard Worker 	}
85*49cdfc7eSAndroid Build Coastguard Worker 
86*49cdfc7eSAndroid Build Coastguard Worker 	return NULL;
87*49cdfc7eSAndroid Build Coastguard Worker }
88*49cdfc7eSAndroid Build Coastguard Worker 
strrchr(const char * s,int c)89*49cdfc7eSAndroid Build Coastguard Worker char *strrchr(const char *s, int c)
90*49cdfc7eSAndroid Build Coastguard Worker {
91*49cdfc7eSAndroid Build Coastguard Worker 	const char *ret = NULL;
92*49cdfc7eSAndroid Build Coastguard Worker 
93*49cdfc7eSAndroid Build Coastguard Worker 	for (; *s; s++) {
94*49cdfc7eSAndroid Build Coastguard Worker 		if (*s == c)
95*49cdfc7eSAndroid Build Coastguard Worker 			ret = s;
96*49cdfc7eSAndroid Build Coastguard Worker 	}
97*49cdfc7eSAndroid Build Coastguard Worker 
98*49cdfc7eSAndroid Build Coastguard Worker 	return (char *)ret;
99*49cdfc7eSAndroid Build Coastguard Worker }
100*49cdfc7eSAndroid Build Coastguard Worker 
101*49cdfc7eSAndroid Build Coastguard Worker #if defined(__x86_64__) && !defined(__ILP32__)
u64divu16(uint64_t a,uint16_t b)102*49cdfc7eSAndroid Build Coastguard Worker uint64_t u64divu16(uint64_t a, uint16_t b)
103*49cdfc7eSAndroid Build Coastguard Worker {
104*49cdfc7eSAndroid Build Coastguard Worker 	return a / b;
105*49cdfc7eSAndroid Build Coastguard Worker }
106*49cdfc7eSAndroid Build Coastguard Worker 
u64modu16(uint64_t a,uint16_t b)107*49cdfc7eSAndroid Build Coastguard Worker unsigned int u64modu16(uint64_t a, uint16_t b)
108*49cdfc7eSAndroid Build Coastguard Worker {
109*49cdfc7eSAndroid Build Coastguard Worker 	return a % b;
110*49cdfc7eSAndroid Build Coastguard Worker }
111*49cdfc7eSAndroid Build Coastguard Worker 
112*49cdfc7eSAndroid Build Coastguard Worker #else /* defined(__x86_64__) && !defined(__ILP32__) */
113*49cdfc7eSAndroid Build Coastguard Worker 
114*49cdfc7eSAndroid Build Coastguard Worker /* u64 short division helpers to avoid need to link libgcc on 32bit archs */
u64divu16(uint64_t a,uint16_t b)115*49cdfc7eSAndroid Build Coastguard Worker uint64_t u64divu16(uint64_t a, uint16_t b)
116*49cdfc7eSAndroid Build Coastguard Worker {
117*49cdfc7eSAndroid Build Coastguard Worker 	uint64_t ret = 0;
118*49cdfc7eSAndroid Build Coastguard Worker 	uint32_t tmp = a >> 32;
119*49cdfc7eSAndroid Build Coastguard Worker 
120*49cdfc7eSAndroid Build Coastguard Worker 	ret = tmp / b;
121*49cdfc7eSAndroid Build Coastguard Worker 	ret <<= 32;
122*49cdfc7eSAndroid Build Coastguard Worker 	tmp %= b;
123*49cdfc7eSAndroid Build Coastguard Worker 	tmp <<= 16;
124*49cdfc7eSAndroid Build Coastguard Worker 	tmp |= (a >> 16) & 0xffff;
125*49cdfc7eSAndroid Build Coastguard Worker 	ret |= (tmp / b) << 16;
126*49cdfc7eSAndroid Build Coastguard Worker 	tmp %= b;
127*49cdfc7eSAndroid Build Coastguard Worker 	tmp <<= 16;
128*49cdfc7eSAndroid Build Coastguard Worker 	tmp |= a & 0xffff;
129*49cdfc7eSAndroid Build Coastguard Worker 	ret |= tmp / b;
130*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
131*49cdfc7eSAndroid Build Coastguard Worker }
132*49cdfc7eSAndroid Build Coastguard Worker 
u64modu16(uint64_t a,uint16_t b)133*49cdfc7eSAndroid Build Coastguard Worker unsigned int u64modu16(uint64_t a, uint16_t b)
134*49cdfc7eSAndroid Build Coastguard Worker {
135*49cdfc7eSAndroid Build Coastguard Worker 	uint32_t tmp = a >> 32;
136*49cdfc7eSAndroid Build Coastguard Worker 
137*49cdfc7eSAndroid Build Coastguard Worker 	tmp %= b;
138*49cdfc7eSAndroid Build Coastguard Worker 	tmp <<= 16;
139*49cdfc7eSAndroid Build Coastguard Worker 	tmp |= (a >> 16) & 0xffff;
140*49cdfc7eSAndroid Build Coastguard Worker 	tmp %= b;
141*49cdfc7eSAndroid Build Coastguard Worker 	tmp <<= 16;
142*49cdfc7eSAndroid Build Coastguard Worker 	tmp |= a & 0xffff;
143*49cdfc7eSAndroid Build Coastguard Worker 	return tmp % b;
144*49cdfc7eSAndroid Build Coastguard Worker }
145*49cdfc7eSAndroid Build Coastguard Worker #endif /* defined(__x86_64__) && !defined(__ILP32__) */
146*49cdfc7eSAndroid Build Coastguard Worker 
ptr2hex(char * dest,uintptr_t val)147*49cdfc7eSAndroid Build Coastguard Worker char *ptr2hex(char *dest, uintptr_t val)
148*49cdfc7eSAndroid Build Coastguard Worker {
149*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int i;
150*49cdfc7eSAndroid Build Coastguard Worker 	uintptr_t tmp;
151*49cdfc7eSAndroid Build Coastguard Worker 	char *ret = dest;
152*49cdfc7eSAndroid Build Coastguard Worker 
153*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 4, tmp = val >> 4; tmp; i += 4, tmp >>= 4)
154*49cdfc7eSAndroid Build Coastguard Worker 		;
155*49cdfc7eSAndroid Build Coastguard Worker 
156*49cdfc7eSAndroid Build Coastguard Worker 	do {
157*49cdfc7eSAndroid Build Coastguard Worker 		i -= 4;
158*49cdfc7eSAndroid Build Coastguard Worker 		tmp = (val >> i) & 0xf;
159*49cdfc7eSAndroid Build Coastguard Worker 		*dest++ = tmp + (tmp >= 10 ? 'A' - 10 : '0');
160*49cdfc7eSAndroid Build Coastguard Worker 	} while (i);
161*49cdfc7eSAndroid Build Coastguard Worker 
162*49cdfc7eSAndroid Build Coastguard Worker 	*dest = '\0';
163*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
164*49cdfc7eSAndroid Build Coastguard Worker }
165*49cdfc7eSAndroid Build Coastguard Worker 
u64tostr(char * dest,uint64_t val,uint16_t base,int caps)166*49cdfc7eSAndroid Build Coastguard Worker char *u64tostr(char *dest, uint64_t val, uint16_t base, int caps)
167*49cdfc7eSAndroid Build Coastguard Worker {
168*49cdfc7eSAndroid Build Coastguard Worker 	unsigned int i;
169*49cdfc7eSAndroid Build Coastguard Worker 	uintptr_t tmp = u64divu16(val, base);
170*49cdfc7eSAndroid Build Coastguard Worker 	char hex = caps ? 'A' : 'a';
171*49cdfc7eSAndroid Build Coastguard Worker 	char *ret = dest;
172*49cdfc7eSAndroid Build Coastguard Worker 
173*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 1; tmp; i++, tmp = u64divu16(tmp, base))
174*49cdfc7eSAndroid Build Coastguard Worker 		;
175*49cdfc7eSAndroid Build Coastguard Worker 
176*49cdfc7eSAndroid Build Coastguard Worker 	dest[i] = '\0';
177*49cdfc7eSAndroid Build Coastguard Worker 
178*49cdfc7eSAndroid Build Coastguard Worker 	do {
179*49cdfc7eSAndroid Build Coastguard Worker 		tmp = u64modu16(val, base);
180*49cdfc7eSAndroid Build Coastguard Worker 		dest[--i] = tmp + (tmp >= 10 ? hex - 10 : '0');
181*49cdfc7eSAndroid Build Coastguard Worker 		val = u64divu16(val, base);
182*49cdfc7eSAndroid Build Coastguard Worker 	} while (i);
183*49cdfc7eSAndroid Build Coastguard Worker 
184*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
185*49cdfc7eSAndroid Build Coastguard Worker }
186*49cdfc7eSAndroid Build Coastguard Worker 
i64tostr(char * dest,int64_t val)187*49cdfc7eSAndroid Build Coastguard Worker char *i64tostr(char *dest, int64_t val)
188*49cdfc7eSAndroid Build Coastguard Worker {
189*49cdfc7eSAndroid Build Coastguard Worker 	if (val < 0) {
190*49cdfc7eSAndroid Build Coastguard Worker 		dest[0] = '-';
191*49cdfc7eSAndroid Build Coastguard Worker 		u64tostr(dest + 1, -val, 10, 0);
192*49cdfc7eSAndroid Build Coastguard Worker 		return dest;
193*49cdfc7eSAndroid Build Coastguard Worker 	}
194*49cdfc7eSAndroid Build Coastguard Worker 
195*49cdfc7eSAndroid Build Coastguard Worker 	return u64tostr(dest, val, 10, 0);
196*49cdfc7eSAndroid Build Coastguard Worker }
197*49cdfc7eSAndroid Build Coastguard Worker 
vsprintf(char * dest,const char * fmt,va_list ap)198*49cdfc7eSAndroid Build Coastguard Worker int vsprintf(char *dest, const char *fmt, va_list ap)
199*49cdfc7eSAndroid Build Coastguard Worker {
200*49cdfc7eSAndroid Build Coastguard Worker 	va_list args;
201*49cdfc7eSAndroid Build Coastguard Worker 	int ret = 0;
202*49cdfc7eSAndroid Build Coastguard Worker 	char conv;
203*49cdfc7eSAndroid Build Coastguard Worker 	uint64_t u64val = 0;
204*49cdfc7eSAndroid Build Coastguard Worker 	int64_t i64val = 0;
205*49cdfc7eSAndroid Build Coastguard Worker 	const char * const uint_conv = "ouxX";
206*49cdfc7eSAndroid Build Coastguard Worker 
207*49cdfc7eSAndroid Build Coastguard Worker 	va_copy(args, ap);
208*49cdfc7eSAndroid Build Coastguard Worker 
209*49cdfc7eSAndroid Build Coastguard Worker 	for (; *fmt; fmt++) {
210*49cdfc7eSAndroid Build Coastguard Worker 		if (*fmt != '%') {
211*49cdfc7eSAndroid Build Coastguard Worker 			dest[ret++] = *fmt;
212*49cdfc7eSAndroid Build Coastguard Worker 			continue;
213*49cdfc7eSAndroid Build Coastguard Worker 		}
214*49cdfc7eSAndroid Build Coastguard Worker 
215*49cdfc7eSAndroid Build Coastguard Worker 		conv = 0;
216*49cdfc7eSAndroid Build Coastguard Worker 		fmt++;
217*49cdfc7eSAndroid Build Coastguard Worker 
218*49cdfc7eSAndroid Build Coastguard Worker 		switch (*fmt) {
219*49cdfc7eSAndroid Build Coastguard Worker 		case '%':
220*49cdfc7eSAndroid Build Coastguard Worker 			dest[ret++] = *fmt;
221*49cdfc7eSAndroid Build Coastguard Worker 			break;
222*49cdfc7eSAndroid Build Coastguard Worker 
223*49cdfc7eSAndroid Build Coastguard Worker 		case 'c':
224*49cdfc7eSAndroid Build Coastguard Worker 			dest[ret++] = va_arg(args, int);
225*49cdfc7eSAndroid Build Coastguard Worker 			break;
226*49cdfc7eSAndroid Build Coastguard Worker 
227*49cdfc7eSAndroid Build Coastguard Worker 		case 's':
228*49cdfc7eSAndroid Build Coastguard Worker 			strcpy(dest + ret, va_arg(args, const char *));
229*49cdfc7eSAndroid Build Coastguard Worker 			ret += strlen(dest + ret);
230*49cdfc7eSAndroid Build Coastguard Worker 			break;
231*49cdfc7eSAndroid Build Coastguard Worker 
232*49cdfc7eSAndroid Build Coastguard Worker 		case 'p':
233*49cdfc7eSAndroid Build Coastguard Worker 			strcpy(dest + ret, "0x");
234*49cdfc7eSAndroid Build Coastguard Worker 			ptr2hex(dest + ret + 2,
235*49cdfc7eSAndroid Build Coastguard Worker 				(uintptr_t)va_arg(args, void *));
236*49cdfc7eSAndroid Build Coastguard Worker 			ret += strlen(dest + ret);
237*49cdfc7eSAndroid Build Coastguard Worker 			break;
238*49cdfc7eSAndroid Build Coastguard Worker 
239*49cdfc7eSAndroid Build Coastguard Worker 		case 'l':
240*49cdfc7eSAndroid Build Coastguard Worker 			fmt++;
241*49cdfc7eSAndroid Build Coastguard Worker 
242*49cdfc7eSAndroid Build Coastguard Worker 			switch (*fmt) {
243*49cdfc7eSAndroid Build Coastguard Worker 			case 'l':
244*49cdfc7eSAndroid Build Coastguard Worker 				fmt++;
245*49cdfc7eSAndroid Build Coastguard Worker 
246*49cdfc7eSAndroid Build Coastguard Worker 				if (*fmt == 'd' || *fmt == 'i') {
247*49cdfc7eSAndroid Build Coastguard Worker 					i64val = va_arg(args, long long);
248*49cdfc7eSAndroid Build Coastguard Worker 					conv = *fmt;
249*49cdfc7eSAndroid Build Coastguard Worker 					break;
250*49cdfc7eSAndroid Build Coastguard Worker 				}
251*49cdfc7eSAndroid Build Coastguard Worker 
252*49cdfc7eSAndroid Build Coastguard Worker 				if (strchr(uint_conv, *fmt)) {
253*49cdfc7eSAndroid Build Coastguard Worker 					u64val = va_arg(args,
254*49cdfc7eSAndroid Build Coastguard Worker 						unsigned long long);
255*49cdfc7eSAndroid Build Coastguard Worker 					conv = *fmt;
256*49cdfc7eSAndroid Build Coastguard Worker 					break;
257*49cdfc7eSAndroid Build Coastguard Worker 				}
258*49cdfc7eSAndroid Build Coastguard Worker 
259*49cdfc7eSAndroid Build Coastguard Worker 				va_end(args);
260*49cdfc7eSAndroid Build Coastguard Worker 				return -1;
261*49cdfc7eSAndroid Build Coastguard Worker 
262*49cdfc7eSAndroid Build Coastguard Worker 			case 'd':
263*49cdfc7eSAndroid Build Coastguard Worker 			case 'i':
264*49cdfc7eSAndroid Build Coastguard Worker 				i64val = va_arg(args, long);
265*49cdfc7eSAndroid Build Coastguard Worker 				conv = *fmt;
266*49cdfc7eSAndroid Build Coastguard Worker 				break;
267*49cdfc7eSAndroid Build Coastguard Worker 
268*49cdfc7eSAndroid Build Coastguard Worker 			default:
269*49cdfc7eSAndroid Build Coastguard Worker 				if (strchr(uint_conv, *fmt)) {
270*49cdfc7eSAndroid Build Coastguard Worker 					u64val = va_arg(args,
271*49cdfc7eSAndroid Build Coastguard Worker 						unsigned long);
272*49cdfc7eSAndroid Build Coastguard Worker 					conv = *fmt;
273*49cdfc7eSAndroid Build Coastguard Worker 					break;
274*49cdfc7eSAndroid Build Coastguard Worker 				}
275*49cdfc7eSAndroid Build Coastguard Worker 
276*49cdfc7eSAndroid Build Coastguard Worker 				va_end(args);
277*49cdfc7eSAndroid Build Coastguard Worker 				return -1;
278*49cdfc7eSAndroid Build Coastguard Worker 			}
279*49cdfc7eSAndroid Build Coastguard Worker 			break;
280*49cdfc7eSAndroid Build Coastguard Worker 
281*49cdfc7eSAndroid Build Coastguard Worker 		case 'h':
282*49cdfc7eSAndroid Build Coastguard Worker 			fmt++;
283*49cdfc7eSAndroid Build Coastguard Worker 
284*49cdfc7eSAndroid Build Coastguard Worker 			switch (*fmt) {
285*49cdfc7eSAndroid Build Coastguard Worker 			case 'h':
286*49cdfc7eSAndroid Build Coastguard Worker 				fmt++;
287*49cdfc7eSAndroid Build Coastguard Worker 
288*49cdfc7eSAndroid Build Coastguard Worker 				if (*fmt == 'd' || *fmt == 'i') {
289*49cdfc7eSAndroid Build Coastguard Worker 					i64val = (signed char)va_arg(args, int);
290*49cdfc7eSAndroid Build Coastguard Worker 					conv = *fmt;
291*49cdfc7eSAndroid Build Coastguard Worker 					break;
292*49cdfc7eSAndroid Build Coastguard Worker 				}
293*49cdfc7eSAndroid Build Coastguard Worker 
294*49cdfc7eSAndroid Build Coastguard Worker 				if (strchr(uint_conv, *fmt)) {
295*49cdfc7eSAndroid Build Coastguard Worker 					u64val = (unsigned char)va_arg(args,
296*49cdfc7eSAndroid Build Coastguard Worker 						unsigned int);
297*49cdfc7eSAndroid Build Coastguard Worker 					conv = *fmt;
298*49cdfc7eSAndroid Build Coastguard Worker 					break;
299*49cdfc7eSAndroid Build Coastguard Worker 				}
300*49cdfc7eSAndroid Build Coastguard Worker 
301*49cdfc7eSAndroid Build Coastguard Worker 				va_end(args);
302*49cdfc7eSAndroid Build Coastguard Worker 				return -1;
303*49cdfc7eSAndroid Build Coastguard Worker 
304*49cdfc7eSAndroid Build Coastguard Worker 			case 'd':
305*49cdfc7eSAndroid Build Coastguard Worker 			case 'i':
306*49cdfc7eSAndroid Build Coastguard Worker 				i64val = (short int)va_arg(args, int);
307*49cdfc7eSAndroid Build Coastguard Worker 				conv = *fmt;
308*49cdfc7eSAndroid Build Coastguard Worker 				break;
309*49cdfc7eSAndroid Build Coastguard Worker 
310*49cdfc7eSAndroid Build Coastguard Worker 			default:
311*49cdfc7eSAndroid Build Coastguard Worker 				if (strchr(uint_conv, *fmt)) {
312*49cdfc7eSAndroid Build Coastguard Worker 					u64val = (unsigned short int)va_arg(
313*49cdfc7eSAndroid Build Coastguard Worker 						args, unsigned int);
314*49cdfc7eSAndroid Build Coastguard Worker 					conv = *fmt;
315*49cdfc7eSAndroid Build Coastguard Worker 					break;
316*49cdfc7eSAndroid Build Coastguard Worker 				}
317*49cdfc7eSAndroid Build Coastguard Worker 
318*49cdfc7eSAndroid Build Coastguard Worker 				va_end(args);
319*49cdfc7eSAndroid Build Coastguard Worker 				return -1;
320*49cdfc7eSAndroid Build Coastguard Worker 			}
321*49cdfc7eSAndroid Build Coastguard Worker 			break;
322*49cdfc7eSAndroid Build Coastguard Worker 
323*49cdfc7eSAndroid Build Coastguard Worker 		case 'z':
324*49cdfc7eSAndroid Build Coastguard Worker 			fmt++;
325*49cdfc7eSAndroid Build Coastguard Worker 
326*49cdfc7eSAndroid Build Coastguard Worker 			if (*fmt == 'd' || *fmt == 'i') {
327*49cdfc7eSAndroid Build Coastguard Worker 				i64val = va_arg(args, ssize_t);
328*49cdfc7eSAndroid Build Coastguard Worker 				conv = *fmt;
329*49cdfc7eSAndroid Build Coastguard Worker 				break;
330*49cdfc7eSAndroid Build Coastguard Worker 			}
331*49cdfc7eSAndroid Build Coastguard Worker 
332*49cdfc7eSAndroid Build Coastguard Worker 			if (strchr(uint_conv, *fmt)) {
333*49cdfc7eSAndroid Build Coastguard Worker 				u64val = va_arg(args, size_t);
334*49cdfc7eSAndroid Build Coastguard Worker 				conv = *fmt;
335*49cdfc7eSAndroid Build Coastguard Worker 				break;
336*49cdfc7eSAndroid Build Coastguard Worker 			}
337*49cdfc7eSAndroid Build Coastguard Worker 
338*49cdfc7eSAndroid Build Coastguard Worker 			va_end(args);
339*49cdfc7eSAndroid Build Coastguard Worker 			return -1;
340*49cdfc7eSAndroid Build Coastguard Worker 
341*49cdfc7eSAndroid Build Coastguard Worker 		case 'd':
342*49cdfc7eSAndroid Build Coastguard Worker 		case 'i':
343*49cdfc7eSAndroid Build Coastguard Worker 			i64val = va_arg(args, int);
344*49cdfc7eSAndroid Build Coastguard Worker 			conv = *fmt;
345*49cdfc7eSAndroid Build Coastguard Worker 			break;
346*49cdfc7eSAndroid Build Coastguard Worker 
347*49cdfc7eSAndroid Build Coastguard Worker 		default:
348*49cdfc7eSAndroid Build Coastguard Worker 			if (strchr(uint_conv, *fmt)) {
349*49cdfc7eSAndroid Build Coastguard Worker 				u64val = va_arg(args, unsigned int);
350*49cdfc7eSAndroid Build Coastguard Worker 				conv = *fmt;
351*49cdfc7eSAndroid Build Coastguard Worker 				break;
352*49cdfc7eSAndroid Build Coastguard Worker 			}
353*49cdfc7eSAndroid Build Coastguard Worker 
354*49cdfc7eSAndroid Build Coastguard Worker 			va_end(args);
355*49cdfc7eSAndroid Build Coastguard Worker 			return -1;
356*49cdfc7eSAndroid Build Coastguard Worker 		}
357*49cdfc7eSAndroid Build Coastguard Worker 
358*49cdfc7eSAndroid Build Coastguard Worker 		switch (conv) {
359*49cdfc7eSAndroid Build Coastguard Worker 		case 0:
360*49cdfc7eSAndroid Build Coastguard Worker 			continue;
361*49cdfc7eSAndroid Build Coastguard Worker 
362*49cdfc7eSAndroid Build Coastguard Worker 		case 'd':
363*49cdfc7eSAndroid Build Coastguard Worker 		case 'i':
364*49cdfc7eSAndroid Build Coastguard Worker 			i64tostr(dest + ret, i64val);
365*49cdfc7eSAndroid Build Coastguard Worker 			ret += strlen(dest + ret);
366*49cdfc7eSAndroid Build Coastguard Worker 			break;
367*49cdfc7eSAndroid Build Coastguard Worker 
368*49cdfc7eSAndroid Build Coastguard Worker 		case 'o':
369*49cdfc7eSAndroid Build Coastguard Worker 			u64tostr(dest + ret, u64val, 8, 0);
370*49cdfc7eSAndroid Build Coastguard Worker 			ret += strlen(dest + ret);
371*49cdfc7eSAndroid Build Coastguard Worker 			break;
372*49cdfc7eSAndroid Build Coastguard Worker 
373*49cdfc7eSAndroid Build Coastguard Worker 		case 'u':
374*49cdfc7eSAndroid Build Coastguard Worker 			u64tostr(dest + ret, u64val, 10, 0);
375*49cdfc7eSAndroid Build Coastguard Worker 			ret += strlen(dest + ret);
376*49cdfc7eSAndroid Build Coastguard Worker 			break;
377*49cdfc7eSAndroid Build Coastguard Worker 
378*49cdfc7eSAndroid Build Coastguard Worker 		case 'x':
379*49cdfc7eSAndroid Build Coastguard Worker 			u64tostr(dest + ret, u64val, 16, 0);
380*49cdfc7eSAndroid Build Coastguard Worker 			ret += strlen(dest + ret);
381*49cdfc7eSAndroid Build Coastguard Worker 			break;
382*49cdfc7eSAndroid Build Coastguard Worker 
383*49cdfc7eSAndroid Build Coastguard Worker 		case 'X':
384*49cdfc7eSAndroid Build Coastguard Worker 			u64tostr(dest + ret, u64val, 16, 1);
385*49cdfc7eSAndroid Build Coastguard Worker 			ret += strlen(dest + ret);
386*49cdfc7eSAndroid Build Coastguard Worker 			break;
387*49cdfc7eSAndroid Build Coastguard Worker 
388*49cdfc7eSAndroid Build Coastguard Worker 		default:
389*49cdfc7eSAndroid Build Coastguard Worker 			va_end(args);
390*49cdfc7eSAndroid Build Coastguard Worker 			return -1;
391*49cdfc7eSAndroid Build Coastguard Worker 		}
392*49cdfc7eSAndroid Build Coastguard Worker 	}
393*49cdfc7eSAndroid Build Coastguard Worker 
394*49cdfc7eSAndroid Build Coastguard Worker 	va_end(args);
395*49cdfc7eSAndroid Build Coastguard Worker 	dest[ret++] = '\0';
396*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
397*49cdfc7eSAndroid Build Coastguard Worker }
398*49cdfc7eSAndroid Build Coastguard Worker 
sprintf(char * dest,const char * fmt,...)399*49cdfc7eSAndroid Build Coastguard Worker int sprintf(char *dest, const char *fmt, ...)
400*49cdfc7eSAndroid Build Coastguard Worker {
401*49cdfc7eSAndroid Build Coastguard Worker 	va_list args;
402*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
403*49cdfc7eSAndroid Build Coastguard Worker 
404*49cdfc7eSAndroid Build Coastguard Worker 	va_start(args, fmt);
405*49cdfc7eSAndroid Build Coastguard Worker 	ret = vsprintf(dest, fmt, args);
406*49cdfc7eSAndroid Build Coastguard Worker 	va_end(args);
407*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
408*49cdfc7eSAndroid Build Coastguard Worker }
409*49cdfc7eSAndroid Build Coastguard Worker 
tst_heap_alloc_aligned(size_t size,size_t align)410*49cdfc7eSAndroid Build Coastguard Worker void *tst_heap_alloc_aligned(size_t size, size_t align)
411*49cdfc7eSAndroid Build Coastguard Worker {
412*49cdfc7eSAndroid Build Coastguard Worker 	uintptr_t addr = (uintptr_t)heap_end;
413*49cdfc7eSAndroid Build Coastguard Worker 	void *ret;
414*49cdfc7eSAndroid Build Coastguard Worker 
415*49cdfc7eSAndroid Build Coastguard Worker 	addr += align - 1;
416*49cdfc7eSAndroid Build Coastguard Worker 	addr -= addr % align;
417*49cdfc7eSAndroid Build Coastguard Worker 	ret = (void *)addr;
418*49cdfc7eSAndroid Build Coastguard Worker 	heap_end = (char *)LTP_ALIGN(addr + size, 4);
419*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
420*49cdfc7eSAndroid Build Coastguard Worker }
421*49cdfc7eSAndroid Build Coastguard Worker 
tst_heap_alloc(size_t size)422*49cdfc7eSAndroid Build Coastguard Worker void *tst_heap_alloc(size_t size)
423*49cdfc7eSAndroid Build Coastguard Worker {
424*49cdfc7eSAndroid Build Coastguard Worker 	void *ret = heap_end;
425*49cdfc7eSAndroid Build Coastguard Worker 
426*49cdfc7eSAndroid Build Coastguard Worker 	heap_end += LTP_ALIGN(size, 4);
427*49cdfc7eSAndroid Build Coastguard Worker 	return ret;
428*49cdfc7eSAndroid Build Coastguard Worker }
429*49cdfc7eSAndroid Build Coastguard Worker 
tst_set_interrupt_callback(unsigned int vector,tst_interrupt_callback func,void * userdata)430*49cdfc7eSAndroid Build Coastguard Worker void tst_set_interrupt_callback(unsigned int vector,
431*49cdfc7eSAndroid Build Coastguard Worker 	tst_interrupt_callback func, void *userdata)
432*49cdfc7eSAndroid Build Coastguard Worker {
433*49cdfc7eSAndroid Build Coastguard Worker 	if (vector >= INTERRUPT_COUNT)
434*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk(TBROK, "Set interrupt callback: vector out of range");
435*49cdfc7eSAndroid Build Coastguard Worker 
436*49cdfc7eSAndroid Build Coastguard Worker 	intr_handlers[vector].callback = func;
437*49cdfc7eSAndroid Build Coastguard Worker 	intr_handlers[vector].userdata = userdata;
438*49cdfc7eSAndroid Build Coastguard Worker }
439*49cdfc7eSAndroid Build Coastguard Worker 
tst_fatal_error(const char * file,const int lineno,const char * message,uintptr_t ip)440*49cdfc7eSAndroid Build Coastguard Worker static void tst_fatal_error(const char *file, const int lineno,
441*49cdfc7eSAndroid Build Coastguard Worker 	const char *message, uintptr_t ip)
442*49cdfc7eSAndroid Build Coastguard Worker {
443*49cdfc7eSAndroid Build Coastguard Worker 	test_result->result = TBROK;
444*49cdfc7eSAndroid Build Coastguard Worker 	test_result->lineno = lineno;
445*49cdfc7eSAndroid Build Coastguard Worker 	test_result->file_addr = (uintptr_t)file;
446*49cdfc7eSAndroid Build Coastguard Worker 	/* Avoid sprintf() here in case of bugs */
447*49cdfc7eSAndroid Build Coastguard Worker 	strcpy(test_result->message, message);
448*49cdfc7eSAndroid Build Coastguard Worker 	strcat(test_result->message, " at address 0x");
449*49cdfc7eSAndroid Build Coastguard Worker 	ptr2hex(test_result->message + strlen(test_result->message), ip);
450*49cdfc7eSAndroid Build Coastguard Worker 	kvm_yield();
451*49cdfc7eSAndroid Build Coastguard Worker 	kvm_exit();
452*49cdfc7eSAndroid Build Coastguard Worker }
453*49cdfc7eSAndroid Build Coastguard Worker 
tst_res_(const char * file,const int lineno,int result,const char * fmt,...)454*49cdfc7eSAndroid Build Coastguard Worker void tst_res_(const char *file, const int lineno, int result,
455*49cdfc7eSAndroid Build Coastguard Worker 	const char *fmt, ...)
456*49cdfc7eSAndroid Build Coastguard Worker {
457*49cdfc7eSAndroid Build Coastguard Worker 	va_list args;
458*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
459*49cdfc7eSAndroid Build Coastguard Worker 
460*49cdfc7eSAndroid Build Coastguard Worker 	va_start(args, fmt);
461*49cdfc7eSAndroid Build Coastguard Worker 	test_result->result = result;
462*49cdfc7eSAndroid Build Coastguard Worker 	test_result->lineno = lineno;
463*49cdfc7eSAndroid Build Coastguard Worker 	test_result->file_addr = (uintptr_t)file;
464*49cdfc7eSAndroid Build Coastguard Worker 	ret = vsprintf(test_result->message, fmt, args);
465*49cdfc7eSAndroid Build Coastguard Worker 	va_end(args);
466*49cdfc7eSAndroid Build Coastguard Worker 
467*49cdfc7eSAndroid Build Coastguard Worker 	if (ret < 0) {
468*49cdfc7eSAndroid Build Coastguard Worker 		tst_brk_(file, lineno, TBROK, "Invalid tst_res() format: %s",
469*49cdfc7eSAndroid Build Coastguard Worker 			fmt);
470*49cdfc7eSAndroid Build Coastguard Worker 	}
471*49cdfc7eSAndroid Build Coastguard Worker 
472*49cdfc7eSAndroid Build Coastguard Worker 	kvm_yield();
473*49cdfc7eSAndroid Build Coastguard Worker }
474*49cdfc7eSAndroid Build Coastguard Worker 
tst_brk_(const char * file,const int lineno,int result,const char * fmt,...)475*49cdfc7eSAndroid Build Coastguard Worker void tst_brk_(const char *file, const int lineno, int result,
476*49cdfc7eSAndroid Build Coastguard Worker 	const char *fmt, ...)
477*49cdfc7eSAndroid Build Coastguard Worker {
478*49cdfc7eSAndroid Build Coastguard Worker 	va_list args;
479*49cdfc7eSAndroid Build Coastguard Worker 	int ret;
480*49cdfc7eSAndroid Build Coastguard Worker 
481*49cdfc7eSAndroid Build Coastguard Worker 	va_start(args, fmt);
482*49cdfc7eSAndroid Build Coastguard Worker 	test_result->result = result;
483*49cdfc7eSAndroid Build Coastguard Worker 	test_result->lineno = lineno;
484*49cdfc7eSAndroid Build Coastguard Worker 	test_result->file_addr = (uintptr_t)file;
485*49cdfc7eSAndroid Build Coastguard Worker 	ret = vsprintf(test_result->message, fmt, args);
486*49cdfc7eSAndroid Build Coastguard Worker 	va_end(args);
487*49cdfc7eSAndroid Build Coastguard Worker 
488*49cdfc7eSAndroid Build Coastguard Worker 	if (ret < 0) {
489*49cdfc7eSAndroid Build Coastguard Worker 		test_result->result = TBROK;
490*49cdfc7eSAndroid Build Coastguard Worker 		strcpy(test_result->message, "Invalid tst_brk() format: ");
491*49cdfc7eSAndroid Build Coastguard Worker 		strcat(test_result->message, fmt);
492*49cdfc7eSAndroid Build Coastguard Worker 	}
493*49cdfc7eSAndroid Build Coastguard Worker 
494*49cdfc7eSAndroid Build Coastguard Worker 	kvm_yield();
495*49cdfc7eSAndroid Build Coastguard Worker 	kvm_exit();
496*49cdfc7eSAndroid Build Coastguard Worker }
497*49cdfc7eSAndroid Build Coastguard Worker 
tst_signal_host(void * data)498*49cdfc7eSAndroid Build Coastguard Worker void tst_signal_host(void *data)
499*49cdfc7eSAndroid Build Coastguard Worker {
500*49cdfc7eSAndroid Build Coastguard Worker 	test_result->file_addr = (uintptr_t)data;
501*49cdfc7eSAndroid Build Coastguard Worker 	test_result->result = KVM_TSYNC;
502*49cdfc7eSAndroid Build Coastguard Worker }
503*49cdfc7eSAndroid Build Coastguard Worker 
tst_wait_host(void * data)504*49cdfc7eSAndroid Build Coastguard Worker void tst_wait_host(void *data)
505*49cdfc7eSAndroid Build Coastguard Worker {
506*49cdfc7eSAndroid Build Coastguard Worker 	volatile int32_t *vres = &test_result->result;
507*49cdfc7eSAndroid Build Coastguard Worker 
508*49cdfc7eSAndroid Build Coastguard Worker 	tst_signal_host(data);
509*49cdfc7eSAndroid Build Coastguard Worker 
510*49cdfc7eSAndroid Build Coastguard Worker 	while (*vres != KVM_TNONE)
511*49cdfc7eSAndroid Build Coastguard Worker 		;
512*49cdfc7eSAndroid Build Coastguard Worker }
513*49cdfc7eSAndroid Build Coastguard Worker 
tst_handle_interrupt(struct kvm_interrupt_frame * ifrm,long vector,unsigned long errcode)514*49cdfc7eSAndroid Build Coastguard Worker void tst_handle_interrupt(struct kvm_interrupt_frame *ifrm, long vector,
515*49cdfc7eSAndroid Build Coastguard Worker 	unsigned long errcode)
516*49cdfc7eSAndroid Build Coastguard Worker {
517*49cdfc7eSAndroid Build Coastguard Worker 	uintptr_t ip = kvm_get_interrupt_ip(ifrm);
518*49cdfc7eSAndroid Build Coastguard Worker 	const char *iname;
519*49cdfc7eSAndroid Build Coastguard Worker 	tst_interrupt_callback callback;
520*49cdfc7eSAndroid Build Coastguard Worker 	int ret = 0;
521*49cdfc7eSAndroid Build Coastguard Worker 
522*49cdfc7eSAndroid Build Coastguard Worker 	if (vector < 0 || vector >= INTERRUPT_COUNT)
523*49cdfc7eSAndroid Build Coastguard Worker 		tst_fatal_error(__FILE__, __LINE__, "Unexpected interrupt", ip);
524*49cdfc7eSAndroid Build Coastguard Worker 
525*49cdfc7eSAndroid Build Coastguard Worker 	callback = intr_handlers[vector].callback;
526*49cdfc7eSAndroid Build Coastguard Worker 
527*49cdfc7eSAndroid Build Coastguard Worker 	if (callback)
528*49cdfc7eSAndroid Build Coastguard Worker 		ret = callback(intr_handlers[vector].userdata, ifrm, errcode);
529*49cdfc7eSAndroid Build Coastguard Worker 
530*49cdfc7eSAndroid Build Coastguard Worker 	iname = tst_interrupt_names[vector];
531*49cdfc7eSAndroid Build Coastguard Worker 	iname = iname ? iname : "Unexpected interrupt";
532*49cdfc7eSAndroid Build Coastguard Worker 
533*49cdfc7eSAndroid Build Coastguard Worker 	if (!ret)
534*49cdfc7eSAndroid Build Coastguard Worker 		tst_fatal_error(__FILE__, __LINE__, iname, ip);
535*49cdfc7eSAndroid Build Coastguard Worker }
536