5 static inline unsigned long long rdtsc()
12 asm volatile ("rdtsc" : "=a"(a
), "=d"(d
));
13 r
= a
| ((long long)d
<< 32);
15 asm volatile ("rdtsc" : "=A"(r
));
20 static unsigned int inl(unsigned short port
)
23 asm volatile("inl %w1, %0" : "=a"(val
) : "Nd"(port
));
27 #define GOAL (1ull << 30)
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 #define MSR_EFER 0xc0000080
49 #define EFER_NX_MASK (1ull << 11)
51 unsigned long long rdmsr(unsigned index
)
55 asm volatile("rdmsr" : "=a"(a
), "=d"(d
) : "c"(index
));
56 return ((unsigned long long)d
<< 32) | a
;
59 void wrmsr(unsigned index
, unsigned long long val
)
61 unsigned a
= val
, d
= val
>> 32;
63 asm volatile("wrmsr" : : "a"(a
), "d"(d
), "c"(index
));
66 static void mov_from_cr8(void)
70 asm volatile ("mov %%cr8, %0" : "=r"(cr8
));
73 static void mov_to_cr8(void)
75 unsigned long cr8
= 0;
77 asm volatile ("mov %0, %%cr8" : : "r"(cr8
));
80 static int is_smp(void)
82 return cpu_count() > 1;
85 static void nop(void *junk
)
94 static void ipi_halt(void)
104 static void inl_pmtimer(void)
115 { cpuid
, "cpuid", .parallel
= 1, },
116 { vmcall
, "vmcall", .parallel
= 1, },
117 { mov_from_cr8
, "mov_from_cr8", .parallel
= 1, },
118 { mov_to_cr8
, "mov_to_cr8" , .parallel
= 1, },
119 { inl_pmtimer
, "inl_from_pmtimer", .parallel
= 1, },
120 { ipi
, "ipi", is_smp
, .parallel
= 0, },
121 { ipi_halt
, "ipi+halt", is_smp
, .parallel
= 0, },
125 volatile int nr_cpus_done
;
127 static void run_test(void *_func
)
130 void (*func
)(void) = _func
;
132 for (i
= 0; i
< iterations
; ++i
)
138 static void do_test(struct test
*test
)
141 unsigned long long t1
, t2
;
142 void (*func
)(void) = test
->func
;
146 if (test
->valid
&& !test
->valid()) {
147 printf("%s (skipped)\n", test
->name
);
155 if (!test
->parallel
) {
156 for (i
= 0; i
< iterations
; ++i
)
160 for (i
= cpu_count(); i
> 0; i
--)
161 on_cpu_async(i
-1, run_test
, func
);
162 while (nr_cpus_done
< cpu_count())
166 } while ((t2
- t1
) < GOAL
);
167 printf("%s %d\n", test
->name
, (int)((t2
- t1
) / iterations
));
170 static void enable_nx(void *junk
)
172 wrmsr(MSR_EFER
, rdmsr(MSR_EFER
) | EFER_NX_MASK
);
181 for (i
= cpu_count(); i
> 0; i
--)
182 on_cpu(i
-1, enable_nx
, 0);
184 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
)