From f5509b6bebc68fc781f0823e628fead884fd69d4 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Thu, 20 Jul 2017 17:22:29 +1000 Subject: spapr_iommu: Realloc guest visible TCE table when hot(un)plugging vfio-pci This replaces g_malloc() with spapr_tce_alloc_table() as this is the standard way of allocating tables and this allows moving the table back to KVM when unplugging a VFIO PCI device and VFIO TCE acceleration support is not present in the KVM. Although spapr_tce_alloc_table() is expected to fail with EBUSY if called when previous fd is not closed yet, in practice we will not see it because cap_spapr_vfio is false at the moment. Signed-off-by: Alexey Kardashevskiy Signed-off-by: David Gibson --- hw/ppc/spapr_iommu.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) (limited to 'hw/ppc/spapr_iommu.c') diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c index a75584c947..fa8b969840 100644 --- a/hw/ppc/spapr_iommu.c +++ b/hw/ppc/spapr_iommu.c @@ -275,33 +275,26 @@ static void spapr_tce_table_realize(DeviceState *dev, Error **errp) 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; - } - - if (!need_vfio) { - /* FIXME: We don't support transition back to KVM accelerated - * TCEs yet */ - return; - } + g_assert(need_vfio != tcet->need_vfio); - tcet->need_vfio = true; + tcet->need_vfio = need_vfio; - if (tcet->fd < 0) { - /* Table is already in userspace, nothing to be do */ - return; - } + oldtable = tcet->table; - 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) -- cgit v1.2.3