aboutsummaryrefslogtreecommitdiff
path: root/include/hw/pci-host
diff options
context:
space:
mode:
authorAlexey Kardashevskiy <aik@ozlabs.ru>2014-05-30 19:34:20 +1000
committerAlexander Graf <agraf@suse.de>2014-06-27 13:48:27 +0200
commit9a321e92343891e30f6fe8bfaad40454ae358bfb (patch)
treea415b9310c7d7a469af6229e085942cc906090b0 /include/hw/pci-host
parentf32935ea2284fe833fdf4a0d6b2fe423fc08a1b2 (diff)
spapr_pci: Use XICS interrupt allocator and do not cache interrupts in PHB
Currently SPAPR PHB keeps track of all allocated MSI (here and below MSI stands for both MSI and MSIX) interrupt because XICS used to be unable to reuse interrupts. This is a problem for dynamic MSI reconfiguration which happens when guest reloads a driver or performs PCI hotplug. Another problem is that the existing implementation can enable MSI on 32 devices maximum (SPAPR_MSIX_MAX_DEVS=32) and there is no good reason for that. This makes use of new XICS ability to reuse interrupts. This reorganizes MSI information storage in sPAPRPHBState. Instead of static array of 32 descriptors (one per a PCI function), this patch adds a GHashTable when @config_addr is a key and (first_irq, num) pair is a value. GHashTable can dynamically grow and shrink so the initial limit of 32 devices is gone. This changes migration stream as @msi_table was a static array while new @msi_devs is a dynamic hash table. This adds temporary array which is used for migration, it is populated in "spapr_pci"::pre_save() callback and expanded into the hash table in post_load() callback. Since the destination side does not know the number of MSI-enabled devices in advance and cannot pre-allocate the temporary array to receive migration state, this makes use of new VMSTATE_STRUCT_VARRAY_ALLOC macro which allocates the array automatically. This resets the MSI configuration space when interrupts are released by the ibm,change-msi RTAS call. This fixed traces to be more informative. This changes vmstate_spapr_pci_msi name from "...lsi" to "...msi" which was incorrect by accident. As the internal representation changed, thus bumps migration version number. Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> [agraf: drop g_malloc_n usage] Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'include/hw/pci-host')
-rw-r--r--include/hw/pci-host/spapr.h21
1 files changed, 14 insertions, 7 deletions
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index 6808e967bd..32f0aa7d10 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -27,8 +27,6 @@
#include "hw/pci/pci_host.h"
#include "hw/ppc/xics.h"
-#define SPAPR_MSIX_MAX_DEVS 32
-
#define TYPE_SPAPR_PCI_HOST_BRIDGE "spapr-pci-host-bridge"
#define TYPE_SPAPR_PCI_VFIO_HOST_BRIDGE "spapr-pci-vfio-host-bridge"
@@ -53,6 +51,16 @@ struct sPAPRPHBClass {
void (*finish_realize)(sPAPRPHBState *sphb, Error **errp);
};
+typedef struct spapr_pci_msi {
+ uint32_t first_irq;
+ uint32_t num;
+} spapr_pci_msi;
+
+typedef struct spapr_pci_msi_mig {
+ uint32_t key;
+ spapr_pci_msi value;
+} spapr_pci_msi_mig;
+
struct sPAPRPHBState {
PCIHostState parent_obj;
@@ -72,11 +80,10 @@ struct sPAPRPHBState {
uint32_t irq;
} lsi_table[PCI_NUM_PINS];
- struct spapr_pci_msi {
- uint32_t config_addr;
- uint32_t irq;
- uint32_t nvec;
- } msi_table[SPAPR_MSIX_MAX_DEVS];
+ GHashTable *msi;
+ /* Temporary cache for migration purposes */
+ int32_t msi_devs_num;
+ spapr_pci_msi_mig *msi_devs;
QLIST_ENTRY(sPAPRPHBState) list;
};