diff --git a/include/kvm/cpufeature.h b/include/kvm/cpufeature.h index 4f566df..92abb87 100644 --- a/include/kvm/cpufeature.h +++ b/include/kvm/cpufeature.h @@ -13,6 +13,7 @@ * CPUID flags we need to deal with */ #define KVM__X86_FEATURE_VMX 5 /* Hardware virtualization */ +#define KVM__X86_FEATURE_SVM 2 /* Secure virtual machine */ #define KVM__X86_FEATURE_XSAVE 26 /* XSAVE/XRSTOR/XSETBV/XGETBV */ #define cpu_feature_disable(reg, feature) \ diff --git a/kvm.c b/kvm.c index f290f8c..4d1efaa 100644 --- a/kvm.c +++ b/kvm.c @@ -137,13 +137,35 @@ void kvm__delete(struct kvm *self) static bool kvm__cpu_supports_vm(void) { struct cpuid_regs regs; + bool ret = false; regs = (struct cpuid_regs) { - .eax = 1, + .eax = 0, }; host_cpuid(®s); - return regs.ecx & (1 << KVM__X86_FEATURE_VMX); + switch (regs.ebx) { + case CPUID_VENDOR_INTEL_1: + if (regs.eax < 1) + return false; + regs = (struct cpuid_regs) { .eax = 1 }; + host_cpuid(®s); + if (regs.ecx & (1 << KVM__X86_FEATURE_VMX)) + ret = true; + break; + case CPUID_VENDOR_AMD_1: + regs = (struct cpuid_regs) { .eax = 0x80000000 }; + host_cpuid(®s); + if (regs.eax < 0x80000001) + return false; + regs = (struct cpuid_regs) { .eax = 0x80000001 }; + host_cpuid(®s); + if (regs.ecx & (1 << KVM__X86_FEATURE_SVM)) + ret = true; + break; + } + + return ret; } struct kvm *kvm__init(const char *kvm_dev)