target/i386: query mshv accel for supported cpuids
We implement mshv_get_supported_cpuid() and invoke it in x86_cpu_get_supported_feature_word() retrieve the cpu features that the host is supporting. Initially we mask the virtualization capabilitities potentially we might need to mask more in the future. Signed-off-by: Magnus Kulke <magnuskulke@linux.microsoft.com> Reviewed-by: Doru Blânzeanu <dblanzeanu@linux.microsoft.com> Link: https://lore.kernel.org/r/20260416121116.527927-7-magnuskulke@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Magnus Kulke committed
Apr 16, 2026 at 14:11 UTC
38a557bc852c8e76347b8f53a82658cc83f0bb48
3 files changed
+38
include/system/mshv.h
+3
@@ -60,4 +60,7 @@ int mshv_irqchip_add_irqfd_notifier_gsi(const EventNotifier *n,
60
const EventNotifier *rn, int virq);
61
int mshv_irqchip_remove_irqfd_notifier_gsi(const EventNotifier *n, int virq);
62
63
+/* cpuid */
64
+uint32_t mshv_get_supported_cpuid(uint32_t func, uint32_t idx, int reg);
65
+
66
#endif
target/i386/cpu.c
+8
@@ -26,6 +26,7 @@
26
#include "tcg/helper-tcg.h"
27
#include "exec/translation-block.h"
28
#include "system/hvf.h"
29
+#include "system/mshv.h"
30
#include "system/whpx.h"
31
#include "whpx/whpx-i386.h"
32
#include "hvf/hvf-i386.h"
@@ -8233,6 +8234,13 @@ uint64_t x86_cpu_get_supported_feature_word(X86CPU *cpu, FeatureWord w)
8234
r = hvf_get_supported_cpuid(wi->cpuid.eax,
8235
wi->cpuid.ecx,
8236
wi->cpuid.reg);
8237
+ } else if (mshv_enabled()) {
8238
+ if (wi->type != CPUID_FEATURE_WORD) {
8239
+ return 0;
8240
+ }
8241
+ r = mshv_get_supported_cpuid(wi->cpuid.eax,
8242
+ wi->cpuid.ecx,
8243
+ wi->cpuid.reg);
8244
} else if (whpx_enabled()) {
8245
switch (wi->type) {
8246
case CPUID_FEATURE_WORD:
target/i386/mshv/mshv-cpu.c
+27
@@ -1664,6 +1664,33 @@ void mshv_arch_destroy_vcpu(CPUState *cpu)
1664
g_clear_pointer(&env->emu_mmio_buf, g_free);
1665
}
1666
1667
+uint32_t mshv_get_supported_cpuid(uint32_t func, uint32_t idx, int reg)
1668
+{
1669
+ uint32_t eax, ebx, ecx, edx;
1670
+ uint32_t ret = 0;
1671
+
1672
+ host_cpuid(func, idx, &eax, &ebx, &ecx, &edx);
1673
+ switch (reg) {
1674
+ case R_EAX:
1675
+ ret = eax; break;
1676
+ case R_EBX:
1677
+ ret = ebx; break;
1678
+ case R_ECX:
1679
+ ret = ecx; break;
1680
+ case R_EDX:
1681
+ ret = edx; break;
1682
+ }
1683
+
1684
+ /* Disable nested virtualization features not yet supported by MSHV */
1685
+ if (func == 0x80000001 && reg == R_ECX) {
1686
+ ret &= ~CPUID_EXT3_SVM;
1687
+ }
1688
+ if (func == 0x01 && reg == R_ECX) {
1689
+ ret &= ~CPUID_EXT_VMX;
1690
+ }
1691
+ return ret;
1692
+}
1693
+
1694
/*
1695
* Default Microsoft Hypervisor behavior for unimplemented MSR is to send a
1696
* fault to the guest if it tries to access it. It is possible to override