History

iommu/vt-d: Gracefully handle DMAR units with no supported address widths

Instead of bailing out completely, such a unit can still be used for interrupt remapping.

David Woodhouse committed 6 years ago

Commit c40aaaa1 parent d2ef0961 file · +31 −15Browse files

Unified · Split

drivers/iommu/intel/dmar.c+31−15
@@ -1024,8 +1024,8 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) · 1023 unmodified lines
1024{1024{
1025 struct intel_iommu *iommu;1025 struct intel_iommu *iommu;
1026 u32 ver, sts;1026 u32 ver, sts;
1027 int agaw = 0;1027 int agaw = -1;
1028 int msagaw = 0;1028 int msagaw = -1;
1029 int err;1029 int err;
1030 1030
1031 if (!drhd->reg_base_addr) {1031 if (!drhd->reg_base_addr) {
@@ -1050,17 +1050,28 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) · 18 unmodified lines
1050 }1050 }
1051 1051
1052 err = -EINVAL;1052 err = -EINVAL;
1053 agaw = iommu_calculate_agaw(iommu);1053 if (cap_sagaw(iommu->cap) == 0) {
1054 if (agaw < 0) {1054 pr_info("%s: No supported address widths. Not attempting DMA translation.\n",
1055 pr_err("Cannot get a valid agaw for iommu (seq_id = %d)\n",1055 iommu->name);
1056 iommu->seq_id);1056 drhd->ignored = 1;
1057 goto err_unmap;1057 }
1058 }1058
1059 msagaw = iommu_calculate_max_sagaw(iommu);1059 if (!drhd->ignored) {
1060 if (msagaw < 0) {1060 agaw = iommu_calculate_agaw(iommu);
1061 pr_err("Cannot get a valid max agaw for iommu (seq_id = %d)\n",1061 if (agaw < 0) {
1062 iommu->seq_id);1062 pr_err("Cannot get a valid agaw for iommu (seq_id = %d)\n",
1063 goto err_unmap;1063 iommu->seq_id);
1064 drhd->ignored = 1;
1065 }
1066 }
1067 if (!drhd->ignored) {
1068 msagaw = iommu_calculate_max_sagaw(iommu);
1069 if (msagaw < 0) {
1070 pr_err("Cannot get a valid max agaw for iommu (seq_id = %d)\n",
1071 iommu->seq_id);
1072 drhd->ignored = 1;
1073 agaw = -1;
1074 }
1064 }1075 }
1065 iommu->agaw = agaw;1076 iommu->agaw = agaw;
1066 iommu->msagaw = msagaw;1077 iommu->msagaw = msagaw;
@@ -1087,7 +1098,12 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) · 20 unmodified lines
1087 1098
1088 raw_spin_lock_init(&iommu->register_lock);1099 raw_spin_lock_init(&iommu->register_lock);
1089 1100
1090 if (intel_iommu_enabled) {1101 /*
1102 * This is only for hotplug; at boot time intel_iommu_enabled won't
1103 * be set yet. When intel_iommu_init() runs, it registers the units
1104 * present at boot time, then sets intel_iommu_enabled.
1105 */
1106 if (intel_iommu_enabled && !drhd->ignored) {
1091 err = iommu_device_sysfs_add(&iommu->iommu, NULL,1107 err = iommu_device_sysfs_add(&iommu->iommu, NULL,
1092 intel_iommu_groups,1108 intel_iommu_groups,
1093 "%s", iommu->name);1109 "%s", iommu->name);
@@ -1117,7 +1133,7 @@ error: · 23 unmodified lines
1117 1133
1118static void free_iommu(struct intel_iommu *iommu)1134static void free_iommu(struct intel_iommu *iommu)
1119{1135{
1120 if (intel_iommu_enabled) {1136 if (intel_iommu_enabled && iommu->iommu.ops) {
1121 iommu_device_unregister(&iommu->iommu);1137 iommu_device_unregister(&iommu->iommu);
1122 iommu_device_sysfs_remove(&iommu->iommu);1138 iommu_device_sysfs_remove(&iommu->iommu);
1123 }1139 }