All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: Michael Roth <mdroth@linux.vnet.ibm.com>
Cc: aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de,
	ncmike@ncultra.org, qemu-ppc@nongnu.org,
	tyreld@linux.vnet.ibm.com, bharata.rao@gmail.com,
	nfont@linux.vnet.ibm.com
Subject: Re: [Qemu-devel] [PATCH v4 10/17] spapr_drc: add spapr_drc_populate_dt()
Date: Mon, 19 Jan 2015 16:15:28 +1100	[thread overview]
Message-ID: <20150119051528.GT5297@voom.fritz.box> (raw)
In-Reply-To: <1419337831-16552-11-git-send-email-mdroth@linux.vnet.ibm.com>

[-- Attachment #1: Type: text/plain, Size: 10925 bytes --]

On Tue, Dec 23, 2014 at 06:30:24AM -0600, Michael Roth wrote:
> This function handles generation of ibm,drc-* array device tree
> properties to describe DRC topology to guests. This will by used
> by the guest to direct RTAS calls to manage any dynamic resources
> we associate with a particular DR Connector as part of
> hotplug/unplug.
> 
> Since general management of boot-time device trees are handled
> outside of sPAPRDRConnector, we insert these values blindly given
> an FDT and offset. A mask of sPAPRDRConnector types is given to
> instruct us on what types of connectors entries should be generated
> for, since descriptions for different connectors may live in
> different parts of the device tree.
> 
> Based on code originally written by Nathan Fontenot.
> 
> Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
> ---
>  hw/ppc/spapr_drc.c         | 225 +++++++++++++++++++++++++++++++++++++++++++++
>  include/hw/ppc/spapr_drc.h |   3 +-
>  2 files changed, 227 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
> index f81c6d1..b162184 100644
> --- a/hw/ppc/spapr_drc.c
> +++ b/hw/ppc/spapr_drc.c
> @@ -501,3 +501,228 @@ sPAPRDRConnector *spapr_dr_connector_by_id(sPAPRDRConnectorType type,
>              (get_type_shift(type) << DRC_INDEX_TYPE_SHIFT) |
>              (id & DRC_INDEX_ID_MASK));
>  }
> +
> +/* internal helper to gather up DRC info specific to populating DRC
> + * topology information in the device tree.
> + */
> +typedef struct DRConnectorDTInfo {
> +    char drc_type[64];
> +    char drc_name[64];
> +    uint32_t drc_index;
> +    uint32_t drc_power_domain;
> +} DRConnectorDTInfo;
> +
> +/* generate a string the describes the DRC to encode into the
> + * device tree.
> + *
> + * as documented by PAPR+ v2.7, 13.5.2.6 and C.6.1
> + */
> +static void spapr_drc_get_type_str(char *buf, sPAPRDRConnectorType type)
> +{
> +    switch (type) {
> +    case SPAPR_DR_CONNECTOR_TYPE_CPU:
> +        sprintf(buf, "CPU");
> +        break;
> +    case SPAPR_DR_CONNECTOR_TYPE_PHB:
> +        sprintf(buf, "PHB");
> +        break;
> +    case SPAPR_DR_CONNECTOR_TYPE_VIO:
> +        sprintf(buf, "SLOT");
> +        break;
> +    case SPAPR_DR_CONNECTOR_TYPE_PCI:
> +        sprintf(buf, "28");
> +        break;
> +    case SPAPR_DR_CONNECTOR_TYPE_LMB:
> +        sprintf(buf, "MEM");
> +        break;
> +    default:
> +        g_assert(false);
> +    }

So this case is simple enough that you can probably get away with it,
but still - interfaces that involve writing to a buffer without any
length checks make me very nervous.

> +}
> +
> +/* generate a human-readable name for a DRC to encode into the DT
> + * description. this is mainly only used within a guest in place
> + * of the unique DRC index.
> + *
> + * in the case of VIO/PCI devices, it corresponds to a
> + * "location code" that maps a logical device/function (DRC index)
> + * to a physical (or virtual in the case of VIO) location in the
> + * system by chaining together the "location label" for each
> + * encapsulating component.
> + *
> + * since this is more to do with diagnosing physical hardware
> + * issues than guest compatibility, we choose location codes/DRC
> + * names that adhere to the documented format, but avoid encoding
> + * the entire topology information into the label/code, instead
> + * just using the location codes based on the labels for the
> + * endpoints (VIO/PCI adaptor connectors), which is basically
> + * just "C" followed by an integer ID.

Hrm.. would it make sense to include here the qemu "id" value on the
DRC device?  That will make names which are matchable to specific
elements on the qemu command line, which about as close an equivalent
to a physical location as I can think of.

> + * DRC names as documented by PAPR+ v2.7, 13.5.2.4
> + * location codes as documented by PAPR+ v2.7, 12.3.1.5
> + */
> +static void spapr_drc_get_name_str(char *buf,
> +                                   sPAPRDRConnectorType type,
> +                                   uint32_t drc_index)
> +{
> +    uint32_t id = drc_index & DRC_INDEX_ID_MASK;
> +
> +    switch (type) {
> +    case SPAPR_DR_CONNECTOR_TYPE_CPU:
> +        sprintf(buf, "CPU %d", id);
> +        break;
> +    case SPAPR_DR_CONNECTOR_TYPE_PHB:
> +        sprintf(buf, "PHB %d", id);
> +        break;
> +    case SPAPR_DR_CONNECTOR_TYPE_VIO:
> +    case SPAPR_DR_CONNECTOR_TYPE_PCI:
> +        sprintf(buf, "C%d", id);
> +        break;
> +    case SPAPR_DR_CONNECTOR_TYPE_LMB:
> +        sprintf(buf, "LMB %d", id);
> +        break;
> +    default:
> +        g_assert(false);
> +    }
> +}
> +
> +static DRConnectorDTInfo *spapr_dr_connector_get_info(uint32_t drc_type_mask,
> +                                                      unsigned int *count)
> +{
> +    Object *root_container;
> +    ObjectProperty *prop;
> +    GArray *drc_info_list = g_array_new(false, true,
> +                                        sizeof(DRConnectorDTInfo));
> +
> +    /* aliases for all DRConnector objects will be rooted in QOM
> +     * composition tree at /dr-connector
> +     */
> +    root_container = container_get(object_get_root(), "/dr-connector");
> +
> +    QTAILQ_FOREACH(prop, &root_container->properties, node) {
> +        Object *obj;
> +        sPAPRDRConnector *drc;
> +        sPAPRDRConnectorClass *drck;
> +        DRConnectorDTInfo drc_info;
> +
> +        if (!strstart(prop->type, "link<", NULL)) {
> +            continue;
> +        }
> +
> +        obj = object_property_get_link(root_container, prop->name, NULL);
> +        drc = SPAPR_DR_CONNECTOR(obj);
> +        drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
> +
> +        if ((drc->type & drc_type_mask) == 0) {
> +            continue;
> +        }
> +
> +        drc_info.drc_index = drck->get_index(drc);
> +        drc_info.drc_power_domain = -1;
> +        spapr_drc_get_type_str(drc_info.drc_type, drc->type);
> +        spapr_drc_get_name_str(drc_info.drc_name, drc->type,
> +                               drck->get_index(drc));
> +        g_array_append_val(drc_info_list, drc_info);
> +    }
> +
> +    if (count) {
> +        *count = drc_info_list->len;
> +    }
> +
> +    /* if count is zero, free everything, including internal storage
> +     * for array
> +     */
> +    return (DRConnectorDTInfo *)g_array_free(drc_info_list, count == 0);
> +}
> +
> +/**
> + * spapr_drc_populate_dt
> + *
> + * @fdt: libfdt device tree
> + * @path: path in the DT to generate properties
> + * @drc_type_mask: mask of sPAPRDRConnectorType values corresponding
> + *   to the types of DRCs to generate entries for
> + *
> + * generate OF properties to describe DRC topology/indices to guests
> + *
> + * as documented in PAPR+ v2.1, 13.5.2
> + */
> +int spapr_drc_populate_dt(void *fdt, int fdt_offset, uint32_t drc_type_mask)
> +{
> +    DRConnectorDTInfo *drc_info_list;
> +    unsigned int i, count;
> +    char *char_buf;
> +    uint32_t *char_buf_count;
> +    uint32_t *int_buf;
> +    int char_buf_offset, ret;
> +
> +    drc_info_list =
> +        spapr_dr_connector_get_info(drc_type_mask, &count);

This is the only call to spapr_dt_connector_get_info().  I don't see a
lot of point in splitting it out from this function, since it involves
a not particular easy to work with array encoding of the information.
Why not go direct from the drc objects to the fdt.

> +    if (!count) {
> +        return 0;
> +    }
> +
> +    int_buf = g_new0(uint32_t, count + 1);
> +    int_buf[0] = cpu_to_be32(count);
> +    char_buf = g_new0(char, count * 128 + sizeof(uint32_t));
> +    char_buf_count = (uint32_t *)&char_buf[0];
> +    *char_buf_count = cpu_to_be32(count);
> +
> +    /* ibm,drc-indexes */
> +    for (i = 0; i < count; i++) {
> +        int_buf[i + 1] = cpu_to_be32(drc_info_list[i].drc_index);
> +    }
> +    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-indexes", int_buf,
> +                      (count + 1) * sizeof(uint32_t));
> +    if (ret) {
> +        fprintf(stderr, "Couldn't create ibm,drc-indexes property\n");
> +        goto out;
> +    }
> +
> +    /* ibm,drc-power-domains */
> +    for (i = 0; i < count; i++) {
> +        int_buf[i + 1] = cpu_to_be32(drc_info_list[i].drc_power_domain);
> +    }
> +    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-power-domains", int_buf,
> +                      (count + 1) * sizeof(uint32_t));
> +    if (ret) {
> +        fprintf(stderr, "Couldn't finalize ibm,drc-power-domains property\n");
> +        goto out;
> +    }
> +
> +    /* ibm,drc-names */
> +    char_buf_offset = sizeof(uint32_t);
> +
> +    for (i = 0; i < count; i++) {
> +        strcpy(char_buf + char_buf_offset, drc_info_list[i].drc_name);
> +        char_buf_offset += strlen(drc_info_list[i].drc_name) + 1;
> +    }
> +    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-names", char_buf,
> +                      char_buf_offset);
> +    if (ret) {
> +        fprintf(stderr, "Couldn't finalize ibm,drc-names property\n");
> +        goto out;
> +    }
> +
> +    /* ibm,drc-types */
> +    char_buf_offset = sizeof(uint32_t);
> +
> +    for (i = 0; i < count; i++) {
> +        strcpy(char_buf + char_buf_offset, drc_info_list[i].drc_type);
> +        char_buf_offset += strlen(drc_info_list[i].drc_type) + 1;
> +    }
> +
> +    ret = fdt_setprop(fdt, fdt_offset, "ibm,drc-types", char_buf,
> +                      char_buf_offset);
> +    if (ret) {
> +        fprintf(stderr, "Couldn't finalize ibm,drc-types property\n");
> +        goto out;
> +    }
> +
> +out:
> +    g_free(int_buf);
> +    g_free(char_buf);
> +    g_free(drc_info_list);
> +    return ret;
> +}
> diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h
> index 63ec687..5c70140 100644
> --- a/include/hw/ppc/spapr_drc.h
> +++ b/include/hw/ppc/spapr_drc.h
> @@ -193,9 +193,10 @@ typedef struct sPAPRDRConnectorClass {
>  
>  sPAPRDRConnector *spapr_dr_connector_new(Object *owner,
>                                           sPAPRDRConnectorType type,
> -                                         uint32_t token);
> +                                         uint32_t id);
>  sPAPRDRConnector *spapr_dr_connector_by_index(uint32_t index);
>  sPAPRDRConnector *spapr_dr_connector_by_id(sPAPRDRConnectorType type,
>                                             uint32_t id);
> +int spapr_drc_populate_dt(void *fdt, int fdt_offset, uint32_t drc_type_mask);
>  
>  #endif /* __HW_SPAPR_DRC_H__ */

-- 
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: Type: application/pgp-signature, Size: 819 bytes --]

  reply	other threads:[~2015-01-19  5:58 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-23 12:30 [Qemu-devel] [PATCH v4 00/17] spapr: add support for pci hotplug Michael Roth
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 01/17] docs: add sPAPR hotplug/dynamic-reconfiguration documentation Michael Roth
2015-01-16  5:28   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 02/17] spapr_drc: initial implementation of sPAPRDRConnector device Michael Roth
2015-01-02 10:32   ` Bharata B Rao
2015-01-26  4:56     ` Michael Roth
2015-01-16  6:19   ` David Gibson
2015-01-26  4:01     ` Michael Roth
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 03/17] spapr_rtas: add get/set-power-level RTAS interfaces Michael Roth
2015-01-16  6:21   ` David Gibson
2015-01-26  5:21     ` Michael Roth
2015-01-27  5:24       ` David Gibson
2015-01-27 21:36         ` Michael Roth
2015-01-27 22:05           ` Tyrel Datwyler
2015-01-28  0:42             ` Michael Roth
2015-02-09 16:29               ` Nathan Fontenot
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 04/17] spapr_rtas: add set-indicator RTAS interface Michael Roth
2015-01-16  6:25   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 05/17] spapr_rtas: add get-sensor-state " Michael Roth
2015-01-16  6:28   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 06/17] spapr: add rtas_st_buffer_direct() helper Michael Roth
2015-01-19  3:25   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 07/17] spapr_rtas: add ibm, configure-connector RTAS interface Michael Roth
2015-01-19  3:44   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 08/17] spapr_events: re-use EPOW event infrastructure for hotplug events Michael Roth
2015-01-19  4:31   ` David Gibson
2015-01-26 16:56     ` Michael Roth
2015-01-27  5:27       ` David Gibson
2015-01-28  3:56       ` Bharata B Rao
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 09/17] spapr_events: event-scan RTAS interface Michael Roth
2015-01-19  4:34   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 10/17] spapr_drc: add spapr_drc_populate_dt() Michael Roth
2015-01-19  5:15   ` David Gibson [this message]
2015-01-26 20:35     ` Michael Roth
2015-01-27  5:30       ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 11/17] spapr: introduce pseries-2.3 machine type Michael Roth
2015-01-19  5:16   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 12/17] spapr_pci: add dynamic-reconfiguration option for spapr-pci-host-bridge Michael Roth
2015-01-19  5:18   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 13/17] spapr_pci: create DRConnectors for each PCI slot during PHB realize Michael Roth
2015-01-19  5:20   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 14/17] spapr_pci: populate DRC dt entries for PHBs Michael Roth
2015-01-19  5:22   ` David Gibson
2015-01-26 20:44     ` Michael Roth
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 15/17] pci: make pci_bar useable outside pci.c Michael Roth
2015-01-19  5:24   ` David Gibson
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 16/17] spapr_pci: enable basic hotplug operations Michael Roth
2015-01-19  5:58   ` David Gibson
2015-01-26 21:17     ` Michael Roth
2015-01-27  5:37       ` David Gibson
2015-01-23  5:17   ` Alexey Kardashevskiy
2015-01-26 21:20     ` Michael Roth
2014-12-23 12:30 ` [Qemu-devel] [PATCH v4 17/17] spapr_pci: emit hotplug add/remove events during hotplug Michael Roth
2015-01-19  6:00   ` David Gibson
2015-01-26 21:32     ` Michael Roth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150119051528.GT5297@voom.fritz.box \
    --to=david@gibson.dropbear.id.au \
    --cc=agraf@suse.de \
    --cc=aik@ozlabs.ru \
    --cc=bharata.rao@gmail.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=ncmike@ncultra.org \
    --cc=nfont@linux.vnet.ibm.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=tyreld@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.