[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 29/50] spapr_drc: Allow FDT fragment to be added late
From: |
David Gibson |
Subject: |
[Qemu-devel] [PULL 29/50] spapr_drc: Allow FDT fragment to be added later |
Date: |
Tue, 26 Feb 2019 15:52:43 +1100 |
From: Greg Kurz <address@hidden>
The current logic is to provide the FDT fragment when attaching a device
to a DRC. This works perfectly fine for our current hotplug support, but
soon we will add support for PHB hotplug which has some constraints, that
CPU, PCI and LMB devices don't seem to have.
The first constraint is that the "ibm,dma-window" property of the PHB
node requires the IOMMU to be configured, ie, spapr_tce_table_enable()
has been called, which happens during PHB reset. It is okay in the case
of hotplug since the device is reset before the hotplug handler is
called. On the contrary with coldplug, the hotplug handler is called
first and device is only reset during the initial system reset. Trying
to create the FDT fragment on the hotplug path in this case, would
result in somthing like this:
ibm,dma-window = < 0x80000000 0x00 0x00 0x00 0x00 >;
This will cause linux in the guest to panic, by simply removing and
re-adding the PHB using the drmgr command:
page = alloc_pages_node(nid, GFP_KERNEL, get_order(sz));
if (!page)
panic("iommu_init_table: Can't allocate %ld bytes\n", sz);
The second and maybe more problematic constraint is that the
"interrupt-map" property needs to reference the interrupt controller
node using the very same phandle that SLOF has already exposed to the
guest. QEMU requires SLOF to call the private KVMPPC_H_UPDATE_DT hcall
at some point to know about this phandle. With the latest QEMU and SLOF,
this happens when SLOF gets quiesced. This means that if the PHB gets
hotplugged after CAS but before SLOF quiesce, then we're sure that the
phandle is not known when the hotplug handler is called.
The FDT is only needed when the guest first invokes RTAS to configure
the connector actually, long after SLOF quiesce. Let's postpone the
creation of FDT fragments for PHBs to rtas_ibm_configure_connector().
Since we only need this for PHBs, introduce a new method in the base
DRC class for that. DRC subtypes will be converted to use it in
subsequent patches.
Allow spapr_drc_attach() to be passed a NULL fdt argument if the method
is available. When all DRC subtypes have been converted, the fdt argument
will eventually disappear.
Signed-off-by: Greg Kurz <address@hidden>
Message-Id: <address@hidden>
Signed-off-by: David Gibson <address@hidden>
---
hw/ppc/spapr_drc.c | 36 +++++++++++++++++++++++++++++++-----
include/hw/ppc/spapr_drc.h | 6 ++++++
2 files changed, 37 insertions(+), 5 deletions(-)
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 2edb7d1e9c..66b965a0a7 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -22,6 +22,7 @@
#include "qemu/error-report.h"
#include "hw/ppc/spapr.h" /* for RTAS return codes */
#include "hw/pci-host/spapr.h" /* spapr_phb_remove_pci_device_cb callback */
+#include "sysemu/device_tree.h"
#include "trace.h"
#define DRC_CONTAINER_PATH "/dr-connector"
@@ -376,6 +377,8 @@ static void prop_get_fdt(Object *obj, Visitor *v, const
char *name,
void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
int fdt_start_offset, Error **errp)
{
+ sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+
trace_spapr_drc_attach(spapr_drc_index(drc));
if (drc->dev) {
@@ -384,11 +387,14 @@ void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState
*d, void *fdt,
}
g_assert((drc->state == SPAPR_DRC_STATE_LOGICAL_UNUSABLE)
|| (drc->state == SPAPR_DRC_STATE_PHYSICAL_POWERON));
- g_assert(fdt);
+ g_assert(fdt || drck->dt_populate);
drc->dev = d;
- drc->fdt = fdt;
- drc->fdt_start_offset = fdt_start_offset;
+
+ if (fdt) {
+ drc->fdt = fdt;
+ drc->fdt_start_offset = fdt_start_offset;
+ }
object_property_add_link(OBJECT(drc), "device",
object_get_typename(OBJECT(drc->dev)),
@@ -1102,10 +1108,30 @@ static void rtas_ibm_configure_connector(PowerPCCPU
*cpu,
goto out;
}
- g_assert(drc->fdt);
-
drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+ g_assert(drc->fdt || drck->dt_populate);
+
+ if (!drc->fdt) {
+ Error *local_err = NULL;
+ void *fdt;
+ int fdt_size;
+
+ fdt = create_device_tree(&fdt_size);
+
+ if (drck->dt_populate(drc, spapr, fdt, &drc->fdt_start_offset,
+ &local_err)) {
+ g_free(fdt);
+ error_free(local_err);
+ rc = SPAPR_DR_CC_RESPONSE_ERROR;
+ goto out;
+ }
+
+ drc->fdt = fdt;
+ drc->ccs_offset = drc->fdt_start_offset;
+ drc->ccs_depth = 0;
+ }
+
do {
uint32_t tag;
const char *name;
diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h
index f6ff32e7e2..2aa919f0cf 100644
--- a/include/hw/ppc/spapr_drc.h
+++ b/include/hw/ppc/spapr_drc.h
@@ -18,6 +18,7 @@
#include "qom/object.h"
#include "sysemu/sysemu.h"
#include "hw/qdev.h"
+#include "qapi/error.h"
#define TYPE_SPAPR_DR_CONNECTOR "spapr-dr-connector"
#define SPAPR_DR_CONNECTOR_GET_CLASS(obj) \
@@ -213,6 +214,8 @@ typedef struct sPAPRDRConnector {
int fdt_start_offset;
} sPAPRDRConnector;
+struct sPAPRMachineState;
+
typedef struct sPAPRDRConnectorClass {
/*< private >*/
DeviceClass parent;
@@ -228,6 +231,9 @@ typedef struct sPAPRDRConnectorClass {
uint32_t (*isolate)(sPAPRDRConnector *drc);
uint32_t (*unisolate)(sPAPRDRConnector *drc);
void (*release)(DeviceState *dev);
+
+ int (*dt_populate)(sPAPRDRConnector *drc, struct sPAPRMachineState *spapr,
+ void *fdt, int *fdt_start_offset, Error **errp);
} sPAPRDRConnectorClass;
typedef struct sPAPRDRCPhysical {
--
2.20.1
- [Qemu-devel] [PULL 16/50] tests/device-plug: Add CPU core unplug request test for spapr, (continued)
- [Qemu-devel] [PULL 16/50] tests/device-plug: Add CPU core unplug request test for spapr, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 25/50] target/ppc: Flush the TLB locally when the LPIDR is written, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 23/50] target/ppc: Add basic support for "new format" HPTE as found on POWER9, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 26/50] target/ppc: Rename PATB/PATBE -> PATE, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 22/50] target/ppc: Fix ordering of hash MMU accesses, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 28/50] target/ppc: Basic POWER9 bare-metal radix MMU support, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 27/50] target/ppc: Support for POWER9 native hash, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 36/50] spapr_irq: Expose the phandle of the interrupt controller, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 30/50] spapr: Generate FDT fragment for LMBs at configure connector time, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 35/50] spapr: Expose the name of the interrupt controller node, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 29/50] spapr_drc: Allow FDT fragment to be added later,
David Gibson <=
- [Qemu-devel] [PULL 39/50] spapr: populate PHB DRC entries for root DT node, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 33/50] spapr/drc: Drop spapr_drc_attach() fdt argument, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 38/50] spapr: create DR connectors for PHBs, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 46/50] ppc/xive: xive does not have a POWER7 interrupt model, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 50/50] ppc/pnv: use IEC binary prefixes to represent sizes, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 42/50] spapr_pci: add ibm, my-drc-index property for PHB hotplug, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 49/50] ppc/pnv: add INITRD_MAX_SIZE constant, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 32/50] spapr/pci: Generate FDT fragment at configure connector time, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 34/50] xics: Write source state to KVM at claim time, David Gibson, 2019/02/25
- [Qemu-devel] [PULL 37/50] spapr_pci: add PHB unrealize, David Gibson, 2019/02/25