Skip to content

Commit

Permalink
Merge tag 'iommu-fixes-v5.1-rc3' of git://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/kernel/git/joro/iommu

Pull IOMMU fixes from Joerg Roedel:

 - Fix a bug in the AMD IOMMU driver not handling exclusion ranges
   correctly. In fact the driver did not reserve these ranges for IOVA
   allocations, so that dma-handles could be allocated in an exclusion
   range, leading to data corruption. Exclusion ranges have not been
   used by any firmware up to now, so this issue remained undiscovered
   for quite some time.

 - Fix wrong warning messages that the IOMMU core code prints when it
   tries to allocate the default domain for an iommu group and the
   driver does not support any of the default domain types (like Intel
   VT-d).

* tag 'iommu-fixes-v5.1-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
  iommu/amd: Reserve exclusion range in iova-domain
  iommu: Don't print warning when IOMMU driver only supports unmanaged domains
  • Loading branch information
torvalds committed Mar 29, 2019
2 parents eed4897 + 8aafaaf commit c0b7f2a
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 9 deletions.
9 changes: 6 additions & 3 deletions drivers/iommu/amd_iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -3169,21 +3169,24 @@ static void amd_iommu_get_resv_regions(struct device *dev,
return;

list_for_each_entry(entry, &amd_iommu_unity_map, list) {
int type, prot = 0;
size_t length;
int prot = 0;

if (devid < entry->devid_start || devid > entry->devid_end)
continue;

type = IOMMU_RESV_DIRECT;
length = entry->address_end - entry->address_start;
if (entry->prot & IOMMU_PROT_IR)
prot |= IOMMU_READ;
if (entry->prot & IOMMU_PROT_IW)
prot |= IOMMU_WRITE;
if (entry->prot & IOMMU_UNITY_MAP_FLAG_EXCL_RANGE)
/* Exclusion range */
type = IOMMU_RESV_RESERVED;

region = iommu_alloc_resv_region(entry->address_start,
length, prot,
IOMMU_RESV_DIRECT);
length, prot, type);
if (!region) {
dev_err(dev, "Out of memory allocating dm-regions\n");
return;
Expand Down
7 changes: 4 additions & 3 deletions drivers/iommu/amd_iommu_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -2013,6 +2013,9 @@ static int __init init_unity_map_range(struct ivmd_header *m)
if (e == NULL)
return -ENOMEM;

if (m->flags & IVMD_FLAG_EXCL_RANGE)
init_exclusion_range(m);

switch (m->type) {
default:
kfree(e);
Expand Down Expand Up @@ -2059,9 +2062,7 @@ static int __init init_memory_definitions(struct acpi_table_header *table)

while (p < end) {
m = (struct ivmd_header *)p;
if (m->flags & IVMD_FLAG_EXCL_RANGE)
init_exclusion_range(m);
else if (m->flags & IVMD_FLAG_UNITY_MAP)
if (m->flags & (IVMD_FLAG_UNITY_MAP | IVMD_FLAG_EXCL_RANGE))
init_unity_map_range(m);

p += m->length;
Expand Down
2 changes: 2 additions & 0 deletions drivers/iommu/amd_iommu_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,8 @@
#define IOMMU_PROT_IR 0x01
#define IOMMU_PROT_IW 0x02

#define IOMMU_UNITY_MAP_FLAG_EXCL_RANGE (1 << 2)

/* IOMMU capabilities */
#define IOMMU_CAP_IOTLB 24
#define IOMMU_CAP_NPCACHE 26
Expand Down
8 changes: 5 additions & 3 deletions drivers/iommu/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1105,10 +1105,12 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev)

dom = __iommu_domain_alloc(dev->bus, iommu_def_domain_type);
if (!dom && iommu_def_domain_type != IOMMU_DOMAIN_DMA) {
dev_warn(dev,
"failed to allocate default IOMMU domain of type %u; falling back to IOMMU_DOMAIN_DMA",
iommu_def_domain_type);
dom = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_DMA);
if (dom) {
dev_warn(dev,
"failed to allocate default IOMMU domain of type %u; falling back to IOMMU_DOMAIN_DMA",
iommu_def_domain_type);
}
}

group->default_domain = dom;
Expand Down

0 comments on commit c0b7f2a

Please sign in to comment.