* [PATCH v4 0/7] hw/nmi: Disconnect of vCPU and disentangle Monitor code
@ 2026-08-11 15:49 Philippe Mathieu-Daudé
2026-08-11 15:49 ` [PATCH v4 1/7] hw/nmi: Use object_child_foreach_recursive() in nmi_children() Philippe Mathieu-Daudé
` (7 more replies)
0 siblings, 8 replies; 14+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-11 15:49 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-ppc, Peter Maydell, Markus Armbruster,
Marc-André Lureau, qemu-s390x, Thomas Huth, Corey Minyard,
Philippe Mathieu-Daudé
Since v3:
- Rename trigger -> inject (API entry point)
- Rename deliver -> raise (machine-specific handler)
- Do not mention 'cpu' in HMP doc
Cover:
- Have s390x always deliver NMI to the first CPU.
- Remove the @cpu_index / @errp arguments from handler.
- Rename API as nmi_trigger() (since not monitor specific).
- Only deliver NMI once
Rationale described by Peter in v1 [*]:
> The current hw/core/nmi.c code is a bit odd because it's partly
> working with a cpu_index and partly not: the code passes cpu_index
> around, but in practice for the QMP command the user can't set
> which CPU to operate on, and for everything except s390 the
> implementation doesn't care anyway. My impression from the IRC
> discussion is that it's not really necessary for the S390 that
> the monitor user be able to specify which CPU to NMI (and in any
> case you can only do that from the HMP command, not the QMP
> command, AIUI), so getting rid of that weird inconsistency makes
> sense to me: and that's what this patchset is doing.
[*] https://lore.kernel.org/qemu-devel/CAFEAcA_0qUFW0MewHC+v+pSOisE-kQDt9Wv4F3RafEkyQ0DGJA@mail.gmail.com/:
Philippe Mathieu-Daudé (7):
hw/nmi: Use object_child_foreach_recursive() in nmi_children()
hw/s390x/virtio-ccw: Always inject NMI to first CPU
hw/nmi: Remove @cpu_index argument from
NMIClass::nmi_monitor_handler()
hw/nmi: Remove @cpu_index argument from nmi_inject()
hw/nmi: Rename nmi_monitor_handler() -> raise_nmi()
hw/nmi: Remove unused @errp argument from raise_nmi()
hw/nmi: Raise NMI line only once
qapi/machine.json | 7 +++---
qapi/run-state.json | 6 +++--
include/hw/core/nmi.h | 34 +++++++++++++++++++++++++--
hw/core/nmi.c | 48 +++++++++++---------------------------
hw/hppa/machine.c | 4 ++--
hw/i386/x86.c | 4 ++--
hw/intc/m68k_irqc.c | 4 ++--
hw/ipmi/ipmi.c | 3 +--
hw/m68k/q800-glue.c | 4 ++--
hw/misc/macio/gpio.c | 4 ++--
hw/ppc/pnv.c | 4 ++--
hw/ppc/spapr.c | 4 ++--
hw/s390x/s390-virtio-ccw.c | 8 +++----
hw/watchdog/watchdog.c | 2 +-
system/cpus.c | 2 +-
hmp-commands.hx | 7 +++---
16 files changed, 78 insertions(+), 67 deletions(-)
--
2.53.0
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v4 1/7] hw/nmi: Use object_child_foreach_recursive() in nmi_children()
2026-08-11 15:49 [PATCH v4 0/7] hw/nmi: Disconnect of vCPU and disentangle Monitor code Philippe Mathieu-Daudé
@ 2026-08-11 15:49 ` Philippe Mathieu-Daudé
2026-08-11 15:49 ` [PATCH v4 2/7] hw/s390x/virtio-ccw: Always inject NMI to first CPU Philippe Mathieu-Daudé
` (6 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-11 15:49 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-ppc, Peter Maydell, Markus Armbruster,
Marc-André Lureau, qemu-s390x, Thomas Huth, Corey Minyard,
Philippe Mathieu-Daudé, Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Replace object_child_foreach() and recursion by a single
object_child_foreach_recursive() call.
Propagate the returned value so callers can check it.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
hw/core/nmi.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/hw/core/nmi.c b/hw/core/nmi.c
index 4b447e126ba..22724046575 100644
--- a/hw/core/nmi.c
+++ b/hw/core/nmi.c
@@ -31,8 +31,6 @@ struct do_nmi_s {
bool handled;
};
-static void nmi_children(Object *o, struct do_nmi_s *ns);
-
static int do_nmi(Object *o, void *opaque)
{
struct do_nmi_s *ns = opaque;
@@ -47,14 +45,13 @@ static int do_nmi(Object *o, void *opaque)
return -1;
}
}
- nmi_children(o, ns);
return 0;
}
-static void nmi_children(Object *o, struct do_nmi_s *ns)
+static int nmi_children(Object *o, struct do_nmi_s *ns)
{
- object_child_foreach(o, do_nmi, ns);
+ return object_child_foreach_recursive(o, do_nmi, ns);
}
void nmi_monitor_handle(int cpu_index, Error **errp)
@@ -65,10 +62,9 @@ void nmi_monitor_handle(int cpu_index, Error **errp)
.handled = false
};
- nmi_children(object_get_root(), &ns);
- if (ns.handled) {
+ if (nmi_children(object_get_root(), &ns)) {
error_propagate(errp, ns.err);
- } else {
+ } else if (!ns.handled) {
error_setg(errp, "machine does not provide NMIs");
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v4 2/7] hw/s390x/virtio-ccw: Always inject NMI to first CPU
2026-08-11 15:49 [PATCH v4 0/7] hw/nmi: Disconnect of vCPU and disentangle Monitor code Philippe Mathieu-Daudé
2026-08-11 15:49 ` [PATCH v4 1/7] hw/nmi: Use object_child_foreach_recursive() in nmi_children() Philippe Mathieu-Daudé
@ 2026-08-11 15:49 ` Philippe Mathieu-Daudé
2026-08-11 20:53 ` Eric Farman
2026-08-12 12:28 ` Cornelia Huck
2026-08-11 15:49 ` [PATCH v4 3/7] hw/nmi: Remove @cpu_index argument from NMIClass::nmi_monitor_handler() Philippe Mathieu-Daudé
` (5 subsequent siblings)
7 siblings, 2 replies; 14+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-11 15:49 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-ppc, Peter Maydell, Markus Armbruster,
Marc-André Lureau, qemu-s390x, Thomas Huth, Corey Minyard,
Philippe Mathieu-Daudé, David Hildenbrand,
Philippe Mathieu-Daudé, Dr. David Alan Gilbert, Halil Pasic,
Christian Borntraeger, Eric Farman, Matthew Rosato, Cornelia Huck,
Richard Henderson, Ilya Leoshkevich, David Hildenbrand,
Eric Blake, Philippe Mathieu-Daudé, Zhao Liu, Paolo Bonzini
From: Philippe Mathieu-Daudé <philmd@linaro.org>
We can trigger NMI from HMP or QMP.
QEMU maps the NMI to the s390x per-CPU 'RESTART' interrupt.
Linux guests usually setup this interrupt to trigger kdump
or crash. Such crashdump can be triggered in QEMU by HMP
"nmi" or QMP "inject-nmi" commands.
Using QMP, since we can not select a particular CPU, the first
CPU is used (CPU#0). See the documentation from commit 795dc6e4
("watchdog: Add new Virtual Watchdog action INJECT-NMI"):
@inject-nmi: a non-maskable interrupt is injected into the
first VCPU (all VCPUS on x86) (since 2.4)
While we can select a particular CPU on HMP, the guest behavior
is expected to be the same if using CPU #N or CPU #0. Since
always using CPU#0 simplifies API maintainance, update s390_nmi()
to inject NMI to the first CPU.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
qapi/machine.json | 7 ++++---
qapi/run-state.json | 6 ++++--
hw/s390x/s390-virtio-ccw.c | 4 +---
hmp-commands.hx | 5 +++--
4 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/qapi/machine.json b/qapi/machine.json
index 9b2248038fc..2d63c1bac3b 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -432,9 +432,10 @@
##
# @inject-nmi:
#
-# Injects a Non-Maskable Interrupt into the default CPU (x86/s390) or
-# all CPUs (ppc64). The command fails when the guest doesn't support
-# injecting.
+# Injects a Non-Maskable Interrupt (machine specific: for example on
+# s390x CCW only the first vCPU receives the NMI, but on x86 machines
+# all vCPUs receive it). The command fails when the guest doesn't
+# support injecting.
#
# Since: 0.14
#
diff --git a/qapi/run-state.json b/qapi/run-state.json
index a5771ad4681..e4fdead1e0b 100644
--- a/qapi/run-state.json
+++ b/qapi/run-state.json
@@ -317,8 +317,10 @@
#
# @none: nothing is done
#
-# @inject-nmi: a non-maskable interrupt is injected into the first
-# VCPU (all VCPUS on x86) (since 2.4)
+# @inject-nmi: a non-maskable interrupt is injected (machine
+# specific: for example on s390x CCW only the first vCPU
+# receives the NMI, but on x86 machines all vCPUs receive
+# it). (since 2.4)
#
# Since: 2.1
##
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 25a9fa49554..4f7861dbbb7 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -727,9 +727,7 @@ static HotplugHandler *s390_get_hotplug_handler(MachineState *machine,
static void s390_nmi(NMIState *n, int cpu_index, Error **errp)
{
- CPUState *cs = qemu_get_cpu(cpu_index);
-
- s390_cpu_restart(S390_CPU(cs));
+ s390_cpu_restart(S390_CPU(first_cpu));
}
static inline bool machine_get_aes_key_wrap(Object *obj, Error **errp)
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 7ae2468a3d9..a1b77ae4044 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -865,12 +865,13 @@ ERST
.name = "nmi",
.args_type = "",
.params = "",
- .help = "inject an NMI",
+ .help = "Inject an NMI, in a machine-specific way",
.cmd = hmp_nmi,
},
SRST
``nmi`` *cpu*
- Inject an NMI on the default CPU (x86/s390) or all CPUs (ppc64).
+ Inject an NMI, in a machine-specific way.
+ Not all machines implement NMI handling.
ERST
{
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v4 3/7] hw/nmi: Remove @cpu_index argument from NMIClass::nmi_monitor_handler()
2026-08-11 15:49 [PATCH v4 0/7] hw/nmi: Disconnect of vCPU and disentangle Monitor code Philippe Mathieu-Daudé
2026-08-11 15:49 ` [PATCH v4 1/7] hw/nmi: Use object_child_foreach_recursive() in nmi_children() Philippe Mathieu-Daudé
2026-08-11 15:49 ` [PATCH v4 2/7] hw/s390x/virtio-ccw: Always inject NMI to first CPU Philippe Mathieu-Daudé
@ 2026-08-11 15:49 ` Philippe Mathieu-Daudé
2026-08-11 15:49 ` [PATCH v4 4/7] hw/nmi: Remove @cpu_index argument from nmi_inject() Philippe Mathieu-Daudé
` (4 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-11 15:49 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-ppc, Peter Maydell, Markus Armbruster,
Marc-André Lureau, qemu-s390x, Thomas Huth, Corey Minyard,
Philippe Mathieu-Daudé, Philippe Mathieu-Daudé,
Richard Henderson, Helge Deller, Michael S. Tsirkin,
Paolo Bonzini, Laurent Vivier, Mark Cave-Ayland, Nicholas Piggin,
Aditya Gupta, Glenn Miles, Harsh Prateek Bora, Ilya Leoshkevich,
David Hildenbrand, Halil Pasic, Christian Borntraeger,
Eric Farman, Matthew Rosato, Cornelia Huck
From: Philippe Mathieu-Daudé <philmd@linaro.org>
Only s390x was using the 'cpu_index' argument, but since the
previous commit it isn't anymore (it use the first cpu).
Since this argument is now completely unused, remove it.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
include/hw/core/nmi.h | 8 +++++++-
hw/core/nmi.c | 2 +-
hw/hppa/machine.c | 2 +-
hw/i386/x86.c | 2 +-
hw/intc/m68k_irqc.c | 2 +-
hw/m68k/q800-glue.c | 2 +-
hw/misc/macio/gpio.c | 2 +-
hw/ppc/pnv.c | 2 +-
hw/ppc/spapr.c | 2 +-
hw/s390x/s390-virtio-ccw.c | 2 +-
10 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/include/hw/core/nmi.h b/include/hw/core/nmi.h
index fff41bebc69..4c4ce79071d 100644
--- a/include/hw/core/nmi.h
+++ b/include/hw/core/nmi.h
@@ -37,7 +37,13 @@ typedef struct NMIState NMIState;
struct NMIClass {
InterfaceClass parent_class;
- void (*nmi_monitor_handler)(NMIState *n, int cpu_index, Error **errp);
+ /**
+ * nmi_monitor_handler: Callback to handle NMI notifications.
+ *
+ * @ns: Class #NMIState state
+ * @errp: pointer to error object
+ */
+ void (*nmi_monitor_handler)(NMIState *ns, Error **errp);
};
void nmi_monitor_handle(int cpu_index, Error **errp);
diff --git a/hw/core/nmi.c b/hw/core/nmi.c
index 22724046575..ff6454437c1 100644
--- a/hw/core/nmi.c
+++ b/hw/core/nmi.c
@@ -40,7 +40,7 @@ static int do_nmi(Object *o, void *opaque)
NMIClass *nc = NMI_GET_CLASS(n);
ns->handled = true;
- nc->nmi_monitor_handler(n, ns->cpu_index, &ns->err);
+ nc->nmi_monitor_handler(n, &ns->err);
if (ns->err) {
return -1;
}
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index d762163ddf5..2b44debc388 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -829,7 +829,7 @@ static void hppa_machine_reset(MachineState *ms, ResetType type)
cpu[0]->env.cmdline_or_bootorder = 'c';
}
-static void hppa_nmi(NMIState *n, int cpu_index, Error **errp)
+static void hppa_nmi(NMIState *ns, Error **errp)
{
CPUState *cs;
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index dc7f0d56b01..0ea5453403d 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -147,7 +147,7 @@ static const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms)
return ms->possible_cpus;
}
-static void x86_nmi(NMIState *n, int cpu_index, Error **errp)
+static void x86_nmi(NMIState *ns, Error **errp)
{
/* cpu index isn't used */
CPUState *cs;
diff --git a/hw/intc/m68k_irqc.c b/hw/intc/m68k_irqc.c
index 68ddb5351be..bc41b44d455 100644
--- a/hw/intc/m68k_irqc.c
+++ b/hw/intc/m68k_irqc.c
@@ -70,7 +70,7 @@ static void m68k_irqc_instance_init(Object *obj)
qdev_init_gpio_in(DEVICE(obj), m68k_set_irq, M68K_IRQC_LEVEL_NUM);
}
-static void m68k_nmi(NMIState *n, int cpu_index, Error **errp)
+static void m68k_nmi(NMIState *n, Error **errp)
{
m68k_set_irq(n, M68K_IRQC_LEVEL_7, 1);
}
diff --git a/hw/m68k/q800-glue.c b/hw/m68k/q800-glue.c
index ac9062c6488..b13e5ef95f1 100644
--- a/hw/m68k/q800-glue.c
+++ b/hw/m68k/q800-glue.c
@@ -159,7 +159,7 @@ static void glue_auxmode_set_irq(void *opaque, int irq, int level)
s->auxmode = level;
}
-static void glue_nmi(NMIState *n, int cpu_index, Error **errp)
+static void glue_nmi(NMIState *n, Error **errp)
{
GLUEState *s = GLUE(n);
diff --git a/hw/misc/macio/gpio.c b/hw/misc/macio/gpio.c
index 1a7c534d652..1bdca728f97 100644
--- a/hw/misc/macio/gpio.c
+++ b/hw/misc/macio/gpio.c
@@ -188,7 +188,7 @@ static void macio_gpio_reset(DeviceState *dev)
macio_set_gpio(s, 1, true);
}
-static void macio_gpio_nmi(NMIState *n, int cpu_index, Error **errp)
+static void macio_gpio_nmi(NMIState *n, Error **errp)
{
macio_set_gpio(MACIO_GPIO(n), 9, true);
macio_set_gpio(MACIO_GPIO(n), 9, false);
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index c0cb45dbfbc..8676be7bbb1 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -3552,7 +3552,7 @@ static void pnv_cpu_do_nmi(PnvChip *chip, PowerPCCPU *cpu, void *opaque)
async_run_on_cpu(CPU(cpu), pnv_cpu_do_nmi_on_cpu, RUN_ON_CPU_HOST_INT(0));
}
-static void pnv_nmi(NMIState *n, int cpu_index, Error **errp)
+static void pnv_nmi(NMIState *ns, Error **errp)
{
PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
int i;
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index b79828b4e90..189334b9f0a 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3550,7 +3550,7 @@ void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg)
}
}
-static void spapr_nmi(NMIState *n, int cpu_index, Error **errp)
+static void spapr_nmi(NMIState *ns, Error **errp)
{
CPUState *cs;
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 4f7861dbbb7..5d8a73a63df 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -725,7 +725,7 @@ static HotplugHandler *s390_get_hotplug_handler(MachineState *machine,
return NULL;
}
-static void s390_nmi(NMIState *n, int cpu_index, Error **errp)
+static void s390_nmi(NMIState *ns, Error **errp)
{
s390_cpu_restart(S390_CPU(first_cpu));
}
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v4 4/7] hw/nmi: Remove @cpu_index argument from nmi_inject()
2026-08-11 15:49 [PATCH v4 0/7] hw/nmi: Disconnect of vCPU and disentangle Monitor code Philippe Mathieu-Daudé
` (2 preceding siblings ...)
2026-08-11 15:49 ` [PATCH v4 3/7] hw/nmi: Remove @cpu_index argument from NMIClass::nmi_monitor_handler() Philippe Mathieu-Daudé
@ 2026-08-11 15:49 ` Philippe Mathieu-Daudé
2026-08-11 16:38 ` Peter Maydell
2026-08-12 8:51 ` Philippe Mathieu-Daudé
2026-08-11 15:49 ` [PATCH v4 5/7] hw/nmi: Rename nmi_monitor_handler() -> raise_nmi() Philippe Mathieu-Daudé
` (3 subsequent siblings)
7 siblings, 2 replies; 14+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-11 15:49 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-ppc, Peter Maydell, Markus Armbruster,
Marc-André Lureau, qemu-s390x, Thomas Huth, Corey Minyard,
Philippe Mathieu-Daudé, Philippe Mathieu-Daudé,
Dr. David Alan Gilbert, Richard Henderson, Paolo Bonzini,
Philippe Mathieu-Daudé
From: Philippe Mathieu-Daudé <philmd@linaro.org>
nmi_monitor_handle() is not related to the monitor, rename
it as nmi_inject().
Return a boolean value indicating success / failure as
recommended by the Error API since commit e3fe3988d7
("error: Document Error API usage rules").
The 'cpu_index' argument is not used, remove it.
This officially drops the current CPU for HMP command.
Document nmi_inject() as suggested by Peter Maydell in
https://lore.kernel.org/qemu-devel/CAFEAcA-yALySmCJLbitCmYpiZKUXJNOavGJG9RYeo8fKqz7gcw@mail.gmail.com/.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
include/hw/core/nmi.h | 25 ++++++++++++++++++++++++-
hw/core/nmi.c | 9 ++++-----
hw/ipmi/ipmi.c | 3 +--
hw/watchdog/watchdog.c | 2 +-
system/cpus.c | 2 +-
hmp-commands.hx | 2 +-
6 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/include/hw/core/nmi.h b/include/hw/core/nmi.h
index 4c4ce79071d..2ff5be1e214 100644
--- a/include/hw/core/nmi.h
+++ b/include/hw/core/nmi.h
@@ -46,6 +46,29 @@ struct NMIClass {
void (*nmi_monitor_handler)(NMIState *ns, Error **errp);
};
-void nmi_monitor_handle(int cpu_index, Error **errp);
+/**
+ * nmi_inject: Inject an NMI, in a machine-specific way
+ * @errp: pointer to error object
+ *
+ * This function injects an NMI, in a machine-specific way. The
+ * intention is that this should typically trigger a guest kernel
+ * dump or reboot, and might happen as a result of user request
+ * from the monitor, watchdog timeouts, and similar events.
+ * (For example on the x86 PC it triggers an NMI on all CPUs,
+ * and on s390 it triggers the RESTART interrupt on the first CPU.)
+ *
+ * The NMI is injected by looking for QOM objects which
+ * implement the TYPE_NMI interface, and calling their nmi_monitor_handler
+ * method. Usually it is the machine model class that implements
+ * this interface.
+ *
+ * Not all machines implement NMI handling; this function
+ * will return an error if used on a machine which does not
+ * implement NMIs.
+ *
+ * On success, return %true.
+ * On failure, store an error through @errp and return %false.
+ */
+bool nmi_inject(Error **errp);
#endif /* NMI_H */
diff --git a/hw/core/nmi.c b/hw/core/nmi.c
index ff6454437c1..2d890f2995d 100644
--- a/hw/core/nmi.c
+++ b/hw/core/nmi.c
@@ -22,11 +22,8 @@
#include "qemu/osdep.h"
#include "hw/core/nmi.h"
#include "qapi/error.h"
-#include "qemu/module.h"
-#include "monitor/monitor.h"
struct do_nmi_s {
- int cpu_index;
Error *err;
bool handled;
};
@@ -54,19 +51,21 @@ static int nmi_children(Object *o, struct do_nmi_s *ns)
return object_child_foreach_recursive(o, do_nmi, ns);
}
-void nmi_monitor_handle(int cpu_index, Error **errp)
+bool nmi_inject(Error **errp)
{
struct do_nmi_s ns = {
- .cpu_index = cpu_index,
.err = NULL,
.handled = false
};
if (nmi_children(object_get_root(), &ns)) {
error_propagate(errp, ns.err);
+ return false;
} else if (!ns.handled) {
error_setg(errp, "machine does not provide NMIs");
+ return false;
}
+ return true;
}
static const TypeInfo nmi_info = {
diff --git a/hw/ipmi/ipmi.c b/hw/ipmi/ipmi.c
index 74818ff3cea..dedf23cb997 100644
--- a/hw/ipmi/ipmi.c
+++ b/hw/ipmi/ipmi.c
@@ -59,8 +59,7 @@ static int ipmi_do_hw_op(IPMIInterface *s, enum ipmi_op op, int checkonly)
if (checkonly) {
return 0;
}
- /* We don't care what CPU we use. */
- nmi_monitor_handle(0, NULL);
+ nmi_inject(NULL);
return 0;
case IPMI_SHUTDOWN_VIA_ACPI_OVERTEMP:
diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c
index 0842fe373ae..5f764a0c1b8 100644
--- a/hw/watchdog/watchdog.c
+++ b/hw/watchdog/watchdog.c
@@ -81,7 +81,7 @@ void watchdog_perform_action(void)
case WATCHDOG_ACTION_INJECT_NMI:
qapi_event_send_watchdog(WATCHDOG_ACTION_INJECT_NMI);
- nmi_monitor_handle(0, NULL);
+ nmi_inject(NULL);
break;
default:
diff --git a/system/cpus.c b/system/cpus.c
index 97e5a5edee2..04809698de4 100644
--- a/system/cpus.c
+++ b/system/cpus.c
@@ -926,6 +926,6 @@ exit:
void qmp_inject_nmi(Error **errp)
{
- nmi_monitor_handle(monitor_get_cpu_index(monitor_cur()), errp);
+ nmi_inject(errp);
}
diff --git a/hmp-commands.hx b/hmp-commands.hx
index a1b77ae4044..b21f361ada0 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -869,7 +869,7 @@ ERST
.cmd = hmp_nmi,
},
SRST
-``nmi`` *cpu*
+``nmi``
Inject an NMI, in a machine-specific way.
Not all machines implement NMI handling.
ERST
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v4 5/7] hw/nmi: Rename nmi_monitor_handler() -> raise_nmi()
2026-08-11 15:49 [PATCH v4 0/7] hw/nmi: Disconnect of vCPU and disentangle Monitor code Philippe Mathieu-Daudé
` (3 preceding siblings ...)
2026-08-11 15:49 ` [PATCH v4 4/7] hw/nmi: Remove @cpu_index argument from nmi_inject() Philippe Mathieu-Daudé
@ 2026-08-11 15:49 ` Philippe Mathieu-Daudé
2026-08-11 15:49 ` [PATCH v4 6/7] hw/nmi: Remove unused @errp argument from raise_nmi() Philippe Mathieu-Daudé
` (2 subsequent siblings)
7 siblings, 0 replies; 14+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-11 15:49 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-ppc, Peter Maydell, Markus Armbruster,
Marc-André Lureau, qemu-s390x, Thomas Huth, Corey Minyard,
Philippe Mathieu-Daudé, Richard Henderson, Helge Deller,
Michael S. Tsirkin, Paolo Bonzini, Laurent Vivier,
Mark Cave-Ayland, Nicholas Piggin, Aditya Gupta, Glenn Miles,
Harsh Prateek Bora, Ilya Leoshkevich, David Hildenbrand,
Halil Pasic, Christian Borntraeger, Eric Farman, Matthew Rosato,
Cornelia Huck
nmi_monitor_handler() is not related to the monitor,
rename it as raise_nmi().
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
include/hw/core/nmi.h | 10 ++++++----
hw/core/nmi.c | 2 +-
hw/hppa/machine.c | 2 +-
hw/i386/x86.c | 2 +-
hw/intc/m68k_irqc.c | 2 +-
hw/m68k/q800-glue.c | 2 +-
hw/misc/macio/gpio.c | 2 +-
hw/ppc/pnv.c | 2 +-
hw/ppc/spapr.c | 2 +-
hw/s390x/s390-virtio-ccw.c | 2 +-
10 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/include/hw/core/nmi.h b/include/hw/core/nmi.h
index 2ff5be1e214..1ba6f393449 100644
--- a/include/hw/core/nmi.h
+++ b/include/hw/core/nmi.h
@@ -38,12 +38,14 @@ struct NMIClass {
InterfaceClass parent_class;
/**
- * nmi_monitor_handler: Callback to handle NMI notifications.
- *
+ * raise_nmi: Callback to handle NMI notifications.
* @ns: Class #NMIState state
* @errp: pointer to error object
+ *
+ * Called by nmi_inject() to perform the machine-specific
+ * action when a NMI is requested.
*/
- void (*nmi_monitor_handler)(NMIState *ns, Error **errp);
+ void (*raise_nmi)(NMIState *ns, Error **errp);
};
/**
@@ -58,7 +60,7 @@ struct NMIClass {
* and on s390 it triggers the RESTART interrupt on the first CPU.)
*
* The NMI is injected by looking for QOM objects which
- * implement the TYPE_NMI interface, and calling their nmi_monitor_handler
+ * implement the TYPE_NMI interface, and calling their raise_nmi
* method. Usually it is the machine model class that implements
* this interface.
*
diff --git a/hw/core/nmi.c b/hw/core/nmi.c
index 2d890f2995d..a6edf4fbf01 100644
--- a/hw/core/nmi.c
+++ b/hw/core/nmi.c
@@ -37,7 +37,7 @@ static int do_nmi(Object *o, void *opaque)
NMIClass *nc = NMI_GET_CLASS(n);
ns->handled = true;
- nc->nmi_monitor_handler(n, &ns->err);
+ nc->raise_nmi(n, &ns->err);
if (ns->err) {
return -1;
}
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index 2b44debc388..717cfde61da 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -851,7 +851,7 @@ static void hppa_machine_common_class_init(ObjectClass *oc, const void *data)
mc->default_ram_id = "hppa.ram";
mc->default_nic = "tulip";
- nc->nmi_monitor_handler = hppa_nmi;
+ nc->raise_nmi = hppa_nmi;
}
static void HP_B160L_machine_init_class_init(ObjectClass *oc, const void *data)
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 0ea5453403d..d1414ff63db 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -389,7 +389,7 @@ static void x86_machine_class_init(ObjectClass *oc, const void *data)
mc->get_default_cpu_node_id = x86_get_default_cpu_node_id;
mc->possible_cpu_arch_ids = x86_possible_cpu_arch_ids;
mc->kvm_type = x86_kvm_type;
- nc->nmi_monitor_handler = x86_nmi;
+ nc->raise_nmi = x86_nmi;
object_class_property_add(oc, X86_MACHINE_SMM, "OnOffAuto",
x86_machine_get_smm, x86_machine_set_smm,
diff --git a/hw/intc/m68k_irqc.c b/hw/intc/m68k_irqc.c
index bc41b44d455..29f758dafd1 100644
--- a/hw/intc/m68k_irqc.c
+++ b/hw/intc/m68k_irqc.c
@@ -97,7 +97,7 @@ static void m68k_irqc_class_init(ObjectClass *oc, const void *data)
InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(oc);
device_class_set_props(dc, m68k_irqc_properties);
- nc->nmi_monitor_handler = m68k_nmi;
+ nc->raise_nmi = m68k_nmi;
device_class_set_legacy_reset(dc, m68k_irqc_reset);
dc->vmsd = &vmstate_m68k_irqc;
ic->get_statistics = m68k_irqc_get_statistics;
diff --git a/hw/m68k/q800-glue.c b/hw/m68k/q800-glue.c
index b13e5ef95f1..265af90a8e6 100644
--- a/hw/m68k/q800-glue.c
+++ b/hw/m68k/q800-glue.c
@@ -237,7 +237,7 @@ static void glue_class_init(ObjectClass *klass, const void *data)
dc->vmsd = &vmstate_glue;
device_class_set_props(dc, glue_properties);
rc->phases.hold = glue_reset_hold;
- nc->nmi_monitor_handler = glue_nmi;
+ nc->raise_nmi = glue_nmi;
}
static const TypeInfo glue_info_types[] = {
diff --git a/hw/misc/macio/gpio.c b/hw/misc/macio/gpio.c
index 1bdca728f97..db0c4ecb3cf 100644
--- a/hw/misc/macio/gpio.c
+++ b/hw/misc/macio/gpio.c
@@ -201,7 +201,7 @@ static void macio_gpio_class_init(ObjectClass *oc, const void *data)
device_class_set_legacy_reset(dc, macio_gpio_reset);
dc->vmsd = &vmstate_macio_gpio;
- nc->nmi_monitor_handler = macio_gpio_nmi;
+ nc->raise_nmi = macio_gpio_nmi;
}
static const TypeInfo macio_gpio_init_info = {
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 8676be7bbb1..a9f74245866 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -3583,7 +3583,7 @@ static void pnv_machine_class_init(ObjectClass *oc, const void *data)
mc->default_ram_size = 1 * GiB;
mc->default_ram_id = "pnv.ram";
ispc->print_info = pnv_pic_print_info;
- nc->nmi_monitor_handler = pnv_nmi;
+ nc->raise_nmi = pnv_nmi;
object_class_property_add_bool(oc, "hb-mode",
pnv_machine_get_hb, pnv_machine_set_hb);
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 189334b9f0a..ad571481c44 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4652,7 +4652,7 @@ static void spapr_machine_class_init(ObjectClass *oc, const void *data)
mc->nvdimm_supported = true;
smc->resize_hpt_default = SPAPR_RESIZE_HPT_ENABLED;
fwc->get_dev_path = spapr_get_fw_dev_path;
- nc->nmi_monitor_handler = spapr_nmi;
+ nc->raise_nmi = spapr_nmi;
vhc->cpu_in_nested = spapr_cpu_in_nested;
vhc->deliver_hv_excp = spapr_exit_nested;
vhc->hypercall = emulate_spapr_hypercall;
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 5d8a73a63df..a59346a2120 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -830,7 +830,7 @@ static void ccw_machine_class_init(ObjectClass *oc, const void *data)
hc->plug = s390_machine_device_plug;
hc->unplug_request = s390_machine_device_unplug_request;
hc->unplug = s390_machine_device_unplug;
- nc->nmi_monitor_handler = s390_nmi;
+ nc->raise_nmi = s390_nmi;
mc->default_ram_id = "s390.ram";
mc->default_nic = "virtio-net-ccw";
dsi->qmp_dump_skeys = s390_qmp_dump_skeys;
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v4 6/7] hw/nmi: Remove unused @errp argument from raise_nmi()
2026-08-11 15:49 [PATCH v4 0/7] hw/nmi: Disconnect of vCPU and disentangle Monitor code Philippe Mathieu-Daudé
` (4 preceding siblings ...)
2026-08-11 15:49 ` [PATCH v4 5/7] hw/nmi: Rename nmi_monitor_handler() -> raise_nmi() Philippe Mathieu-Daudé
@ 2026-08-11 15:49 ` Philippe Mathieu-Daudé
2026-08-11 16:34 ` Peter Maydell
2026-08-11 15:49 ` [PATCH v4 7/7] hw/nmi: Raise NMI line only once Philippe Mathieu-Daudé
2026-08-11 18:40 ` [PATCH v4 0/7] hw/nmi: Disconnect of vCPU and disentangle Monitor code marcandre.lureau
7 siblings, 1 reply; 14+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-11 15:49 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-ppc, Peter Maydell, Markus Armbruster,
Marc-André Lureau, qemu-s390x, Thomas Huth, Corey Minyard,
Philippe Mathieu-Daudé, Richard Henderson, Helge Deller,
Michael S. Tsirkin, Paolo Bonzini, Laurent Vivier,
Mark Cave-Ayland, Nicholas Piggin, Aditya Gupta, Glenn Miles,
Harsh Prateek Bora, Ilya Leoshkevich, David Hildenbrand,
Halil Pasic, Christian Borntraeger, Eric Farman, Matthew Rosato,
Cornelia Huck
Not a single handler update @errp. The single user is
nmi_inject() filling with "machine does not provide NMIs".
Remove the unused argument from the raise_nmi() callback,
simplifying the methods in hw/core/nmi.c.
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
include/hw/core/nmi.h | 3 +--
hw/core/nmi.c | 32 ++++++--------------------------
hw/hppa/machine.c | 2 +-
hw/i386/x86.c | 2 +-
hw/intc/m68k_irqc.c | 2 +-
hw/m68k/q800-glue.c | 2 +-
hw/misc/macio/gpio.c | 2 +-
hw/ppc/pnv.c | 2 +-
hw/ppc/spapr.c | 2 +-
hw/s390x/s390-virtio-ccw.c | 2 +-
10 files changed, 15 insertions(+), 36 deletions(-)
diff --git a/include/hw/core/nmi.h b/include/hw/core/nmi.h
index 1ba6f393449..d900d85e40c 100644
--- a/include/hw/core/nmi.h
+++ b/include/hw/core/nmi.h
@@ -40,12 +40,11 @@ struct NMIClass {
/**
* raise_nmi: Callback to handle NMI notifications.
* @ns: Class #NMIState state
- * @errp: pointer to error object
*
* Called by nmi_inject() to perform the machine-specific
* action when a NMI is requested.
*/
- void (*raise_nmi)(NMIState *ns, Error **errp);
+ void (*raise_nmi)(NMIState *ns);
};
/**
diff --git a/hw/core/nmi.c b/hw/core/nmi.c
index a6edf4fbf01..c44b0cf892d 100644
--- a/hw/core/nmi.c
+++ b/hw/core/nmi.c
@@ -23,45 +23,25 @@
#include "hw/core/nmi.h"
#include "qapi/error.h"
-struct do_nmi_s {
- Error *err;
- bool handled;
-};
-
static int do_nmi(Object *o, void *opaque)
{
- struct do_nmi_s *ns = opaque;
+ bool *handled = opaque;
NMIState *n = (NMIState *) object_dynamic_cast(o, TYPE_NMI);
if (n) {
- NMIClass *nc = NMI_GET_CLASS(n);
-
- ns->handled = true;
- nc->raise_nmi(n, &ns->err);
- if (ns->err) {
- return -1;
- }
+ *handled = true;
+ NMI_GET_CLASS(n)->raise_nmi(n);
}
return 0;
}
-static int nmi_children(Object *o, struct do_nmi_s *ns)
-{
- return object_child_foreach_recursive(o, do_nmi, ns);
-}
-
bool nmi_inject(Error **errp)
{
- struct do_nmi_s ns = {
- .err = NULL,
- .handled = false
- };
+ bool handled = false;
- if (nmi_children(object_get_root(), &ns)) {
- error_propagate(errp, ns.err);
- return false;
- } else if (!ns.handled) {
+ object_child_foreach_recursive(object_get_root(), do_nmi, &handled);
+ if (!handled) {
error_setg(errp, "machine does not provide NMIs");
return false;
}
diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c
index 717cfde61da..98931481b20 100644
--- a/hw/hppa/machine.c
+++ b/hw/hppa/machine.c
@@ -829,7 +829,7 @@ static void hppa_machine_reset(MachineState *ms, ResetType type)
cpu[0]->env.cmdline_or_bootorder = 'c';
}
-static void hppa_nmi(NMIState *ns, Error **errp)
+static void hppa_nmi(NMIState *ns)
{
CPUState *cs;
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index d1414ff63db..f8ba3244e22 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -147,7 +147,7 @@ static const CPUArchIdList *x86_possible_cpu_arch_ids(MachineState *ms)
return ms->possible_cpus;
}
-static void x86_nmi(NMIState *ns, Error **errp)
+static void x86_nmi(NMIState *ns)
{
/* cpu index isn't used */
CPUState *cs;
diff --git a/hw/intc/m68k_irqc.c b/hw/intc/m68k_irqc.c
index 29f758dafd1..47f626c0fa0 100644
--- a/hw/intc/m68k_irqc.c
+++ b/hw/intc/m68k_irqc.c
@@ -70,7 +70,7 @@ static void m68k_irqc_instance_init(Object *obj)
qdev_init_gpio_in(DEVICE(obj), m68k_set_irq, M68K_IRQC_LEVEL_NUM);
}
-static void m68k_nmi(NMIState *n, Error **errp)
+static void m68k_nmi(NMIState *n)
{
m68k_set_irq(n, M68K_IRQC_LEVEL_7, 1);
}
diff --git a/hw/m68k/q800-glue.c b/hw/m68k/q800-glue.c
index 265af90a8e6..223e7d9019c 100644
--- a/hw/m68k/q800-glue.c
+++ b/hw/m68k/q800-glue.c
@@ -159,7 +159,7 @@ static void glue_auxmode_set_irq(void *opaque, int irq, int level)
s->auxmode = level;
}
-static void glue_nmi(NMIState *n, Error **errp)
+static void glue_nmi(NMIState *n)
{
GLUEState *s = GLUE(n);
diff --git a/hw/misc/macio/gpio.c b/hw/misc/macio/gpio.c
index db0c4ecb3cf..ba001f7b206 100644
--- a/hw/misc/macio/gpio.c
+++ b/hw/misc/macio/gpio.c
@@ -188,7 +188,7 @@ static void macio_gpio_reset(DeviceState *dev)
macio_set_gpio(s, 1, true);
}
-static void macio_gpio_nmi(NMIState *n, Error **errp)
+static void macio_gpio_nmi(NMIState *n)
{
macio_set_gpio(MACIO_GPIO(n), 9, true);
macio_set_gpio(MACIO_GPIO(n), 9, false);
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index a9f74245866..f0413639f98 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -3552,7 +3552,7 @@ static void pnv_cpu_do_nmi(PnvChip *chip, PowerPCCPU *cpu, void *opaque)
async_run_on_cpu(CPU(cpu), pnv_cpu_do_nmi_on_cpu, RUN_ON_CPU_HOST_INT(0));
}
-static void pnv_nmi(NMIState *ns, Error **errp)
+static void pnv_nmi(NMIState *ns)
{
PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
int i;
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index ad571481c44..e0678156e73 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3550,7 +3550,7 @@ void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg)
}
}
-static void spapr_nmi(NMIState *ns, Error **errp)
+static void spapr_nmi(NMIState *ns)
{
CPUState *cs;
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index a59346a2120..c1ce7825650 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -725,7 +725,7 @@ static HotplugHandler *s390_get_hotplug_handler(MachineState *machine,
return NULL;
}
-static void s390_nmi(NMIState *ns, Error **errp)
+static void s390_nmi(NMIState *ns)
{
s390_cpu_restart(S390_CPU(first_cpu));
}
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v4 7/7] hw/nmi: Raise NMI line only once
2026-08-11 15:49 [PATCH v4 0/7] hw/nmi: Disconnect of vCPU and disentangle Monitor code Philippe Mathieu-Daudé
` (5 preceding siblings ...)
2026-08-11 15:49 ` [PATCH v4 6/7] hw/nmi: Remove unused @errp argument from raise_nmi() Philippe Mathieu-Daudé
@ 2026-08-11 15:49 ` Philippe Mathieu-Daudé
2026-08-11 18:40 ` [PATCH v4 0/7] hw/nmi: Disconnect of vCPU and disentangle Monitor code marcandre.lureau
7 siblings, 0 replies; 14+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-11 15:49 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-ppc, Peter Maydell, Markus Armbruster,
Marc-André Lureau, qemu-s390x, Thomas Huth, Corey Minyard,
Philippe Mathieu-Daudé
We only expect one device in the system to implement the
TYPE_NMI interface (typically the machine, but in a few cases
for e.g. m68k and ppc this is an interrupt controller or
similar device); so we don't need to keep walking the whole
QOM tree once we've found it. As no machine type creates more
than one object implementing TYPE_NMI, this is not a behaviour
change.
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
hw/core/nmi.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/hw/core/nmi.c b/hw/core/nmi.c
index c44b0cf892d..84f21665987 100644
--- a/hw/core/nmi.c
+++ b/hw/core/nmi.c
@@ -31,6 +31,11 @@ static int do_nmi(Object *o, void *opaque)
if (n) {
*handled = true;
NMI_GET_CLASS(n)->raise_nmi(n);
+ /*
+ * We expect only one object to implement TYPE_NMI, so once
+ * we've asked it to deliver the NMI we can stop looking.
+ */
+ return 1;
}
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v4 6/7] hw/nmi: Remove unused @errp argument from raise_nmi()
2026-08-11 15:49 ` [PATCH v4 6/7] hw/nmi: Remove unused @errp argument from raise_nmi() Philippe Mathieu-Daudé
@ 2026-08-11 16:34 ` Peter Maydell
0 siblings, 0 replies; 14+ messages in thread
From: Peter Maydell @ 2026-08-11 16:34 UTC (permalink / raw)
To: Philippe Mathieu-Daudé
Cc: qemu-devel, qemu-ppc, Markus Armbruster, Marc-André Lureau,
qemu-s390x, Thomas Huth, Corey Minyard, Richard Henderson,
Helge Deller, Michael S. Tsirkin, Paolo Bonzini, Laurent Vivier,
Mark Cave-Ayland, Nicholas Piggin, Aditya Gupta, Glenn Miles,
Harsh Prateek Bora, Ilya Leoshkevich, David Hildenbrand,
Halil Pasic, Christian Borntraeger, Eric Farman, Matthew Rosato,
Cornelia Huck
On Tue, 11 Aug 2026 at 16:50, Philippe Mathieu-Daudé
<philmd@oss.qualcomm.com> wrote:
>
> Not a single handler update @errp. The single user is
> nmi_inject() filling with "machine does not provide NMIs".
> Remove the unused argument from the raise_nmi() callback,
> simplifying the methods in hw/core/nmi.c.
>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 4/7] hw/nmi: Remove @cpu_index argument from nmi_inject()
2026-08-11 15:49 ` [PATCH v4 4/7] hw/nmi: Remove @cpu_index argument from nmi_inject() Philippe Mathieu-Daudé
@ 2026-08-11 16:38 ` Peter Maydell
2026-08-12 8:51 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 14+ messages in thread
From: Peter Maydell @ 2026-08-11 16:38 UTC (permalink / raw)
To: Philippe Mathieu-Daudé
Cc: qemu-devel, qemu-ppc, Markus Armbruster, Marc-André Lureau,
qemu-s390x, Thomas Huth, Corey Minyard,
Philippe Mathieu-Daudé, Dr. David Alan Gilbert,
Richard Henderson, Paolo Bonzini, Philippe Mathieu-Daudé
On Tue, 11 Aug 2026 at 16:50, Philippe Mathieu-Daudé
<philmd@oss.qualcomm.com> wrote:
>
> From: Philippe Mathieu-Daudé <philmd@linaro.org>
>
> nmi_monitor_handle() is not related to the monitor, rename
> it as nmi_inject().
>
> Return a boolean value indicating success / failure as
> recommended by the Error API since commit e3fe3988d7
> ("error: Document Error API usage rules").
>
> The 'cpu_index' argument is not used, remove it.
> This officially drops the current CPU for HMP command.
>
> Document nmi_inject() as suggested by Peter Maydell in
> https://lore.kernel.org/qemu-devel/CAFEAcA-yALySmCJLbitCmYpiZKUXJNOavGJG9RYeo8fKqz7gcw@mail.gmail.com/.
>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
> ---
> include/hw/core/nmi.h | 25 ++++++++++++++++++++++++-
> hw/core/nmi.c | 9 ++++-----
> hw/ipmi/ipmi.c | 3 +--
> hw/watchdog/watchdog.c | 2 +-
> system/cpus.c | 2 +-
> hmp-commands.hx | 2 +-
> 6 files changed, 32 insertions(+), 11 deletions(-)
>
> diff --git a/include/hw/core/nmi.h b/include/hw/core/nmi.h
> index 4c4ce79071d..2ff5be1e214 100644
> --- a/include/hw/core/nmi.h
> +++ b/include/hw/core/nmi.h
> @@ -46,6 +46,29 @@ struct NMIClass {
> void (*nmi_monitor_handler)(NMIState *ns, Error **errp);
> };
>
> -void nmi_monitor_handle(int cpu_index, Error **errp);
> +/**
> + * nmi_inject: Inject an NMI, in a machine-specific way
> + * @errp: pointer to error object
> + *
> + * This function injects an NMI, in a machine-specific way. The
> + * intention is that this should typically trigger a guest kernel
> + * dump or reboot, and might happen as a result of user request
> + * from the monitor, watchdog timeouts, and similar events.
> + * (For example on the x86 PC it triggers an NMI on all CPUs,
> + * and on s390 it triggers the RESTART interrupt on the first CPU.)
> + *
> + * The NMI is injected by looking for QOM objects which
> + * implement the TYPE_NMI interface, and calling their nmi_monitor_handler
> + * method. Usually it is the machine model class that implements
> + * this interface.
I guess with patch 7 this ought to say "looking for a QOM
object which implements the TYPE_NMI interface, and calling
its nmi_monitor_handler method".
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
thanks
-- PMM
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 0/7] hw/nmi: Disconnect of vCPU and disentangle Monitor code
2026-08-11 15:49 [PATCH v4 0/7] hw/nmi: Disconnect of vCPU and disentangle Monitor code Philippe Mathieu-Daudé
` (6 preceding siblings ...)
2026-08-11 15:49 ` [PATCH v4 7/7] hw/nmi: Raise NMI line only once Philippe Mathieu-Daudé
@ 2026-08-11 18:40 ` marcandre.lureau
7 siblings, 0 replies; 14+ messages in thread
From: marcandre.lureau @ 2026-08-11 18:40 UTC (permalink / raw)
To: Philippe Mathieu-Daudé
Cc: qemu-devel, qemu-ppc, Peter Maydell, Markus Armbruster,
Marc-André Lureau, qemu-s390x, Thomas Huth, Corey Minyard
On Tue, 11 Aug 2026 17:49:23 +0200, Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> wrote:
> hw/nmi: Disconnect of vCPU and disentangle Monitor code
>
> Since v3:
> - Rename trigger -> inject (API entry point)
> - Rename deliver -> raise (machine-specific handler)
> - Do not mention 'cpu' in HMP doc
>
> [...]
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
--
Marc-André Lureau <marcandre.lureau@redhat.com>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 2/7] hw/s390x/virtio-ccw: Always inject NMI to first CPU
2026-08-11 15:49 ` [PATCH v4 2/7] hw/s390x/virtio-ccw: Always inject NMI to first CPU Philippe Mathieu-Daudé
@ 2026-08-11 20:53 ` Eric Farman
2026-08-12 12:28 ` Cornelia Huck
1 sibling, 0 replies; 14+ messages in thread
From: Eric Farman @ 2026-08-11 20:53 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: qemu-ppc, Peter Maydell, Markus Armbruster,
Marc-André Lureau, qemu-s390x, Thomas Huth, Corey Minyard,
Philippe Mathieu-Daudé, David Hildenbrand,
Dr. David Alan Gilbert, Halil Pasic, Christian Borntraeger,
Matthew Rosato, Cornelia Huck, Richard Henderson,
Ilya Leoshkevich, David Hildenbrand, Eric Blake,
Philippe Mathieu-Daudé, Zhao Liu, Paolo Bonzini
On 8/11/26 11:49 AM, Philippe Mathieu-Daudé wrote:
> From: Philippe Mathieu-Daudé <philmd@linaro.org>
>
> We can trigger NMI from HMP or QMP.
>
> QEMU maps the NMI to the s390x per-CPU 'RESTART' interrupt.
> Linux guests usually setup this interrupt to trigger kdump
> or crash. Such crashdump can be triggered in QEMU by HMP
> "nmi" or QMP "inject-nmi" commands.
>
> Using QMP, since we can not select a particular CPU, the first
> CPU is used (CPU#0). See the documentation from commit 795dc6e4
> ("watchdog: Add new Virtual Watchdog action INJECT-NMI"):
>
> @inject-nmi: a non-maskable interrupt is injected into the
> first VCPU (all VCPUS on x86) (since 2.4)
>
> While we can select a particular CPU on HMP, the guest behavior
> is expected to be the same if using CPU #N or CPU #0. Since
> always using CPU#0 simplifies API maintainance, update s390_nmi()
nit: maintenance
> to inject NMI to the first CPU.
>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: David Hildenbrand <david@redhat.com>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
> ---
> qapi/machine.json | 7 ++++---
> qapi/run-state.json | 6 ++++--
> hw/s390x/s390-virtio-ccw.c | 4 +---
> hmp-commands.hx | 5 +++--
> 4 files changed, 12 insertions(+), 10 deletions(-)
Reviewed-by: Eric Farman <farman@linux.ibm.com>
>
> diff --git a/qapi/machine.json b/qapi/machine.json
> index 9b2248038fc..2d63c1bac3b 100644
> --- a/qapi/machine.json
> +++ b/qapi/machine.json
> @@ -432,9 +432,10 @@
> ##
> # @inject-nmi:
> #
> -# Injects a Non-Maskable Interrupt into the default CPU (x86/s390) or
> -# all CPUs (ppc64). The command fails when the guest doesn't support
> -# injecting.
> +# Injects a Non-Maskable Interrupt (machine specific: for example on
> +# s390x CCW only the first vCPU receives the NMI, but on x86 machines
> +# all vCPUs receive it). The command fails when the guest doesn't
> +# support injecting.
> #
> # Since: 0.14
> #
> diff --git a/qapi/run-state.json b/qapi/run-state.json
> index a5771ad4681..e4fdead1e0b 100644
> --- a/qapi/run-state.json
> +++ b/qapi/run-state.json
> @@ -317,8 +317,10 @@
> #
> # @none: nothing is done
> #
> -# @inject-nmi: a non-maskable interrupt is injected into the first
> -# VCPU (all VCPUS on x86) (since 2.4)
> +# @inject-nmi: a non-maskable interrupt is injected (machine
> +# specific: for example on s390x CCW only the first vCPU
> +# receives the NMI, but on x86 machines all vCPUs receive
> +# it). (since 2.4)
> #
> # Since: 2.1
> ##
> diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
> index 25a9fa49554..4f7861dbbb7 100644
> --- a/hw/s390x/s390-virtio-ccw.c
> +++ b/hw/s390x/s390-virtio-ccw.c
> @@ -727,9 +727,7 @@ static HotplugHandler *s390_get_hotplug_handler(MachineState *machine,
>
> static void s390_nmi(NMIState *n, int cpu_index, Error **errp)
> {
> - CPUState *cs = qemu_get_cpu(cpu_index);
> -
> - s390_cpu_restart(S390_CPU(cs));
> + s390_cpu_restart(S390_CPU(first_cpu));
> }
>
> static inline bool machine_get_aes_key_wrap(Object *obj, Error **errp)
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 7ae2468a3d9..a1b77ae4044 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -865,12 +865,13 @@ ERST
> .name = "nmi",
> .args_type = "",
> .params = "",
> - .help = "inject an NMI",
> + .help = "Inject an NMI, in a machine-specific way",
> .cmd = hmp_nmi,
> },
> SRST
> ``nmi`` *cpu*
> - Inject an NMI on the default CPU (x86/s390) or all CPUs (ppc64).
> + Inject an NMI, in a machine-specific way.
> + Not all machines implement NMI handling.
> ERST
>
> {
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v4 4/7] hw/nmi: Remove @cpu_index argument from nmi_inject()
2026-08-11 15:49 ` [PATCH v4 4/7] hw/nmi: Remove @cpu_index argument from nmi_inject() Philippe Mathieu-Daudé
2026-08-11 16:38 ` Peter Maydell
@ 2026-08-12 8:51 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 14+ messages in thread
From: Philippe Mathieu-Daudé @ 2026-08-12 8:51 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-ppc, Peter Maydell, Markus Armbruster,
Marc-André Lureau, qemu-s390x, Thomas Huth, Corey Minyard,
Philippe Mathieu-Daudé, Dr. David Alan Gilbert,
Richard Henderson, Paolo Bonzini, Philippe Mathieu-Daudé
On 11/8/26 17:49, Philippe Mathieu-Daudé wrote:
> From: Philippe Mathieu-Daudé <philmd@linaro.org>
>
> nmi_monitor_handle() is not related to the monitor, rename
> it as nmi_inject().
>
> Return a boolean value indicating success / failure as
> recommended by the Error API since commit e3fe3988d7
> ("error: Document Error API usage rules").
>
> The 'cpu_index' argument is not used, remove it.
> This officially drops the current CPU for HMP command.
>
> Document nmi_inject() as suggested by Peter Maydell in
> https://lore.kernel.org/qemu-devel/CAFEAcA-yALySmCJLbitCmYpiZKUXJNOavGJG9RYeo8fKqz7gcw@mail.gmail.com/.
>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
> ---
> include/hw/core/nmi.h | 25 ++++++++++++++++++++++++-
> hw/core/nmi.c | 9 ++++-----
> hw/ipmi/ipmi.c | 3 +--
> hw/watchdog/watchdog.c | 2 +-
> system/cpus.c | 2 +-
> hmp-commands.hx | 2 +-
> 6 files changed, 32 insertions(+), 11 deletions(-)
> diff --git a/system/cpus.c b/system/cpus.c
> index 97e5a5edee2..04809698de4 100644
> --- a/system/cpus.c
> +++ b/system/cpus.c
> @@ -926,6 +926,6 @@ exit:
>
> void qmp_inject_nmi(Error **errp)
> {
> - nmi_monitor_handle(monitor_get_cpu_index(monitor_cur()), errp);
> + nmi_inject(errp);
> }
Squashing:
-- >8 --diff --
git a/system/cpus.c b/system/cpus.c
index 3729f2cc10d..b9dd4478fda 100644
--- a/system/cpus.c
+++ b/system/cpus.c
@@ -25,3 +25,2 @@
#include "qemu/osdep.h"
-#include "monitor/monitor.h"
#include "qemu/coroutine-tls.h"
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v4 2/7] hw/s390x/virtio-ccw: Always inject NMI to first CPU
2026-08-11 15:49 ` [PATCH v4 2/7] hw/s390x/virtio-ccw: Always inject NMI to first CPU Philippe Mathieu-Daudé
2026-08-11 20:53 ` Eric Farman
@ 2026-08-12 12:28 ` Cornelia Huck
1 sibling, 0 replies; 14+ messages in thread
From: Cornelia Huck @ 2026-08-12 12:28 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: qemu-ppc, Peter Maydell, Markus Armbruster,
Marc-André Lureau, qemu-s390x, Thomas Huth, Corey Minyard,
Philippe Mathieu-Daudé, David Hildenbrand,
Philippe Mathieu-Daudé, Dr. David Alan Gilbert, Halil Pasic,
Christian Borntraeger, Eric Farman, Matthew Rosato,
Richard Henderson, Ilya Leoshkevich, David Hildenbrand,
Eric Blake, Philippe Mathieu-Daudé, Zhao Liu, Paolo Bonzini
On Tue, Aug 11 2026, Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> wrote:
> From: Philippe Mathieu-Daudé <philmd@linaro.org>
>
> We can trigger NMI from HMP or QMP.
>
> QEMU maps the NMI to the s390x per-CPU 'RESTART' interrupt.
> Linux guests usually setup this interrupt to trigger kdump
> or crash. Such crashdump can be triggered in QEMU by HMP
> "nmi" or QMP "inject-nmi" commands.
>
> Using QMP, since we can not select a particular CPU, the first
> CPU is used (CPU#0). See the documentation from commit 795dc6e4
> ("watchdog: Add new Virtual Watchdog action INJECT-NMI"):
>
> @inject-nmi: a non-maskable interrupt is injected into the
> first VCPU (all VCPUS on x86) (since 2.4)
>
> While we can select a particular CPU on HMP, the guest behavior
> is expected to be the same if using CPU #N or CPU #0. Since
> always using CPU#0 simplifies API maintainance, update s390_nmi()
> to inject NMI to the first CPU.
In theory, we could have different actions setup for different cpus. In
practice, Linux does not do that, and I'm not sure if anything else we
might run does -- especially as we always end up with CPU 0 for QMP
anyway.
So I'm fine with getting rid of the different behaviour between HMP and
QMP, especially as it allows simplifying the code.
>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
> Reviewed-by: David Hildenbrand <david@redhat.com>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
> ---
> qapi/machine.json | 7 ++++---
> qapi/run-state.json | 6 ++++--
> hw/s390x/s390-virtio-ccw.c | 4 +---
> hmp-commands.hx | 5 +++--
> 4 files changed, 12 insertions(+), 10 deletions(-)
Acked-by: Cornelia Huck <cohuck@redhat.com>
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2026-08-12 12:29 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-11 15:49 [PATCH v4 0/7] hw/nmi: Disconnect of vCPU and disentangle Monitor code Philippe Mathieu-Daudé
2026-08-11 15:49 ` [PATCH v4 1/7] hw/nmi: Use object_child_foreach_recursive() in nmi_children() Philippe Mathieu-Daudé
2026-08-11 15:49 ` [PATCH v4 2/7] hw/s390x/virtio-ccw: Always inject NMI to first CPU Philippe Mathieu-Daudé
2026-08-11 20:53 ` Eric Farman
2026-08-12 12:28 ` Cornelia Huck
2026-08-11 15:49 ` [PATCH v4 3/7] hw/nmi: Remove @cpu_index argument from NMIClass::nmi_monitor_handler() Philippe Mathieu-Daudé
2026-08-11 15:49 ` [PATCH v4 4/7] hw/nmi: Remove @cpu_index argument from nmi_inject() Philippe Mathieu-Daudé
2026-08-11 16:38 ` Peter Maydell
2026-08-12 8:51 ` Philippe Mathieu-Daudé
2026-08-11 15:49 ` [PATCH v4 5/7] hw/nmi: Rename nmi_monitor_handler() -> raise_nmi() Philippe Mathieu-Daudé
2026-08-11 15:49 ` [PATCH v4 6/7] hw/nmi: Remove unused @errp argument from raise_nmi() Philippe Mathieu-Daudé
2026-08-11 16:34 ` Peter Maydell
2026-08-11 15:49 ` [PATCH v4 7/7] hw/nmi: Raise NMI line only once Philippe Mathieu-Daudé
2026-08-11 18:40 ` [PATCH v4 0/7] hw/nmi: Disconnect of vCPU and disentangle Monitor code marcandre.lureau
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.