i386: do not call cpudef-only models functions for max, host, base

Some cpu properties have to be set only for cpu models in builtin_x86_defs,
registered with x86_register_cpu_model_type, and not for
cpu models "base", "max", and the subclass "host".

These properties are the ones set by function x86_cpu_apply_props,
(also including kvm_default_props, tcg_default_props),
and the "vendor" property for the KVM and HVF accelerators.

After recent refactoring of cpu, which also affected these properties,
they were instead set unconditionally for all x86 cpus.

This has been detected as a bug with Nested on AMD with cpu "host",
as svm was not turned on by default, due to the wrongful setting of
kvm_default_props via x86_cpu_apply_props, which set svm to "off".

Rectify the bug introduced in commit "i386: split cpu accelerators"
and document the functions that are builtin_x86_defs-only.

Signed-off-by: Claudio Fontana <cfontana@suse.de>
Tested-by: Alexander Bulekov <alxndr@bu.edu>
Fixes: f5cc5a5c ("i386: split cpu accelerators from cpu.c,"...)
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/477
Message-Id: <20210723112921.12637-1-cfontana@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Claudio Fontana 2021-07-23 13:29:21 +02:00 committed by Paolo Bonzini
parent 3407259b20
commit 5b8978d804
4 changed files with 89 additions and 59 deletions

View file

@ -52,47 +52,6 @@ static bool kvm_cpu_realizefn(CPUState *cs, Error **errp)
return host_cpu_realizefn(cs, errp);
}
/*
* KVM-specific features that are automatically added/removed
* from all CPU models when KVM is enabled.
*
* NOTE: features can be enabled by default only if they were
* already available in the oldest kernel version supported
* by the KVM accelerator (see "OS requirements" section at
* docs/system/target-i386.rst)
*/
static PropValue kvm_default_props[] = {
{ "kvmclock", "on" },
{ "kvm-nopiodelay", "on" },
{ "kvm-asyncpf", "on" },
{ "kvm-steal-time", "on" },
{ "kvm-pv-eoi", "on" },
{ "kvmclock-stable-bit", "on" },
{ "x2apic", "on" },
{ "kvm-msi-ext-dest-id", "off" },
{ "acpi", "off" },
{ "monitor", "off" },
{ "svm", "off" },
{ NULL, NULL },
};
void x86_cpu_change_kvm_default(const char *prop, const char *value)
{
PropValue *pv;
for (pv = kvm_default_props; pv->prop; pv++) {
if (!strcmp(pv->prop, prop)) {
pv->value = value;
break;
}
}
/*
* It is valid to call this function only for properties that
* are already present in the kvm_default_props table.
*/
assert(pv->prop);
}
static bool lmce_supported(void)
{
uint64_t mce_cap = 0;
@ -150,22 +109,70 @@ static void kvm_cpu_xsave_init(void)
}
}
/*
* KVM-specific features that are automatically added/removed
* from cpudef models when KVM is enabled.
* Only for builtin_x86_defs models initialized with x86_register_cpudef_types.
*
* NOTE: features can be enabled by default only if they were
* already available in the oldest kernel version supported
* by the KVM accelerator (see "OS requirements" section at
* docs/system/target-i386.rst)
*/
static PropValue kvm_default_props[] = {
{ "kvmclock", "on" },
{ "kvm-nopiodelay", "on" },
{ "kvm-asyncpf", "on" },
{ "kvm-steal-time", "on" },
{ "kvm-pv-eoi", "on" },
{ "kvmclock-stable-bit", "on" },
{ "x2apic", "on" },
{ "kvm-msi-ext-dest-id", "off" },
{ "acpi", "off" },
{ "monitor", "off" },
{ "svm", "off" },
{ NULL, NULL },
};
/*
* Only for builtin_x86_defs models initialized with x86_register_cpudef_types.
*/
void x86_cpu_change_kvm_default(const char *prop, const char *value)
{
PropValue *pv;
for (pv = kvm_default_props; pv->prop; pv++) {
if (!strcmp(pv->prop, prop)) {
pv->value = value;
break;
}
}
/*
* It is valid to call this function only for properties that
* are already present in the kvm_default_props table.
*/
assert(pv->prop);
}
static void kvm_cpu_instance_init(CPUState *cs)
{
X86CPU *cpu = X86_CPU(cs);
X86CPUClass *xcc = X86_CPU_GET_CLASS(cpu);
host_cpu_instance_init(cpu);
if (!kvm_irqchip_in_kernel()) {
x86_cpu_change_kvm_default("x2apic", "off");
} else if (kvm_irqchip_is_split() && kvm_enable_x2apic()) {
x86_cpu_change_kvm_default("kvm-msi-ext-dest-id", "on");
if (xcc->model) {
/* only applies to builtin_x86_defs cpus */
if (!kvm_irqchip_in_kernel()) {
x86_cpu_change_kvm_default("x2apic", "off");
} else if (kvm_irqchip_is_split() && kvm_enable_x2apic()) {
x86_cpu_change_kvm_default("kvm-msi-ext-dest-id", "on");
}
/* Special cases not set in the X86CPUDefinition structs: */
x86_cpu_apply_props(cpu, kvm_default_props);
}
/* Special cases not set in the X86CPUDefinition structs: */
x86_cpu_apply_props(cpu, kvm_default_props);
if (cpu->max_features) {
kvm_cpu_max_instance_init(cpu);
}