Message ID | 20201218103400.689660-4-groug@kaod.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | spapr: Fix visibility and traversal of DR connectors | expand |
On 12/18/20 7:33 AM, Greg Kurz wrote: > No need to expose the way DRCs are traversed outside of spapr_drc.c. > > Signed-off-by: Greg Kurz <groug@kaod.org> > --- Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com> > include/hw/ppc/spapr_drc.h | 6 ++++++ > hw/ppc/spapr_drc.c | 31 +++++++++++++++++++++++++++++ > hw/ppc/spapr_hcall.c | 40 ++++++-------------------------------- > 3 files changed, 43 insertions(+), 34 deletions(-) > > diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h > index 5d80019f82e2..8982927d5c24 100644 > --- a/include/hw/ppc/spapr_drc.h > +++ b/include/hw/ppc/spapr_drc.h > @@ -245,6 +245,12 @@ int spapr_dt_drc(void *fdt, int offset, Object *owner, uint32_t drc_type_mask); > void spapr_drc_attach(SpaprDrc *drc, DeviceState *d); > void spapr_drc_detach(SpaprDrc *drc); > > +/* > + * Reset all DRCs, causing pending hot-plug/unplug requests to complete. > + * Safely handles potential DRC removal (eg. PHBs or PCI bridges). > + */ > +void spapr_drc_reset_all(struct SpaprMachineState *spapr); > + > static inline bool spapr_drc_unplug_requested(SpaprDrc *drc) > { > return drc->unplug_requested; > diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c > index 5b5e2ac58a7e..a4d2608017c5 100644 > --- a/hw/ppc/spapr_drc.c > +++ b/hw/ppc/spapr_drc.c > @@ -949,6 +949,37 @@ out: > return ret; > } > > +void spapr_drc_reset_all(SpaprMachineState *spapr) > +{ > + Object *drc_container; > + ObjectProperty *prop; > + ObjectPropertyIterator iter; > + > + drc_container = container_get(object_get_root(), DRC_CONTAINER_PATH); > +restart: > + object_property_iter_init(&iter, drc_container); > + while ((prop = object_property_iter_next(&iter))) { > + SpaprDrc *drc; > + > + if (!strstart(prop->type, "link<", NULL)) { > + continue; > + } > + drc = SPAPR_DR_CONNECTOR(object_property_get_link(drc_container, > + prop->name, > + &error_abort)); > + > + /* > + * This will complete any pending plug/unplug requests. > + * In case of a unplugged PHB or PCI bridge, this will > + * cause some DRCs to be destroyed and thus potentially > + * invalidate the iterator. > + */ > + if (spapr_drc_reset(drc)) { > + goto restart; > + } > + } > +} > + > /* > * RTAS calls > */ > diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c > index aa22830ac4bd..e5dfc1ba7acc 100644 > --- a/hw/ppc/spapr_hcall.c > +++ b/hw/ppc/spapr_hcall.c > @@ -1632,39 +1632,6 @@ static uint32_t cas_check_pvr(PowerPCCPU *cpu, uint32_t max_compat, > return best_compat; > } > > -static void spapr_handle_transient_dev_before_cas(SpaprMachineState *spapr) > -{ > - Object *drc_container; > - ObjectProperty *prop; > - ObjectPropertyIterator iter; > - > - drc_container = container_get(object_get_root(), "/dr-connector"); > -restart: > - object_property_iter_init(&iter, drc_container); > - while ((prop = object_property_iter_next(&iter))) { > - SpaprDrc *drc; > - > - if (!strstart(prop->type, "link<", NULL)) { > - continue; > - } > - drc = SPAPR_DR_CONNECTOR(object_property_get_link(drc_container, > - prop->name, > - &error_abort)); > - > - /* > - * This will complete any pending plug/unplug requests. > - * In case of a unplugged PHB or PCI bridge, this will > - * cause some DRCs to be destroyed and thus potentially > - * invalidate the iterator. > - */ > - if (spapr_drc_reset(drc)) { > - goto restart; > - } > - } > - > - spapr_clear_pending_hotplug_events(spapr); > -} > - > target_ulong do_client_architecture_support(PowerPCCPU *cpu, > SpaprMachineState *spapr, > target_ulong vec, > @@ -1822,7 +1789,12 @@ target_ulong do_client_architecture_support(PowerPCCPU *cpu, > > spapr_irq_update_active_intc(spapr); > > - spapr_handle_transient_dev_before_cas(spapr); > + /* > + * Process all pending hot-plug/unplug requests now. An updated full > + * rendered FDT will be returned to the guest. > + */ > + spapr_drc_reset_all(spapr); > + spapr_clear_pending_hotplug_events(spapr); > > /* > * If spapr_machine_reset() did not set up a HPT but one is necessary >
On Fri, Dec 18, 2020 at 11:33:57AM +0100, Greg Kurz wrote: > No need to expose the way DRCs are traversed outside of spapr_drc.c. > > Signed-off-by: Greg Kurz <groug@kaod.org> Applied, thanks. > --- > include/hw/ppc/spapr_drc.h | 6 ++++++ > hw/ppc/spapr_drc.c | 31 +++++++++++++++++++++++++++++ > hw/ppc/spapr_hcall.c | 40 ++++++-------------------------------- > 3 files changed, 43 insertions(+), 34 deletions(-) > > diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h > index 5d80019f82e2..8982927d5c24 100644 > --- a/include/hw/ppc/spapr_drc.h > +++ b/include/hw/ppc/spapr_drc.h > @@ -245,6 +245,12 @@ int spapr_dt_drc(void *fdt, int offset, Object *owner, uint32_t drc_type_mask); > void spapr_drc_attach(SpaprDrc *drc, DeviceState *d); > void spapr_drc_detach(SpaprDrc *drc); > > +/* > + * Reset all DRCs, causing pending hot-plug/unplug requests to complete. > + * Safely handles potential DRC removal (eg. PHBs or PCI bridges). > + */ > +void spapr_drc_reset_all(struct SpaprMachineState *spapr); > + > static inline bool spapr_drc_unplug_requested(SpaprDrc *drc) > { > return drc->unplug_requested; > diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c > index 5b5e2ac58a7e..a4d2608017c5 100644 > --- a/hw/ppc/spapr_drc.c > +++ b/hw/ppc/spapr_drc.c > @@ -949,6 +949,37 @@ out: > return ret; > } > > +void spapr_drc_reset_all(SpaprMachineState *spapr) > +{ > + Object *drc_container; > + ObjectProperty *prop; > + ObjectPropertyIterator iter; > + > + drc_container = container_get(object_get_root(), DRC_CONTAINER_PATH); > +restart: > + object_property_iter_init(&iter, drc_container); > + while ((prop = object_property_iter_next(&iter))) { > + SpaprDrc *drc; > + > + if (!strstart(prop->type, "link<", NULL)) { > + continue; > + } > + drc = SPAPR_DR_CONNECTOR(object_property_get_link(drc_container, > + prop->name, > + &error_abort)); > + > + /* > + * This will complete any pending plug/unplug requests. > + * In case of a unplugged PHB or PCI bridge, this will > + * cause some DRCs to be destroyed and thus potentially > + * invalidate the iterator. > + */ > + if (spapr_drc_reset(drc)) { > + goto restart; > + } > + } > +} > + > /* > * RTAS calls > */ > diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c > index aa22830ac4bd..e5dfc1ba7acc 100644 > --- a/hw/ppc/spapr_hcall.c > +++ b/hw/ppc/spapr_hcall.c > @@ -1632,39 +1632,6 @@ static uint32_t cas_check_pvr(PowerPCCPU *cpu, uint32_t max_compat, > return best_compat; > } > > -static void spapr_handle_transient_dev_before_cas(SpaprMachineState *spapr) > -{ > - Object *drc_container; > - ObjectProperty *prop; > - ObjectPropertyIterator iter; > - > - drc_container = container_get(object_get_root(), "/dr-connector"); > -restart: > - object_property_iter_init(&iter, drc_container); > - while ((prop = object_property_iter_next(&iter))) { > - SpaprDrc *drc; > - > - if (!strstart(prop->type, "link<", NULL)) { > - continue; > - } > - drc = SPAPR_DR_CONNECTOR(object_property_get_link(drc_container, > - prop->name, > - &error_abort)); > - > - /* > - * This will complete any pending plug/unplug requests. > - * In case of a unplugged PHB or PCI bridge, this will > - * cause some DRCs to be destroyed and thus potentially > - * invalidate the iterator. > - */ > - if (spapr_drc_reset(drc)) { > - goto restart; > - } > - } > - > - spapr_clear_pending_hotplug_events(spapr); > -} > - > target_ulong do_client_architecture_support(PowerPCCPU *cpu, > SpaprMachineState *spapr, > target_ulong vec, > @@ -1822,7 +1789,12 @@ target_ulong do_client_architecture_support(PowerPCCPU *cpu, > > spapr_irq_update_active_intc(spapr); > > - spapr_handle_transient_dev_before_cas(spapr); > + /* > + * Process all pending hot-plug/unplug requests now. An updated full > + * rendered FDT will be returned to the guest. > + */ > + spapr_drc_reset_all(spapr); > + spapr_clear_pending_hotplug_events(spapr); > > /* > * If spapr_machine_reset() did not set up a HPT but one is necessary
diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h index 5d80019f82e2..8982927d5c24 100644 --- a/include/hw/ppc/spapr_drc.h +++ b/include/hw/ppc/spapr_drc.h @@ -245,6 +245,12 @@ int spapr_dt_drc(void *fdt, int offset, Object *owner, uint32_t drc_type_mask); void spapr_drc_attach(SpaprDrc *drc, DeviceState *d); void spapr_drc_detach(SpaprDrc *drc); +/* + * Reset all DRCs, causing pending hot-plug/unplug requests to complete. + * Safely handles potential DRC removal (eg. PHBs or PCI bridges). + */ +void spapr_drc_reset_all(struct SpaprMachineState *spapr); + static inline bool spapr_drc_unplug_requested(SpaprDrc *drc) { return drc->unplug_requested; diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 5b5e2ac58a7e..a4d2608017c5 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -949,6 +949,37 @@ out: return ret; } +void spapr_drc_reset_all(SpaprMachineState *spapr) +{ + Object *drc_container; + ObjectProperty *prop; + ObjectPropertyIterator iter; + + drc_container = container_get(object_get_root(), DRC_CONTAINER_PATH); +restart: + object_property_iter_init(&iter, drc_container); + while ((prop = object_property_iter_next(&iter))) { + SpaprDrc *drc; + + if (!strstart(prop->type, "link<", NULL)) { + continue; + } + drc = SPAPR_DR_CONNECTOR(object_property_get_link(drc_container, + prop->name, + &error_abort)); + + /* + * This will complete any pending plug/unplug requests. + * In case of a unplugged PHB or PCI bridge, this will + * cause some DRCs to be destroyed and thus potentially + * invalidate the iterator. + */ + if (spapr_drc_reset(drc)) { + goto restart; + } + } +} + /* * RTAS calls */ diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index aa22830ac4bd..e5dfc1ba7acc 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -1632,39 +1632,6 @@ static uint32_t cas_check_pvr(PowerPCCPU *cpu, uint32_t max_compat, return best_compat; } -static void spapr_handle_transient_dev_before_cas(SpaprMachineState *spapr) -{ - Object *drc_container; - ObjectProperty *prop; - ObjectPropertyIterator iter; - - drc_container = container_get(object_get_root(), "/dr-connector"); -restart: - object_property_iter_init(&iter, drc_container); - while ((prop = object_property_iter_next(&iter))) { - SpaprDrc *drc; - - if (!strstart(prop->type, "link<", NULL)) { - continue; - } - drc = SPAPR_DR_CONNECTOR(object_property_get_link(drc_container, - prop->name, - &error_abort)); - - /* - * This will complete any pending plug/unplug requests. - * In case of a unplugged PHB or PCI bridge, this will - * cause some DRCs to be destroyed and thus potentially - * invalidate the iterator. - */ - if (spapr_drc_reset(drc)) { - goto restart; - } - } - - spapr_clear_pending_hotplug_events(spapr); -} - target_ulong do_client_architecture_support(PowerPCCPU *cpu, SpaprMachineState *spapr, target_ulong vec, @@ -1822,7 +1789,12 @@ target_ulong do_client_architecture_support(PowerPCCPU *cpu, spapr_irq_update_active_intc(spapr); - spapr_handle_transient_dev_before_cas(spapr); + /* + * Process all pending hot-plug/unplug requests now. An updated full + * rendered FDT will be returned to the guest. + */ + spapr_drc_reset_all(spapr); + spapr_clear_pending_hotplug_events(spapr); /* * If spapr_machine_reset() did not set up a HPT but one is necessary
No need to expose the way DRCs are traversed outside of spapr_drc.c. Signed-off-by: Greg Kurz <groug@kaod.org> --- include/hw/ppc/spapr_drc.h | 6 ++++++ hw/ppc/spapr_drc.c | 31 +++++++++++++++++++++++++++++ hw/ppc/spapr_hcall.c | 40 ++++++-------------------------------- 3 files changed, 43 insertions(+), 34 deletions(-)