aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel
diff options
context:
space:
mode:
authorHeiher <r@hev.cc>2018-06-11 05:01:10 -0400
committerPaul Burton <paul.burton@mips.com>2018-06-24 12:27:27 -0400
commitc8bf38055efaf764fd8c313695759c64dc735842 (patch)
tree01514c17094ee3154485f4b1888492f319c4cd83 /arch/mips/kernel
parentbe462bd9700aec12029d43d48e6ff2207cb68fb7 (diff)
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
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r--arch/mips/kernel/genex.S46
1 files changed, 46 insertions, 0 deletions
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index 37b9383eacd3..6c257b52f57f 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -354,16 +354,56 @@ NESTED(ejtag_debug_handler, PT_SIZE, sp)
354 sll k0, k0, 30 # Check for SDBBP. 354 sll k0, k0, 30 # Check for SDBBP.
355 bgez k0, ejtag_return 355 bgez k0, ejtag_return
356 356
357#ifdef CONFIG_SMP
3581: PTR_LA k0, ejtag_debug_buffer_spinlock
359 ll k0, 0(k0)
360 bnez k0, 1b
361 PTR_LA k0, ejtag_debug_buffer_spinlock
362 sc k0, 0(k0)
363 beqz k0, 1b
364# ifdef CONFIG_WEAK_REORDERING_BEYOND_LLSC
365 sync
366# endif
367
368 PTR_LA k0, ejtag_debug_buffer
369 LONG_S k1, 0(k0)
370
371 ASM_CPUID_MFC0 k1, ASM_SMP_CPUID_REG
372 PTR_SRL k1, SMP_CPUID_PTRSHIFT
373 PTR_SLL k1, LONGLOG
374 PTR_LA k0, ejtag_debug_buffer_per_cpu
375 PTR_ADDU k0, k1
376
377 PTR_LA k1, ejtag_debug_buffer
378 LONG_L k1, 0(k1)
379 LONG_S k1, 0(k0)
380
381 PTR_LA k0, ejtag_debug_buffer_spinlock
382 sw zero, 0(k0)
383#else
357 PTR_LA k0, ejtag_debug_buffer 384 PTR_LA k0, ejtag_debug_buffer
358 LONG_S k1, 0(k0) 385 LONG_S k1, 0(k0)
386#endif
387
359 SAVE_ALL 388 SAVE_ALL
360 move a0, sp 389 move a0, sp
361 jal ejtag_exception_handler 390 jal ejtag_exception_handler
362 RESTORE_ALL 391 RESTORE_ALL
392
393#ifdef CONFIG_SMP
394 ASM_CPUID_MFC0 k1, ASM_SMP_CPUID_REG
395 PTR_SRL k1, SMP_CPUID_PTRSHIFT
396 PTR_SLL k1, LONGLOG
397 PTR_LA k0, ejtag_debug_buffer_per_cpu
398 PTR_ADDU k0, k1
399 LONG_L k1, 0(k0)
400#else
363 PTR_LA k0, ejtag_debug_buffer 401 PTR_LA k0, ejtag_debug_buffer
364 LONG_L k1, 0(k0) 402 LONG_L k1, 0(k0)
403#endif
365 404
366ejtag_return: 405ejtag_return:
406 back_to_back_c0_hazard
367 MFC0 k0, CP0_DESAVE 407 MFC0 k0, CP0_DESAVE
368 .set mips32 408 .set mips32
369 deret 409 deret
@@ -377,6 +417,12 @@ ejtag_return:
377 .data 417 .data
378EXPORT(ejtag_debug_buffer) 418EXPORT(ejtag_debug_buffer)
379 .fill LONGSIZE 419 .fill LONGSIZE
420#ifdef CONFIG_SMP
421EXPORT(ejtag_debug_buffer_spinlock)
422 .fill LONGSIZE
423EXPORT(ejtag_debug_buffer_per_cpu)
424 .fill LONGSIZE * NR_CPUS
425#endif
380 .previous 426 .previous
381 427
382 __INIT 428 __INIT