hw/i386/pc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
QEMU currently crashes when you try to inspect the machines based on
TYPE_PC_MACHINE for their properties:
$ echo '{ "execute": "qmp_capabilities" }
{ "execute": "qom-list-properties","arguments":
{ "typename": "pc-q35-10.0-machine"}}' \
| ./qemu-system-x86_64 -M pc -qmp stdio
{"QMP": {"version": {"qemu": {"micro": 50, "minor": 2, "major": 9},
"package": "v9.2.0-1070-g87e115c122-dirty"}, "capabilities": ["oob"]}}
{"return": {}}
Segmentation fault (core dumped)
This happens because TYPE_PC_MACHINE machines add a machine_init-
done_notifier in their instance_init function - but instance_init
of machines are not only called for machines that are realized,
but also for machines that are introspected, so in this case the
listener is added for a q35 machine that is never realized. But
since there is already a running pc machine, the listener function
is triggered immediately, causing a crash since it was not for the
right machine it was meant for.
Such listener functions must never be installed from an instance_init
function. Let's do it from pc_basic_device_init() instead - this
function is called from the MachineClass->init() function instead,
i.e. guaranteed to be only called once in the lifetime of a QEMU
process.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2779
Signed-off-by: Thomas Huth <thuth@redhat.com>
---
hw/i386/pc.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index b46975c8a4..85b8a76455 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1241,6 +1241,9 @@ void pc_basic_device_init(struct PCMachineState *pcms,
/* Super I/O */
pc_superio_init(isa_bus, create_fdctrl, pcms->i8042_enabled,
pcms->vmport != ON_OFF_AUTO_ON, &error_fatal);
+
+ pcms->machine_done.notify = pc_machine_done;
+ qemu_add_machine_init_done_notifier(&pcms->machine_done);
}
void pc_nic_init(PCMachineClass *pcmc, ISABus *isa_bus, PCIBus *pci_bus)
@@ -1714,9 +1717,6 @@ static void pc_machine_initfn(Object *obj)
if (pcmc->pci_enabled) {
cxl_machine_init(obj, &pcms->cxl_devices_state);
}
-
- pcms->machine_done.notify = pc_machine_done;
- qemu_add_machine_init_done_notifier(&pcms->machine_done);
}
static void pc_machine_reset(MachineState *machine, ResetType type)
--
2.48.1
Hi Thomas, On 17/1/25 20:21, Thomas Huth wrote: > QEMU currently crashes when you try to inspect the machines based on > TYPE_PC_MACHINE for their properties: > > $ echo '{ "execute": "qmp_capabilities" } > { "execute": "qom-list-properties","arguments": > { "typename": "pc-q35-10.0-machine"}}' \ > | ./qemu-system-x86_64 -M pc -qmp stdio > {"QMP": {"version": {"qemu": {"micro": 50, "minor": 2, "major": 9}, > "package": "v9.2.0-1070-g87e115c122-dirty"}, "capabilities": ["oob"]}} > {"return": {}} > Segmentation fault (core dumped) > > This happens because TYPE_PC_MACHINE machines add a machine_init- > done_notifier in their instance_init function - but instance_init > of machines are not only called for machines that are realized, > but also for machines that are introspected, so in this case the > listener is added for a q35 machine that is never realized. But > since there is already a running pc machine, the listener function > is triggered immediately, causing a crash since it was not for the > right machine it was meant for. > > Such listener functions must never be installed from an instance_init > function. Let's do it from pc_basic_device_init() instead - this > function is called from the MachineClass->init() function instead, > i.e. guaranteed to be only called once in the lifetime of a QEMU > process. > > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2779 > Signed-off-by: Thomas Huth <thuth@redhat.com> > --- > hw/i386/pc.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c > index b46975c8a4..85b8a76455 100644 > --- a/hw/i386/pc.c > +++ b/hw/i386/pc.c > @@ -1241,6 +1241,9 @@ void pc_basic_device_init(struct PCMachineState *pcms, > /* Super I/O */ > pc_superio_init(isa_bus, create_fdctrl, pcms->i8042_enabled, > pcms->vmport != ON_OFF_AUTO_ON, &error_fatal); > + > + pcms->machine_done.notify = pc_machine_done; I could accept if we rename: pc_machine_done() -> pc_basic_device_init_done[_notifier]() > + qemu_add_machine_init_done_notifier(&pcms->machine_done); > } > > void pc_nic_init(PCMachineClass *pcmc, ISABus *isa_bus, PCIBus *pci_bus) > @@ -1714,9 +1717,6 @@ static void pc_machine_initfn(Object *obj) > if (pcmc->pci_enabled) { > cxl_machine_init(obj, &pcms->cxl_devices_state); > } > - > - pcms->machine_done.notify = pc_machine_done; > - qemu_add_machine_init_done_notifier(&pcms->machine_done); > } > > static void pc_machine_reset(MachineState *machine, ResetType type)
On 29/01/2025 08.11, Philippe Mathieu-Daudé wrote: > Hi Thomas, > > On 17/1/25 20:21, Thomas Huth wrote: >> QEMU currently crashes when you try to inspect the machines based on >> TYPE_PC_MACHINE for their properties: >> >> $ echo '{ "execute": "qmp_capabilities" } >> { "execute": "qom-list-properties","arguments": >> { "typename": "pc-q35-10.0-machine"}}' \ >> | ./qemu-system-x86_64 -M pc -qmp stdio >> {"QMP": {"version": {"qemu": {"micro": 50, "minor": 2, "major": 9}, >> "package": "v9.2.0-1070-g87e115c122-dirty"}, "capabilities": ["oob"]}} >> {"return": {}} >> Segmentation fault (core dumped) >> >> This happens because TYPE_PC_MACHINE machines add a machine_init- >> done_notifier in their instance_init function - but instance_init >> of machines are not only called for machines that are realized, >> but also for machines that are introspected, so in this case the >> listener is added for a q35 machine that is never realized. But >> since there is already a running pc machine, the listener function >> is triggered immediately, causing a crash since it was not for the >> right machine it was meant for. >> >> Such listener functions must never be installed from an instance_init >> function. Let's do it from pc_basic_device_init() instead - this >> function is called from the MachineClass->init() function instead, >> i.e. guaranteed to be only called once in the lifetime of a QEMU >> process. >> >> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2779 >> Signed-off-by: Thomas Huth <thuth@redhat.com> >> --- >> hw/i386/pc.c | 6 +++--- >> 1 file changed, 3 insertions(+), 3 deletions(-) >> >> diff --git a/hw/i386/pc.c b/hw/i386/pc.c >> index b46975c8a4..85b8a76455 100644 >> --- a/hw/i386/pc.c >> +++ b/hw/i386/pc.c >> @@ -1241,6 +1241,9 @@ void pc_basic_device_init(struct PCMachineState *pcms, >> /* Super I/O */ >> pc_superio_init(isa_bus, create_fdctrl, pcms->i8042_enabled, >> pcms->vmport != ON_OFF_AUTO_ON, &error_fatal); >> + >> + pcms->machine_done.notify = pc_machine_done; > > I could accept if we rename: > > pc_machine_done() -> pc_basic_device_init_done[_notifier]() Not sure whether that's such a good idea: The notifier is called when the machine init has been done, not when the device init has been done. It just happens to be instantiated from a function called pc_basic_device_init() now, but that does not really mean that the notifier function should get a similar name, should it? Thomas >> + qemu_add_machine_init_done_notifier(&pcms->machine_done); >> } >> void pc_nic_init(PCMachineClass *pcmc, ISABus *isa_bus, PCIBus *pci_bus) >> @@ -1714,9 +1717,6 @@ static void pc_machine_initfn(Object *obj) >> if (pcmc->pci_enabled) { >> cxl_machine_init(obj, &pcms->cxl_devices_state); >> } >> - >> - pcms->machine_done.notify = pc_machine_done; >> - qemu_add_machine_init_done_notifier(&pcms->machine_done); >> } >> static void pc_machine_reset(MachineState *machine, ResetType type) >
On 17/01/2025 20.21, Thomas Huth wrote: > QEMU currently crashes when you try to inspect the machines based on > TYPE_PC_MACHINE for their properties: > > $ echo '{ "execute": "qmp_capabilities" } > { "execute": "qom-list-properties","arguments": > { "typename": "pc-q35-10.0-machine"}}' \ > | ./qemu-system-x86_64 -M pc -qmp stdio > {"QMP": {"version": {"qemu": {"micro": 50, "minor": 2, "major": 9}, > "package": "v9.2.0-1070-g87e115c122-dirty"}, "capabilities": ["oob"]}} > {"return": {}} > Segmentation fault (core dumped) > > This happens because TYPE_PC_MACHINE machines add a machine_init- > done_notifier in their instance_init function - but instance_init > of machines are not only called for machines that are realized, > but also for machines that are introspected, so in this case the > listener is added for a q35 machine that is never realized. But > since there is already a running pc machine, the listener function > is triggered immediately, causing a crash since it was not for the > right machine it was meant for. > > Such listener functions must never be installed from an instance_init > function. Let's do it from pc_basic_device_init() instead - this > function is called from the MachineClass->init() function instead, > i.e. guaranteed to be only called once in the lifetime of a QEMU > process. > > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2779 > Signed-off-by: Thomas Huth <thuth@redhat.com> > --- > hw/i386/pc.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c > index b46975c8a4..85b8a76455 100644 > --- a/hw/i386/pc.c > +++ b/hw/i386/pc.c > @@ -1241,6 +1241,9 @@ void pc_basic_device_init(struct PCMachineState *pcms, > /* Super I/O */ > pc_superio_init(isa_bus, create_fdctrl, pcms->i8042_enabled, > pcms->vmport != ON_OFF_AUTO_ON, &error_fatal); > + > + pcms->machine_done.notify = pc_machine_done; > + qemu_add_machine_init_done_notifier(&pcms->machine_done); > } > > void pc_nic_init(PCMachineClass *pcmc, ISABus *isa_bus, PCIBus *pci_bus) > @@ -1714,9 +1717,6 @@ static void pc_machine_initfn(Object *obj) > if (pcmc->pci_enabled) { > cxl_machine_init(obj, &pcms->cxl_devices_state); > } > - > - pcms->machine_done.notify = pc_machine_done; > - qemu_add_machine_init_done_notifier(&pcms->machine_done); > } > > static void pc_machine_reset(MachineState *machine, ResetType type) Friendly ping! Thomas
On Wed, Jan 29, 2025 at 08:00:40AM +0100, Thomas Huth wrote: > On 17/01/2025 20.21, Thomas Huth wrote: > > QEMU currently crashes when you try to inspect the machines based on > > TYPE_PC_MACHINE for their properties: > > > > $ echo '{ "execute": "qmp_capabilities" } > > { "execute": "qom-list-properties","arguments": > > { "typename": "pc-q35-10.0-machine"}}' \ > > | ./qemu-system-x86_64 -M pc -qmp stdio > > {"QMP": {"version": {"qemu": {"micro": 50, "minor": 2, "major": 9}, > > "package": "v9.2.0-1070-g87e115c122-dirty"}, "capabilities": ["oob"]}} > > {"return": {}} > > Segmentation fault (core dumped) > > > > This happens because TYPE_PC_MACHINE machines add a machine_init- > > done_notifier in their instance_init function - but instance_init > > of machines are not only called for machines that are realized, > > but also for machines that are introspected, so in this case the > > listener is added for a q35 machine that is never realized. But > > since there is already a running pc machine, the listener function > > is triggered immediately, causing a crash since it was not for the > > right machine it was meant for. > > > > Such listener functions must never be installed from an instance_init > > function. Let's do it from pc_basic_device_init() instead - this > > function is called from the MachineClass->init() function instead, > > i.e. guaranteed to be only called once in the lifetime of a QEMU > > process. > > > > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2779 > > Signed-off-by: Thomas Huth <thuth@redhat.com> > > --- > > hw/i386/pc.c | 6 +++--- > > 1 file changed, 3 insertions(+), 3 deletions(-) > > > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c > > index b46975c8a4..85b8a76455 100644 > > --- a/hw/i386/pc.c > > +++ b/hw/i386/pc.c > > @@ -1241,6 +1241,9 @@ void pc_basic_device_init(struct PCMachineState *pcms, > > /* Super I/O */ > > pc_superio_init(isa_bus, create_fdctrl, pcms->i8042_enabled, > > pcms->vmport != ON_OFF_AUTO_ON, &error_fatal); > > + > > + pcms->machine_done.notify = pc_machine_done; > > + qemu_add_machine_init_done_notifier(&pcms->machine_done); > > } > > void pc_nic_init(PCMachineClass *pcmc, ISABus *isa_bus, PCIBus *pci_bus) > > @@ -1714,9 +1717,6 @@ static void pc_machine_initfn(Object *obj) > > if (pcmc->pci_enabled) { > > cxl_machine_init(obj, &pcms->cxl_devices_state); > > } > > - > > - pcms->machine_done.notify = pc_machine_done; > > - qemu_add_machine_init_done_notifier(&pcms->machine_done); > > } > > static void pc_machine_reset(MachineState *machine, ResetType type) > > Friendly ping! > > Thomas donnu how i missed it. pls address Philip's comment though.
On 29/01/2025 21.04, Michael S. Tsirkin wrote: > On Wed, Jan 29, 2025 at 08:00:40AM +0100, Thomas Huth wrote: >> On 17/01/2025 20.21, Thomas Huth wrote: >>> QEMU currently crashes when you try to inspect the machines based on >>> TYPE_PC_MACHINE for their properties: >>> >>> $ echo '{ "execute": "qmp_capabilities" } >>> { "execute": "qom-list-properties","arguments": >>> { "typename": "pc-q35-10.0-machine"}}' \ >>> | ./qemu-system-x86_64 -M pc -qmp stdio >>> {"QMP": {"version": {"qemu": {"micro": 50, "minor": 2, "major": 9}, >>> "package": "v9.2.0-1070-g87e115c122-dirty"}, "capabilities": ["oob"]}} >>> {"return": {}} >>> Segmentation fault (core dumped) >>> >>> This happens because TYPE_PC_MACHINE machines add a machine_init- >>> done_notifier in their instance_init function - but instance_init >>> of machines are not only called for machines that are realized, >>> but also for machines that are introspected, so in this case the >>> listener is added for a q35 machine that is never realized. But >>> since there is already a running pc machine, the listener function >>> is triggered immediately, causing a crash since it was not for the >>> right machine it was meant for. >>> >>> Such listener functions must never be installed from an instance_init >>> function. Let's do it from pc_basic_device_init() instead - this >>> function is called from the MachineClass->init() function instead, >>> i.e. guaranteed to be only called once in the lifetime of a QEMU >>> process. >>> >>> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2779 >>> Signed-off-by: Thomas Huth <thuth@redhat.com> >>> --- >>> hw/i386/pc.c | 6 +++--- >>> 1 file changed, 3 insertions(+), 3 deletions(-) >>> >>> diff --git a/hw/i386/pc.c b/hw/i386/pc.c >>> index b46975c8a4..85b8a76455 100644 >>> --- a/hw/i386/pc.c >>> +++ b/hw/i386/pc.c >>> @@ -1241,6 +1241,9 @@ void pc_basic_device_init(struct PCMachineState *pcms, >>> /* Super I/O */ >>> pc_superio_init(isa_bus, create_fdctrl, pcms->i8042_enabled, >>> pcms->vmport != ON_OFF_AUTO_ON, &error_fatal); >>> + >>> + pcms->machine_done.notify = pc_machine_done; >>> + qemu_add_machine_init_done_notifier(&pcms->machine_done); >>> } >>> void pc_nic_init(PCMachineClass *pcmc, ISABus *isa_bus, PCIBus *pci_bus) >>> @@ -1714,9 +1717,6 @@ static void pc_machine_initfn(Object *obj) >>> if (pcmc->pci_enabled) { >>> cxl_machine_init(obj, &pcms->cxl_devices_state); >>> } >>> - >>> - pcms->machine_done.notify = pc_machine_done; >>> - qemu_add_machine_init_done_notifier(&pcms->machine_done); >>> } >>> static void pc_machine_reset(MachineState *machine, ResetType type) >> >> Friendly ping! >> >> Thomas > > > donnu how i missed it. pls address Philip's comment though. Hi Michael, I think we should *not* rename pc_machine_done() since this is about a "machine_done" notifier, not about a "basic_device_init_done" or whatever notifier. So I'd prefer if we can keep this patch as it is. Unless you disagree, could you please pick this up? Thanks, Thomas
On 4/2/25 09:57, Thomas Huth wrote: > On 29/01/2025 21.04, Michael S. Tsirkin wrote: >> On Wed, Jan 29, 2025 at 08:00:40AM +0100, Thomas Huth wrote: >>> On 17/01/2025 20.21, Thomas Huth wrote: >>>> QEMU currently crashes when you try to inspect the machines based on >>>> TYPE_PC_MACHINE for their properties: >>>> >>>> $ echo '{ "execute": "qmp_capabilities" } >>>> { "execute": "qom-list-properties","arguments": >>>> { "typename": "pc-q35-10.0-machine"}}' \ >>>> | ./qemu-system-x86_64 -M pc -qmp stdio >>>> {"QMP": {"version": {"qemu": {"micro": 50, "minor": 2, "major": 9}, >>>> "package": "v9.2.0-1070-g87e115c122-dirty"}, "capabilities": >>>> ["oob"]}} >>>> {"return": {}} >>>> Segmentation fault (core dumped) >>>> >>>> This happens because TYPE_PC_MACHINE machines add a machine_init- >>>> done_notifier in their instance_init function - but instance_init >>>> of machines are not only called for machines that are realized, >>>> but also for machines that are introspected, so in this case the >>>> listener is added for a q35 machine that is never realized. But >>>> since there is already a running pc machine, the listener function >>>> is triggered immediately, causing a crash since it was not for the >>>> right machine it was meant for. >>>> >>>> Such listener functions must never be installed from an instance_init >>>> function. Let's do it from pc_basic_device_init() instead - this >>>> function is called from the MachineClass->init() function instead, >>>> i.e. guaranteed to be only called once in the lifetime of a QEMU >>>> process. >>>> >>>> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2779 >>>> Signed-off-by: Thomas Huth <thuth@redhat.com> >>>> --- >>>> hw/i386/pc.c | 6 +++--- >>>> 1 file changed, 3 insertions(+), 3 deletions(-) >>>> >>>> diff --git a/hw/i386/pc.c b/hw/i386/pc.c >>>> index b46975c8a4..85b8a76455 100644 >>>> --- a/hw/i386/pc.c >>>> +++ b/hw/i386/pc.c >>>> @@ -1241,6 +1241,9 @@ void pc_basic_device_init(struct >>>> PCMachineState *pcms, >>>> /* Super I/O */ >>>> pc_superio_init(isa_bus, create_fdctrl, pcms->i8042_enabled, >>>> pcms->vmport != ON_OFF_AUTO_ON, &error_fatal); >>>> + >>>> + pcms->machine_done.notify = pc_machine_done; >>>> + qemu_add_machine_init_done_notifier(&pcms->machine_done); >>>> } >>>> void pc_nic_init(PCMachineClass *pcmc, ISABus *isa_bus, PCIBus >>>> *pci_bus) >>>> @@ -1714,9 +1717,6 @@ static void pc_machine_initfn(Object *obj) >>>> if (pcmc->pci_enabled) { >>>> cxl_machine_init(obj, &pcms->cxl_devices_state); >>>> } >>>> - >>>> - pcms->machine_done.notify = pc_machine_done; >>>> - qemu_add_machine_init_done_notifier(&pcms->machine_done); >>>> } >>>> static void pc_machine_reset(MachineState *machine, ResetType type) >>> >>> Friendly ping! >>> >>> Thomas >> >> >> donnu how i missed it. pls address Philip's comment though. > > Hi Michael, > > I think we should *not* rename pc_machine_done() since this is about a > "machine_done" notifier, not about a "basic_device_init_done" or > whatever notifier. So I'd prefer if we can keep this patch as it is. > Unless you disagree, could you please pick this up? I don't have a strong opinion on this, so fine by me!
© 2016 - 2025 Red Hat, Inc.