aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dma-debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dma-debug.c')
-rw-r--r--lib/dma-debug.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index d3e06a5e981e..d87a17a819d0 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -1085,13 +1085,27 @@ void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
1085 ref.dev = dev; 1085 ref.dev = dev;
1086 ref.dev_addr = dma_addr; 1086 ref.dev_addr = dma_addr;
1087 bucket = get_hash_bucket(&ref, &flags); 1087 bucket = get_hash_bucket(&ref, &flags);
1088 entry = bucket_find_exact(bucket, &ref);
1089 1088
1090 if (!entry) 1089 list_for_each_entry(entry, &bucket->list, list) {
1091 goto out; 1090 if (!exact_match(&ref, entry))
1091 continue;
1092
1093 /*
1094 * The same physical address can be mapped multiple
1095 * times. Without a hardware IOMMU this results in the
1096 * same device addresses being put into the dma-debug
1097 * hash multiple times too. This can result in false
1098 * positives being reported. Therefore we implement a
1099 * best-fit algorithm here which updates the first entry
1100 * from the hash which fits the reference value and is
1101 * not currently listed as being checked.
1102 */
1103 if (entry->map_err_type == MAP_ERR_NOT_CHECKED) {
1104 entry->map_err_type = MAP_ERR_CHECKED;
1105 break;
1106 }
1107 }
1092 1108
1093 entry->map_err_type = MAP_ERR_CHECKED;
1094out:
1095 put_hash_bucket(bucket, &flags); 1109 put_hash_bucket(bucket, &flags);
1096} 1110}
1097EXPORT_SYMBOL(debug_dma_mapping_error); 1111EXPORT_SYMBOL(debug_dma_mapping_error);