All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH][MIPS] fix oops in r4k_dma_cache_inv
@ 2009-01-24 13:15 Yoichi Yuasa
  2009-01-24 19:10 ` Ralf Baechle
  0 siblings, 1 reply; 4+ messages in thread
From: Yoichi Yuasa @ 2009-01-24 13:15 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: yoichi_yuasa, linux-mips

This patch adds alignment for cache operation address in r4k_dma_cache_inv().
The following oops is fixed by it. 

Unhandled kernel unaligned access or invalid instruction[#1]:
Cpu 0
$ 0   : 00000000 9000c400 8f9a9fff 803e0000
$ 4   : 8f9a9000 00001000 00000001 00000002
$ 8   : 00000000 00000000 8f998084 8f986600
$12   : 00000000 00000000 00000008 00000008
$16   : 8f9a9000 8f9a3500 00000000 00000001
$20   : 00000002 803e0000 803d0000 00000000
$24   : 00000000 80240000                  
$28   : 8f81a000 8f81b708 803d0000 8009560c
Hi    : 10623d20
Lo    : 4fdf2cc8
epc   : 80098470 r4k_dma_cache_inv+0x28/0x64
    Not tainted
ra    : 8009560c dma_map_sg+0xf8/0x14c
Status: 9000c402    KERNEL EXL 
Cause : 00800010
BadVA : 8f9a9fff
PrId  : 000028a0 (Nevada)
Modules linked in:
Process swapper (pid: 1, threadinfo=8f81a000, task=8f820000, tls=00000000)
Stack : 8f967424 8f967510 8f9a03ee 8f99e140 8f999300 8f998074 8f998000 00000003
        803e0000 80253a38 8f967424 8f967510 80370000 8024e344 00000000 8f9a3580
        00000008 8f81b770 8f998074 8f99e140 802389fc 8f999458 8f998000 80253a38
        80253db4 80253cbc 800df150 00000000 80257af8 8f9a0360 8f99e140 9000c401
        8f9a0360 8f99e140 8f986600 8f9674a8 802391ac 8f81b844 8f967400 80224788
        ...
Call Trace:
[<80098470>] r4k_dma_cache_inv+0x28/0x64
[<8009560c>] dma_map_sg+0xf8/0x14c
[<8024e344>] ata_qc_issue+0x1ec/0x308
[<80253db4>] ata_scsi_translate+0x134/0x1e8
[<802391ac>] scsi_dispatch_cmd+0x10c/0x270
[<8024028c>] scsi_request_fn+0x28c/0x53c


Signed-off-by: Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>

diff -pruN -X /home/yuasa/Memo/dontdiff linux-orig/arch/mips/mm/c-r4k.c linux/arch/mips/mm/c-r4k.c
--- linux-orig/arch/mips/mm/c-r4k.c	2009-01-15 10:27:30.170434561 +0900
+++ linux/arch/mips/mm/c-r4k.c	2009-01-15 17:06:07.326434524 +0900
@@ -612,6 +612,8 @@ static void r4k_dma_cache_wback_inv(unsi
 
 static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
 {
+	unsigned long lsize = cpu_dcache_line_size();
+
 	/* Catch bad driver code */
 	BUG_ON(size == 0);
 
@@ -620,7 +622,8 @@ static void r4k_dma_cache_inv(unsigned l
 			r4k_blast_scache();
 		else {
 			cache_op(Hit_Writeback_Inv_SD, addr);
-			cache_op(Hit_Writeback_Inv_SD, addr + size - 1);
+			cache_op(Hit_Writeback_Inv_SD,
+				 (addr + size - 1) & ~(lsize - 1));
 			blast_inv_scache_range(addr, addr + size);
 		}
 		return;
@@ -631,7 +634,7 @@ static void r4k_dma_cache_inv(unsigned l
 	} else {
 		R4600_HIT_CACHEOP_WAR_IMPL;
 		cache_op(Hit_Writeback_Inv_D, addr);
-		cache_op(Hit_Writeback_Inv_D, addr + size - 1);
+		cache_op(Hit_Writeback_Inv_D, (addr + size - 1) & ~(lsize - 1));
 		blast_inv_dcache_range(addr, addr + size);
 	}
 

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

* Re: [PATCH][MIPS] fix oops in r4k_dma_cache_inv
  2009-01-24 13:15 [PATCH][MIPS] fix oops in r4k_dma_cache_inv Yoichi Yuasa
@ 2009-01-24 19:10 ` Ralf Baechle
  2009-01-25 12:27   ` Shane McDonald
  2009-01-25 12:30   ` Yoichi Yuasa
  0 siblings, 2 replies; 4+ messages in thread
From: Ralf Baechle @ 2009-01-24 19:10 UTC (permalink / raw)
  To: Yoichi Yuasa; +Cc: linux-mips

On Sat, Jan 24, 2009 at 10:15:42PM +0900, Yoichi Yuasa wrote:

Patch looks ok - but I think we also have to assume that the starting
address of the range might be miss-aligned, so how about this patch?

  Ralf

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 56290a7..c43f4b2 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -619,8 +619,20 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
 		if (size >= scache_size)
 			r4k_blast_scache();
 		else {
-			cache_op(Hit_Writeback_Inv_SD, addr);
-			cache_op(Hit_Writeback_Inv_SD, addr + size - 1);
+			unsigned long lsize = cpu_scache_line_size();
+			unsigned long almask = ~(lsize - 1);
+
+			/*
+			 * There is no clearly documented alignment requirement
+			 * for the cache instruction on MIPS processors and
+			 * some processors, among them the RM5200 and RM7000
+			 * QED processors will throw an address error for cache
+			 * hit ops with insufficient alignment.  Solved by
+			 * aligning the address to cache line size.
+			 */
+			cache_op(Hit_Writeback_Inv_SD, addr & almask);
+			cache_op(Hit_Writeback_Inv_SD,
+				 (addr + size - 1) & almask);
 			blast_inv_scache_range(addr, addr + size);
 		}
 		return;
@@ -629,9 +641,12 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
 	if (cpu_has_safe_index_cacheops && size >= dcache_size) {
 		r4k_blast_dcache();
 	} else {
+		unsigned long lsize = cpu_dcache_line_size();
+		unsigned long almask = ~(lsize - 1);
+
 		R4600_HIT_CACHEOP_WAR_IMPL;
-		cache_op(Hit_Writeback_Inv_D, addr);
-		cache_op(Hit_Writeback_Inv_D, addr + size - 1);
+		cache_op(Hit_Writeback_Inv_D, addr & almask);
+		cache_op(Hit_Writeback_Inv_D, (addr + size - 1)  & almask);
 		blast_inv_dcache_range(addr, addr + size);
 	}
 

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

* Re: [PATCH][MIPS] fix oops in r4k_dma_cache_inv
  2009-01-24 19:10 ` Ralf Baechle
@ 2009-01-25 12:27   ` Shane McDonald
  2009-01-25 12:30   ` Yoichi Yuasa
  1 sibling, 0 replies; 4+ messages in thread
From: Shane McDonald @ 2009-01-25 12:27 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: Yoichi Yuasa, linux-mips

On Sat, Jan 24, 2009 at 1:10 PM, Ralf Baechle <ralf@linux-mips.org> wrote:
> On Sat, Jan 24, 2009 at 10:15:42PM +0900, Yoichi Yuasa wrote:
>
> Patch looks ok - but I think we also have to assume that the starting
> address of the range might be miss-aligned, so how about this patch?
>
>  Ralf
>
> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
>
> diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
> index 56290a7..c43f4b2 100644
> --- a/arch/mips/mm/c-r4k.c
> +++ b/arch/mips/mm/c-r4k.c
> @@ -619,8 +619,20 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
>                if (size >= scache_size)
>                        r4k_blast_scache();
>                else {
> -                       cache_op(Hit_Writeback_Inv_SD, addr);
> -                       cache_op(Hit_Writeback_Inv_SD, addr + size - 1);
> +                       unsigned long lsize = cpu_scache_line_size();
> +                       unsigned long almask = ~(lsize - 1);
> +
> +                       /*
> +                        * There is no clearly documented alignment requirement
> +                        * for the cache instruction on MIPS processors and
> +                        * some processors, among them the RM5200 and RM7000
> +                        * QED processors will throw an address error for cache
> +                        * hit ops with insufficient alignment.  Solved by
> +                        * aligning the address to cache line size.
> +                        */
> +                       cache_op(Hit_Writeback_Inv_SD, addr & almask);
> +                       cache_op(Hit_Writeback_Inv_SD,
> +                                (addr + size - 1) & almask);
>                        blast_inv_scache_range(addr, addr + size);
>                }
>                return;
> @@ -629,9 +641,12 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
>        if (cpu_has_safe_index_cacheops && size >= dcache_size) {
>                r4k_blast_dcache();
>        } else {
> +               unsigned long lsize = cpu_dcache_line_size();
> +               unsigned long almask = ~(lsize - 1);
> +
>                R4600_HIT_CACHEOP_WAR_IMPL;
> -               cache_op(Hit_Writeback_Inv_D, addr);
> -               cache_op(Hit_Writeback_Inv_D, addr + size - 1);
> +               cache_op(Hit_Writeback_Inv_D, addr & almask);
> +               cache_op(Hit_Writeback_Inv_D, (addr + size - 1)  & almask);
>                blast_inv_dcache_range(addr, addr + size);
>        }
>

This patch resolves the oops on my RM7035C-based board.

Tested-by: Shane McDonald <mcdonald.shane@gmail.com>

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

* Re: [PATCH][MIPS] fix oops in r4k_dma_cache_inv
  2009-01-24 19:10 ` Ralf Baechle
  2009-01-25 12:27   ` Shane McDonald
@ 2009-01-25 12:30   ` Yoichi Yuasa
  1 sibling, 0 replies; 4+ messages in thread
From: Yoichi Yuasa @ 2009-01-25 12:30 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: yoichi_yuasa, linux-mips

It's good for me.

Acked-by: Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>

On Sat, 24 Jan 2009 19:10:55 +0000
Ralf Baechle <ralf@linux-mips.org> wrote:

> On Sat, Jan 24, 2009 at 10:15:42PM +0900, Yoichi Yuasa wrote:
> 
> Patch looks ok - but I think we also have to assume that the starting
> address of the range might be miss-aligned, so how about this patch?
> 
>   Ralf
> 
> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
> 
> diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
> index 56290a7..c43f4b2 100644
> --- a/arch/mips/mm/c-r4k.c
> +++ b/arch/mips/mm/c-r4k.c
> @@ -619,8 +619,20 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
>  		if (size >= scache_size)
>  			r4k_blast_scache();
>  		else {
> -			cache_op(Hit_Writeback_Inv_SD, addr);
> -			cache_op(Hit_Writeback_Inv_SD, addr + size - 1);
> +			unsigned long lsize = cpu_scache_line_size();
> +			unsigned long almask = ~(lsize - 1);
> +
> +			/*
> +			 * There is no clearly documented alignment requirement
> +			 * for the cache instruction on MIPS processors and
> +			 * some processors, among them the RM5200 and RM7000
> +			 * QED processors will throw an address error for cache
> +			 * hit ops with insufficient alignment.  Solved by
> +			 * aligning the address to cache line size.
> +			 */
> +			cache_op(Hit_Writeback_Inv_SD, addr & almask);
> +			cache_op(Hit_Writeback_Inv_SD,
> +				 (addr + size - 1) & almask);
>  			blast_inv_scache_range(addr, addr + size);
>  		}
>  		return;
> @@ -629,9 +641,12 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
>  	if (cpu_has_safe_index_cacheops && size >= dcache_size) {
>  		r4k_blast_dcache();
>  	} else {
> +		unsigned long lsize = cpu_dcache_line_size();
> +		unsigned long almask = ~(lsize - 1);
> +
>  		R4600_HIT_CACHEOP_WAR_IMPL;
> -		cache_op(Hit_Writeback_Inv_D, addr);
> -		cache_op(Hit_Writeback_Inv_D, addr + size - 1);
> +		cache_op(Hit_Writeback_Inv_D, addr & almask);
> +		cache_op(Hit_Writeback_Inv_D, (addr + size - 1)  & almask);
>  		blast_inv_dcache_range(addr, addr + size);
>  	}
>  

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

end of thread, other threads:[~2009-01-25 12:31 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-24 13:15 [PATCH][MIPS] fix oops in r4k_dma_cache_inv Yoichi Yuasa
2009-01-24 19:10 ` Ralf Baechle
2009-01-25 12:27   ` Shane McDonald
2009-01-25 12:30   ` Yoichi Yuasa

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.