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>
Mohamed Mediouni committed
Apr 22, 2026 at 23:41 UTC
9d63874d67818e2e953ad26fa61d2f7760daa363
1 file changed
+13
-4
target/i386/whpx/whpx-all.c
+13
-4
@@ -881,7 +881,6 @@ static void handle_io(CPUState *env, uint16_t port, void *buffer,
881
static void whpx_bump_rip(CPUState *cpu, WHV_RUN_VP_EXIT_CONTEXT *exit_ctx)
882
{
883
WHV_REGISTER_VALUE reg;
884
- whpx_get_reg(cpu, WHvX64RegisterRip, ®);
884
reg.Reg64 = exit_ctx->VpContext.Rip + exit_ctx->VpContext.InstructionLength;
885
whpx_set_reg(cpu, WHvX64RegisterRip, reg);
886
}
@@ -909,13 +908,23 @@ static int whpx_handle_portio(CPUState *cpu,
908
} else {
909
reg.Reg64 = (uint64_t)val;
910
}
912
- whpx_bump_rip(cpu, exit_ctx);
913
- whpx_set_reg(cpu, WHvX64RegisterRax, reg);
911
+ /* vmport calls cpu_synchronize_state on an I/O port read */
912
+ if (!cpu->vcpu_dirty) {
913
+ whpx_bump_rip(cpu, exit_ctx);
914
+ whpx_set_reg(cpu, WHvX64RegisterRax, reg);
915
+ } else {
916
+ env->eip = exit_ctx->VpContext.Rip + exit_ctx->VpContext.InstructionLength;
917
+ env->regs[R_EAX] = reg.Reg64;
918
+ }
919
return 0;
920
} else if (!ctx->AccessInfo.StringOp && ctx->AccessInfo.IsWrite) {
921
RAX(env) = ctx->Rax;
922
handle_io(cpu, ctx->PortNumber, &RAX(env), 1, ctx->AccessInfo.AccessSize, 1);
918
- whpx_bump_rip(cpu, exit_ctx);
923
+ if (!cpu->vcpu_dirty) {
924
+ whpx_bump_rip(cpu, exit_ctx);
925
+ } else {
926
+ env->eip = exit_ctx->VpContext.Rip + exit_ctx->VpContext.InstructionLength;
927
+ }
928
return 0;
929
}
930