Skip to content

Commit 17c7fa0

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 39667f3 commit 17c7fa0

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)
@@ -2822,10 +2823,11 @@ void iommu_put_resv_regions(struct device *dev, struct list_head *list)
28222823
}
28232824
EXPORT_SYMBOL(iommu_put_resv_regions);
28242825

2825-
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2826-
size_t length, int prot,
2827-
enum iommu_resv_type type,
2828-
gfp_t gfp)
2826+
struct iommu_resv_region *iommu_alloc_resv_region_tr(phys_addr_t start,
2827+
dma_addr_t dva_start,
2828+
size_t length, int prot,
2829+
enum iommu_resv_type type,
2830+
gfp_t gfp)
28292831
{
28302832
struct iommu_resv_region *region;
28312833

@@ -2835,11 +2837,25 @@ struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
28352837

28362838
INIT_LIST_HEAD(&region->list);
28372839
region->start = start;
2840+
if (type == IOMMU_RESV_TRANSLATED)
2841+
region->dva = dva_start;
28382842
region->length = length;
28392843
region->prot = prot;
28402844
region->type = type;
28412845
return region;
28422846
}
2847+
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region_tr);
2848+
2849+
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2850+
size_t length, int prot,
2851+
enum iommu_resv_type type,
2852+
gfp_t gfp)
2853+
{
2854+
if (type == IOMMU_RESV_TRANSLATED)
2855+
return NULL;
2856+
2857+
return iommu_alloc_resv_region_tr(start, 0, length, prot, type, gfp);
2858+
}
28432859
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region);
28442860

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

293298
/**
294299
* struct iommu_resv_region - descriptor for a reserved memory region
295300
* @list: Linked list pointers
296301
* @start: System physical start address of the region
302+
* @start: Device virtual start address of the region for IOMMU_RESV_TRANSLATED
297303
* @length: Length of the region in bytes
298304
* @prot: IOMMU Protection flags (READ/WRITE/...)
299305
* @type: Type of the reserved region
@@ -302,6 +308,7 @@ enum iommu_resv_type {
302308
struct iommu_resv_region {
303309
struct list_head list;
304310
phys_addr_t start;
311+
dma_addr_t dva;
305312
size_t length;
306313
int prot;
307314
enum iommu_resv_type type;
@@ -892,6 +899,9 @@ extern bool iommu_default_passthrough(void);
892899
extern struct iommu_resv_region *
893900
iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot,
894901
enum iommu_resv_type type, gfp_t gfp);
902+
extern struct iommu_resv_region *
903+
iommu_alloc_resv_region_tr(phys_addr_t start, dma_addr_t dva_start, size_t length,
904+
int prot, enum iommu_resv_type type, gfp_t gfp);
895905
extern int iommu_get_group_resv_regions(struct iommu_group *group,
896906
struct list_head *head);
897907

0 commit comments

Comments
 (0)