提交 a54234c3 编写于 作者: J Jiri Denemark

cpu_x86: Refactor internal KVM features

The internal features are only used in explicit checks with
cpuHasFeature. Loading them into the CPU map is dangerous since the
features may accidentally be reported to users when decoding CPUID data.
Signed-off-by: NJiri Denemark <jdenemar@redhat.com>
上级 74b23a00
......@@ -59,33 +59,75 @@ struct _virCPUx86Feature {
bool migratable;
};
typedef struct _virCPUx86KVMFeature virCPUx86KVMFeature;
typedef virCPUx86KVMFeature *virCPUx86KVMFeaturePtr;
struct _virCPUx86KVMFeature {
const char *name;
const virCPUx86CPUID cpuid;
};
static const virCPUx86KVMFeature x86_kvm_features[] =
{
{VIR_CPU_x86_KVM_CLOCKSOURCE, { .eax_in = 0x40000001, .eax = 0x00000001 }},
{VIR_CPU_x86_KVM_NOP_IO_DELAY, { .eax_in = 0x40000001, .eax = 0x00000002 }},
{VIR_CPU_x86_KVM_MMU_OP, { .eax_in = 0x40000001, .eax = 0x00000004 }},
{VIR_CPU_x86_KVM_CLOCKSOURCE2, { .eax_in = 0x40000001, .eax = 0x00000008 }},
{VIR_CPU_x86_KVM_ASYNC_PF, { .eax_in = 0x40000001, .eax = 0x00000010 }},
{VIR_CPU_x86_KVM_STEAL_TIME, { .eax_in = 0x40000001, .eax = 0x00000020 }},
{VIR_CPU_x86_KVM_PV_EOI, { .eax_in = 0x40000001, .eax = 0x00000040 }},
{VIR_CPU_x86_KVM_PV_UNHALT, { .eax_in = 0x40000001, .eax = 0x00000080 }},
{VIR_CPU_x86_KVM_CLOCKSOURCE_STABLE_BIT,
{ .eax_in = 0x40000001, .eax = 0x01000000 }},
{VIR_CPU_x86_KVM_HV_RUNTIME, { .eax_in = 0x40000003, .eax = 0x00000001 }},
{VIR_CPU_x86_KVM_HV_SYNIC, { .eax_in = 0x40000003, .eax = 0x00000004 }},
{VIR_CPU_x86_KVM_HV_STIMER, { .eax_in = 0x40000003, .eax = 0x00000008 }},
{VIR_CPU_x86_KVM_HV_RELAXED, { .eax_in = 0x40000003, .eax = 0x00000020 }},
{VIR_CPU_x86_KVM_HV_SPINLOCK, { .eax_in = 0x40000003, .eax = 0x00000022 }},
{VIR_CPU_x86_KVM_HV_VAPIC, { .eax_in = 0x40000003, .eax = 0x00000030 }},
{VIR_CPU_x86_KVM_HV_VPINDEX, { .eax_in = 0x40000003, .eax = 0x00000040 }},
{VIR_CPU_x86_KVM_HV_RESET, { .eax_in = 0x40000003, .eax = 0x00000080 }},
#define KVM_FEATURE_DEF(Name, Eax_in, Eax) \
static virCPUx86CPUID Name ## _cpuid[] = { \
{ .eax_in = Eax_in, .eax = Eax }, \
}
#define KVM_FEATURE(Name) \
{ \
.name = (char *) Name, \
.data = { \
.len = ARRAY_CARDINALITY(Name ## _cpuid), \
.data = Name ## _cpuid \
} \
}
KVM_FEATURE_DEF(VIR_CPU_x86_KVM_CLOCKSOURCE,
0x40000001, 0x00000001);
KVM_FEATURE_DEF(VIR_CPU_x86_KVM_NOP_IO_DELAY,
0x40000001, 0x00000002);
KVM_FEATURE_DEF(VIR_CPU_x86_KVM_MMU_OP,
0x40000001, 0x00000004);
KVM_FEATURE_DEF(VIR_CPU_x86_KVM_CLOCKSOURCE2,
0x40000001, 0x00000008);
KVM_FEATURE_DEF(VIR_CPU_x86_KVM_ASYNC_PF,
0x40000001, 0x00000010);
KVM_FEATURE_DEF(VIR_CPU_x86_KVM_STEAL_TIME,
0x40000001, 0x00000020);
KVM_FEATURE_DEF(VIR_CPU_x86_KVM_PV_EOI,
0x40000001, 0x00000040);
KVM_FEATURE_DEF(VIR_CPU_x86_KVM_PV_UNHALT,
0x40000001, 0x00000080);
KVM_FEATURE_DEF(VIR_CPU_x86_KVM_CLOCKSOURCE_STABLE_BIT,
0x40000001, 0x01000000);
KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_RUNTIME,
0x40000003, 0x00000001);
KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_SYNIC,
0x40000003, 0x00000004);
KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_STIMER,
0x40000003, 0x00000008);
KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_RELAXED,
0x40000003, 0x00000020);
KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_SPINLOCK,
0x40000003, 0x00000022);
KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_VAPIC,
0x40000003, 0x00000030);
KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_VPINDEX,
0x40000003, 0x00000040);
KVM_FEATURE_DEF(VIR_CPU_x86_KVM_HV_RESET,
0x40000003, 0x00000080);
static virCPUx86Feature x86_kvm_features[] =
{
KVM_FEATURE(VIR_CPU_x86_KVM_CLOCKSOURCE),
KVM_FEATURE(VIR_CPU_x86_KVM_NOP_IO_DELAY),
KVM_FEATURE(VIR_CPU_x86_KVM_MMU_OP),
KVM_FEATURE(VIR_CPU_x86_KVM_CLOCKSOURCE2),
KVM_FEATURE(VIR_CPU_x86_KVM_ASYNC_PF),
KVM_FEATURE(VIR_CPU_x86_KVM_STEAL_TIME),
KVM_FEATURE(VIR_CPU_x86_KVM_PV_EOI),
KVM_FEATURE(VIR_CPU_x86_KVM_PV_UNHALT),
KVM_FEATURE(VIR_CPU_x86_KVM_CLOCKSOURCE_STABLE_BIT),
KVM_FEATURE(VIR_CPU_x86_KVM_HV_RUNTIME),
KVM_FEATURE(VIR_CPU_x86_KVM_HV_SYNIC),
KVM_FEATURE(VIR_CPU_x86_KVM_HV_STIMER),
KVM_FEATURE(VIR_CPU_x86_KVM_HV_RELAXED),
KVM_FEATURE(VIR_CPU_x86_KVM_HV_SPINLOCK),
KVM_FEATURE(VIR_CPU_x86_KVM_HV_VAPIC),
KVM_FEATURE(VIR_CPU_x86_KVM_HV_VPINDEX),
KVM_FEATURE(VIR_CPU_x86_KVM_HV_RESET),
};
typedef struct _virCPUx86Model virCPUx86Model;
......@@ -627,6 +669,21 @@ x86FeatureFind(virCPUx86MapPtr map,
}
static virCPUx86FeaturePtr
x86FeatureFindInternal(const char *name)
{
size_t i;
size_t count = ARRAY_CARDINALITY(x86_kvm_features);
for (i = 0; i < count; i++) {
if (STREQ(x86_kvm_features[i].name, name))
return x86_kvm_features + i;
}
return NULL;
}
static char *
x86FeatureNames(virCPUx86MapPtr map,
const char *separator,
......@@ -1159,47 +1216,6 @@ x86MapLoadCallback(cpuMapElement element,
}
static int
x86MapLoadInternalFeatures(virCPUx86MapPtr map)
{
size_t i;
virCPUx86FeaturePtr feature = NULL;
size_t nfeatures = map->nfeatures;
size_t count = ARRAY_CARDINALITY(x86_kvm_features);
if (VIR_EXPAND_N(map->features, nfeatures, count) < 0)
goto error;
for (i = 0; i < count; i++) {
const char *name = x86_kvm_features[i].name;
if (x86FeatureFind(map, name)) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("CPU feature %s already defined"), name);
goto error;
}
if (!(feature = x86FeatureNew()))
goto error;
if (VIR_STRDUP(feature->name, name) < 0)
goto error;
if (virCPUx86DataAddCPUID(&feature->data, &x86_kvm_features[i].cpuid))
goto error;
map->features[map->nfeatures++] = feature;
feature = NULL;
}
return 0;
error:
x86FeatureFree(feature);
return -1;
}
static virCPUx86MapPtr
virCPUx86LoadMap(void)
{
......@@ -1211,9 +1227,6 @@ virCPUx86LoadMap(void)
if (cpuMapLoad("x86", x86MapLoadCallback, map) < 0)
goto error;
if (x86MapLoadInternalFeatures(map) < 0)
goto error;
return map;
error:
......@@ -2177,7 +2190,8 @@ x86HasFeature(const virCPUData *data,
if (!(map = virCPUx86GetMap()))
return -1;
if (!(feature = x86FeatureFind(map, name)))
if (!(feature = x86FeatureFind(map, name)) &&
!(feature = x86FeatureFindInternal(name)))
goto cleanup;
ret = x86DataIsSubset(&data->data.x86, &feature->data) ? 1 : 0;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册