You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: drivers/iommu/iommu.c
+26-5Lines changed: 26 additions & 5 deletions
Original file line number
Diff line number
Diff line change
@@ -1143,35 +1143,43 @@ static int iommu_create_device_fw_mappings(struct iommu_domain *domain,
1143
1143
1144
1144
/* We need to consider overlapping regions for different devices */
1145
1145
list_for_each_entry(entry, &mappings, list) {
1146
-
dma_addr_tstart, end, addr;
1146
+
dma_addr_tstart, end, addr, iova;
1147
1147
size_tmap_size=0;
1148
1148
1149
1149
if (entry->type==IOMMU_RESV_DIRECT)
1150
1150
dev->iommu->require_direct=1;
1151
+
if (entry->type==IOMMU_RESV_TRANSLATED)
1152
+
dev->iommu->require_translated=1;
1151
1153
1152
1154
if ((entry->type!=IOMMU_RESV_DIRECT&&
1153
-
entry->type!=IOMMU_RESV_DIRECT_RELAXABLE) ||
1155
+
entry->type!=IOMMU_RESV_DIRECT_RELAXABLE&&
1156
+
entry->type!=IOMMU_RESV_TRANSLATED) ||
1154
1157
!iommu_is_dma_domain(domain))
1155
1158
continue;
1156
1159
1157
1160
start=ALIGN(entry->start, pg_size);
1158
1161
end=ALIGN(entry->start+entry->length, pg_size);
1159
1162
1160
-
for (addr=start; addr <= end; addr+=pg_size) {
1163
+
if (entry->type==IOMMU_RESV_TRANSLATED)
1164
+
iova=ALIGN(entry->dva, pg_size);
1165
+
else
1166
+
iova=start;
1167
+
1168
+
for (addr=start; addr <= end; addr+=pg_size, iova+=pg_size) {
1161
1169
phys_addr_tphys_addr;
1162
1170
1163
1171
if (addr==end)
1164
1172
goto map_end;
1165
1173
1166
-
phys_addr=iommu_iova_to_phys(domain, addr);
1174
+
phys_addr=iommu_iova_to_phys(domain, iova);
1167
1175
if (!phys_addr) {
1168
1176
map_size+=pg_size;
1169
1177
continue;
1170
1178
}
1171
1179
1172
1180
map_end:
1173
1181
if (map_size) {
1174
-
ret=iommu_map(domain, addr-map_size,
1182
+
ret=iommu_map(domain, iova-map_size,
1175
1183
addr-map_size, map_size,
1176
1184
entry->prot, GFP_KERNEL);
1177
1185
if (ret)
@@ -2266,6 +2274,19 @@ static int __iommu_device_set_domain(struct iommu_group *group,
2266
2274
"Firmware has requested this device have a 1:1 IOMMU mapping, rejecting configuring the device without a 1:1 mapping. Contact your platform vendor.\n");
2267
2275
return-EINVAL;
2268
2276
}
2277
+
/*
2278
+
* If the device requires IOMMU_RESV_TRANSLATED then we cannot allow
2279
+
* the identy or blocking domain to be attached as it does not contain
2280
+
* the required translated mapping.
2281
+
*/
2282
+
if (dev->iommu->require_translated&&
2283
+
(new_domain->type==IOMMU_DOMAIN_IDENTITY||
2284
+
new_domain->type==IOMMU_DOMAIN_BLOCKED||
2285
+
new_domain==group->blocking_domain)) {
2286
+
dev_warn(dev,
2287
+
"Firmware has requested this device have a translated IOMMU mapping, rejecting configuring the device without a translated mapping. Contact your platform vendor.\n");
0 commit comments