* @arch: CPU architecture
* @guest: guest CPU definition to be updated
* @host: host CPU definition
+ * @removedPolicy: default policy for features removed from the CPU model
*
* Updates @guest CPU definition possibly taking @host CPU into account. This
* is required for maintaining compatibility with older libvirt releases or to
* support guest CPU definitions specified relatively to host CPU, such as CPUs
* with VIR_CPU_MODE_CUSTOM and optional features or VIR_CPU_MATCH_MINIMUM, or
- * CPUs with VIR_CPU_MODE_HOST_MODEL.
+ * CPUs with VIR_CPU_MODE_HOST_MODEL. If @guest CPU uses a CPU model which
+ * specifies some features as removed, such features that were not already
+ * present in the @guest CPU definition will be added there with @removedPolicy.
*
* Returns 0 on success, -1 on error.
*/
int
virCPUUpdate(virArch arch,
virCPUDef *guest,
- const virCPUDef *host)
+ const virCPUDef *host,
+ virCPUFeaturePolicy removedPolicy)
{
struct cpuArchDriver *driver;
bool relative;
return -1;
}
- if (driver->update(guest, host, relative) < 0)
+ if (driver->update(guest, host, relative, removedPolicy) < 0)
return -1;
VIR_DEBUG("model=%s", NULLSTR(guest->model));
typedef int
(*virCPUArchUpdate)(virCPUDef *guest,
const virCPUDef *host,
- bool relative);
+ bool relative,
+ virCPUFeaturePolicy removedPolicy);
typedef int
(*virCPUArchUpdateLive)(virCPUDef *cpu,
int
virCPUUpdate(virArch arch,
virCPUDef *guest,
- const virCPUDef *host)
+ const virCPUDef *host,
+ virCPUFeaturePolicy removedPolicy)
ATTRIBUTE_NONNULL(2);
int
static int
virCPUarmUpdate(virCPUDef *guest,
const virCPUDef *host,
- bool relative)
+ bool relative,
+ virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED)
{
g_autoptr(virCPUDef) updated = virCPUDefCopyWithoutModel(guest);
static int
virCPULoongArchUpdate(virCPUDef *guest G_GNUC_UNUSED,
const virCPUDef *host G_GNUC_UNUSED,
- bool relative G_GNUC_UNUSED)
+ bool relative G_GNUC_UNUSED,
+ virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED)
{
return 0;
}
static int
virCPUppc64Update(virCPUDef *guest,
const virCPUDef *host G_GNUC_UNUSED,
- bool relative G_GNUC_UNUSED)
+ bool relative G_GNUC_UNUSED,
+ virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED)
{
/*
* - host-passthrough doesn't even get here
static int
virCPURiscv64Update(virCPUDef *guest,
const virCPUDef *host,
- bool relative)
+ bool relative,
+ virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED)
{
g_autoptr(virCPUDef) updated = virCPUDefCopyWithoutModel(guest);
static int
virCPUs390Update(virCPUDef *guest,
const virCPUDef *host,
- bool relative)
+ bool relative,
+ virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED)
{
g_autoptr(virCPUDef) updated = virCPUDefCopyWithoutModel(guest);
size_t i;
}
+/*
+ * Adds features removed from the CPU @model to @cpu with a specified @policy
+ * unless the features were already explicitly mentioned in @cpu.
+ */
+static void
+virCPUx86AddRemovedFeatures(virCPUDef *cpu,
+ virCPUx86Model *model,
+ virCPUFeaturePolicy policy)
+{
+ char **feat;
+
+ for (feat = model->removedFeatures; feat && *feat; feat++)
+ virCPUDefAddFeatureIfMissing(cpu, *feat, policy);
+}
+
+
/*
* Disables features removed from the CPU @model unless they are already
* mentioned in @cpu to make sure these features will always be explicitly
virCPUx86DisableRemovedFeatures(virCPUDef *cpu,
virCPUx86Model *model)
{
- char **feat = model->removedFeatures;
-
- if (!feat)
- return;
-
- while (*feat) {
- virCPUDefAddFeatureIfMissing(cpu, *feat, VIR_CPU_FEATURE_DISABLE);
- feat++;
- }
+ virCPUx86AddRemovedFeatures(cpu, model, VIR_CPU_FEATURE_DISABLE);
}
static int
virCPUx86Update(virCPUDef *guest,
const virCPUDef *host,
- bool relative)
+ bool relative,
+ virCPUFeaturePolicy removedPolicy)
{
g_autoptr(virCPUx86Model) model = NULL;
virCPUx86Model *guestModel;
return -1;
}
- virCPUx86DisableRemovedFeatures(guest, guestModel);
+ virCPUx86AddRemovedFeatures(guest, guestModel, removedPolicy);
return 0;
}
if (virCPUUpdate(def->os.arch, def->cpu,
virQEMUCapsGetHostModel(qCaps, def->virtType,
- VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE)) < 0)
+ VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE),
+ VIR_CPU_FEATURE_DISABLE) < 0)
return -1;
}
if (virCPUUpdate(def->os.arch, def->cpu,
virQEMUCapsGetHostModel(qemuCaps, def->virtType,
- VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE)) < 0)
+ VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE),
+ VIR_CPU_FEATURE_DISABLE) < 0)
return -1;
cpuModels = virQEMUCapsGetCPUModels(qemuCaps, def->virtType, NULL, NULL);
virCPUDefCopyModelFilter(cpu, hostmig, false, virQEMUCapsCPUFilterFeatures,
&host->arch);
- if (virCPUUpdate(vm->def->os.arch, vm->def->cpu, cpu) < 0)
+ if (virCPUUpdate(vm->def->os.arch, vm->def->cpu, cpu,
+ VIR_CPU_FEATURE_DISABLE) < 0)
return -1;
if (qemuProcessUpdateCPU(vm, VIR_ASYNC_JOB_NONE) < 0)
goto cleanup;
}
- if (virCPUUpdate(host->arch, cpu, host) < 0 ||
+ if (virCPUUpdate(host->arch, cpu, host, VIR_CPU_FEATURE_DISABLE) < 0 ||
virCPUTranslate(host->arch, cpu, data->models) < 0) {
ret = -1;
goto cleanup;
if (!(migHost = virCPUCopyMigratable(data->arch, host)))
return -1;
- if (virCPUUpdate(host->arch, cpu, migHost) < 0)
+ if (virCPUUpdate(host->arch, cpu, migHost, VIR_CPU_FEATURE_DISABLE) < 0)
return -1;
result = g_strdup_printf("%s+%s", data->host, data->name);