diff options
author | Grant Grundler <grundler@parisc-linux.org> | 2005-10-21 22:55:34 -0400 |
---|---|---|
committer | Kyle McMartin <kyle@parisc-linux.org> | 2005-10-21 22:55:34 -0400 |
commit | 37318a3cb1028933417533084ddbf9d84be06878 (patch) | |
tree | 2806c46b71e68f2c5da2cff54adfc0407a5b7cce /arch/parisc/kernel | |
parent | c2709020adb442f7d25f0805af08a3b6cfedd7be (diff) |
[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>
Diffstat (limited to 'arch/parisc/kernel')
-rw-r--r-- | arch/parisc/kernel/pacache.S | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index 4a7d9c8903f4..e217ae369fbb 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S | |||
@@ -351,7 +351,11 @@ copy_user_page_asm: | |||
351 | std %r22, 120(%r26) | 351 | std %r22, 120(%r26) |
352 | ldo 128(%r26), %r26 | 352 | ldo 128(%r26), %r26 |
353 | 353 | ||
354 | ADDIB> -1, %r1, 1b /* bundle 10 */ | 354 | /* conditional branches nullify on forward taken branch, and on |
355 | * non-taken backward branch. Note that .+4 is a backwards branch. | ||
356 | * The ldd should only get executed if the branch is taken. | ||
357 | */ | ||
358 | ADDIB>,n -1, %r1, 1b /* bundle 10 */ | ||
355 | ldd 0(%r25), %r19 /* start next loads */ | 359 | ldd 0(%r25), %r19 /* start next loads */ |
356 | 360 | ||
357 | #else | 361 | #else |
@@ -363,10 +367,10 @@ copy_user_page_asm: | |||
363 | * the full 64 bit register values on interrupt, we can't | 367 | * the full 64 bit register values on interrupt, we can't |
364 | * use ldd/std on a 32 bit kernel. | 368 | * use ldd/std on a 32 bit kernel. |
365 | */ | 369 | */ |
370 | ldw 0(%r25), %r19 | ||
366 | ldi 64, %r1 /* PAGE_SIZE/64 == 64 */ | 371 | ldi 64, %r1 /* PAGE_SIZE/64 == 64 */ |
367 | 372 | ||
368 | 1: | 373 | 1: |
369 | ldw 0(%r25), %r19 | ||
370 | ldw 4(%r25), %r20 | 374 | ldw 4(%r25), %r20 |
371 | ldw 8(%r25), %r21 | 375 | ldw 8(%r25), %r21 |
372 | ldw 12(%r25), %r22 | 376 | ldw 12(%r25), %r22 |
@@ -396,11 +400,12 @@ copy_user_page_asm: | |||
396 | ldw 60(%r25), %r22 | 400 | ldw 60(%r25), %r22 |
397 | stw %r19, 48(%r26) | 401 | stw %r19, 48(%r26) |
398 | stw %r20, 52(%r26) | 402 | stw %r20, 52(%r26) |
403 | ldo 64(%r25), %r25 | ||
399 | stw %r21, 56(%r26) | 404 | stw %r21, 56(%r26) |
400 | stw %r22, 60(%r26) | 405 | stw %r22, 60(%r26) |
401 | ldo 64(%r26), %r26 | 406 | ldo 64(%r26), %r26 |
402 | ADDIB> -1, %r1, 1b | 407 | ADDIB>,n -1, %r1, 1b |
403 | ldo 64(%r25), %r25 | 408 | ldw 0(%r25), %r19 |
404 | #endif | 409 | #endif |
405 | bv %r0(%r2) | 410 | bv %r0(%r2) |
406 | nop | 411 | nop |