[PATCH v3 04/10] iommu/dma: Add a helper function to reserve RMRs for IOMMU drivers
Shameer Kolothum
shameerali.kolothum.thodi at huawei.com
Tue Apr 20 09:27:45 BST 2021
IOMMU drivers can use this to implement their .get_resv_regions callback
for any RMR address regions specific to a device.
As per ACPI IORT E.b spec, a check is added to make sure OS has preserved
the PCIe configuration done by boot firmware.
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi at huawei.com>
---
drivers/iommu/dma-iommu.c | 35 +++++++++++++++++++++++++++++++++++
include/linux/dma-iommu.h | 7 +++++++
2 files changed, 42 insertions(+)
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index a942cc04eee1..c624000bf230 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -191,6 +191,41 @@ void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list)
}
EXPORT_SYMBOL(iommu_dma_get_resv_regions);
+void iommu_dma_get_rmr_resv_regions(struct device *dev, struct iommu_rmr *rmr,
+ struct list_head *list)
+{
+ int prot = IOMMU_READ | IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
+ struct iommu_resv_region *region;
+ enum iommu_resv_type type;
+
+ /*
+ * For ACPI, please make sure the OS has preserved the PCIe configuration
+ * performed by the boot firmware(See IORT revision E.b).
+ */
+ if (!is_of_node(dev_iommu_fwspec_get(dev)->iommu_fwnode) &&
+ dev_is_pci(dev)) {
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct pci_host_bridge *host = pci_find_host_bridge(pdev->bus);
+
+ if (!host->preserve_config)
+ return;
+ }
+
+ if (rmr->flags & IOMMU_RMR_REMAP_PERMITTED)
+ type = IOMMU_RESV_DIRECT_RELAXABLE;
+ else
+ type = IOMMU_RESV_DIRECT;
+
+ region = iommu_alloc_resv_region(rmr->base_address,
+ rmr->length, prot,
+ type);
+ if (!region)
+ return;
+
+ list_add_tail(®ion->list, list);
+}
+EXPORT_SYMBOL(iommu_dma_get_rmr_resv_regions);
+
/**
* iommu_dma_get_rmrs - Retrieve Reserved Memory Regions(RMRs) associated
* with a given IOMMU
diff --git a/include/linux/dma-iommu.h b/include/linux/dma-iommu.h
index beb84c4fe5b1..dbad5073c9e0 100644
--- a/include/linux/dma-iommu.h
+++ b/include/linux/dma-iommu.h
@@ -40,6 +40,8 @@ void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list);
void iommu_dma_free_cpu_cached_iovas(unsigned int cpu,
struct iommu_domain *domain);
+void iommu_dma_get_rmr_resv_regions(struct device *dev, struct iommu_rmr *rmr,
+ struct list_head *list);
int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head *list);
struct iommu_rmr *iommu_dma_alloc_rmr(u64 base, u64 length, u32 sid, u32 flags);
@@ -89,6 +91,11 @@ static inline void iommu_dma_free_cpu_cached_iovas(unsigned int cpu,
{
}
+static void iommu_dma_get_rmr_resv_regions(struct device *dev, struct iommu_rmr *rmr,
+ struct list_head *list)
+{
+}
+
int iommu_dma_get_rmrs(struct fwnode_handle *iommu, struct list_head *list);
{
return 0;
--
2.17.1
More information about the linux-arm-kernel
mailing list