Skip to content

Commit 9d3a4de

Browse files
rmurphy-armjoergroedel
authored andcommitted
iommu: Disambiguate MSI region types
The introduction of reserved regions has left a couple of rough edges which we could do with sorting out sooner rather than later. Since we are not yet addressing the potential dynamic aspect of software-managed reservations and presenting them at arbitrary fixed addresses, it is incongruous that we end up displaying hardware vs. software-managed MSI regions to userspace differently, especially since ARM-based systems may actually require one or the other, or even potentially both at once, (which iommu-dma currently has no hope of dealing with at all). Let's resolve the former user-visible inconsistency ASAP before the ABI has been baked into a kernel release, in a way that also lays the groundwork for the latter shortcoming to be addressed by follow-up patches. For clarity, rename the software-managed type to IOMMU_RESV_SW_MSI, use IOMMU_RESV_MSI to describe the hardware type, and document everything a little bit. Since the x86 MSI remapping hardware falls squarely under this meaning of IOMMU_RESV_MSI, apply that type to their regions as well, so that we tell the same story to userspace across all platforms. Secondly, as the various region types require quite different handling, and it really makes little sense to ever try combining them, convert the bitfield-esque #defines to a plain enum in the process before anyone gets the wrong impression. Fixes: d30ddca ("iommu: Add a new type field in iommu_resv_region") Reviewed-by: Eric Auger <eric.auger@redhat.com> CC: Alex Williamson <alex.williamson@redhat.com> CC: David Woodhouse <dwmw2@infradead.org> CC: kvm@vger.kernel.org Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent cd37a29 commit 9d3a4de

File tree

7 files changed

+23
-15
lines changed

7 files changed

+23
-15
lines changed

drivers/iommu/amd_iommu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3202,7 +3202,7 @@ static void amd_iommu_get_resv_regions(struct device *dev,
32023202

32033203
region = iommu_alloc_resv_region(MSI_RANGE_START,
32043204
MSI_RANGE_END - MSI_RANGE_START + 1,
3205-
0, IOMMU_RESV_RESERVED);
3205+
0, IOMMU_RESV_MSI);
32063206
if (!region)
32073207
return;
32083208
list_add_tail(&region->list, head);

drivers/iommu/arm-smmu-v3.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1888,7 +1888,7 @@ static void arm_smmu_get_resv_regions(struct device *dev,
18881888
int prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
18891889

18901890
region = iommu_alloc_resv_region(MSI_IOVA_BASE, MSI_IOVA_LENGTH,
1891-
prot, IOMMU_RESV_MSI);
1891+
prot, IOMMU_RESV_SW_MSI);
18921892
if (!region)
18931893
return;
18941894

drivers/iommu/arm-smmu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1608,7 +1608,7 @@ static void arm_smmu_get_resv_regions(struct device *dev,
16081608
int prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
16091609

16101610
region = iommu_alloc_resv_region(MSI_IOVA_BASE, MSI_IOVA_LENGTH,
1611-
prot, IOMMU_RESV_MSI);
1611+
prot, IOMMU_RESV_SW_MSI);
16121612
if (!region)
16131613
return;
16141614

drivers/iommu/intel-iommu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5249,7 +5249,7 @@ static void intel_iommu_get_resv_regions(struct device *device,
52495249

52505250
reg = iommu_alloc_resv_region(IOAPIC_RANGE_START,
52515251
IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1,
5252-
0, IOMMU_RESV_RESERVED);
5252+
0, IOMMU_RESV_MSI);
52535253
if (!reg)
52545254
return;
52555255
list_add_tail(&reg->list, head);

drivers/iommu/iommu.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ static const char * const iommu_group_resv_type_string[] = {
7272
[IOMMU_RESV_DIRECT] = "direct",
7373
[IOMMU_RESV_RESERVED] = "reserved",
7474
[IOMMU_RESV_MSI] = "msi",
75+
[IOMMU_RESV_SW_MSI] = "msi",
7576
};
7677

7778
#define IOMMU_GROUP_ATTR(_name, _mode, _show, _store) \
@@ -1743,8 +1744,8 @@ void iommu_put_resv_regions(struct device *dev, struct list_head *list)
17431744
}
17441745

17451746
struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
1746-
size_t length,
1747-
int prot, int type)
1747+
size_t length, int prot,
1748+
enum iommu_resv_type type)
17481749
{
17491750
struct iommu_resv_region *region;
17501751

drivers/vfio/vfio_iommu_type1.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,8 +1182,7 @@ static struct vfio_group *find_iommu_group(struct vfio_domain *domain,
11821182
return NULL;
11831183
}
11841184

1185-
static bool vfio_iommu_has_resv_msi(struct iommu_group *group,
1186-
phys_addr_t *base)
1185+
static bool vfio_iommu_has_sw_msi(struct iommu_group *group, phys_addr_t *base)
11871186
{
11881187
struct list_head group_resv_regions;
11891188
struct iommu_resv_region *region, *next;
@@ -1192,7 +1191,7 @@ static bool vfio_iommu_has_resv_msi(struct iommu_group *group,
11921191
INIT_LIST_HEAD(&group_resv_regions);
11931192
iommu_get_group_resv_regions(group, &group_resv_regions);
11941193
list_for_each_entry(region, &group_resv_regions, list) {
1195-
if (region->type & IOMMU_RESV_MSI) {
1194+
if (region->type == IOMMU_RESV_SW_MSI) {
11961195
*base = region->start;
11971196
ret = true;
11981197
goto out;
@@ -1283,7 +1282,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
12831282
if (ret)
12841283
goto out_domain;
12851284

1286-
resv_msi = vfio_iommu_has_resv_msi(iommu_group, &resv_msi_base);
1285+
resv_msi = vfio_iommu_has_sw_msi(iommu_group, &resv_msi_base);
12871286

12881287
INIT_LIST_HEAD(&domain->group_list);
12891288
list_add(&group->next, &domain->group_list);

include/linux/iommu.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,16 @@ enum iommu_attr {
125125
};
126126

127127
/* These are the possible reserved region types */
128-
#define IOMMU_RESV_DIRECT (1 << 0)
129-
#define IOMMU_RESV_RESERVED (1 << 1)
130-
#define IOMMU_RESV_MSI (1 << 2)
128+
enum iommu_resv_type {
129+
/* Memory regions which must be mapped 1:1 at all times */
130+
IOMMU_RESV_DIRECT,
131+
/* Arbitrary "never map this or give it to a device" address ranges */
132+
IOMMU_RESV_RESERVED,
133+
/* Hardware MSI region (untranslated) */
134+
IOMMU_RESV_MSI,
135+
/* Software-managed MSI translation window */
136+
IOMMU_RESV_SW_MSI,
137+
};
131138

132139
/**
133140
* struct iommu_resv_region - descriptor for a reserved memory region
@@ -142,7 +149,7 @@ struct iommu_resv_region {
142149
phys_addr_t start;
143150
size_t length;
144151
int prot;
145-
int type;
152+
enum iommu_resv_type type;
146153
};
147154

148155
#ifdef CONFIG_IOMMU_API
@@ -288,7 +295,8 @@ extern void iommu_get_resv_regions(struct device *dev, struct list_head *list);
288295
extern void iommu_put_resv_regions(struct device *dev, struct list_head *list);
289296
extern int iommu_request_dm_for_dev(struct device *dev);
290297
extern struct iommu_resv_region *
291-
iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot, int type);
298+
iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot,
299+
enum iommu_resv_type type);
292300
extern int iommu_get_group_resv_regions(struct iommu_group *group,
293301
struct list_head *head);
294302

0 commit comments

Comments
 (0)