summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/.gitignore1
-rw-r--r--tests/Makefile.include2
-rw-r--r--tests/libqos/virtio.c2
-rw-r--r--tests/tcg/cris/Makefile21
-rw-r--r--tests/tcg/cris/check_abs.c4
-rw-r--r--tests/tcg/cris/check_addc.c2
-rw-r--r--tests/tcg/cris/check_addcm.c4
-rw-r--r--tests/tcg/cris/check_addcv17.s65
-rw-r--r--tests/tcg/cris/check_bound.c6
-rw-r--r--tests/tcg/cris/check_ftag.c8
-rw-r--r--tests/tcg/cris/check_int64.c4
-rw-r--r--tests/tcg/cris/check_lz.c2
-rw-r--r--tests/tcg/cris/check_openpf4.c5
-rw-r--r--tests/tcg/cris/check_swap.c2
-rw-r--r--tests/tcg/cris/check_time1.c46
-rw-r--r--tests/tcg/cris/crisutils.h20
-rw-r--r--tests/tcg/cris/sys.c26
-rw-r--r--tests/tcg/cris/sys.h2
-rw-r--r--tests/test-coroutine.c42
-rw-r--r--tests/test-x86-cpuid-compat.c171
20 files changed, 344 insertions, 91 deletions
diff --git a/tests/.gitignore b/tests/.gitignore
index 24ac6cfa77..0f0c79b1a9 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -75,6 +75,7 @@ test-visitor-serialization
test-vmstate
test-write-threshold
test-x86-cpuid
+test-x86-cpuid-compat
test-xbzrle
test-netfilter
test-filter-mirror
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 2aa78c1820..8162f6f735 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -243,6 +243,7 @@ check-qtest-i386-y += tests/test-netfilter$(EXESUF)
check-qtest-i386-y += tests/test-filter-mirror$(EXESUF)
check-qtest-i386-y += tests/test-filter-redirector$(EXESUF)
check-qtest-i386-y += tests/postcopy-test$(EXESUF)
+check-qtest-i386-y += tests/test-x86-cpuid-compat$(EXESUF)
check-qtest-x86_64-y += $(check-qtest-i386-y)
gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
@@ -663,6 +664,7 @@ tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o $(test-block-o
tests/test-netfilter$(EXESUF): tests/test-netfilter.o $(qtest-obj-y)
tests/test-filter-mirror$(EXESUF): tests/test-filter-mirror.o $(qtest-obj-y)
tests/test-filter-redirector$(EXESUF): tests/test-filter-redirector.o $(qtest-obj-y)
+tests/test-x86-cpuid-compat$(EXESUF): tests/test-x86-cpuid-compat.o $(qtest-obj-y)
tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y)
tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o
tests/ptimer-test$(EXESUF): tests/ptimer-test.o tests/ptimer-test-stubs.o hw/core/ptimer.o
diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c
index 37ff860c16..105bccecaa 100644
--- a/tests/libqos/virtio.c
+++ b/tests/libqos/virtio.c
@@ -147,7 +147,7 @@ void qvring_init(const QGuestAllocator *alloc, QVirtQueue *vq, uint64_t addr)
for (i = 0; i < vq->size - 1; i++) {
/* vq->desc[i].addr */
- writew(vq->desc + (16 * i), 0);
+ writeq(vq->desc + (16 * i), 0);
/* vq->desc[i].next */
writew(vq->desc + (16 * i) + 14, i + 1);
}
diff --git a/tests/tcg/cris/Makefile b/tests/tcg/cris/Makefile
index d34bfd8f7a..6b3dba446c 100644
--- a/tests/tcg/cris/Makefile
+++ b/tests/tcg/cris/Makefile
@@ -23,6 +23,7 @@ SYS = sys.o
TESTCASES += check_abs.tst
TESTCASES += check_addc.tst
TESTCASES += check_addcm.tst
+TESTCASES += check_addcv17.tst
TESTCASES += check_addo.tst
TESTCASES += check_addoq.tst
TESTCASES += check_addi.tst
@@ -108,14 +109,12 @@ TESTCASES += check_stat4.ctst
TESTCASES += check_openpf1.ctst
TESTCASES += check_openpf2.ctst
TESTCASES += check_openpf3.ctst
-TESTCASES += check_openpf4.ctst
TESTCASES += check_openpf5.ctst
TESTCASES += check_mapbrk.ctst
TESTCASES += check_mmap1.ctst
TESTCASES += check_mmap2.ctst
TESTCASES += check_mmap3.ctst
TESTCASES += check_sigalrm.ctst
-TESTCASES += check_time1.ctst
TESTCASES += check_time2.ctst
TESTCASES += check_settls1.ctst
@@ -136,13 +135,27 @@ all: build
%.ctst: %.o
$(CC) $(CFLAGS) $(LDLIBS) $< -o $@
+
+sysv10.o: sys.c
+ $(CC) $(CFLAGS) -mcpu=v10 -c $< -o $@
+
+crtv10.o: crt.s
+ $(AS) $(ASFLAGS) -mcpu=v10 -c $< -o $@
+
+check_addcv17.tst: ASFLAGS += -mcpu=v10
+check_addcv17.tst: CRT := crtv10.o
+check_addcv17.tst: SYS := sysv10.o
+check_addcv17.tst: crtv10.o sysv10.o
+
build: $(CRT) $(SYS) $(TESTCASES)
check: $(CRT) $(SYS) $(TESTCASES)
@echo -e "\nQEMU simulator."
for case in $(TESTCASES); do \
echo -n "$$case "; \
- $(SIM) ./$$case; \
+ SIMARGS=; \
+ case $$case in *v17*) SIMARGS="-cpu crisv17";; esac; \
+ $(SIM) $$SIMARGS ./$$case; \
done
check-g: $(CRT) $(SYS) $(TESTCASES)
@echo -e "\nGDB simulator."
@@ -152,4 +165,4 @@ check-g: $(CRT) $(SYS) $(TESTCASES)
done
clean:
- $(RM) -fr $(TESTCASES) $(CRT) $(SYS)
+ $(RM) -fr $(TESTCASES) *.o
diff --git a/tests/tcg/cris/check_abs.c b/tests/tcg/cris/check_abs.c
index 9770a8d9ef..08b67b6ef0 100644
--- a/tests/tcg/cris/check_abs.c
+++ b/tests/tcg/cris/check_abs.c
@@ -4,14 +4,14 @@
#include "sys.h"
#include "crisutils.h"
-static inline int cris_abs(int n)
+static always_inline int cris_abs(int n)
{
int r;
asm ("abs\t%1, %0\n" : "=r" (r) : "r" (n));
return r;
}
-static inline void
+static always_inline void
verify_abs(int val, int res,
const int n, const int z, const int v, const int c)
{
diff --git a/tests/tcg/cris/check_addc.c b/tests/tcg/cris/check_addc.c
index facd1bea2d..fc3fb1faa8 100644
--- a/tests/tcg/cris/check_addc.c
+++ b/tests/tcg/cris/check_addc.c
@@ -4,7 +4,7 @@
#include "sys.h"
#include "crisutils.h"
-static inline int cris_addc(int a, const int b)
+static always_inline int cris_addc(int a, const int b)
{
asm ("addc\t%1, %0\n" : "+r" (a) : "r" (b));
return a;
diff --git a/tests/tcg/cris/check_addcm.c b/tests/tcg/cris/check_addcm.c
index 7928bc9999..b355ba164f 100644
--- a/tests/tcg/cris/check_addcm.c
+++ b/tests/tcg/cris/check_addcm.c
@@ -5,14 +5,14 @@
#include "crisutils.h"
/* need to avoid acr as source here. */
-static inline int cris_addc_m(int a, const int *b)
+static always_inline int cris_addc_m(int a, const int *b)
{
asm volatile ("addc [%1], %0\n" : "+r" (a) : "r" (b));
return a;
}
/* 'b' is a crisv32 constrain to avoid postinc with $acr. */
-static inline int cris_addc_pi_m(int a, int **b)
+static always_inline int cris_addc_pi_m(int a, int **b)
{
asm volatile ("addc [%1+], %0\n" : "+r" (a), "+b" (*b));
return a;
diff --git a/tests/tcg/cris/check_addcv17.s b/tests/tcg/cris/check_addcv17.s
new file mode 100644
index 0000000000..52ef7a9716
--- /dev/null
+++ b/tests/tcg/cris/check_addcv17.s
@@ -0,0 +1,65 @@
+# mach: crisv17
+
+ .include "testutils.inc"
+
+ .macro addc Rs Rd inc=0
+# Create the instruction manually since there is no assembler support yet
+ .word (\Rd << 12) | \Rs | (\inc << 10) | 0x09a0
+ .endm
+
+ start
+
+ .data
+mem1:
+ .dword 0x0
+mem2:
+ .dword 0x12345678
+
+ .text
+ move.d mem1,r4
+ clearf nzvc
+ addc 4 3
+ test_cc 0 1 0 0
+ checkr3 0
+
+ move.d mem1,r4
+ clearf nzvc
+ ax
+ addc 4 3
+ test_cc 0 0 0 0
+ checkr3 0
+
+ move.d mem1,r4
+ clearf nzvc
+ setf c
+ addc 4 3
+ test_cc 0 0 0 0
+ checkr3 1
+
+ move.d mem2,r4
+ moveq 2, r3
+ clearf nzvc
+ setf c
+ addc 4 3
+ test_cc 0 0 0 0
+ checkr3 1234567b
+
+ move.d mem2,r5
+ clearf nzvc
+ cmp.d r4,r5
+ test_cc 0 1 0 0
+
+ move.d mem2,r4
+ moveq 2, r3
+ clearf nzvc
+ addc 4 3 inc=1
+ test_cc 0 0 0 0
+ checkr3 1234567a
+
+ move.d mem2,r5
+ clearf nzvc
+ addq 4,r5
+ cmp.d r4,r5
+ test_cc 0 1 0 0
+
+ quit
diff --git a/tests/tcg/cris/check_bound.c b/tests/tcg/cris/check_bound.c
index e8831754ec..d956ab9ade 100644
--- a/tests/tcg/cris/check_bound.c
+++ b/tests/tcg/cris/check_bound.c
@@ -4,21 +4,21 @@
#include "sys.h"
#include "crisutils.h"
-static inline int cris_bound_b(int v, int b)
+static always_inline int cris_bound_b(int v, int b)
{
int r = v;
asm ("bound.b\t%1, %0\n" : "+r" (r) : "ri" (b));
return r;
}
-static inline int cris_bound_w(int v, int b)
+static always_inline int cris_bound_w(int v, int b)
{
int r = v;
asm ("bound.w\t%1, %0\n" : "+r" (r) : "ri" (b));
return r;
}
-static inline int cris_bound_d(int v, int b)
+static always_inline int cris_bound_d(int v, int b)
{
int r = v;
asm ("bound.d\t%1, %0\n" : "+r" (r) : "ri" (b));
diff --git a/tests/tcg/cris/check_ftag.c b/tests/tcg/cris/check_ftag.c
index 908773a38a..aaa5c97115 100644
--- a/tests/tcg/cris/check_ftag.c
+++ b/tests/tcg/cris/check_ftag.c
@@ -4,22 +4,22 @@
#include "sys.h"
#include "crisutils.h"
-static inline void cris_ftag_i(unsigned int x)
+static always_inline void cris_ftag_i(unsigned int x)
{
register unsigned int v asm("$r10") = x;
asm ("ftagi\t[%0]\n" : : "r" (v) );
}
-static inline void cris_ftag_d(unsigned int x)
+static always_inline void cris_ftag_d(unsigned int x)
{
register unsigned int v asm("$r10") = x;
asm ("ftagd\t[%0]\n" : : "r" (v) );
}
-static inline void cris_fidx_i(unsigned int x)
+static always_inline void cris_fidx_i(unsigned int x)
{
register unsigned int v asm("$r10") = x;
asm ("fidxi\t[%0]\n" : : "r" (v) );
}
-static inline void cris_fidx_d(unsigned int x)
+static always_inline void cris_fidx_d(unsigned int x)
{
register unsigned int v asm("$r10") = x;
asm ("fidxd\t[%0]\n" : : "r" (v) );
diff --git a/tests/tcg/cris/check_int64.c b/tests/tcg/cris/check_int64.c
index fc600176e2..69caec1bb2 100644
--- a/tests/tcg/cris/check_int64.c
+++ b/tests/tcg/cris/check_int64.c
@@ -5,12 +5,12 @@
#include "crisutils.h"
-static inline int64_t add64(const int64_t a, const int64_t b)
+static always_inline int64_t add64(const int64_t a, const int64_t b)
{
return a + b;
}
-static inline int64_t sub64(const int64_t a, const int64_t b)
+static always_inline int64_t sub64(const int64_t a, const int64_t b)
{
return a - b;
}
diff --git a/tests/tcg/cris/check_lz.c b/tests/tcg/cris/check_lz.c
index 69c2e6d4ec..bf051a6b55 100644
--- a/tests/tcg/cris/check_lz.c
+++ b/tests/tcg/cris/check_lz.c
@@ -3,7 +3,7 @@
#include <stdint.h>
#include "sys.h"
-static inline int cris_lz(int x)
+static always_inline int cris_lz(int x)
{
int r;
asm ("lz\t%1, %0\n" : "=r" (r) : "r" (x));
diff --git a/tests/tcg/cris/check_openpf4.c b/tests/tcg/cris/check_openpf4.c
deleted file mode 100644
index 8bbee41a64..0000000000
--- a/tests/tcg/cris/check_openpf4.c
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Basic file operations, now *with* sysroot.
-#sim: --sysroot=@exedir@
-*/
-#define PREFIX "/"
-#include "check_openpf3.c"
diff --git a/tests/tcg/cris/check_swap.c b/tests/tcg/cris/check_swap.c
index f851cbcef1..9a68c1e5d7 100644
--- a/tests/tcg/cris/check_swap.c
+++ b/tests/tcg/cris/check_swap.c
@@ -9,7 +9,7 @@
#define B 2
#define R 1
-static inline int cris_swap(const int mode, int x)
+static always_inline int cris_swap(const int mode, int x)
{
switch (mode)
{
diff --git a/tests/tcg/cris/check_time1.c b/tests/tcg/cris/check_time1.c
deleted file mode 100644
index 3fcf0e1535..0000000000
--- a/tests/tcg/cris/check_time1.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Basic time functionality test: check that milliseconds are
- incremented for each syscall (does not work on host). */
-#include <stdio.h>
-#include <time.h>
-#include <sys/time.h>
-#include <string.h>
-#include <stdlib.h>
-
-void err (const char *s)
-{
- perror (s);
- abort ();
-}
-
-int
-main (void)
-{
- struct timeval t_m = {0, 0};
- struct timezone t_z = {0, 0};
- struct timeval t_m1 = {0, 0};
- int i;
-
- if (gettimeofday (&t_m, &t_z) != 0)
- err ("gettimeofday");
-
- for (i = 1; i < 10000; i++)
- if (gettimeofday (&t_m1, NULL) != 0)
- err ("gettimeofday 1");
- else
- if (t_m1.tv_sec * 1000000 + t_m1.tv_usec
- != (t_m.tv_sec * 1000000 + t_m.tv_usec + i * 1000))
- {
- fprintf (stderr, "t0 (%ld, %ld), i %d, t1 (%ld, %ld)\n",
- t_m.tv_sec, t_m.tv_usec, i, t_m1.tv_sec, t_m1.tv_usec);
- abort ();
- }
-
- if (time (NULL) != t_m1.tv_sec)
- {
- fprintf (stderr, "time != gettod\n");
- abort ();
- }
-
- printf ("pass\n");
- exit (0);
-}
diff --git a/tests/tcg/cris/crisutils.h b/tests/tcg/cris/crisutils.h
index 3456b9d50d..bbbe6c5540 100644
--- a/tests/tcg/cris/crisutils.h
+++ b/tests/tcg/cris/crisutils.h
@@ -13,57 +13,57 @@ void _err(void) {
_fail(tst_cc_loc);
}
-static inline void cris_tst_cc_n1(void)
+static always_inline void cris_tst_cc_n1(void)
{
asm volatile ("bpl _err\n"
"nop\n");
}
-static inline void cris_tst_cc_n0(void)
+static always_inline void cris_tst_cc_n0(void)
{
asm volatile ("bmi _err\n"
"nop\n");
}
-static inline void cris_tst_cc_z1(void)
+static always_inline void cris_tst_cc_z1(void)
{
asm volatile ("bne _err\n"
"nop\n");
}
-static inline void cris_tst_cc_z0(void)
+static always_inline void cris_tst_cc_z0(void)
{
asm volatile ("beq _err\n"
"nop\n");
}
-static inline void cris_tst_cc_v1(void)
+static always_inline void cris_tst_cc_v1(void)
{
asm volatile ("bvc _err\n"
"nop\n");
}
-static inline void cris_tst_cc_v0(void)
+static always_inline void cris_tst_cc_v0(void)
{
asm volatile ("bvs _err\n"
"nop\n");
}
-static inline void cris_tst_cc_c1(void)
+static always_inline void cris_tst_cc_c1(void)
{
asm volatile ("bcc _err\n"
"nop\n");
}
-static inline void cris_tst_cc_c0(void)
+static always_inline void cris_tst_cc_c0(void)
{
asm volatile ("bcs _err\n"
"nop\n");
}
-static inline void cris_tst_mov_cc(int n, int z)
+static always_inline void cris_tst_mov_cc(int n, int z)
{
if (n) cris_tst_cc_n1(); else cris_tst_cc_n0();
if (z) cris_tst_cc_z1(); else cris_tst_cc_z0();
asm volatile ("" : : "g" (_err));
}
-static inline void cris_tst_cc(const int n, const int z,
+static always_inline void cris_tst_cc(const int n, const int z,
const int v, const int c)
{
if (n) cris_tst_cc_n1(); else cris_tst_cc_n0();
diff --git a/tests/tcg/cris/sys.c b/tests/tcg/cris/sys.c
index 551c5dd7cb..21f08c0747 100644
--- a/tests/tcg/cris/sys.c
+++ b/tests/tcg/cris/sys.c
@@ -33,19 +33,27 @@ void *memset (void *s, int c, size_t n) {
}
void exit (int status) {
- asm volatile ("moveq 1, $r9\n" /* NR_exit. */
- "break 13\n");
+ register unsigned int callno asm ("r9") = 1; /* NR_exit */
+
+ asm volatile ("break 13\n"
+ :
+ : "r" (callno)
+ : "memory" );
while(1)
;
}
ssize_t write (int fd, const void *buf, size_t count) {
- int r;
- asm ("move.d %0, $r10\n"
- "move.d %1, $r11\n"
- "move.d %2, $r12\n"
- "moveq 4, $r9\n" /* NR_write. */
- "break 13\n" : : "r" (fd), "r" (buf), "r" (count) : "memory");
- asm ("move.d $r10, %0\n" : "=r" (r));
+ register unsigned int callno asm ("r9") = 4; /* NR_write */
+ register unsigned int r10 asm ("r10") = fd;
+ register const void *r11 asm ("r11") = buf;
+ register size_t r12 asm ("r12") = count;
+ register unsigned int r asm ("r10");
+
+ asm volatile ("break 13\n"
+ : "=r" (r)
+ : "r" (callno), "0" (r10), "r" (r11), "r" (r12)
+ : "memory");
+
return r;
}
diff --git a/tests/tcg/cris/sys.h b/tests/tcg/cris/sys.h
index c5f88e1a29..3dd47bb673 100644
--- a/tests/tcg/cris/sys.h
+++ b/tests/tcg/cris/sys.h
@@ -3,6 +3,8 @@
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
+#define always_inline inline __attribute__((always_inline))
+
#define CURRENT_LOCATION __FILE__ ":" TOSTRING(__LINE__)
#define err() \
diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c
index 6431dd6d7c..abd97c23c1 100644
--- a/tests/test-coroutine.c
+++ b/tests/test-coroutine.c
@@ -53,6 +53,47 @@ static void test_self(void)
}
/*
+ * Check that qemu_coroutine_entered() works
+ */
+
+static void coroutine_fn verify_entered_step_2(void *opaque)
+{
+ Coroutine *caller = (Coroutine *)opaque;
+
+ g_assert(qemu_coroutine_entered(caller));
+ g_assert(qemu_coroutine_entered(qemu_coroutine_self()));
+ qemu_coroutine_yield();
+
+ /* Once more to check it still works after yielding */
+ g_assert(qemu_coroutine_entered(caller));
+ g_assert(qemu_coroutine_entered(qemu_coroutine_self()));
+ qemu_coroutine_yield();
+}
+
+static void coroutine_fn verify_entered_step_1(void *opaque)
+{
+ Coroutine *self = qemu_coroutine_self();
+ Coroutine *coroutine;
+
+ g_assert(qemu_coroutine_entered(self));
+
+ coroutine = qemu_coroutine_create(verify_entered_step_2, self);
+ g_assert(!qemu_coroutine_entered(coroutine));
+ qemu_coroutine_enter(coroutine);
+ g_assert(!qemu_coroutine_entered(coroutine));
+ qemu_coroutine_enter(coroutine);
+}
+
+static void test_entered(void)
+{
+ Coroutine *coroutine;
+
+ coroutine = qemu_coroutine_create(verify_entered_step_1, NULL);
+ g_assert(!qemu_coroutine_entered(coroutine));
+ qemu_coroutine_enter(coroutine);
+}
+
+/*
* Check that coroutines may nest multiple levels
*/
@@ -389,6 +430,7 @@ int main(int argc, char **argv)
g_test_add_func("/basic/yield", test_yield);
g_test_add_func("/basic/nesting", test_nesting);
g_test_add_func("/basic/self", test_self);
+ g_test_add_func("/basic/entered", test_entered);
g_test_add_func("/basic/in_coroutine", test_in_coroutine);
g_test_add_func("/basic/order", test_order);
if (g_test_perf()) {
diff --git a/tests/test-x86-cpuid-compat.c b/tests/test-x86-cpuid-compat.c
new file mode 100644
index 0000000000..83162a44c0
--- /dev/null
+++ b/tests/test-x86-cpuid-compat.c
@@ -0,0 +1,171 @@
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qapi/qmp/qlist.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qint.h"
+#include "libqtest.h"
+
+static char *get_cpu0_qom_path(void)
+{
+ QDict *resp;
+ QList *ret;
+ QDict *cpu0;
+ char *path;
+
+ resp = qmp("{'execute': 'query-cpus', 'arguments': {}}");
+ g_assert(qdict_haskey(resp, "return"));
+ ret = qdict_get_qlist(resp, "return");
+
+ cpu0 = qobject_to_qdict(qlist_peek(ret));
+ path = g_strdup(qdict_get_str(cpu0, "qom_path"));
+ QDECREF(resp);
+ return path;
+}
+
+static QObject *qom_get(const char *path, const char *prop)
+{
+ QDict *resp = qmp("{ 'execute': 'qom-get',"
+ " 'arguments': { 'path': %s,"
+ " 'property': %s } }",
+ path, prop);
+ QObject *ret = qdict_get(resp, "return");
+ qobject_incref(ret);
+ QDECREF(resp);
+ return ret;
+}
+
+typedef struct CpuidTestArgs {
+ const char *cmdline;
+ const char *property;
+ int64_t expected_value;
+} CpuidTestArgs;
+
+static void test_cpuid_prop(const void *data)
+{
+ const CpuidTestArgs *args = data;
+ char *path;
+ QInt *value;
+
+ qtest_start(args->cmdline);
+ path = get_cpu0_qom_path();
+ value = qobject_to_qint(qom_get(path, args->property));
+ g_assert_cmpint(qint_get_int(value), ==, args->expected_value);
+ qtest_end();
+
+ QDECREF(value);
+ g_free(path);
+}
+
+static void add_cpuid_test(const char *name, const char *cmdline,
+ const char *property, int64_t expected_value)
+{
+ CpuidTestArgs *args = g_new0(CpuidTestArgs, 1);
+ args->cmdline = cmdline;
+ args->property = property;
+ args->expected_value = expected_value;
+ qtest_add_data_func(name, args, test_cpuid_prop);
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+
+ /* Original level values for CPU models: */
+ add_cpuid_test("x86/cpuid/phenom/level",
+ "-cpu phenom", "level", 5);
+ add_cpuid_test("x86/cpuid/Conroe/level",
+ "-cpu Conroe", "level", 10);
+ add_cpuid_test("x86/cpuid/SandyBridge/level",
+ "-cpu SandyBridge", "level", 0xd);
+ add_cpuid_test("x86/cpuid/486/xlevel",
+ "-cpu 486", "xlevel", 0);
+ add_cpuid_test("x86/cpuid/core2duo/xlevel",
+ "-cpu core2duo", "xlevel", 0x80000008);
+ add_cpuid_test("x86/cpuid/phenom/xlevel",
+ "-cpu phenom", "xlevel", 0x8000001A);
+ add_cpuid_test("x86/cpuid/athlon/xlevel",
+ "-cpu athlon", "xlevel", 0x80000008);
+
+ /* If level is not large enough, it should increase automatically: */
+ /* CPUID[6].EAX: */
+ add_cpuid_test("x86/cpuid/auto-level/phenom/arat",
+ "-cpu 486,+arat", "level", 6);
+ /* CPUID[EAX=7,ECX=0].EBX: */
+ add_cpuid_test("x86/cpuid/auto-level/phenom/fsgsbase",
+ "-cpu phenom,+fsgsbase", "level", 7);
+ /* CPUID[EAX=7,ECX=0].ECX: */
+ add_cpuid_test("x86/cpuid/auto-level/phenom/avx512vbmi",
+ "-cpu phenom,+avx512vbmi", "level", 7);
+ /* CPUID[EAX=0xd,ECX=1].EAX: */
+ add_cpuid_test("x86/cpuid/auto-level/phenom/xsaveopt",
+ "-cpu phenom,+xsaveopt", "level", 0xd);
+ /* CPUID[8000_0001].EDX: */
+ add_cpuid_test("x86/cpuid/auto-xlevel/486/3dnow",
+ "-cpu 486,+3dnow", "xlevel", 0x80000001);
+ /* CPUID[8000_0001].ECX: */
+ add_cpuid_test("x86/cpuid/auto-xlevel/486/sse4a",
+ "-cpu 486,+sse4a", "xlevel", 0x80000001);
+ /* CPUID[8000_0007].EDX: */
+ add_cpuid_test("x86/cpuid/auto-xlevel/486/invtsc",
+ "-cpu 486,+invtsc", "xlevel", 0x80000007);
+ /* CPUID[8000_000A].EDX: */
+ add_cpuid_test("x86/cpuid/auto-xlevel/486/npt",
+ "-cpu 486,+npt", "xlevel", 0x8000000A);
+ /* CPUID[C000_0001].EDX: */
+ add_cpuid_test("x86/cpuid/auto-xlevel2/phenom/xstore",
+ "-cpu phenom,+xstore", "xlevel2", 0xC0000001);
+ /* SVM needs CPUID[0x8000000A] */
+ add_cpuid_test("x86/cpuid/auto-xlevel/athlon/svm",
+ "-cpu athlon,+svm", "xlevel", 0x8000000A);
+
+
+ /* If level is already large enough, it shouldn't change: */
+ add_cpuid_test("x86/cpuid/auto-level/SandyBridge/multiple",
+ "-cpu SandyBridge,+arat,+fsgsbase,+avx512vbmi",
+ "level", 0xd);
+ /* If level is explicitly set, it shouldn't change: */
+ add_cpuid_test("x86/cpuid/auto-level/486/fixed/0xF",
+ "-cpu 486,level=0xF,+arat,+fsgsbase,+avx512vbmi,+xsaveopt",
+ "level", 0xF);
+ add_cpuid_test("x86/cpuid/auto-level/486/fixed/2",
+ "-cpu 486,level=2,+arat,+fsgsbase,+avx512vbmi,+xsaveopt",
+ "level", 2);
+ add_cpuid_test("x86/cpuid/auto-level/486/fixed/0",
+ "-cpu 486,level=0,+arat,+fsgsbase,+avx512vbmi,+xsaveopt",
+ "level", 0);
+
+ /* if xlevel is already large enough, it shouldn't change: */
+ add_cpuid_test("x86/cpuid/auto-xlevel/phenom/3dnow",
+ "-cpu phenom,+3dnow,+sse4a,+invtsc,+npt,+svm",
+ "xlevel", 0x8000001A);
+ /* If xlevel is explicitly set, it shouldn't change: */
+ add_cpuid_test("x86/cpuid/auto-xlevel/486/fixed/80000002",
+ "-cpu 486,xlevel=0x80000002,+3dnow,+sse4a,+invtsc,+npt,+svm",
+ "xlevel", 0x80000002);
+ add_cpuid_test("x86/cpuid/auto-xlevel/486/fixed/8000001A",
+ "-cpu 486,xlevel=0x8000001A,+3dnow,+sse4a,+invtsc,+npt,+svm",
+ "xlevel", 0x8000001A);
+ add_cpuid_test("x86/cpuid/auto-xlevel/phenom/fixed/0",
+ "-cpu 486,xlevel=0,+3dnow,+sse4a,+invtsc,+npt,+svm",
+ "xlevel", 0);
+
+ /* if xlevel2 is already large enough, it shouldn't change: */
+ add_cpuid_test("x86/cpuid/auto-xlevel2/486/fixed",
+ "-cpu 486,xlevel2=0xC0000002,+xstore",
+ "xlevel2", 0xC0000002);
+
+ /* Check compatibility of old machine-types that didn't
+ * auto-increase level/xlevel/xlevel2: */
+
+ add_cpuid_test("x86/cpuid/auto-level/pc-2.7",
+ "-machine pc-i440fx-2.7 -cpu 486,+arat,+avx512vbmi,+xsaveopt",
+ "level", 1);
+ add_cpuid_test("x86/cpuid/auto-xlevel/pc-2.7",
+ "-machine pc-i440fx-2.7 -cpu 486,+3dnow,+sse4a,+invtsc,+npt,+svm",
+ "xlevel", 0);
+ add_cpuid_test("x86/cpuid/auto-xlevel2/pc-2.7",
+ "-machine pc-i440fx-2.7 -cpu 486,+xstore",
+ "xlevel2", 0);
+
+ return g_test_run();
+}