linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH][POWERPC] Workaround for iommu page alignment
@ 2008-01-07 21:45 Benjamin Herrenschmidt
  2008-01-07 21:57 ` Olof Johansson
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Benjamin Herrenschmidt @ 2008-01-07 21:45 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev list, Linux Kernel list

Our iommu page size is currently always 4K. That means with our current
code, drivers may do a dma_map_sg() of a 64K page and obtain a dma_addr_t
that is only 4K aligned.

This works fine in most cases except some infiniband HW it seems, where
they tell the HW about the page size and it ignores the low bits of the
DMA address.

This works around it by making our IOMMU code enforce a PAGE_SIZE alignment
for mappings of objects that are page aligned in the first place and whose
size is larger or equal to a page.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

Looks like it fell through the holiday cracks ... 

It could still go in 2.6.24 I suppose... If not, put it in 2.6.25 and
we'll backport to stable later.

Index: linux-work/arch/powerpc/kernel/iommu.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/iommu.c	2007-12-21 10:39:39.000000000 +1100
+++ linux-work/arch/powerpc/kernel/iommu.c	2007-12-21 10:46:18.000000000 +1100
@@ -278,6 +278,7 @@ int iommu_map_sg(struct iommu_table *tbl
 	unsigned long flags;
 	struct scatterlist *s, *outs, *segstart;
 	int outcount, incount, i;
+	unsigned int align;
 	unsigned long handle;
 
 	BUG_ON(direction == DMA_NONE);
@@ -309,7 +310,11 @@ int iommu_map_sg(struct iommu_table *tbl
 		/* Allocate iommu entries for that segment */
 		vaddr = (unsigned long) sg_virt(s);
 		npages = iommu_num_pages(vaddr, slen);
-		entry = iommu_range_alloc(tbl, npages, &handle, mask >> IOMMU_PAGE_SHIFT, 0);
+		align = 0;
+		if (IOMMU_PAGE_SHIFT < PAGE_SHIFT && (vaddr & ~PAGE_MASK) == 0)
+			align = PAGE_SHIFT - IOMMU_PAGE_SHIFT;
+		entry = iommu_range_alloc(tbl, npages, &handle,
+					  mask >> IOMMU_PAGE_SHIFT, align);
 
 		DBG("  - vaddr: %lx, size: %lx\n", vaddr, slen);
 
@@ -572,7 +577,7 @@ dma_addr_t iommu_map_single(struct iommu
 {
 	dma_addr_t dma_handle = DMA_ERROR_CODE;
 	unsigned long uaddr;
-	unsigned int npages;
+	unsigned int npages, align;
 
 	BUG_ON(direction == DMA_NONE);
 
@@ -580,8 +585,13 @@ dma_addr_t iommu_map_single(struct iommu
 	npages = iommu_num_pages(uaddr, size);
 
 	if (tbl) {
+		align = 0;
+		if (IOMMU_PAGE_SHIFT < PAGE_SHIFT &&
+		    ((unsigned long)vaddr & ~PAGE_MASK) == 0)
+			align = PAGE_SHIFT - IOMMU_PAGE_SHIFT;
+
 		dma_handle = iommu_alloc(tbl, vaddr, npages, direction,
-					 mask >> IOMMU_PAGE_SHIFT, 0);
+					 mask >> IOMMU_PAGE_SHIFT, align);
 		if (dma_handle == DMA_ERROR_CODE) {
 			if (printk_ratelimit())  {
 				printk(KERN_INFO "iommu_alloc failed, "



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH][POWERPC] Workaround for iommu page alignment
  2008-01-07 21:45 [PATCH][POWERPC] Workaround for iommu page alignment Benjamin Herrenschmidt
@ 2008-01-07 21:57 ` Olof Johansson
  2008-01-07 22:41 ` Michael Ellerman
  2008-01-07 23:34 ` [PATCH][POWERPC] Workaround for iommu page alignment (#2) Benjamin Herrenschmidt
  2 siblings, 0 replies; 7+ messages in thread
From: Olof Johansson @ 2008-01-07 21:57 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Paul Mackerras, linuxppc-dev list, Linux Kernel list

On Tue, Jan 08, 2008 at 08:45:59AM +1100, Benjamin Herrenschmidt wrote:
> Our iommu page size is currently always 4K. That means with our current
> code, drivers may do a dma_map_sg() of a 64K page and obtain a dma_addr_t
> that is only 4K aligned.
> 
> This works fine in most cases except some infiniband HW it seems, where
> they tell the HW about the page size and it ignores the low bits of the
> DMA address.
> 
> This works around it by making our IOMMU code enforce a PAGE_SIZE alignment
> for mappings of objects that are page aligned in the first place and whose
> size is larger or equal to a page.
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

Acked-by: Olof Johansson <olof@lixom.net>


-Olof

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH][POWERPC] Workaround for iommu page alignment
  2008-01-07 21:45 [PATCH][POWERPC] Workaround for iommu page alignment Benjamin Herrenschmidt
  2008-01-07 21:57 ` Olof Johansson
@ 2008-01-07 22:41 ` Michael Ellerman
  2008-01-07 23:33   ` Benjamin Herrenschmidt
  2008-01-07 23:34 ` [PATCH][POWERPC] Workaround for iommu page alignment (#2) Benjamin Herrenschmidt
  2 siblings, 1 reply; 7+ messages in thread
From: Michael Ellerman @ 2008-01-07 22:41 UTC (permalink / raw)
  To: benh; +Cc: Paul Mackerras, linuxppc-dev list, Linux Kernel list

[-- Attachment #1: Type: text/plain, Size: 1040 bytes --]

On Tue, 2008-01-08 at 08:45 +1100, Benjamin Herrenschmidt wrote:
> Our iommu page size is currently always 4K. That means with our current
> code, drivers may do a dma_map_sg() of a 64K page and obtain a dma_addr_t
> that is only 4K aligned.
> 
> This works fine in most cases except some infiniband HW it seems, where
> they tell the HW about the page size and it ignores the low bits of the
> DMA address.
> 
> This works around it by making our IOMMU code enforce a PAGE_SIZE alignment
> for mappings of objects that are page aligned in the first place and whose
> size is larger or equal to a page.
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I don't see in the code where you implement the "size > PAGE_SIZE"
condition. But I only just got back from holidays .. :)

cheers

-- 
Michael Ellerman
OzLabs, IBM Australia Development Lab

wwweb: http://michael.ellerman.id.au
phone: +61 2 6212 1183 (tie line 70 21183)

We do not inherit the earth from our ancestors,
we borrow it from our children. - S.M.A.R.T Person

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH][POWERPC] Workaround for iommu page alignment
  2008-01-07 22:41 ` Michael Ellerman
@ 2008-01-07 23:33   ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 7+ messages in thread
From: Benjamin Herrenschmidt @ 2008-01-07 23:33 UTC (permalink / raw)
  To: michael; +Cc: Paul Mackerras, linuxppc-dev list, Linux Kernel list


> I don't see in the code where you implement the "size > PAGE_SIZE"
> condition. But I only just got back from holidays .. :)

Indeed ... a "quilt ref" was missing :-(

New patch coming ...

Ben.



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH][POWERPC] Workaround for iommu page alignment (#2)
  2008-01-07 21:45 [PATCH][POWERPC] Workaround for iommu page alignment Benjamin Herrenschmidt
  2008-01-07 21:57 ` Olof Johansson
  2008-01-07 22:41 ` Michael Ellerman
@ 2008-01-07 23:34 ` Benjamin Herrenschmidt
  2008-01-08  3:48   ` Olof Johansson
  2 siblings, 1 reply; 7+ messages in thread
From: Benjamin Herrenschmidt @ 2008-01-07 23:34 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev list, Linux Kernel list

powerpc: Workaround for iommu page alignment

Our iommu page size is currently always 4K. That means with our current
code, drivers may do a dma_map_sg() of a 64K page and obtain a dma_addr_t
that is only 4K aligned.

This works fine in most cases except some infiniband HW it seems, where
they tell the HW about the page size and it ignores the low bits of the
DMA address.

This works around it by making our IOMMU code enforce a PAGE_SIZE alignment
for mappings of objects that are page aligned in the first place and whose
size is larger or equal to a page.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---

And this version actually does what the comment says (I had forgotten
to quilt ref... a common mistake).

Index: linux-work/arch/powerpc/kernel/iommu.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/iommu.c	2007-12-21 10:39:39.000000000 +1100
+++ linux-work/arch/powerpc/kernel/iommu.c	2007-12-21 10:48:12.000000000 +1100
@@ -278,6 +278,7 @@ int iommu_map_sg(struct iommu_table *tbl
 	unsigned long flags;
 	struct scatterlist *s, *outs, *segstart;
 	int outcount, incount, i;
+	unsigned int align;
 	unsigned long handle;
 
 	BUG_ON(direction == DMA_NONE);
@@ -309,7 +310,12 @@ int iommu_map_sg(struct iommu_table *tbl
 		/* Allocate iommu entries for that segment */
 		vaddr = (unsigned long) sg_virt(s);
 		npages = iommu_num_pages(vaddr, slen);
-		entry = iommu_range_alloc(tbl, npages, &handle, mask >> IOMMU_PAGE_SHIFT, 0);
+		align = 0;
+		if (IOMMU_PAGE_SHIFT < PAGE_SHIFT && slen >= PAGE_SIZE &&
+		    (vaddr & ~PAGE_MASK) == 0)
+			align = PAGE_SHIFT - IOMMU_PAGE_SHIFT;
+		entry = iommu_range_alloc(tbl, npages, &handle,
+					  mask >> IOMMU_PAGE_SHIFT, align);
 
 		DBG("  - vaddr: %lx, size: %lx\n", vaddr, slen);
 
@@ -572,7 +578,7 @@ dma_addr_t iommu_map_single(struct iommu
 {
 	dma_addr_t dma_handle = DMA_ERROR_CODE;
 	unsigned long uaddr;
-	unsigned int npages;
+	unsigned int npages, align;
 
 	BUG_ON(direction == DMA_NONE);
 
@@ -580,8 +586,13 @@ dma_addr_t iommu_map_single(struct iommu
 	npages = iommu_num_pages(uaddr, size);
 
 	if (tbl) {
+		align = 0;
+		if (IOMMU_PAGE_SHIFT < PAGE_SHIFT && size >= PAGE_SIZE &&
+		    ((unsigned long)vaddr & ~PAGE_MASK) == 0)
+			align = PAGE_SHIFT - IOMMU_PAGE_SHIFT;
+
 		dma_handle = iommu_alloc(tbl, vaddr, npages, direction,
-					 mask >> IOMMU_PAGE_SHIFT, 0);
+					 mask >> IOMMU_PAGE_SHIFT, align);
 		if (dma_handle == DMA_ERROR_CODE) {
 			if (printk_ratelimit())  {
 				printk(KERN_INFO "iommu_alloc failed, "



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH][POWERPC] Workaround for iommu page alignment (#2)
  2008-01-07 23:34 ` [PATCH][POWERPC] Workaround for iommu page alignment (#2) Benjamin Herrenschmidt
@ 2008-01-08  3:48   ` Olof Johansson
  2008-01-08  4:02     ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 7+ messages in thread
From: Olof Johansson @ 2008-01-08  3:48 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Paul Mackerras, linuxppc-dev list, Linux Kernel list

On Tue, Jan 08, 2008 at 10:34:22AM +1100, Benjamin Herrenschmidt wrote:
> powerpc: Workaround for iommu page alignment
> 
> Our iommu page size is currently always 4K. That means with our current
> code, drivers may do a dma_map_sg() of a 64K page and obtain a dma_addr_t
> that is only 4K aligned.
> 
> This works fine in most cases except some infiniband HW it seems, where
> they tell the HW about the page size and it ignores the low bits of the
> DMA address.
> 
> This works around it by making our IOMMU code enforce a PAGE_SIZE alignment
> for mappings of objects that are page aligned in the first place and whose
> size is larger or equal to a page.
> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
> 
> And this version actually does what the comment says (I had forgotten
> to quilt ref... a common mistake).

And sloppy of me to not catch it. Anyway:

Acked-by: Olof Johansson <olof@lixom.net>

I wonder how long until there's a device that has some other < PAGE_SIZE
alignment bug^Wrequirement that we'll need to meet too. :(


-Olof


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH][POWERPC] Workaround for iommu page alignment (#2)
  2008-01-08  3:48   ` Olof Johansson
@ 2008-01-08  4:02     ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 7+ messages in thread
From: Benjamin Herrenschmidt @ 2008-01-08  4:02 UTC (permalink / raw)
  To: Olof Johansson; +Cc: Paul Mackerras, linuxppc-dev list, Linux Kernel list

> And sloppy of me to not catch it. Anyway:
> 
> Acked-by: Olof Johansson <olof@lixom.net>
> 
> I wonder how long until there's a device that has some other < PAGE_SIZE
> alignment bug^Wrequirement that we'll need to meet too. :(

Yeah, it's a worry...

Ben.



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2008-01-08  4:02 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-01-07 21:45 [PATCH][POWERPC] Workaround for iommu page alignment Benjamin Herrenschmidt
2008-01-07 21:57 ` Olof Johansson
2008-01-07 22:41 ` Michael Ellerman
2008-01-07 23:33   ` Benjamin Herrenschmidt
2008-01-07 23:34 ` [PATCH][POWERPC] Workaround for iommu page alignment (#2) Benjamin Herrenschmidt
2008-01-08  3:48   ` Olof Johansson
2008-01-08  4:02     ` Benjamin Herrenschmidt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).