diff options
Diffstat (limited to 'iommu-fix.patch')
-rw-r--r-- | iommu-fix.patch | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/iommu-fix.patch b/iommu-fix.patch new file mode 100644 index 000000000..08cdafd1a --- /dev/null +++ b/iommu-fix.patch @@ -0,0 +1,92 @@ +From b91309eedd77374fdecc379942c44f903e2dedff Mon Sep 17 00:00:00 2001 +From: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com> +Date: Tue, 23 Feb 2016 13:03:30 +0100 +Subject: [PATCH] iommu/amd: Fix boot warning when device 00:00.0 is not iommu + covered + +The setup code for the performance counters in the AMD IOMMU driver +tests whether the counters can be written. It tests to setup a counter +for device 00:00.0, which fails on systems where this particular device +is not covered by the IOMMU. + +Fix this by not relying on device 00:00.0 but only on the IOMMU being +present. + +Cc: stable@vger.kernel.org +Signed-off-by: Suravee Suthikulpanit <Suravee.Suthikulpanit@amd.com> +Signed-off-by: Joerg Roedel <jroedel@suse.de> +--- + drivers/iommu/amd_iommu_init.c | 34 ++++++++++++++++++++++------------ + 1 file changed, 22 insertions(+), 12 deletions(-) + +diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c +index 013bdff..d06a6d9 100644 +--- a/drivers/iommu/amd_iommu_init.c ++++ b/drivers/iommu/amd_iommu_init.c +@@ -228,6 +228,10 @@ static int amd_iommu_enable_interrupts(void); + static int __init iommu_go_to_state(enum iommu_init_state state); + static void init_device_table_dma(void); + ++static int iommu_pc_get_set_reg_val(struct amd_iommu *iommu, ++ u8 bank, u8 cntr, u8 fxn, ++ u64 *value, bool is_write); ++ + static inline void update_last_devid(u16 devid) + { + if (devid > amd_iommu_last_bdf) +@@ -1142,8 +1146,8 @@ static void init_iommu_perf_ctr(struct amd_iommu *iommu) + amd_iommu_pc_present = true; + + /* Check if the performance counters can be written to */ +- if ((0 != amd_iommu_pc_get_set_reg_val(0, 0, 0, 0, &val, true)) || +- (0 != amd_iommu_pc_get_set_reg_val(0, 0, 0, 0, &val2, false)) || ++ if ((0 != iommu_pc_get_set_reg_val(iommu, 0, 0, 0, &val, true)) || ++ (0 != iommu_pc_get_set_reg_val(iommu, 0, 0, 0, &val2, false)) || + (val != val2)) { + pr_err("AMD-Vi: Unable to write to IOMMU perf counter.\n"); + amd_iommu_pc_present = false; +@@ -2283,22 +2287,15 @@ u8 amd_iommu_pc_get_max_counters(u16 devid) + } + EXPORT_SYMBOL(amd_iommu_pc_get_max_counters); + +-int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn, ++static int iommu_pc_get_set_reg_val(struct amd_iommu *iommu, ++ u8 bank, u8 cntr, u8 fxn, + u64 *value, bool is_write) + { +- struct amd_iommu *iommu; + u32 offset; + u32 max_offset_lim; + +- /* Make sure the IOMMU PC resource is available */ +- if (!amd_iommu_pc_present) +- return -ENODEV; +- +- /* Locate the iommu associated with the device ID */ +- iommu = amd_iommu_rlookup_table[devid]; +- + /* Check for valid iommu and pc register indexing */ +- if (WARN_ON((iommu == NULL) || (fxn > 0x28) || (fxn & 7))) ++ if (WARN_ON((fxn > 0x28) || (fxn & 7))) + return -ENODEV; + + offset = (u32)(((0x40|bank) << 12) | (cntr << 8) | fxn); +@@ -2322,3 +2319,16 @@ int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn, + return 0; + } + EXPORT_SYMBOL(amd_iommu_pc_get_set_reg_val); ++ ++int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn, ++ u64 *value, bool is_write) ++{ ++ struct amd_iommu *iommu = amd_iommu_rlookup_table[devid]; ++ ++ /* Make sure the IOMMU PC resource is available */ ++ if (!amd_iommu_pc_present || iommu == NULL) ++ return -ENODEV; ++ ++ return iommu_pc_get_set_reg_val(iommu, bank, cntr, fxn, ++ value, is_write); ++} +-- +1.8.4.5 |