提交 57c7ea51 编写于 作者: A Alex Smith 提交者: Ralf Baechle

MIPS: ptrace: Avoid smp_processor_id() in preemptible code

ptrace_{get,set}_watch_regs access current_cpu_data to get the watch
register count/masks, which calls smp_processor_id(). However they are
run in preemptible context and therefore trigger warnings like so:

[ 6340.092000] BUG: using smp_processor_id() in preemptible [00000000] code: gdb/367
[ 6340.092000] caller is ptrace_get_watch_regs+0x44/0x220

Since the watch register count/masks should be the same across all
CPUs, use boot_cpu_data instead. Note that this may need to change in
future should a heterogenous system be supported where the count/masks
are not the same across all CPUs (the current code is also incorrect
for this scenario - current_cpu_data here would not necessarily be
correct for the CPU that the target task will execute on).
Signed-off-by: NAlex Smith <alex.smith@imgtec.com>
Reviewed-by: NPaul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/6879/Signed-off-by: NRalf Baechle <ralf@linux-mips.org>
上级 f02ffb19
...@@ -163,7 +163,7 @@ int ptrace_get_watch_regs(struct task_struct *child, ...@@ -163,7 +163,7 @@ int ptrace_get_watch_regs(struct task_struct *child,
enum pt_watch_style style; enum pt_watch_style style;
int i; int i;
if (!cpu_has_watch || current_cpu_data.watch_reg_use_cnt == 0) if (!cpu_has_watch || boot_cpu_data.watch_reg_use_cnt == 0)
return -EIO; return -EIO;
if (!access_ok(VERIFY_WRITE, addr, sizeof(struct pt_watch_regs))) if (!access_ok(VERIFY_WRITE, addr, sizeof(struct pt_watch_regs)))
return -EIO; return -EIO;
...@@ -177,14 +177,14 @@ int ptrace_get_watch_regs(struct task_struct *child, ...@@ -177,14 +177,14 @@ int ptrace_get_watch_regs(struct task_struct *child,
#endif #endif
__put_user(style, &addr->style); __put_user(style, &addr->style);
__put_user(current_cpu_data.watch_reg_use_cnt, __put_user(boot_cpu_data.watch_reg_use_cnt,
&addr->WATCH_STYLE.num_valid); &addr->WATCH_STYLE.num_valid);
for (i = 0; i < current_cpu_data.watch_reg_use_cnt; i++) { for (i = 0; i < boot_cpu_data.watch_reg_use_cnt; i++) {
__put_user(child->thread.watch.mips3264.watchlo[i], __put_user(child->thread.watch.mips3264.watchlo[i],
&addr->WATCH_STYLE.watchlo[i]); &addr->WATCH_STYLE.watchlo[i]);
__put_user(child->thread.watch.mips3264.watchhi[i] & 0xfff, __put_user(child->thread.watch.mips3264.watchhi[i] & 0xfff,
&addr->WATCH_STYLE.watchhi[i]); &addr->WATCH_STYLE.watchhi[i]);
__put_user(current_cpu_data.watch_reg_masks[i], __put_user(boot_cpu_data.watch_reg_masks[i],
&addr->WATCH_STYLE.watch_masks[i]); &addr->WATCH_STYLE.watch_masks[i]);
} }
for (; i < 8; i++) { for (; i < 8; i++) {
...@@ -204,12 +204,12 @@ int ptrace_set_watch_regs(struct task_struct *child, ...@@ -204,12 +204,12 @@ int ptrace_set_watch_regs(struct task_struct *child,
unsigned long lt[NUM_WATCH_REGS]; unsigned long lt[NUM_WATCH_REGS];
u16 ht[NUM_WATCH_REGS]; u16 ht[NUM_WATCH_REGS];
if (!cpu_has_watch || current_cpu_data.watch_reg_use_cnt == 0) if (!cpu_has_watch || boot_cpu_data.watch_reg_use_cnt == 0)
return -EIO; return -EIO;
if (!access_ok(VERIFY_READ, addr, sizeof(struct pt_watch_regs))) if (!access_ok(VERIFY_READ, addr, sizeof(struct pt_watch_regs)))
return -EIO; return -EIO;
/* Check the values. */ /* Check the values. */
for (i = 0; i < current_cpu_data.watch_reg_use_cnt; i++) { for (i = 0; i < boot_cpu_data.watch_reg_use_cnt; i++) {
__get_user(lt[i], &addr->WATCH_STYLE.watchlo[i]); __get_user(lt[i], &addr->WATCH_STYLE.watchlo[i]);
#ifdef CONFIG_32BIT #ifdef CONFIG_32BIT
if (lt[i] & __UA_LIMIT) if (lt[i] & __UA_LIMIT)
...@@ -228,7 +228,7 @@ int ptrace_set_watch_regs(struct task_struct *child, ...@@ -228,7 +228,7 @@ int ptrace_set_watch_regs(struct task_struct *child,
return -EINVAL; return -EINVAL;
} }
/* Install them. */ /* Install them. */
for (i = 0; i < current_cpu_data.watch_reg_use_cnt; i++) { for (i = 0; i < boot_cpu_data.watch_reg_use_cnt; i++) {
if (lt[i] & 7) if (lt[i] & 7)
watch_active = 1; watch_active = 1;
child->thread.watch.mips3264.watchlo[i] = lt[i]; child->thread.watch.mips3264.watchlo[i] = lt[i];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册