Skip to content
This repository has been archived by the owner on Sep 26, 2021. It is now read-only.

Commit

Permalink
use CPUID instead of shelling out for VT-d detection
Browse files Browse the repository at this point in the history
Signed-off-by: Jade Auer <jda@tapodi.net>
  • Loading branch information
jda authored and shin- committed Jan 8, 2019
1 parent ff19455 commit 5a8ce1a
Show file tree
Hide file tree
Showing 14 changed files with 1,468 additions and 215 deletions.
22 changes: 0 additions & 22 deletions drivers/virtualbox/virtualbox_darwin.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,5 @@
package virtualbox

import (
"strings"
"syscall"

"github.com/docker/machine/libmachine/log"
)

// IsVTXDisabled checks if VT-X is disabled in the BIOS. If it is, the vm will fail to start.
// If we can't be sure it is disabled, we carry on and will check the vm logs after it's started.
func (d *Driver) IsVTXDisabled() bool {
features, err := syscall.Sysctl("machdep.cpu.features")
if err != nil {
log.Debugf("Couldn't check that VT-X/AMD-v is enabled. Will check that the vm is properly created: %v", err)
return false
}
return isVTXDisabled(features)
}

func isVTXDisabled(features string) bool {
return !strings.Contains(features, "VMX")
}

func detectVBoxManageCmd() string {
return detectVBoxManageCmdInPath()
}
Expand Down
10 changes: 0 additions & 10 deletions drivers/virtualbox/virtualbox_darwin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,10 @@ import (
"github.com/stretchr/testify/assert"
)

const (
featuresWithVMX = "FPU VME DE PSE TSC MSR PAE MCE CX8 APIC SEP MTRR PGE MCA CMOV PAT PSE36 VMX PBE SSE3 PCLMULQDQ DTES64 AVX1.0 RDRAND F16C"
featuresNoVMX = "FPU VME DE PSE TSC MSR PAE MCE CX8 APIC SEP MTRR PGE MCA CMOV PAT PSE36 PBE SSE3 PCLMULQDQ DTES64 AVX1.0 RDRAND F16C"
)

func TestShareName(t *testing.T) {
name, dir := getShareDriveAndName()

assert.Equal(t, name, "Users")
assert.Equal(t, dir, "/Users")

}

func TestIsVTXEnabled(t *testing.T) {
assert.False(t, isVTXDisabled(featuresWithVMX))
assert.True(t, isVTXDisabled(featuresNoVMX))
}
32 changes: 0 additions & 32 deletions drivers/virtualbox/virtualbox_freebsd.go
Original file line number Diff line number Diff line change
@@ -1,37 +1,5 @@
package virtualbox

import (
"bytes"
"io/ioutil"

"github.com/docker/machine/libmachine/log"
)

// IsVTXDisabled checks if VT-X is disabled in the BIOS. If it is, the vm will fail to start.
// If we can't be sure it is disabled, we carry on and will check the vm logs after it's started.
// We want to check that either vmx or svm flags are present in /proc/cpuinfo.
func (d *Driver) IsVTXDisabled() bool {
cpuinfo, err := ioutil.ReadFile("/proc/cpuinfo")
if err != nil {
log.Debugf("Couldn't check that VT-X/AMD-v is enabled. Will check that the vm is properly created: %v", err)
return false
}
return isVTXDisabled(cpuinfo)
}

func isVTXDisabled(cpuinfo []byte) bool {
features := [2][]byte{
{'v', 'm', 'x'},
{'s', 'v', 'm'},
}
for _, v := range features {
if bytes.Contains(cpuinfo, v) {
return false
}
}
return true
}

func detectVBoxManageCmd() string {
return detectVBoxManageCmdInPath()
}
Expand Down
32 changes: 0 additions & 32 deletions drivers/virtualbox/virtualbox_linux.go
Original file line number Diff line number Diff line change
@@ -1,37 +1,5 @@
package virtualbox

import (
"bytes"
"io/ioutil"

"github.com/docker/machine/libmachine/log"
)

// IsVTXDisabled checks if VT-X is disabled in the BIOS. If it is, the vm will fail to start.
// If we can't be sure it is disabled, we carry on and will check the vm logs after it's started.
// We want to check that either vmx or svm flags are present in /proc/cpuinfo.
func (d *Driver) IsVTXDisabled() bool {
cpuinfo, err := ioutil.ReadFile("/proc/cpuinfo")
if err != nil {
log.Debugf("Couldn't check that VT-X/AMD-v is enabled. Will check that the vm is properly created: %v", err)
return false
}
return isVTXDisabled(cpuinfo)
}

func isVTXDisabled(cpuinfo []byte) bool {
features := [2][]byte{
{'v', 'm', 'x'},
{'s', 'v', 'm'},
}
for _, v := range features {
if bytes.Contains(cpuinfo, v) {
return false
}
}
return true
}

func detectVBoxManageCmd() string {
return detectVBoxManageCmdInPath()
}
Expand Down
101 changes: 0 additions & 101 deletions drivers/virtualbox/virtualbox_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,110 +6,9 @@ import (
"github.com/stretchr/testify/assert"
)

const (
amdCPUInfo = `
processor : 0
vendor_id : AuthenticAMD
cpu family : 20
model : 1
model name : AMD C-50 Processor
stepping : 0
microcode : 0x5000026
cpu MHz : 800.000
cache size : 512 KB
physical id : 0
siblings : 2
core id : 0
cpu cores : 2
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 6
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl nonstop_tsc extd_apicid aperfmperf pni monitor ssse3 cx16 popcnt lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch ibs skinit wdt arat hw_pstate npt lbrv svm_lock nrip_save pausefilter vmmcall
bugs : fxsave_leak sysret_ss_attrs
bogomips : 1995.09
TLB size : 1024 4K pages
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management: ts ttp tm stc 100mhzsteps hwpstate
`
intelCPUInfo = `
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 70
model name : Intel(R) Core(TM) i7-4850HQ CPU @ 2.30GHz
stepping : 1
microcode : 0x19
cpu MHz : 2294.688
cache size : 6144 KB
physical id : 0
siblings : 1
core id : 0
cpu cores : 1
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr vmx pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc pni pclmulqdq monitor ssse3 cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx rdrand hypervisor lahf_lm abm
bugs :
bogomips : 4589.37
clflush size : 64
cache_alignment : 64
address sizes : 39 bits physical, 48 bits virtual
power management:
`

faultyCPUInfo = `
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 70
model name : Intel(R) Core(TM) i7-4850HQ CPU @ 2.30GHz
stepping : 1
microcode : 0x19
cpu MHz : 2294.688
cache size : 6144 KB
physical id : 0
siblings : 1
core id : 0
cpu cores : 1
apicid : 0
initial apicid : 0
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc pni pclmulqdq monitor ssse3 cx16 sse4_1 sse4_2 movbe popcnt aes xsave avx rdrand hypervisor lahf_lm abm
bugs :
bogomips : 4589.37
clflush size : 64
cache_alignment : 64
address sizes : 39 bits physical, 48 bits virtual
power management:
`
)

func TestShareName(t *testing.T) {
name, dir := getShareDriveAndName()

assert.Equal(t, name, "hosthome")
assert.Equal(t, dir, "/home")
}

func TestCpuInfoOnAMD(t *testing.T) {
assert.False(t, isVTXDisabled([]byte(amdCPUInfo)))
}

func TestCpuInfoOnIntel(t *testing.T) {
assert.False(t, isVTXDisabled([]byte(intelCPUInfo)))
}

func TestCpuInfoOnNone(t *testing.T) {
assert.True(t, isVTXDisabled([]byte(faultyCPUInfo)))
}
4 changes: 0 additions & 4 deletions drivers/virtualbox/virtualbox_openbsd.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
package virtualbox

func (d *Driver) IsVTXDisabled() bool {
return false
}

func detectVBoxManageCmd() string {
return detectVBoxManageCmdInPath()
}
Expand Down
14 changes: 0 additions & 14 deletions drivers/virtualbox/virtualbox_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,6 @@ import (
"golang.org/x/sys/windows/registry"
)

// IsVTXDisabled checks if VT-X is disabled in the BIOS. If it is, the vm will fail to start.
// If we can't be sure it is disabled, we carry on and will check the vm logs after it's started.
func (d *Driver) IsVTXDisabled() bool {
errmsg := "Couldn't check that VT-X/AMD-v is enabled. Will check that the vm is properly created: %v"
output, err := cmdOutput("wmic", "cpu", "get", "VirtualizationFirmwareEnabled")
if err != nil {
log.Debugf(errmsg, err)
return false
}

disabled := strings.Contains(output, "FALSE")
return disabled
}

// cmdOutput runs a shell command and returns its output.
func cmdOutput(name string, args ...string) (string, error) {
cmd := exec.Command(name, args...)
Expand Down
14 changes: 14 additions & 0 deletions drivers/virtualbox/vtx_intel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// +build 386 amd64

package virtualbox

import "github.com/intel-go/cpuid"

// IsVTXDisabled checks if VT-x is disabled in the CPU.
func (d *Driver) IsVTXDisabled() bool {
if cpuid.HasFeature(cpuid.VMX) || cpuid.HasFeature(cpuid.SVM) {
return false
}

return true
}
8 changes: 8 additions & 0 deletions drivers/virtualbox/vtx_other.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// +build !386,!amd64

package virtualbox

// IsVTXDisabled checks if VT-x is disabled in the CPU.
func (d *Driver) IsVTXDisabled() bool {
return true
}
28 changes: 28 additions & 0 deletions vendor/github.com/intel-go/cpuid/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions vendor/github.com/intel-go/cpuid/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 5a8ce1a

Please sign in to comment.