Instead of bailing out completely, such a unit can still be used for interrupt remapping.
Unified · Split
| @@ -1024,8 +1024,8 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) · 1023 unmodified lines | ||
| 1024 | 1024 | { |
| 1025 | 1025 | struct intel_iommu *iommu; |
| 1026 | 1026 | u32 ver, sts; |
| 1027 | − int agaw = 0; | |
| 1028 | − int msagaw = 0; | |
| 1027 | + int agaw = -1; | |
| 1028 | + int msagaw = -1; | |
| 1029 | 1029 | int err; |
| 1030 | 1030 | |
| 1031 | 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 | 1052 | err = -EINVAL; |
| 1053 | − agaw = iommu_calculate_agaw(iommu); | |
| 1054 | − if (agaw < 0) { | |
| 1055 | − pr_err("Cannot get a valid agaw for iommu (seq_id = %d)\n", | |
| 1056 | − iommu->seq_id); | |
| 1057 | − goto err_unmap; | |
| 1058 | − } | |
| 1059 | − msagaw = iommu_calculate_max_sagaw(iommu); | |
| 1060 | − if (msagaw < 0) { | |
| 1061 | − pr_err("Cannot get a valid max agaw for iommu (seq_id = %d)\n", | |
| 1062 | − iommu->seq_id); | |
| 1063 | − goto err_unmap; | |
| 1053 | + if (cap_sagaw(iommu->cap) == 0) { | |
| 1054 | + pr_info("%s: No supported address widths. Not attempting DMA translation.\n", | |
| 1055 | + iommu->name); | |
| 1056 | + drhd->ignored = 1; | |
| 1057 | + } | |
| 1058 | + | |
| 1059 | + if (!drhd->ignored) { | |
| 1060 | + agaw = iommu_calculate_agaw(iommu); | |
| 1061 | + if (agaw < 0) { | |
| 1062 | + pr_err("Cannot get a valid agaw for iommu (seq_id = %d)\n", | |
| 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 | 1076 | iommu->agaw = agaw; |
| 1066 | 1077 | iommu->msagaw = msagaw; |
| @@ -1087,7 +1098,12 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) · 20 unmodified lines | ||
| 1087 | 1098 | |
| 1088 | 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 | 1107 | err = iommu_device_sysfs_add(&iommu->iommu, NULL, |
| 1092 | 1108 | intel_iommu_groups, |
| 1093 | 1109 | "%s", iommu->name); |
| @@ -1117,7 +1133,7 @@ error: · 23 unmodified lines | ||
| 1117 | 1133 | |
| 1118 | 1134 | static void free_iommu(struct intel_iommu *iommu) |
| 1119 | 1135 | { |
| 1120 | − if (intel_iommu_enabled) { | |
| 1136 | + if (intel_iommu_enabled && iommu->iommu.ops) { | |
| 1121 | 1137 | iommu_device_unregister(&iommu->iommu); |
| 1122 | 1138 | iommu_device_sysfs_remove(&iommu->iommu); |
| 1123 | 1139 | } |