From: Shivang Upadhyay <[email protected]> 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 <[email protected]> Cc: Harsh Prateek Bora <[email protected]> Cc: BALATON Zoltan <[email protected]> Cc: [email protected] Reported-by: Nathan Chancellor <[email protected]> Suggested-by: Peter Maydell <[email protected]> Fixes: a16d4c2f162a86d ("ppc/pnv: fix dumpdtb option") Fixes: b7460b0d546ec0e ("ppc/pnv: fix dumpdtb option") in 10.0.x series Signed-off-by: Shivang Upadhyay <[email protected]> Tested-by: Nathan Chancellor <[email protected]> Reviewed-by: Aditya Gupta <[email protected]> Reviewed-by: Peter Maydell <[email protected]> Message-ID: <[email protected]> Signed-off-by: Philippe Mathieu-Daudé <[email protected]> (cherry picked from commit ba48bff09fa1fea8030eb26f2bc0add8c3549bb7) Signed-off-by: Michael Tokarev <[email protected]> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 9f9f3ce4ac..e510a1cae1 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -716,31 +716,10 @@ static void pnv_powerdown_notify(Notifier *n, void *opaque) static void pnv_reset(MachineState *machine, ResetType type) { - PnvMachineState *pnv = PNV_MACHINE(machine); - IPMIBmc *bmc; void *fdt; qemu_devices_reset(type); - /* - * The machine should provide by default an internal BMC simulator. - * If not, try to use the BMC device that was provided on the command - * line. - */ - bmc = pnv_bmc_find(&error_fatal); - if (!pnv->bmc) { - if (!bmc) { - if (!qtest_enabled()) { - warn_report("machine has no BMC device. Use '-device " - "ipmi-bmc-sim,id=bmc0 -device isa-ipmi-bt,bmc=bmc0,irq=10' " - "to define one"); - } - } else { - pnv_bmc_set_pnor(bmc, pnv->pnor); - pnv->bmc = bmc; - } - } - fdt = machine->fdt; cpu_physical_memory_write(PNV_FDT_ADDR, fdt, fdt_totalsize(fdt)); } @@ -916,6 +895,37 @@ static uint64_t pnv_chip_get_ram_size(PnvMachineState *pnv, int chip_id) return chip_id == 0 ? 1 * GiB : QEMU_ALIGN_DOWN(ram_per_chip, 1 * MiB); } +static void pnv_machine_init_done(Notifier *notifier, void *data) +{ + PnvMachineState *pnv = container_of(notifier, PnvMachineState, machine_init_done); + MachineState *machine = MACHINE(pnv); + IPMIBmc *bmc; + + /* + * The machine should provide by default an internal BMC simulator. + * If not, try to use the BMC device that was provided on the command + * line. + */ + bmc = pnv_bmc_find(&error_fatal); + if (!pnv->bmc) { + if (!bmc) { + if (!qtest_enabled()) { + warn_report("machine has no BMC device. Use '-device " + "ipmi-bmc-sim,id=bmc0 -device isa-ipmi-bt,bmc=bmc0,irq=10' " + "to define one"); + } + } else { + pnv_bmc_set_pnor(bmc, pnv->pnor); + pnv->bmc = bmc; + } + } + + if (!machine->fdt) { + machine->fdt = pnv_dt_create(machine); + _FDT((fdt_pack(machine->fdt))); + } +} + static void pnv_init(MachineState *machine) { const char *bios_name = machine->firmware ?: FW_FILE_NAME; @@ -1191,10 +1201,8 @@ static void pnv_init(MachineState *machine) pmc->i2c_init(pnv); } - if (!machine->fdt) { - machine->fdt = pnv_dt_create(machine); - _FDT((fdt_pack(machine->fdt))); - } + pnv->machine_init_done.notify = pnv_machine_init_done; + qemu_add_machine_init_done_notifier(&pnv->machine_init_done); } /* diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index d8fca079f2..cf3bb46693 100644 --- a/include/hw/ppc/pnv.h +++ b/include/hw/ppc/pnv.h @@ -106,6 +106,8 @@ struct PnvMachineState { bool big_core; bool lpar_per_core; + + Notifier machine_init_done; }; PnvChip *pnv_get_chip(PnvMachineState *pnv, uint32_t chip_id); -- 2.47.3
