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


Reply via email to