1
0
mirror of https://github.com/systemd/systemd.git synced 2024-11-07 01:27:11 +03:00

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
This commit is contained in:
Mike Gilbert 2017-12-29 13:30:38 -05:00 committed by Lennart Poettering
parent 3a4f3e423d
commit d31b0033b7

View File

@ -18,6 +18,9 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>. 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 <errno.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
@ -56,30 +59,14 @@ static int detect_vm_cpuid(void) {
{ "bhyve bhyve ", VIRTUALIZATION_BHYVE }, { "bhyve bhyve ", VIRTUALIZATION_BHYVE },
}; };
uint32_t eax, ecx; uint32_t eax, ebx, ecx, edx;
bool hypervisor; bool hypervisor;
/* http://lwn.net/Articles/301888/ */ /* 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 */ /* First detect whether there is a hypervisor */
eax = 1; if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) == 0)
__asm__ __volatile__ ( return VIRTUALIZATION_NONE;
/* 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)
);
hypervisor = !!(ecx & 0x80000000U); hypervisor = !!(ecx & 0x80000000U);
@ -91,17 +78,12 @@ static int detect_vm_cpuid(void) {
unsigned j; unsigned j;
/* There is a hypervisor, see what it is */ /* There is a hypervisor, see what it is */
eax = 0x40000000U; if (__get_cpuid(0x40000000U, &eax, &ebx, &ecx, &edx) == 0)
__asm__ __volatile__ ( return VIRTUALIZATION_NONE;
/* 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]) sig.sig32[0] = ebx;
: "0" (eax) sig.sig32[1] = ecx;
); sig.sig32[2] = edx;
log_debug("Virtualization found, CPUID=%s", sig.text); log_debug("Virtualization found, CPUID=%s", sig.text);