summaryrefslogtreecommitdiff
path: root/src/basic/virt.c
diff options
context:
space:
mode:
authorMike Gilbert <floppymaster@gmail.com>2017-12-29 13:30:38 -0500
committerSven Eden <yamakuzure@gmx.net>2018-05-30 07:49:46 +0200
commit9376a8929700bfe3d2d45a41d9e66232ca9ec9dd (patch)
tree352fb0f77f14abe54bb8cedc0531868eba2cfc83 /src/basic/virt.c
parentfcd59dd68aaaa7d0c288ee70c6dfb85b20ec1236 (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.c42
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);