aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Grundler <grundler@parisc-linux.org>2005-10-21 22:55:34 -0400
committerKyle McMartin <kyle@parisc-linux.org>2005-10-21 22:55:34 -0400
commit37318a3cb1028933417533084ddbf9d84be06878 (patch)
tree2806c46b71e68f2c5da2cff54adfc0407a5b7cce
parentc2709020adb442f7d25f0805af08a3b6cfedd7be (diff)
downloadkernel_samsung_smdk4412-37318a3cb1028933417533084ddbf9d84be06878.zip
kernel_samsung_smdk4412-37318a3cb1028933417533084ddbf9d84be06878.tar.gz
kernel_samsung_smdk4412-37318a3cb1028933417533084ddbf9d84be06878.tar.bz2
[PARISC] Fix copy_user_page_asm to NOT access past end of page
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>
-rw-r--r--arch/parisc/kernel/pacache.S13
1 files changed, 9 insertions, 4 deletions
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
index 4a7d9c8..e217ae3 100644
--- a/arch/parisc/kernel/pacache.S
+++ b/arch/parisc/kernel/pacache.S
@@ -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