kvm: rename kvm/user to kvm/test
[qemu-kvm/amd-iommu.git] / kvm / test / x86 / vmexit.c
blobc3a01e0b5b17d7d28761e8de130a8f82ae822e65
2 #include "libcflat.h"
3 #include "smp.h"
5 static inline unsigned long long rdtsc()
7 long long r;
9 #ifdef __x86_64__
10 unsigned a, d;
12 asm volatile ("rdtsc" : "=a"(a), "=d"(d));
13 r = a | ((long long)d << 32);
14 #else
15 asm volatile ("rdtsc" : "=A"(r));
16 #endif
17 return r;
20 static unsigned int inl(unsigned short port)
22 unsigned int val;
23 asm volatile("inl %w1, %0" : "=a"(val) : "Nd"(port));
24 return val;
27 #define GOAL (1ull << 30)
29 #ifdef __x86_64__
30 # define R "r"
31 #else
32 # define R "e"
33 #endif
35 static void cpuid(void)
37 asm volatile ("push %%"R "bx; cpuid; pop %%"R "bx"
38 : : : "eax", "ecx", "edx");
41 static void vmcall(void)
43 unsigned long a = 0, b, c, d;
45 asm volatile ("vmcall" : "+a"(a), "=b"(b), "=c"(c), "=d"(d));
48 static void mov_from_cr8(void)
50 unsigned long cr8;
52 asm volatile ("mov %%cr8, %0" : "=r"(cr8));
55 static void mov_to_cr8(void)
57 unsigned long cr8 = 0;
59 asm volatile ("mov %0, %%cr8" : : "r"(cr8));
62 static int is_smp(void)
64 return cpu_count() > 1;
67 static void nop(void *junk)
71 static void ipi(void)
73 on_cpu(1, nop, 0);
76 static void ipi_halt(void)
78 unsigned long long t;
80 on_cpu(1, nop, 0);
81 t = rdtsc() + 2000;
82 while (rdtsc() < t)
86 static void inl_pmtimer(void)
88 inl(0xb008);
91 static struct test {
92 void (*func)(void);
93 const char *name;
94 int (*valid)(void);
95 int parallel;
96 } tests[] = {
97 { cpuid, "cpuid", .parallel = 1, },
98 { vmcall, "vmcall", .parallel = 1, },
99 { mov_from_cr8, "mov_from_cr8", .parallel = 1, },
100 { mov_to_cr8, "mov_to_cr8" , .parallel = 1, },
101 { inl_pmtimer, "inl_from_pmtimer", .parallel = 1, },
102 { ipi, "ipi", is_smp, .parallel = 0, },
103 { ipi_halt, "ipi+halt", is_smp, .parallel = 0, },
106 unsigned iterations;
107 volatile int nr_cpus_done;
109 static void run_test(void *_func)
111 int i;
112 void (*func)(void) = _func;
114 for (i = 0; i < iterations; ++i)
115 func();
117 nr_cpus_done++;
120 static void do_test(struct test *test)
122 int i;
123 unsigned long long t1, t2;
124 void (*func)(void) = test->func;
126 iterations = 32;
128 if (test->valid && !test->valid()) {
129 printf("%s (skipped)\n", test->name);
130 return;
133 do {
134 iterations *= 2;
135 t1 = rdtsc();
137 if (!test->parallel) {
138 for (i = 0; i < iterations; ++i)
139 func();
140 } else {
141 nr_cpus_done = 0;
142 for (i = cpu_count(); i > 0; i--)
143 on_cpu_async(i-1, run_test, func);
144 while (nr_cpus_done < cpu_count())
147 t2 = rdtsc();
148 } while ((t2 - t1) < GOAL);
149 printf("%s %d\n", test->name, (int)((t2 - t1) / iterations));
152 #define ARRAY_SIZE(_x) (sizeof(_x) / sizeof((_x)[0]))
154 int main(void)
156 int i;
158 smp_init();
160 for (i = 0; i < ARRAY_SIZE(tests); ++i)
161 do_test(&tests[i]);
163 return 0;