MIPS: Fix ejtag handler on SMP

On SMP systems, the shared ejtag debug buffer may be overwritten by
other cores, because every cores can generate ejtag exception at
same time.

Unfortunately, in that context, it's difficult to relax more registers
to access per cpu buffers. so use ll/sc to serialize the access.

[paul.burton@mips.com:
  This could in theory be backported at least as far back as the
  beginning of the git era, however in general it's exceedingly rare
  that anyone would hit this without further changes, so it doesn't seem
  worthwhile marking for backport.]

Signed-off-by: Heiher <r@hev.cc>
Patchwork: https://patchwork.linux-mips.org/patch/19507/
Signed-off-by: Paul Burton <paul.burton@mips.com>
Cc: jhogan@kernel.org
Cc: ralf@linux-mips.org
This commit is contained in:
Heiher 2018-06-11 17:01:10 +08:00 committed by Paul Burton
parent be462bd970
commit c8bf38055e
No known key found for this signature in database
GPG Key ID: 3EA79FACB57500DD

View File

@ -354,16 +354,56 @@ NESTED(ejtag_debug_handler, PT_SIZE, sp)
sll k0, k0, 30 # Check for SDBBP.
bgez k0, ejtag_return
#ifdef CONFIG_SMP
1: PTR_LA k0, ejtag_debug_buffer_spinlock
ll k0, 0(k0)
bnez k0, 1b
PTR_LA k0, ejtag_debug_buffer_spinlock
sc k0, 0(k0)
beqz k0, 1b
# ifdef CONFIG_WEAK_REORDERING_BEYOND_LLSC
sync
# endif
PTR_LA k0, ejtag_debug_buffer
LONG_S k1, 0(k0)
ASM_CPUID_MFC0 k1, ASM_SMP_CPUID_REG
PTR_SRL k1, SMP_CPUID_PTRSHIFT
PTR_SLL k1, LONGLOG
PTR_LA k0, ejtag_debug_buffer_per_cpu
PTR_ADDU k0, k1
PTR_LA k1, ejtag_debug_buffer
LONG_L k1, 0(k1)
LONG_S k1, 0(k0)
PTR_LA k0, ejtag_debug_buffer_spinlock
sw zero, 0(k0)
#else
PTR_LA k0, ejtag_debug_buffer
LONG_S k1, 0(k0)
#endif
SAVE_ALL
move a0, sp
jal ejtag_exception_handler
RESTORE_ALL
#ifdef CONFIG_SMP
ASM_CPUID_MFC0 k1, ASM_SMP_CPUID_REG
PTR_SRL k1, SMP_CPUID_PTRSHIFT
PTR_SLL k1, LONGLOG
PTR_LA k0, ejtag_debug_buffer_per_cpu
PTR_ADDU k0, k1
LONG_L k1, 0(k0)
#else
PTR_LA k0, ejtag_debug_buffer
LONG_L k1, 0(k0)
#endif
ejtag_return:
back_to_back_c0_hazard
MFC0 k0, CP0_DESAVE
.set mips32
deret
@ -377,6 +417,12 @@ ejtag_return:
.data
EXPORT(ejtag_debug_buffer)
.fill LONGSIZE
#ifdef CONFIG_SMP
EXPORT(ejtag_debug_buffer_spinlock)
.fill LONGSIZE
EXPORT(ejtag_debug_buffer_per_cpu)
.fill LONGSIZE * NR_CPUS
#endif
.previous
__INIT