@samitouri / QOSamiQemu / commits / ba48bff09f

ppc/pnv: generate dtb after machine initialization is complete

Currently, the machine dtb is generated in pnv_init(), before all devices are fully initialized. This can result in an incomplete dtb for the system, as seen in bug [1]. Fix this by deferring dtb generation until machine initialization is complete, using the machine_init_done_notifier hook. [1] https://lore.kernel.org/all/20260323231612.GA2637687@ax162/ Cc: Aditya Gupta <adityag@linux.ibm.com> Cc: Harsh Prateek Bora <harshpb@linux.ibm.com> Cc: BALATON Zoltan <balaton@eik.bme.hu> Cc: qemu-stable@nongnu.org Reported-by: Nathan Chancellor <nathan@kernel.org> Suggested-by: Peter Maydell <peter.maydell@linaro.org> Fixes: a16d4c2f162a86d ("ppc/pnv: fix dumpdtb option") Signed-off-by: Shivang Upadhyay <shivangu@linux.ibm.com> Tested-by: Nathan Chancellor <nathan@kernel.org> Reviewed-by: Aditya Gupta <adityag@linux.ibm.com> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-ID: <20260327124136.983955-1-shivangu@linux.ibm.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>

Shivang Upadhyay committed Mar 24, 2026 at 19:20 UTC ba48bff09fa1fea8030eb26f2bc0add8c3549bb7
2 files changed +35 -25
hw/ppc/pnv.c
+33 -25
@@ -748,31 +748,10 @@ static void pnv_powerdown_notify(Notifier *n, void *opaque)
748
749 static void pnv_reset(MachineState *machine, ResetType type)
750 {
751 - PnvMachineState *pnv = PNV_MACHINE(machine);
752 - IPMIBmc *bmc;
751 void *fdt;
752
753 qemu_devices_reset(type);
754
757 - /*
758 - * The machine should provide by default an internal BMC simulator.
759 - * If not, try to use the BMC device that was provided on the command
760 - * line.
761 - */
762 - bmc = pnv_bmc_find(&error_fatal);
763 - if (!pnv->bmc) {
764 - if (!bmc) {
765 - if (!qtest_enabled()) {
766 - warn_report("machine has no BMC device. Use '-device "
767 - "ipmi-bmc-sim,id=bmc0 -device isa-ipmi-bt,bmc=bmc0,irq=10' "
768 - "to define one");
769 - }
770 - } else {
771 - pnv_bmc_set_pnor(bmc, pnv->pnor);
772 - pnv->bmc = bmc;
773 - }
774 - }
775 -
755 fdt = machine->fdt;
756 cpu_physical_memory_write(PNV_FDT_ADDR, fdt, fdt_totalsize(fdt));
757 }
@@ -984,6 +963,37 @@ static uint64_t pnv_chip_get_ram_size(PnvMachineState *pnv, int chip_id)
963 return chip_id == 0 ? 1 * GiB : QEMU_ALIGN_DOWN(ram_per_chip, 1 * MiB);
964 }
965
966 +static void pnv_machine_init_done(Notifier *notifier, void *data)
967 +{
968 + PnvMachineState *pnv = container_of(notifier, PnvMachineState, machine_init_done);
969 + MachineState *machine = MACHINE(pnv);
970 + IPMIBmc *bmc;
971 +
972 + /*
973 + * The machine should provide by default an internal BMC simulator.
974 + * If not, try to use the BMC device that was provided on the command
975 + * line.
976 + */
977 + bmc = pnv_bmc_find(&error_fatal);
978 + if (!pnv->bmc) {
979 + if (!bmc) {
980 + if (!qtest_enabled()) {
981 + warn_report("machine has no BMC device. Use '-device "
982 + "ipmi-bmc-sim,id=bmc0 -device isa-ipmi-bt,bmc=bmc0,irq=10' "
983 + "to define one");
984 + }
985 + } else {
986 + pnv_bmc_set_pnor(bmc, pnv->pnor);
987 + pnv->bmc = bmc;
988 + }
989 + }
990 +
991 + if (!machine->fdt) {
992 + machine->fdt = pnv_dt_create(machine);
993 + _FDT((fdt_pack(machine->fdt)));
994 + }
995 +}
996 +
997 static void pnv_init(MachineState *machine)
998 {
999 const char *bios_name = machine->firmware ?: FW_FILE_NAME;
@@ -1244,10 +1254,8 @@ static void pnv_init(MachineState *machine)
1254 pmc->i2c_init(pnv);
1255 }
1256
1247 - if (!machine->fdt) {
1248 - machine->fdt = pnv_dt_create(machine);
1249 - _FDT((fdt_pack(machine->fdt)));
1250 - }
1257 + pnv->machine_init_done.notify = pnv_machine_init_done;
1258 + qemu_add_machine_init_done_notifier(&pnv->machine_init_done);
1259 }
1260
1261 /*
include/hw/ppc/pnv.h
+2
@@ -111,6 +111,8 @@ struct PnvMachineState {
111
112 bool big_core;
113 bool lpar_per_core;
114 +
115 + Notifier machine_init_done;
116 };
117
118 PnvChip *pnv_get_chip(PnvMachineState *pnv, uint32_t chip_id);