* [PATCH] ppc/pnv: Create BMC devices only when defaults are enabled
@ 2020-04-04 15:36 Cédric Le Goater
2020-04-04 21:44 ` Nathan Chancellor
2020-04-06 1:00 ` David Gibson
0 siblings, 2 replies; 4+ messages in thread
From: Cédric Le Goater @ 2020-04-04 15:36 UTC (permalink / raw)
To: David Gibson
Cc: Corey Minyard, Greg Kurz, qemu-devel, qemu-ppc,
Cédric Le Goater, Oliver O'Halloran, Nathan Chancellor
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>
---
include/hw/ppc/pnv.h | 2 ++
hw/ppc/pnv.c | 32 ++++++++++++++++++++++++++-----
hw/ppc/pnv_bmc.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 74 insertions(+), 5 deletions(-)
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index fb4d0c0234b3..d4b0b0e2ff71 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -241,6 +241,8 @@ struct PnvMachineState {
void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt);
void pnv_bmc_powerdown(IPMIBmc *bmc);
IPMIBmc *pnv_bmc_create(PnvPnor *pnor);
+IPMIBmc *pnv_bmc_find(Error **errp);
+void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor);
/*
* POWER8 MMIO base addresses
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index ac83b8698b8e..a3b7a8d0ff32 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -573,10 +573,29 @@ static void pnv_powerdown_notify(Notifier *n, void *opaque)
static void pnv_reset(MachineState *machine)
{
+ PnvMachineState *pnv = PNV_MACHINE(machine);
+ IPMIBmc *bmc;
void *fdt;
qemu_devices_reset();
+ /*
+ * 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) {
+ 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 = pnv_dt_create(machine);
/* Pack resulting tree */
@@ -835,9 +854,6 @@ static void pnv_init(MachineState *machine)
}
g_free(chip_typename);
- /* Create the machine BMC simulator */
- pnv->bmc = pnv_bmc_create(pnv->pnor);
-
/* Instantiate ISA bus on chip 0 */
pnv->isa_bus = pnv_isa_create(pnv->chips[0], &error_fatal);
@@ -847,8 +863,14 @@ static void pnv_init(MachineState *machine)
/* Create an RTC ISA device too */
mc146818_rtc_init(pnv->isa_bus, 2000, NULL);
- /* Create the IPMI BT device for communication with the BMC */
- pnv_ipmi_bt_init(pnv->isa_bus, pnv->bmc, 10);
+ /*
+ * Create the machine BMC simulator and the IPMI BT device for
+ * communication with the BMC
+ */
+ if (defaults_enabled()) {
+ pnv->bmc = pnv_bmc_create(pnv->pnor);
+ pnv_ipmi_bt_init(pnv->isa_bus, pnv->bmc, 10);
+ }
/*
* OpenPOWER systems use a IPMI SEL Event message to notify the
diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
index 8863354c1c08..4e018b8b70e4 100644
--- a/hw/ppc/pnv_bmc.c
+++ b/hw/ppc/pnv_bmc.c
@@ -213,6 +213,18 @@ static const IPMINetfn hiomap_netfn = {
.cmd_handlers = hiomap_cmds
};
+
+void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor)
+{
+ object_ref(OBJECT(pnor));
+ object_property_add_const_link(OBJECT(bmc), "pnor", OBJECT(pnor),
+ &error_abort);
+
+ /* Install the HIOMAP protocol handlers to access the PNOR */
+ ipmi_sim_register_netfn(IPMI_BMC_SIMULATOR(bmc), IPMI_NETFN_OEM,
+ &hiomap_netfn);
+}
+
/*
* Instantiate the machine BMC. PowerNV uses the QEMU internal
* simulator but it could also be external.
@@ -232,3 +244,36 @@ IPMIBmc *pnv_bmc_create(PnvPnor *pnor)
return IPMI_BMC(obj);
}
+
+typedef struct ForeachArgs {
+ const char *name;
+ Object *obj;
+} ForeachArgs;
+
+static int bmc_find(Object *child, void *opaque)
+{
+ ForeachArgs *args = opaque;
+
+ if (object_dynamic_cast(child, args->name)) {
+ if (args->obj) {
+ return 1;
+ }
+ args->obj = child;
+ }
+ return 0;
+}
+
+IPMIBmc *pnv_bmc_find(Error **errp)
+{
+ ForeachArgs args = { TYPE_IPMI_BMC_SIMULATOR, NULL };
+ int ret;
+
+ ret = object_child_foreach_recursive(object_get_root(), bmc_find, &args);
+ if (ret) {
+ error_setg(errp, "machine should have only one BMC device. "
+ "Use '-nodefaults'");
+ return NULL;
+ }
+
+ return args.obj ? IPMI_BMC(args.obj) : NULL;
+}
--
2.25.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] ppc/pnv: Create BMC devices only when defaults are enabled
2020-04-04 15:36 [PATCH] ppc/pnv: Create BMC devices only when defaults are enabled Cédric Le Goater
@ 2020-04-04 21:44 ` Nathan Chancellor
2020-04-05 7:06 ` Cédric Le Goater
2020-04-06 1:00 ` David Gibson
1 sibling, 1 reply; 4+ messages in thread
From: Nathan Chancellor @ 2020-04-04 21:44 UTC (permalink / raw)
To: Cédric Le Goater
Cc: Corey Minyard, qemu-devel, Greg Kurz, qemu-ppc,
Oliver O'Halloran, David Gibson
Hi Cédric,
On Sat, Apr 04, 2020 at 05:36:55PM +0200, Cédric Le Goater wrote:
> 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>
This fixes my issue when -nodefaults is passed and that does not regress
QEMU 3.1.0 or 4.2.0. Thank you for the quick fix!
Tested-by: Nathan Chancellor <natechancellor@gmail.com>
A few comments inline.
> ---
> include/hw/ppc/pnv.h | 2 ++
> hw/ppc/pnv.c | 32 ++++++++++++++++++++++++++-----
> hw/ppc/pnv_bmc.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 74 insertions(+), 5 deletions(-)
>
> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
> index fb4d0c0234b3..d4b0b0e2ff71 100644
> --- a/include/hw/ppc/pnv.h
> +++ b/include/hw/ppc/pnv.h
> @@ -241,6 +241,8 @@ struct PnvMachineState {
> void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt);
> void pnv_bmc_powerdown(IPMIBmc *bmc);
> IPMIBmc *pnv_bmc_create(PnvPnor *pnor);
> +IPMIBmc *pnv_bmc_find(Error **errp);
> +void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor);
>
> /*
> * POWER8 MMIO base addresses
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index ac83b8698b8e..a3b7a8d0ff32 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -573,10 +573,29 @@ static void pnv_powerdown_notify(Notifier *n, void *opaque)
>
> static void pnv_reset(MachineState *machine)
> {
> + PnvMachineState *pnv = PNV_MACHINE(machine);
> + IPMIBmc *bmc;
> void *fdt;
>
> qemu_devices_reset();
>
> + /*
> + * 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) {
> + 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");
If I pass no -device flags + -nodefaults, I don't see this message. Is
that expected?
> + } else {
> + pnv_bmc_set_pnor(bmc, pnv->pnor);
> + pnv->bmc = bmc;
> + }
> + }
> +
> fdt = pnv_dt_create(machine);
>
> /* Pack resulting tree */
> @@ -835,9 +854,6 @@ static void pnv_init(MachineState *machine)
> }
> g_free(chip_typename);
>
> - /* Create the machine BMC simulator */
> - pnv->bmc = pnv_bmc_create(pnv->pnor);
> -
> /* Instantiate ISA bus on chip 0 */
> pnv->isa_bus = pnv_isa_create(pnv->chips[0], &error_fatal);
>
> @@ -847,8 +863,14 @@ static void pnv_init(MachineState *machine)
> /* Create an RTC ISA device too */
> mc146818_rtc_init(pnv->isa_bus, 2000, NULL);
>
> - /* Create the IPMI BT device for communication with the BMC */
> - pnv_ipmi_bt_init(pnv->isa_bus, pnv->bmc, 10);
> + /*
> + * Create the machine BMC simulator and the IPMI BT device for
> + * communication with the BMC
> + */
> + if (defaults_enabled()) {
> + pnv->bmc = pnv_bmc_create(pnv->pnor);
> + pnv_ipmi_bt_init(pnv->isa_bus, pnv->bmc, 10);
> + }
>
> /*
> * OpenPOWER systems use a IPMI SEL Event message to notify the
> diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
> index 8863354c1c08..4e018b8b70e4 100644
> --- a/hw/ppc/pnv_bmc.c
> +++ b/hw/ppc/pnv_bmc.c
> @@ -213,6 +213,18 @@ static const IPMINetfn hiomap_netfn = {
> .cmd_handlers = hiomap_cmds
> };
>
> +
> +void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor)
> +{
> + object_ref(OBJECT(pnor));
> + object_property_add_const_link(OBJECT(bmc), "pnor", OBJECT(pnor),
> + &error_abort);
> +
> + /* Install the HIOMAP protocol handlers to access the PNOR */
> + ipmi_sim_register_netfn(IPMI_BMC_SIMULATOR(bmc), IPMI_NETFN_OEM,
> + &hiomap_netfn);
> +}
> +
> /*
> * Instantiate the machine BMC. PowerNV uses the QEMU internal
> * simulator but it could also be external.
> @@ -232,3 +244,36 @@ IPMIBmc *pnv_bmc_create(PnvPnor *pnor)
>
> return IPMI_BMC(obj);
> }
> +
> +typedef struct ForeachArgs {
> + const char *name;
> + Object *obj;
> +} ForeachArgs;
> +
> +static int bmc_find(Object *child, void *opaque)
> +{
> + ForeachArgs *args = opaque;
> +
> + if (object_dynamic_cast(child, args->name)) {
> + if (args->obj) {
> + return 1;
> + }
> + args->obj = child;
> + }
> + return 0;
> +}
> +
> +IPMIBmc *pnv_bmc_find(Error **errp)
> +{
> + ForeachArgs args = { TYPE_IPMI_BMC_SIMULATOR, NULL };
> + int ret;
> +
> + ret = object_child_foreach_recursive(object_get_root(), bmc_find, &args);
> + if (ret) {
> + error_setg(errp, "machine should have only one BMC device. "
> + "Use '-nodefaults'");
When passing the -device flags in the commit message as I did in my
original command without -nodefaults, I still see the
qemu-system-ppc64: error creating device tree: node: FDT_ERR_EXISTS
message. Is that expected?
> + return NULL;
> + }
> +
> + return args.obj ? IPMI_BMC(args.obj) : NULL;
> +}
> --
> 2.25.1
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] ppc/pnv: Create BMC devices only when defaults are enabled
2020-04-04 21:44 ` Nathan Chancellor
@ 2020-04-05 7:06 ` Cédric Le Goater
0 siblings, 0 replies; 4+ messages in thread
From: Cédric Le Goater @ 2020-04-05 7:06 UTC (permalink / raw)
To: Nathan Chancellor
Cc: Corey Minyard, qemu-devel, Greg Kurz, qemu-ppc,
Oliver O'Halloran, David Gibson
On 4/4/20 11:44 PM, Nathan Chancellor wrote:
> Hi Cédric,
>
> On Sat, Apr 04, 2020 at 05:36:55PM +0200, Cédric Le Goater wrote:
>> 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>
>
> This fixes my issue when -nodefaults is passed and that does not regress
> QEMU 3.1.0 or 4.2.0. Thank you for the quick fix!
>
> Tested-by: Nathan Chancellor <natechancellor@gmail.com>
>
> A few comments inline.
>
>> ---
>> include/hw/ppc/pnv.h | 2 ++
>> hw/ppc/pnv.c | 32 ++++++++++++++++++++++++++-----
>> hw/ppc/pnv_bmc.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 74 insertions(+), 5 deletions(-)
>>
>> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
>> index fb4d0c0234b3..d4b0b0e2ff71 100644
>> --- a/include/hw/ppc/pnv.h
>> +++ b/include/hw/ppc/pnv.h
>> @@ -241,6 +241,8 @@ struct PnvMachineState {
>> void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt);
>> void pnv_bmc_powerdown(IPMIBmc *bmc);
>> IPMIBmc *pnv_bmc_create(PnvPnor *pnor);
>> +IPMIBmc *pnv_bmc_find(Error **errp);
>> +void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor);
>>
>> /*
>> * POWER8 MMIO base addresses
>> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
>> index ac83b8698b8e..a3b7a8d0ff32 100644
>> --- a/hw/ppc/pnv.c
>> +++ b/hw/ppc/pnv.c
>> @@ -573,10 +573,29 @@ static void pnv_powerdown_notify(Notifier *n, void *opaque)
>>
>> static void pnv_reset(MachineState *machine)
>> {
>> + PnvMachineState *pnv = PNV_MACHINE(machine);
>> + IPMIBmc *bmc;
>> void *fdt;
>>
>> qemu_devices_reset();
>>
>> + /*
>> + * 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) {
>> + 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");
>
> If I pass no -device flags + -nodefaults, I don't see this message. Is
> that expected?
yes. Because the machine instantiates the default BMC devices.
>
>> + } else {
>> + pnv_bmc_set_pnor(bmc, pnv->pnor);
>> + pnv->bmc = bmc;
>> + }
>> + }
>> +
>> fdt = pnv_dt_create(machine);
>>
>> /* Pack resulting tree */
>> @@ -835,9 +854,6 @@ static void pnv_init(MachineState *machine)
>> }
>> g_free(chip_typename);
>>
>> - /* Create the machine BMC simulator */
>> - pnv->bmc = pnv_bmc_create(pnv->pnor);
>> -
>> /* Instantiate ISA bus on chip 0 */
>> pnv->isa_bus = pnv_isa_create(pnv->chips[0], &error_fatal);
>>
>> @@ -847,8 +863,14 @@ static void pnv_init(MachineState *machine)
>> /* Create an RTC ISA device too */
>> mc146818_rtc_init(pnv->isa_bus, 2000, NULL);
>>
>> - /* Create the IPMI BT device for communication with the BMC */
>> - pnv_ipmi_bt_init(pnv->isa_bus, pnv->bmc, 10);
>> + /*
>> + * Create the machine BMC simulator and the IPMI BT device for
>> + * communication with the BMC
>> + */
>> + if (defaults_enabled()) {
>> + pnv->bmc = pnv_bmc_create(pnv->pnor);
>> + pnv_ipmi_bt_init(pnv->isa_bus, pnv->bmc, 10);
>> + }
>>
>> /*
>> * OpenPOWER systems use a IPMI SEL Event message to notify the
>> diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
>> index 8863354c1c08..4e018b8b70e4 100644
>> --- a/hw/ppc/pnv_bmc.c
>> +++ b/hw/ppc/pnv_bmc.c
>> @@ -213,6 +213,18 @@ static const IPMINetfn hiomap_netfn = {
>> .cmd_handlers = hiomap_cmds
>> };
>>
>> +
>> +void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor)
>> +{
>> + object_ref(OBJECT(pnor));
>> + object_property_add_const_link(OBJECT(bmc), "pnor", OBJECT(pnor),
>> + &error_abort);
>> +
>> + /* Install the HIOMAP protocol handlers to access the PNOR */
>> + ipmi_sim_register_netfn(IPMI_BMC_SIMULATOR(bmc), IPMI_NETFN_OEM,
>> + &hiomap_netfn);
>> +}
>> +
>> /*
>> * Instantiate the machine BMC. PowerNV uses the QEMU internal
>> * simulator but it could also be external.
>> @@ -232,3 +244,36 @@ IPMIBmc *pnv_bmc_create(PnvPnor *pnor)
>>
>> return IPMI_BMC(obj);
>> }
>> +
>> +typedef struct ForeachArgs {
>> + const char *name;
>> + Object *obj;
>> +} ForeachArgs;
>> +
>> +static int bmc_find(Object *child, void *opaque)
>> +{
>> + ForeachArgs *args = opaque;
>> +
>> + if (object_dynamic_cast(child, args->name)) {
>> + if (args->obj) {
>> + return 1;
>> + }
>> + args->obj = child;
>> + }
>> + return 0;
>> +}
>> +
>> +IPMIBmc *pnv_bmc_find(Error **errp)
>> +{
>> + ForeachArgs args = { TYPE_IPMI_BMC_SIMULATOR, NULL };
>> + int ret;
>> +
>> + ret = object_child_foreach_recursive(object_get_root(), bmc_find, &args);
>> + if (ret) {
>> + error_setg(errp, "machine should have only one BMC device. "
>> + "Use '-nodefaults'");
>
> When passing the -device flags in the commit message as I did in my
> original command without -nodefaults, I still see the
>
> qemu-system-ppc64: error creating device tree: node: FDT_ERR_EXISTS
>
> message. Is that expected?
object_child_foreach_recursive() is broken. Here is the fix :
http://patchwork.ozlabs.org/patch/1266419/
Sorry. I should have copied you.
But there are other ways to find multiple instances of the same type.
May be we will need to rework that part a bit.
Thanks,
C.
>
>> + return NULL;
>> + }
>> +
>> + return args.obj ? IPMI_BMC(args.obj) : NULL;
>> +}
>> --
>> 2.25.1
>>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] ppc/pnv: Create BMC devices only when defaults are enabled
2020-04-04 15:36 [PATCH] ppc/pnv: Create BMC devices only when defaults are enabled Cédric Le Goater
2020-04-04 21:44 ` Nathan Chancellor
@ 2020-04-06 1:00 ` David Gibson
1 sibling, 0 replies; 4+ messages in thread
From: David Gibson @ 2020-04-06 1:00 UTC (permalink / raw)
To: Cédric Le Goater
Cc: Corey Minyard, Greg Kurz, qemu-devel, qemu-ppc,
Oliver O'Halloran, Nathan Chancellor
[-- Attachment #1: Type: text/plain, Size: 5826 bytes --]
On Sat, Apr 04, 2020 at 05:36:55PM +0200, Cédric Le Goater wrote:
> 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>
As a regression fix, applied to ppc-for-5.0.
> ---
> include/hw/ppc/pnv.h | 2 ++
> hw/ppc/pnv.c | 32 ++++++++++++++++++++++++++-----
> hw/ppc/pnv_bmc.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 74 insertions(+), 5 deletions(-)
>
> diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
> index fb4d0c0234b3..d4b0b0e2ff71 100644
> --- a/include/hw/ppc/pnv.h
> +++ b/include/hw/ppc/pnv.h
> @@ -241,6 +241,8 @@ struct PnvMachineState {
> void pnv_dt_bmc_sensors(IPMIBmc *bmc, void *fdt);
> void pnv_bmc_powerdown(IPMIBmc *bmc);
> IPMIBmc *pnv_bmc_create(PnvPnor *pnor);
> +IPMIBmc *pnv_bmc_find(Error **errp);
> +void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor);
>
> /*
> * POWER8 MMIO base addresses
> diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
> index ac83b8698b8e..a3b7a8d0ff32 100644
> --- a/hw/ppc/pnv.c
> +++ b/hw/ppc/pnv.c
> @@ -573,10 +573,29 @@ static void pnv_powerdown_notify(Notifier *n, void *opaque)
>
> static void pnv_reset(MachineState *machine)
> {
> + PnvMachineState *pnv = PNV_MACHINE(machine);
> + IPMIBmc *bmc;
> void *fdt;
>
> qemu_devices_reset();
>
> + /*
> + * 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) {
> + 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 = pnv_dt_create(machine);
>
> /* Pack resulting tree */
> @@ -835,9 +854,6 @@ static void pnv_init(MachineState *machine)
> }
> g_free(chip_typename);
>
> - /* Create the machine BMC simulator */
> - pnv->bmc = pnv_bmc_create(pnv->pnor);
> -
> /* Instantiate ISA bus on chip 0 */
> pnv->isa_bus = pnv_isa_create(pnv->chips[0], &error_fatal);
>
> @@ -847,8 +863,14 @@ static void pnv_init(MachineState *machine)
> /* Create an RTC ISA device too */
> mc146818_rtc_init(pnv->isa_bus, 2000, NULL);
>
> - /* Create the IPMI BT device for communication with the BMC */
> - pnv_ipmi_bt_init(pnv->isa_bus, pnv->bmc, 10);
> + /*
> + * Create the machine BMC simulator and the IPMI BT device for
> + * communication with the BMC
> + */
> + if (defaults_enabled()) {
> + pnv->bmc = pnv_bmc_create(pnv->pnor);
> + pnv_ipmi_bt_init(pnv->isa_bus, pnv->bmc, 10);
> + }
>
> /*
> * OpenPOWER systems use a IPMI SEL Event message to notify the
> diff --git a/hw/ppc/pnv_bmc.c b/hw/ppc/pnv_bmc.c
> index 8863354c1c08..4e018b8b70e4 100644
> --- a/hw/ppc/pnv_bmc.c
> +++ b/hw/ppc/pnv_bmc.c
> @@ -213,6 +213,18 @@ static const IPMINetfn hiomap_netfn = {
> .cmd_handlers = hiomap_cmds
> };
>
> +
> +void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor)
> +{
> + object_ref(OBJECT(pnor));
> + object_property_add_const_link(OBJECT(bmc), "pnor", OBJECT(pnor),
> + &error_abort);
> +
> + /* Install the HIOMAP protocol handlers to access the PNOR */
> + ipmi_sim_register_netfn(IPMI_BMC_SIMULATOR(bmc), IPMI_NETFN_OEM,
> + &hiomap_netfn);
> +}
> +
> /*
> * Instantiate the machine BMC. PowerNV uses the QEMU internal
> * simulator but it could also be external.
> @@ -232,3 +244,36 @@ IPMIBmc *pnv_bmc_create(PnvPnor *pnor)
>
> return IPMI_BMC(obj);
> }
> +
> +typedef struct ForeachArgs {
> + const char *name;
> + Object *obj;
> +} ForeachArgs;
> +
> +static int bmc_find(Object *child, void *opaque)
> +{
> + ForeachArgs *args = opaque;
> +
> + if (object_dynamic_cast(child, args->name)) {
> + if (args->obj) {
> + return 1;
> + }
> + args->obj = child;
> + }
> + return 0;
> +}
> +
> +IPMIBmc *pnv_bmc_find(Error **errp)
> +{
> + ForeachArgs args = { TYPE_IPMI_BMC_SIMULATOR, NULL };
> + int ret;
> +
> + ret = object_child_foreach_recursive(object_get_root(), bmc_find, &args);
> + if (ret) {
> + error_setg(errp, "machine should have only one BMC device. "
> + "Use '-nodefaults'");
> + return NULL;
> + }
> +
> + return args.obj ? IPMI_BMC(args.obj) : NULL;
> +}
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-04-06 1:31 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-04 15:36 [PATCH] ppc/pnv: Create BMC devices only when defaults are enabled Cédric Le Goater
2020-04-04 21:44 ` Nathan Chancellor
2020-04-05 7:06 ` Cédric Le Goater
2020-04-06 1:00 ` David Gibson
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.