From: Alejandro Jimenez <[email protected]> Enable the appropriate memory region for an address space depending on the address translation mode selected for it. This is currently based on a generic x86 IOMMU property, and only done during the address space initialization. Extract the code into a helper and toggle the regions based on whether the specific address space is using address translation (via the newly introduced addr_translation field). Later, region activation will also be controlled by availability of DMA remapping capability (via dma-remap property to be introduced in follow up changes).
Signed-off-by: Alejandro Jimenez <[email protected]> Reviewed-by: Michael S. Tsirkin <[email protected]> Message-ID: <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> --- hw/i386/amd_iommu.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c index d74d42b3dd..67a26f5247 100644 --- a/hw/i386/amd_iommu.c +++ b/hw/i386/amd_iommu.c @@ -74,6 +74,8 @@ struct AMDVIAddressSpace { QLIST_ENTRY(AMDVIAddressSpace) next; /* Record DMA translation ranges */ IOVATree *iova_tree; + /* DMA address translation active */ + bool addr_translation; }; /* AMDVI cache entry */ @@ -982,6 +984,23 @@ static void amdvi_iommu_address_space_sync_all(AMDVIState *s) } } +/* + * Toggle between address translation and passthrough modes by enabling the + * corresponding memory regions. + */ +static void amdvi_switch_address_space(AMDVIAddressSpace *amdvi_as) +{ + if (amdvi_as->addr_translation) { + /* Enabling DMA region */ + memory_region_set_enabled(&amdvi_as->iommu_nodma, false); + memory_region_set_enabled(MEMORY_REGION(&amdvi_as->iommu), true); + } else { + /* Disabling DMA region, using passthrough */ + memory_region_set_enabled(MEMORY_REGION(&amdvi_as->iommu), false); + memory_region_set_enabled(&amdvi_as->iommu_nodma, true); + } +} + /* log error without aborting since linux seems to be using reserved bits */ static void amdvi_inval_devtab_entry(AMDVIState *s, uint64_t *cmd) { @@ -2070,6 +2089,7 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn) iommu_as[devfn]->iommu_state = s; iommu_as[devfn]->notifier_flags = IOMMU_NOTIFIER_NONE; iommu_as[devfn]->iova_tree = iova_tree_new(); + iommu_as[devfn]->addr_translation = false; amdvi_dev_as = iommu_as[devfn]; @@ -2112,8 +2132,7 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn) AMDVI_INT_ADDR_FIRST, &amdvi_dev_as->iommu_ir, 1); - memory_region_set_enabled(&amdvi_dev_as->iommu_nodma, false); - memory_region_set_enabled(MEMORY_REGION(&amdvi_dev_as->iommu), true); + amdvi_switch_address_space(amdvi_dev_as); } return &iommu_as[devfn]->as; } -- MST
