mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 11:22:23 +00:00
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: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
parent
74b23a00eb
commit
a54234c37b
@ -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[] =
|
||||
#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[] =
|
||||
{
|
||||
{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 }},
|
||||
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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user