Skip to content
  • James Hogan's avatar
    MIPS: cpu_name_string: Use raw_smp_processor_id(). · e95008a1
    James Hogan authored
    
    
    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>
    e95008a1