PageRenderTime 26ms CodeModel.GetById 11ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/mips/kernel/signal-common.h

https://bitbucket.org/evzijst/gittest
C Header | 137 lines | 86 code | 25 blank | 26 comment | 8 complexity | bd52034189ff4b1413a51709c6821571 MD5 | raw file
  1/*
  2 * This file is subject to the terms and conditions of the GNU General Public
  3 * License.  See the file "COPYING" in the main directory of this archive
  4 * for more details.
  5 *
  6 * Copyright (C) 1991, 1992  Linus Torvalds
  7 * Copyright (C) 1994 - 2000  Ralf Baechle
  8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  9 */
 10
 11static inline int
 12setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
 13{
 14	int err = 0;
 15
 16	err |= __put_user(regs->cp0_epc, &sc->sc_pc);
 17	err |= __put_user(regs->cp0_status, &sc->sc_status);
 18
 19#define save_gp_reg(i) do {						\
 20	err |= __put_user(regs->regs[i], &sc->sc_regs[i]);		\
 21} while(0)
 22	__put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2);
 23	save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
 24	save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
 25	save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
 26	save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
 27	save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
 28	save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
 29	save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
 30	save_gp_reg(31);
 31#undef save_gp_reg
 32
 33	err |= __put_user(regs->hi, &sc->sc_mdhi);
 34	err |= __put_user(regs->lo, &sc->sc_mdlo);
 35	err |= __put_user(regs->cp0_cause, &sc->sc_cause);
 36	err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr);
 37
 38	err |= __put_user(!!used_math(), &sc->sc_used_math);
 39
 40	if (!used_math())
 41		goto out;
 42
 43	/*
 44	 * Save FPU state to signal context.  Signal handler will "inherit"
 45	 * current FPU state.
 46	 */
 47	preempt_disable();
 48
 49	if (!is_fpu_owner()) {
 50		own_fpu();
 51		restore_fp(current);
 52	}
 53	err |= save_fp_context(sc);
 54
 55	preempt_enable();
 56
 57out:
 58	return err;
 59}
 60
 61static inline int
 62restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
 63{
 64	int err = 0;
 65	unsigned int used_math;
 66
 67	/* Always make any pending restarted system calls return -EINTR */
 68	current_thread_info()->restart_block.fn = do_no_restart_syscall;
 69
 70	err |= __get_user(regs->cp0_epc, &sc->sc_pc);
 71	err |= __get_user(regs->hi, &sc->sc_mdhi);
 72	err |= __get_user(regs->lo, &sc->sc_mdlo);
 73
 74#define restore_gp_reg(i) do {						\
 75	err |= __get_user(regs->regs[i], &sc->sc_regs[i]);		\
 76} while(0)
 77	restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
 78	restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
 79	restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
 80	restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
 81	restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
 82	restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
 83	restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
 84	restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
 85	restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
 86	restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
 87	restore_gp_reg(31);
 88#undef restore_gp_reg
 89
 90	err |= __get_user(used_math, &sc->sc_used_math);
 91	conditional_used_math(used_math);
 92
 93	preempt_disable();
 94
 95	if (used_math()) {
 96		/* restore fpu context if we have used it before */
 97		own_fpu();
 98		err |= restore_fp_context(sc);
 99	} else {
100		/* signal handler may have used FPU.  Give it up. */
101		lose_fpu();
102	}
103
104	preempt_enable();
105
106	return err;
107}
108
109/*
110 * Determine which stack to use..
111 */
112static inline void *
113get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
114{
115	unsigned long sp, almask;
116
117	/* Default to using normal stack */
118	sp = regs->regs[29];
119
120	/*
121 	 * FPU emulator may have it's own trampoline active just
122 	 * above the user stack, 16-bytes before the next lowest
123 	 * 16 byte boundary.  Try to avoid trashing it.
124 	 */
125 	sp -= 32;
126
127	/* This is the X/Open sanctioned signal stack switching.  */
128	if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
129		sp = current->sas_ss_sp + current->sas_ss_size;
130
131	if (PLAT_TRAMPOLINE_STUFF_LINE)
132		almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1);
133	else
134		almask = ALMASK;
135
136	return (void *)((sp - frame_size) & almask);
137}