Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
9224652c
Commit
9224652c
authored
Oct 17, 2008
by
Tony Luck
Browse files
Options
Browse Files
Download
Plain Diff
Pull utrace into release branch
parents
4d4230c2
680973ed
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
285 additions
and
133 deletions
+285
-133
arch/ia64/Kconfig
arch/ia64/Kconfig
+1
-0
arch/ia64/ia32/ia32_entry.S
arch/ia64/ia32/ia32_entry.S
+6
-1
arch/ia64/ia32/sys_ia32.c
arch/ia64/ia32/sys_ia32.c
+6
-77
arch/ia64/include/asm/ptrace.h
arch/ia64/include/asm/ptrace.h
+8
-0
arch/ia64/include/asm/syscall.h
arch/ia64/include/asm/syscall.h
+163
-0
arch/ia64/include/asm/thread_info.h
arch/ia64/include/asm/thread_info.h
+0
-3
arch/ia64/kernel/entry.S
arch/ia64/kernel/entry.S
+5
-0
arch/ia64/kernel/perfmon.c
arch/ia64/kernel/perfmon.c
+3
-4
arch/ia64/kernel/process.c
arch/ia64/kernel/process.c
+6
-15
arch/ia64/kernel/ptrace.c
arch/ia64/kernel/ptrace.c
+79
-33
arch/ia64/kernel/signal.c
arch/ia64/kernel/signal.c
+8
-0
No files found.
arch/ia64/Kconfig
View file @
9224652c
...
@@ -21,6 +21,7 @@ config IA64
...
@@ -21,6 +21,7 @@ config IA64
select HAVE_KRETPROBES
select HAVE_KRETPROBES
select HAVE_DMA_ATTRS
select HAVE_DMA_ATTRS
select HAVE_KVM
select HAVE_KVM
select HAVE_ARCH_TRACEHOOK
default y
default y
help
help
The Itanium Processor Family is Intel's 64-bit successor to
The Itanium Processor Family is Intel's 64-bit successor to
...
...
arch/ia64/ia32/ia32_entry.S
View file @
9224652c
...
@@ -108,6 +108,11 @@ GLOBAL_ENTRY(ia32_trace_syscall)
...
@@ -108,6 +108,11 @@ GLOBAL_ENTRY(ia32_trace_syscall)
;;
;;
st8
[
r2
]=
r3
//
initialize
return
code
to
-
ENOSYS
st8
[
r2
]=
r3
//
initialize
return
code
to
-
ENOSYS
br.call.sptk.few
rp
=
syscall_trace_enter
//
give
parent
a
chance
to
catch
syscall
args
br.call.sptk.few
rp
=
syscall_trace_enter
//
give
parent
a
chance
to
catch
syscall
args
cmp.lt
p6
,
p0
=
r8
,
r0
//
check
tracehook
adds
r2
=
IA64_PT_REGS_R8_OFFSET
+
16
,
sp
//
r2
=
&
pt_regs
.
r8
;;
(
p6
)
st8.spill
[
r2
]=
r8
//
store
return
value
in
slot
for
r8
(
p6
)
br.spnt.few
.
ret4
.
ret2
:
//
Need
to
reload
arguments
(
they
may
be
changed
by
the
tracing
process
)
.
ret2
:
//
Need
to
reload
arguments
(
they
may
be
changed
by
the
tracing
process
)
adds
r2
=
IA64_PT_REGS_R1_OFFSET
+
16
,
sp
//
r2
=
&
pt_regs
.
r1
adds
r2
=
IA64_PT_REGS_R1_OFFSET
+
16
,
sp
//
r2
=
&
pt_regs
.
r1
adds
r3
=
IA64_PT_REGS_R13_OFFSET
+
16
,
sp
//
r3
=
&
pt_regs
.
r13
adds
r3
=
IA64_PT_REGS_R13_OFFSET
+
16
,
sp
//
r3
=
&
pt_regs
.
r13
...
@@ -199,7 +204,7 @@ ia32_syscall_table:
...
@@ -199,7 +204,7 @@ ia32_syscall_table:
data8
sys_setuid
/*
16
-
bit
version
*/
data8
sys_setuid
/*
16
-
bit
version
*/
data8
sys_getuid
/*
16
-
bit
version
*/
data8
sys_getuid
/*
16
-
bit
version
*/
data8
compat_sys_stime
/*
25
*/
data8
compat_sys_stime
/*
25
*/
data8
sys32
_ptrace
data8
compat_sys
_ptrace
data8
sys32_alarm
data8
sys32_alarm
data8
sys_ni_syscall
data8
sys_ni_syscall
data8
sys_pause
data8
sys_pause
...
...
arch/ia64/ia32/sys_ia32.c
View file @
9224652c
...
@@ -1194,25 +1194,6 @@ sys32_waitpid (int pid, unsigned int *stat_addr, int options)
...
@@ -1194,25 +1194,6 @@ sys32_waitpid (int pid, unsigned int *stat_addr, int options)
return
compat_sys_wait4
(
pid
,
stat_addr
,
options
,
NULL
);
return
compat_sys_wait4
(
pid
,
stat_addr
,
options
,
NULL
);
}
}
static
unsigned
int
ia32_peek
(
struct
task_struct
*
child
,
unsigned
long
addr
,
unsigned
int
*
val
)
{
size_t
copied
;
unsigned
int
ret
;
copied
=
access_process_vm
(
child
,
addr
,
val
,
sizeof
(
*
val
),
0
);
return
(
copied
!=
sizeof
(
ret
))
?
-
EIO
:
0
;
}
static
unsigned
int
ia32_poke
(
struct
task_struct
*
child
,
unsigned
long
addr
,
unsigned
int
val
)
{
if
(
access_process_vm
(
child
,
addr
,
&
val
,
sizeof
(
val
),
1
)
!=
sizeof
(
val
))
return
-
EIO
;
return
0
;
}
/*
/*
* The order in which registers are stored in the ptrace regs structure
* The order in which registers are stored in the ptrace regs structure
*/
*/
...
@@ -1510,49 +1491,15 @@ restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __u
...
@@ -1510,49 +1491,15 @@ restore_ia32_fpxstate (struct task_struct *tsk, struct ia32_user_fxsr_struct __u
return
0
;
return
0
;
}
}
asmlinkage
long
long
compat_arch_ptrace
(
struct
task_struct
*
child
,
compat_long_t
request
,
sys32_ptrace
(
int
request
,
pid_t
pid
,
unsigned
int
addr
,
unsigned
int
data
)
compat_ulong_t
caddr
,
compat_ulong_t
c
data
)
{
{
struct
task_struct
*
child
;
unsigned
long
addr
=
caddr
;
unsigned
int
value
,
tmp
;
unsigned
long
data
=
cdata
;
unsigned
int
tmp
;
long
i
,
ret
;
long
i
,
ret
;
lock_kernel
();
if
(
request
==
PTRACE_TRACEME
)
{
ret
=
ptrace_traceme
();
goto
out
;
}
child
=
ptrace_get_task_struct
(
pid
);
if
(
IS_ERR
(
child
))
{
ret
=
PTR_ERR
(
child
);
goto
out
;
}
if
(
request
==
PTRACE_ATTACH
)
{
ret
=
sys_ptrace
(
request
,
pid
,
addr
,
data
);
goto
out_tsk
;
}
ret
=
ptrace_check_attach
(
child
,
request
==
PTRACE_KILL
);
if
(
ret
<
0
)
goto
out_tsk
;
switch
(
request
)
{
switch
(
request
)
{
case
PTRACE_PEEKTEXT
:
case
PTRACE_PEEKDATA
:
/* read word at location addr */
ret
=
ia32_peek
(
child
,
addr
,
&
value
);
if
(
ret
==
0
)
ret
=
put_user
(
value
,
(
unsigned
int
__user
*
)
compat_ptr
(
data
));
else
ret
=
-
EIO
;
goto
out_tsk
;
case
PTRACE_POKETEXT
:
case
PTRACE_POKEDATA
:
/* write the word at location addr */
ret
=
ia32_poke
(
child
,
addr
,
data
);
goto
out_tsk
;
case
PTRACE_PEEKUSR
:
/* read word at addr in USER area */
case
PTRACE_PEEKUSR
:
/* read word at addr in USER area */
ret
=
-
EIO
;
ret
=
-
EIO
;
if
((
addr
&
3
)
||
addr
>
17
*
sizeof
(
int
))
if
((
addr
&
3
)
||
addr
>
17
*
sizeof
(
int
))
...
@@ -1617,27 +1564,9 @@ sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data)
...
@@ -1617,27 +1564,9 @@ sys32_ptrace (int request, pid_t pid, unsigned int addr, unsigned int data)
compat_ptr
(
data
));
compat_ptr
(
data
));
break
;
break
;
case
PTRACE_GETEVENTMSG
:
ret
=
put_user
(
child
->
ptrace_message
,
(
unsigned
int
__user
*
)
compat_ptr
(
data
));
break
;
case
PTRACE_SYSCALL
:
/* continue, stop after next syscall */
case
PTRACE_CONT
:
/* restart after signal. */
case
PTRACE_KILL
:
case
PTRACE_SINGLESTEP
:
/* execute chile for one instruction */
case
PTRACE_DETACH
:
/* detach a process */
ret
=
sys_ptrace
(
request
,
pid
,
addr
,
data
);
break
;
default:
default:
ret
=
ptrace_request
(
child
,
request
,
addr
,
data
);
return
compat_ptrace_request
(
child
,
request
,
caddr
,
cdata
);
break
;
}
}
out_tsk:
put_task_struct
(
child
);
out:
unlock_kernel
();
return
ret
;
return
ret
;
}
}
...
...
arch/ia64/include/asm/ptrace.h
View file @
9224652c
...
@@ -240,6 +240,12 @@ struct switch_stack {
...
@@ -240,6 +240,12 @@ struct switch_stack {
*/
*/
# define instruction_pointer(regs) ((regs)->cr_iip + ia64_psr(regs)->ri)
# define instruction_pointer(regs) ((regs)->cr_iip + ia64_psr(regs)->ri)
static
inline
unsigned
long
user_stack_pointer
(
struct
pt_regs
*
regs
)
{
/* FIXME: should this be bspstore + nr_dirty regs? */
return
regs
->
ar_bspstore
;
}
#define regs_return_value(regs) ((regs)->r8)
#define regs_return_value(regs) ((regs)->r8)
/* Conserve space in histogram by encoding slot bits in address
/* Conserve space in histogram by encoding slot bits in address
...
@@ -319,6 +325,8 @@ struct switch_stack {
...
@@ -319,6 +325,8 @@ struct switch_stack {
#define arch_has_block_step() (1)
#define arch_has_block_step() (1)
extern
void
user_enable_block_step
(
struct
task_struct
*
);
extern
void
user_enable_block_step
(
struct
task_struct
*
);
#define __ARCH_WANT_COMPAT_SYS_PTRACE
#endif
/* !__KERNEL__ */
#endif
/* !__KERNEL__ */
/* pt_all_user_regs is used for PTRACE_GETREGS PTRACE_SETREGS */
/* pt_all_user_regs is used for PTRACE_GETREGS PTRACE_SETREGS */
...
...
arch/ia64/include/asm/syscall.h
0 → 100644
View file @
9224652c
/*
* Access to user system call parameters and results
*
* Copyright (C) 2008 Intel Corp. Shaohua Li <shaohua.li@intel.com>
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* See asm-generic/syscall.h for descriptions of what we must do here.
*/
#ifndef _ASM_SYSCALL_H
#define _ASM_SYSCALL_H 1
#include <linux/sched.h>
#include <linux/err.h>
static
inline
long
syscall_get_nr
(
struct
task_struct
*
task
,
struct
pt_regs
*
regs
)
{
if
((
long
)
regs
->
cr_ifs
<
0
)
/* Not a syscall */
return
-
1
;
#ifdef CONFIG_IA32_SUPPORT
if
(
IS_IA32_PROCESS
(
regs
))
return
regs
->
r1
;
#endif
return
regs
->
r15
;
}
static
inline
void
syscall_rollback
(
struct
task_struct
*
task
,
struct
pt_regs
*
regs
)
{
#ifdef CONFIG_IA32_SUPPORT
if
(
IS_IA32_PROCESS
(
regs
))
regs
->
r8
=
regs
->
r1
;
#endif
/* do nothing */
}
static
inline
long
syscall_get_error
(
struct
task_struct
*
task
,
struct
pt_regs
*
regs
)
{
#ifdef CONFIG_IA32_SUPPORT
if
(
IS_IA32_PROCESS
(
regs
))
return
regs
->
r8
;
#endif
return
regs
->
r10
==
-
1
?
regs
->
r8
:
0
;
}
static
inline
long
syscall_get_return_value
(
struct
task_struct
*
task
,
struct
pt_regs
*
regs
)
{
return
regs
->
r8
;
}
static
inline
void
syscall_set_return_value
(
struct
task_struct
*
task
,
struct
pt_regs
*
regs
,
int
error
,
long
val
)
{
#ifdef CONFIG_IA32_SUPPORT
if
(
IS_IA32_PROCESS
(
regs
))
{
regs
->
r8
=
(
long
)
error
?
error
:
val
;
return
;
}
#endif
if
(
error
)
{
/* error < 0, but ia64 uses > 0 return value */
regs
->
r8
=
-
error
;
regs
->
r10
=
-
1
;
}
else
{
regs
->
r8
=
val
;
regs
->
r10
=
0
;
}
}
extern
void
ia64_syscall_get_set_arguments
(
struct
task_struct
*
task
,
struct
pt_regs
*
regs
,
unsigned
int
i
,
unsigned
int
n
,
unsigned
long
*
args
,
int
rw
);
static
inline
void
syscall_get_arguments
(
struct
task_struct
*
task
,
struct
pt_regs
*
regs
,
unsigned
int
i
,
unsigned
int
n
,
unsigned
long
*
args
)
{
BUG_ON
(
i
+
n
>
6
);
#ifdef CONFIG_IA32_SUPPORT
if
(
IS_IA32_PROCESS
(
regs
))
{
switch
(
i
+
n
)
{
case
6
:
if
(
!
n
--
)
break
;
*
args
++
=
regs
->
r13
;
case
5
:
if
(
!
n
--
)
break
;
*
args
++
=
regs
->
r15
;
case
4
:
if
(
!
n
--
)
break
;
*
args
++
=
regs
->
r14
;
case
3
:
if
(
!
n
--
)
break
;
*
args
++
=
regs
->
r10
;
case
2
:
if
(
!
n
--
)
break
;
*
args
++
=
regs
->
r9
;
case
1
:
if
(
!
n
--
)
break
;
*
args
++
=
regs
->
r11
;
case
0
:
if
(
!
n
--
)
break
;
default:
BUG
();
break
;
}
return
;
}
#endif
ia64_syscall_get_set_arguments
(
task
,
regs
,
i
,
n
,
args
,
0
);
}
static
inline
void
syscall_set_arguments
(
struct
task_struct
*
task
,
struct
pt_regs
*
regs
,
unsigned
int
i
,
unsigned
int
n
,
unsigned
long
*
args
)
{
BUG_ON
(
i
+
n
>
6
);
#ifdef CONFIG_IA32_SUPPORT
if
(
IS_IA32_PROCESS
(
regs
))
{
switch
(
i
+
n
)
{
case
6
:
if
(
!
n
--
)
break
;
regs
->
r13
=
*
args
++
;
case
5
:
if
(
!
n
--
)
break
;
regs
->
r15
=
*
args
++
;
case
4
:
if
(
!
n
--
)
break
;
regs
->
r14
=
*
args
++
;
case
3
:
if
(
!
n
--
)
break
;
regs
->
r10
=
*
args
++
;
case
2
:
if
(
!
n
--
)
break
;
regs
->
r9
=
*
args
++
;
case
1
:
if
(
!
n
--
)
break
;
regs
->
r11
=
*
args
++
;
case
0
:
if
(
!
n
--
)
break
;
}
return
;
}
#endif
ia64_syscall_get_set_arguments
(
task
,
regs
,
i
,
n
,
args
,
1
);
}
#endif
/* _ASM_SYSCALL_H */
arch/ia64/include/asm/thread_info.h
View file @
9224652c
...
@@ -87,9 +87,6 @@ struct thread_info {
...
@@ -87,9 +87,6 @@ struct thread_info {
#define alloc_task_struct() ((struct task_struct *)__get_free_pages(GFP_KERNEL | __GFP_COMP, KERNEL_STACK_SIZE_ORDER))
#define alloc_task_struct() ((struct task_struct *)__get_free_pages(GFP_KERNEL | __GFP_COMP, KERNEL_STACK_SIZE_ORDER))
#define free_task_struct(tsk) free_pages((unsigned long) (tsk), KERNEL_STACK_SIZE_ORDER)
#define free_task_struct(tsk) free_pages((unsigned long) (tsk), KERNEL_STACK_SIZE_ORDER)
#define tsk_set_notify_resume(tsk) \
set_ti_thread_flag(task_thread_info(tsk), TIF_NOTIFY_RESUME)
extern
void
tsk_clear_notify_resume
(
struct
task_struct
*
tsk
);
#endif
/* !__ASSEMBLY */
#endif
/* !__ASSEMBLY */
/*
/*
...
...
arch/ia64/kernel/entry.S
View file @
9224652c
...
@@ -534,6 +534,11 @@ GLOBAL_ENTRY(ia64_trace_syscall)
...
@@ -534,6 +534,11 @@ GLOBAL_ENTRY(ia64_trace_syscall)
stf.spill
[
r16
]=
f10
stf.spill
[
r16
]=
f10
stf.spill
[
r17
]=
f11
stf.spill
[
r17
]=
f11
br.call.sptk.many
rp
=
syscall_trace_enter
//
give
parent
a
chance
to
catch
syscall
args
br.call.sptk.many
rp
=
syscall_trace_enter
//
give
parent
a
chance
to
catch
syscall
args
cmp.lt
p6
,
p0
=
r8
,
r0
//
check
tracehook
adds
r2
=
PT
(
R8
)+
16
,
sp
//
r2
=
&
pt_regs
.
r8
adds
r3
=
PT
(
R10
)+
16
,
sp
//
r3
=
&
pt_regs
.
r10
mov
r10
=
0
(
p6
)
br.cond.sptk
strace_error
//
syscall
failed
->
adds
r16
=
PT
(
F6
)+
16
,
sp
adds
r16
=
PT
(
F6
)+
16
,
sp
adds
r17
=
PT
(
F7
)+
16
,
sp
adds
r17
=
PT
(
F7
)+
16
,
sp
;;
;;
...
...
arch/ia64/kernel/perfmon.c
View file @
9224652c
...
@@ -40,6 +40,7 @@
...
@@ -40,6 +40,7 @@
#include <linux/capability.h>
#include <linux/capability.h>
#include <linux/rcupdate.h>
#include <linux/rcupdate.h>
#include <linux/completion.h>
#include <linux/completion.h>
#include <linux/tracehook.h>
#include <asm/errno.h>
#include <asm/errno.h>
#include <asm/intrinsics.h>
#include <asm/intrinsics.h>
...
@@ -3684,7 +3685,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
...
@@ -3684,7 +3685,7 @@ pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
PFM_SET_WORK_PENDING
(
task
,
1
);
PFM_SET_WORK_PENDING
(
task
,
1
);
tsk_
set_notify_resume
(
task
);
set_notify_resume
(
task
);
/*
/*
* XXX: send reschedule if task runs on another CPU
* XXX: send reschedule if task runs on another CPU
...
@@ -5044,8 +5045,6 @@ pfm_handle_work(void)
...
@@ -5044,8 +5045,6 @@ pfm_handle_work(void)
PFM_SET_WORK_PENDING
(
current
,
0
);
PFM_SET_WORK_PENDING
(
current
,
0
);
tsk_clear_notify_resume
(
current
);
regs
=
task_pt_regs
(
current
);
regs
=
task_pt_regs
(
current
);
/*
/*
...
@@ -5414,7 +5413,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str
...
@@ -5414,7 +5413,7 @@ pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, str
* when coming from ctxsw, current still points to the
* when coming from ctxsw, current still points to the
* previous task, therefore we must work with task and not current.
* previous task, therefore we must work with task and not current.
*/
*/
tsk_
set_notify_resume
(
task
);
set_notify_resume
(
task
);
}
}
/*
/*
* defer until state is changed (shorten spin window). the context is locked
* defer until state is changed (shorten spin window). the context is locked
...
...
arch/ia64/kernel/process.c
View file @
9224652c
...
@@ -28,6 +28,7 @@
...
@@ -28,6 +28,7 @@
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/kdebug.h>
#include <linux/kdebug.h>
#include <linux/utsname.h>
#include <linux/utsname.h>
#include <linux/tracehook.h>
#include <asm/cpu.h>
#include <asm/cpu.h>
#include <asm/delay.h>
#include <asm/delay.h>
...
@@ -160,21 +161,6 @@ show_regs (struct pt_regs *regs)
...
@@ -160,21 +161,6 @@ show_regs (struct pt_regs *regs)
show_stack
(
NULL
,
NULL
);
show_stack
(
NULL
,
NULL
);
}
}
void
tsk_clear_notify_resume
(
struct
task_struct
*
tsk
)
{
#ifdef CONFIG_PERFMON
if
(
tsk
->
thread
.
pfm_needs_checking
)
return
;
#endif
if
(
test_ti_thread_flag
(
task_thread_info
(
tsk
),
TIF_RESTORE_RSE
))
return
;
clear_ti_thread_flag
(
task_thread_info
(
tsk
),
TIF_NOTIFY_RESUME
);
}
/*
* do_notify_resume_user():
* Called from notify_resume_user at entry.S, with interrupts disabled.
*/
void
void
do_notify_resume_user
(
sigset_t
*
unused
,
struct
sigscratch
*
scr
,
long
in_syscall
)
do_notify_resume_user
(
sigset_t
*
unused
,
struct
sigscratch
*
scr
,
long
in_syscall
)
{
{
...
@@ -203,6 +189,11 @@ do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
...
@@ -203,6 +189,11 @@ do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
ia64_do_signal
(
scr
,
in_syscall
);
ia64_do_signal
(
scr
,
in_syscall
);
}
}
if
(
test_thread_flag
(
TIF_NOTIFY_RESUME
))
{
clear_thread_flag
(
TIF_NOTIFY_RESUME
);
tracehook_notify_resume
(
&
scr
->
pt
);
}
/* copy user rbs to kernel rbs */
/* copy user rbs to kernel rbs */
if
(
unlikely
(
test_thread_flag
(
TIF_RESTORE_RSE
)))
{
if
(
unlikely
(
test_thread_flag
(
TIF_RESTORE_RSE
)))
{
local_irq_enable
();
/* force interrupt enable */
local_irq_enable
();
/* force interrupt enable */
...
...
arch/ia64/kernel/ptrace.c
View file @
9224652c
...
@@ -22,6 +22,7 @@
...
@@ -22,6 +22,7 @@
#include <linux/signal.h>
#include <linux/signal.h>
#include <linux/regset.h>
#include <linux/regset.h>
#include <linux/elf.h>
#include <linux/elf.h>
#include <linux/tracehook.h>
#include <asm/pgtable.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/processor.h>
...
@@ -603,7 +604,7 @@ void ia64_ptrace_stop(void)
...
@@ -603,7 +604,7 @@ void ia64_ptrace_stop(void)
{
{
if
(
test_and_set_tsk_thread_flag
(
current
,
TIF_RESTORE_RSE
))
if
(
test_and_set_tsk_thread_flag
(
current
,
TIF_RESTORE_RSE
))
return
;
return
;
tsk_
set_notify_resume
(
current
);
set_notify_resume
(
current
);
unw_init_running
(
do_sync_rbs
,
ia64_sync_user_rbs
);
unw_init_running
(
do_sync_rbs
,
ia64_sync_user_rbs
);
}
}
...
@@ -613,7 +614,6 @@ void ia64_ptrace_stop(void)
...
@@ -613,7 +614,6 @@ void ia64_ptrace_stop(void)
void
ia64_sync_krbs
(
void
)
void
ia64_sync_krbs
(
void
)
{
{
clear_tsk_thread_flag
(
current
,
TIF_RESTORE_RSE
);
clear_tsk_thread_flag
(
current
,
TIF_RESTORE_RSE
);
tsk_clear_notify_resume
(
current
);
unw_init_running
(
do_sync_rbs
,
ia64_sync_kernel_rbs
);
unw_init_running
(
do_sync_rbs
,
ia64_sync_kernel_rbs
);
}
}
...
@@ -644,7 +644,7 @@ ptrace_attach_sync_user_rbs (struct task_struct *child)
...
@@ -644,7 +644,7 @@ ptrace_attach_sync_user_rbs (struct task_struct *child)
spin_lock_irq
(
&
child
->
sighand
->
siglock
);
spin_lock_irq
(
&
child
->
sighand
->
siglock
);
if
(
child
->
state
==
TASK_STOPPED
&&
if
(
child
->
state
==
TASK_STOPPED
&&
!
test_and_set_tsk_thread_flag
(
child
,
TIF_RESTORE_RSE
))
{
!
test_and_set_tsk_thread_flag
(
child
,
TIF_RESTORE_RSE
))
{
tsk_
set_notify_resume
(
child
);
set_notify_resume
(
child
);
child
->
state
=
TASK_TRACED
;
child
->
state
=
TASK_TRACED
;
stopped
=
1
;
stopped
=
1
;
...
@@ -1232,37 +1232,16 @@ arch_ptrace (struct task_struct *child, long request, long addr, long data)
...
@@ -1232,37 +1232,16 @@ arch_ptrace (struct task_struct *child, long request, long addr, long data)
}
}
static
void
syscall_trace
(
void
)
{
/*
* The 0x80 provides a way for the tracing parent to
* distinguish between a syscall stop and SIGTRAP delivery.
*/
ptrace_notify
(
SIGTRAP
|
((
current
->
ptrace
&
PT_TRACESYSGOOD
)
?
0x80
:
0
));
/*
* This isn't the same as continuing with a signal, but it
* will do for normal use. strace only continues with a
* signal if the stopping signal is not SIGTRAP. -brl
*/
if
(
current
->
exit_code
)
{
send_sig
(
current
->
exit_code
,
current
,
1
);
current
->
exit_code
=
0
;
}
}
/* "asmlinkage" so the input arguments are preserved... */
/* "asmlinkage" so the input arguments are preserved... */
asmlinkage
void
asmlinkage
long
syscall_trace_enter
(
long
arg0
,
long
arg1
,
long
arg2
,
long
arg3
,
syscall_trace_enter
(
long
arg0
,
long
arg1
,
long
arg2
,
long
arg3
,
long
arg4
,
long
arg5
,
long
arg6
,
long
arg7
,
long
arg4
,
long
arg5
,
long
arg6
,
long
arg7
,
struct
pt_regs
regs
)
struct
pt_regs
regs
)
{
{
if
(
test_thread_flag
(
TIF_SYSCALL_TRACE
)
if
(
test_thread_flag
(
TIF_SYSCALL_TRACE
)
)
&&
(
current
->
ptrace
&
PT_PTRACED
))
if
(
tracehook_report_syscall_entry
(
&
regs
))
syscall_trace
()
;
return
-
ENOSYS
;
/* copy user rbs to kernel rbs */
/* copy user rbs to kernel rbs */
if
(
test_thread_flag
(
TIF_RESTORE_RSE
))
if
(
test_thread_flag
(
TIF_RESTORE_RSE
))
...
@@ -1283,6 +1262,7 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
...
@@ -1283,6 +1262,7 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
audit_syscall_entry
(
arch
,
syscall
,
arg0
,
arg1
,
arg2
,
arg3
);
audit_syscall_entry
(
arch
,
syscall
,
arg0
,
arg1
,
arg2
,
arg3
);
}
}
return
0
;
}
}
/* "asmlinkage" so the input arguments are preserved... */
/* "asmlinkage" so the input arguments are preserved... */
...
@@ -1292,6 +1272,8 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
...
@@ -1292,6 +1272,8 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
long
arg4
,
long
arg5
,
long
arg6
,
long
arg7
,
long
arg4
,
long
arg5
,
long
arg6
,
long
arg7
,
struct
pt_regs
regs
)
struct
pt_regs
regs
)
{
{
int
step
;
if
(
unlikely
(
current
->
audit_context
))
{
if
(
unlikely
(
current
->
audit_context
))
{
int
success
=
AUDITSC_RESULT
(
regs
.
r10
);
int
success
=
AUDITSC_RESULT
(
regs
.
r10
);
long
result
=
regs
.
r8
;
long
result
=
regs
.
r8
;
...
@@ -1301,10 +1283,9 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
...
@@ -1301,10 +1283,9 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
audit_syscall_exit
(
success
,
result
);
audit_syscall_exit
(
success
,
result
);
}
}
if
((
test_thread_flag
(
TIF_SYSCALL_TRACE
)
step
=
test_thread_flag
(
TIF_SINGLESTEP
);
||
test_thread_flag
(
TIF_SINGLESTEP
))
if
(
step
||
test_thread_flag
(
TIF_SYSCALL_TRACE
))
&&
(
current
->
ptrace
&
PT_PTRACED
))
tracehook_report_syscall_exit
(
&
regs
,
step
);
syscall_trace
();
/* copy user rbs to kernel rbs */
/* copy user rbs to kernel rbs */
if
(
test_thread_flag
(
TIF_RESTORE_RSE
))
if
(
test_thread_flag
(
TIF_RESTORE_RSE
))
...
@@ -1940,7 +1921,7 @@ gpregs_writeback(struct task_struct *target,
...
@@ -1940,7 +1921,7 @@ gpregs_writeback(struct task_struct *target,
{
{
if
(
test_and_set_tsk_thread_flag
(
target
,
TIF_RESTORE_RSE
))
if
(
test_and_set_tsk_thread_flag
(
target
,
TIF_RESTORE_RSE
))
return
0
;
return
0
;
tsk_
set_notify_resume
(
target
);
set_notify_resume
(
target
);
return
do_regset_call
(
do_gpregs_writeback
,
target
,
regset
,
0
,
0
,
return
do_regset_call
(
do_gpregs_writeback
,
target
,
regset
,
0
,
0
,
NULL
,
NULL
);
NULL
,
NULL
);
}
}
...
@@ -2199,3 +2180,68 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *tsk)
...
@@ -2199,3 +2180,68 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *tsk)
#endif
#endif
return
&
user_ia64_view
;
return
&
user_ia64_view
;
}
}
struct
syscall_get_set_args
{
unsigned
int
i
;
unsigned
int
n
;
unsigned
long
*
args
;
struct
pt_regs
*
regs
;
int
rw
;
};
static
void
syscall_get_set_args_cb
(
struct
unw_frame_info
*
info
,
void
*
data
)
{
struct
syscall_get_set_args
*
args
=
data
;
struct
pt_regs
*
pt
=
args
->
regs
;
unsigned
long
*
krbs
,
cfm
,
ndirty
;
int
i
,
count
;
if
(
unw_unwind_to_user
(
info
)
<
0
)
return
;
cfm
=
pt
->
cr_ifs
;
krbs
=
(
unsigned
long
*
)
info
->
task
+
IA64_RBS_OFFSET
/
8
;
ndirty
=
ia64_rse_num_regs
(
krbs
,
krbs
+
(
pt
->
loadrs
>>
19
));
count
=
0
;
if
(
in_syscall
(
pt
))
count
=
min_t
(
int
,
args
->
n
,
cfm
&
0x7f
);
for
(
i
=
0
;
i
<
count
;
i
++
)
{
if
(
args
->
rw
)
*
ia64_rse_skip_regs
(
krbs
,
ndirty
+
i
+
args
->
i
)
=
args
->
args
[
i
];
else
args
->
args
[
i
]
=
*
ia64_rse_skip_regs
(
krbs
,
ndirty
+
i
+
args
->
i
);
}
if
(
!
args
->
rw
)
{
while
(
i
<
args
->
n
)
{
args
->
args
[
i
]
=
0
;
i
++
;
}
}
}
void
ia64_syscall_get_set_arguments
(
struct
task_struct
*
task
,
struct
pt_regs
*
regs
,
unsigned
int
i
,
unsigned
int
n
,
unsigned
long
*
args
,
int
rw
)
{
struct
syscall_get_set_args
data
=
{
.
i
=
i
,
.
n
=
n
,
.
args
=
args
,
.
regs
=
regs
,
.
rw
=
rw
,
};
if
(
task
==
current
)
unw_init_running
(
syscall_get_set_args_cb
,
&
data
);
else
{
struct
unw_frame_info
ufi
;
memset
(
&
ufi
,
0
,
sizeof
(
ufi
));
unw_init_from_blocked_task
(
&
ufi
,
task
);
syscall_get_set_args_cb
(
&
ufi
,
&
data
);
}
}
arch/ia64/kernel/signal.c
View file @
9224652c
...
@@ -11,6 +11,7 @@
...
@@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/mm.h>
#include <linux/ptrace.h>
#include <linux/ptrace.h>
#include <linux/tracehook.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/signal.h>
#include <linux/smp.h>
#include <linux/smp.h>
...
@@ -439,6 +440,13 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigse
...
@@ -439,6 +440,13 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigse
sigaddset
(
&
current
->
blocked
,
sig
);
sigaddset
(
&
current
->
blocked
,
sig
);
recalc_sigpending
();
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sighand
->
siglock
);
spin_unlock_irq
(
&
current
->
sighand
->
siglock
);
/*
* Let tracing know that we've done the handler setup.
*/
tracehook_signal_handler
(
sig
,
info
,
ka
,
&
scr
->
pt
,
test_thread_flag
(
TIF_SINGLESTEP
));
return
1
;
return
1
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment