Commit de03f1bf1a for qemu.org
commit de03f1bf1ab0bb35cf8228e4c5eb6dc91150f399
Author: Mohamed Mediouni <mohamed@unpredictable.fr>
Date: Wed Apr 22 23:42:21 2026 +0200
target/i386: emulate, hvf: rdmsr/wrmsr GPF handling
In that case, the instruction pointer mustn't be incremented.
Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
Link: https://lore.kernel.org/r/20260422214225.2242-34-mohamed@unpredictable.fr
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
diff --git a/target/i386/emulate/x86_emu.c b/target/i386/emulate/x86_emu.c
index c2da1a133f..c6ea854290 100644
--- a/target/i386/emulate/x86_emu.c
+++ b/target/i386/emulate/x86_emu.c
@@ -792,15 +792,17 @@ void x86_emul_raise_exception(CPUX86State *env, int exception_index, int error_c
static bool exec_rdmsr(CPUX86State *env, struct x86_decode *decode)
{
- emul_ops->simulate_rdmsr(env_cpu(env));
- env->eip += decode->len;
+ if (!emul_ops->simulate_rdmsr(env_cpu(env))) {
+ env->eip += decode->len;
+ }
return 0;
}
static bool exec_wrmsr(CPUX86State *env, struct x86_decode *decode)
{
- emul_ops->simulate_wrmsr(env_cpu(env));
- env->eip += decode->len;
+ if (!emul_ops->simulate_wrmsr(env_cpu(env))) {
+ env->eip += decode->len;
+ }
return 0;
}
diff --git a/target/i386/emulate/x86_emu.h b/target/i386/emulate/x86_emu.h
index a8d4c93098..b985240b90 100644
--- a/target/i386/emulate/x86_emu.h
+++ b/target/i386/emulate/x86_emu.h
@@ -31,8 +31,8 @@ struct x86_emul_ops {
target_ulong (*read_cr) (CPUState *cpu, int cr);
void (*handle_io)(CPUState *cpu, uint16_t port, void *data, int direction,
int size, int count);
- void (*simulate_rdmsr)(CPUState *cs);
- void (*simulate_wrmsr)(CPUState *cs);
+ bool (*simulate_rdmsr)(CPUState *cs);
+ bool (*simulate_wrmsr)(CPUState *cs);
bool (*is_protected_mode)(CPUState *cpu);
bool (*is_long_mode)(CPUState *cpu);
bool (*is_user_mode)(CPUState *cpu);
diff --git a/target/i386/hvf/hvf-i386.h b/target/i386/hvf/hvf-i386.h
index 8c42ae6b01..b91c17e2fc 100644
--- a/target/i386/hvf/hvf-i386.h
+++ b/target/i386/hvf/hvf-i386.h
@@ -19,8 +19,8 @@
uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx, int reg);
void hvf_handle_io(CPUState *, uint16_t, void *, int, int, int);
-void hvf_simulate_rdmsr(CPUState *cpu);
-void hvf_simulate_wrmsr(CPUState *cpu);
+bool hvf_simulate_rdmsr(CPUState *cpu);
+bool hvf_simulate_wrmsr(CPUState *cpu);
/* Host specific functions */
int hvf_inject_interrupt(CPUArchState *env, int vector);
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index cdc8bd1950..2d1a943b96 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -536,7 +536,7 @@ void hvf_store_regs(CPUState *cs)
macvm_set_rip(cs, env->eip);
}
-void hvf_simulate_rdmsr(CPUState *cs)
+bool hvf_simulate_rdmsr(CPUState *cs)
{
X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
@@ -557,6 +557,7 @@ void hvf_simulate_rdmsr(CPUState *cs)
ret = apic_msr_read(cpu->apic_state, index, &val);
if (ret < 0) {
x86_emul_raise_exception(env, EXCP0D_GPF, 0);
+ return 1;
}
break;
@@ -639,9 +640,10 @@ void hvf_simulate_rdmsr(CPUState *cs)
RAX(env) = (uint32_t)val;
RDX(env) = (uint32_t)(val >> 32);
+ return 0;
}
-void hvf_simulate_wrmsr(CPUState *cs)
+bool hvf_simulate_wrmsr(CPUState *cs)
{
X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
@@ -657,6 +659,7 @@ void hvf_simulate_wrmsr(CPUState *cs)
r = cpu_set_apic_base(cpu->apic_state, data);
if (r < 0) {
x86_emul_raise_exception(env, EXCP0D_GPF, 0);
+ return 1;
}
break;
@@ -668,6 +671,7 @@ void hvf_simulate_wrmsr(CPUState *cs)
ret = apic_msr_write(cpu->apic_state, index, data);
if (ret < 0) {
x86_emul_raise_exception(env, EXCP0D_GPF, 0);
+ return 1;
}
break;
@@ -746,6 +750,7 @@ void hvf_simulate_wrmsr(CPUState *cs)
g_hypervisor_iface->wrmsr_handler(cs, msr, data);
printf("write msr %llx\n", RCX(cs));*/
+ return 0;
}
static int hvf_handle_vmexit(CPUState *cpu)