Commit d9225244af for qemu.org

commit d9225244af3907dcfb39831077e9b9d4e30f1f50
Author: Mohamed Mediouni <mohamed@unpredictable.fr>
Date:   Wed Apr 22 23:42:05 2026 +0200

    whpx: i386: unknown MSR configurability

    Add an option to inject back a GPF for unknown MSRs.

    Keep it on by default for now as Linux expects accesses to some
    AMD-specific MSRs to always succeed when on an AMD host.

    Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
    Link: https://lore.kernel.org/r/20260422214225.2242-18-mohamed@unpredictable.fr
    Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

diff --git a/accel/whpx/whpx-common.c b/accel/whpx/whpx-common.c
index 59be996aef..497c03138e 100644
--- a/accel/whpx/whpx-common.c
+++ b/accel/whpx/whpx-common.c
@@ -538,6 +538,8 @@ static void whpx_accel_class_init(ObjectClass *oc, const void *data)
         NULL, NULL);
     object_class_property_set_description(oc, "hyperv",
         "Configure Hyper-V enlightenments");
+
+    whpx_arch_accel_class_init(oc);
 }

 static void whpx_accel_instance_init(Object *obj)
@@ -552,6 +554,7 @@ static void whpx_accel_instance_init(Object *obj)
     whpx->hyperv_enlightenments_required = false;
     /* Value determined at whpx_accel_init */
     whpx->hyperv_enlightenments_enabled = false;
+    whpx->ignore_unknown_msr = true;
 }

 static const TypeInfo whpx_accel_type = {
diff --git a/include/system/whpx-all.h b/include/system/whpx-all.h
index 2cbea71b14..4022571fff 100644
--- a/include/system/whpx-all.h
+++ b/include/system/whpx-all.h
@@ -20,6 +20,7 @@ void whpx_translate_cpu_breakpoints(
     CPUState *cpu,
     int cpu_breakpoint_count);
 void whpx_arch_destroy_vcpu(CPUState *cpu);
+void whpx_arch_accel_class_init(ObjectClass *oc);

 /* called by whpx-accel-ops */
 bool whpx_arch_supports_guest_debug(void);
diff --git a/include/system/whpx-internal.h b/include/system/whpx-internal.h
index cf782cf5f8..86639627b3 100644
--- a/include/system/whpx-internal.h
+++ b/include/system/whpx-internal.h
@@ -47,6 +47,7 @@ struct whpx_state {
     bool hyperv_enlightenments_required;
     bool hyperv_enlightenments_enabled;

+    bool ignore_unknown_msr;
 };

 extern struct whpx_state whpx_global;
diff --git a/target/arm/whpx/whpx-all.c b/target/arm/whpx/whpx-all.c
index 4019a513aa..94304a4230 100644
--- a/target/arm/whpx/whpx-all.c
+++ b/target/arm/whpx/whpx-all.c
@@ -823,6 +823,10 @@ void whpx_cpu_instance_init(CPUState *cs)
 {
 }

+void whpx_arch_accel_class_init(ObjectClass *oc)
+{
+}
+
 int whpx_accel_init(AccelState *as, MachineState *ms)
 {
     struct whpx_state *whpx;
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index 9fc44f8a67..eecc7f48ed 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -2133,6 +2133,10 @@ int whpx_vcpu_run(CPUState *cpu)
                     vcpu->exit_ctx.MsrAccess.AccessInfo.IsWrite);
             }

+            if (!is_known_msr && !whpx->ignore_unknown_msr) {
+                x86_emul_raise_exception(&X86_CPU(cpu)->env, EXCP0D_GPF, 0);
+            }
+
             hr = whp_dispatch.WHvSetVirtualProcessorRegisters(
                 whpx->partition,
                 cpu->cpu_index,
@@ -2532,6 +2536,47 @@ void whpx_cpu_instance_init(CPUState *cs)
  * Partition support
  */

+static void whpx_set_unknown_msr(Object *obj, Visitor *v,
+                                   const char *name, void *opaque,
+                                   Error **errp)
+{
+    struct whpx_state *whpx = &whpx_global;
+    OnOffAuto mode;
+
+    if (!visit_type_OnOffAuto(v, name, &mode, errp)) {
+        return;
+    }
+
+    switch (mode) {
+    case ON_OFF_AUTO_ON:
+        whpx->ignore_unknown_msr = true;
+        break;
+
+    case ON_OFF_AUTO_OFF:
+        whpx->ignore_unknown_msr = false;
+        break;
+
+    case ON_OFF_AUTO_AUTO:
+        whpx->ignore_unknown_msr = true;
+        break;
+    default:
+        /*
+         * The value was checked in visit_type_OnOffAuto() above. If
+         * we get here, then something is wrong in QEMU.
+         */
+        abort();
+    }
+}
+
+void whpx_arch_accel_class_init(ObjectClass *oc)
+{
+    object_class_property_add(oc, "ignore-unknown-msr", "OnOffAuto",
+        NULL, whpx_set_unknown_msr,
+        NULL, NULL);
+    object_class_property_set_description(oc, "ignore-unknown-msr",
+        "Configure unknown MSR behavior");
+}
+
 int whpx_accel_init(AccelState *as, MachineState *ms)
 {
     struct whpx_state *whpx;