qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC PATCH 10/14] spapr_pci: Track guest Partitionable Endp


From: David Gibson
Subject: [Qemu-devel] [RFC PATCH 10/14] spapr_pci: Track guest Partitionable Endpoints
Date: Sat, 19 Sep 2015 17:18:33 +1000

PAPR has a concept of Partitionable Endpoints (PEs) on PCI, which are
groups of devices that can't be isolated from each other, which is used in
the Enhanced Error Handling (EEH) interface.

At the moment, we don't model PEs in our PAPR host bridge implementation.
We get away with it because spapr-pci-host-bridge doesn't support the EEH
interfaces, and spapr-pci-vfio-host-bridge, which does, only supports
devices from a single IOMMU group, and therefore a single PE (although
that's not actually properly enforced).

In order to generalize this, this adds tracking of guest PEs to the PAPR
host bridge code.  For now, at least, we only construct PEs for VFIO
devices, since we don't implement EEH for emulated devices anyway
PEs.

Signed-off-by: David Gibson <address@hidden>
---
 hw/ppc/spapr_pci.c          | 39 +++++++++++++++++++++++++++++++++++++++
 include/hw/pci-host/spapr.h |  8 ++++++++
 2 files changed, 47 insertions(+)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 3a1ebea..81ad3ae 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -423,6 +423,29 @@ static void 
rtas_ibm_query_interrupt_source_number(PowerPCCPU *cpu,
     rtas_st(rets, 2, 1);/* 0 == level; 1 == edge */
 }
 
+static sPAPRPHBGuestPE *spapr_phb_pe_by_device(sPAPRPHBState *phb,
+                                               PCIDevice *pdev)
+{
+    VFIOGroup *group = vfio_pci_device_group(pdev);
+    sPAPRPHBGuestPE *pe;
+
+    if (!group) {
+        return NULL;
+    }
+
+    QLIST_FOREACH(pe, &phb->pe_list, list) {
+        if (pe->group == group) {
+            /* We already have a PE for this group */
+            return pe;
+        }
+    }
+
+    pe = g_malloc0(sizeof(*pe));
+    pe->group = group;
+    QLIST_INSERT_HEAD(&phb->pe_list, pe, list);
+    return pe;
+}
+
 static void rtas_ibm_set_eeh_option(PowerPCCPU *cpu,
                                     sPAPRMachineState *spapr,
                                     uint32_t token, uint32_t nargs,
@@ -1200,8 +1223,14 @@ static void spapr_phb_add_pci_device(sPAPRDRConnector 
*drc,
 
     if (object_dynamic_cast(OBJECT(pdev), "vfio-pci")) {
         sPAPRTCETable *tcet = spapr_tce_find_by_liobn(phb->dma_liobn);
+        sPAPRPHBGuestPE *pe;
 
         spapr_tce_need_vfio(tcet);
+
+        pe = spapr_phb_pe_by_device(phb, pdev);
+        if (pe) {
+            pe->num_devices++;
+        }
     }
 
     if (dev->hotplugged) {
@@ -1243,6 +1272,14 @@ static void spapr_phb_remove_pci_device(sPAPRDRConnector 
*drc,
                                         Error **errp)
 {
     sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
+    sPAPRPHBGuestPE *pe =spapr_phb_pe_by_device(phb, pdev);
+
+    if (pe) {
+        if (--pe->num_devices == 0) {
+            QLIST_REMOVE(pe, list);
+            g_free(pe);
+        }
+    }
 
     drck->detach(drc, DEVICE(pdev), spapr_phb_remove_pci_device_cb, phb, errp);
 }
@@ -1501,6 +1538,8 @@ static void spapr_phb_realize(DeviceState *dev, Error 
**errp)
     info->finish_realize(sphb, errp);
 
     sphb->msi = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free);
+
+    QLIST_INIT(&sphb->pe_list);
 }
 
 static void spapr_phb_finish_realize(sPAPRPHBState *sphb, Error **errp)
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index 741fe65..535e5ef 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -62,6 +62,12 @@ typedef struct spapr_pci_msi_mig {
     spapr_pci_msi value;
 } spapr_pci_msi_mig;
 
+typedef struct sPAPRPHBGuestPE {
+    int num_devices;
+    VFIOGroup *group;
+    QLIST_ENTRY(sPAPRPHBGuestPE) list;
+} sPAPRPHBGuestPE;
+
 struct sPAPRPHBState {
     PCIHostState parent_obj;
 
@@ -88,6 +94,8 @@ struct sPAPRPHBState {
     int32_t msi_devs_num;
     spapr_pci_msi_mig *msi_devs;
 
+    QLIST_HEAD(, sPAPRPHBGuestPE) pe_list;
+
     QLIST_ENTRY(sPAPRPHBState) list;
 };
 
-- 
2.4.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]