cpu: Add removedPolicy parameter to virCPUUpdate

virCPUUpdate check the CPU definition for features that were marked as
removed in the specified CPU model and explicitly adds those that were
not mentioned in the definition. So far such features were added with
VIR_CPU_FEATURE_DISABLE policy, but the caller may want to use a
different policy in some situations, which is now possible via the
removedPolicy parameter.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
Jiri Denemark 2024-04-26 09:57:31 +02:00
parent 8c1b07b088
commit 30458c6071
11 changed files with 49 additions and 26 deletions

View File

@ -560,19 +560,23 @@ virCPUBaseline(virArch arch,
* @arch: CPU architecture * @arch: CPU architecture
* @guest: guest CPU definition to be updated * @guest: guest CPU definition to be updated
* @host: host CPU definition * @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 * Updates @guest CPU definition possibly taking @host CPU into account. This
* is required for maintaining compatibility with older libvirt releases or to * is required for maintaining compatibility with older libvirt releases or to
* support guest CPU definitions specified relatively to host CPU, such as CPUs * 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 * 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. * Returns 0 on success, -1 on error.
*/ */
int int
virCPUUpdate(virArch arch, virCPUUpdate(virArch arch,
virCPUDef *guest, virCPUDef *guest,
const virCPUDef *host) const virCPUDef *host,
virCPUFeaturePolicy removedPolicy)
{ {
struct cpuArchDriver *driver; struct cpuArchDriver *driver;
bool relative; bool relative;
@ -622,7 +626,7 @@ virCPUUpdate(virArch arch,
return -1; return -1;
} }
if (driver->update(guest, host, relative) < 0) if (driver->update(guest, host, relative, removedPolicy) < 0)
return -1; return -1;
VIR_DEBUG("model=%s", NULLSTR(guest->model)); VIR_DEBUG("model=%s", NULLSTR(guest->model));

View File

@ -81,7 +81,8 @@ typedef virCPUDef *
typedef int typedef int
(*virCPUArchUpdate)(virCPUDef *guest, (*virCPUArchUpdate)(virCPUDef *guest,
const virCPUDef *host, const virCPUDef *host,
bool relative); bool relative,
virCPUFeaturePolicy removedPolicy);
typedef int typedef int
(*virCPUArchUpdateLive)(virCPUDef *cpu, (*virCPUArchUpdateLive)(virCPUDef *cpu,
@ -229,7 +230,8 @@ virCPUBaseline(virArch arch,
int int
virCPUUpdate(virArch arch, virCPUUpdate(virArch arch,
virCPUDef *guest, virCPUDef *guest,
const virCPUDef *host) const virCPUDef *host,
virCPUFeaturePolicy removedPolicy)
ATTRIBUTE_NONNULL(2); ATTRIBUTE_NONNULL(2);
int int

View File

@ -448,7 +448,8 @@ virCPUarmGetMap(void)
static int static int
virCPUarmUpdate(virCPUDef *guest, virCPUarmUpdate(virCPUDef *guest,
const virCPUDef *host, const virCPUDef *host,
bool relative) bool relative,
virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED)
{ {
g_autoptr(virCPUDef) updated = virCPUDefCopyWithoutModel(guest); g_autoptr(virCPUDef) updated = virCPUDefCopyWithoutModel(guest);

View File

@ -39,7 +39,8 @@ virCPULoongArchCompare(virCPUDef *host G_GNUC_UNUSED,
static int static int
virCPULoongArchUpdate(virCPUDef *guest G_GNUC_UNUSED, virCPULoongArchUpdate(virCPUDef *guest G_GNUC_UNUSED,
const virCPUDef *host 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; return 0;
} }

View File

@ -654,7 +654,8 @@ virCPUppc64GetHost(virCPUDef *cpu,
static int static int
virCPUppc64Update(virCPUDef *guest, virCPUppc64Update(virCPUDef *guest,
const virCPUDef *host G_GNUC_UNUSED, 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 * - host-passthrough doesn't even get here

View File

@ -49,7 +49,8 @@ virCPURiscv64ValidateFeatures(virCPUDef *cpu G_GNUC_UNUSED)
static int static int
virCPURiscv64Update(virCPUDef *guest, virCPURiscv64Update(virCPUDef *guest,
const virCPUDef *host, const virCPUDef *host,
bool relative) bool relative,
virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED)
{ {
g_autoptr(virCPUDef) updated = virCPUDefCopyWithoutModel(guest); g_autoptr(virCPUDef) updated = virCPUDefCopyWithoutModel(guest);

View File

@ -42,7 +42,8 @@ virCPUs390Compare(virCPUDef *host G_GNUC_UNUSED,
static int static int
virCPUs390Update(virCPUDef *guest, virCPUs390Update(virCPUDef *guest,
const virCPUDef *host, const virCPUDef *host,
bool relative) bool relative,
virCPUFeaturePolicy removedPolicy G_GNUC_UNUSED)
{ {
g_autoptr(virCPUDef) updated = virCPUDefCopyWithoutModel(guest); g_autoptr(virCPUDef) updated = virCPUDefCopyWithoutModel(guest);
size_t i; size_t i;

View File

@ -829,6 +829,22 @@ x86DataAddSignature(virCPUx86Data *data,
} }
/*
* 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 * Disables features removed from the CPU @model unless they are already
* mentioned in @cpu to make sure these features will always be explicitly * mentioned in @cpu to make sure these features will always be explicitly
@ -838,15 +854,7 @@ static void
virCPUx86DisableRemovedFeatures(virCPUDef *cpu, virCPUx86DisableRemovedFeatures(virCPUDef *cpu,
virCPUx86Model *model) virCPUx86Model *model)
{ {
char **feat = model->removedFeatures; virCPUx86AddRemovedFeatures(cpu, model, VIR_CPU_FEATURE_DISABLE);
if (!feat)
return;
while (*feat) {
virCPUDefAddFeatureIfMissing(cpu, *feat, VIR_CPU_FEATURE_DISABLE);
feat++;
}
} }
@ -2940,7 +2948,8 @@ x86UpdateHostModel(virCPUDef *guest,
static int static int
virCPUx86Update(virCPUDef *guest, virCPUx86Update(virCPUDef *guest,
const virCPUDef *host, const virCPUDef *host,
bool relative) bool relative,
virCPUFeaturePolicy removedPolicy)
{ {
g_autoptr(virCPUx86Model) model = NULL; g_autoptr(virCPUx86Model) model = NULL;
virCPUx86Model *guestModel; virCPUx86Model *guestModel;
@ -2985,7 +2994,7 @@ virCPUx86Update(virCPUDef *guest,
return -1; return -1;
} }
virCPUx86DisableRemovedFeatures(guest, guestModel); virCPUx86AddRemovedFeatures(guest, guestModel, removedPolicy);
return 0; return 0;
} }

View File

@ -6763,7 +6763,8 @@ qemuDomainDefFormatBufInternal(virQEMUDriver *driver,
if (virCPUUpdate(def->os.arch, def->cpu, if (virCPUUpdate(def->os.arch, def->cpu,
virQEMUCapsGetHostModel(qCaps, def->virtType, virQEMUCapsGetHostModel(qCaps, def->virtType,
VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE)) < 0) VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE),
VIR_CPU_FEATURE_DISABLE) < 0)
return -1; return -1;
} }

View File

@ -6281,7 +6281,8 @@ qemuProcessUpdateGuestCPU(virDomainDef *def,
if (virCPUUpdate(def->os.arch, def->cpu, if (virCPUUpdate(def->os.arch, def->cpu,
virQEMUCapsGetHostModel(qemuCaps, def->virtType, virQEMUCapsGetHostModel(qemuCaps, def->virtType,
VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE)) < 0) VIR_QEMU_CAPS_HOST_CPU_MIGRATABLE),
VIR_CPU_FEATURE_DISABLE) < 0)
return -1; return -1;
cpuModels = virQEMUCapsGetCPUModels(qemuCaps, def->virtType, NULL, NULL); cpuModels = virQEMUCapsGetCPUModels(qemuCaps, def->virtType, NULL, NULL);
@ -8914,7 +8915,8 @@ qemuProcessRefreshCPU(virQEMUDriver *driver,
virCPUDefCopyModelFilter(cpu, hostmig, false, virQEMUCapsCPUFilterFeatures, virCPUDefCopyModelFilter(cpu, hostmig, false, virQEMUCapsCPUFilterFeatures,
&host->arch); &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; return -1;
if (qemuProcessUpdateCPU(vm, VIR_ASYNC_JOB_NONE) < 0) if (qemuProcessUpdateCPU(vm, VIR_ASYNC_JOB_NONE) < 0)

View File

@ -236,7 +236,7 @@ cpuTestGuestCPU(const void *arg)
goto cleanup; 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) { virCPUTranslate(host->arch, cpu, data->models) < 0) {
ret = -1; ret = -1;
goto cleanup; goto cleanup;
@ -363,7 +363,7 @@ cpuTestUpdate(const void *arg)
if (!(migHost = virCPUCopyMigratable(data->arch, host))) if (!(migHost = virCPUCopyMigratable(data->arch, host)))
return -1; return -1;
if (virCPUUpdate(host->arch, cpu, migHost) < 0) if (virCPUUpdate(host->arch, cpu, migHost, VIR_CPU_FEATURE_DISABLE) < 0)
return -1; return -1;
result = g_strdup_printf("%s+%s", data->host, data->name); result = g_strdup_printf("%s+%s", data->host, data->name);