Commit 5a8ce1ae authored by Jade Auer's avatar Jade Auer Committed by Joffrey F

use CPUID instead of shelling out for VT-d detection

Signed-off-by: default avatarJade Auer <[email protected]>
parent ff19455b
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()
}
......
......@@ -6,11 +6,6 @@ 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()
......@@ -18,8 +13,3 @@ func TestShareName(t *testing.T) {
assert.Equal(t, dir, "/Users")
}
func TestIsVTXEnabled(t *testing.T) {
assert.False(t, isVTXDisabled(featuresWithVMX))
assert.True(t, isVTXDisabled(featuresNoVMX))
}
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()
}
......
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()
}
......
......@@ -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)))
}
package virtualbox
func (d *Driver) IsVTXDisabled() bool {
return false
}
func detectVBoxManageCmd() string {
return detectVBoxManageCmdInPath()
}
......
......@@ -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...)
......
// +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
}
// +build !386,!amd64
package virtualbox
// IsVTXDisabled checks if VT-x is disabled in the CPU.
func (d *Driver) IsVTXDisabled() bool {
return true
}
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
Copyright (c) 2015, Intel Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
This diff is collapsed.
This diff is collapsed.
// Copyright 2017 Intel Corporation.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "textflag.h"
// func cpuid_low(arg1, arg2 uint32) (eax, ebx, ecx, edx uint32)
TEXT ·cpuid_low(SB),NOSPLIT,$0-24
MOVL arg1+0(FP), AX
MOVL arg2+4(FP), CX
CPUID
MOVL AX, eax+8(FP)
MOVL BX, ebx+12(FP)
MOVL CX, ecx+16(FP)
MOVL DX, edx+20(FP)
RET
// func xgetbv_low(arg1 uint32) (eax, edx uint32)
TEXT ·xgetbv_low(SB),NOSPLIT,$0-16
MOVL arg1+0(FP), CX
BYTE $0x0F
BYTE $0x01
BYTE $0xD0
MOVL AX,eax+8(FP)
MOVL DX,edx+12(FP)
RET
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment