The function is renamed to virCPUDataCheckFeature and another function (virCPUCheckFeature) which works on CPU definition rather than raw CPU data is introduced. Signed-off-by: Jiri Denemark <jdenemar@xxxxxxxxxx> --- src/cpu/cpu.c | 55 ++++++++++++++++++++++++++++++++++++------- src/cpu/cpu.h | 23 ++++++++++++++---- src/cpu/cpu_arm.c | 1 - src/cpu/cpu_ppc64.c | 1 - src/cpu/cpu_s390.c | 1 - src/cpu/cpu_x86.c | 30 ++++++++++++++++++++--- src/libvirt_private.syms | 3 ++- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_domain.c | 7 ++++-- src/qemu/qemu_parse_command.c | 2 +- src/qemu/qemu_process.c | 10 ++++---- src/vmware/vmware_conf.c | 6 ++--- tests/cputest.c | 6 ++++- 13 files changed, 113 insertions(+), 34 deletions(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index e215304..d6b0372 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -648,9 +648,45 @@ virCPUUpdate(virArch arch, /** - * cpuHasFeature: + * virCPUCheckFeature: * - * @data: internal CPU representation + * @arch: CPU architecture + * @cpu: CPU definition + * @feature: feature to be checked for + * + * Checks whether @feature is supported by the CPU described by @cpu. + * + * Returns 1 if the feature is supported, 0 if it's not supported, or + * -1 on error. + */ +int +virCPUCheckFeature(virArch arch, + const virCPUDef *cpu, + const char *feature) +{ + struct cpuArchDriver *driver; + + VIR_DEBUG("arch=%s, cpu=%p, feature=%s", + virArchToString(arch), cpu, feature); + + if (!(driver = cpuGetSubDriver(arch))) + return -1; + + if (!driver->checkFeature) { + virReportError(VIR_ERR_NO_SUPPORT, + _("cannot check guest CPU feature for %s architecture"), + virArchToString(arch)); + return -1; + } + + return driver->checkFeature(cpu, feature); +} + + +/** + * virCPUDataCheckFeature: + * + * @data: CPU data * @feature: feature to be checked for * * Checks whether @feature is supported by the CPU described by @data. @@ -659,24 +695,25 @@ virCPUUpdate(virArch arch, * -1 on error. */ int -cpuHasFeature(const virCPUData *data, - const char *feature) +virCPUDataCheckFeature(const virCPUData *data, + const char *feature) { struct cpuArchDriver *driver; - VIR_DEBUG("data=%p, feature=%s", data, feature); + VIR_DEBUG("arch=%s, data=%p, feature=%s", + virArchToString(data->arch), data, feature); - if ((driver = cpuGetSubDriver(data->arch)) == NULL) + if (!(driver = cpuGetSubDriver(data->arch))) return -1; - if (driver->hasFeature == NULL) { + if (!driver->dataCheckFeature) { virReportError(VIR_ERR_NO_SUPPORT, - _("cannot check guest CPU data for %s architecture"), + _("cannot check guest CPU feature for %s architecture"), virArchToString(data->arch)); return -1; } - return driver->hasFeature(data, feature); + return driver->dataCheckFeature(data, feature); } diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index b8036b2..77ccb38 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -91,8 +91,12 @@ typedef int const virCPUDef *host); typedef int -(*cpuArchHasFeature) (const virCPUData *data, - const char *feature); +(*virCPUArchCheckFeature)(const virCPUDef *cpu, + const char *feature); + +typedef int +(*virCPUArchDataCheckFeature)(const virCPUData *data, + const char *feature); typedef char * (*cpuArchDataFormat)(const virCPUData *data); @@ -120,7 +124,8 @@ struct cpuArchDriver { cpuArchGuestData guestData; cpuArchBaseline baseline; virCPUArchUpdate update; - cpuArchHasFeature hasFeature; + virCPUArchCheckFeature checkFeature; + virCPUArchDataCheckFeature dataCheckFeature; cpuArchDataFormat dataFormat; cpuArchDataParse dataParse; cpuArchGetModels getModels; @@ -193,9 +198,17 @@ virCPUUpdate(virArch arch, const virCPUDef *host) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); + int -cpuHasFeature(const virCPUData *data, - const char *feature) +virCPUCheckFeature(virArch arch, + const virCPUDef *cpu, + const char *feature) + ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); + + +int +virCPUDataCheckFeature(const virCPUData *data, + const char *feature) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); diff --git a/src/cpu/cpu_arm.c b/src/cpu/cpu_arm.c index 49da36e..3b68d83 100644 --- a/src/cpu/cpu_arm.c +++ b/src/cpu/cpu_arm.c @@ -131,5 +131,4 @@ struct cpuArchDriver cpuDriverArm = { .guestData = armGuestData, .baseline = armBaseline, .update = virCPUarmUpdate, - .hasFeature = NULL, }; diff --git a/src/cpu/cpu_ppc64.c b/src/cpu/cpu_ppc64.c index 00faa22..6f005e5 100644 --- a/src/cpu/cpu_ppc64.c +++ b/src/cpu/cpu_ppc64.c @@ -910,6 +910,5 @@ struct cpuArchDriver cpuDriverPPC64 = { .guestData = ppc64DriverGuestData, .baseline = ppc64DriverBaseline, .update = virCPUppc64Update, - .hasFeature = NULL, .getModels = ppc64DriverGetModels, }; diff --git a/src/cpu/cpu_s390.c b/src/cpu/cpu_s390.c index 23a7f9d..fb352a0 100644 --- a/src/cpu/cpu_s390.c +++ b/src/cpu/cpu_s390.c @@ -83,5 +83,4 @@ struct cpuArchDriver cpuDriverS390 = { .guestData = NULL, .baseline = NULL, .update = NULL, - .hasFeature = NULL, }; diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c index 69b081d..782c917 100644 --- a/src/cpu/cpu_x86.c +++ b/src/cpu/cpu_x86.c @@ -2601,8 +2601,30 @@ virCPUx86Update(virCPUDefPtr guest, static int -x86HasFeature(const virCPUData *data, - const char *name) +virCPUx86CheckFeature(const virCPUDef *cpu, + const char *name) +{ + int ret = -1; + virCPUx86MapPtr map; + virCPUx86ModelPtr model = NULL; + + if (!(map = virCPUx86GetMap())) + return -1; + + if (!(model = x86ModelFromCPU(cpu, map, -1))) + goto cleanup; + + ret = x86FeatureInData(name, &model->data, map); + + cleanup: + x86ModelFree(model); + return ret; +} + + +static int +virCPUx86DataCheckFeature(const virCPUData *data, + const char *name) { virCPUx86MapPtr map; @@ -2612,6 +2634,7 @@ x86HasFeature(const virCPUData *data, return x86FeatureInData(name, &data->data.x86, map); } + static int x86GetModels(char ***models) { @@ -2708,7 +2731,8 @@ struct cpuArchDriver cpuDriverX86 = { .guestData = x86GuestData, .baseline = x86Baseline, .update = virCPUx86Update, - .hasFeature = x86HasFeature, + .checkFeature = virCPUx86CheckFeature, + .dataCheckFeature = virCPUx86DataCheckFeature, .dataFormat = x86CPUDataFormat, .dataParse = x86CPUDataParse, .getModels = x86GetModels, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 1f50499..15aac81 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -969,8 +969,9 @@ cpuDecode; cpuEncode; cpuGetModels; cpuGuestData; -cpuHasFeature; cpuNodeData; +virCPUCheckFeature; +virCPUDataCheckFeature; virCPUTranslate; virCPUUpdate; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index ce04c76..985b628 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6473,7 +6473,7 @@ qemuBuildCpuModelArgStr(virQEMUDriverPtr driver, */ if ((def->os.arch == VIR_ARCH_X86_64 || def->os.arch == VIR_ARCH_I686) && compareAgainstHost) { - int hasSVM = cpuHasFeature(data, "svm"); + int hasSVM = virCPUDataCheckFeature(data, "svm"); if (hasSVM < 0) goto cleanup; *hasHwVirt = hasSVM > 0 ? true : false; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index d8c589e..decbdd0 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -3402,10 +3402,13 @@ char *qemuDomainFormatXML(virQEMUDriverPtr driver, { virDomainDefPtr def; - if ((flags & VIR_DOMAIN_XML_INACTIVE) && vm->newDef) + if ((flags & VIR_DOMAIN_XML_INACTIVE) && vm->newDef) { def = vm->newDef; - else + } else { def = vm->def; + if (virDomainObjIsActive(vm)) + flags &= ~VIR_DOMAIN_XML_UPDATE_CPU; + } return qemuDomainDefFormatXML(driver, def, flags); } diff --git a/src/qemu/qemu_parse_command.c b/src/qemu/qemu_parse_command.c index 82d1621..e3a6a34 100644 --- a/src/qemu/qemu_parse_command.c +++ b/src/qemu/qemu_parse_command.c @@ -1605,7 +1605,7 @@ qemuParseCommandLineCPU(virDomainDefPtr dom, NULL, NULL, NULL, NULL) < 0) goto cleanup; - is_32bit = (cpuHasFeature(cpuData, "lm") != 1); + is_32bit = (virCPUDataCheckFeature(cpuData, "lm") != 1); cpuDataFree(cpuData); } else if (model) { is_32bit = STREQ(model, "qemu32"); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 662a46a..d4269db 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3694,7 +3694,7 @@ qemuProcessVerifyGuestCPU(virQEMUDriverPtr driver, } if (def->features[VIR_DOMAIN_FEATURE_PVSPINLOCK] == VIR_TRISTATE_SWITCH_ON) { - if (!cpuHasFeature(guestcpu, VIR_CPU_x86_KVM_PV_UNHALT)) { + if (!virCPUDataCheckFeature(guestcpu, VIR_CPU_x86_KVM_PV_UNHALT)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("host doesn't support paravirtual spinlocks")); goto cleanup; @@ -3707,7 +3707,7 @@ qemuProcessVerifyGuestCPU(virQEMUDriverPtr driver, if (virAsprintf(&cpuFeature, "__kvm_hv_%s", virDomainHypervTypeToString(i)) < 0) goto cleanup; - if (!cpuHasFeature(guestcpu, cpuFeature)) { + if (!virCPUDataCheckFeature(guestcpu, cpuFeature)) { switch ((virDomainHyperv) i) { case VIR_DOMAIN_HYPERV_RELAXED: case VIR_DOMAIN_HYPERV_VAPIC: @@ -3743,7 +3743,7 @@ qemuProcessVerifyGuestCPU(virQEMUDriverPtr driver, continue; if (STREQ(feature->name, "invtsc") && - !cpuHasFeature(guestcpu, feature->name)) { + !virCPUDataCheckFeature(guestcpu, feature->name)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("host doesn't support invariant TSC")); goto cleanup; @@ -4448,8 +4448,8 @@ qemuProcessStartValidateGuestCPU(virDomainObjPtr vm, case VIR_CPU_COMPARE_INCOMPATIBLE: if (cpuEncode(host->arch, host, NULL, &hostData, NULL, NULL, NULL, NULL) == 0 && - (!cpuHasFeature(hostData, "hle") || - !cpuHasFeature(hostData, "rtm")) && + (!virCPUDataCheckFeature(hostData, "hle") || + !virCPUDataCheckFeature(hostData, "rtm")) && (STREQ_NULLABLE(cpu->model, "Haswell") || STREQ_NULLABLE(cpu->model, "Broadwell"))) noTSX = true; diff --git a/src/vmware/vmware_conf.c b/src/vmware/vmware_conf.c index 8736976..4222f4e 100644 --- a/src/vmware/vmware_conf.c +++ b/src/vmware/vmware_conf.c @@ -100,9 +100,9 @@ vmwareCapsInit(void) * - Host CPU is x86_64 with virtualization extensions */ if (caps->host.arch == VIR_ARCH_X86_64 || - (cpuHasFeature(data, "lm") && - (cpuHasFeature(data, "vmx") || - cpuHasFeature(data, "svm")))) { + (virCPUDataCheckFeature(data, "lm") && + (virCPUDataCheckFeature(data, "vmx") || + virCPUDataCheckFeature(data, "svm")))) { if ((guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, diff --git a/tests/cputest.c b/tests/cputest.c index e6696e9..72f00b6 100644 --- a/tests/cputest.c +++ b/tests/cputest.c @@ -430,7 +430,11 @@ cpuTestHasFeature(const void *arg) NULL, NULL, NULL, NULL) < 0) goto cleanup; - result = cpuHasFeature(hostData, data->name); + result = virCPUCheckFeature(host->arch, host, data->name); + + if (data->result == result) + result = virCPUDataCheckFeature(hostData, data->name); + if (data->result == -1) virResetLastError(); -- 2.9.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list