MSHV today lacks an immediate-exit API. QEMU tehre kicks a vCPU by sending SIG_IPI to interrupt an active MSHV_VP_RUN ioctl invocation.
The generic kick path suppresses repeat signals using CPUState::thread_kicked, which is cleared when we return to the the outer vCPU loop (in mshv_vcpu_thread()). MSHV cannot guarantee that a signal will cause sucha return: it may be handled between MSHV_VP_RUN calls or MSHV_RUN_VP may return an unrelated intercept instead of EINTR. Hence we install an MSHV-specific kick impl that sends SIG_IPI for every requested vCPU kick. Signed-off-by: Magnus Kulke <[email protected]> --- accel/mshv/mshv-all.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index 7289c8d1c2..0f733cac9d 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -888,6 +888,24 @@ static void mshv_start_vcpu_thread(CPUState *cpu) QEMU_THREAD_JOINABLE); } +static void mshv_kick_vcpu_thread(CPUState *cpu) +{ + int err; + + /* don't kick ourselves, we are already running */ + if (qemu_cpu_is_self(cpu)) { + return; + } + + err = pthread_kill(cpu->thread->thread, SIG_IPI); + /* in case the vcpu thread has been torn down we don't want to abort */ + if (err && err != ESRCH) { + error_report("failed to kick MSHV vCPU %d: %s", + cpu->cpu_index, strerror(err)); + abort(); + } +} + static void do_mshv_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg) { @@ -996,6 +1014,7 @@ static void mshv_accel_ops_class_init(ObjectClass *oc, const void *data) AccelOpsClass *ops = ACCEL_OPS_CLASS(oc); ops->create_vcpu_thread = mshv_start_vcpu_thread; + ops->kick_vcpu_thread = mshv_kick_vcpu_thread; ops->cpu_thread_is_idle = mshv_vcpu_thread_is_idle; ops->synchronize_post_init = mshv_cpu_synchronize_post_init; ops->synchronize_post_reset = mshv_cpu_synchronize_post_reset; -- 2.34.1
