amd_iommu: Add support for pass though mode

Introduce 'nodma' shared memory region to support PT mode
so that for each device, we only create an alias to shared memory
region when DMA-remapping is disabled.

Reviewed-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Signed-off-by: Santosh Shukla <santosh.shukla@amd.com>
Message-Id: <20240927172913.121477-3-santosh.shukla@amd.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Suravee Suthikulpanit 2024-09-27 12:29:10 -05:00 committed by Michael S. Tsirkin
parent 2e6f051cfc
commit c1f46999ef
2 changed files with 42 additions and 9 deletions

View File

@ -62,6 +62,7 @@ struct AMDVIAddressSpace {
AMDVIState *iommu_state; /* AMDVI - one per machine */
MemoryRegion root; /* AMDVI Root memory map region */
IOMMUMemoryRegion iommu; /* Device's address translation region */
MemoryRegion iommu_nodma; /* Alias of shared nodma memory region */
MemoryRegion iommu_ir; /* Device's interrupt remapping region */
AddressSpace as; /* device's corresponding address space */
};
@ -1412,6 +1413,7 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
AMDVIState *s = opaque;
AMDVIAddressSpace **iommu_as, *amdvi_dev_as;
int bus_num = pci_bus_num(bus);
X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s);
iommu_as = s->address_spaces[bus_num];
@ -1436,13 +1438,13 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
* Memory region relationships looks like (Address range shows
* only lower 32 bits to make it short in length...):
*
* |-----------------+-------------------+----------|
* |--------------------+-------------------+----------|
* | Name | Address range | Priority |
* |-----------------+-------------------+----------+
* | amdvi_root | 00000000-ffffffff | 0 |
* | amdvi_iommu | 00000000-ffffffff | 1 |
* | amdvi_iommu_ir | fee00000-feefffff | 64 |
* |-----------------+-------------------+----------|
* |--------------------+-------------------+----------+
* | amdvi-root | 00000000-ffffffff | 0 |
* | amdvi-iommu_nodma | 00000000-ffffffff | 0 |
* | amdvi-iommu_ir | fee00000-feefffff | 64 |
* |--------------------+-------------------+----------|
*/
memory_region_init_iommu(&amdvi_dev_as->iommu,
sizeof(amdvi_dev_as->iommu),
@ -1461,7 +1463,25 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn)
64);
memory_region_add_subregion_overlap(&amdvi_dev_as->root, 0,
MEMORY_REGION(&amdvi_dev_as->iommu),
1);
0);
/* Build the DMA Disabled alias to shared memory */
memory_region_init_alias(&amdvi_dev_as->iommu_nodma, OBJECT(s),
"amdvi-sys", &s->mr_sys, 0,
memory_region_size(&s->mr_sys));
memory_region_add_subregion_overlap(&amdvi_dev_as->root, 0,
&amdvi_dev_as->iommu_nodma,
0);
if (!x86_iommu->pt_supported) {
memory_region_set_enabled(&amdvi_dev_as->iommu_nodma, false);
memory_region_set_enabled(MEMORY_REGION(&amdvi_dev_as->iommu),
true);
} else {
memory_region_set_enabled(MEMORY_REGION(&amdvi_dev_as->iommu),
false);
memory_region_set_enabled(&amdvi_dev_as->iommu_nodma, true);
}
}
return &iommu_as[devfn]->as;
}
@ -1602,6 +1622,17 @@ static void amdvi_sysbus_realize(DeviceState *dev, Error **errp)
"amdvi-mmio", AMDVI_MMIO_SIZE);
memory_region_add_subregion(get_system_memory(), AMDVI_BASE_ADDR,
&s->mr_mmio);
/* Create the share memory regions by all devices */
memory_region_init(&s->mr_sys, OBJECT(s), "amdvi-sys", UINT64_MAX);
/* set up the DMA disabled memory region */
memory_region_init_alias(&s->mr_nodma, OBJECT(s),
"amdvi-nodma", get_system_memory(), 0,
memory_region_size(get_system_memory()));
memory_region_add_subregion_overlap(&s->mr_sys, 0,
&s->mr_nodma, 0);
pci_setup_iommu(bus, &amdvi_iommu_ops, s);
amdvi_init(s);
}

View File

@ -354,6 +354,8 @@ struct AMDVIState {
uint32_t pprlog_tail; /* ppr log tail */
MemoryRegion mr_mmio; /* MMIO region */
MemoryRegion mr_sys;
MemoryRegion mr_nodma;
uint8_t mmior[AMDVI_MMIO_SIZE]; /* read/write MMIO */
uint8_t w1cmask[AMDVI_MMIO_SIZE]; /* read/write 1 clear mask */
uint8_t romask[AMDVI_MMIO_SIZE]; /* MMIO read/only mask */