diff options
author | Jonas Bonn | 2012-03-02 10:05:24 +0100 |
---|---|---|
committer | Jonas Bonn | 2012-03-06 10:37:00 +0100 |
commit | 6cbe5e95267449ea0b79c0b049342409949da3ac (patch) | |
tree | 21243a6c899b27f67338d77a28ccbe0f473272bc | |
parent | 2f099a280e92c259598d8ed8da82c7ec2dd49845 (diff) |
openrisc: sanitize use of orig_gpr11
The pt_regs struct had both a 'syscallno' field and an 'orig_gpr11' field
and it wasn't really clear how these were supposed to be used. This patch
removes the syscallno field altogether and makes orig_gpr11 work more
like other architectures: keep track of syscall number in progress or
hold -1 for non-syscall exceptions.
Signed-off-by: Jonas Bonn <jonas@southpole.se>
-rw-r--r-- | arch/openrisc/include/asm/ptrace.h | 6 | ||||
-rw-r--r-- | arch/openrisc/include/asm/syscall.h | 7 | ||||
-rw-r--r-- | arch/openrisc/kernel/entry.S | 16 | ||||
-rw-r--r-- | arch/openrisc/kernel/ptrace.c | 4 | ||||
-rw-r--r-- | arch/openrisc/kernel/signal.c | 2 | ||||
-rw-r--r-- | arch/openrisc/kernel/traps.c | 8 |
6 files changed, 22 insertions, 21 deletions
diff --git a/arch/openrisc/include/asm/ptrace.h b/arch/openrisc/include/asm/ptrace.h index e612ce4512c7..4651a737591d 100644 --- a/arch/openrisc/include/asm/ptrace.h +++ b/arch/openrisc/include/asm/ptrace.h @@ -73,9 +73,13 @@ struct pt_regs { }; }; long pc; + /* For restarting system calls: + * Set to syscall number for syscall exceptions, + * -1 for all other exceptions. + */ long orig_gpr11; /* For restarting system calls */ - long syscallno; /* Syscall number (used by strace) */ long dummy; /* Cheap alignment fix */ + long dummy2; /* Cheap alignment fix */ }; /* TODO: Rename this to REDZONE because that's what it is */ diff --git a/arch/openrisc/include/asm/syscall.h b/arch/openrisc/include/asm/syscall.h index 9f0337055d26..b752bb67891d 100644 --- a/arch/openrisc/include/asm/syscall.h +++ b/arch/openrisc/include/asm/syscall.h @@ -25,7 +25,7 @@ static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs) { - return regs->syscallno ? regs->syscallno : -1; + return regs->orig_gpr11; } static inline void @@ -50,10 +50,7 @@ static inline void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, int error, long val) { - if (error) - regs->gpr[11] = -error; - else - regs->gpr[11] = val; + regs->gpr[11] = (long) error ?: val; } static inline void diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S index d5f9c35a583f..6e61af8682b8 100644 --- a/arch/openrisc/kernel/entry.S +++ b/arch/openrisc/kernel/entry.S @@ -95,7 +95,6 @@ handler: ;\ /* r1, EPCR, ESR a already saved */ ;\ l.sw PT_GPR2(r1),r2 ;\ l.sw PT_GPR3(r1),r3 ;\ - l.sw PT_ORIG_GPR11(r1),r11 ;\ /* r4 already save */ ;\ l.sw PT_GPR5(r1),r5 ;\ l.sw PT_GPR6(r1),r6 ;\ @@ -125,7 +124,9 @@ handler: ;\ /* r30 already save */ ;\ /* l.sw PT_GPR30(r1),r30*/ ;\ l.sw PT_GPR31(r1),r31 ;\ - l.sw PT_SYSCALLNO(r1),r0 + /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\ + l.addi r30,r0,-1 ;\ + l.sw PT_ORIG_GPR11(r1),r30 #define UNHANDLED_EXCEPTION(handler,vector) \ .global handler ;\ @@ -133,7 +134,6 @@ handler: ;\ /* r1, EPCR, ESR already saved */ ;\ l.sw PT_GPR2(r1),r2 ;\ l.sw PT_GPR3(r1),r3 ;\ - l.sw PT_ORIG_GPR11(r1),r11 ;\ l.sw PT_GPR5(r1),r5 ;\ l.sw PT_GPR6(r1),r6 ;\ l.sw PT_GPR7(r1),r7 ;\ @@ -162,7 +162,9 @@ handler: ;\ /* r31 already saved */ ;\ l.sw PT_GPR30(r1),r30 ;\ /* l.sw PT_GPR31(r1),r31 */ ;\ - l.sw PT_SYSCALLNO(r1),r0 ;\ + /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\ + l.addi r30,r0,-1 ;\ + l.sw PT_ORIG_GPR11(r1),r30 ;\ l.addi r3,r1,0 ;\ /* r4 is exception EA */ ;\ l.addi r5,r0,vector ;\ @@ -554,6 +556,7 @@ ENTRY(_sys_call_handler) l.sw PT_GPR9(r1),r9 /* r10 already saved */ l.sw PT_GPR11(r1),r11 + /* orig_gpr11 must be set for syscalls */ l.sw PT_ORIG_GPR11(r1),r11 /* r12,r13 already saved */ @@ -567,9 +570,6 @@ ENTRY(_sys_call_handler) /* r30 is the only register we clobber in the fast path */ /* r30 already saved */ /* l.sw PT_GPR30(r1),r30 */ - /* This is used by do_signal to determine whether to check for - * syscall restart or not */ - l.sw PT_SYSCALLNO(r1),r11 _syscall_check_trace_enter: /* If TIF_SYSCALL_TRACE is set, then we want to do syscall tracing */ @@ -731,7 +731,7 @@ _syscall_trace_enter: * so that we can do the syscall for real and return to the syscall * hot path. */ - l.lwz r11,PT_SYSCALLNO(r1) + l.lwz r11,PT_GPR11(r1) l.lwz r3,PT_GPR3(r1) l.lwz r4,PT_GPR4(r1) l.lwz r5,PT_GPR5(r1) diff --git a/arch/openrisc/kernel/ptrace.c b/arch/openrisc/kernel/ptrace.c index 7259047d5f9d..6deacb6b95a4 100644 --- a/arch/openrisc/kernel/ptrace.c +++ b/arch/openrisc/kernel/ptrace.c @@ -188,11 +188,11 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) */ ret = -1L; - audit_syscall_entry(audit_arch(), regs->syscallno, + audit_syscall_entry(audit_arch(), regs->gpr[11], regs->gpr[3], regs->gpr[4], regs->gpr[5], regs->gpr[6]); - return ret ? : regs->syscallno; + return ret ? : regs->gpr[11]; } asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) diff --git a/arch/openrisc/kernel/signal.c b/arch/openrisc/kernel/signal.c index cf35ea032a70..e970743251ae 100644 --- a/arch/openrisc/kernel/signal.c +++ b/arch/openrisc/kernel/signal.c @@ -305,7 +305,7 @@ void do_signal(struct pt_regs *regs) * below mean that the syscall executed to completion and no * restart is necessary. */ - if (regs->syscallno) { + if (regs->orig_gpr11) { int restart = 0; switch (regs->gpr[11]) { diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c index ab68ffc85750..a2ee12948f40 100644 --- a/arch/openrisc/kernel/traps.c +++ b/arch/openrisc/kernel/traps.c @@ -146,8 +146,8 @@ void show_registers(struct pt_regs *regs) regs->gpr[24], regs->gpr[25], regs->gpr[26], regs->gpr[27]); printk("GPR28: %08lx GPR29: %08lx GPR30: %08lx GPR31: %08lx\n", regs->gpr[28], regs->gpr[29], regs->gpr[30], regs->gpr[31]); - printk(" RES: %08lx oGPR11: %08lx syscallno: %08lx\n", - regs->gpr[11], regs->orig_gpr11, regs->syscallno); + printk(" RES: %08lx oGPR11: %08lx\n", + regs->gpr[11], regs->orig_gpr11); printk("Process %s (pid: %d, stackpage=%08lx)\n", current->comm, current->pid, (unsigned long)current); @@ -208,8 +208,8 @@ void nommu_dump_state(struct pt_regs *regs, regs->gpr[24], regs->gpr[25], regs->gpr[26], regs->gpr[27]); printk("GPR28: %08lx GPR29: %08lx GPR30: %08lx GPR31: %08lx\n", regs->gpr[28], regs->gpr[29], regs->gpr[30], regs->gpr[31]); - printk(" RES: %08lx oGPR11: %08lx syscallno: %08lx\n", - regs->gpr[11], regs->orig_gpr11, regs->syscallno); + printk(" RES: %08lx oGPR11: %08lx\n", + regs->gpr[11], regs->orig_gpr11); printk("Process %s (pid: %d, stackpage=%08lx)\n", ((struct task_struct *)(__pa(current)))->comm, |