iommu: parisc: make the IOMMUs respect the segment boundary limits
Make PARISC's two IOMMU implementations not allocate a memory area spanning
LLD's segment boundary.
[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Cc: Kyle McMartin <kyle@parisc-linux.org>
Cc: Matthew Wilcox <matthew@wil.cx>
Cc: Grant Grundler <grundler@parisc-linux.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index 1695fac..60d338c 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -43,6 +43,7 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/scatterlist.h>
+#include <linux/iommu-helper.h>
#include <asm/byteorder.h>
#include <asm/cache.h> /* for L1_CACHE_BYTES */
@@ -302,13 +303,17 @@
*/
#define CCIO_SEARCH_LOOP(ioc, res_idx, mask, size) \
for(; res_ptr < res_end; ++res_ptr) { \
- if(0 == (*res_ptr & mask)) { \
- *res_ptr |= mask; \
- res_idx = (unsigned int)((unsigned long)res_ptr - (unsigned long)ioc->res_map); \
- ioc->res_hint = res_idx + (size >> 3); \
- goto resource_found; \
- } \
- }
+ int ret;\
+ unsigned int idx;\
+ idx = (unsigned int)((unsigned long)res_ptr - (unsigned long)ioc->res_map); \
+ ret = iommu_is_span_boundary(idx << 3, pages_needed, 0, boundary_size);\
+ if ((0 == (*res_ptr & mask)) && !ret) { \
+ *res_ptr |= mask; \
+ res_idx = idx;\
+ ioc->res_hint = res_idx + (size >> 3); \
+ goto resource_found; \
+ } \
+ }
#define CCIO_FIND_FREE_MAPPING(ioa, res_idx, mask, size) \
u##size *res_ptr = (u##size *)&((ioc)->res_map[ioa->res_hint & ~((size >> 3) - 1)]); \
@@ -345,6 +350,7 @@
{
unsigned int pages_needed = size >> IOVP_SHIFT;
unsigned int res_idx;
+ unsigned long boundary_size;
#ifdef CCIO_SEARCH_TIME
unsigned long cr_start = mfctl(16);
#endif
@@ -360,6 +366,9 @@
** ggg sacrifices another 710 to the computer gods.
*/
+ boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, 1 << IOVP_SHIFT);
+ boundary_size >>= IOVP_SHIFT;
+
if (pages_needed <= 8) {
/*
* LAN traffic will not thrash the TLB IFF the same NIC