From: Heiher <r@xxxxxx> 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. Signed-off-by: Heiher <r@xxxxxx> --- arch/mips/kernel/genex.S | 44 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 37b9383eacd3..fec6256bac1e 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -354,16 +354,54 @@ 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) + + lw k1, TI_CPU(gp) + 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 + lw k1, TI_CPU(gp) + 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 +415,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 -- 2.17.1