From: Alexander Graf <agraf@suse.de>
To: David Gibson <david@gibson.dropbear.id.au>
Cc: aik@ozlabs.ru, mdroth@linux.vnet.ibm.com, qemu-ppc@nongnu.org,
qemu-devel@nongnu.org, afaerber@suse.de
Subject: Re: [Qemu-devel] [PATCH 17/33] spapr_drc: initial implementation of sPAPRDRConnector device
Date: Fri, 08 May 2015 00:39:20 +0200 [thread overview]
Message-ID: <554BE998.3070300@suse.de> (raw)
In-Reply-To: <1430976839-13944-18-git-send-email-david@gibson.dropbear.id.au>
On 07.05.15 07:33, David Gibson wrote:
> From: Michael Roth <mdroth@linux.vnet.ibm.com>
>
> This device emulates a firmware abstraction used by pSeries guests to
> manage hotplug/dynamic-reconfiguration of host-bridges, PCI devices,
> memory, and CPUs. It is conceptually similar to an SHPC device,
> complete with LED indicators to identify individual slots to physical
> physical users and indicate when it is safe to remove a device. In
> some cases it is also used to manage virtualized resources, such a
> memory, CPUs, and physical-host bridges, which in the case of pSeries
> guests are virtualized resources where the physical components are
> managed by the host.
>
> Guests communicate with these DR Connectors using RTAS calls,
> generally by addressing the unique DRC index associated with a
> particular connector for a particular resource. For introspection
> purposes we expose this state initially as QOM properties, and
> in subsequent patches will introduce the RTAS calls that make use of
> it. This constitutes to the 'guest' interface.
>
> On the QEMU side we provide an attach/detach interface to associate
> or cleanup a DeviceState with a particular sPAPRDRConnector in
> response to hotplug/unplug, respectively. This constitutes the
> 'physical' interface to the DR Connector.
>
> Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
> ---
> hw/ppc/Makefile.objs | 2 +-
> hw/ppc/spapr_drc.c | 588 +++++++++++++++++++++++++++++++++++++++++++++
> include/hw/ppc/spapr_drc.h | 199 +++++++++++++++
> 3 files changed, 788 insertions(+), 1 deletion(-)
> create mode 100644 hw/ppc/spapr_drc.c
> create mode 100644 include/hw/ppc/spapr_drc.h
>
> diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
> index 437955d..c8ab06e 100644
> --- a/hw/ppc/Makefile.objs
> +++ b/hw/ppc/Makefile.objs
> @@ -3,7 +3,7 @@ obj-y += ppc.o ppc_booke.o
> # IBM pSeries (sPAPR)
> obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o
> obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o
> -obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o
> +obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o
> ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy)
> obj-y += spapr_pci_vfio.o
> endif
> diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
> new file mode 100644
> index 0000000..047c6c7
> --- /dev/null
> +++ b/hw/ppc/spapr_drc.c
> @@ -0,0 +1,588 @@
> +/*
> + * QEMU SPAPR Dynamic Reconfiguration Connector Implementation
> + *
> + * Copyright IBM Corp. 2014
> + *
> + * Authors:
> + * Michael Roth <mdroth@linux.vnet.ibm.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +
> +#include "hw/ppc/spapr_drc.h"
> +#include "qom/object.h"
> +#include "hw/qdev.h"
> +#include "qapi/visitor.h"
> +#include "qemu/error-report.h"
> +
> +/* #define DEBUG_SPAPR_DRC */
> +
> +#ifdef DEBUG_SPAPR_DRC
> +#define DPRINTF(fmt, ...) \
> + do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
> +#define DPRINTFN(fmt, ...) \
> + do { DPRINTF(fmt, ## __VA_ARGS__); fprintf(stderr, "\n"); } while (0)
> +#else
> +#define DPRINTF(fmt, ...) \
> + do { } while (0)
> +#define DPRINTFN(fmt, ...) \
> + do { } while (0)
> +#endif
> +
> +#define DRC_CONTAINER_PATH "/dr-connector"
> +#define DRC_INDEX_TYPE_SHIFT 28
> +#define DRC_INDEX_ID_MASK (~(~0 << DRC_INDEX_TYPE_SHIFT))
> +
> +static sPAPRDRConnectorTypeShift get_type_shift(sPAPRDRConnectorType type)
> +{
> + uint32_t shift = 0;
> +
> + /* make sure this isn't SPAPR_DR_CONNECTOR_TYPE_ANY, or some
> + * other wonky value.
> + */
> + g_assert(is_power_of_2(type));
> +
> + while (type != (1 << shift)) {
> + shift++;
> + }
> + return shift;
> +}
> +
> +static uint32_t get_index(sPAPRDRConnector *drc)
> +{
> + /* no set format for a drc index: it only needs to be globally
> + * unique. this is how we encode the DRC type on bare-metal
> + * however, so might as well do that here
> + */
> + return (get_type_shift(drc->type) << DRC_INDEX_TYPE_SHIFT) |
> + (drc->id & DRC_INDEX_ID_MASK);
> +}
> +
> +static int set_isolation_state(sPAPRDRConnector *drc,
> + sPAPRDRIsolationState state)
> +{
> + sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
> +
> + DPRINTFN("drc: %x, set_isolation_state: %x", get_index(drc), state);
> +
> + drc->isolation_state = state;
> +
> + if (drc->isolation_state == SPAPR_DR_ISOLATION_STATE_ISOLATED) {
> + /* if we're awaiting release, but still in an unconfigured state,
> + * it's likely the guest is still in the process of configuring
> + * the device and is transitioning the devices to an ISOLATED
> + * state as a part of that process. so we only complete the
> + * removal when this transition happens for a device in a
> + * configured state, as suggested by the state diagram from
> + * PAPR+ 2.7, 13.4
> + */
> + if (drc->awaiting_release) {
> + if (drc->configured) {
> + DPRINTFN("finalizing device removal");
> + drck->detach(drc, DEVICE(drc->dev), drc->detach_cb,
> + drc->detach_cb_opaque, NULL);
> + } else {
> + DPRINTFN("deferring device removal on unconfigured device\n");
> + }
> + }
> + drc->configured = false;
> + }
> +
> + return 0;
> +}
> +
> +static int set_indicator_state(sPAPRDRConnector *drc,
> + sPAPRDRIndicatorState state)
> +{
> + DPRINTFN("drc: %x, set_indicator_state: %x", get_index(drc), state);
> + drc->indicator_state = state;
> + return 0;
> +}
> +
> +static int set_allocation_state(sPAPRDRConnector *drc,
> + sPAPRDRAllocationState state)
> +{
> + sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
> +
> + DPRINTFN("drc: %x, set_allocation_state: %x", get_index(drc), state);
> +
> + if (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI) {
> + drc->allocation_state = state;
> + if (drc->awaiting_release &&
> + drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
> + DPRINTFN("finalizing device removal");
> + drck->detach(drc, DEVICE(drc->dev), drc->detach_cb,
> + drc->detach_cb_opaque, NULL);
> + }
> + }
> + return 0;
> +}
> +
> +static uint32_t get_type(sPAPRDRConnector *drc)
> +{
> + return drc->type;
> +}
> +
> +static const char *get_name(sPAPRDRConnector *drc)
> +{
> + return drc->name;
> +}
> +
> +static const void *get_fdt(sPAPRDRConnector *drc, int *fdt_start_offset)
> +{
> + if (fdt_start_offset) {
> + *fdt_start_offset = drc->fdt_start_offset;
> + }
> + return drc->fdt;
> +}
> +
> +static void set_configured(sPAPRDRConnector *drc)
> +{
> + DPRINTFN("drc: %x, set_configured", get_index(drc));
> +
> + if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_UNISOLATED) {
> + /* guest should be not configuring an isolated device */
> + DPRINTFN("drc: %x, set_configured: skipping isolated device",
> + get_index(drc));
> + return;
> + }
> + drc->configured = true;
> +}
> +
> +/*
> + * dr-entity-sense sensor value
> + * returned via get-sensor-state RTAS calls
> + * as expected by state diagram in PAPR+ 2.7, 13.4
> + * based on the current allocation/indicator/power states
> + * for the DR connector.
> + */
> +static sPAPRDREntitySense entity_sense(sPAPRDRConnector *drc)
> +{
> + sPAPRDREntitySense state;
> +
> + if (drc->dev) {
> + if (drc->type != SPAPR_DR_CONNECTOR_TYPE_PCI &&
> + drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
> + /* for logical DR, we return a state of UNUSABLE
> + * iff the allocation state UNUSABLE.
> + * Otherwise, report the state as USABLE/PRESENT,
> + * as we would for PCI.
> + */
> + state = SPAPR_DR_ENTITY_SENSE_UNUSABLE;
> + } else {
> + /* this assumes all PCI devices are assigned to
> + * a 'live insertion' power domain, where QEMU
> + * manages power state automatically as opposed
> + * to the guest. present, non-PCI resources are
> + * unaffected by power state.
> + */
> + state = SPAPR_DR_ENTITY_SENSE_PRESENT;
> + }
> + } else {
> + if (drc->type == SPAPR_DR_CONNECTOR_TYPE_PCI) {
> + /* PCI devices, and only PCI devices, use EMPTY
> + * in cases where we'd otherwise use UNUSABLE
> + */
> + state = SPAPR_DR_ENTITY_SENSE_EMPTY;
> + } else {
> + state = SPAPR_DR_ENTITY_SENSE_UNUSABLE;
> + }
> + }
> +
> + DPRINTFN("drc: %x, entity_sense: %x", get_index(drc), state);
> + return state;
> +}
> +
> +static void prop_get_index(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
> + sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
> + uint32_t value = (uint32_t)drck->get_index(drc);
> + visit_type_uint32(v, &value, name, errp);
> +}
> +
> +static void prop_get_type(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
> + sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
> + uint32_t value = (uint32_t)drck->get_type(drc);
> + visit_type_uint32(v, &value, name, errp);
> +}
> +
> +static char *prop_get_name(Object *obj, Error **errp)
> +{
> + sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
> + sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
> + return g_strdup(drck->get_name(drc));
> +}
> +
> +static void prop_get_entity_sense(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
> + sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
> + uint32_t value = (uint32_t)drck->entity_sense(drc);
> + visit_type_uint32(v, &value, name, errp);
> +}
> +
> +static void prop_get_fdt(Object *obj, Visitor *v, void *opaque,
> + const char *name, Error **errp)
> +{
> + sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(obj);
> + int fdt_offset_next, fdt_offset, fdt_depth;
> + void *fdt;
> +
> + if (!drc->fdt) {
> + return;
> + }
> +
> + fdt = drc->fdt;
> + fdt_offset = drc->fdt_start_offset;
> + fdt_depth = 0;
> +
> + do {
> + const char *name = NULL;
> + const struct fdt_property *prop = NULL;
> + int prop_len = 0, name_len = 0;
> + uint32_t tag;
> +
> + tag = fdt_next_tag(fdt, fdt_offset, &fdt_offset_next);
> + switch (tag) {
> + case FDT_BEGIN_NODE:
> + fdt_depth++;
> + name = fdt_get_name(fdt, fdt_offset, &name_len);
> + visit_start_struct(v, NULL, NULL, name, 0, NULL);
> + break;
> + case FDT_END_NODE:
> + /* shouldn't ever see an FDT_END_NODE before FDT_BEGIN_NODE */
> + g_assert(fdt_depth > 0);
> + visit_end_struct(v, NULL);
> + fdt_depth--;
> + break;
> + case FDT_PROP: {
> + int i;
> + prop = fdt_get_property_by_offset(fdt, fdt_offset, &prop_len);
Did this fdt function only get introduced recently? My test system has
1.3.0 installed which doesn't contain it apparently.
Please add a configure check to verify it actually exists if it's really
necessary.
Alex
next prev parent reply other threads:[~2015-05-07 22:39 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-07 5:33 [Qemu-devel] [PATCH 00/33] Accumulated -machine pseries patches 2015-05-07 David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 01/33] spapr_pci: Fix unsafe signed/unsigned comparisons David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 02/33] spapr_iommu: Disable in-kernel IOMMU tables for >4GB windows David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 03/33] spapr_iommu: Make H_PUT_TCE_INDIRECT endian-safe David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 04/33] spapr_pci: Introduce a liobn number generating macros David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 05/33] spapr_vio: " David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 06/33] spapr_pci: Define default DMA window size as a macro David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 07/33] spapr_iommu: Add separate trace points for PCI DMA operations David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 08/33] spapr_pci: Make find_phb()/find_dev() public David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 09/33] spapr_iommu: Make spapr_tce_find_by_liobn() public David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 10/33] spapr_pci: Rework device-tree rendering David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 11/33] spapr_iommu: Give unique QOM name to TCE table David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 12/33] hw/ppc/spapr_iommu: Fix the check for invalid upper bits in liobn David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 13/33] pseries: Add pseries-2.4 machine type David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 14/33] hw/ppc/spapr: Fix error message when firmware could not be loaded David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 15/33] hw/ppc/spapr: Use error_report() instead of hw_error() David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 16/33] docs: add sPAPR hotplug/dynamic-reconfiguration documentation David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 17/33] spapr_drc: initial implementation of sPAPRDRConnector device David Gibson
2015-05-07 22:39 ` Alexander Graf [this message]
2015-05-08 0:01 ` David Gibson
2015-05-11 21:02 ` Alexander Graf
2015-05-07 5:33 ` [Qemu-devel] [PATCH 18/33] spapr_rtas: add get/set-power-level RTAS interfaces David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 19/33] spapr_rtas: add set-indicator RTAS interface David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 20/33] spapr_rtas: add get-sensor-state " David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 21/33] spapr: add rtas_st_buffer_direct() helper David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 22/33] spapr_rtas: add ibm, configure-connector RTAS interface David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 23/33] spapr_events: re-use EPOW event infrastructure for hotplug events David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 24/33] spapr_events: event-scan RTAS interface David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 25/33] spapr_drc: add spapr_drc_populate_dt() David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 26/33] spapr_pci: add dynamic-reconfiguration option for spapr-pci-host-bridge David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 27/33] spapr_pci: create DRConnectors for each PCI slot during PHB realize David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 28/33] pci: make pci_bar useable outside pci.c David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 29/33] spapr_pci: enable basic hotplug operations David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 30/33] spapr_pci: emit hotplug add/remove events during hotplug David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 31/33] machine: add default_ram_size to machine class David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 32/33] spapr: override default ram size to 512MB David Gibson
2015-05-07 5:33 ` [Qemu-devel] [PATCH 33/33] pseries: Enable in-kernel H_LOGICAL_CI_{LOAD, STORE} implementations David Gibson
2015-05-07 22:24 ` [Qemu-devel] [PATCH 00/33] Accumulated -machine pseries patches 2015-05-07 Alexander Graf
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=554BE998.3070300@suse.de \
--to=agraf@suse.de \
--cc=afaerber@suse.de \
--cc=aik@ozlabs.ru \
--cc=david@gibson.dropbear.id.au \
--cc=mdroth@linux.vnet.ibm.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
/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.