Commit e95008a1 authored by James Hogan's avatar James Hogan Committed by Ralf Baechle

MIPS: cpu_name_string: Use raw_smp_processor_id().

If cpu_name_string() is used in non-atomic context when preemption is
enabled, it can trigger a BUG such as this one:

BUG: using smp_processor_id() in preemptible [00000000] code: unaligned/156
caller is __show_regs+0x1e4/0x330
CPU: 2 PID: 156 Comm: unaligned Tainted: G        W       4.3.0-00366-ga3592179816d-dirty #1501
Stack : ffffffff80900000 ffffffff8019bc18 000000000000005f ffffffff80a20000
         0000000000000000 0000000000000009 ffffffff8019c0e0 ffffffff80835648
         a8000000ff2bdec0 ffffffff80a1e628 000000000000009c 0000000000000002
         ffffffff80840000 a8000000fff2ffb0 0000000000000020 ffffffff8020e43c
         a8000000fff2fcf8 ffffffff80a20000 0000000000000000 ffffffff808f2607
         ffffffff8082b138 ffffffff8019cd1c 0000000000000030 ffffffff8082b138
         0000000000000002 000000000000009c 0000000000000000 0000000000000000
         0000000000000000 a8000000fff2fc40 0000000000000000 ffffffff8044dbf4
         0000000000000000 0000000000000000 0000000000000000 ffffffff8010c400
         ffffffff80855bb0 ffffffff8010d008 0000000000000000 ffffffff8044dbf4
         ...
Call Trace:
[<ffffffff8010d008>] show_stack+0x90/0xb0
[<ffffffff8044dbf4>] dump_stack+0x84/0xe0
[<ffffffff8046d4ec>] check_preemption_disabled+0x10c/0x110
[<ffffffff8010c40c>] __show_regs+0x1e4/0x330
[<ffffffff8010d060>] show_registers+0x28/0xc0
[<ffffffff80110748>] do_ade+0xcc8/0xce0
[<ffffffff80105b84>] resume_userspace_check+0x0/0x10

This is possible because cpu_name_string() is used by __show_regs(),
which is used by both show_regs() and show_registers(). These two
functions are used by various exception handling functions, only some of
which ensure that interrupts or preemption is disabled.

However the following have interrupts explicitly enabled or not
explicitly disabled:
- do_reserved() (irqs enabled)
- do_ade() (irqs not disabled)

This can be hit by setting /sys/kernel/debug/mips/unaligned_action to 2,
and triggering an address error exception, e.g. an unaligned access or
access to kernel segment from user mode.

To fix the above cases, use raw_smp_processor_id() instead. It is
unusual for CPU names to be different in the same system, and even if
they were, its possible the process has migrated between the exception
of interest and the cpu_name_string() call anyway.
Signed-off-by: default avatarJames Hogan <james.hogan@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/12212/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent e34b6fcf
...@@ -102,7 +102,7 @@ extern void cpu_probe(void); ...@@ -102,7 +102,7 @@ extern void cpu_probe(void);
extern void cpu_report(void); extern void cpu_report(void);
extern const char *__cpu_name[]; extern const char *__cpu_name[];
#define cpu_name_string() __cpu_name[smp_processor_id()] #define cpu_name_string() __cpu_name[raw_smp_processor_id()]
struct seq_file; struct seq_file;
struct notifier_block; struct notifier_block;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment