Recent commit b8165118f52c "spapr: support memory unplug for qtest" broke CPU hotplug tests for old machine types:
$ QTEST_QEMU_BINARY=ppc64-softmmu/qemu-system-ppc64 ./tests/cpu-plug-test -m=slow /ppc64/cpu-plug/pseries-3.1/device-add/2x3x1&maxcpus=6: OK /ppc64/cpu-plug/pseries-2.12-sxxm/device-add/2x3x1&maxcpus=6: OK /ppc64/cpu-plug/pseries-3.0/device-add/2x3x1&maxcpus=6: OK /ppc64/cpu-plug/pseries-2.10/device-add/2x3x1&maxcpus=6: OK /ppc64/cpu-plug/pseries-2.11/device-add/2x3x1&maxcpus=6: OK /ppc64/cpu-plug/pseries-2.12/device-add/2x3x1&maxcpus=6: OK /ppc64/cpu-plug/pseries-2.9/device-add/2x3x1&maxcpus=6: OK /ppc64/cpu-plug/pseries-2.7/device-add/2x3x1&maxcpus=6: ** ERROR:/home/thuth/devel/qemu/hw/ppc/spapr_events.c:313:rtas_event_log_to_source: assertion failed: (source->enabled) Broken pipe /home/thuth/devel/qemu/tests/libqtest.c:143: kill_qemu() detected QEMU death from signal 6 (Aborted) (core dumped) Aborted (core dumped) The rtas_event_log_to_source() function is supposed to return the event source to be used for a given event type. In the case of hotplug, it first tries EVENT_CLASS_HOT_PLUG and, if the guest doesn't support it, it falls back to EVENT_CLASS_EPOW. This works well for machine types that enable EVENT_CLASS_HOT_PLUG. For older machine types, this happened to work because they don't set the OV5_HP_EVT bit in spapr->ov5. CAS hence logically keeps the bit cleared in spapr->ov5_cas and we avoid the assert. As shown by commit b8165118f52c, the logic is fragile and we need a bigger hammer to ensure that rtas_event_log_to_source() doesn't go down the EVENT_CLASS_HOT_PLUG path with older machine types. Signed-off-by: Greg Kurz <gr...@kaod.org> --- hw/ppc/spapr_events.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c index ab9a1f0063d5..1a09dab6857d 100644 --- a/hw/ppc/spapr_events.c +++ b/hw/ppc/spapr_events.c @@ -307,11 +307,13 @@ rtas_event_log_to_source(sPAPRMachineState *spapr, int log_type) switch (log_type) { case RTAS_LOG_TYPE_HOTPLUG: - source = spapr_event_sources_get_source(spapr->event_sources, - EVENT_CLASS_HOT_PLUG); - if (spapr_ovec_test(spapr->ov5_cas, OV5_HP_EVT)) { - g_assert(source->enabled); - break; + if (spapr->use_hotplug_event_source) { + source = spapr_event_sources_get_source(spapr->event_sources, + EVENT_CLASS_HOT_PLUG); + if (spapr_ovec_test(spapr->ov5_cas, OV5_HP_EVT)) { + g_assert(source->enabled); + break; + } } /* fall back to epow for legacy hotplug interrupt source */ case RTAS_LOG_TYPE_EPOW: