Skip to content

Commit b1bee19

Browse files
jannaumarcan
authored andcommitted
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 64e8e79 commit b1bee19

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
@@ -81,6 +81,7 @@ static const char * const iommu_group_resv_type_string[] = {
8181
[IOMMU_RESV_RESERVED] = "reserved",
8282
[IOMMU_RESV_MSI] = "msi",
8383
[IOMMU_RESV_SW_MSI] = "msi",
84+
[IOMMU_RESV_TRANSLATED] = "translated",
8485
};
8586

8687
#define IOMMU_CMD_LINE_DMA_API BIT(0)
@@ -2697,10 +2698,11 @@ void iommu_put_resv_regions(struct device *dev, struct list_head *list)
26972698
}
26982699
EXPORT_SYMBOL(iommu_put_resv_regions);
26992700

2700-
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2701-
size_t length, int prot,
2702-
enum iommu_resv_type type,
2703-
gfp_t gfp)
2701+
struct iommu_resv_region *iommu_alloc_resv_region_tr(phys_addr_t start,
2702+
dma_addr_t dva_start,
2703+
size_t length, int prot,
2704+
enum iommu_resv_type type,
2705+
gfp_t gfp)
27042706
{
27052707
struct iommu_resv_region *region;
27062708

@@ -2710,11 +2712,25 @@ struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
27102712

27112713
INIT_LIST_HEAD(&region->list);
27122714
region->start = start;
2715+
if (type == IOMMU_RESV_TRANSLATED)
2716+
region->dva = dva_start;
27132717
region->length = length;
27142718
region->prot = prot;
27152719
region->type = type;
27162720
return region;
27172721
}
2722+
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region_tr);
2723+
2724+
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2725+
size_t length, int prot,
2726+
enum iommu_resv_type type,
2727+
gfp_t gfp)
2728+
{
2729+
if (type == IOMMU_RESV_TRANSLATED)
2730+
return NULL;
2731+
2732+
return iommu_alloc_resv_region_tr(start, 0, length, prot, type, gfp);
2733+
}
27182734
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region);
27192735

27202736
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
@@ -145,12 +145,18 @@ enum iommu_resv_type {
145145
IOMMU_RESV_MSI,
146146
/* Software-managed MSI translation window */
147147
IOMMU_RESV_SW_MSI,
148+
/*
149+
* Memory regions which must be mapped with the specified mapping
150+
* at all times.
151+
*/
152+
IOMMU_RESV_TRANSLATED,
148153
};
149154

150155
/**
151156
* struct iommu_resv_region - descriptor for a reserved memory region
152157
* @list: Linked list pointers
153158
* @start: System physical start address of the region
159+
* @start: Device virtual start address of the region for IOMMU_RESV_TRANSLATED
154160
* @length: Length of the region in bytes
155161
* @prot: IOMMU Protection flags (READ/WRITE/...)
156162
* @type: Type of the reserved region
@@ -159,6 +165,7 @@ enum iommu_resv_type {
159165
struct iommu_resv_region {
160166
struct list_head list;
161167
phys_addr_t start;
168+
dma_addr_t dva;
162169
size_t length;
163170
int prot;
164171
enum iommu_resv_type type;
@@ -491,6 +498,9 @@ extern bool iommu_default_passthrough(void);
491498
extern struct iommu_resv_region *
492499
iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot,
493500
enum iommu_resv_type type, gfp_t gfp);
501+
extern struct iommu_resv_region *
502+
iommu_alloc_resv_region_tr(phys_addr_t start, dma_addr_t dva_start, size_t length,
503+
int prot, enum iommu_resv_type type, gfp_t gfp);
494504
extern int iommu_get_group_resv_regions(struct iommu_group *group,
495505
struct list_head *head);
496506

0 commit comments

Comments
 (0)