提交 0aa9383f 编写于 作者: J Jiri Denemark

cpu: Introduce virCPUExpandFeatures

Having to use cpuBaseline with VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES
flag to expand CPU features is strange. Not to mention that cpuBaseline
can only expand host CPU definitions (i.e., it completely ignores
feature policies). The new virCPUExpandFeatures API is designed to work
with both host and guest CPU definitions.
Signed-off-by: NJiri Denemark <jdenemar@redhat.com>
上级 532fc7b7
...@@ -1076,3 +1076,53 @@ virCPUConvertLegacy(virArch arch, ...@@ -1076,3 +1076,53 @@ virCPUConvertLegacy(virArch arch,
VIR_DEBUG("model=%s", NULLSTR(cpu->model)); VIR_DEBUG("model=%s", NULLSTR(cpu->model));
return 0; return 0;
} }
static int
virCPUFeatureCompare(const void *p1,
const void *p2)
{
const virCPUFeatureDef *f1 = p1;
const virCPUFeatureDef *f2 = p2;
return strcmp(f1->name, f2->name);
}
/**
* virCPUExpandFeatures:
*
* @arch: CPU architecture
* @cpu: CPU definition to be expanded
*
* Add all features implicitly enabled by the CPU model to the list of
* features. The @cpu is expected to be either a host or a guest representation
* of a host CPU, i.e., only VIR_CPU_FEATURE_REQUIRE and
* VIR_CPU_FEATURE_DISABLE policies are supported.
*
* The updated list of features in the CPU definition is sorted.
*
* Return -1 on error, 0 on success.
*/
int
virCPUExpandFeatures(virArch arch,
virCPUDefPtr cpu)
{
struct cpuArchDriver *driver;
VIR_DEBUG("arch=%s, cpu=%p, model=%s, nfeatures=%zu",
virArchToString(arch), cpu, NULLSTR(cpu->model), cpu->nfeatures);
if (!(driver = cpuGetSubDriver(arch)))
return -1;
if (driver->expandFeatures &&
driver->expandFeatures(cpu) < 0)
return -1;
qsort(cpu->features, cpu->nfeatures, sizeof(*cpu->features),
virCPUFeatureCompare);
VIR_DEBUG("nfeatures=%zu", cpu->nfeatures);
return 0;
}
...@@ -116,6 +116,9 @@ typedef int ...@@ -116,6 +116,9 @@ typedef int
typedef int typedef int
(*virCPUArchConvertLegacy)(virCPUDefPtr cpu); (*virCPUArchConvertLegacy)(virCPUDefPtr cpu);
typedef int
(*virCPUArchExpandFeatures)(virCPUDefPtr cpu);
struct cpuArchDriver { struct cpuArchDriver {
const char *name; const char *name;
const virArch *arch; const virArch *arch;
...@@ -135,6 +138,7 @@ struct cpuArchDriver { ...@@ -135,6 +138,7 @@ struct cpuArchDriver {
virCPUArchGetModels getModels; virCPUArchGetModels getModels;
virCPUArchTranslate translate; virCPUArchTranslate translate;
virCPUArchConvertLegacy convertLegacy; virCPUArchConvertLegacy convertLegacy;
virCPUArchExpandFeatures expandFeatures;
}; };
...@@ -247,6 +251,10 @@ virCPUConvertLegacy(virArch arch, ...@@ -247,6 +251,10 @@ virCPUConvertLegacy(virArch arch,
virCPUDefPtr cpu) virCPUDefPtr cpu)
ATTRIBUTE_NONNULL(2); ATTRIBUTE_NONNULL(2);
int
virCPUExpandFeatures(virArch arch,
virCPUDefPtr cpu);
/* virCPUDataFormat and virCPUDataParse are implemented for unit tests only and /* virCPUDataFormat and virCPUDataParse are implemented for unit tests only and
* have no real-life usage * have no real-life usage
*/ */
......
...@@ -2891,6 +2891,58 @@ virCPUx86Translate(virCPUDefPtr cpu, ...@@ -2891,6 +2891,58 @@ virCPUx86Translate(virCPUDefPtr cpu,
} }
static int
virCPUx86ExpandFeatures(virCPUDefPtr cpu)
{
virCPUx86MapPtr map;
virCPUDefPtr expanded = NULL;
virCPUx86ModelPtr model = NULL;
bool host = cpu->type == VIR_CPU_TYPE_HOST;
size_t i;
int ret = -1;
if (!(map = virCPUx86GetMap()))
goto cleanup;
if (!(expanded = virCPUDefCopy(cpu)))
goto cleanup;
virCPUDefFreeFeatures(expanded);
if (!(model = x86ModelFind(map, cpu->model))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("unknown CPU model %s"), cpu->model);
goto cleanup;
}
if (!(model = x86ModelCopy(model)) ||
x86DataToCPUFeatures(expanded, host ? -1 : VIR_CPU_FEATURE_REQUIRE,
&model->data, map) < 0)
goto cleanup;
for (i = 0; i < cpu->nfeatures; i++) {
virCPUFeatureDefPtr f = cpu->features + i;
if (!host &&
f->policy != VIR_CPU_FEATURE_REQUIRE &&
f->policy != VIR_CPU_FEATURE_DISABLE)
continue;
if (virCPUDefUpdateFeature(expanded, f->name, f->policy) < 0)
goto cleanup;
}
virCPUDefFreeModel(cpu);
ret = virCPUDefCopyModel(cpu, expanded, false);
cleanup:
virCPUDefFree(expanded);
x86ModelFree(model);
return ret;
}
int int
virCPUx86DataAddCPUID(virCPUDataPtr cpuData, virCPUx86DataAddCPUID(virCPUDataPtr cpuData,
const virCPUx86CPUID *cpuid) const virCPUx86CPUID *cpuid)
...@@ -2965,4 +3017,5 @@ struct cpuArchDriver cpuDriverX86 = { ...@@ -2965,4 +3017,5 @@ struct cpuArchDriver cpuDriverX86 = {
.dataParse = virCPUx86DataParse, .dataParse = virCPUx86DataParse,
.getModels = virCPUx86GetModels, .getModels = virCPUx86GetModels,
.translate = virCPUx86Translate, .translate = virCPUx86Translate,
.expandFeatures = virCPUx86ExpandFeatures,
}; };
...@@ -1021,6 +1021,7 @@ virCPUDataFormat; ...@@ -1021,6 +1021,7 @@ virCPUDataFormat;
virCPUDataFree; virCPUDataFree;
virCPUDataNew; virCPUDataNew;
virCPUDataParse; virCPUDataParse;
virCPUExpandFeatures;
virCPUGetHost; virCPUGetHost;
virCPUGetModels; virCPUGetModels;
virCPUProbeHost; virCPUProbeHost;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册