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;