aboutsummaryrefslogtreecommitdiff
path: root/arch/ia64
diff options
context:
space:
mode:
authorPetr Tesarik <ptesarik@suse.cz>2008-02-11 22:41:18 +0100
committerTony Luck <tony.luck@intel.com>2008-03-05 15:47:31 -0800
commit972559a05222c1d7ebd5dcde637542713bb8778d (patch)
tree71718577801cc213c870d6eabe8e7856b1df6b7e /arch/ia64
parent29e8c3c304b62f31b799565c9ee85d42bd163f80 (diff)
[IA64] access user RBS directly
Because the user RBS of a process is now completely stored in user-mode when the process is ptrace-stopped, accesses to the RBS should no longer augment any part of the kernel RBS. This means we can get rid of most ia64_peek() and ia64_poke() calls. Signed-off-by: Petr Tesarik <ptesarik@suse.cz> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/kernel/ptrace.c44
1 files changed, 14 insertions, 30 deletions
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 331d6768b5d..9d2591423eb 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -908,7 +908,7 @@ static int
access_uarea (struct task_struct *child, unsigned long addr,
unsigned long *data, int write_access)
{
- unsigned long *ptr, regnum, urbs_end, rnat_addr, cfm;
+ unsigned long *ptr, regnum, urbs_end, cfm;
struct switch_stack *sw;
struct pt_regs *pt;
# define pt_reg_addr(pt, reg) ((void *) \
@@ -1093,16 +1093,8 @@ access_uarea (struct task_struct *child, unsigned long addr,
return 0;
case PT_AR_RNAT:
- urbs_end = ia64_get_user_rbs_end(child, pt, NULL);
- rnat_addr = (long) ia64_rse_rnat_addr((long *)
- urbs_end);
- if (write_access)
- return ia64_poke(child, sw, urbs_end,
- rnat_addr, *data);
- else
- return ia64_peek(child, sw, urbs_end,
- rnat_addr, data);
-
+ ptr = pt_reg_addr(pt, ar_rnat);
+ break;
case PT_R1:
ptr = pt_reg_addr(pt, r1);
break;
@@ -1541,11 +1533,10 @@ asmlinkage long
sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
{
struct pt_regs *pt;
- unsigned long urbs_end, peek_or_poke;
+ unsigned long peek_or_poke;
struct task_struct *child;
struct switch_stack *sw;
long ret;
- struct unw_frame_info info;
lock_kernel();
ret = -EPERM;
@@ -1593,26 +1584,19 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
case PTRACE_PEEKTEXT:
case PTRACE_PEEKDATA:
/* read word at location addr */
- urbs_end = ia64_get_user_rbs_end(child, pt, NULL);
- ret = ia64_peek(child, sw, urbs_end, addr, &data);
- if (ret == 0) {
- ret = data;
- /* ensure "ret" is not mistaken as an error code: */
- force_successful_syscall_return();
+ if (access_process_vm(child, addr, &data, sizeof(data), 0)
+ != sizeof(data)) {
+ ret = -EIO;
+ goto out_tsk;
}
+ ret = data;
+ /* ensure "ret" is not mistaken as an error code */
+ force_successful_syscall_return();
goto out_tsk;
- case PTRACE_POKETEXT:
- case PTRACE_POKEDATA:
- /* write the word at location addr */
- urbs_end = ia64_get_user_rbs_end(child, pt, NULL);
- ret = ia64_poke(child, sw, urbs_end, addr, data);
-
- /* Make sure user RBS has the latest data */
- unw_init_from_blocked_task(&info, child);
- do_sync_rbs(&info, ia64_sync_user_rbs);
-
- goto out_tsk;
+ /* PTRACE_POKETEXT and PTRACE_POKEDATA is handled
+ * by the generic ptrace_request().
+ */
case PTRACE_PEEKUSR:
/* read the word at addr in the USER area */