diff options
author | James Hogan <james.hogan@imgtec.com> | 2016-01-25 16:06:59 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2016-03-29 23:56:36 +0200 |
commit | e95008a121e37cbee9cdc029483f059206d323be (patch) | |
tree | 3da4334f94ac5521bc3bc6f56ab06ddff97b57a9 /arch/mips | |
parent | e34b6fcf9b09ec9d93503edd5f81489791ffd602 (diff) | |
download | linux-rt-e95008a121e37cbee9cdc029483f059206d323be.tar.gz |
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: James Hogan <james.hogan@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/12212/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/include/asm/cpu-info.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h index e7dc785a91ca..af12c1f9f1a8 100644 --- a/arch/mips/include/asm/cpu-info.h +++ b/arch/mips/include/asm/cpu-info.h @@ -102,7 +102,7 @@ extern void cpu_probe(void); extern void cpu_report(void); 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 notifier_block; |