Skip to content

Commit c645317

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 6c596f5 commit c645317

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
@@ -89,6 +89,7 @@ static const char * const iommu_group_resv_type_string[] = {
8989
[IOMMU_RESV_RESERVED] = "reserved",
9090
[IOMMU_RESV_MSI] = "msi",
9191
[IOMMU_RESV_SW_MSI] = "msi",
92+
[IOMMU_RESV_TRANSLATED] = "translated",
9293
};
9394

9495
#define IOMMU_CMD_LINE_DMA_API BIT(0)
@@ -2816,10 +2817,11 @@ void iommu_put_resv_regions(struct device *dev, struct list_head *list)
28162817
}
28172818
EXPORT_SYMBOL(iommu_put_resv_regions);
28182819

2819-
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2820-
size_t length, int prot,
2821-
enum iommu_resv_type type,
2822-
gfp_t gfp)
2820+
struct iommu_resv_region *iommu_alloc_resv_region_tr(phys_addr_t start,
2821+
dma_addr_t dva_start,
2822+
size_t length, int prot,
2823+
enum iommu_resv_type type,
2824+
gfp_t gfp)
28232825
{
28242826
struct iommu_resv_region *region;
28252827

@@ -2829,11 +2831,25 @@ struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
28292831

28302832
INIT_LIST_HEAD(&region->list);
28312833
region->start = start;
2834+
if (type == IOMMU_RESV_TRANSLATED)
2835+
region->dva = dva_start;
28322836
region->length = length;
28332837
region->prot = prot;
28342838
region->type = type;
28352839
return region;
28362840
}
2841+
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region_tr);
2842+
2843+
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2844+
size_t length, int prot,
2845+
enum iommu_resv_type type,
2846+
gfp_t gfp)
2847+
{
2848+
if (type == IOMMU_RESV_TRANSLATED)
2849+
return NULL;
2850+
2851+
return iommu_alloc_resv_region_tr(start, 0, length, prot, type, gfp);
2852+
}
28372853
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region);
28382854

28392855
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
@@ -152,12 +152,18 @@ enum iommu_resv_type {
152152
IOMMU_RESV_MSI,
153153
/* Software-managed MSI translation window */
154154
IOMMU_RESV_SW_MSI,
155+
/*
156+
* Memory regions which must be mapped with the specified mapping
157+
* at all times.
158+
*/
159+
IOMMU_RESV_TRANSLATED,
155160
};
156161

157162
/**
158163
* struct iommu_resv_region - descriptor for a reserved memory region
159164
* @list: Linked list pointers
160165
* @start: System physical start address of the region
166+
* @start: Device virtual start address of the region for IOMMU_RESV_TRANSLATED
161167
* @length: Length of the region in bytes
162168
* @prot: IOMMU Protection flags (READ/WRITE/...)
163169
* @type: Type of the reserved region
@@ -166,6 +172,7 @@ enum iommu_resv_type {
166172
struct iommu_resv_region {
167173
struct list_head list;
168174
phys_addr_t start;
175+
dma_addr_t dva;
169176
size_t length;
170177
int prot;
171178
enum iommu_resv_type type;
@@ -500,6 +507,9 @@ extern bool iommu_default_passthrough(void);
500507
extern struct iommu_resv_region *
501508
iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot,
502509
enum iommu_resv_type type, gfp_t gfp);
510+
extern struct iommu_resv_region *
511+
iommu_alloc_resv_region_tr(phys_addr_t start, dma_addr_t dva_start, size_t length,
512+
int prot, enum iommu_resv_type type, gfp_t gfp);
503513
extern int iommu_get_group_resv_regions(struct iommu_group *group,
504514
struct list_head *head);
505515

0 commit comments

Comments
 (0)