Skip to content

Commit 5892b71

Browse files
committed
iommu: Add IOMMU_RESV_TRANSLATED for non 1:1 mapped reserved regions
The display controller in Apple silicon SoCs uses bootloader mappings which require IOMMU translation. Signed-off-by: Janne Grunau <j@jannau.net>
1 parent 7053170 commit 5892b71

2 files changed

Lines changed: 30 additions & 4 deletions

File tree

drivers/iommu/iommu.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ static const char * const iommu_group_resv_type_string[] = {
8686
[IOMMU_RESV_RESERVED] = "reserved",
8787
[IOMMU_RESV_MSI] = "msi",
8888
[IOMMU_RESV_SW_MSI] = "msi",
89+
[IOMMU_RESV_TRANSLATED] = "translated",
8990
};
9091

9192
#define IOMMU_CMD_LINE_DMA_API BIT(0)
@@ -2758,10 +2759,11 @@ void iommu_put_resv_regions(struct device *dev, struct list_head *list)
27582759
}
27592760
EXPORT_SYMBOL(iommu_put_resv_regions);
27602761

2761-
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2762-
size_t length, int prot,
2763-
enum iommu_resv_type type,
2764-
gfp_t gfp)
2762+
struct iommu_resv_region *iommu_alloc_resv_region_tr(phys_addr_t start,
2763+
dma_addr_t dva_start,
2764+
size_t length, int prot,
2765+
enum iommu_resv_type type,
2766+
gfp_t gfp)
27652767
{
27662768
struct iommu_resv_region *region;
27672769

@@ -2771,11 +2773,25 @@ struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
27712773

27722774
INIT_LIST_HEAD(&region->list);
27732775
region->start = start;
2776+
if (type == IOMMU_RESV_TRANSLATED)
2777+
region->dva = dva_start;
27742778
region->length = length;
27752779
region->prot = prot;
27762780
region->type = type;
27772781
return region;
27782782
}
2783+
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region_tr);
2784+
2785+
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2786+
size_t length, int prot,
2787+
enum iommu_resv_type type,
2788+
gfp_t gfp)
2789+
{
2790+
if (type == IOMMU_RESV_TRANSLATED)
2791+
return NULL;
2792+
2793+
return iommu_alloc_resv_region_tr(start, 0, length, prot, type, gfp);
2794+
}
27792795
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region);
27802796

27812797
void iommu_set_default_passthrough(bool cmd_line)

include/linux/iommu.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,12 +273,18 @@ enum iommu_resv_type {
273273
IOMMU_RESV_MSI,
274274
/* Software-managed MSI translation window */
275275
IOMMU_RESV_SW_MSI,
276+
/*
277+
* Memory regions which must be mapped with the specified mapping
278+
* at all times.
279+
*/
280+
IOMMU_RESV_TRANSLATED,
276281
};
277282

278283
/**
279284
* struct iommu_resv_region - descriptor for a reserved memory region
280285
* @list: Linked list pointers
281286
* @start: System physical start address of the region
287+
* @start: Device virtual start address of the region for IOMMU_RESV_TRANSLATED
282288
* @length: Length of the region in bytes
283289
* @prot: IOMMU Protection flags (READ/WRITE/...)
284290
* @type: Type of the reserved region
@@ -287,6 +293,7 @@ enum iommu_resv_type {
287293
struct iommu_resv_region {
288294
struct list_head list;
289295
phys_addr_t start;
296+
dma_addr_t dva;
290297
size_t length;
291298
int prot;
292299
enum iommu_resv_type type;
@@ -877,6 +884,9 @@ extern bool iommu_default_passthrough(void);
877884
extern struct iommu_resv_region *
878885
iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot,
879886
enum iommu_resv_type type, gfp_t gfp);
887+
extern struct iommu_resv_region *
888+
iommu_alloc_resv_region_tr(phys_addr_t start, dma_addr_t dva_start, size_t length,
889+
int prot, enum iommu_resv_type type, gfp_t gfp);
880890
extern int iommu_get_group_resv_regions(struct iommu_group *group,
881891
struct list_head *head);
882892

0 commit comments

Comments
 (0)