diff options
Diffstat (limited to 'arch/powerpc/kernel/ptrace.c')
-rw-r--r-- | arch/powerpc/kernel/ptrace.c | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index dd4837c4a68a..75bc744a6217 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -35,16 +35,28 @@ | |||
35 | #include <asm/pgtable.h> | 35 | #include <asm/pgtable.h> |
36 | #include <asm/system.h> | 36 | #include <asm/system.h> |
37 | 37 | ||
38 | #ifdef CONFIG_PPC64 | 38 | /* |
39 | #include "ptrace-ppc64.h" | 39 | * does not yet catch signals sent when the child dies. |
40 | * in exit.c or in signal.c. | ||
41 | */ | ||
42 | |||
43 | /* | ||
44 | * Set of msr bits that gdb can change on behalf of a process. | ||
45 | */ | ||
46 | #if defined(CONFIG_40x) || defined(CONFIG_BOOKE) | ||
47 | #define MSR_DEBUGCHANGE 0 | ||
40 | #else | 48 | #else |
41 | #include "ptrace-ppc32.h" | 49 | #define MSR_DEBUGCHANGE (MSR_SE | MSR_BE) |
42 | #endif | 50 | #endif |
43 | 51 | ||
44 | /* | 52 | /* |
45 | * does not yet catch signals sent when the child dies. | 53 | * Max register writeable via put_reg |
46 | * in exit.c or in signal.c. | ||
47 | */ | 54 | */ |
55 | #ifdef CONFIG_PPC32 | ||
56 | #define PT_MAX_PUT_REG PT_MQ | ||
57 | #else | ||
58 | #define PT_MAX_PUT_REG PT_CCR | ||
59 | #endif | ||
48 | 60 | ||
49 | /* | 61 | /* |
50 | * Get contents of register REGNO in task TASK. | 62 | * Get contents of register REGNO in task TASK. |
@@ -58,7 +70,7 @@ unsigned long ptrace_get_reg(struct task_struct *task, int regno) | |||
58 | 70 | ||
59 | if (regno == PT_MSR) { | 71 | if (regno == PT_MSR) { |
60 | tmp = ((unsigned long *)task->thread.regs)[PT_MSR]; | 72 | tmp = ((unsigned long *)task->thread.regs)[PT_MSR]; |
61 | return PT_MUNGE_MSR(tmp, task); | 73 | return tmp | task->thread.fpexc_mode; |
62 | } | 74 | } |
63 | 75 | ||
64 | if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) | 76 | if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) |
@@ -274,6 +286,27 @@ static void clear_single_step(struct task_struct *task) | |||
274 | clear_tsk_thread_flag(task, TIF_SINGLESTEP); | 286 | clear_tsk_thread_flag(task, TIF_SINGLESTEP); |
275 | } | 287 | } |
276 | 288 | ||
289 | #ifdef CONFIG_PPC64 | ||
290 | static int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, | ||
291 | unsigned long data) | ||
292 | { | ||
293 | /* We only support one DABR and no IABRS at the moment */ | ||
294 | if (addr > 0) | ||
295 | return -EINVAL; | ||
296 | |||
297 | /* The bottom 3 bits are flags */ | ||
298 | if ((data & ~0x7UL) >= TASK_SIZE) | ||
299 | return -EIO; | ||
300 | |||
301 | /* Ensure translation is on */ | ||
302 | if (data && !(data & DABR_TRANSLATION)) | ||
303 | return -EIO; | ||
304 | |||
305 | task->thread.dabr = data; | ||
306 | return 0; | ||
307 | } | ||
308 | #endif | ||
309 | |||
277 | /* | 310 | /* |
278 | * Called by kernel/ptrace.c when detaching.. | 311 | * Called by kernel/ptrace.c when detaching.. |
279 | * | 312 | * |