i386: Support KVM_CAP_ENFORCE_PV_FEATURE_CPUID

By default, KVM allows the guest to use all currently supported PV features
even when they were not announced in guest visible CPUIDs. Introduce a new
"kvm-pv-enforce-cpuid" flag to limit the supported feature set to the
exposed features. The feature is supported by Linux >= 5.10 and is not
enabled by default in QEMU.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Message-Id: <20210902093530.345756-4-vkuznets@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Vitaly Kuznetsov 2021-09-02 11:35:25 +02:00 committed by Paolo Bonzini
parent 8bdfec393a
commit 988f7b8bfe
3 changed files with 15 additions and 0 deletions

View File

@ -6860,6 +6860,8 @@ static Property x86_cpu_properties[] = {
DEFINE_PROP_BOOL("l3-cache", X86CPU, enable_l3_cache, true), DEFINE_PROP_BOOL("l3-cache", X86CPU, enable_l3_cache, true),
DEFINE_PROP_BOOL("kvm-no-smi-migration", X86CPU, kvm_no_smi_migration, DEFINE_PROP_BOOL("kvm-no-smi-migration", X86CPU, kvm_no_smi_migration,
false), false),
DEFINE_PROP_BOOL("kvm-pv-enforce-cpuid", X86CPU, kvm_pv_enforce_cpuid,
false),
DEFINE_PROP_BOOL("vmware-cpuid-freq", X86CPU, vmware_cpuid_freq, true), DEFINE_PROP_BOOL("vmware-cpuid-freq", X86CPU, vmware_cpuid_freq, true),
DEFINE_PROP_BOOL("tcg-cpuid", X86CPU, expose_tcg, true), DEFINE_PROP_BOOL("tcg-cpuid", X86CPU, expose_tcg, true),
DEFINE_PROP_BOOL("x-migrate-smi-count", X86CPU, migrate_smi_count, DEFINE_PROP_BOOL("x-migrate-smi-count", X86CPU, migrate_smi_count,

View File

@ -1802,6 +1802,9 @@ struct X86CPU {
/* Stop SMI delivery for migration compatibility with old machines */ /* Stop SMI delivery for migration compatibility with old machines */
bool kvm_no_smi_migration; bool kvm_no_smi_migration;
/* Forcefully disable KVM PV features not exposed in guest CPUIDs */
bool kvm_pv_enforce_cpuid;
/* Number of physical address bits supported */ /* Number of physical address bits supported */
uint32_t phys_bits; uint32_t phys_bits;

View File

@ -1629,6 +1629,16 @@ int kvm_arch_init_vcpu(CPUState *cs)
cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused); cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused);
if (cpu->kvm_pv_enforce_cpuid) {
r = kvm_vcpu_enable_cap(cs, KVM_CAP_ENFORCE_PV_FEATURE_CPUID, 0, 1);
if (r < 0) {
fprintf(stderr,
"failed to enable KVM_CAP_ENFORCE_PV_FEATURE_CPUID: %s",
strerror(-r));
abort();
}
}
for (i = 0; i <= limit; i++) { for (i = 0; i <= limit; i++) {
if (cpuid_i == KVM_MAX_CPUID_ENTRIES) { if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
fprintf(stderr, "unsupported level value: 0x%x\n", limit); fprintf(stderr, "unsupported level value: 0x%x\n", limit);