diff options
author | Adrian Huang <adrianhuang0701@gmail.com> | 2019-11-14 14:14:47 +0800 |
---|---|---|
committer | Joerg Roedel <jroedel@suse.de> | 2019-12-23 14:06:15 +0100 |
commit | 387caf0b759ac437a65ad5d59665558025f350fc (patch) | |
tree | 76ee0055b568b51eceb4033f5d913827c090d7ae /drivers/iommu | |
parent | 46cf053efec6a3a5f343fead837777efe8252a46 (diff) | |
download | blackbird-op-linux-387caf0b759ac437a65ad5d59665558025f350fc.tar.gz blackbird-op-linux-387caf0b759ac437a65ad5d59665558025f350fc.zip |
iommu/amd: Treat per-device exclusion ranges as r/w unity-mapped regions
Some buggy BIOSes might define multiple exclusion ranges of the
IVMD entries which are associated with the same IOMMU hardware.
This leads to the overwritten exclusion range (exclusion_start
and exclusion_length members) in set_device_exclusion_range().
Here is a real case:
When attaching two Broadcom RAID controllers to a server, the first
one reports the failure during booting (the disks connecting to the
RAID controller cannot be detected).
This patch prevents the issue by treating per-device exclusion
ranges as r/w unity-mapped regions.
Discussion:
* https://lists.linuxfoundation.org/pipermail/iommu/2019-November/040140.html
Suggested-by: Joerg Roedel <joro@8bytes.org>
Signed-off-by: Adrian Huang <ahuang12@lenovo.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu')
-rw-r--r-- | drivers/iommu/amd_iommu_init.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 568c52317757..1b65302e07b1 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -71,6 +71,8 @@ #define IVHD_FLAG_ISOC_EN_MASK 0x08 #define IVMD_FLAG_EXCL_RANGE 0x08 +#define IVMD_FLAG_IW 0x04 +#define IVMD_FLAG_IR 0x02 #define IVMD_FLAG_UNITY_MAP 0x01 #define ACPI_DEVFLAG_INITPASS 0x01 @@ -1121,16 +1123,14 @@ static void __init set_device_exclusion_range(u16 devid, struct ivmd_header *m) if (!(m->flags & IVMD_FLAG_EXCL_RANGE)) return; - if (iommu) { - /* - * We only can configure exclusion ranges per IOMMU, not - * per device. But we can enable the exclusion range per - * device. This is done here - */ - set_dev_entry_bit(devid, DEV_ENTRY_EX); - iommu->exclusion_start = m->range_start; - iommu->exclusion_length = m->range_length; - } + /* + * Treat per-device exclusion ranges as r/w unity-mapped regions + * since some buggy BIOSes might lead to the overwritten exclusion + * range (exclusion_start and exclusion_length members). This + * happens when there are multiple exclusion ranges (IVMD entries) + * defined in ACPI table. + */ + m->flags = (IVMD_FLAG_IW | IVMD_FLAG_IR | IVMD_FLAG_UNITY_MAP); } /* |