From 7d32afb5ad9bfb677149718b440db7c863ee8957 Mon Sep 17 00:00:00 2001 From: ouxianfei Date: Sun, 1 Dec 2019 20:58:19 +0800 Subject: [PATCH] Fix the implementation of rdtsc in src/mevent_test.c:68 In inline assembly of xhyve/src/mevent_test.c:68, an unused inline assembly `__asm__ __volatile__ ("cpuid")` is written here. `cpuid` is a instruction which override register eax, ebx, ecx and edx by the information of cpu, (details can be found in x86_64 specification). This inline assembly is not only unuseful, under some context, this inline assembly may corrupt the normal C data flow, and cause errors in C world. For example: ``` static __inline uint64_t rdtsc(void) { unsigned a, d; __asm__ __volatile__ ("cpuid"); __asm__ __volatile__ ("rdtsc" : "=a" (a), "=d" (d)); return (((uint64_t) a) | (((uint64_t) d) << 32)); } int __attribute__((noinline)) set_val(int v) { return v; } int main() { int a = set_val(0); int b = set_val(1); int c = set_val(2); a = a + b; b = b + c; c = c + a; uint64_t d = rdtsc(); printf("%d, %d, %d, %lx\n", a, b, c, d); return 0; } ``` The above code on my pc (gcc-8 -O2) will output 1, 2, 3, 7bcbf4733e902, (assume rdtsc now is 7bcbf4733e902), but the actual output should be 1, 3, 3, 7bcbf4733e902, the reason is that cpuid override some registers unexpectedly. --- src/mevent_test.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mevent_test.c b/src/mevent_test.c index 9ab3089..89269b8 100644 --- a/src/mevent_test.c +++ b/src/mevent_test.c @@ -65,7 +65,6 @@ uint64_t tevbuf[TEVSZ]; static __inline uint64_t rdtsc(void) { unsigned a, d; - __asm__ __volatile__ ("cpuid"); __asm__ __volatile__ ("rdtsc" : "=a" (a), "=d" (d)); return (((uint64_t) a) | (((uint64_t) d) << 32));