1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-30 06:25:37 +03:00

sd-boot: don't use TSC in virtualized environments

Replaces: f699bd81e8

Fixes: #22060
This commit is contained in:
Lennart Poettering 2022-02-08 11:35:10 +01:00
parent 16cec133c6
commit 3bcc999fa5

View File

@ -2,18 +2,47 @@
#include <efi.h>
#include <efilib.h>
#if defined(__i386__) || defined(__x86_64__)
#include <cpuid.h>
#endif
#include "ticks.h"
#if defined(__i386__) || defined(__x86_64__)
static BOOLEAN in_hypervisor(void) {
uint32_t eax, ebx, ecx, edx;
/* The TSC might or might not be virtualized in VMs (and thus might not be accurate or start at zero
* at boot), depending on hypervisor and CPU functionality. If it's not virtualized it's not useful
* for keeping time, hence don't attempt to use it.
*
* This is a dumbed down version of src/basic/virt.c's detect_vm() that safely works in the UEFI
* environment. */
if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) == 0)
return FALSE;
return !!(ecx & 0x80000000U);
}
#endif
#ifdef __x86_64__
static UINT64 ticks_read(void) {
UINT64 a, d;
if (in_hypervisor())
return 0;
__asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
return (d << 32) | a;
}
#elif defined(__i386__)
static UINT64 ticks_read(void) {
UINT64 val;
if (in_hypervisor())
return 0;
__asm__ volatile ("rdtsc" : "=A" (val));
return val;
}