diff options
-rw-r--r-- | hw/ppc/spapr_iommu.c | 32 | ||||
-rw-r--r-- | include/hw/ppc/spapr.h | 2 |
2 files changed, 34 insertions, 0 deletions
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c index 5166cde422..ed28565d8c 100644 --- a/hw/ppc/spapr_iommu.c +++ b/hw/ppc/spapr_iommu.c @@ -168,6 +168,38 @@ static int spapr_tce_table_realize(DeviceState *dev) 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; + + 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; + } + + tcet->need_vfio = true; + + 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); + + kvmppc_remove_spapr_tce(tcet->table, tcet->fd, tcet->nb_table); + + tcet->fd = -1; + tcet->table = newtable; +} + sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, uint64_t bus_offset, uint32_t page_shift, diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 27d65d5f1d..5baa90683b 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -589,6 +589,8 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn, uint32_t page_shift, uint32_t nb_table, bool need_vfio); +void spapr_tce_set_need_vfio(sPAPRTCETable *tcet, bool need_vfio); + MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet); int spapr_dma_dt(void *fdt, int node_off, const char *propname, uint32_t liobn, uint64_t window, uint32_t size); |