Skip to content

Commit 096ad8b

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 7f228ef commit 096ad8b

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

8586
#define IOMMU_CMD_LINE_DMA_API BIT(0)
@@ -2667,10 +2668,11 @@ void iommu_put_resv_regions(struct device *dev, struct list_head *list)
26672668
}
26682669
EXPORT_SYMBOL(iommu_put_resv_regions);
26692670

2670-
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2671-
size_t length, int prot,
2672-
enum iommu_resv_type type,
2673-
gfp_t gfp)
2671+
struct iommu_resv_region *iommu_alloc_resv_region_tr(phys_addr_t start,
2672+
dma_addr_t dva_start,
2673+
size_t length, int prot,
2674+
enum iommu_resv_type type,
2675+
gfp_t gfp)
26742676
{
26752677
struct iommu_resv_region *region;
26762678

@@ -2680,11 +2682,25 @@ struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
26802682

26812683
INIT_LIST_HEAD(&region->list);
26822684
region->start = start;
2685+
if (type == IOMMU_RESV_TRANSLATED)
2686+
region->dva = dva_start;
26832687
region->length = length;
26842688
region->prot = prot;
26852689
region->type = type;
26862690
return region;
26872691
}
2692+
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region_tr);
2693+
2694+
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
2695+
size_t length, int prot,
2696+
enum iommu_resv_type type,
2697+
gfp_t gfp)
2698+
{
2699+
if (type == IOMMU_RESV_TRANSLATED)
2700+
return NULL;
2701+
2702+
return iommu_alloc_resv_region_tr(start, 0, length, prot, type, gfp);
2703+
}
26882704
EXPORT_SYMBOL_GPL(iommu_alloc_resv_region);
26892705

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

151156
/**
152157
* struct iommu_resv_region - descriptor for a reserved memory region
153158
* @list: Linked list pointers
154159
* @start: System physical start address of the region
160+
* @start: Device virtual start address of the region for IOMMU_RESV_TRANSLATED
155161
* @length: Length of the region in bytes
156162
* @prot: IOMMU Protection flags (READ/WRITE/...)
157163
* @type: Type of the reserved region
@@ -160,6 +166,7 @@ enum iommu_resv_type {
160166
struct iommu_resv_region {
161167
struct list_head list;
162168
phys_addr_t start;
169+
dma_addr_t dva;
163170
size_t length;
164171
int prot;
165172
enum iommu_resv_type type;
@@ -492,6 +499,9 @@ extern bool iommu_default_passthrough(void);
492499
extern struct iommu_resv_region *
493500
iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot,
494501
enum iommu_resv_type type, gfp_t gfp);
502+
extern struct iommu_resv_region *
503+
iommu_alloc_resv_region_tr(phys_addr_t start, dma_addr_t dva_start, size_t length,
504+
int prot, enum iommu_resv_type type, gfp_t gfp);
495505
extern int iommu_get_group_resv_regions(struct iommu_group *group,
496506
struct list_head *head);
497507

0 commit comments

Comments
 (0)