Skip to content

Commit a5898a5

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 4ab8f43 commit a5898a5

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
@@ -90,6 +90,7 @@ static const char * const iommu_group_resv_type_string[] = {
9090
[IOMMU_RESV_RESERVED] = "reserved",
9191
[IOMMU_RESV_MSI] = "msi",
9292
[IOMMU_RESV_SW_MSI] = "msi",
93+
[IOMMU_RESV_TRANSLATED] = "translated",
9394
};
9495

9596
#define IOMMU_CMD_LINE_DMA_API BIT(0)
@@ -2859,10 +2860,11 @@ void iommu_put_resv_regions(struct device *dev, struct list_head *list)
28592860
}
28602861
EXPORT_SYMBOL(iommu_put_resv_regions);
28612862

2862-
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2863-
size_t length, int prot,
2864-
enum iommu_resv_type type,
2865-
gfp_t gfp)
2863+
struct iommu_resv_region *iommu_alloc_resv_region_tr(phys_addr_t start,
2864+
dma_addr_t dva_start,
2865+
size_t length, int prot,
2866+
enum iommu_resv_type type,
2867+
gfp_t gfp)
28662868
{
28672869
struct iommu_resv_region *region;
28682870

@@ -2872,11 +2874,25 @@ struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
28722874

28732875
INIT_LIST_HEAD(&region->list);
28742876
region->start = start;
2877+
if (type == IOMMU_RESV_TRANSLATED)
2878+
region->dva = dva_start;
28752879
region->length = length;
28762880
region->prot = prot;
28772881
region->type = type;
28782882
return region;
28792883
}
2884+
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region_tr);
2885+
2886+
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2887+
size_t length, int prot,
2888+
enum iommu_resv_type type,
2889+
gfp_t gfp)
2890+
{
2891+
if (type == IOMMU_RESV_TRANSLATED)
2892+
return NULL;
2893+
2894+
return iommu_alloc_resv_region_tr(start, 0, length, prot, type, gfp);
2895+
}
28802896
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region);
28812897

28822898
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
@@ -289,12 +289,18 @@ enum iommu_resv_type {
289289
IOMMU_RESV_MSI,
290290
/* Software-managed MSI translation window */
291291
IOMMU_RESV_SW_MSI,
292+
/*
293+
* Memory regions which must be mapped with the specified mapping
294+
* at all times.
295+
*/
296+
IOMMU_RESV_TRANSLATED,
292297
};
293298

294299
/**
295300
* struct iommu_resv_region - descriptor for a reserved memory region
296301
* @list: Linked list pointers
297302
* @start: System physical start address of the region
303+
* @start: Device virtual start address of the region for IOMMU_RESV_TRANSLATED
298304
* @length: Length of the region in bytes
299305
* @prot: IOMMU Protection flags (READ/WRITE/...)
300306
* @type: Type of the reserved region
@@ -303,6 +309,7 @@ enum iommu_resv_type {
303309
struct iommu_resv_region {
304310
struct list_head list;
305311
phys_addr_t start;
312+
dma_addr_t dva;
306313
size_t length;
307314
int prot;
308315
enum iommu_resv_type type;
@@ -937,6 +944,9 @@ extern bool iommu_default_passthrough(void);
937944
extern struct iommu_resv_region *
938945
iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot,
939946
enum iommu_resv_type type, gfp_t gfp);
947+
extern struct iommu_resv_region *
948+
iommu_alloc_resv_region_tr(phys_addr_t start, dma_addr_t dva_start, size_t length,
949+
int prot, enum iommu_resv_type type, gfp_t gfp);
940950
extern int iommu_get_group_resv_regions(struct iommu_group *group,
941951
struct list_head *head);
942952

0 commit comments

Comments
 (0)