Skip to content

Commit 07bcb16

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 629e8b8 commit 07bcb16

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)
@@ -2841,10 +2842,11 @@ void iommu_put_resv_regions(struct device *dev, struct list_head *list)
28412842
}
28422843
EXPORT_SYMBOL(iommu_put_resv_regions);
28432844

2844-
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2845-
size_t length, int prot,
2846-
enum iommu_resv_type type,
2847-
gfp_t gfp)
2845+
struct iommu_resv_region *iommu_alloc_resv_region_tr(phys_addr_t start,
2846+
dma_addr_t dva_start,
2847+
size_t length, int prot,
2848+
enum iommu_resv_type type,
2849+
gfp_t gfp)
28482850
{
28492851
struct iommu_resv_region *region;
28502852

@@ -2854,11 +2856,25 @@ struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
28542856

28552857
INIT_LIST_HEAD(&region->list);
28562858
region->start = start;
2859+
if (type == IOMMU_RESV_TRANSLATED)
2860+
region->dva = dva_start;
28572861
region->length = length;
28582862
region->prot = prot;
28592863
region->type = type;
28602864
return region;
28612865
}
2866+
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region_tr);
2867+
2868+
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2869+
size_t length, int prot,
2870+
enum iommu_resv_type type,
2871+
gfp_t gfp)
2872+
{
2873+
if (type == IOMMU_RESV_TRANSLATED)
2874+
return NULL;
2875+
2876+
return iommu_alloc_resv_region_tr(start, 0, length, prot, type, gfp);
2877+
}
28622878
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region);
28632879

28642880
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;
@@ -936,6 +943,9 @@ extern bool iommu_default_passthrough(void);
936943
extern struct iommu_resv_region *
937944
iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot,
938945
enum iommu_resv_type type, gfp_t gfp);
946+
extern struct iommu_resv_region *
947+
iommu_alloc_resv_region_tr(phys_addr_t start, dma_addr_t dva_start, size_t length,
948+
int prot, enum iommu_resv_type type, gfp_t gfp);
939949
extern int iommu_get_group_resv_regions(struct iommu_group *group,
940950
struct list_head *head);
941951

0 commit comments

Comments
 (0)