]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
sparc: fix accurate exception reporting in copy_{from_to}_user for Niagara
authorMichael Karcher <kernel@mkarcher.dialup.fu-berlin.de>
Thu, 4 Sep 2025 22:03:32 +0000 (00:03 +0200)
committerAndreas Larsson <andreas@gaisler.com>
Fri, 19 Sep 2025 18:56:36 +0000 (20:56 +0200)
The referenced commit introduced exception handlers on user-space memory
references in copy_from_user and copy_to_user. These handlers return from
the respective function and calculate the remaining bytes left to copy
using the current register contents. This commit fixes a couple of bad
calculations and a broken epilogue in the exception handlers. This will
prevent crashes and ensure correct return values of copy_from_user and
copy_to_user in the faulting case. The behaviour of memcpy stays unchanged.

Fixes: 7ae3aaf53f16 ("sparc64: Convert NGcopy_{from,to}_user to accurate exception reporting.")
Tested-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> # on SPARC T4 with modified kernel to use Niagara 1 code
Tested-by: Magnus Lindholm <linmag7@gmail.com> # on Sun Fire T2000
Signed-off-by: Michael Karcher <kernel@mkarcher.dialup.fu-berlin.de>
Tested-by: Ethan Hawke <ehawk@ember.systems> # on Sun Fire T2000
Tested-by: Ken Link <iissmart@numberzero.org> # on Sun Fire T1000
Reviewed-by: Andreas Larsson <andreas@gaisler.com>
Link: https://lore.kernel.org/r/20250905-memcpy_series-v4-3-1ca72dda195b@mkarcher.dialup.fu-berlin.de
Signed-off-by: Andreas Larsson <andreas@gaisler.com>
arch/sparc/lib/NGmemcpy.S

index ee51c12306894eee4195887d2b28b2619f63c2b1..bbd3ea0a64822c7410278fcc3d101ce9cef96c89 100644 (file)
@@ -79,8 +79,8 @@
 #ifndef EX_RETVAL
 #define EX_RETVAL(x)   x
 __restore_asi:
-       ret
        wr      %g0, ASI_AIUS, %asi
+       ret
         restore
 ENTRY(NG_ret_i2_plus_i4_plus_1)
        ba,pt   %xcc, __restore_asi
@@ -125,15 +125,16 @@ ENTRY(NG_ret_i2_plus_g1_minus_56)
        ba,pt   %xcc, __restore_asi
         add    %i2, %g1, %i0
 ENDPROC(NG_ret_i2_plus_g1_minus_56)
-ENTRY(NG_ret_i2_plus_i4)
+ENTRY(NG_ret_i2_plus_i4_plus_16)
+        add     %i4, 16, %i4
        ba,pt   %xcc, __restore_asi
         add    %i2, %i4, %i0
-ENDPROC(NG_ret_i2_plus_i4)
-ENTRY(NG_ret_i2_plus_i4_minus_8)
-       sub     %i4, 8, %i4
+ENDPROC(NG_ret_i2_plus_i4_plus_16)
+ENTRY(NG_ret_i2_plus_i4_plus_8)
+       add     %i4, 8, %i4
        ba,pt   %xcc, __restore_asi
         add    %i2, %i4, %i0
-ENDPROC(NG_ret_i2_plus_i4_minus_8)
+ENDPROC(NG_ret_i2_plus_i4_plus_8)
 ENTRY(NG_ret_i2_plus_8)
        ba,pt   %xcc, __restore_asi
         add    %i2, 8, %i0
@@ -160,6 +161,12 @@ ENTRY(NG_ret_i2_and_7_plus_i4)
        ba,pt   %xcc, __restore_asi
         add    %i2, %i4, %i0
 ENDPROC(NG_ret_i2_and_7_plus_i4)
+ENTRY(NG_ret_i2_and_7_plus_i4_plus_8)
+       and     %i2, 7, %i2
+       add     %i4, 8, %i4
+       ba,pt   %xcc, __restore_asi
+        add    %i2, %i4, %i0
+ENDPROC(NG_ret_i2_and_7_plus_i4)
 #endif
 
        .align          64
@@ -405,13 +412,13 @@ FUNC_NAME:        /* %i0=dst, %i1=src, %i2=len */
        andn            %i2, 0xf, %i4
        and             %i2, 0xf, %i2
 1:     subcc           %i4, 0x10, %i4
-       EX_LD(LOAD(ldx, %i1, %o4), NG_ret_i2_plus_i4)
+       EX_LD(LOAD(ldx, %i1, %o4), NG_ret_i2_plus_i4_plus_16)
        add             %i1, 0x08, %i1
-       EX_LD(LOAD(ldx, %i1, %g1), NG_ret_i2_plus_i4)
+       EX_LD(LOAD(ldx, %i1, %g1), NG_ret_i2_plus_i4_plus_16)
        sub             %i1, 0x08, %i1
-       EX_ST(STORE(stx, %o4, %i1 + %i3), NG_ret_i2_plus_i4)
+       EX_ST(STORE(stx, %o4, %i1 + %i3), NG_ret_i2_plus_i4_plus_16)
        add             %i1, 0x8, %i1
-       EX_ST(STORE(stx, %g1, %i1 + %i3), NG_ret_i2_plus_i4_minus_8)
+       EX_ST(STORE(stx, %g1, %i1 + %i3), NG_ret_i2_plus_i4_plus_8)
        bgu,pt          %XCC, 1b
         add            %i1, 0x8, %i1
 73:    andcc           %i2, 0x8, %g0
@@ -468,7 +475,7 @@ FUNC_NAME:  /* %i0=dst, %i1=src, %i2=len */
        subcc           %i4, 0x8, %i4
        srlx            %g3, %i3, %i5
        or              %i5, %g2, %i5
-       EX_ST(STORE(stx, %i5, %o0), NG_ret_i2_and_7_plus_i4)
+       EX_ST(STORE(stx, %i5, %o0), NG_ret_i2_and_7_plus_i4_plus_8)
        add             %o0, 0x8, %o0
        bgu,pt          %icc, 1b
         sllx           %g3, %g1, %g2