This enables support for nested SVM using the regular CPU model/features block. If the CPU model or features include 'svm' or 'vmx', then the '-enable-nesting' flag will be added to the QEMU command line. Several of the models already include svm support, but QEMU was just masking out the svm bit silently. So this will enable SVM on such models * src/qemu/qemu_conf.h: flag for -enable-nesting * src/qemu/qemu_conf.c: Use -enable-nesting if VMX or SVM are in the CPUID --- src/qemu/qemu_conf.c | 39 +++++++++++++++++++++++++++++++++++++-- src/qemu/qemu_conf.h | 1 + 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 7a37c70..a2aab95 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -1210,6 +1210,8 @@ static unsigned long long qemudComputeCmdFlags(const char *help, flags |= QEMUD_CMD_FLAG_NO_KVM_PIT; if (strstr(help, "-tdf")) flags |= QEMUD_CMD_FLAG_TDF; + if (strstr(help, "-enable-nesting")) + flags |= QEMUD_CMD_FLAG_NESTING; if (strstr(help, ",menu=on")) flags |= QEMUD_CMD_FLAG_BOOT_MENU; @@ -3494,13 +3496,36 @@ error: } +#define CPUID_FUNCTION_SVM 0x80000001 +#define CPUID_ECX_SVM 0x00000004 + +#define CPUID_FUNCTION_VMX 0x00000001 +#define CPUID_ECX_VMX 0x00000020 + +static bool qemuCpuHasHwVirt(union cpuData *data) +{ + int i; + for (i = 0 ; i < data->x86.basic_len ; i++) { + if (data->x86.basic[i].function == CPUID_FUNCTION_VMX && + (data->x86.basic[i].ecx & CPUID_ECX_VMX)) + return true; + } + for (i = 0 ; i < data->x86.extended_len ; i++) { + if (data->x86.extended[i].function == CPUID_FUNCTION_SVM && + (data->x86.extended[i].ecx & CPUID_ECX_SVM)) + return true; + } + return false; +} + static int qemuBuildCpuArgStr(const struct qemud_driver *driver, const virDomainDefPtr def, const char *emulator, unsigned long long qemuCmdFlags, const struct utsname *ut, - char **opt) + char **opt, + bool *hasHwVirt) { const virCPUDefPtr host = driver->caps->host.cpu; virCPUDefPtr guest = NULL; @@ -3511,6 +3536,8 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver, virBuffer buf = VIR_BUFFER_INITIALIZER; int i; + *hasHwVirt = false; + if (def->cpu && def->cpu->model) { if (qemudProbeCPUModels(emulator, qemuCmdFlags, ut->machine, &ncpus, &cpus) < 0) @@ -3552,6 +3579,8 @@ qemuBuildCpuArgStr(const struct qemud_driver *driver, if (cpuDecode(guest, data, cpus, ncpus, preferred) < 0) goto cleanup; + *hasHwVirt = qemuCpuHasHwVirt(data); + virBufferVSprintf(&buf, "%s", guest->model); for (i = 0; i < guest->nfeatures; i++) { char sign; @@ -3678,6 +3707,7 @@ int qemudBuildCommandLine(virConnectPtr conn, char *cpu; char *smp; int last_good_net = -1; + bool hasHwVirt = false; uname_normalize(&ut); @@ -3871,13 +3901,18 @@ int qemudBuildCommandLine(virConnectPtr conn, ADD_ARG_LIT(def->os.machine); } - if (qemuBuildCpuArgStr(driver, def, emulator, qemuCmdFlags, &ut, &cpu) < 0) + if (qemuBuildCpuArgStr(driver, def, emulator, qemuCmdFlags, + &ut, &cpu, &hasHwVirt) < 0) goto error; if (cpu) { ADD_ARG_LIT("-cpu"); ADD_ARG_LIT(cpu); VIR_FREE(cpu); + + if ((qemuCmdFlags & QEMUD_CMD_FLAG_NESTING) && + hasHwVirt) + ADD_ARG_LIT("-enable-nesting"); } if (disableKQEMU) diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 2c9e608..16f72f5 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -93,6 +93,7 @@ enum qemud_cmd_flags { QEMUD_CMD_FLAG_NODEFCONFIG = (1LL << 37), /* -nodefconfig */ QEMUD_CMD_FLAG_BOOT_MENU = (1LL << 38), /* -boot menu=on support */ QEMUD_CMD_FLAG_ENABLE_KQEMU = (1LL << 39), /* -enable-kqemu flag */ + QEMUD_CMD_FLAG_NESTING = (1LL << 40), /* -enable-nesting (SVM/VMX) */ }; /* Main driver state */ -- 1.7.2.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list