summaryrefslogtreecommitdiffstats
path: root/hw/ppc/spapr_iommu.c
diff options
context:
space:
mode:
authorPeter Maydell2017-09-08 15:44:44 +0200
committerPeter Maydell2017-09-08 15:44:44 +0200
commita1ae46d1b4f2a95ad5d3da8d15bc6403bcdbb24a (patch)
treeb2d02f48aa15e70cecc4c61401634d122d408035 /hw/ppc/spapr_iommu.c
parentMerge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into st... (diff)
parentppc: spapr: Move VCPU ID calculation into sPAPR (diff)
downloadqemu-a1ae46d1b4f2a95ad5d3da8d15bc6403bcdbb24a.tar.gz
qemu-a1ae46d1b4f2a95ad5d3da8d15bc6403bcdbb24a.tar.xz
qemu-a1ae46d1b4f2a95ad5d3da8d15bc6403bcdbb24a.zip
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.11-20170908' into staging
ppc patch queue 2017-09-08 This is the first batch of ppc related patches for qemu-2.11, and it's accumulated quite a few things. Includes: * A cleanup to handling of ppc cpu models from Igor * First parts of fixes to handling of guest vs. host SMT modes from Sam Bobroff * Preliminary patches towards supporting the Sam460 board from Balaton Zoltan * Several fixes for hotplug logic * Assorted other fixes and cleanups # gpg: Signature made Fri 08 Sep 2017 06:28:42 BST # gpg: using RSA key 0x6C38CACA20D9B392 # gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" # gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>" # gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" # gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>" # Primary key fingerprint: 75F4 6586 AE61 A66C C44E 87DC 6C38 CACA 20D9 B392 * remotes/dgibson/tags/ppc-for-2.11-20170908: (40 commits) ppc: spapr: Move VCPU ID calculation into sPAPR ppc: remove non implemented cpu models ppc: drop caching ObjectClass from PowerPCCPUAlias ppc: simplify cpu model lookup by PVR ppc: replace inter-function cyclic dependency/recurssion with 2 simple lookups ppc: make cpu alias point only to real cpu models ppc: make cpu_model translation to type consistent ppc: use macros to make cpu type name from string literal target/ppc: Remove old STATUS file PPC: KVM: Support machine option to set VSMT mode spapr: fallback to raw mode if best compat mode cannot be set during CAS hw/nvram/spapr_nvram: Device can not be created by the users hw/ppc/spapr_cpu_core: Add a proper check for spapr machine ppc4xx: Export ECB and PLB emulation ppc4xx_i2c: Move to hw/i2c ppc4xx_i2c: QOMify ppc4xx: Split off 4xx I2C emulation from ppc405_uc to its own file ppc4xx: Make MAL emulation more generic ppc4xx: Move MAL from ppc405_uc to ppc4xx_devs spapr_iommu: Realloc guest visible TCE table when hot(un)plugging vfio-pci ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/ppc/spapr_iommu.c')
-rw-r--r--hw/ppc/spapr_iommu.c57
1 files changed, 27 insertions, 30 deletions
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index ed2d53559a..fa8b969840 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -248,66 +248,59 @@ static const VMStateDescription vmstate_spapr_tce_table = {
}
};
-static int spapr_tce_table_realize(DeviceState *dev)
+static void spapr_tce_table_realize(DeviceState *dev, Error **errp)
{
sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
Object *tcetobj = OBJECT(tcet);
- char tmp[32];
+ gchar *tmp;
tcet->fd = -1;
tcet->need_vfio = false;
- snprintf(tmp, sizeof(tmp), "tce-root-%x", tcet->liobn);
+ tmp = g_strdup_printf("tce-root-%x", tcet->liobn);
memory_region_init(&tcet->root, tcetobj, tmp, UINT64_MAX);
+ g_free(tmp);
- snprintf(tmp, sizeof(tmp), "tce-iommu-%x", tcet->liobn);
+ tmp = g_strdup_printf("tce-iommu-%x", tcet->liobn);
memory_region_init_iommu(&tcet->iommu, sizeof(tcet->iommu),
TYPE_SPAPR_IOMMU_MEMORY_REGION,
tcetobj, tmp, 0);
+ g_free(tmp);
QLIST_INSERT_HEAD(&spapr_tce_tables, tcet, list);
vmstate_register(DEVICE(tcet), tcet->liobn, &vmstate_spapr_tce_table,
tcet);
-
- return 0;
}
void spapr_tce_set_need_vfio(sPAPRTCETable *tcet, bool need_vfio)
{
size_t table_size = tcet->nb_table * sizeof(uint64_t);
- void *newtable;
+ uint64_t *oldtable;
+ int newfd = -1;
- if (need_vfio == tcet->need_vfio) {
- /* Nothing to do */
- return;
- }
+ g_assert(need_vfio != tcet->need_vfio);
- if (!need_vfio) {
- /* FIXME: We don't support transition back to KVM accelerated
- * TCEs yet */
- return;
- }
+ tcet->need_vfio = need_vfio;
- tcet->need_vfio = true;
+ oldtable = tcet->table;
- if (tcet->fd < 0) {
- /* Table is already in userspace, nothing to be do */
- return;
- }
-
- newtable = g_malloc(table_size);
- memcpy(newtable, tcet->table, table_size);
+ tcet->table = spapr_tce_alloc_table(tcet->liobn,
+ tcet->page_shift,
+ tcet->bus_offset,
+ tcet->nb_table,
+ &newfd,
+ need_vfio);
+ memcpy(tcet->table, oldtable, table_size);
- kvmppc_remove_spapr_tce(tcet->table, tcet->fd, tcet->nb_table);
+ spapr_tce_free_table(oldtable, tcet->fd, tcet->nb_table);
- tcet->fd = -1;
- tcet->table = newtable;
+ tcet->fd = newfd;
}
sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn)
{
sPAPRTCETable *tcet;
- char tmp[32];
+ gchar *tmp;
if (spapr_tce_find_by_liobn(liobn)) {
error_report("Attempted to create TCE table with duplicate"
@@ -318,8 +311,10 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn)
tcet = SPAPR_TCE_TABLE(object_new(TYPE_SPAPR_TCE_TABLE));
tcet->liobn = liobn;
- snprintf(tmp, sizeof(tmp), "tce-table-%x", liobn);
+ tmp = g_strdup_printf("tce-table-%x", liobn);
object_property_add_child(OBJECT(owner), tmp, OBJECT(tcet), NULL);
+ g_free(tmp);
+ object_unref(OBJECT(tcet));
object_property_set_bool(OBJECT(tcet), true, "realized", NULL);
@@ -372,6 +367,8 @@ static void spapr_tce_table_unrealize(DeviceState *dev, Error **errp)
{
sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
+ vmstate_unregister(DEVICE(tcet), &vmstate_spapr_tce_table, tcet);
+
QLIST_REMOVE(tcet, list);
spapr_tce_table_disable(tcet);
@@ -615,7 +612,7 @@ int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname,
static void spapr_tce_table_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
- dc->init = spapr_tce_table_realize;
+ dc->realize = spapr_tce_table_realize;
dc->reset = spapr_tce_reset;
dc->unrealize = spapr_tce_table_unrealize;
/* Reason: This is just an internal device for handling the hypercalls */