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

Commit aea8e7c8 authored by Max Filippov's avatar Max Filippov Committed by Chris Zankel
Browse files

xtensa: check thread flags atomically on return from user exception



Check pending signals and rescheduling thread flags with interrupts
disabled, and don't enable them if no flags are set. Call
trace_hardirqs_on after thread flags handling, so that rescheduling is
done and hardirqs tracking flag is updated in the correct task context.

Signed-off-by: default avatarMax Filippov <jcmvbkbc@gmail.com>
Signed-off-by: default avatarChris Zankel <chris@zankel.net>
parent 0bc2ba94
Loading
Loading
Loading
Loading
+21 −18
Original line number Diff line number Diff line
@@ -423,29 +423,14 @@ common_exception:
	.global common_exception_return
common_exception_return:

#ifdef CONFIG_TRACE_IRQFLAGS
	l32i	a4, a1, PT_DEPC
	/* Double exception means we came here with an exception
	 * while PS.EXCM was set, i.e. interrupts disabled.
	 */
	bgeui	a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
	l32i	a4, a1, PT_EXCCAUSE
	bnei	a4, EXCCAUSE_LEVEL1_INTERRUPT, 1f
	/* We came here with an interrupt means interrupts were enabled
	 * and we'll reenable them on return.
	 */
	movi	a4, trace_hardirqs_on
	callx4	a4
1:
#endif
	rsil	a2, LOCKLEVEL

	/* Jump if we are returning from kernel exceptions. */

1:	l32i	a3, a1, PT_PS
	l32i	a3, a1, PT_PS
	_bbci.l	a3, PS_UM_BIT, 4f

	rsil	a2, 0

	/* Specific to a user exception exit:
	 * We need to check some flags for signal handling and rescheduling,
	 * and have to restore WB and WS, extra states, and all registers
@@ -465,6 +450,7 @@ common_exception_return:

	/* Call do_signal() */

	rsil	a2, 0
	movi	a4, do_notify_resume	# int do_notify_resume(struct pt_regs*)
	mov	a6, a1
	callx4	a4
@@ -472,6 +458,7 @@ common_exception_return:

3:	/* Reschedule */

	rsil	a2, 0
	movi	a4, schedule	# void schedule (void)
	callx4	a4
	j	1b
@@ -483,7 +470,23 @@ common_exception_return:
	movi	a4, check_tlb_sanity
	callx4	a4
#endif
4:	/* Restore optional registers. */
4:
#ifdef CONFIG_TRACE_IRQFLAGS
	l32i	a4, a1, PT_DEPC
	/* Double exception means we came here with an exception
	 * while PS.EXCM was set, i.e. interrupts disabled.
	 */
	bgeui	a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
	l32i	a4, a1, PT_EXCCAUSE
	bnei	a4, EXCCAUSE_LEVEL1_INTERRUPT, 1f
	/* We came here with an interrupt means interrupts were enabled
	 * and we'll reenable them on return.
	 */
	movi	a4, trace_hardirqs_on
	callx4	a4
1:
#endif
	/* Restore optional registers. */

	load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT