Skip to content

Commit 76c199e

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 0c38364 commit 76c199e

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
@@ -85,6 +85,7 @@ static const char * const iommu_group_resv_type_string[] = {
8585
[IOMMU_RESV_RESERVED] = "reserved",
8686
[IOMMU_RESV_MSI] = "msi",
8787
[IOMMU_RESV_SW_MSI] = "msi",
88+
[IOMMU_RESV_TRANSLATED] = "translated",
8889
};
8990

9091
#define IOMMU_CMD_LINE_DMA_API BIT(0)
@@ -2767,10 +2768,11 @@ void iommu_put_resv_regions(struct device *dev, struct list_head *list)
27672768
}
27682769
EXPORT_SYMBOL(iommu_put_resv_regions);
27692770

2770-
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2771-
size_t length, int prot,
2772-
enum iommu_resv_type type,
2773-
gfp_t gfp)
2771+
struct iommu_resv_region *iommu_alloc_resv_region_tr(phys_addr_t start,
2772+
dma_addr_t dva_start,
2773+
size_t length, int prot,
2774+
enum iommu_resv_type type,
2775+
gfp_t gfp)
27742776
{
27752777
struct iommu_resv_region *region;
27762778

@@ -2780,11 +2782,25 @@ struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
27802782

27812783
INIT_LIST_HEAD(&region->list);
27822784
region->start = start;
2785+
if (type == IOMMU_RESV_TRANSLATED)
2786+
region->dva = dva_start;
27832787
region->length = length;
27842788
region->prot = prot;
27852789
region->type = type;
27862790
return region;
27872791
}
2792+
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region_tr);
2793+
2794+
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2795+
size_t length, int prot,
2796+
enum iommu_resv_type type,
2797+
gfp_t gfp)
2798+
{
2799+
if (type == IOMMU_RESV_TRANSLATED)
2800+
return NULL;
2801+
2802+
return iommu_alloc_resv_region_tr(start, 0, length, prot, type, gfp);
2803+
}
27882804
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region);
27892805

27902806
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
@@ -267,12 +267,18 @@ enum iommu_resv_type {
267267
IOMMU_RESV_MSI,
268268
/* Software-managed MSI translation window */
269269
IOMMU_RESV_SW_MSI,
270+
/*
271+
* Memory regions which must be mapped with the specified mapping
272+
* at all times.
273+
*/
274+
IOMMU_RESV_TRANSLATED,
270275
};
271276

272277
/**
273278
* struct iommu_resv_region - descriptor for a reserved memory region
274279
* @list: Linked list pointers
275280
* @start: System physical start address of the region
281+
* @start: Device virtual start address of the region for IOMMU_RESV_TRANSLATED
276282
* @length: Length of the region in bytes
277283
* @prot: IOMMU Protection flags (READ/WRITE/...)
278284
* @type: Type of the reserved region
@@ -281,6 +287,7 @@ enum iommu_resv_type {
281287
struct iommu_resv_region {
282288
struct list_head list;
283289
phys_addr_t start;
290+
dma_addr_t dva;
284291
size_t length;
285292
int prot;
286293
enum iommu_resv_type type;
@@ -811,6 +818,9 @@ extern bool iommu_default_passthrough(void);
811818
extern struct iommu_resv_region *
812819
iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot,
813820
enum iommu_resv_type type, gfp_t gfp);
821+
extern struct iommu_resv_region *
822+
iommu_alloc_resv_region_tr(phys_addr_t start, dma_addr_t dva_start, size_t length,
823+
int prot, enum iommu_resv_type type, gfp_t gfp);
814824
extern int iommu_get_group_resv_regions(struct iommu_group *group,
815825
struct list_head *head);
816826

0 commit comments

Comments
 (0)