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(a)redhat.com>
---
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