Imagine a simple CPU timing check that is used for VM detection.
static inline unsigned long long rdtsc_diff_vmexit() {
unsigned long long ret, ret2;
unsigned eax, edx;
__asm__ volatile("rdtsc" : "=a" (eax), "=d" (edx));
ret = ((unsigned long long)eax) | (((unsigned long long)edx) << 32);
/* vm exit forced here. it uses: eax = 0; cpuid; */
__asm__ volatile("cpuid" : /* no output */ : "a"(0x00));
/**/
__asm__ volatile("rdtsc" : "=a" (eax), "=d" (edx));
ret2 = ((unsigned long long)eax) | (((unsigned long long)edx) << 32);
return ret2 - ret;
}
On a real hardware, cpuid will take significantly less time then when running in KVM.
I was playing with rdtsc offsetting and I was thinking if it is possible to just not exit on CPUID? I have tried disabling the exit and unsurprisingly the VM did not boot (UEFI firmware did not show up at all, no serial output).
I was trying to figure out why it is happening. The only thing that I can think about that could potentially cause issues is reporting of CPU cores/threads.
So the question is: Is it even possible? If not, why? If yes, are there any resources I can use to get it working?