diff options
author | Mike Gilbert <floppymaster@gmail.com> | 2017-12-29 13:30:38 -0500 |
---|---|---|
committer | Sven Eden <yamakuzure@gmx.net> | 2018-05-30 07:49:46 +0200 |
commit | 9376a8929700bfe3d2d45a41d9e66232ca9ec9dd (patch) | |
tree | 352fb0f77f14abe54bb8cedc0531868eba2cfc83 /src/basic/virt.c | |
parent | fcd59dd68aaaa7d0c288ee70c6dfb85b20ec1236 (diff) |
basic: detect_vm_cpuid: use gcc's __get_cpuid() function (#7758)
The __get_cpuid() function includes a safety check to ensure that
executing the cpuid instruction is valid/safe.
This method also works with clang.
https://lists.freedesktop.org/archives/systemd-devel/2017-December/040054.html
Diffstat (limited to 'src/basic/virt.c')
-rw-r--r-- | src/basic/virt.c | 42 |
1 files changed, 12 insertions, 30 deletions
diff --git a/src/basic/virt.c b/src/basic/virt.c index eac5c0626..15dc860ad 100644 --- a/src/basic/virt.c +++ b/src/basic/virt.c @@ -18,6 +18,9 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#if defined(__i386__) || defined(__x86_64__) +//#include <cpuid.h> +#endif #include <errno.h> #include <stdint.h> #include <stdlib.h> @@ -57,30 +60,14 @@ static int detect_vm_cpuid(void) { { "bhyve bhyve ", VIRTUALIZATION_BHYVE }, }; - uint32_t eax, ecx; + uint32_t eax, ebx, ecx, edx; bool hypervisor; /* http://lwn.net/Articles/301888/ */ -#if defined (__i386__) -#define REG_a "eax" -#define REG_b "ebx" -#elif defined (__amd64__) -#define REG_a "rax" -#define REG_b "rbx" -#endif - /* First detect whether there is a hypervisor */ - eax = 1; - __asm__ __volatile__ ( - /* ebx/rbx is being used for PIC! */ - " push %%"REG_b" \n\t" - " cpuid \n\t" - " pop %%"REG_b" \n\t" - - : "=a" (eax), "=c" (ecx) - : "0" (eax) - ); + if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) == 0) + return VIRTUALIZATION_NONE; hypervisor = !!(ecx & 0x80000000U); @@ -92,17 +79,12 @@ static int detect_vm_cpuid(void) { unsigned j; /* There is a hypervisor, see what it is */ - eax = 0x40000000U; - __asm__ __volatile__ ( - /* ebx/rbx is being used for PIC! */ - " push %%"REG_b" \n\t" - " cpuid \n\t" - " mov %%ebx, %1 \n\t" - " pop %%"REG_b" \n\t" - - : "=a" (eax), "=r" (sig.sig32[0]), "=c" (sig.sig32[1]), "=d" (sig.sig32[2]) - : "0" (eax) - ); + if (__get_cpuid(0x40000000U, &eax, &ebx, &ecx, &edx) == 0) + return VIRTUALIZATION_NONE; + + sig.sig32[0] = ebx; + sig.sig32[1] = ecx; + sig.sig32[2] = edx; log_debug("Virtualization found, CPUID=%s", sig.text); |