#include <linux/ptrace.h>
#include <linux/suspend.h>
#include <linux/unistd.h>
+#include <linux/compiler.h>
#include <asm/asm.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
#include <asm/cacheflush.h>
#include <asm/fpu.h>
#include <asm/sim.h>
#ifdef CONFIG_TRAD_SIGNALS
save_static_function(sys_sigsuspend);
-static_unused int _sys_sigsuspend(struct pt_regs regs)
+__attribute_used__ noinline static int
+_sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
{
sigset_t *uset, saveset, newset;
#endif
save_static_function(sys_rt_sigsuspend);
-static_unused int _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
+__attribute_used__ noinline static int
+_sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
{
sigset_t *unewset, saveset, newset;
size_t sigsetsize;
err |= __get_user(current->used_math, &sc->sc_used_math);
+ preempt_disable();
+
if (current->used_math) {
/* restore fpu context if we have used it before */
own_fpu();
lose_fpu();
}
+ preempt_enable();
+
return err;
}
+#if PLAT_TRAMPOLINE_STUFF_LINE
+#define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE)))
+#else
+#define __tramp
+#endif
+
#ifdef CONFIG_TRAD_SIGNALS
struct sigframe {
u32 sf_ass[4]; /* argument save space for o32 */
- u32 sf_code[2]; /* signal trampoline */
- struct sigcontext sf_sc;
+ u32 sf_code[2] __tramp; /* signal trampoline */
+ struct sigcontext sf_sc __tramp;
sigset_t sf_mask;
};
#endif
struct rt_sigframe {
u32 rs_ass[4]; /* argument save space for o32 */
- u32 rs_code[2]; /* signal trampoline */
- struct siginfo rs_info;
+ u32 rs_code[2] __tramp; /* signal trampoline */
+ struct siginfo rs_info __tramp;
struct ucontext rs_uc;
};
* Save FPU state to signal context. Signal handler will "inherit"
* current FPU state.
*/
+ preempt_disable();
+
if (!is_fpu_owner()) {
own_fpu();
restore_fp(current);
}
err |= save_fp_context(sc);
+ preempt_enable();
+
out:
return err;
}
static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
size_t frame_size)
{
- unsigned long sp;
+ unsigned long sp, almask;
/* Default to using normal stack */
sp = regs->regs[29];
if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
sp = current->sas_ss_sp + current->sas_ss_size;
- return (void *)((sp - frame_size) & ALMASK);
+ if (PLAT_TRAMPOLINE_STUFF_LINE)
+ almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1);
+ else
+ almask = ALMASK;
+
+ return (void *)((sp - frame_size) & ~(PLAT_TRAMPOLINE_STUFF_LINE - 1));
}
#ifdef CONFIG_TRAD_SIGNALS
* li v0, __NR_sigreturn
* syscall
*/
+ if (PLAT_TRAMPOLINE_STUFF_LINE)
+ __builtin_memset(frame->sf_code, '0',
+ 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);
* li v0, __NR_rt_sigreturn
* syscall
*/
+ if (PLAT_TRAMPOLINE_STUFF_LINE)
+ __builtin_memset(frame->rs_code, '0',
+ 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);
setup_frame(ka, regs, sig, oldset);
#endif
- if (ka->sa.sa_flags & SA_ONESHOT)
- ka->sa.sa_handler = SIG_DFL;
if (!(ka->sa.sa_flags & SA_NODEFER)) {
spin_lock_irq(¤t->sighand->siglock);
sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask);