Skip to content

Commit c0ff3c5

Browse files
committed
MIPS: Enable HAVE_ARCH_TRACEHOOK.
This enables /proc/<pid>/syscall and the ptrace PTRACE_GETREGSET and PTRACE_SETREGSET operations. Signed-off-by: Ralf Baechle <[email protected]>
1 parent 6a9c001 commit c0ff3c5

File tree

3 files changed

+81
-1
lines changed

3 files changed

+81
-1
lines changed

arch/mips/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ config MIPS
88
select HAVE_PERF_EVENTS
99
select PERF_USE_VMALLOC
1010
select HAVE_ARCH_KGDB
11+
select HAVE_ARCH_TRACEHOOK
1112
select ARCH_HAVE_CUSTOM_GPIO_H
1213
select HAVE_FUNCTION_TRACER
1314
select HAVE_FUNCTION_TRACE_MCOUNT_TEST

arch/mips/include/asm/ptrace.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ static inline long regs_return_value(struct pt_regs *regs)
8181

8282
#define instruction_pointer(regs) ((regs)->cp0_epc)
8383
#define profile_pc(regs) instruction_pointer(regs)
84-
#define user_stack_pointer(r) ((r)->regs[29])
8584

8685
extern asmlinkage void syscall_trace_enter(struct pt_regs *regs);
8786
extern asmlinkage void syscall_trace_leave(struct pt_regs *regs);
@@ -100,4 +99,17 @@ static inline void die_if_kernel(const char *str, struct pt_regs *regs)
10099
(struct pt_regs *)((sp | (THREAD_SIZE - 1)) + 1 - 32) - 1; \
101100
})
102101

102+
/* Helpers for working with the user stack pointer */
103+
104+
static inline unsigned long user_stack_pointer(struct pt_regs *regs)
105+
{
106+
return regs->regs[29];
107+
}
108+
109+
static inline void user_stack_pointer_set(struct pt_regs *regs,
110+
unsigned long val)
111+
{
112+
regs->regs[29] = val;
113+
}
114+
103115
#endif /* _ASM_PTRACE_H */

arch/mips/include/asm/syscall.h

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,81 @@
11
/*
2+
* Access to user system call parameters and results
3+
*
24
* This file is subject to the terms and conditions of the GNU General Public
35
* License. See the file "COPYING" in the main directory of this archive
46
* for more details.
57
*
8+
* See asm-generic/syscall.h for descriptions of what we must do here.
9+
*
610
* Copyright (C) 2012 Ralf Baechle <[email protected]>
711
*/
812

913
#ifndef __ASM_MIPS_SYSCALL_H
1014
#define __ASM_MIPS_SYSCALL_H
1115

16+
#include <linux/kernel.h>
17+
#include <linux/sched.h>
18+
#include <linux/uaccess.h>
19+
#include <asm/ptrace.h>
20+
21+
static inline long syscall_get_nr(struct task_struct *task,
22+
struct pt_regs *regs)
23+
{
24+
return regs->regs[2];
25+
}
26+
27+
static inline unsigned long mips_get_syscall_arg(unsigned long *arg,
28+
struct task_struct *task, struct pt_regs *regs, unsigned int n)
29+
{
30+
unsigned long usp = regs->regs[29];
31+
32+
switch (n) {
33+
case 0: case 1: case 2: case 3:
34+
*arg = regs->regs[4 + n];
35+
36+
return 0;
37+
38+
#ifdef CONFIG_32BIT
39+
case 4: case 5: case 6: case 7:
40+
return get_user(*arg, (int *)usp + 4 * n);
41+
#endif
42+
43+
#ifdef CONFIG_64BIT
44+
case 4: case 5: case 6: case 7:
45+
#ifdef CONFIG_MIPS32_O32
46+
if (test_thread_flag(TIF_32BIT_REGS))
47+
return get_user(*arg, (int *)usp + 4 * n);
48+
else
49+
#endif
50+
*arg = regs->regs[4 + n];
51+
52+
return 0;
53+
#endif
54+
55+
default:
56+
BUG();
57+
}
58+
}
59+
60+
static inline void syscall_get_arguments(struct task_struct *task,
61+
struct pt_regs *regs,
62+
unsigned int i, unsigned int n,
63+
unsigned long *args)
64+
{
65+
unsigned long arg;
66+
int ret;
67+
68+
while (n--)
69+
ret |= mips_get_syscall_arg(&arg, task, regs, i++);
70+
71+
/*
72+
* No way to communicate an error because this is a void function.
73+
*/
74+
#if 0
75+
return ret;
76+
#endif
77+
}
78+
1279
extern const unsigned long sys_call_table[];
1380
extern const unsigned long sys32_call_table[];
1481
extern const unsigned long sysn32_call_table[];

0 commit comments

Comments
 (0)