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

Commit 02416dcf authored by Ralf Baechle's avatar Ralf Baechle
Browse files

Redo RM9000 workaround which along with other DSP ASE changes was


causing some headache for debuggers knowing about signal frames.

Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent aac8aa77
Loading
Loading
Loading
Loading
+28 −6
Original line number Diff line number Diff line
@@ -160,7 +160,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
static inline void *
get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
{
	unsigned long sp, almask;
	unsigned long sp;

	/* Default to using normal stack */
	sp = regs->regs[29];
@@ -176,10 +176,32 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
	if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
		sp = current->sas_ss_sp + current->sas_ss_size;

	if (PLAT_TRAMPOLINE_STUFF_LINE)
		almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1);
	else
		almask = ALMASK;
	return (void *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK));
}

static inline int install_sigtramp(unsigned int __user *tramp,
	unsigned int syscall)
{
	int err;

	/*
	 * Set up the return code ...
	 *
	 *         li      v0, __NR__foo_sigreturn
	 *         syscall
	 */

	return (void *)((sp - frame_size) & almask);
	err = __put_user(0x24020000 + syscall, tramp + 0);
	err |= __put_user(0x0000000c          , tramp + 1);
	if (ICACHE_REFILLS_WORKAROUND_WAR) {
		err |= __put_user(0, tramp + 2);
		err |= __put_user(0, tramp + 3);
		err |= __put_user(0, tramp + 4);
		err |= __put_user(0, tramp + 5);
		err |= __put_user(0, tramp + 6);
		err |= __put_user(0, tramp + 7);
	}
	flush_cache_sigtramp((unsigned long) tramp);

	return err;
}
+27 −32
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
 */
#include <linux/config.h>
#include <linux/cache.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/personality.h>
@@ -30,6 +31,7 @@
#include <asm/uaccess.h>
#include <asm/ucontext.h>
#include <asm/cpu-features.h>
#include <asm/war.h>

#include "signal-common.h"

@@ -157,26 +159,39 @@ asmlinkage int sys_sigaltstack(nabi_no_regargs struct pt_regs regs)
	return do_sigaltstack(uss, uoss, usp);
}

#if PLAT_TRAMPOLINE_STUFF_LINE
#define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))
#else
#define __tramp
#endif

/*
 * Horribly complicated - with the bloody RM9000 workarounds enabled
 * the signal trampolines is moving to the end of the structure so we can
 * increase the alignment without breaking software compatibility.
 */
#ifdef CONFIG_TRAD_SIGNALS
struct sigframe {
	u32 sf_ass[4];			/* argument save space for o32 */
	u32 sf_code[2] __tramp;		/* signal trampoline */
	struct sigcontext sf_sc __tramp;
#if ICACHE_REFILLS_WORKAROUND_WAR
	u32 sf_pad[2];
#else
	u32 sf_code[2];			/* signal trampoline */
#endif
	struct sigcontext sf_sc;
	sigset_t sf_mask;
#if ICACHE_REFILLS_WORKAROUND_WAR
	u32 sf_code[8] ____cacheline_aligned;	/* signal trampoline */
#endif
};
#endif

struct rt_sigframe {
	u32 rs_ass[4];			/* argument save space for o32 */
	u32 rs_code[2] __tramp;		/* signal trampoline */
	struct siginfo rs_info __tramp;
#if ICACHE_REFILLS_WORKAROUND_WAR
	u32 rs_pad[2];
#else
	u32 rs_code[2];			/* signal trampoline */
#endif
	struct siginfo rs_info;
	struct ucontext rs_uc;
#if ICACHE_REFILLS_WORKAROUND_WAR
	u32 rs_code[8] ____cacheline_aligned;	/* signal trampoline */
#endif
};

#ifdef CONFIG_TRAD_SIGNALS
@@ -273,17 +288,7 @@ void setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
		goto give_sigsegv;

	/*
	 * Set up the return code ...
	 *
	 *         li      v0, __NR_sigreturn
	 *         syscall
	 */
	if (PLAT_TRAMPOLINE_STUFF_LINE)
		__clear_user(frame->sf_code, PLAT_TRAMPOLINE_STUFF_LINE);
	err |= __put_user(0x24020000 + __NR_sigreturn, frame->sf_code + 0);
	err |= __put_user(0x0000000c                 , frame->sf_code + 1);
	flush_cache_sigtramp((unsigned long) frame->sf_code);
	install_sigtramp(frame->sf_code, __NR_sigreturn);

	err |= setup_sigcontext(regs, &frame->sf_sc);
	err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
@@ -329,17 +334,7 @@ void setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
		goto give_sigsegv;

	/*
	 * Set up the return code ...
	 *
	 *         li      v0, __NR_rt_sigreturn
	 *         syscall
	 */
	if (PLAT_TRAMPOLINE_STUFF_LINE)
		__clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);
	err |= __put_user(0x24020000 + __NR_rt_sigreturn, frame->rs_code + 0);
	err |= __put_user(0x0000000c                    , frame->rs_code + 1);
	flush_cache_sigtramp((unsigned long) frame->rs_code);
	install_sigtramp(frame->rs_code, __NR_rt_sigreturn);

	/* Create siginfo.  */
	err |= copy_siginfo_to_user(&frame->rs_info, info);
+16 −0
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
 * Copyright (C) 1994 - 2000  Ralf Baechle
 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
 */
#include <linux/cache.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
@@ -30,6 +31,7 @@
#include <asm/ucontext.h>
#include <asm/system.h>
#include <asm/fpu.h>
#include <asm/war.h>

#define SI_PAD_SIZE32   ((SI_MAX_SIZE/sizeof(int)) - 3)

@@ -392,16 +394,30 @@ static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc)

struct sigframe {
	u32 sf_ass[4];			/* argument save space for o32 */
#if ICACHE_REFILLS_WORKAROUND_WAR
	u32 sf_pad[2];
#else
	u32 sf_code[2];			/* signal trampoline */
#endif
	struct sigcontext32 sf_sc;
	sigset_t sf_mask;
#if ICACHE_REFILLS_WORKAROUND_WAR
	u32 sf_code[8] ____cacheline_aligned;	/* signal trampoline */
#endif
};

struct rt_sigframe32 {
	u32 rs_ass[4];			/* argument save space for o32 */
#if ICACHE_REFILLS_WORKAROUND_WAR
	u32 rs_pad[2];
#else
	u32 rs_code[2];			/* signal trampoline */
#endif
	compat_siginfo_t rs_info;
	struct ucontext32 rs_uc;
#if ICACHE_REFILLS_WORKAROUND_WAR
	u32 rs_code[8] __attribute__((aligned(32)));	/* signal trampoline */
#endif
};

int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from)
+13 −19
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
#include <linux/cache.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/smp.h>
@@ -36,6 +38,7 @@
#include <asm/system.h>
#include <asm/fpu.h>
#include <asm/cpu-features.h>
#include <asm/war.h>

#include "signal-common.h"

@@ -62,17 +65,18 @@ struct ucontextn32 {
	sigset_t            uc_sigmask;   /* mask last for extensibility */
};

#if PLAT_TRAMPOLINE_STUFF_LINE
#define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))
#else
#define __tramp
#endif

struct rt_sigframe_n32 {
	u32 rs_ass[4];			/* argument save space for o32 */
	u32 rs_code[2] __tramp;		/* signal trampoline */
	struct siginfo rs_info __tramp;
#if ICACHE_REFILLS_WORKAROUND_WAR
	u32 rs_pad[2];
#else
	u32 rs_code[2];			/* signal trampoline */
#endif
	struct siginfo rs_info;
	struct ucontextn32 rs_uc;
#if ICACHE_REFILLS_WORKAROUND_WAR
	u32 rs_code[8] ____cacheline_aligned;		/* signal trampoline */
#endif
};

save_static_function(sysn32_rt_sigreturn);
@@ -137,17 +141,7 @@ void setup_rt_frame_n32(struct k_sigaction * ka,
	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
		goto give_sigsegv;

	/*
	 * Set up the return code ...
	 *
	 *         li      v0, __NR_rt_sigreturn
	 *         syscall
	 */
	if (PLAT_TRAMPOLINE_STUFF_LINE)
		__clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE);
	err |= __put_user(0x24020000 + __NR_N32_rt_sigreturn, frame->rs_code + 0);
	err |= __put_user(0x0000000c                        , frame->rs_code + 1);
	flush_cache_sigtramp((unsigned long) frame->rs_code);
	install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn);

	/* Create siginfo.  */
	err |= copy_siginfo_to_user(&frame->rs_info, info);
+0 −11
Original line number Diff line number Diff line
@@ -109,17 +109,6 @@
#define cpu_has_dsp		(cpu_data[0].ases & MIPS_ASE_DSP)
#endif

/*
 * Certain CPUs may throw bizarre exceptions if not the whole cacheline
 * contains valid instructions.  For these we ensure proper alignment of
 * signal trampolines and pad them to the size of a full cache lines with
 * nops.  This is also used in structure definitions so can't be a test macro
 * like the others.
 */
#ifndef PLAT_TRAMPOLINE_STUFF_LINE
#define PLAT_TRAMPOLINE_STUFF_LINE	0UL
#endif

#ifdef CONFIG_32BIT
# ifndef cpu_has_nofpuex
# define cpu_has_nofpuex	(cpu_data[0].options & MIPS_CPU_NOFPUEX)
Loading