Skip to content

Commit d4b9ff3

Browse files
committed
KVM: x86: Treat MONTIOR/MWAIT as a "partially emulated" feature
Enumerate MWAIT in cpuid_func_emulated(), but only if the caller wants to include "partially emulated" features, i.e. features that KVM kinda sorta emulates, but with major caveats. This will allow initializing the guest cpu_caps based on the set of features that KVM virtualizes and/or emulates, without needing to handle things like MONITOR/MWAIT as one-off exceptions. Adding one-off handling for individual features is quite painful, especially when considering future hardening. It's very doable to verify, at compile time, that every CPUID-based feature that KVM queries when emulating guest behavior is actually known to KVM, e.g. to prevent KVM bugs where KVM emulates some feature but fails to advertise support to userspace. In other words, any features that are special cased, i.e. not handled generically in the CPUID framework, would also need to be special cased for any hardening efforts that build on said framework. Link: https://lore.kernel.org/r/20241128013424.4096668-44-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent ff402f5 commit d4b9ff3

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

arch/x86/kvm/cpuid.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,7 +1213,8 @@ static struct kvm_cpuid_entry2 *do_host_cpuid(struct kvm_cpuid_array *array,
12131213
return entry;
12141214
}
12151215

1216-
static int cpuid_func_emulated(struct kvm_cpuid_entry2 *entry, u32 func)
1216+
static int cpuid_func_emulated(struct kvm_cpuid_entry2 *entry, u32 func,
1217+
bool include_partially_emulated)
12171218
{
12181219
memset(entry, 0, sizeof(*entry));
12191220

@@ -1227,6 +1228,16 @@ static int cpuid_func_emulated(struct kvm_cpuid_entry2 *entry, u32 func)
12271228
return 1;
12281229
case 1:
12291230
entry->ecx = feature_bit(MOVBE);
1231+
/*
1232+
* KVM allows userspace to enumerate MONITOR+MWAIT support to
1233+
* the guest, but the MWAIT feature flag is never advertised
1234+
* to userspace because MONITOR+MWAIT aren't virtualized by
1235+
* hardware, can't be faithfully emulated in software (KVM
1236+
* emulates them as NOPs), and allowing the guest to execute
1237+
* them natively requires enabling a per-VM capability.
1238+
*/
1239+
if (include_partially_emulated)
1240+
entry->ecx |= feature_bit(MWAIT);
12301241
return 1;
12311242
case 7:
12321243
entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
@@ -1244,7 +1255,7 @@ static int __do_cpuid_func_emulated(struct kvm_cpuid_array *array, u32 func)
12441255
if (array->nent >= array->maxnent)
12451256
return -E2BIG;
12461257

1247-
array->nent += cpuid_func_emulated(&array->entries[array->nent], func);
1258+
array->nent += cpuid_func_emulated(&array->entries[array->nent], func, false);
12481259
return 0;
12491260
}
12501261

0 commit comments

Comments
 (0)