@samitouri / QOSamiQemu / commits / 9d63874d67

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, &reg);
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