diff options
author | Jonas Bonn <jonas@southpole.se> | 2012-03-02 04:05:24 -0500 |
---|---|---|
committer | Jonas Bonn <jonas@southpole.se> | 2012-03-06 04:37:00 -0500 |
commit | 6cbe5e95267449ea0b79c0b049342409949da3ac (patch) | |
tree | 21243a6c899b27f67338d77a28ccbe0f473272bc /arch/openrisc | |
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>
Diffstat (limited to 'arch/openrisc')
-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 { | |||
73 | }; | 73 | }; |
74 | }; | 74 | }; |
75 | long pc; | 75 | long pc; |
76 | /* For restarting system calls: | ||
77 | * Set to syscall number for syscall exceptions, | ||
78 | * -1 for all other exceptions. | ||
79 | */ | ||
76 | long orig_gpr11; /* For restarting system calls */ | 80 | long orig_gpr11; /* For restarting system calls */ |
77 | long syscallno; /* Syscall number (used by strace) */ | ||
78 | long dummy; /* Cheap alignment fix */ | 81 | long dummy; /* Cheap alignment fix */ |
82 | long dummy2; /* Cheap alignment fix */ | ||
79 | }; | 83 | }; |
80 | 84 | ||
81 | /* TODO: Rename this to REDZONE because that's what it is */ | 85 | /* 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 @@ | |||
25 | static inline int | 25 | static inline int |
26 | syscall_get_nr(struct task_struct *task, struct pt_regs *regs) | 26 | syscall_get_nr(struct task_struct *task, struct pt_regs *regs) |
27 | { | 27 | { |
28 | return regs->syscallno ? regs->syscallno : -1; | 28 | return regs->orig_gpr11; |
29 | } | 29 | } |
30 | 30 | ||
31 | static inline void | 31 | static inline void |
@@ -50,10 +50,7 @@ static inline void | |||
50 | syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, | 50 | syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, |
51 | int error, long val) | 51 | int error, long val) |
52 | { | 52 | { |
53 | if (error) | 53 | regs->gpr[11] = (long) error ?: val; |
54 | regs->gpr[11] = -error; | ||
55 | else | ||
56 | regs->gpr[11] = val; | ||
57 | } | 54 | } |
58 | 55 | ||
59 | static inline void | 56 | 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: ;\ | |||
95 | /* r1, EPCR, ESR a already saved */ ;\ | 95 | /* r1, EPCR, ESR a already saved */ ;\ |
96 | l.sw PT_GPR2(r1),r2 ;\ | 96 | l.sw PT_GPR2(r1),r2 ;\ |
97 | l.sw PT_GPR3(r1),r3 ;\ | 97 | l.sw PT_GPR3(r1),r3 ;\ |
98 | l.sw PT_ORIG_GPR11(r1),r11 ;\ | ||
99 | /* r4 already save */ ;\ | 98 | /* r4 already save */ ;\ |
100 | l.sw PT_GPR5(r1),r5 ;\ | 99 | l.sw PT_GPR5(r1),r5 ;\ |
101 | l.sw PT_GPR6(r1),r6 ;\ | 100 | l.sw PT_GPR6(r1),r6 ;\ |
@@ -125,7 +124,9 @@ handler: ;\ | |||
125 | /* r30 already save */ ;\ | 124 | /* r30 already save */ ;\ |
126 | /* l.sw PT_GPR30(r1),r30*/ ;\ | 125 | /* l.sw PT_GPR30(r1),r30*/ ;\ |
127 | l.sw PT_GPR31(r1),r31 ;\ | 126 | l.sw PT_GPR31(r1),r31 ;\ |
128 | l.sw PT_SYSCALLNO(r1),r0 | 127 | /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\ |
128 | l.addi r30,r0,-1 ;\ | ||
129 | l.sw PT_ORIG_GPR11(r1),r30 | ||
129 | 130 | ||
130 | #define UNHANDLED_EXCEPTION(handler,vector) \ | 131 | #define UNHANDLED_EXCEPTION(handler,vector) \ |
131 | .global handler ;\ | 132 | .global handler ;\ |
@@ -133,7 +134,6 @@ handler: ;\ | |||
133 | /* r1, EPCR, ESR already saved */ ;\ | 134 | /* r1, EPCR, ESR already saved */ ;\ |
134 | l.sw PT_GPR2(r1),r2 ;\ | 135 | l.sw PT_GPR2(r1),r2 ;\ |
135 | l.sw PT_GPR3(r1),r3 ;\ | 136 | l.sw PT_GPR3(r1),r3 ;\ |
136 | l.sw PT_ORIG_GPR11(r1),r11 ;\ | ||
137 | l.sw PT_GPR5(r1),r5 ;\ | 137 | l.sw PT_GPR5(r1),r5 ;\ |
138 | l.sw PT_GPR6(r1),r6 ;\ | 138 | l.sw PT_GPR6(r1),r6 ;\ |
139 | l.sw PT_GPR7(r1),r7 ;\ | 139 | l.sw PT_GPR7(r1),r7 ;\ |
@@ -162,7 +162,9 @@ handler: ;\ | |||
162 | /* r31 already saved */ ;\ | 162 | /* r31 already saved */ ;\ |
163 | l.sw PT_GPR30(r1),r30 ;\ | 163 | l.sw PT_GPR30(r1),r30 ;\ |
164 | /* l.sw PT_GPR31(r1),r31 */ ;\ | 164 | /* l.sw PT_GPR31(r1),r31 */ ;\ |
165 | l.sw PT_SYSCALLNO(r1),r0 ;\ | 165 | /* Store -1 in orig_gpr11 for non-syscall exceptions */ ;\ |
166 | l.addi r30,r0,-1 ;\ | ||
167 | l.sw PT_ORIG_GPR11(r1),r30 ;\ | ||
166 | l.addi r3,r1,0 ;\ | 168 | l.addi r3,r1,0 ;\ |
167 | /* r4 is exception EA */ ;\ | 169 | /* r4 is exception EA */ ;\ |
168 | l.addi r5,r0,vector ;\ | 170 | l.addi r5,r0,vector ;\ |
@@ -554,6 +556,7 @@ ENTRY(_sys_call_handler) | |||
554 | l.sw PT_GPR9(r1),r9 | 556 | l.sw PT_GPR9(r1),r9 |
555 | /* r10 already saved */ | 557 | /* r10 already saved */ |
556 | l.sw PT_GPR11(r1),r11 | 558 | l.sw PT_GPR11(r1),r11 |
559 | /* orig_gpr11 must be set for syscalls */ | ||
557 | l.sw PT_ORIG_GPR11(r1),r11 | 560 | l.sw PT_ORIG_GPR11(r1),r11 |
558 | /* r12,r13 already saved */ | 561 | /* r12,r13 already saved */ |
559 | 562 | ||
@@ -567,9 +570,6 @@ ENTRY(_sys_call_handler) | |||
567 | /* r30 is the only register we clobber in the fast path */ | 570 | /* r30 is the only register we clobber in the fast path */ |
568 | /* r30 already saved */ | 571 | /* r30 already saved */ |
569 | /* l.sw PT_GPR30(r1),r30 */ | 572 | /* l.sw PT_GPR30(r1),r30 */ |
570 | /* This is used by do_signal to determine whether to check for | ||
571 | * syscall restart or not */ | ||
572 | l.sw PT_SYSCALLNO(r1),r11 | ||
573 | 573 | ||
574 | _syscall_check_trace_enter: | 574 | _syscall_check_trace_enter: |
575 | /* If TIF_SYSCALL_TRACE is set, then we want to do syscall tracing */ | 575 | /* If TIF_SYSCALL_TRACE is set, then we want to do syscall tracing */ |
@@ -731,7 +731,7 @@ _syscall_trace_enter: | |||
731 | * so that we can do the syscall for real and return to the syscall | 731 | * so that we can do the syscall for real and return to the syscall |
732 | * hot path. | 732 | * hot path. |
733 | */ | 733 | */ |
734 | l.lwz r11,PT_SYSCALLNO(r1) | 734 | l.lwz r11,PT_GPR11(r1) |
735 | l.lwz r3,PT_GPR3(r1) | 735 | l.lwz r3,PT_GPR3(r1) |
736 | l.lwz r4,PT_GPR4(r1) | 736 | l.lwz r4,PT_GPR4(r1) |
737 | l.lwz r5,PT_GPR5(r1) | 737 | 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) | |||
188 | */ | 188 | */ |
189 | ret = -1L; | 189 | ret = -1L; |
190 | 190 | ||
191 | audit_syscall_entry(audit_arch(), regs->syscallno, | 191 | audit_syscall_entry(audit_arch(), regs->gpr[11], |
192 | regs->gpr[3], regs->gpr[4], | 192 | regs->gpr[3], regs->gpr[4], |
193 | regs->gpr[5], regs->gpr[6]); | 193 | regs->gpr[5], regs->gpr[6]); |
194 | 194 | ||
195 | return ret ? : regs->syscallno; | 195 | return ret ? : regs->gpr[11]; |
196 | } | 196 | } |
197 | 197 | ||
198 | asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) | 198 | 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) | |||
305 | * below mean that the syscall executed to completion and no | 305 | * below mean that the syscall executed to completion and no |
306 | * restart is necessary. | 306 | * restart is necessary. |
307 | */ | 307 | */ |
308 | if (regs->syscallno) { | 308 | if (regs->orig_gpr11) { |
309 | int restart = 0; | 309 | int restart = 0; |
310 | 310 | ||
311 | switch (regs->gpr[11]) { | 311 | 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) | |||
146 | regs->gpr[24], regs->gpr[25], regs->gpr[26], regs->gpr[27]); | 146 | regs->gpr[24], regs->gpr[25], regs->gpr[26], regs->gpr[27]); |
147 | printk("GPR28: %08lx GPR29: %08lx GPR30: %08lx GPR31: %08lx\n", | 147 | printk("GPR28: %08lx GPR29: %08lx GPR30: %08lx GPR31: %08lx\n", |
148 | regs->gpr[28], regs->gpr[29], regs->gpr[30], regs->gpr[31]); | 148 | regs->gpr[28], regs->gpr[29], regs->gpr[30], regs->gpr[31]); |
149 | printk(" RES: %08lx oGPR11: %08lx syscallno: %08lx\n", | 149 | printk(" RES: %08lx oGPR11: %08lx\n", |
150 | regs->gpr[11], regs->orig_gpr11, regs->syscallno); | 150 | regs->gpr[11], regs->orig_gpr11); |
151 | 151 | ||
152 | printk("Process %s (pid: %d, stackpage=%08lx)\n", | 152 | printk("Process %s (pid: %d, stackpage=%08lx)\n", |
153 | current->comm, current->pid, (unsigned long)current); | 153 | current->comm, current->pid, (unsigned long)current); |
@@ -208,8 +208,8 @@ void nommu_dump_state(struct pt_regs *regs, | |||
208 | regs->gpr[24], regs->gpr[25], regs->gpr[26], regs->gpr[27]); | 208 | regs->gpr[24], regs->gpr[25], regs->gpr[26], regs->gpr[27]); |
209 | printk("GPR28: %08lx GPR29: %08lx GPR30: %08lx GPR31: %08lx\n", | 209 | printk("GPR28: %08lx GPR29: %08lx GPR30: %08lx GPR31: %08lx\n", |
210 | regs->gpr[28], regs->gpr[29], regs->gpr[30], regs->gpr[31]); | 210 | regs->gpr[28], regs->gpr[29], regs->gpr[30], regs->gpr[31]); |
211 | printk(" RES: %08lx oGPR11: %08lx syscallno: %08lx\n", | 211 | printk(" RES: %08lx oGPR11: %08lx\n", |
212 | regs->gpr[11], regs->orig_gpr11, regs->syscallno); | 212 | regs->gpr[11], regs->orig_gpr11); |
213 | 213 | ||
214 | printk("Process %s (pid: %d, stackpage=%08lx)\n", | 214 | printk("Process %s (pid: %d, stackpage=%08lx)\n", |
215 | ((struct task_struct *)(__pa(current)))->comm, | 215 | ((struct task_struct *)(__pa(current)))->comm, |