Skip to content

Commit c3200b8

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 98f7e32 commit c3200b8

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)
@@ -2781,10 +2782,11 @@ void iommu_put_resv_regions(struct device *dev, struct list_head *list)
27812782
}
27822783
EXPORT_SYMBOL(iommu_put_resv_regions);
27832784

2784-
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2785-
size_t length, int prot,
2786-
enum iommu_resv_type type,
2787-
gfp_t gfp)
2785+
struct iommu_resv_region *iommu_alloc_resv_region_tr(phys_addr_t start,
2786+
dma_addr_t dva_start,
2787+
size_t length, int prot,
2788+
enum iommu_resv_type type,
2789+
gfp_t gfp)
27882790
{
27892791
struct iommu_resv_region *region;
27902792

@@ -2794,11 +2796,25 @@ struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
27942796

27952797
INIT_LIST_HEAD(&region->list);
27962798
region->start = start;
2799+
if (type == IOMMU_RESV_TRANSLATED)
2800+
region->dva = dva_start;
27972801
region->length = length;
27982802
region->prot = prot;
27992803
region->type = type;
28002804
return region;
28012805
}
2806+
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region_tr);
2807+
2808+
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2809+
size_t length, int prot,
2810+
enum iommu_resv_type type,
2811+
gfp_t gfp)
2812+
{
2813+
if (type == IOMMU_RESV_TRANSLATED)
2814+
return NULL;
2815+
2816+
return iommu_alloc_resv_region_tr(start, 0, length, prot, type, gfp);
2817+
}
28022818
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region);
28032819

28042820
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
@@ -271,12 +271,18 @@ enum iommu_resv_type {
271271
IOMMU_RESV_MSI,
272272
/* Software-managed MSI translation window */
273273
IOMMU_RESV_SW_MSI,
274+
/*
275+
* Memory regions which must be mapped with the specified mapping
276+
* at all times.
277+
*/
278+
IOMMU_RESV_TRANSLATED,
274279
};
275280

276281
/**
277282
* struct iommu_resv_region - descriptor for a reserved memory region
278283
* @list: Linked list pointers
279284
* @start: System physical start address of the region
285+
* @start: Device virtual start address of the region for IOMMU_RESV_TRANSLATED
280286
* @length: Length of the region in bytes
281287
* @prot: IOMMU Protection flags (READ/WRITE/...)
282288
* @type: Type of the reserved region
@@ -285,6 +291,7 @@ enum iommu_resv_type {
285291
struct iommu_resv_region {
286292
struct list_head list;
287293
phys_addr_t start;
294+
dma_addr_t dva;
288295
size_t length;
289296
int prot;
290297
enum iommu_resv_type type;
@@ -819,6 +826,9 @@ extern bool iommu_default_passthrough(void);
819826
extern struct iommu_resv_region *
820827
iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot,
821828
enum iommu_resv_type type, gfp_t gfp);
829+
extern struct iommu_resv_region *
830+
iommu_alloc_resv_region_tr(phys_addr_t start, dma_addr_t dva_start, size_t length,
831+
int prot, enum iommu_resv_type type, gfp_t gfp);
822832
extern int iommu_get_group_resv_regions(struct iommu_group *group,
823833
struct list_head *head);
824834

0 commit comments

Comments
 (0)