aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Kardashevskiy <aik@ozlabs.ru>2013-01-10 15:29:09 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-01-15 13:25:46 -0500
commit1715a826a5b72d4fb882504d0babcea9aec8a0db (patch)
treef7f4fc57450c6e5842002f9c459a11a0d7b7ebda
parent61383407677aef05928541a00678591abea2d84c (diff)
powerpc: Add DSCR support to ptrace
The DSCR (aka Data Stream Control Register) is supported on some server PowerPC chips and allow some control over the prefetch of data streams. The kernel already supports DSCR value per thread but there is also a need in a ability to change it from an external process for the specific pid. The patch adds new register index PT_DSCR (index=44) which can be set/get by: ptrace(PTRACE_POKEUSER, traced_process, PT_DSCR << 3, dscr); dscr = ptrace(PTRACE_PEEKUSER, traced_process, PT_DSCR << 3, NULL); The patch does not increase PT_REGS_COUNT as the pt_regs struct has not been changed. Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/include/uapi/asm/ptrace.h1
-rw-r--r--arch/powerpc/kernel/ptrace.c29
2 files changed, 30 insertions, 0 deletions
diff --git a/arch/powerpc/include/uapi/asm/ptrace.h b/arch/powerpc/include/uapi/asm/ptrace.h
index ee67a2bc91bb..5a4863c76b5f 100644
--- a/arch/powerpc/include/uapi/asm/ptrace.h
+++ b/arch/powerpc/include/uapi/asm/ptrace.h
@@ -108,6 +108,7 @@ struct pt_regs {
108#define PT_DAR 41 108#define PT_DAR 41
109#define PT_DSISR 42 109#define PT_DSISR 42
110#define PT_RESULT 43 110#define PT_RESULT 43
111#define PT_DSCR 44
111#define PT_REGS_COUNT 44 112#define PT_REGS_COUNT 44
112 113
113#define PT_FPR0 48 /* each FP reg occupies 2 slots in this space */ 114#define PT_FPR0 48 /* each FP reg occupies 2 slots in this space */
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index d4afcccf1238..245c1b6a0858 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -179,6 +179,30 @@ static int set_user_msr(struct task_struct *task, unsigned long msr)
179 return 0; 179 return 0;
180} 180}
181 181
182#ifdef CONFIG_PPC64
183static unsigned long get_user_dscr(struct task_struct *task)
184{
185 return task->thread.dscr;
186}
187
188static int set_user_dscr(struct task_struct *task, unsigned long dscr)
189{
190 task->thread.dscr = dscr;
191 task->thread.dscr_inherit = 1;
192 return 0;
193}
194#else
195static unsigned long get_user_dscr(struct task_struct *task)
196{
197 return -EIO;
198}
199
200static int set_user_dscr(struct task_struct *task, unsigned long dscr)
201{
202 return -EIO;
203}
204#endif
205
182/* 206/*
183 * We prevent mucking around with the reserved area of trap 207 * We prevent mucking around with the reserved area of trap
184 * which are used internally by the kernel. 208 * which are used internally by the kernel.
@@ -200,6 +224,9 @@ unsigned long ptrace_get_reg(struct task_struct *task, int regno)
200 if (regno == PT_MSR) 224 if (regno == PT_MSR)
201 return get_user_msr(task); 225 return get_user_msr(task);
202 226
227 if (regno == PT_DSCR)
228 return get_user_dscr(task);
229
203 if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long))) 230 if (regno < (sizeof(struct pt_regs) / sizeof(unsigned long)))
204 return ((unsigned long *)task->thread.regs)[regno]; 231 return ((unsigned long *)task->thread.regs)[regno];
205 232
@@ -218,6 +245,8 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data)
218 return set_user_msr(task, data); 245 return set_user_msr(task, data);
219 if (regno == PT_TRAP) 246 if (regno == PT_TRAP)
220 return set_user_trap(task, data); 247 return set_user_trap(task, data);
248 if (regno == PT_DSCR)
249 return set_user_dscr(task, data);
221 250
222 if (regno <= PT_MAX_PUT_REG) { 251 if (regno <= PT_MAX_PUT_REG) {
223 ((unsigned long *)task->thread.regs)[regno] = data; 252 ((unsigned long *)task->thread.regs)[regno] = data;