1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#include <linux/bootmem.h>
37#include <linux/dma-mapping.h>
38#include <xen/swiotlb-xen.h>
39#include <xen/page.h>
40#include <xen/xen-ops.h>
41
42
43
44
45
46
47static char *xen_io_tlb_start, *xen_io_tlb_end;
48static unsigned long xen_io_tlb_nslabs;
49
50
51
52
53u64 start_dma_addr;
54
55static dma_addr_t xen_phys_to_bus(phys_addr_t paddr)
56{
57 return phys_to_machine(XPADDR(paddr)).maddr;;
58}
59
60static phys_addr_t xen_bus_to_phys(dma_addr_t baddr)
61{
62 return machine_to_phys(XMADDR(baddr)).paddr;
63}
64
65static dma_addr_t xen_virt_to_bus(void *address)
66{
67 return xen_phys_to_bus(virt_to_phys(address));
68}
69
70static int check_pages_physically_contiguous(unsigned long pfn,
71 unsigned int offset,
72 size_t length)
73{
74 unsigned long next_mfn;
75 int i;
76 int nr_pages;
77
78 next_mfn = pfn_to_mfn(pfn);
79 nr_pages = (offset + length + PAGE_SIZE-1) >> PAGE_SHIFT;
80
81 for (i = 1; i < nr_pages; i++) {
82 if (pfn_to_mfn(++pfn) != ++next_mfn)
83 return 0;
84 }
85 return 1;
86}
87
88static int range_straddles_page_boundary(phys_addr_t p, size_t size)
89{
90 unsigned long pfn = PFN_DOWN(p);
91 unsigned int offset = p & ~PAGE_MASK;
92
93 if (offset + size <= PAGE_SIZE)
94 return 0;
95 if (check_pages_physically_contiguous(pfn, offset, size))
96 return 0;
97 return 1;
98}
99
100static int is_xen_swiotlb_buffer(dma_addr_t dma_addr)
101{
102 unsigned long mfn = PFN_DOWN(dma_addr);
103 unsigned long pfn = mfn_to_local_pfn(mfn);
104 phys_addr_t paddr;
105
106
107
108
109
110 if (pfn_valid(pfn)) {
111 paddr = PFN_PHYS(pfn);
112 return paddr >= virt_to_phys(xen_io_tlb_start) &&
113 paddr < virt_to_phys(xen_io_tlb_end);
114 }
115 return 0;
116}
117
118static int max_dma_bits = 32;
119
120static int
121xen_swiotlb_fixup(void *buf, size_t size, unsigned long nslabs)
122{
123 int i, rc;
124 int dma_bits;
125
126 dma_bits = get_order(IO_TLB_SEGSIZE << IO_TLB_SHIFT) + PAGE_SHIFT;
127
128 i = 0;
129 do {
130 int slabs = min(nslabs - i, (unsigned long)IO_TLB_SEGSIZE);
131
132 do {
133 rc = xen_create_contiguous_region(
134 (unsigned long)buf + (i << IO_TLB_SHIFT),
135 get_order(slabs << IO_TLB_SHIFT),
136 dma_bits);
137 } while (rc && dma_bits++ < max_dma_bits);
138 if (rc)
139 return rc;
140
141 i += slabs;
142 } while (i < nslabs);
143 return 0;
144}
145
146void __init xen_swiotlb_init(int verbose)
147{
148 unsigned long bytes;
149 int rc;
150
151 xen_io_tlb_nslabs = (64 * 1024 * 1024 >> IO_TLB_SHIFT);
152 xen_io_tlb_nslabs = ALIGN(xen_io_tlb_nslabs, IO_TLB_SEGSIZE);
153
154 bytes = xen_io_tlb_nslabs << IO_TLB_SHIFT;
155
156
157
158
159 xen_io_tlb_start = alloc_bootmem(bytes);
160 if (!xen_io_tlb_start)
161 panic("Cannot allocate SWIOTLB buffer");
162
163 xen_io_tlb_end = xen_io_tlb_start + bytes;
164
165
166
167 rc = xen_swiotlb_fixup(xen_io_tlb_start,
168 bytes,
169 xen_io_tlb_nslabs);
170 if (rc)
171 goto error;
172
173 start_dma_addr = xen_virt_to_bus(xen_io_tlb_start);
174 swiotlb_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs, verbose);
175
176 return;
177error:
178 panic("DMA(%d): Failed to exchange pages allocated for DMA with Xen! "\
179 "We either don't have the permission or you do not have enough"\
180 "free memory under 4GB!\n", rc);
181}
182
183void *
184xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
185 dma_addr_t *dma_handle, gfp_t flags)
186{
187 void *ret;
188 int order = get_order(size);
189 u64 dma_mask = DMA_BIT_MASK(32);
190 unsigned long vstart;
191
192
193
194
195
196
197
198 flags &= ~(__GFP_DMA | __GFP_HIGHMEM);
199
200 if (dma_alloc_from_coherent(hwdev, size, dma_handle, &ret))
201 return ret;
202
203 vstart = __get_free_pages(flags, order);
204 ret = (void *)vstart;
205
206 if (hwdev && hwdev->coherent_dma_mask)
207 dma_mask = dma_alloc_coherent_mask(hwdev, flags);
208
209 if (ret) {
210 if (xen_create_contiguous_region(vstart, order,
211 fls64(dma_mask)) != 0) {
212 free_pages(vstart, order);
213 return NULL;
214 }
215 memset(ret, 0, size);
216 *dma_handle = virt_to_machine(ret).maddr;
217 }
218 return ret;
219}
220EXPORT_SYMBOL_GPL(xen_swiotlb_alloc_coherent);
221
222void
223xen_swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr,
224 dma_addr_t dev_addr)
225{
226 int order = get_order(size);
227
228 if (dma_release_from_coherent(hwdev, order, vaddr))
229 return;
230
231 xen_destroy_contiguous_region((unsigned long)vaddr, order);
232 free_pages((unsigned long)vaddr, order);
233}
234EXPORT_SYMBOL_GPL(xen_swiotlb_free_coherent);
235
236
237
238
239
240
241
242
243
244dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
245 unsigned long offset, size_t size,
246 enum dma_data_direction dir,
247 struct dma_attrs *attrs)
248{
249 phys_addr_t phys = page_to_phys(page) + offset;
250 dma_addr_t dev_addr = xen_phys_to_bus(phys);
251 void *map;
252
253 BUG_ON(dir == DMA_NONE);
254
255
256
257
258
259 if (dma_capable(dev, dev_addr, size) &&
260 !range_straddles_page_boundary(phys, size) && !swiotlb_force)
261 return dev_addr;
262
263
264
265
266 map = swiotlb_tbl_map_single(dev, start_dma_addr, phys, size, dir);
267 if (!map)
268 return DMA_ERROR_CODE;
269
270 dev_addr = xen_virt_to_bus(map);
271
272
273
274
275 if (!dma_capable(dev, dev_addr, size))
276 panic("map_single: bounce buffer is not DMA'ble");
277
278 return dev_addr;
279}
280EXPORT_SYMBOL_GPL(xen_swiotlb_map_page);
281
282
283
284
285
286
287
288
289
290static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
291 size_t size, enum dma_data_direction dir)
292{
293 phys_addr_t paddr = xen_bus_to_phys(dev_addr);
294
295 BUG_ON(dir == DMA_NONE);
296
297
298 if (is_xen_swiotlb_buffer(dev_addr)) {
299 swiotlb_tbl_unmap_single(hwdev, phys_to_virt(paddr), size, dir);
300 return;
301 }
302
303 if (dir != DMA_FROM_DEVICE)
304 return;
305
306
307
308
309
310
311
312 dma_mark_clean(phys_to_virt(paddr), size);
313}
314
315void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
316 size_t size, enum dma_data_direction dir,
317 struct dma_attrs *attrs)
318{
319 xen_unmap_single(hwdev, dev_addr, size, dir);
320}
321EXPORT_SYMBOL_GPL(xen_swiotlb_unmap_page);
322
323
324
325
326
327
328
329
330
331
332
333static void
334xen_swiotlb_sync_single(struct device *hwdev, dma_addr_t dev_addr,
335 size_t size, enum dma_data_direction dir,
336 enum dma_sync_target target)
337{
338 phys_addr_t paddr = xen_bus_to_phys(dev_addr);
339
340 BUG_ON(dir == DMA_NONE);
341
342
343 if (is_xen_swiotlb_buffer(dev_addr)) {
344 swiotlb_tbl_sync_single(hwdev, phys_to_virt(paddr), size, dir,
345 target);
346 return;
347 }
348
349 if (dir != DMA_FROM_DEVICE)
350 return;
351
352 dma_mark_clean(phys_to_virt(paddr), size);
353}
354
355void
356xen_swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr,
357 size_t size, enum dma_data_direction dir)
358{
359 xen_swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_CPU);
360}
361EXPORT_SYMBOL_GPL(xen_swiotlb_sync_single_for_cpu);
362
363void
364xen_swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr,
365 size_t size, enum dma_data_direction dir)
366{
367 xen_swiotlb_sync_single(hwdev, dev_addr, size, dir, SYNC_FOR_DEVICE);
368}
369EXPORT_SYMBOL_GPL(xen_swiotlb_sync_single_for_device);
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387int
388xen_swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
389 int nelems, enum dma_data_direction dir,
390 struct dma_attrs *attrs)
391{
392 struct scatterlist *sg;
393 int i;
394
395 BUG_ON(dir == DMA_NONE);
396
397 for_each_sg(sgl, sg, nelems, i) {
398 phys_addr_t paddr = sg_phys(sg);
399 dma_addr_t dev_addr = xen_phys_to_bus(paddr);
400
401 if (swiotlb_force ||
402 !dma_capable(hwdev, dev_addr, sg->length) ||
403 range_straddles_page_boundary(paddr, sg->length)) {
404 void *map = swiotlb_tbl_map_single(hwdev,
405 start_dma_addr,
406 sg_phys(sg),
407 sg->length, dir);
408 if (!map) {
409
410
411 xen_swiotlb_unmap_sg_attrs(hwdev, sgl, i, dir,
412 attrs);
413 sgl[0].dma_length = 0;
414 return DMA_ERROR_CODE;
415 }
416 sg->dma_address = xen_virt_to_bus(map);
417 } else
418 sg->dma_address = dev_addr;
419 sg->dma_length = sg->length;
420 }
421 return nelems;
422}
423EXPORT_SYMBOL_GPL(xen_swiotlb_map_sg_attrs);
424
425int
426xen_swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
427 enum dma_data_direction dir)
428{
429 return xen_swiotlb_map_sg_attrs(hwdev, sgl, nelems, dir, NULL);
430}
431EXPORT_SYMBOL_GPL(xen_swiotlb_map_sg);
432
433
434
435
436
437void
438xen_swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl,
439 int nelems, enum dma_data_direction dir,
440 struct dma_attrs *attrs)
441{
442 struct scatterlist *sg;
443 int i;
444
445 BUG_ON(dir == DMA_NONE);
446
447 for_each_sg(sgl, sg, nelems, i)
448 xen_unmap_single(hwdev, sg->dma_address, sg->dma_length, dir);
449
450}
451EXPORT_SYMBOL_GPL(xen_swiotlb_unmap_sg_attrs);
452
453void
454xen_swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
455 enum dma_data_direction dir)
456{
457 return xen_swiotlb_unmap_sg_attrs(hwdev, sgl, nelems, dir, NULL);
458}
459EXPORT_SYMBOL_GPL(xen_swiotlb_unmap_sg);
460
461
462
463
464
465
466
467
468static void
469xen_swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sgl,
470 int nelems, enum dma_data_direction dir,
471 enum dma_sync_target target)
472{
473 struct scatterlist *sg;
474 int i;
475
476 for_each_sg(sgl, sg, nelems, i)
477 xen_swiotlb_sync_single(hwdev, sg->dma_address,
478 sg->dma_length, dir, target);
479}
480
481void
482xen_swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
483 int nelems, enum dma_data_direction dir)
484{
485 xen_swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_CPU);
486}
487EXPORT_SYMBOL_GPL(xen_swiotlb_sync_sg_for_cpu);
488
489void
490xen_swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
491 int nelems, enum dma_data_direction dir)
492{
493 xen_swiotlb_sync_sg(hwdev, sg, nelems, dir, SYNC_FOR_DEVICE);
494}
495EXPORT_SYMBOL_GPL(xen_swiotlb_sync_sg_for_device);
496
497int
498xen_swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr)
499{
500 return !dma_addr;
501}
502EXPORT_SYMBOL_GPL(xen_swiotlb_dma_mapping_error);
503
504
505
506
507
508
509
510int
511xen_swiotlb_dma_supported(struct device *hwdev, u64 mask)
512{
513 return xen_virt_to_bus(xen_io_tlb_end - 1) <= mask;
514}
515EXPORT_SYMBOL_GPL(xen_swiotlb_dma_supported);
516