Commit 94579094 authored by Tony Luck's avatar Tony Luck

[IA64] clean up ptrace corner cases

Patch from yanmin.zhang@intel.com to fix up some corner cases
in ptrace.  Many thanks to davidm for reviewing and improving.
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent e3ce98a2
...@@ -51,8 +51,11 @@ ...@@ -51,8 +51,11 @@
* setup a null register window frame. * setup a null register window frame.
*/ */
ENTRY(ia64_execve) ENTRY(ia64_execve)
.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(3) /*
alloc loc1=ar.pfs,3,2,4,0 * Allocate 8 input registers since ptrace() may clobber them
*/
.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
alloc loc1=ar.pfs,8,2,4,0
mov loc0=rp mov loc0=rp
.body .body
mov out0=in0 // filename mov out0=in0 // filename
...@@ -113,8 +116,11 @@ END(ia64_execve) ...@@ -113,8 +116,11 @@ END(ia64_execve)
* u64 tls) * u64 tls)
*/ */
GLOBAL_ENTRY(sys_clone2) GLOBAL_ENTRY(sys_clone2)
.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(6) /*
alloc r16=ar.pfs,6,2,6,0 * Allocate 8 input registers since ptrace() may clobber them
*/
.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
alloc r16=ar.pfs,8,2,6,0
DO_SAVE_SWITCH_STACK DO_SAVE_SWITCH_STACK
adds r2=PT(R16)+IA64_SWITCH_STACK_SIZE+16,sp adds r2=PT(R16)+IA64_SWITCH_STACK_SIZE+16,sp
mov loc0=rp mov loc0=rp
...@@ -142,8 +148,11 @@ END(sys_clone2) ...@@ -142,8 +148,11 @@ END(sys_clone2)
* Deprecated. Use sys_clone2() instead. * Deprecated. Use sys_clone2() instead.
*/ */
GLOBAL_ENTRY(sys_clone) GLOBAL_ENTRY(sys_clone)
.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5) /*
alloc r16=ar.pfs,5,2,6,0 * Allocate 8 input registers since ptrace() may clobber them
*/
.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
alloc r16=ar.pfs,8,2,6,0
DO_SAVE_SWITCH_STACK DO_SAVE_SWITCH_STACK
adds r2=PT(R16)+IA64_SWITCH_STACK_SIZE+16,sp adds r2=PT(R16)+IA64_SWITCH_STACK_SIZE+16,sp
mov loc0=rp mov loc0=rp
...@@ -1212,7 +1221,10 @@ END(sys_rt_sigsuspend) ...@@ -1212,7 +1221,10 @@ END(sys_rt_sigsuspend)
ENTRY(sys_rt_sigreturn) ENTRY(sys_rt_sigreturn)
PT_REGS_UNWIND_INFO(0) PT_REGS_UNWIND_INFO(0)
alloc r2=ar.pfs,0,0,1,0 /*
* Allocate 8 input registers since ptrace() may clobber them
*/
alloc r2=ar.pfs,8,0,1,0
.prologue .prologue
PT_REGS_SAVES(16) PT_REGS_SAVES(16)
adds sp=-16,sp adds sp=-16,sp
......
...@@ -612,8 +612,9 @@ GLOBAL_ENTRY(fsys_bubble_down) ...@@ -612,8 +612,9 @@ GLOBAL_ENTRY(fsys_bubble_down)
;; ;;
mov rp=r2 // set the real return addr mov rp=r2 // set the real return addr
tbit.z p8,p0=r3,TIF_SYSCALL_TRACE tbit.z p8,p0=r3,TIF_SYSCALL_TRACE
;;
(p8) br.call.sptk.many b6=b6 // ignore this return addr (p10) br.cond.spnt.many ia64_ret_from_syscall // p10==true means out registers are more than 8
(p8) br.call.sptk.many b6=b6 // ignore this return addr
br.cond.sptk ia64_trace_syscall br.cond.sptk ia64_trace_syscall
END(fsys_bubble_down) END(fsys_bubble_down)
......
...@@ -81,6 +81,7 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) ...@@ -81,6 +81,7 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
LOAD_FSYSCALL_TABLE(r14) LOAD_FSYSCALL_TABLE(r14)
mov r16=IA64_KR(CURRENT) // 12 cycle read latency mov r16=IA64_KR(CURRENT) // 12 cycle read latency
tnat.nz p10,p9=r15
mov r19=NR_syscalls-1 mov r19=NR_syscalls-1
;; ;;
shladd r18=r17,3,r14 shladd r18=r17,3,r14
...@@ -119,7 +120,8 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) ...@@ -119,7 +120,8 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc)
#endif #endif
mov r10=-1 mov r10=-1
mov r8=ENOSYS (p10) mov r8=EINVAL
(p9) mov r8=ENOSYS
FSYS_RETURN FSYS_RETURN
END(__kernel_syscall_via_epc) END(__kernel_syscall_via_epc)
......
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
#include <asm/unistd.h> #include <asm/unistd.h>
#include <asm/errno.h>
#if 1 #if 1
# define PSR_DEFAULT_BITS psr.ac # define PSR_DEFAULT_BITS psr.ac
...@@ -732,10 +733,12 @@ ENTRY(break_fault) ...@@ -732,10 +733,12 @@ ENTRY(break_fault)
ssm psr.ic | PSR_DEFAULT_BITS ssm psr.ic | PSR_DEFAULT_BITS
;; ;;
srlz.i // guarantee that interruption collection is on srlz.i // guarantee that interruption collection is on
mov r3=NR_syscalls - 1
;; ;;
(p15) ssm psr.i // restore psr.i (p15) ssm psr.i // restore psr.i
// p10==true means out registers are more than 8 or r15's Nat is true
(p10) br.cond.spnt.many ia64_ret_from_syscall
;; ;;
mov r3=NR_syscalls - 1
movl r16=sys_call_table movl r16=sys_call_table
adds r15=-1024,r15 // r15 contains the syscall number---subtract 1024 adds r15=-1024,r15 // r15 contains the syscall number---subtract 1024
...@@ -836,8 +839,11 @@ END(interrupt) ...@@ -836,8 +839,11 @@ END(interrupt)
* On exit: * On exit:
* - executing on bank 1 registers * - executing on bank 1 registers
* - psr.ic enabled, interrupts restored * - psr.ic enabled, interrupts restored
* - p10: TRUE if syscall is invoked with more than 8 out
* registers or r15's Nat is true
* - r1: kernel's gp * - r1: kernel's gp
* - r3: preserved (same as on entry) * - r3: preserved (same as on entry)
* - r8: -EINVAL if p10 is true
* - r12: points to kernel stack * - r12: points to kernel stack
* - r13: points to current task * - r13: points to current task
* - p15: TRUE if interrupts need to be re-enabled * - p15: TRUE if interrupts need to be re-enabled
...@@ -871,12 +877,17 @@ GLOBAL_ENTRY(ia64_syscall_setup) ...@@ -871,12 +877,17 @@ GLOBAL_ENTRY(ia64_syscall_setup)
;; ;;
st8 [r16]=r19,PT(AR_RNAT)-PT(CR_IFS) // store ar.pfs.pfm in cr.ifs st8 [r16]=r19,PT(AR_RNAT)-PT(CR_IFS) // store ar.pfs.pfm in cr.ifs
extr.u r11=r19,7,7 // I0 // get sol of ar.pfs
and r8=0x7f,r19 // A // get sof of ar.pfs
st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc
tbit.nz p15,p0=r29,IA64_PSR_I_BIT // I0
(p9) mov in1=-1 (p9) mov in1=-1
;;
(pUStk) sub r18=r18,r22 // r18=RSE.ndirty*8 (pUStk) sub r18=r18,r22 // r18=RSE.ndirty*8
tbit.nz p15,p0=r29,IA64_PSR_I_BIT
tnat.nz p10,p0=in2 tnat.nz p10,p0=in2
add r11=8,r11
;; ;;
(pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16 // skip over ar_rnat field (pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16 // skip over ar_rnat field
(pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17 // skip over ar_bspstore field (pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17 // skip over ar_bspstore field
...@@ -904,25 +915,29 @@ GLOBAL_ENTRY(ia64_syscall_setup) ...@@ -904,25 +915,29 @@ GLOBAL_ENTRY(ia64_syscall_setup)
(p13) mov in5=-1 (p13) mov in5=-1
;; ;;
st8 [r16]=r21,PT(R8)-PT(AR_FPSR) // save ar.fpsr st8 [r16]=r21,PT(R8)-PT(AR_FPSR) // save ar.fpsr
st8.spill [r17]=r15 // save r15
tnat.nz p14,p0=in6 tnat.nz p14,p0=in6
cmp.lt p10,p9=r11,r8 // frame size can't be more than local+8
;; ;;
stf8 [r16]=f1 // ensure pt_regs.r8 != 0 (see handle_syscall_error) stf8 [r16]=f1 // ensure pt_regs.r8 != 0 (see handle_syscall_error)
(p9) tnat.nz p10,p0=r15
adds r12=-16,r1 // switch to kernel memory stack (with 16 bytes of scratch) adds r12=-16,r1 // switch to kernel memory stack (with 16 bytes of scratch)
st8.spill [r17]=r15 // save r15
tnat.nz p8,p0=in7 tnat.nz p8,p0=in7
nop.i 0
mov r13=r2 // establish `current' mov r13=r2 // establish `current'
movl r1=__gp // establish kernel global pointer movl r1=__gp // establish kernel global pointer
;; ;;
(p14) mov in6=-1 (p14) mov in6=-1
(p8) mov in7=-1 (p8) mov in7=-1
tnat.nz p9,p0=r15 nop.i 0
cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
movl r17=FPSR_DEFAULT movl r17=FPSR_DEFAULT
;; ;;
mov.m ar.fpsr=r17 // set ar.fpsr to kernel default value mov.m ar.fpsr=r17 // set ar.fpsr to kernel default value
(p9) mov r15=-1 (p10) mov r8=-EINVAL
br.ret.sptk.many b7 br.ret.sptk.many b7
END(ia64_syscall_setup) END(ia64_syscall_setup)
......
...@@ -632,7 +632,7 @@ dump_fpu (struct pt_regs *pt, elf_fpregset_t dst) ...@@ -632,7 +632,7 @@ dump_fpu (struct pt_regs *pt, elf_fpregset_t dst)
return 1; /* f0-f31 are always valid so we always return 1 */ return 1; /* f0-f31 are always valid so we always return 1 */
} }
asmlinkage long long
sys_execve (char __user *filename, char __user * __user *argv, char __user * __user *envp, sys_execve (char __user *filename, char __user * __user *argv, char __user * __user *envp,
struct pt_regs *regs) struct pt_regs *regs)
{ {
......
...@@ -374,7 +374,7 @@ asmlinkage unsigned long sys_mmap2( ...@@ -374,7 +374,7 @@ asmlinkage unsigned long sys_mmap2(
int fd, long pgoff); int fd, long pgoff);
struct pt_regs; struct pt_regs;
struct sigaction; struct sigaction;
asmlinkage long sys_execve(char __user *filename, char __user * __user *argv, long sys_execve(char __user *filename, char __user * __user *argv,
char __user * __user *envp, struct pt_regs *regs); char __user * __user *envp, struct pt_regs *regs);
asmlinkage long sys_pipe(long arg0, long arg1, long arg2, long arg3, asmlinkage long sys_pipe(long arg0, long arg1, long arg2, long arg3,
long arg4, long arg5, long arg6, long arg7, long stack); long arg4, long arg5, long arg6, long arg7, long stack);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment