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);
     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;
     }