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:
parent
be462bd970
commit
c8bf38055e
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue