qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

ppc/pnv: Create BMC devices only when defaults are enabled

Commit e2392d4395dd ("ppc/pnv: Create BMC devices at machine init")
introduced default BMC devices which can be a problem when the same
devices are defined on the command line with :

-device ipmi-bmc-sim,id=bmc0 -device isa-ipmi-bt,bmc=bmc0,irq=10

QEMU fails with :

qemu-system-ppc64: error creating device tree: node: FDT_ERR_EXISTS

Use defaults_enabled() when creating the default BMC devices to let
the user provide its own BMC devices using '-nodefaults'. If no BMC
device are provided, output a warning but let QEMU run as this is a
supported configuration. However, when multiple BMC devices are
defined, stop QEMU with a clear error as the results are unexpected.

Fixes: e2392d4395dd ("ppc/pnv: Create BMC devices at machine init")
Reported-by: Nathan Chancellor <natechancellor@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20200404153655.166834-1-clg@kaod.org>
Tested-by: Nathan Chancellor <natechancellor@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>

authored by

Cédric Le Goater and committed by
David Gibson
25f3170b a872e432

+74 -5
+27 -5
hw/ppc/pnv.c
··· 571 571 572 572 static void pnv_reset(MachineState *machine) 573 573 { 574 + PnvMachineState *pnv = PNV_MACHINE(machine); 575 + IPMIBmc *bmc; 574 576 void *fdt; 575 577 576 578 qemu_devices_reset(); 579 + 580 + /* 581 + * The machine should provide by default an internal BMC simulator. 582 + * If not, try to use the BMC device that was provided on the command 583 + * line. 584 + */ 585 + bmc = pnv_bmc_find(&error_fatal); 586 + if (!pnv->bmc) { 587 + if (!bmc) { 588 + warn_report("machine has no BMC device. Use '-device " 589 + "ipmi-bmc-sim,id=bmc0 -device isa-ipmi-bt,bmc=bmc0,irq=10' " 590 + "to define one"); 591 + } else { 592 + pnv_bmc_set_pnor(bmc, pnv->pnor); 593 + pnv->bmc = bmc; 594 + } 595 + } 577 596 578 597 fdt = pnv_dt_create(machine); 579 598 ··· 833 852 } 834 853 g_free(chip_typename); 835 854 836 - /* Create the machine BMC simulator */ 837 - pnv->bmc = pnv_bmc_create(pnv->pnor); 838 - 839 855 /* Instantiate ISA bus on chip 0 */ 840 856 pnv->isa_bus = pnv_isa_create(pnv->chips[0], &error_fatal); 841 857 ··· 845 861 /* Create an RTC ISA device too */ 846 862 mc146818_rtc_init(pnv->isa_bus, 2000, NULL); 847 863 848 - /* Create the IPMI BT device for communication with the BMC */ 849 - pnv_ipmi_bt_init(pnv->isa_bus, pnv->bmc, 10); 864 + /* 865 + * Create the machine BMC simulator and the IPMI BT device for 866 + * communication with the BMC 867 + */ 868 + if (defaults_enabled()) { 869 + pnv->bmc = pnv_bmc_create(pnv->pnor); 870 + pnv_ipmi_bt_init(pnv->isa_bus, pnv->bmc, 10); 871 + } 850 872 851 873 /* 852 874 * OpenPOWER systems use a IPMI SEL Event message to notify the
+45
hw/ppc/pnv_bmc.c
··· 213 213 .cmd_handlers = hiomap_cmds 214 214 }; 215 215 216 + 217 + void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor) 218 + { 219 + object_ref(OBJECT(pnor)); 220 + object_property_add_const_link(OBJECT(bmc), "pnor", OBJECT(pnor), 221 + &error_abort); 222 + 223 + /* Install the HIOMAP protocol handlers to access the PNOR */ 224 + ipmi_sim_register_netfn(IPMI_BMC_SIMULATOR(bmc), IPMI_NETFN_OEM, 225 + &hiomap_netfn); 226 + } 227 + 216 228 /* 217 229 * Instantiate the machine BMC. PowerNV uses the QEMU internal 218 230 * simulator but it could also be external. ··· 232 244 233 245 return IPMI_BMC(obj); 234 246 } 247 + 248 + typedef struct ForeachArgs { 249 + const char *name; 250 + Object *obj; 251 + } ForeachArgs; 252 + 253 + static int bmc_find(Object *child, void *opaque) 254 + { 255 + ForeachArgs *args = opaque; 256 + 257 + if (object_dynamic_cast(child, args->name)) { 258 + if (args->obj) { 259 + return 1; 260 + } 261 + args->obj = child; 262 + } 263 + return 0; 264 + } 265 + 266 + IPMIBmc *pnv_bmc_find(Error **errp) 267 + { 268 + ForeachArgs args = { TYPE_IPMI_BMC_SIMULATOR, NULL }; 269 + int ret; 270 + 271 + ret = object_child_foreach_recursive(object_get_root(), bmc_find, &args); 272 + if (ret) { 273 + error_setg(errp, "machine should have only one BMC device. " 274 + "Use '-nodefaults'"); 275 + return NULL; 276 + } 277 + 278 + return args.obj ? IPMI_BMC(args.obj) : NULL; 279 + }
+2
include/hw/ppc/pnv.h
··· 241 241 void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt); 242 242 void pnv_bmc_powerdown(IPMIBmc *bmc); 243 243 IPMIBmc *pnv_bmc_create(PnvPnor *pnor); 244 + IPMIBmc *pnv_bmc_find(Error **errp); 245 + void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor); 244 246 245 247 /* 246 248 * POWER8 MMIO base addresses