Commit 9d63874d67 for qemu.org
commit 9d63874d67818e2e953ad26fa61d2f7760daa363
Author: Mohamed Mediouni <mohamed@unpredictable.fr>
Date: Wed Apr 22 23:41:59 2026 +0200
whpx: i386: IO port fast path cleanup
vmport calls synchronise_state within an I/O port read.
Support that properly.
What was there before worked because of a side effect of
whpx_get_reg synchronising context if cpu->vcpu_dirty.
Remove that whpx_get_reg call in whpx_bump_rip too as it's no longer
needed now.
Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
Link: https://lore.kernel.org/r/20260422214225.2242-12-mohamed@unpredictable.fr
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index ab8e97787f..75f0f062d4 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -881,7 +881,6 @@ static void handle_io(CPUState *env, uint16_t port, void *buffer,
static void whpx_bump_rip(CPUState *cpu, WHV_RUN_VP_EXIT_CONTEXT *exit_ctx)
{
WHV_REGISTER_VALUE reg;
- whpx_get_reg(cpu, WHvX64RegisterRip, ®);
reg.Reg64 = exit_ctx->VpContext.Rip + exit_ctx->VpContext.InstructionLength;
whpx_set_reg(cpu, WHvX64RegisterRip, reg);
}
@@ -909,13 +908,23 @@ static int whpx_handle_portio(CPUState *cpu,
} else {
reg.Reg64 = (uint64_t)val;
}
- whpx_bump_rip(cpu, exit_ctx);
- whpx_set_reg(cpu, WHvX64RegisterRax, reg);
+ /* vmport calls cpu_synchronize_state on an I/O port read */
+ if (!cpu->vcpu_dirty) {
+ whpx_bump_rip(cpu, exit_ctx);
+ whpx_set_reg(cpu, WHvX64RegisterRax, reg);
+ } else {
+ env->eip = exit_ctx->VpContext.Rip + exit_ctx->VpContext.InstructionLength;
+ env->regs[R_EAX] = reg.Reg64;
+ }
return 0;
} else if (!ctx->AccessInfo.StringOp && ctx->AccessInfo.IsWrite) {
RAX(env) = ctx->Rax;
handle_io(cpu, ctx->PortNumber, &RAX(env), 1, ctx->AccessInfo.AccessSize, 1);
- whpx_bump_rip(cpu, exit_ctx);
+ if (!cpu->vcpu_dirty) {
+ whpx_bump_rip(cpu, exit_ctx);
+ } else {
+ env->eip = exit_ctx->VpContext.Rip + exit_ctx->VpContext.InstructionLength;
+ }
return 0;
}