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

Commit 39d6411b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull two Tile arch fixes from Chris Metcalf:
 "These are both bug-fixes, one to avoid some issues in how we invoke
  the "pending userspace work" flags on return to userspace, and the
  other to provide the same signal handler arguments for tilegx32 that
  we do for tilegx64."

* 'stable' of git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile:
  arch/tile: apply commit 74fca9da to the compat signal handling as well
  arch/tile: fix up some issues in calling do_work_pending()
parents 80116529 a134d228
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -100,9 +100,14 @@ extern void cpu_idle_on_new_stack(struct thread_info *old_ti,

#else /* __ASSEMBLY__ */

/* how to get the thread information struct from ASM */
/*
 * How to get the thread information struct from assembly.
 * Note that we use different macros since different architectures
 * have different semantics in their "mm" instruction and we would
 * like to guarantee that the macro expands to exactly one instruction.
 */
#ifdef __tilegx__
#define GET_THREAD_INFO(reg) move reg, sp; mm reg, zero, LOG2_THREAD_SIZE, 63
#define EXTRACT_THREAD_INFO(reg) mm reg, zero, LOG2_THREAD_SIZE, 63
#else
#define GET_THREAD_INFO(reg) mm reg, sp, zero, LOG2_THREAD_SIZE, 31
#endif
+5 −7
Original line number Diff line number Diff line
@@ -403,19 +403,17 @@ int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
	 * Set up registers for signal handler.
	 * Registers that we don't modify keep the value they had from
	 * user-space at the time we took the signal.
	 * We always pass siginfo and mcontext, regardless of SA_SIGINFO,
	 * since some things rely on this (e.g. glibc's debug/segfault.c).
	 */
	regs->pc = ptr_to_compat_reg(ka->sa.sa_handler);
	regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
	regs->sp = ptr_to_compat_reg(frame);
	regs->lr = restorer;
	regs->regs[0] = (unsigned long) usig;

	if (ka->sa.sa_flags & SA_SIGINFO) {
		/* Need extra arguments, so mark to restore caller-saves. */
	regs->regs[1] = ptr_to_compat_reg(&frame->info);
	regs->regs[2] = ptr_to_compat_reg(&frame->uc);
	regs->flags |= PT_FLAGS_CALLER_SAVES;
	}

	/*
	 * Notify any tracer that was single-stepping it.
+28 −13
Original line number Diff line number Diff line
@@ -838,6 +838,18 @@ STD_ENTRY(interrupt_return)
.Lresume_userspace:
	FEEDBACK_REENTER(interrupt_return)

	/*
	 * Use r33 to hold whether we have already loaded the callee-saves
	 * into ptregs.  We don't want to do it twice in this loop, since
	 * then we'd clobber whatever changes are made by ptrace, etc.
	 * Get base of stack in r32.
	 */
	{
	 GET_THREAD_INFO(r32)
	 movei  r33, 0
	}

.Lretry_work_pending:
	/*
	 * Disable interrupts so as to make sure we don't
	 * miss an interrupt that sets any of the thread flags (like
@@ -848,9 +860,6 @@ STD_ENTRY(interrupt_return)
	IRQ_DISABLE(r20, r21)
	TRACE_IRQS_OFF  /* Note: clobbers registers r0-r29 */

	/* Get base of stack in r32; note r30/31 are used as arguments here. */
	GET_THREAD_INFO(r32)


	/* Check to see if there is any work to do before returning to user. */
	{
@@ -866,16 +875,18 @@ STD_ENTRY(interrupt_return)

	/*
	 * Make sure we have all the registers saved for signal
	 * handling or single-step.  Call out to C code to figure out
	 * exactly what we need to do for each flag bit, then if
	 * necessary, reload the flags and recheck.
	 * handling, notify-resume, or single-step.  Call out to C
	 * code to figure out exactly what we need to do for each flag bit,
	 * then if necessary, reload the flags and recheck.
	 */
	push_extra_callee_saves r0
	{
	 PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
	 jal    do_work_pending
	 bnz    r33, 1f
	}
	bnz     r0, .Lresume_userspace
	push_extra_callee_saves r0
	movei   r33, 1
1:	jal     do_work_pending
	bnz     r0, .Lretry_work_pending

	/*
	 * In the NMI case we
@@ -1180,10 +1191,12 @@ handle_syscall:
	add     r20, r20, tp
	lw      r21, r20
	addi    r21, r21, 1
	{
	 sw     r20, r21
	 GET_THREAD_INFO(r31)
	}

	/* Trace syscalls, if requested. */
	GET_THREAD_INFO(r31)
	addi	r31, r31, THREAD_INFO_FLAGS_OFFSET
	lw	r30, r31
	andi    r30, r30, _TIF_SYSCALL_TRACE
@@ -1362,7 +1375,10 @@ handle_ill:
3:
	/* set PC and continue */
	lw      r26, r24
	{
	 sw     r28, r26
	 GET_THREAD_INFO(r0)
	}

	/*
	 * Clear TIF_SINGLESTEP to prevent recursion if we execute an ill.
@@ -1370,7 +1386,6 @@ handle_ill:
	 * need to clear it here and can't really impose on all other arches.
	 * So what's another write between friends?
	 */
	GET_THREAD_INFO(r0)

	addi    r1, r0, THREAD_INFO_FLAGS_OFFSET
	{
+28 −10
Original line number Diff line number Diff line
@@ -646,6 +646,20 @@ STD_ENTRY(interrupt_return)
.Lresume_userspace:
	FEEDBACK_REENTER(interrupt_return)

	/*
	 * Use r33 to hold whether we have already loaded the callee-saves
	 * into ptregs.  We don't want to do it twice in this loop, since
	 * then we'd clobber whatever changes are made by ptrace, etc.
	 */
	{
	 movei  r33, 0
	 move   r32, sp
	}

	/* Get base of stack in r32. */
	EXTRACT_THREAD_INFO(r32)

.Lretry_work_pending:
	/*
	 * Disable interrupts so as to make sure we don't
	 * miss an interrupt that sets any of the thread flags (like
@@ -656,9 +670,6 @@ STD_ENTRY(interrupt_return)
	IRQ_DISABLE(r20, r21)
	TRACE_IRQS_OFF  /* Note: clobbers registers r0-r29 */

	/* Get base of stack in r32; note r30/31 are used as arguments here. */
	GET_THREAD_INFO(r32)


	/* Check to see if there is any work to do before returning to user. */
	{
@@ -674,16 +685,18 @@ STD_ENTRY(interrupt_return)

	/*
	 * Make sure we have all the registers saved for signal
	 * handling or single-step.  Call out to C code to figure out
	 * handling or notify-resume.  Call out to C code to figure out
	 * exactly what we need to do for each flag bit, then if
	 * necessary, reload the flags and recheck.
	 */
	push_extra_callee_saves r0
	{
	 PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
	 jal    do_work_pending
	 bnez   r33, 1f
	}
	bnez    r0, .Lresume_userspace
	push_extra_callee_saves r0
	movei   r33, 1
1:	jal     do_work_pending
	bnez    r0, .Lretry_work_pending

	/*
	 * In the NMI case we
@@ -968,11 +981,16 @@ handle_syscall:
	shl16insli r20, r20, hw0(irq_stat + IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET)
	add     r20, r20, tp
	ld4s    r21, r20
	{
	 addi   r21, r21, 1
	 move   r31, sp
	}
	{
	 st4    r20, r21
	 EXTRACT_THREAD_INFO(r31)
	}

	/* Trace syscalls, if requested. */
	GET_THREAD_INFO(r31)
	addi	r31, r31, THREAD_INFO_FLAGS_OFFSET
	ld	r30, r31
	andi    r30, r30, _TIF_SYSCALL_TRACE
+5 −2
Original line number Diff line number Diff line
@@ -567,6 +567,10 @@ struct task_struct *__sched _switch_to(struct task_struct *prev,
 */
int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
{
	/* If we enter in kernel mode, do nothing and exit the caller loop. */
	if (!user_mode(regs))
		return 0;

	if (thread_info_flags & _TIF_NEED_RESCHED) {
		schedule();
		return 1;
@@ -589,7 +593,6 @@ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
		return 1;
	}
	if (thread_info_flags & _TIF_SINGLESTEP) {
		if ((regs->ex1 & SPR_EX_CONTEXT_1_1__PL_MASK) == 0)
		single_step_once(regs);
		return 0;
	}