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>
---
target/i386/whpx/whpx-all.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index 7c80d653d1..61aec98e66 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -862,7 +862,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);
}
@@ -890,13 +889,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;
}
--
2.50.1 (Apple Git-155)