mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-17 01:34:00 +08:00
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>
This commit is contained in:
parent
2f099a280e
commit
6cbe5e9526
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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]) {
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user