[PARISC] Fix copy_user_page_asm to NOT access past end of page
authorGrant Grundler <grundler@parisc-linux.org>
Sat, 22 Oct 2005 02:55:34 +0000 (22:55 -0400)
committerKyle McMartin <kyle@parisc-linux.org>
Sat, 22 Oct 2005 02:55:34 +0000 (22:55 -0400)
2.6.12-rc2-pa3 fix copy_user_page_asm to NOT access past end of page.

My bad. /o\
Lamont confirmed that instructions following a conditional
branch are *alway* executed regardless if the branch is taken or not.
Unless they are nullified (which was missing in this case).

He also noted:
Conditional branches nullify on forward taken branch, and on
non-taken backward branch. Note that .+4 is a backwards branch.

This makes alot more sense than the giberish in the PA20 arch book.

Compiles and boots on both 64-bit (a500) and 32-bit (j6k).

Signed-off-by: Grant Grundler <grundler@parisc-linux.org>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
arch/parisc/kernel/pacache.S

index 4a7d9c8..e217ae3 100644 (file)
@@ -351,7 +351,11 @@ copy_user_page_asm:
        std             %r22, 120(%r26)
        ldo             128(%r26), %r26
 
-       ADDIB>          -1, %r1, 1b             /* bundle 10 */
+       /* conditional branches nullify on forward taken branch, and on
+        * non-taken backward branch. Note that .+4 is a backwards branch.
+        * The ldd should only get executed if the branch is taken.
+        */
+       ADDIB>,n        -1, %r1, 1b             /* bundle 10 */
        ldd             0(%r25), %r19           /* start next loads */
 
 #else
@@ -363,10 +367,10 @@ copy_user_page_asm:
         * the full 64 bit register values on interrupt, we can't
         * use ldd/std on a 32 bit kernel.
         */
+       ldw             0(%r25), %r19
        ldi             64, %r1         /* PAGE_SIZE/64 == 64 */
 
 1:
-       ldw             0(%r25), %r19
        ldw             4(%r25), %r20
        ldw             8(%r25), %r21
        ldw             12(%r25), %r22
@@ -396,11 +400,12 @@ copy_user_page_asm:
        ldw             60(%r25), %r22
        stw             %r19, 48(%r26)
        stw             %r20, 52(%r26)
+       ldo             64(%r25), %r25
        stw             %r21, 56(%r26)
        stw             %r22, 60(%r26)
        ldo             64(%r26), %r26
-       ADDIB>          -1, %r1, 1b
-       ldo             64(%r25), %r25
+       ADDIB>,n        -1, %r1, 1b
+       ldw             0(%r25), %r19
 #endif
        bv              %r0(%r2)
        nop