aboutsummaryrefslogtreecommitdiff
path: root/arch/parisc/kernel/unaligned.c
diff options
context:
space:
mode:
authorCarlos O'Donell <carlos@parisc-linux.org>2006-04-22 14:47:21 -0600
committerKyle McMartin <kyle@hera.kernel.org>2006-06-27 23:28:33 +0000
commit3fd3a74f45c935f7d6d5c2fb48f06324b18826b7 (patch)
tree552033cbdc4e19b667a25c55e642a172a1ec3b2e /arch/parisc/kernel/unaligned.c
parentc8224e0074f1dce12e95e53ca469f6fe49cc9101 (diff)
[PARISC] Use FIXUP_BRANCH_CLOBBER to asm clobber list
Joel Soete noticed correctly that the fixup's clobbers must be listed as the ASM clobbers. FIXUP_BRANCH in unaligned.c has a new macro which lists all the clobbers in the fixup, we use this throughout the file to simplify the process of listing clobbers in the future. A missing "r1" clobber is added to our uaccess.h for the 64-bit __put_kernel_asm. Interestingly this is a pretty serious bug since gcc generates pretty good use of r1 as a temporary and the uses of __put_kernel_asm are varied and dangerous if r1 is scratched during an invalid write. Signed-off-by: Joel Soete <soete.joel@tiscali.be> Signed-off-by: Carlos O'Donell <carlos@parisc-linux.org> Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Diffstat (limited to 'arch/parisc/kernel/unaligned.c')
-rw-r--r--arch/parisc/kernel/unaligned.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
index de0a1b21cb40..92328fbddb3e 100644
--- a/arch/parisc/kernel/unaligned.c
+++ b/arch/parisc/kernel/unaligned.c
@@ -43,6 +43,8 @@
"\tldil L%%" #lbl ", %%r1\n" \
"\tldo R%%" #lbl "(%%r1), %%r1\n" \
"\tbv,n %%r0(%%r1)\n"
+/* If you use FIXUP_BRANCH, then you must list this clobber */
+#define FIXUP_BRANCH_CLOBBER "r1"
/* 1111 1100 0000 0000 0001 0011 1100 0000 */
#define OPCODE1(a,b,c) ((a)<<26|(b)<<12|(c)<<6)
@@ -157,7 +159,7 @@ static int emulate_ldh(struct pt_regs *regs, int toreg)
" .previous\n"
: "=r" (val), "=r" (ret)
: "0" (val), "r" (saddr), "r" (regs->isr)
- : "r20" );
+ : "r20", FIXUP_BRANCH_CLOBBER );
DPRINTF("val = 0x" RFMT "\n", val);
@@ -202,7 +204,7 @@ static int emulate_ldw(struct pt_regs *regs, int toreg, int flop)
" .previous\n"
: "=r" (val), "=r" (ret)
: "0" (val), "r" (saddr), "r" (regs->isr)
- : "r19", "r20" );
+ : "r19", "r20", FIXUP_BRANCH_CLOBBER );
DPRINTF("val = 0x" RFMT "\n", val);
@@ -253,7 +255,7 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
" .previous\n"
: "=r" (val), "=r" (ret)
: "0" (val), "r" (saddr), "r" (regs->isr)
- : "r19", "r20" );
+ : "r19", "r20", FIXUP_BRANCH_CLOBBER );
#else
{
unsigned long valh=0,vall=0;
@@ -287,7 +289,7 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop)
" .previous\n"
: "=r" (valh), "=r" (vall), "=r" (ret)
: "0" (valh), "1" (vall), "r" (saddr), "r" (regs->isr)
- : "r19", "r20" );
+ : "r19", "r20", FIXUP_BRANCH_CLOBBER );
val=((__u64)valh<<32)|(__u64)vall;
}
#endif
@@ -335,7 +337,7 @@ static int emulate_sth(struct pt_regs *regs, int frreg)
" .previous\n"
: "=r" (ret)
: "r" (val), "r" (regs->ior), "r" (regs->isr)
- : "r19" );
+ : "r19", FIXUP_BRANCH_CLOBBER );
return ret;
}
@@ -389,7 +391,7 @@ static int emulate_stw(struct pt_regs *regs, int frreg, int flop)
" .previous\n"
: "=r" (ret)
: "r" (val), "r" (regs->ior), "r" (regs->isr)
- : "r19", "r20", "r21", "r22", "r1" );
+ : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER );
return 0;
}
@@ -450,7 +452,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
" .previous\n"
: "=r" (ret)
: "r" (val), "r" (regs->ior), "r" (regs->isr)
- : "r19", "r20", "r21", "r22", "r1" );
+ : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER );
#else
{
unsigned long valh=(val>>32),vall=(val&0xffffffffl);
@@ -495,7 +497,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop)
" .previous\n"
: "=r" (ret)
: "r" (valh), "r" (vall), "r" (regs->ior), "r" (regs->isr)
- : "r19", "r20", "r21", "r1" );
+ : "r19", "r20", "r21", "r1", FIXUP_BRANCH_CLOBBER );
}
#endif