Message ID | 1477370856-8940-9-git-send-email-mdroth@linux.vnet.ibm.com |
---|---|
State | New |
Headers | show |
On Mon, Oct 24, 2016 at 11:47:34PM -0500, Michael Roth wrote: > From: Bharata B Rao <bharata@linux.vnet.ibm.com> > > Add support for DRC count indexed hotplug ID type which is primarily > needed for memory hot unplug. This type allows for specifying the > number of DRs that should be plugged/unplugged starting from a given > DRC index. > > Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com> > * updated rtas_event_log_v6_hp to reflect count/index field ordering > used in PAPR hotplug ACR > Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com> Reviewed-by: David Gibson <david@gibson.dropbear.id.au> > --- > hw/ppc/spapr_events.c | 76 ++++++++++++++++++++++++++++++++++++++++---------- > include/hw/ppc/spapr.h | 4 +++ > 2 files changed, 65 insertions(+), 15 deletions(-) > > diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c > index b6b3511..596e991 100644 > --- a/hw/ppc/spapr_events.c > +++ b/hw/ppc/spapr_events.c > @@ -175,6 +175,16 @@ struct epow_log_full { > struct rtas_event_log_v6_epow epow; > } QEMU_PACKED; > > +union drc_identifier { > + uint32_t index; > + uint32_t count; > + struct { > + uint32_t count; > + uint32_t index; > + } count_indexed; > + char name[1]; > +} QEMU_PACKED; > + > struct rtas_event_log_v6_hp { > #define RTAS_LOG_V6_SECTION_ID_HOTPLUG 0x4850 /* HP */ > struct rtas_event_log_v6_section_header hdr; > @@ -191,12 +201,9 @@ struct rtas_event_log_v6_hp { > #define RTAS_LOG_V6_HP_ID_DRC_NAME 1 > #define RTAS_LOG_V6_HP_ID_DRC_INDEX 2 > #define RTAS_LOG_V6_HP_ID_DRC_COUNT 3 > +#define RTAS_LOG_V6_HP_ID_DRC_COUNT_INDEXED 4 > uint8_t reserved; > - union { > - uint32_t index; > - uint32_t count; > - char name[1]; > - } drc; > + union drc_identifier drc_id; > } QEMU_PACKED; > > struct hp_log_full { > @@ -496,7 +503,7 @@ static void spapr_hotplug_set_signalled(uint32_t drc_index) > > static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action, > sPAPRDRConnectorType drc_type, > - uint32_t drc) > + union drc_identifier *drc_id) > { > sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); > struct hp_log_full *new_hp; > @@ -541,7 +548,7 @@ static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action, > case SPAPR_DR_CONNECTOR_TYPE_PCI: > hp->hotplug_type = RTAS_LOG_V6_HP_TYPE_PCI; > if (hp->hotplug_action == RTAS_LOG_V6_HP_ACTION_ADD) { > - spapr_hotplug_set_signalled(drc); > + spapr_hotplug_set_signalled(drc_id->index); > } > break; > case SPAPR_DR_CONNECTOR_TYPE_LMB: > @@ -559,9 +566,18 @@ static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action, > } > > if (hp_id == RTAS_LOG_V6_HP_ID_DRC_COUNT) { > - hp->drc.count = cpu_to_be32(drc); > + hp->drc_id.count = cpu_to_be32(drc_id->count); > } else if (hp_id == RTAS_LOG_V6_HP_ID_DRC_INDEX) { > - hp->drc.index = cpu_to_be32(drc); > + hp->drc_id.index = cpu_to_be32(drc_id->index); > + } else if (hp_id == RTAS_LOG_V6_HP_ID_DRC_COUNT_INDEXED) { > + /* we should not be using count_indexed value unless the guest > + * supports dedicated hotplug event source > + */ > + g_assert(spapr_ovec_test(spapr->ov5_cas, OV5_HP_EVT)); > + hp->drc_id.count_indexed.count = > + cpu_to_be32(drc_id->count_indexed.count); > + hp->drc_id.count_indexed.index = > + cpu_to_be32(drc_id->count_indexed.index); > } > > rtas_event_log_queue(RTAS_LOG_TYPE_HOTPLUG, new_hp, true); > @@ -575,34 +591,64 @@ void spapr_hotplug_req_add_by_index(sPAPRDRConnector *drc) > { > sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); > sPAPRDRConnectorType drc_type = drck->get_type(drc); > - uint32_t index = drck->get_index(drc); > + union drc_identifier drc_id; > > + drc_id.index = drck->get_index(drc); > spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_INDEX, > - RTAS_LOG_V6_HP_ACTION_ADD, drc_type, index); > + RTAS_LOG_V6_HP_ACTION_ADD, drc_type, &drc_id); > } > > void spapr_hotplug_req_remove_by_index(sPAPRDRConnector *drc) > { > sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); > sPAPRDRConnectorType drc_type = drck->get_type(drc); > - uint32_t index = drck->get_index(drc); > + union drc_identifier drc_id; > > + drc_id.index = drck->get_index(drc); > spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_INDEX, > - RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, index); > + RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, &drc_id); > } > > void spapr_hotplug_req_add_by_count(sPAPRDRConnectorType drc_type, > uint32_t count) > { > + union drc_identifier drc_id; > + > + drc_id.count = count; > spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_COUNT, > - RTAS_LOG_V6_HP_ACTION_ADD, drc_type, count); > + RTAS_LOG_V6_HP_ACTION_ADD, drc_type, &drc_id); > } > > void spapr_hotplug_req_remove_by_count(sPAPRDRConnectorType drc_type, > uint32_t count) > { > + union drc_identifier drc_id; > + > + drc_id.count = count; > spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_COUNT, > - RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, count); > + RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, &drc_id); > +} > + > +void spapr_hotplug_req_add_by_count_indexed(sPAPRDRConnectorType drc_type, > + uint32_t count, uint32_t index) > +{ > + union drc_identifier drc_id; > + > + drc_id.count_indexed.count = count; > + drc_id.count_indexed.index = index; > + spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_COUNT_INDEXED, > + RTAS_LOG_V6_HP_ACTION_ADD, drc_type, &drc_id); > +} > + > +void spapr_hotplug_req_remove_by_count_indexed(sPAPRDRConnectorType drc_type, > + uint32_t count, uint32_t index) > +{ > + union drc_identifier drc_id; > + > + drc_id.count_indexed.count = count; > + drc_id.count_indexed.index = index; > + spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_COUNT_INDEXED, > + RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, &drc_id); > } > > static void check_exception(PowerPCCPU *cpu, sPAPRMachineState *spapr, > diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h > index 21af971..bd5bcf7 100644 > --- a/include/hw/ppc/spapr.h > +++ b/include/hw/ppc/spapr.h > @@ -610,6 +610,10 @@ void spapr_hotplug_req_add_by_count(sPAPRDRConnectorType drc_type, > uint32_t count); > void spapr_hotplug_req_remove_by_count(sPAPRDRConnectorType drc_type, > uint32_t count); > +void spapr_hotplug_req_add_by_count_indexed(sPAPRDRConnectorType drc_type, > + uint32_t count, uint32_t index); > +void spapr_hotplug_req_remove_by_count_indexed(sPAPRDRConnectorType drc_type, > + uint32_t count, uint32_t index); > void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu, Error **errp); > void *spapr_populate_hotplug_cpu_dt(CPUState *cs, int *fdt_offset, > sPAPRMachineState *spapr);
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c index b6b3511..596e991 100644 --- a/hw/ppc/spapr_events.c +++ b/hw/ppc/spapr_events.c @@ -175,6 +175,16 @@ struct epow_log_full { struct rtas_event_log_v6_epow epow; } QEMU_PACKED; +union drc_identifier { + uint32_t index; + uint32_t count; + struct { + uint32_t count; + uint32_t index; + } count_indexed; + char name[1]; +} QEMU_PACKED; + struct rtas_event_log_v6_hp { #define RTAS_LOG_V6_SECTION_ID_HOTPLUG 0x4850 /* HP */ struct rtas_event_log_v6_section_header hdr; @@ -191,12 +201,9 @@ struct rtas_event_log_v6_hp { #define RTAS_LOG_V6_HP_ID_DRC_NAME 1 #define RTAS_LOG_V6_HP_ID_DRC_INDEX 2 #define RTAS_LOG_V6_HP_ID_DRC_COUNT 3 +#define RTAS_LOG_V6_HP_ID_DRC_COUNT_INDEXED 4 uint8_t reserved; - union { - uint32_t index; - uint32_t count; - char name[1]; - } drc; + union drc_identifier drc_id; } QEMU_PACKED; struct hp_log_full { @@ -496,7 +503,7 @@ static void spapr_hotplug_set_signalled(uint32_t drc_index) static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action, sPAPRDRConnectorType drc_type, - uint32_t drc) + union drc_identifier *drc_id) { sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); struct hp_log_full *new_hp; @@ -541,7 +548,7 @@ static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action, case SPAPR_DR_CONNECTOR_TYPE_PCI: hp->hotplug_type = RTAS_LOG_V6_HP_TYPE_PCI; if (hp->hotplug_action == RTAS_LOG_V6_HP_ACTION_ADD) { - spapr_hotplug_set_signalled(drc); + spapr_hotplug_set_signalled(drc_id->index); } break; case SPAPR_DR_CONNECTOR_TYPE_LMB: @@ -559,9 +566,18 @@ static void spapr_hotplug_req_event(uint8_t hp_id, uint8_t hp_action, } if (hp_id == RTAS_LOG_V6_HP_ID_DRC_COUNT) { - hp->drc.count = cpu_to_be32(drc); + hp->drc_id.count = cpu_to_be32(drc_id->count); } else if (hp_id == RTAS_LOG_V6_HP_ID_DRC_INDEX) { - hp->drc.index = cpu_to_be32(drc); + hp->drc_id.index = cpu_to_be32(drc_id->index); + } else if (hp_id == RTAS_LOG_V6_HP_ID_DRC_COUNT_INDEXED) { + /* we should not be using count_indexed value unless the guest + * supports dedicated hotplug event source + */ + g_assert(spapr_ovec_test(spapr->ov5_cas, OV5_HP_EVT)); + hp->drc_id.count_indexed.count = + cpu_to_be32(drc_id->count_indexed.count); + hp->drc_id.count_indexed.index = + cpu_to_be32(drc_id->count_indexed.index); } rtas_event_log_queue(RTAS_LOG_TYPE_HOTPLUG, new_hp, true); @@ -575,34 +591,64 @@ void spapr_hotplug_req_add_by_index(sPAPRDRConnector *drc) { sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); sPAPRDRConnectorType drc_type = drck->get_type(drc); - uint32_t index = drck->get_index(drc); + union drc_identifier drc_id; + drc_id.index = drck->get_index(drc); spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_INDEX, - RTAS_LOG_V6_HP_ACTION_ADD, drc_type, index); + RTAS_LOG_V6_HP_ACTION_ADD, drc_type, &drc_id); } void spapr_hotplug_req_remove_by_index(sPAPRDRConnector *drc) { sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); sPAPRDRConnectorType drc_type = drck->get_type(drc); - uint32_t index = drck->get_index(drc); + union drc_identifier drc_id; + drc_id.index = drck->get_index(drc); spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_INDEX, - RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, index); + RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, &drc_id); } void spapr_hotplug_req_add_by_count(sPAPRDRConnectorType drc_type, uint32_t count) { + union drc_identifier drc_id; + + drc_id.count = count; spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_COUNT, - RTAS_LOG_V6_HP_ACTION_ADD, drc_type, count); + RTAS_LOG_V6_HP_ACTION_ADD, drc_type, &drc_id); } void spapr_hotplug_req_remove_by_count(sPAPRDRConnectorType drc_type, uint32_t count) { + union drc_identifier drc_id; + + drc_id.count = count; spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_COUNT, - RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, count); + RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, &drc_id); +} + +void spapr_hotplug_req_add_by_count_indexed(sPAPRDRConnectorType drc_type, + uint32_t count, uint32_t index) +{ + union drc_identifier drc_id; + + drc_id.count_indexed.count = count; + drc_id.count_indexed.index = index; + spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_COUNT_INDEXED, + RTAS_LOG_V6_HP_ACTION_ADD, drc_type, &drc_id); +} + +void spapr_hotplug_req_remove_by_count_indexed(sPAPRDRConnectorType drc_type, + uint32_t count, uint32_t index) +{ + union drc_identifier drc_id; + + drc_id.count_indexed.count = count; + drc_id.count_indexed.index = index; + spapr_hotplug_req_event(RTAS_LOG_V6_HP_ID_DRC_COUNT_INDEXED, + RTAS_LOG_V6_HP_ACTION_REMOVE, drc_type, &drc_id); } static void check_exception(PowerPCCPU *cpu, sPAPRMachineState *spapr, diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 21af971..bd5bcf7 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -610,6 +610,10 @@ void spapr_hotplug_req_add_by_count(sPAPRDRConnectorType drc_type, uint32_t count); void spapr_hotplug_req_remove_by_count(sPAPRDRConnectorType drc_type, uint32_t count); +void spapr_hotplug_req_add_by_count_indexed(sPAPRDRConnectorType drc_type, + uint32_t count, uint32_t index); +void spapr_hotplug_req_remove_by_count_indexed(sPAPRDRConnectorType drc_type, + uint32_t count, uint32_t index); void spapr_cpu_init(sPAPRMachineState *spapr, PowerPCCPU *cpu, Error **errp); void *spapr_populate_hotplug_cpu_dt(CPUState *cs, int *fdt_offset, sPAPRMachineState *spapr);