mirror of
https://github.com/systemd/systemd.git
synced 2024-11-06 16:59:03 +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:
parent
3a4f3e423d
commit
d31b0033b7
@ -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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user