diff --git a/cpus.c b/cpus.c index e916137dbf..7b9f8eb1e7 100644 --- a/cpus.c +++ b/cpus.c @@ -1213,3 +1213,16 @@ void qmp_pmemsave(int64_t addr, int64_t size, const char *filename, exit: fclose(f); } + +void qmp_inject_nmi(Error **errp) +{ +#if defined(TARGET_I386) + CPUState *env; + + for (env = first_cpu; env != NULL; env = env->next_cpu) { + cpu_interrupt(env, CPU_INTERRUPT_NMI); + } +#else + error_set(errp, QERR_UNSUPPORTED); +#endif +} diff --git a/hmp-commands.hx b/hmp-commands.hx index 950375164e..b82aff8d3b 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -736,8 +736,7 @@ ETEXI .args_type = "", .params = "", .help = "inject an NMI on all guest's CPUs", - .user_print = monitor_user_noop, - .mhandler.cmd_new = do_inject_nmi, + .mhandler.cmd = hmp_inject_nmi, }, #endif STEXI diff --git a/hmp.c b/hmp.c index d6235269b0..0ebc398335 100644 --- a/hmp.c +++ b/hmp.c @@ -593,3 +593,11 @@ void hmp_cont(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, &errp); } } + +void hmp_inject_nmi(Monitor *mon, const QDict *qdict) +{ + Error *errp = NULL; + + qmp_inject_nmi(&errp); + hmp_handle_error(mon, &errp); +} diff --git a/hmp.h b/hmp.h index b0347047b4..8a31f8710a 100644 --- a/hmp.h +++ b/hmp.h @@ -40,5 +40,6 @@ void hmp_cpu(Monitor *mon, const QDict *qdict); void hmp_memsave(Monitor *mon, const QDict *qdict); void hmp_pmemsave(Monitor *mon, const QDict *qdict); void hmp_cont(Monitor *mon, const QDict *qdict); +void hmp_inject_nmi(Monitor *mon, const QDict *qdict); #endif diff --git a/monitor.c b/monitor.c index b0d1862de8..62b17475a7 100644 --- a/monitor.c +++ b/monitor.c @@ -2204,25 +2204,6 @@ static void do_wav_capture(Monitor *mon, const QDict *qdict) } #endif -#if defined(TARGET_I386) -static int do_inject_nmi(Monitor *mon, const QDict *qdict, QObject **ret_data) -{ - CPUState *env; - - for (env = first_cpu; env != NULL; env = env->next_cpu) { - cpu_interrupt(env, CPU_INTERRUPT_NMI); - } - - return 0; -} -#else -static int do_inject_nmi(Monitor *mon, const QDict *qdict, QObject **ret_data) -{ - qerror_report(QERR_UNSUPPORTED); - return -1; -} -#endif - static qemu_acl *find_acl(Monitor *mon, const char *name) { qemu_acl *acl = qemu_acl_find(name); diff --git a/qapi-schema.json b/qapi-schema.json index b6fd3f1d35..fea513fc76 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -966,3 +966,16 @@ ## { 'command': 'cont' } +## +# @inject-nmi: +# +# Injects an Non-Maskable Interrupt into all guest's VCPUs. +# +# Returns: If successful, nothing +# If the Virtual Machine doesn't support NMI injection, Unsupported +# +# Since: 0.14.0 +# +# Notes: Only x86 Virtual Machines support this command. +## +{ 'command': 'inject-nmi' } diff --git a/qmp-commands.hx b/qmp-commands.hx index 03b261710c..2e7670815a 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -407,10 +407,7 @@ EQMP { .name = "inject-nmi", .args_type = "", - .params = "", - .help = "", - .user_print = monitor_user_noop, - .mhandler.cmd_new = do_inject_nmi, + .mhandler.cmd_new = qmp_marshal_input_inject_nmi, }, SQMP