Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit c8bf3805 authored by Heiher's avatar Heiher Committed by Paul Burton
Browse files

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: default avatarHeiher <r@hev.cc>
Patchwork: https://patchwork.linux-mips.org/patch/19507/


Signed-off-by: default avatarPaul Burton <paul.burton@mips.com>
Cc: jhogan@kernel.org
Cc: ralf@linux-mips.org
parent be462bd9
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
@@ -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