summaryrefslogtreecommitdiff
path: root/arch/parisc/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/parisc/kernel/signal.c')
-rw-r--r--arch/parisc/kernel/signal.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c
index 9b910a0251b8..1fd300c00a80 100644
--- a/arch/parisc/kernel/signal.c
+++ b/arch/parisc/kernel/signal.c
@@ -476,6 +476,9 @@ insert_restart_trampoline(struct pt_regs *regs)
case -ERESTART_RESTARTBLOCK: {
/* Restart the system call - no handlers present */
unsigned int *usp = (unsigned int *)regs->gr[30];
+ unsigned long start = (unsigned long) &usp[2];
+ unsigned long end = (unsigned long) &usp[5];
+ long err = 0;
/* Setup a trampoline to restart the syscall
* with __NR_restart_syscall
@@ -487,23 +490,21 @@ insert_restart_trampoline(struct pt_regs *regs)
* 16: ldi __NR_restart_syscall, %r20
*/
#ifdef CONFIG_64BIT
- put_user(regs->gr[31] >> 32, &usp[0]);
- put_user(regs->gr[31] & 0xffffffff, &usp[1]);
- put_user(0x0fc010df, &usp[2]);
+ err |= put_user(regs->gr[31] >> 32, &usp[0]);
+ err |= put_user(regs->gr[31] & 0xffffffff, &usp[1]);
+ err |= put_user(0x0fc010df, &usp[2]);
#else
- put_user(regs->gr[31], &usp[0]);
- put_user(0x0fc0109f, &usp[2]);
+ err |= put_user(regs->gr[31], &usp[0]);
+ err |= put_user(0x0fc0109f, &usp[2]);
#endif
- put_user(0xe0008200, &usp[3]);
- put_user(0x34140000, &usp[4]);
+ err |= put_user(0xe0008200, &usp[3]);
+ err |= put_user(0x34140000, &usp[4]);
- /* Stack is 64-byte aligned, and we only need
- * to flush 1 cache line.
- * Flushing one cacheline is cheap.
- * "sync" on bigger (> 4 way) boxes is not.
- */
- flush_user_dcache_range(regs->gr[30], regs->gr[30] + 4);
- flush_user_icache_range(regs->gr[30], regs->gr[30] + 4);
+ WARN_ON(err);
+
+ /* flush data/instruction cache for new insns */
+ flush_user_dcache_range(start, end);
+ flush_user_icache_range(start, end);
regs->gr[31] = regs->gr[30] + 8;
return;