All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] parisc: fix bugs in pa_memcpy
@ 2017-04-14 18:15 Mikulas Patocka
  2017-04-15 15:26 ` Helge Deller
  0 siblings, 1 reply; 2+ messages in thread
From: Mikulas Patocka @ 2017-04-14 18:15 UTC (permalink / raw)
  To: Helge Deller; +Cc: Al Viro, John David Anglin, linux-parisc

The patch 554bfeceb8a22d448cd986fc9efce25e833278a1 ("parisc: Fix access
fault handling in pa_memcpy()") reimplements the pa_memcpy function.
Unfortunatelly, it makes the kernel unbootable. The crash happens in the
function ide_complete_cmd where memcpy is called with the same source and
destination address.

This patch fixes a few bugs in pa_memcpy:

* When jumping to .Lcopy_loop_16 for the first time, don't skip the
  instruction "ldi 31,t0" (this bug made the kernel unbootable)
* Use the COND macro when comparing length, so that the comparison is
  64-bit (a theoretical issue, in case the length is greater than
  0xffffffff)
* Don't use the COND macro after the "extru" instruction (the PA-RISC
  specification says that the upper 32-bits of extru result are undefined,
  although they are set to zero in practice)
* Fix exception addresses in .Lcopy16_fault and .Lcopy8_fault
* Rename .Lcopy_loop_4 to .Lcopy_loop_8 (so that it is consistent with
  .Lcopy8_fault)

Cc: <stable@vger.kernel.org> # v4.9+
Fixes: 554bfeceb8a2 ("parisc: Fix access fault handling in pa_memcpy()")
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>

---
 arch/parisc/lib/lusercopy.S |   27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

Index: linux-4.11-rc6/arch/parisc/lib/lusercopy.S
===================================================================
--- linux-4.11-rc6.orig/arch/parisc/lib/lusercopy.S
+++ linux-4.11-rc6/arch/parisc/lib/lusercopy.S
@@ -201,7 +201,7 @@ ENTRY_CFI(pa_memcpy)
 	add	dst,len,end
 
 	/* short copy with less than 16 bytes? */
-	cmpib,>>=,n 15,len,.Lbyte_loop
+	cmpib,COND(>>=),n 15,len,.Lbyte_loop
 
 	/* same alignment? */
 	xor	src,dst,t0
@@ -216,7 +216,7 @@ ENTRY_CFI(pa_memcpy)
 	/* loop until we are 64-bit aligned */
 .Lalign_loop64:
 	extru	dst,31,3,t1
-	cmpib,=,n	0,t1,.Lcopy_loop_16
+	cmpib,=,n	0,t1,.Lcopy_loop_16_start
 20:	ldb,ma	1(srcspc,src),t1
 21:	stb,ma	t1,1(dstspc,dst)
 	b	.Lalign_loop64
@@ -225,6 +225,7 @@ ENTRY_CFI(pa_memcpy)
 	ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done)
 	ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done)
 
+.Lcopy_loop_16_start:
 	ldi	31,t0
 .Lcopy_loop_16:
 	cmpb,COND(>>=),n t0,len,.Lword_loop
@@ -267,7 +268,7 @@ ENTRY_CFI(pa_memcpy)
 	/* loop until we are 32-bit aligned */
 .Lalign_loop32:
 	extru	dst,31,2,t1
-	cmpib,=,n	0,t1,.Lcopy_loop_4
+	cmpib,=,n	0,t1,.Lcopy_loop_8
 20:	ldb,ma	1(srcspc,src),t1
 21:	stb,ma	t1,1(dstspc,dst)
 	b	.Lalign_loop32
@@ -277,7 +278,7 @@ ENTRY_CFI(pa_memcpy)
 	ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done)
 
 
-.Lcopy_loop_4:
+.Lcopy_loop_8:
 	cmpib,COND(>>=),n 15,len,.Lbyte_loop
 
 10:	ldw	0(srcspc,src),t1
@@ -299,7 +300,7 @@ ENTRY_CFI(pa_memcpy)
 	ASM_EXCEPTIONTABLE_ENTRY(16b,.Lcopy_done)
 	ASM_EXCEPTIONTABLE_ENTRY(17b,.Lcopy_done)
 
-	b	.Lcopy_loop_4
+	b	.Lcopy_loop_8
 	ldo	-16(len),len
 
 .Lbyte_loop:
@@ -324,7 +325,7 @@ ENTRY_CFI(pa_memcpy)
 .Lunaligned_copy:
 	/* align until dst is 32bit-word-aligned */
 	extru	dst,31,2,t1
-	cmpib,COND(=),n	0,t1,.Lcopy_dstaligned
+	cmpib,=,n	0,t1,.Lcopy_dstaligned
 20:	ldb	0(srcspc,src),t1
 	ldo	1(src),src
 21:	stb,ma	t1,1(dstspc,dst)
@@ -362,7 +363,7 @@ ENTRY_CFI(pa_memcpy)
 	cmpiclr,<> 1,t0,%r0
 	b,n .Lcase1
 .Lcase0:
-	cmpb,= %r0,len,.Lcda_finish
+	cmpb,COND(=) %r0,len,.Lcda_finish
 	nop
 
 1:	ldw,ma 4(srcspc,src), a3
@@ -376,7 +377,7 @@ ENTRY_CFI(pa_memcpy)
 1:	ldw,ma 4(srcspc,src), a3
 	ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
 	ldo -1(len),len
-	cmpb,=,n %r0,len,.Ldo0
+	cmpb,COND(=),n %r0,len,.Ldo0
 .Ldo4:
 1:	ldw,ma 4(srcspc,src), a0
 	ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
@@ -402,7 +403,7 @@ ENTRY_CFI(pa_memcpy)
 1:	stw,ma t0, 4(dstspc,dst)
 	ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done)
 	ldo -4(len),len
-	cmpb,<> %r0,len,.Ldo4
+	cmpb,COND(<>) %r0,len,.Ldo4
 	nop
 .Ldo0:
 	shrpw a2, a3, %sar, t0
@@ -436,14 +437,14 @@ ENTRY_CFI(pa_memcpy)
 	/* fault exception fixup handlers: */
 #ifdef CONFIG_64BIT
 .Lcopy16_fault:
-10:	b	.Lcopy_done
-	std,ma	t1,8(dstspc,dst)
+	b	.Lcopy_done
+10:	std,ma	t1,8(dstspc,dst)
 	ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done)
 #endif
 
 .Lcopy8_fault:
-10:	b	.Lcopy_done
-	stw,ma	t1,4(dstspc,dst)
+	b	.Lcopy_done
+10:	stw,ma	t1,4(dstspc,dst)
 	ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done)
 
 	.exit

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

* Re: [PATCH] parisc: fix bugs in pa_memcpy
  2017-04-14 18:15 [PATCH] parisc: fix bugs in pa_memcpy Mikulas Patocka
@ 2017-04-15 15:26 ` Helge Deller
  0 siblings, 0 replies; 2+ messages in thread
From: Helge Deller @ 2017-04-15 15:26 UTC (permalink / raw)
  To: Mikulas Patocka; +Cc: Al Viro, John David Anglin, linux-parisc

On 14.04.2017 20:15, Mikulas Patocka wrote:
> The patch 554bfeceb8a22d448cd986fc9efce25e833278a1 ("parisc: Fix access
> fault handling in pa_memcpy()") reimplements the pa_memcpy function.
> Unfortunatelly, it makes the kernel unbootable. The crash happens in the
> function ide_complete_cmd where memcpy is called with the same source and
> destination address.
> 
> This patch fixes a few bugs in pa_memcpy:
> 
> * When jumping to .Lcopy_loop_16 for the first time, don't skip the
>   instruction "ldi 31,t0" (this bug made the kernel unbootable)
> * Use the COND macro when comparing length, so that the comparison is
>   64-bit (a theoretical issue, in case the length is greater than
>   0xffffffff)
> * Don't use the COND macro after the "extru" instruction (the PA-RISC
>   specification says that the upper 32-bits of extru result are undefined,
>   although they are set to zero in practice)
> * Fix exception addresses in .Lcopy16_fault and .Lcopy8_fault
> * Rename .Lcopy_loop_4 to .Lcopy_loop_8 (so that it is consistent with
>   .Lcopy8_fault)
> 
> Cc: <stable@vger.kernel.org> # v4.9+
> Fixes: 554bfeceb8a2 ("parisc: Fix access fault handling in pa_memcpy()")
> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>

Nice catch!
Thanks,
Helge



> 
> ---
>  arch/parisc/lib/lusercopy.S |   27 ++++++++++++++-------------
>  1 file changed, 14 insertions(+), 13 deletions(-)
> 
> Index: linux-4.11-rc6/arch/parisc/lib/lusercopy.S
> ===================================================================
> --- linux-4.11-rc6.orig/arch/parisc/lib/lusercopy.S
> +++ linux-4.11-rc6/arch/parisc/lib/lusercopy.S
> @@ -201,7 +201,7 @@ ENTRY_CFI(pa_memcpy)
>  	add	dst,len,end
>  
>  	/* short copy with less than 16 bytes? */
> -	cmpib,>>=,n 15,len,.Lbyte_loop
> +	cmpib,COND(>>=),n 15,len,.Lbyte_loop
>  
>  	/* same alignment? */
>  	xor	src,dst,t0
> @@ -216,7 +216,7 @@ ENTRY_CFI(pa_memcpy)
>  	/* loop until we are 64-bit aligned */
>  .Lalign_loop64:
>  	extru	dst,31,3,t1
> -	cmpib,=,n	0,t1,.Lcopy_loop_16
> +	cmpib,=,n	0,t1,.Lcopy_loop_16_start
>  20:	ldb,ma	1(srcspc,src),t1
>  21:	stb,ma	t1,1(dstspc,dst)
>  	b	.Lalign_loop64
> @@ -225,6 +225,7 @@ ENTRY_CFI(pa_memcpy)
>  	ASM_EXCEPTIONTABLE_ENTRY(20b,.Lcopy_done)
>  	ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done)
>  
> +.Lcopy_loop_16_start:
>  	ldi	31,t0
>  .Lcopy_loop_16:
>  	cmpb,COND(>>=),n t0,len,.Lword_loop
> @@ -267,7 +268,7 @@ ENTRY_CFI(pa_memcpy)
>  	/* loop until we are 32-bit aligned */
>  .Lalign_loop32:
>  	extru	dst,31,2,t1
> -	cmpib,=,n	0,t1,.Lcopy_loop_4
> +	cmpib,=,n	0,t1,.Lcopy_loop_8
>  20:	ldb,ma	1(srcspc,src),t1
>  21:	stb,ma	t1,1(dstspc,dst)
>  	b	.Lalign_loop32
> @@ -277,7 +278,7 @@ ENTRY_CFI(pa_memcpy)
>  	ASM_EXCEPTIONTABLE_ENTRY(21b,.Lcopy_done)
>  
>  
> -.Lcopy_loop_4:
> +.Lcopy_loop_8:
>  	cmpib,COND(>>=),n 15,len,.Lbyte_loop
>  
>  10:	ldw	0(srcspc,src),t1
> @@ -299,7 +300,7 @@ ENTRY_CFI(pa_memcpy)
>  	ASM_EXCEPTIONTABLE_ENTRY(16b,.Lcopy_done)
>  	ASM_EXCEPTIONTABLE_ENTRY(17b,.Lcopy_done)
>  
> -	b	.Lcopy_loop_4
> +	b	.Lcopy_loop_8
>  	ldo	-16(len),len
>  
>  .Lbyte_loop:
> @@ -324,7 +325,7 @@ ENTRY_CFI(pa_memcpy)
>  .Lunaligned_copy:
>  	/* align until dst is 32bit-word-aligned */
>  	extru	dst,31,2,t1
> -	cmpib,COND(=),n	0,t1,.Lcopy_dstaligned
> +	cmpib,=,n	0,t1,.Lcopy_dstaligned
>  20:	ldb	0(srcspc,src),t1
>  	ldo	1(src),src
>  21:	stb,ma	t1,1(dstspc,dst)
> @@ -362,7 +363,7 @@ ENTRY_CFI(pa_memcpy)
>  	cmpiclr,<> 1,t0,%r0
>  	b,n .Lcase1
>  .Lcase0:
> -	cmpb,= %r0,len,.Lcda_finish
> +	cmpb,COND(=) %r0,len,.Lcda_finish
>  	nop
>  
>  1:	ldw,ma 4(srcspc,src), a3
> @@ -376,7 +377,7 @@ ENTRY_CFI(pa_memcpy)
>  1:	ldw,ma 4(srcspc,src), a3
>  	ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
>  	ldo -1(len),len
> -	cmpb,=,n %r0,len,.Ldo0
> +	cmpb,COND(=),n %r0,len,.Ldo0
>  .Ldo4:
>  1:	ldw,ma 4(srcspc,src), a0
>  	ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcda_rdfault)
> @@ -402,7 +403,7 @@ ENTRY_CFI(pa_memcpy)
>  1:	stw,ma t0, 4(dstspc,dst)
>  	ASM_EXCEPTIONTABLE_ENTRY(1b,.Lcopy_done)
>  	ldo -4(len),len
> -	cmpb,<> %r0,len,.Ldo4
> +	cmpb,COND(<>) %r0,len,.Ldo4
>  	nop
>  .Ldo0:
>  	shrpw a2, a3, %sar, t0
> @@ -436,14 +437,14 @@ ENTRY_CFI(pa_memcpy)
>  	/* fault exception fixup handlers: */
>  #ifdef CONFIG_64BIT
>  .Lcopy16_fault:
> -10:	b	.Lcopy_done
> -	std,ma	t1,8(dstspc,dst)
> +	b	.Lcopy_done
> +10:	std,ma	t1,8(dstspc,dst)
>  	ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done)
>  #endif
>  
>  .Lcopy8_fault:
> -10:	b	.Lcopy_done
> -	stw,ma	t1,4(dstspc,dst)
> +	b	.Lcopy_done
> +10:	stw,ma	t1,4(dstspc,dst)
>  	ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done)
>  
>  	.exit
> 


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

end of thread, other threads:[~2017-04-15 15:26 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-14 18:15 [PATCH] parisc: fix bugs in pa_memcpy Mikulas Patocka
2017-04-15 15:26 ` Helge Deller

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.