Skip to content

Commit 948b82a

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 5b0cca0 commit 948b82a

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)
@@ -2863,10 +2864,11 @@ void iommu_put_resv_regions(struct device *dev, struct list_head *list)
28632864
}
28642865
EXPORT_SYMBOL(iommu_put_resv_regions);
28652866

2866-
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2867-
size_t length, int prot,
2868-
enum iommu_resv_type type,
2869-
gfp_t gfp)
2867+
struct iommu_resv_region *iommu_alloc_resv_region_tr(phys_addr_t start,
2868+
dma_addr_t dva_start,
2869+
size_t length, int prot,
2870+
enum iommu_resv_type type,
2871+
gfp_t gfp)
28702872
{
28712873
struct iommu_resv_region *region;
28722874

@@ -2876,11 +2878,25 @@ struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
28762878

28772879
INIT_LIST_HEAD(&region->list);
28782880
region->start = start;
2881+
if (type == IOMMU_RESV_TRANSLATED)
2882+
region->dva = dva_start;
28792883
region->length = length;
28802884
region->prot = prot;
28812885
region->type = type;
28822886
return region;
28832887
}
2888+
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region_tr);
2889+
2890+
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2891+
size_t length, int prot,
2892+
enum iommu_resv_type type,
2893+
gfp_t gfp)
2894+
{
2895+
if (type == IOMMU_RESV_TRANSLATED)
2896+
return NULL;
2897+
2898+
return iommu_alloc_resv_region_tr(start, 0, length, prot, type, gfp);
2899+
}
28842900
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region);
28852901

28862902
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)