diff options
| -rw-r--r-- | arch/x86/Kconfig.debug | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/pci-calgary_64.c | 54 | ||||
| -rw-r--r-- | arch/x86/kernel/pci-gart_64.c | 45 | ||||
| -rw-r--r-- | arch/x86/kernel/pci-swiotlb.c | 2 | ||||
| -rw-r--r-- | include/linux/dma-debug.h | 7 | ||||
| -rw-r--r-- | include/linux/swiotlb.h | 3 | ||||
| -rw-r--r-- | lib/dma-debug.c | 72 | ||||
| -rw-r--r-- | lib/swiotlb.c | 119 |
8 files changed, 149 insertions, 156 deletions
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index d8359e73317f..5865712d105d 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug | |||
| @@ -161,8 +161,7 @@ config IOMMU_DEBUG | |||
| 161 | 161 | ||
| 162 | config IOMMU_LEAK | 162 | config IOMMU_LEAK |
| 163 | bool "IOMMU leak tracing" | 163 | bool "IOMMU leak tracing" |
| 164 | depends on DEBUG_KERNEL | 164 | depends on IOMMU_DEBUG && DMA_API_DEBUG |
| 165 | depends on IOMMU_DEBUG | ||
| 166 | ---help--- | 165 | ---help--- |
| 167 | Add a simple leak tracer to the IOMMU code. This is useful when you | 166 | Add a simple leak tracer to the IOMMU code. This is useful when you |
| 168 | are debugging a buggy device driver that leaks IOMMU mappings. | 167 | are debugging a buggy device driver that leaks IOMMU mappings. |
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index 755c21e906f3..971a3bec47a8 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c | |||
| @@ -186,37 +186,6 @@ static struct cal_chipset_ops calioc2_chip_ops = { | |||
| 186 | 186 | ||
| 187 | static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, }; | 187 | static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, }; |
| 188 | 188 | ||
| 189 | /* enable this to stress test the chip's TCE cache */ | ||
| 190 | #ifdef CONFIG_IOMMU_DEBUG | ||
| 191 | static int debugging = 1; | ||
| 192 | |||
| 193 | static inline unsigned long verify_bit_range(unsigned long* bitmap, | ||
| 194 | int expected, unsigned long start, unsigned long end) | ||
| 195 | { | ||
| 196 | unsigned long idx = start; | ||
| 197 | |||
| 198 | BUG_ON(start >= end); | ||
| 199 | |||
| 200 | while (idx < end) { | ||
| 201 | if (!!test_bit(idx, bitmap) != expected) | ||
| 202 | return idx; | ||
| 203 | ++idx; | ||
| 204 | } | ||
| 205 | |||
| 206 | /* all bits have the expected value */ | ||
| 207 | return ~0UL; | ||
| 208 | } | ||
| 209 | #else /* debugging is disabled */ | ||
| 210 | static int debugging; | ||
| 211 | |||
| 212 | static inline unsigned long verify_bit_range(unsigned long* bitmap, | ||
| 213 | int expected, unsigned long start, unsigned long end) | ||
| 214 | { | ||
| 215 | return ~0UL; | ||
| 216 | } | ||
| 217 | |||
| 218 | #endif /* CONFIG_IOMMU_DEBUG */ | ||
| 219 | |||
| 220 | static inline int translation_enabled(struct iommu_table *tbl) | 189 | static inline int translation_enabled(struct iommu_table *tbl) |
| 221 | { | 190 | { |
| 222 | /* only PHBs with translation enabled have an IOMMU table */ | 191 | /* only PHBs with translation enabled have an IOMMU table */ |
| @@ -228,7 +197,6 @@ static void iommu_range_reserve(struct iommu_table *tbl, | |||
| 228 | { | 197 | { |
| 229 | unsigned long index; | 198 | unsigned long index; |
| 230 | unsigned long end; | 199 | unsigned long end; |
| 231 | unsigned long badbit; | ||
| 232 | unsigned long flags; | 200 | unsigned long flags; |
| 233 | 201 | ||
| 234 | index = start_addr >> PAGE_SHIFT; | 202 | index = start_addr >> PAGE_SHIFT; |
| @@ -243,14 +211,6 @@ static void iommu_range_reserve(struct iommu_table *tbl, | |||
| 243 | 211 | ||
| 244 | spin_lock_irqsave(&tbl->it_lock, flags); | 212 | spin_lock_irqsave(&tbl->it_lock, flags); |
| 245 | 213 | ||
| 246 | badbit = verify_bit_range(tbl->it_map, 0, index, end); | ||
| 247 | if (badbit != ~0UL) { | ||
| 248 | if (printk_ratelimit()) | ||
| 249 | printk(KERN_ERR "Calgary: entry already allocated at " | ||
| 250 | "0x%lx tbl %p dma 0x%lx npages %u\n", | ||
| 251 | badbit, tbl, start_addr, npages); | ||
| 252 | } | ||
| 253 | |||
| 254 | iommu_area_reserve(tbl->it_map, index, npages); | 214 | iommu_area_reserve(tbl->it_map, index, npages); |
| 255 | 215 | ||
| 256 | spin_unlock_irqrestore(&tbl->it_lock, flags); | 216 | spin_unlock_irqrestore(&tbl->it_lock, flags); |
| @@ -326,7 +286,6 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, | |||
| 326 | unsigned int npages) | 286 | unsigned int npages) |
| 327 | { | 287 | { |
| 328 | unsigned long entry; | 288 | unsigned long entry; |
| 329 | unsigned long badbit; | ||
| 330 | unsigned long badend; | 289 | unsigned long badend; |
| 331 | unsigned long flags; | 290 | unsigned long flags; |
| 332 | 291 | ||
| @@ -346,14 +305,6 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, | |||
| 346 | 305 | ||
| 347 | spin_lock_irqsave(&tbl->it_lock, flags); | 306 | spin_lock_irqsave(&tbl->it_lock, flags); |
| 348 | 307 | ||
| 349 | badbit = verify_bit_range(tbl->it_map, 1, entry, entry + npages); | ||
| 350 | if (badbit != ~0UL) { | ||
| 351 | if (printk_ratelimit()) | ||
| 352 | printk(KERN_ERR "Calgary: bit is off at 0x%lx " | ||
| 353 | "tbl %p dma 0x%Lx entry 0x%lx npages %u\n", | ||
| 354 | badbit, tbl, dma_addr, entry, npages); | ||
| 355 | } | ||
| 356 | |||
| 357 | iommu_area_free(tbl->it_map, entry, npages); | 308 | iommu_area_free(tbl->it_map, entry, npages); |
| 358 | 309 | ||
| 359 | spin_unlock_irqrestore(&tbl->it_lock, flags); | 310 | spin_unlock_irqrestore(&tbl->it_lock, flags); |
| @@ -1488,9 +1439,8 @@ void __init detect_calgary(void) | |||
| 1488 | iommu_detected = 1; | 1439 | iommu_detected = 1; |
| 1489 | calgary_detected = 1; | 1440 | calgary_detected = 1; |
| 1490 | printk(KERN_INFO "PCI-DMA: Calgary IOMMU detected.\n"); | 1441 | printk(KERN_INFO "PCI-DMA: Calgary IOMMU detected.\n"); |
| 1491 | printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d, " | 1442 | printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d\n", |
| 1492 | "CONFIG_IOMMU_DEBUG is %s.\n", specified_table_size, | 1443 | specified_table_size); |
| 1493 | debugging ? "enabled" : "disabled"); | ||
| 1494 | 1444 | ||
| 1495 | /* swiotlb for devices that aren't behind the Calgary. */ | 1445 | /* swiotlb for devices that aren't behind the Calgary. */ |
| 1496 | if (max_pfn > MAX_DMA32_PFN) | 1446 | if (max_pfn > MAX_DMA32_PFN) |
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c index b284b58c035c..1e8920d98f7c 100644 --- a/arch/x86/kernel/pci-gart_64.c +++ b/arch/x86/kernel/pci-gart_64.c | |||
| @@ -144,48 +144,21 @@ static void flush_gart(void) | |||
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | #ifdef CONFIG_IOMMU_LEAK | 146 | #ifdef CONFIG_IOMMU_LEAK |
| 147 | |||
| 148 | #define SET_LEAK(x) \ | ||
| 149 | do { \ | ||
| 150 | if (iommu_leak_tab) \ | ||
| 151 | iommu_leak_tab[x] = __builtin_return_address(0);\ | ||
| 152 | } while (0) | ||
| 153 | |||
| 154 | #define CLEAR_LEAK(x) \ | ||
| 155 | do { \ | ||
| 156 | if (iommu_leak_tab) \ | ||
| 157 | iommu_leak_tab[x] = NULL; \ | ||
| 158 | } while (0) | ||
| 159 | |||
| 160 | /* Debugging aid for drivers that don't free their IOMMU tables */ | 147 | /* Debugging aid for drivers that don't free their IOMMU tables */ |
| 161 | static void **iommu_leak_tab; | ||
| 162 | static int leak_trace; | 148 | static int leak_trace; |
| 163 | static int iommu_leak_pages = 20; | 149 | static int iommu_leak_pages = 20; |
| 164 | 150 | ||
| 165 | static void dump_leak(void) | 151 | static void dump_leak(void) |
| 166 | { | 152 | { |
| 167 | int i; | ||
| 168 | static int dump; | 153 | static int dump; |
| 169 | 154 | ||
| 170 | if (dump || !iommu_leak_tab) | 155 | if (dump) |
| 171 | return; | 156 | return; |
| 172 | dump = 1; | 157 | dump = 1; |
| 173 | show_stack(NULL, NULL); | ||
| 174 | 158 | ||
| 175 | /* Very crude. dump some from the end of the table too */ | 159 | show_stack(NULL, NULL); |
| 176 | printk(KERN_DEBUG "Dumping %d pages from end of IOMMU:\n", | 160 | debug_dma_dump_mappings(NULL); |
| 177 | iommu_leak_pages); | ||
| 178 | for (i = 0; i < iommu_leak_pages; i += 2) { | ||
| 179 | printk(KERN_DEBUG "%lu: ", iommu_pages-i); | ||
| 180 | printk_address((unsigned long) iommu_leak_tab[iommu_pages-i], | ||
| 181 | 0); | ||
| 182 | printk(KERN_CONT "%c", (i+1)%2 == 0 ? '\n' : ' '); | ||
| 183 | } | ||
| 184 | printk(KERN_DEBUG "\n"); | ||
| 185 | } | 161 | } |
| 186 | #else | ||
| 187 | # define SET_LEAK(x) | ||
| 188 | # define CLEAR_LEAK(x) | ||
| 189 | #endif | 162 | #endif |
| 190 | 163 | ||
| 191 | static void iommu_full(struct device *dev, size_t size, int dir) | 164 | static void iommu_full(struct device *dev, size_t size, int dir) |
| @@ -248,7 +221,6 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, | |||
| 248 | 221 | ||
| 249 | for (i = 0; i < npages; i++) { | 222 | for (i = 0; i < npages; i++) { |
| 250 | iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem); | 223 | iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem); |
| 251 | SET_LEAK(iommu_page + i); | ||
| 252 | phys_mem += PAGE_SIZE; | 224 | phys_mem += PAGE_SIZE; |
| 253 | } | 225 | } |
| 254 | return iommu_bus_base + iommu_page*PAGE_SIZE + (phys_mem & ~PAGE_MASK); | 226 | return iommu_bus_base + iommu_page*PAGE_SIZE + (phys_mem & ~PAGE_MASK); |
| @@ -294,7 +266,6 @@ static void gart_unmap_page(struct device *dev, dma_addr_t dma_addr, | |||
| 294 | npages = iommu_num_pages(dma_addr, size, PAGE_SIZE); | 266 | npages = iommu_num_pages(dma_addr, size, PAGE_SIZE); |
| 295 | for (i = 0; i < npages; i++) { | 267 | for (i = 0; i < npages; i++) { |
| 296 | iommu_gatt_base[iommu_page + i] = gart_unmapped_entry; | 268 | iommu_gatt_base[iommu_page + i] = gart_unmapped_entry; |
| 297 | CLEAR_LEAK(iommu_page + i); | ||
| 298 | } | 269 | } |
| 299 | free_iommu(iommu_page, npages); | 270 | free_iommu(iommu_page, npages); |
| 300 | } | 271 | } |
| @@ -377,7 +348,6 @@ static int __dma_map_cont(struct device *dev, struct scatterlist *start, | |||
| 377 | pages = iommu_num_pages(s->offset, s->length, PAGE_SIZE); | 348 | pages = iommu_num_pages(s->offset, s->length, PAGE_SIZE); |
| 378 | while (pages--) { | 349 | while (pages--) { |
| 379 | iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr); | 350 | iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr); |
| 380 | SET_LEAK(iommu_page); | ||
| 381 | addr += PAGE_SIZE; | 351 | addr += PAGE_SIZE; |
| 382 | iommu_page++; | 352 | iommu_page++; |
| 383 | } | 353 | } |
| @@ -801,11 +771,12 @@ void __init gart_iommu_init(void) | |||
| 801 | 771 | ||
| 802 | #ifdef CONFIG_IOMMU_LEAK | 772 | #ifdef CONFIG_IOMMU_LEAK |
| 803 | if (leak_trace) { | 773 | if (leak_trace) { |
| 804 | iommu_leak_tab = (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, | 774 | int ret; |
| 805 | get_order(iommu_pages*sizeof(void *))); | 775 | |
| 806 | if (!iommu_leak_tab) | 776 | ret = dma_debug_resize_entries(iommu_pages); |
| 777 | if (ret) | ||
| 807 | printk(KERN_DEBUG | 778 | printk(KERN_DEBUG |
| 808 | "PCI-DMA: Cannot allocate leak trace area\n"); | 779 | "PCI-DMA: Cannot trace all the entries\n"); |
| 809 | } | 780 | } |
| 810 | #endif | 781 | #endif |
| 811 | 782 | ||
diff --git a/arch/x86/kernel/pci-swiotlb.c b/arch/x86/kernel/pci-swiotlb.c index 221a3853e268..a1712f2b50f1 100644 --- a/arch/x86/kernel/pci-swiotlb.c +++ b/arch/x86/kernel/pci-swiotlb.c | |||
| @@ -28,7 +28,7 @@ dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr) | |||
| 28 | return paddr; | 28 | return paddr; |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | phys_addr_t swiotlb_bus_to_phys(dma_addr_t baddr) | 31 | phys_addr_t swiotlb_bus_to_phys(struct device *hwdev, dma_addr_t baddr) |
| 32 | { | 32 | { |
| 33 | return baddr; | 33 | return baddr; |
| 34 | } | 34 | } |
diff --git a/include/linux/dma-debug.h b/include/linux/dma-debug.h index 28d53cb7b5a2..171ad8aedc83 100644 --- a/include/linux/dma-debug.h +++ b/include/linux/dma-debug.h | |||
| @@ -32,6 +32,8 @@ extern void dma_debug_add_bus(struct bus_type *bus); | |||
| 32 | 32 | ||
| 33 | extern void dma_debug_init(u32 num_entries); | 33 | extern void dma_debug_init(u32 num_entries); |
| 34 | 34 | ||
| 35 | extern int dma_debug_resize_entries(u32 num_entries); | ||
| 36 | |||
| 35 | extern void debug_dma_map_page(struct device *dev, struct page *page, | 37 | extern void debug_dma_map_page(struct device *dev, struct page *page, |
| 36 | size_t offset, size_t size, | 38 | size_t offset, size_t size, |
| 37 | int direction, dma_addr_t dma_addr, | 39 | int direction, dma_addr_t dma_addr, |
| @@ -91,6 +93,11 @@ static inline void dma_debug_init(u32 num_entries) | |||
| 91 | { | 93 | { |
| 92 | } | 94 | } |
| 93 | 95 | ||
| 96 | static inline int dma_debug_resize_entries(u32 num_entries) | ||
| 97 | { | ||
| 98 | return 0; | ||
| 99 | } | ||
| 100 | |||
| 94 | static inline void debug_dma_map_page(struct device *dev, struct page *page, | 101 | static inline void debug_dma_map_page(struct device *dev, struct page *page, |
| 95 | size_t offset, size_t size, | 102 | size_t offset, size_t size, |
| 96 | int direction, dma_addr_t dma_addr, | 103 | int direction, dma_addr_t dma_addr, |
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index ac9ff54f7cb3..cb1a6631b8f4 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h | |||
| @@ -29,7 +29,8 @@ extern void *swiotlb_alloc(unsigned order, unsigned long nslabs); | |||
| 29 | 29 | ||
| 30 | extern dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, | 30 | extern dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, |
| 31 | phys_addr_t address); | 31 | phys_addr_t address); |
| 32 | extern phys_addr_t swiotlb_bus_to_phys(dma_addr_t address); | 32 | extern phys_addr_t swiotlb_bus_to_phys(struct device *hwdev, |
| 33 | dma_addr_t address); | ||
| 33 | 34 | ||
| 34 | extern int swiotlb_arch_range_needs_mapping(phys_addr_t paddr, size_t size); | 35 | extern int swiotlb_arch_range_needs_mapping(phys_addr_t paddr, size_t size); |
| 35 | 36 | ||
diff --git a/lib/dma-debug.c b/lib/dma-debug.c index 69da09a085a1..cdd205d6bf7c 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c | |||
| @@ -85,6 +85,7 @@ static u32 show_num_errors = 1; | |||
| 85 | 85 | ||
| 86 | static u32 num_free_entries; | 86 | static u32 num_free_entries; |
| 87 | static u32 min_free_entries; | 87 | static u32 min_free_entries; |
| 88 | static u32 nr_total_entries; | ||
| 88 | 89 | ||
| 89 | /* number of preallocated entries requested by kernel cmdline */ | 90 | /* number of preallocated entries requested by kernel cmdline */ |
| 90 | static u32 req_entries; | 91 | static u32 req_entries; |
| @@ -257,6 +258,21 @@ static void add_dma_entry(struct dma_debug_entry *entry) | |||
| 257 | put_hash_bucket(bucket, &flags); | 258 | put_hash_bucket(bucket, &flags); |
| 258 | } | 259 | } |
| 259 | 260 | ||
| 261 | static struct dma_debug_entry *__dma_entry_alloc(void) | ||
| 262 | { | ||
| 263 | struct dma_debug_entry *entry; | ||
| 264 | |||
| 265 | entry = list_entry(free_entries.next, struct dma_debug_entry, list); | ||
| 266 | list_del(&entry->list); | ||
| 267 | memset(entry, 0, sizeof(*entry)); | ||
| 268 | |||
| 269 | num_free_entries -= 1; | ||
| 270 | if (num_free_entries < min_free_entries) | ||
| 271 | min_free_entries = num_free_entries; | ||
| 272 | |||
| 273 | return entry; | ||
| 274 | } | ||
| 275 | |||
| 260 | /* struct dma_entry allocator | 276 | /* struct dma_entry allocator |
| 261 | * | 277 | * |
| 262 | * The next two functions implement the allocator for | 278 | * The next two functions implement the allocator for |
| @@ -276,9 +292,7 @@ static struct dma_debug_entry *dma_entry_alloc(void) | |||
| 276 | goto out; | 292 | goto out; |
| 277 | } | 293 | } |
| 278 | 294 | ||
| 279 | entry = list_entry(free_entries.next, struct dma_debug_entry, list); | 295 | entry = __dma_entry_alloc(); |
| 280 | list_del(&entry->list); | ||
| 281 | memset(entry, 0, sizeof(*entry)); | ||
| 282 | 296 | ||
| 283 | #ifdef CONFIG_STACKTRACE | 297 | #ifdef CONFIG_STACKTRACE |
| 284 | entry->stacktrace.max_entries = DMA_DEBUG_STACKTRACE_ENTRIES; | 298 | entry->stacktrace.max_entries = DMA_DEBUG_STACKTRACE_ENTRIES; |
| @@ -286,9 +300,6 @@ static struct dma_debug_entry *dma_entry_alloc(void) | |||
| 286 | entry->stacktrace.skip = 2; | 300 | entry->stacktrace.skip = 2; |
| 287 | save_stack_trace(&entry->stacktrace); | 301 | save_stack_trace(&entry->stacktrace); |
| 288 | #endif | 302 | #endif |
| 289 | num_free_entries -= 1; | ||
| 290 | if (num_free_entries < min_free_entries) | ||
| 291 | min_free_entries = num_free_entries; | ||
| 292 | 303 | ||
| 293 | out: | 304 | out: |
| 294 | spin_unlock_irqrestore(&free_entries_lock, flags); | 305 | spin_unlock_irqrestore(&free_entries_lock, flags); |
| @@ -310,6 +321,53 @@ static void dma_entry_free(struct dma_debug_entry *entry) | |||
| 310 | spin_unlock_irqrestore(&free_entries_lock, flags); | 321 | spin_unlock_irqrestore(&free_entries_lock, flags); |
| 311 | } | 322 | } |
| 312 | 323 | ||
| 324 | int dma_debug_resize_entries(u32 num_entries) | ||
| 325 | { | ||
| 326 | int i, delta, ret = 0; | ||
| 327 | unsigned long flags; | ||
| 328 | struct dma_debug_entry *entry; | ||
| 329 | LIST_HEAD(tmp); | ||
| 330 | |||
| 331 | spin_lock_irqsave(&free_entries_lock, flags); | ||
| 332 | |||
| 333 | if (nr_total_entries < num_entries) { | ||
| 334 | delta = num_entries - nr_total_entries; | ||
| 335 | |||
| 336 | spin_unlock_irqrestore(&free_entries_lock, flags); | ||
| 337 | |||
| 338 | for (i = 0; i < delta; i++) { | ||
| 339 | entry = kzalloc(sizeof(*entry), GFP_KERNEL); | ||
| 340 | if (!entry) | ||
| 341 | break; | ||
| 342 | |||
| 343 | list_add_tail(&entry->list, &tmp); | ||
| 344 | } | ||
| 345 | |||
| 346 | spin_lock_irqsave(&free_entries_lock, flags); | ||
| 347 | |||
| 348 | list_splice(&tmp, &free_entries); | ||
| 349 | nr_total_entries += i; | ||
| 350 | num_free_entries += i; | ||
| 351 | } else { | ||
| 352 | delta = nr_total_entries - num_entries; | ||
| 353 | |||
| 354 | for (i = 0; i < delta && !list_empty(&free_entries); i++) { | ||
| 355 | entry = __dma_entry_alloc(); | ||
| 356 | kfree(entry); | ||
| 357 | } | ||
| 358 | |||
| 359 | nr_total_entries -= i; | ||
| 360 | } | ||
| 361 | |||
| 362 | if (nr_total_entries != num_entries) | ||
| 363 | ret = 1; | ||
| 364 | |||
| 365 | spin_unlock_irqrestore(&free_entries_lock, flags); | ||
| 366 | |||
| 367 | return ret; | ||
| 368 | } | ||
| 369 | EXPORT_SYMBOL(dma_debug_resize_entries); | ||
| 370 | |||
| 313 | /* | 371 | /* |
| 314 | * DMA-API debugging init code | 372 | * DMA-API debugging init code |
| 315 | * | 373 | * |
| @@ -439,6 +497,8 @@ void dma_debug_init(u32 num_entries) | |||
| 439 | return; | 497 | return; |
| 440 | } | 498 | } |
| 441 | 499 | ||
| 500 | nr_total_entries = num_free_entries; | ||
| 501 | |||
| 442 | printk(KERN_INFO "DMA-API: debugging enabled by kernel config\n"); | 502 | printk(KERN_INFO "DMA-API: debugging enabled by kernel config\n"); |
| 443 | } | 503 | } |
| 444 | 504 | ||
diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 2b0b5a7d2ced..bffe6d7ef9d9 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c | |||
| @@ -60,8 +60,8 @@ enum dma_sync_target { | |||
| 60 | int swiotlb_force; | 60 | int swiotlb_force; |
| 61 | 61 | ||
| 62 | /* | 62 | /* |
| 63 | * Used to do a quick range check in swiotlb_unmap_single and | 63 | * Used to do a quick range check in unmap_single and |
| 64 | * swiotlb_sync_single_*, to see if the memory was in fact allocated by this | 64 | * sync_single_*, to see if the memory was in fact allocated by this |
| 65 | * API. | 65 | * API. |
| 66 | */ | 66 | */ |
| 67 | static char *io_tlb_start, *io_tlb_end; | 67 | static char *io_tlb_start, *io_tlb_end; |
| @@ -129,7 +129,7 @@ dma_addr_t __weak swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr) | |||
| 129 | return paddr; | 129 | return paddr; |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | phys_addr_t __weak swiotlb_bus_to_phys(dma_addr_t baddr) | 132 | phys_addr_t __weak swiotlb_bus_to_phys(struct device *hwdev, dma_addr_t baddr) |
| 133 | { | 133 | { |
| 134 | return baddr; | 134 | return baddr; |
| 135 | } | 135 | } |
| @@ -140,9 +140,15 @@ static dma_addr_t swiotlb_virt_to_bus(struct device *hwdev, | |||
| 140 | return swiotlb_phys_to_bus(hwdev, virt_to_phys(address)); | 140 | return swiotlb_phys_to_bus(hwdev, virt_to_phys(address)); |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | static void *swiotlb_bus_to_virt(dma_addr_t address) | 143 | void * __weak swiotlb_bus_to_virt(struct device *hwdev, dma_addr_t address) |
| 144 | { | 144 | { |
| 145 | return phys_to_virt(swiotlb_bus_to_phys(address)); | 145 | return phys_to_virt(swiotlb_bus_to_phys(hwdev, address)); |
| 146 | } | ||
| 147 | |||
| 148 | int __weak swiotlb_arch_address_needs_mapping(struct device *hwdev, | ||
| 149 | dma_addr_t addr, size_t size) | ||
| 150 | { | ||
| 151 | return !is_buffer_dma_capable(dma_get_mask(hwdev), addr, size); | ||
| 146 | } | 152 | } |
| 147 | 153 | ||
| 148 | int __weak swiotlb_arch_range_needs_mapping(phys_addr_t paddr, size_t size) | 154 | int __weak swiotlb_arch_range_needs_mapping(phys_addr_t paddr, size_t size) |
| @@ -309,10 +315,10 @@ cleanup1: | |||
| 309 | return -ENOMEM; | 315 | return -ENOMEM; |
| 310 | } | 316 | } |
| 311 | 317 | ||
| 312 | static int | 318 | static inline int |
| 313 | address_needs_mapping(struct device *hwdev, dma_addr_t addr, size_t size) | 319 | address_needs_mapping(struct device *hwdev, dma_addr_t addr, size_t size) |
| 314 | { | 320 | { |
| 315 | return !is_buffer_dma_capable(dma_get_mask(hwdev), addr, size); | 321 | return swiotlb_arch_address_needs_mapping(hwdev, addr, size); |
| 316 | } | 322 | } |
| 317 | 323 | ||
| 318 | static inline int range_needs_mapping(phys_addr_t paddr, size_t size) | 324 | static inline int range_needs_mapping(phys_addr_t paddr, size_t size) |
| @@ -341,7 +347,7 @@ static void swiotlb_bounce(phys_addr_t phys, char *dma_addr, size_t size, | |||
| 341 | unsigned long flags; | 347 | unsigned long flags; |
| 342 | 348 | ||
| 343 | while (size) { | 349 | while (size) { |
| 344 | sz = min(PAGE_SIZE - offset, size); | 350 | sz = min_t(size_t, PAGE_SIZE - offset, size); |
| 345 | 351 | ||
| 346 | local_irq_save(flags); | 352 | local_irq_save(flags); |
| 347 | buffer = kmap_atomic(pfn_to_page(pfn), | 353 | buffer = kmap_atomic(pfn_to_page(pfn), |
| @@ -476,7 +482,7 @@ found: | |||
| 476 | * dma_addr is the kernel virtual address of the bounce buffer to unmap. | 482 | * dma_addr is the kernel virtual address of the bounce buffer to unmap. |
| 477 | */ | 483 | */ |
| 478 | static void | 484 | static void |
| 479 | unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir) | 485 | do_unmap_single(struct device *hwdev, char *dma_addr, size_t size, int dir) |
| 480 | { | 486 | { |
| 481 | unsigned long flags; | 487 | unsigned long flags; |
| 482 | int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; | 488 | int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT; |
| @@ -560,7 +566,6 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, | |||
| 560 | size)) { | 566 | size)) { |
| 561 | /* | 567 | /* |
| 562 | * The allocated memory isn't reachable by the device. | 568 | * The allocated memory isn't reachable by the device. |
| 563 | * Fall back on swiotlb_map_single(). | ||
| 564 | */ | 569 | */ |
| 565 | free_pages((unsigned long) ret, order); | 570 | free_pages((unsigned long) ret, order); |
| 566 | ret = NULL; | 571 | ret = NULL; |
| @@ -568,9 +573,8 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, | |||
| 568 | if (!ret) { | 573 | if (!ret) { |
| 569 | /* | 574 | /* |
| 570 | * We are either out of memory or the device can't DMA | 575 | * We are either out of memory or the device can't DMA |
| 571 | * to GFP_DMA memory; fall back on | 576 | * to GFP_DMA memory; fall back on map_single(), which |
| 572 | * swiotlb_map_single(), which will grab memory from | 577 | * will grab memory from the lowest available address range. |
| 573 | * the lowest available address range. | ||
| 574 | */ | 578 | */ |
| 575 | ret = map_single(hwdev, 0, size, DMA_FROM_DEVICE); | 579 | ret = map_single(hwdev, 0, size, DMA_FROM_DEVICE); |
| 576 | if (!ret) | 580 | if (!ret) |
| @@ -587,7 +591,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size, | |||
| 587 | (unsigned long long)dev_addr); | 591 | (unsigned long long)dev_addr); |
| 588 | 592 | ||
| 589 | /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ | 593 | /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ |
| 590 | unmap_single(hwdev, ret, size, DMA_TO_DEVICE); | 594 | do_unmap_single(hwdev, ret, size, DMA_TO_DEVICE); |
| 591 | return NULL; | 595 | return NULL; |
| 592 | } | 596 | } |
| 593 | *dma_handle = dev_addr; | 597 | *dma_handle = dev_addr; |
| @@ -604,7 +608,7 @@ swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, | |||
| 604 | free_pages((unsigned long) vaddr, get_order(size)); | 608 | free_pages((unsigned long) vaddr, get_order(size)); |
| 605 | else | 609 | else |
| 606 | /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ | 610 | /* DMA_TO_DEVICE to avoid memcpy in unmap_single */ |
| 607 | unmap_single(hwdev, vaddr, size, DMA_TO_DEVICE); | 611 | do_unmap_single(hwdev, vaddr, size, DMA_TO_DEVICE); |
| 608 | } | 612 | } |
| 609 | EXPORT_SYMBOL(swiotlb_free_coherent); | 613 | EXPORT_SYMBOL(swiotlb_free_coherent); |
| 610 | 614 | ||
| @@ -634,7 +638,7 @@ swiotlb_full(struct device *dev, size_t size, int dir, int do_panic) | |||
| 634 | * physical address to use is returned. | 638 | * physical address to use is returned. |
| 635 | * | 639 | * |
| 636 | * Once the device is given the dma address, the device owns this memory until | 640 | * Once the device is given the dma address, the device owns this memory until |
| 637 | * either swiotlb_unmap_single or swiotlb_dma_sync_single is performed. | 641 | * either swiotlb_unmap_page or swiotlb_dma_sync_single is performed. |
| 638 | */ | 642 | */ |
| 639 | dma_addr_t swiotlb_map_page(struct device *dev, struct page *page, | 643 | dma_addr_t swiotlb_map_page(struct device *dev, struct page *page, |
| 640 | unsigned long offset, size_t size, | 644 | unsigned long offset, size_t size, |
| @@ -642,18 +646,17 @@ dma_addr_t swiotlb_map_page(struct device *dev, struct page *page, | |||
| 642 | struct dma_attrs *attrs) | 646 | struct dma_attrs *attrs) |
| 643 | { | 647 | { |
| 644 | phys_addr_t phys = page_to_phys(page) + offset; | 648 | phys_addr_t phys = page_to_phys(page) + offset; |
| 645 | void *ptr = page_address(page) + offset; | ||
| 646 | dma_addr_t dev_addr = swiotlb_phys_to_bus(dev, phys); | 649 | dma_addr_t dev_addr = swiotlb_phys_to_bus(dev, phys); |
| 647 | void *map; | 650 | void *map; |
| 648 | 651 | ||
| 649 | BUG_ON(dir == DMA_NONE); | 652 | BUG_ON(dir == DMA_NONE); |
| 650 | /* | 653 | /* |
| 651 | * If the pointer passed in happens to be in the device's DMA window, | 654 | * If the address happens to be in the device's DMA window, |
| 652 | * we can safely return the device addr and not worry about bounce | 655 | * we can safely return the device addr and not worry about bounce |
| 653 | * buffering it. | 656 | * buffering it. |
| 654 | */ | 657 | */ |
| 655 | if (!address_needs_mapping(dev, dev_addr, size) && | 658 | if (!address_needs_mapping(dev, dev_addr, size) && |
| 656 | !range_needs_mapping(virt_to_phys(ptr), size)) | 659 | !range_needs_mapping(phys, size)) |
| 657 | return dev_addr; | 660 | return dev_addr; |
| 658 | 661 | ||
| 659 | /* | 662 | /* |
| @@ -679,23 +682,35 @@ EXPORT_SYMBOL_GPL(swiotlb_map_page); | |||
| 679 | 682 | ||
| 680 | /* | 683 | /* |
| 681 | * Unmap a single streaming mode DMA translation. The dma_addr and size must | 684 | * Unmap a single streaming mode DMA translation. The dma_addr and size must |
| 682 | * match what was provided for in a previous swiotlb_map_single call. All | 685 | * match what was provided for in a previous swiotlb_map_page call. All |
| 683 | * other usages are undefined. | 686 | * other usages are undefined. |
| 684 | * | 687 | * |
| 685 | * After this call, reads by the cpu to the buffer are guaranteed to see | 688 | * After this call, reads by the cpu to the buffer are guaranteed to see |
| 686 | * whatever the device wrote there. | 689 | * whatever the device wrote there. |
| 687 | */ | 690 | */ |
| 691 | static void unmap_single(struct device *hwdev, dma_addr_t dev_addr, | ||
| 692 | size_t size, int dir) | ||
| 693 | { | ||
| 694 | char *dma_addr = swiotlb_bus_to_virt(hwdev, dev_addr); | ||
| 695 | |||
| 696 | BUG_ON(dir == DMA_NONE); | ||
| 697 | |||
| 698 | if (is_swiotlb_buffer(dma_addr)) { | ||
| 699 | do_unmap_single(hwdev, dma_addr, size, dir); | ||
| 700 | return; | ||
| 701 | } | ||
| 702 | |||
| 703 | if (dir != DMA_FROM_DEVICE) | ||
| 704 | return; | ||
| 705 | |||
| 706 | dma_mark_clean(dma_addr, size); | ||
| 707 | } | ||
| 708 | |||
| 688 | void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr, | 709 | void swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr, |
| 689 | size_t size, enum dma_data_direction dir, | 710 | size_t size, enum dma_data_direction dir, |
| 690 | struct dma_attrs *attrs) | 711 | struct dma_attrs *attrs) |
| 691 | { | 712 | { |
| 692 | char *dma_addr = swiotlb_bus_to_virt(dev_addr); | 713 | unmap_single(hwdev, dev_addr, size, dir); |
| 693 | |||
| 694 | BUG_ON(dir == DMA_NONE); | ||
| 695 | if (is_swiotlb_buffer(dma_addr)) | ||
| 696 | unmap_single(hwdev, dma_addr, size, dir); | ||
| 697 | else if (dir == DMA_FROM_DEVICE) | ||
| 698 | dma_mark_clean(dma_addr, size); | ||
| 699 | } | 714 | } |
| 700 | EXPORT_SYMBOL_GPL(swiotlb_unmap_page); | 715 | EXPORT_SYMBOL_GPL(swiotlb_unmap_page); |
| 701 | 716 | ||
| @@ -703,7 +718,7 @@ EXPORT_SYMBOL_GPL(swiotlb_unmap_page); | |||
| 703 | * Make physical memory consistent for a single streaming mode DMA translation | 718 | * Make physical memory consistent for a single streaming mode DMA translation |
| 704 | * after a transfer. | 719 | * after a transfer. |
| 705 | * | 720 | * |
| 706 | * If you perform a swiotlb_map_single() but wish to interrogate the buffer | 721 | * If you perform a swiotlb_map_page() but wish to interrogate the buffer |
| 707 | * using the cpu, yet do not wish to teardown the dma mapping, you must | 722 | * using the cpu, yet do not wish to teardown the dma mapping, you must |
| 708 | * call this function before doing so. At the next point you give the dma | 723 | * call this function before doing so. At the next point you give the dma |
| 709 | * address back to the card, you must first perform a | 724 | * address back to the card, you must first perform a |
| @@ -713,13 +728,19 @@ static void | |||
| 713 | swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr, | 728 | swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr, |
| 714 | size_t size, int dir, int target) | 729 | size_t size, int dir, int target) |
| 715 | { | 730 | { |
| 716 | char *dma_addr = swiotlb_bus_to_virt(dev_addr); | 731 | char *dma_addr = swiotlb_bus_to_virt(hwdev, dev_addr); |
| 717 | 732 | ||
| 718 | BUG_ON(dir == DMA_NONE); | 733 | BUG_ON(dir == DMA_NONE); |
| 719 | if (is_swiotlb_buffer(dma_addr)) | 734 | |
| 735 | if (is_swiotlb_buffer(dma_addr)) { | ||
| 720 | sync_single(hwdev, dma_addr, size, dir, target); | 736 | sync_single(hwdev, dma_addr, size, dir, target); |
| 721 | else if (dir == DMA_FROM_DEVICE) | 737 | return; |
| 722 | dma_mark_clean(dma_addr, size); | 738 | } |
| 739 | |||
| 740 | if (dir != DMA_FROM_DEVICE) | ||
| 741 | return; | ||
| 742 | |||
| 743 | dma_mark_clean(dma_addr, size); | ||
| 723 | } | 744 | } |
| 724 | 745 | ||
| 725 | void | 746 | void |
| @@ -746,13 +767,7 @@ swiotlb_sync_single_range(struct device *hwdev, dma_addr_t dev_addr, | |||
| 746 | unsigned long offset, size_t size, | 767 | unsigned long offset, size_t size, |
| 747 | int dir, int target) | 768 | int dir, int target) |
| 748 | { | 769 | { |
| 749 | char *dma_addr = swiotlb_bus_to_virt(dev_addr) + offset; | 770 | swiotlb_sync_single(hwdev, dev_addr + offset, size, dir, target); |
| 750 | |||
| 751 | BUG_ON(dir == DMA_NONE); | ||
| 752 | if (is_swiotlb_buffer(dma_addr)) | ||
| 753 | sync_single(hwdev, dma_addr, size, dir, target); | ||
| 754 | else if (dir == DMA_FROM_DEVICE) | ||
| 755 | dma_mark_clean(dma_addr, size); | ||
| 756 | } | 771 | } |
| 757 | 772 | ||
| 758 | void | 773 | void |
| @@ -777,7 +792,7 @@ EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_device); | |||
| 777 | 792 | ||
| 778 | /* | 793 | /* |
| 779 | * Map a set of buffers described by scatterlist in streaming mode for DMA. | 794 | * Map a set of buffers described by scatterlist in streaming mode for DMA. |
| 780 | * This is the scatter-gather version of the above swiotlb_map_single | 795 | * This is the scatter-gather version of the above swiotlb_map_page |
| 781 | * interface. Here the scatter gather list elements are each tagged with the | 796 | * interface. Here the scatter gather list elements are each tagged with the |
| 782 | * appropriate dma address and length. They are obtained via | 797 | * appropriate dma address and length. They are obtained via |
| 783 | * sg_dma_{address,length}(SG). | 798 | * sg_dma_{address,length}(SG). |
| @@ -788,7 +803,7 @@ EXPORT_SYMBOL_GPL(swiotlb_sync_single_range_for_device); | |||
| 788 | * The routine returns the number of addr/length pairs actually | 803 | * The routine returns the number of addr/length pairs actually |
| 789 | * used, at most nents. | 804 | * used, at most nents. |
| 790 | * | 805 | * |
| 791 | * Device ownership issues as mentioned above for swiotlb_map_single are the | 806 | * Device ownership issues as mentioned above for swiotlb_map_page are the |
| 792 | * same here. | 807 | * same here. |
| 793 | */ | 808 | */ |
| 794 | int | 809 | int |
| @@ -836,7 +851,7 @@ EXPORT_SYMBOL(swiotlb_map_sg); | |||
| 836 | 851 | ||
| 837 | /* | 852 | /* |
| 838 | * Unmap a set of streaming mode DMA translations. Again, cpu read rules | 853 | * Unmap a set of streaming mode DMA translations. Again, cpu read rules |
| 839 | * concerning calls here are the same as for swiotlb_unmap_single() above. | 854 | * concerning calls here are the same as for swiotlb_unmap_page() above. |
| 840 | */ | 855 | */ |
| 841 | void | 856 | void |
| 842 | swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl, | 857 | swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl, |
| @@ -847,13 +862,9 @@ swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl, | |||
| 847 | 862 | ||
| 848 | BUG_ON(dir == DMA_NONE); | 863 | BUG_ON(dir == DMA_NONE); |
| 849 | 864 | ||
| 850 | for_each_sg(sgl, sg, nelems, i) { | 865 | for_each_sg(sgl, sg, nelems, i) |
| 851 | if (sg->dma_address != swiotlb_phys_to_bus(hwdev, sg_phys(sg))) | 866 | unmap_single(hwdev, sg->dma_address, sg->dma_length, dir); |
| 852 | unmap_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), | 867 | |
| 853 | sg->dma_length, dir); | ||
| 854 | else if (dir == DMA_FROM_DEVICE) | ||
| 855 | dma_mark_clean(swiotlb_bus_to_virt(sg->dma_address), sg->dma_length); | ||
| 856 | } | ||
| 857 | } | 868 | } |
| 858 | EXPORT_SYMBOL(swiotlb_unmap_sg_attrs); | 869 | EXPORT_SYMBOL(swiotlb_unmap_sg_attrs); |
| 859 | 870 | ||
| @@ -879,15 +890,9 @@ swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sgl, | |||
| 879 | struct scatterlist *sg; | 890 | struct scatterlist *sg; |
| 880 | int i; | 891 | int i; |
| 881 | 892 | ||
| 882 | BUG_ON(dir == DMA_NONE); | 893 | for_each_sg(sgl, sg, nelems, i) |
| 883 | 894 | swiotlb_sync_single(hwdev, sg->dma_address, | |
| 884 | for_each_sg(sgl, sg, nelems, i) { | ||
| 885 | if (sg->dma_address != swiotlb_phys_to_bus(hwdev, sg_phys(sg))) | ||
| 886 | sync_single(hwdev, swiotlb_bus_to_virt(sg->dma_address), | ||
| 887 | sg->dma_length, dir, target); | 895 | sg->dma_length, dir, target); |
| 888 | else if (dir == DMA_FROM_DEVICE) | ||
| 889 | dma_mark_clean(swiotlb_bus_to_virt(sg->dma_address), sg->dma_length); | ||
| 890 | } | ||
| 891 | } | 896 | } |
| 892 | 897 | ||
| 893 | void | 898 | void |
