On 5/20/25 13:30, Magnus Kulke wrote:
+ int ret;
+ hv_message exit_msg = { 0 };
You probably don't want to fill 512 bytes on every vmentry. Maybe pass
&exit_msg up from mshv_cpu_exec()?
+ /*
+ * Read cpu->exit_request before KVM_RUN reads run->immediate_exit.
+ * Matching barrier in kvm_eat_signals.
+ */
+ smp_rmb();
The comment is obviously wrong; unfortunately, the code is wrong too:
1) qemu_cpu_kick_self() is only needed for an old KVM API. In that API
the signal handler is blocked while QEMU runs. In your case,
qemu_cpu_kick_self() is an expensive way to do nothing.
2) Because of this, there's a race condition between delivering the
signal and entering MSHV_RUN_VP
You need support in the hypervisor for this: KVM and HVF both have it.
There are two ways to do it, for both cases the hypervisor side for the
latter can be something like this:
diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
index 72df774e410a..627afece4046 100644
--- a/drivers/hv/mshv_root_main.c
+++ b/drivers/hv/mshv_root_main.c
@@ -530,7 +530,7 @@ static long mshv_run_vp_with_root_scheduler(
struct hv_output_dispatch_vp output;
ret = mshv_pre_guest_mode_work(vp);
- if (ret)
+ if (ret || vp->run.flags.immediate_exit)
break;
if (vp->run.flags.intercept_suspend)
@@ -585,6 +585,7 @@
}
} while (!vp->run.flags.intercept_suspend);
+ vp->run.flags.immediate_exit = 0;
return ret;
}
Instead of calling qemu_cpu_kick_self(), your signal handler would
invoke a new MSHV ioctl that sets vp->run.flags.immediate_exit = 1.
And then you also don't need the barrier, by the way, because all
inter-thread communication is mediated by the signal handler.
Paolo