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>
Mohamed Mediouni committed
Apr 22, 2026 at 23:42 UTC
d9225244af3907dcfb39831077e9b9d4e30f1f50
5 files changed
+54
accel/whpx/whpx-common.c
+3
@@ -538,6 +538,8 @@ static void whpx_accel_class_init(ObjectClass *oc, const void *data)
538
NULL, NULL);
539
object_class_property_set_description(oc, "hyperv",
540
"Configure Hyper-V enlightenments");
541
+
542
+ whpx_arch_accel_class_init(oc);
543
}
544
545
static void whpx_accel_instance_init(Object *obj)
@@ -552,6 +554,7 @@ static void whpx_accel_instance_init(Object *obj)
554
whpx->hyperv_enlightenments_required = false;
555
/* Value determined at whpx_accel_init */
556
whpx->hyperv_enlightenments_enabled = false;
557
+ whpx->ignore_unknown_msr = true;
558
}
559
560
static const TypeInfo whpx_accel_type = {
include/system/whpx-all.h
+1
@@ -20,6 +20,7 @@ void whpx_translate_cpu_breakpoints(
20
CPUState *cpu,
21
int cpu_breakpoint_count);
22
void whpx_arch_destroy_vcpu(CPUState *cpu);
23
+void whpx_arch_accel_class_init(ObjectClass *oc);
24
25
/* called by whpx-accel-ops */
26
bool whpx_arch_supports_guest_debug(void);
include/system/whpx-internal.h
+1
@@ -47,6 +47,7 @@ struct whpx_state {
47
bool hyperv_enlightenments_required;
48
bool hyperv_enlightenments_enabled;
49
50
+ bool ignore_unknown_msr;
51
};
52
53
extern struct whpx_state whpx_global;
target/arm/whpx/whpx-all.c
+4
@@ -823,6 +823,10 @@ void whpx_cpu_instance_init(CPUState *cs)
823
{
824
}
825
826
+void whpx_arch_accel_class_init(ObjectClass *oc)
827
+{
828
+}
829
+
830
int whpx_accel_init(AccelState *as, MachineState *ms)
831
{
832
struct whpx_state *whpx;
target/i386/whpx/whpx-all.c
+45
@@ -2133,6 +2133,10 @@ int whpx_vcpu_run(CPUState *cpu)
2133
vcpu->exit_ctx.MsrAccess.AccessInfo.IsWrite);
2134
}
2135
2136
+ if (!is_known_msr && !whpx->ignore_unknown_msr) {
2137
+ x86_emul_raise_exception(&X86_CPU(cpu)->env, EXCP0D_GPF, 0);
2138
+ }
2139
+
2140
hr = whp_dispatch.WHvSetVirtualProcessorRegisters(
2141
whpx->partition,
2142
cpu->cpu_index,
@@ -2532,6 +2536,47 @@ void whpx_cpu_instance_init(CPUState *cs)
2536
* Partition support
2537
*/
2538
2539
+static void whpx_set_unknown_msr(Object *obj, Visitor *v,
2540
+ const char *name, void *opaque,
2541
+ Error **errp)
2542
+{
2543
+ struct whpx_state *whpx = &whpx_global;
2544
+ OnOffAuto mode;
2545
+
2546
+ if (!visit_type_OnOffAuto(v, name, &mode, errp)) {
2547
+ return;
2548
+ }
2549
+
2550
+ switch (mode) {
2551
+ case ON_OFF_AUTO_ON:
2552
+ whpx->ignore_unknown_msr = true;
2553
+ break;
2554
+
2555
+ case ON_OFF_AUTO_OFF:
2556
+ whpx->ignore_unknown_msr = false;
2557
+ break;
2558
+
2559
+ case ON_OFF_AUTO_AUTO:
2560
+ whpx->ignore_unknown_msr = true;
2561
+ break;
2562
+ default:
2563
+ /*
2564
+ * The value was checked in visit_type_OnOffAuto() above. If
2565
+ * we get here, then something is wrong in QEMU.
2566
+ */
2567
+ abort();
2568
+ }
2569
+}
2570
+
2571
+void whpx_arch_accel_class_init(ObjectClass *oc)
2572
+{
2573
+ object_class_property_add(oc, "ignore-unknown-msr", "OnOffAuto",
2574
+ NULL, whpx_set_unknown_msr,
2575
+ NULL, NULL);
2576
+ object_class_property_set_description(oc, "ignore-unknown-msr",
2577
+ "Configure unknown MSR behavior");
2578
+}
2579
+
2580
int whpx_accel_init(AccelState *as, MachineState *ms)
2581
{
2582
struct whpx_state *whpx;