Ejemplo n.º 1
0
static int ia32_restore_sigcontext(struct pt_regs *regs,
				   struct sigcontext_ia32 __user *sc,
				   unsigned int *peax)
{
	unsigned int tmpflags, gs, oldgs, err = 0;
	void __user *buf;
	u32 tmp;

	/* Always make any pending restarted system calls return -EINTR */
	current_thread_info()->restart_block.fn = do_no_restart_syscall;

#if DEBUG_SIG
	printk(KERN_DEBUG "SIG restore_sigcontext: "
	       "sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
	       sc, sc->err, sc->ip, sc->cs, sc->flags);
#endif

	/*
	 * Reload fs and gs if they have changed in the signal
	 * handler.  This does not handle long fs/gs base changes in
	 * the handler, but does not clobber them at least in the
	 * normal case.
	 */
	err |= __get_user(gs, &sc->gs);
	gs |= 3;
	savesegment(gs, oldgs);
	if (gs != oldgs)
		load_gs_index(gs);

	RELOAD_SEG(fs, 3);
	RELOAD_SEG(ds, 3);
	RELOAD_SEG(es, 3);

	COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
	COPY(dx); COPY(cx); COPY(ip);
	/* Don't touch extended registers */

	err |= __get_user(regs->cs, &sc->cs);
	regs->cs |= 3;
	err |= __get_user(regs->ss, &sc->ss);
	regs->ss |= 3;

	err |= __get_user(tmpflags, &sc->flags);
	regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
	/* disable syscall checks */
	regs->orig_ax = -1;

	err |= __get_user(tmp, &sc->fpstate);
	buf = compat_ptr(tmp);
	err |= restore_i387_xstate_ia32(buf);

	err |= __get_user(tmp, &sc->ax);
	*peax = tmp;

	return err;
}
Ejemplo n.º 2
0
static int ia32_restore_sigcontext(struct pt_regs *regs,
                                   struct sigcontext_ia32 __user *sc,
                                   unsigned int *pax)
{
    unsigned int tmpflags, err = 0;
    void __user *buf;
    u32 tmp;

    /* Always make any pending restarted system calls return -EINTR */
    current_thread_info()->restart_block.fn = do_no_restart_syscall;

    get_user_try {
        /*
         * Reload fs and gs if they have changed in the signal
         * handler.  This does not handle long fs/gs base changes in
         * the handler, but does not clobber them at least in the
         * normal case.
         */
        RELOAD_SEG(gs);
        RELOAD_SEG(fs);
        RELOAD_SEG(ds);
        RELOAD_SEG(es);

        COPY(di);
        COPY(si);
        COPY(bp);
        COPY(sp);
        COPY(bx);
        COPY(dx);
        COPY(cx);
        COPY(ip);
        /* Don't touch extended registers */

        COPY_SEG_CPL3(cs);
        COPY_SEG_CPL3(ss);

        get_user_ex(tmpflags, &sc->flags);
        regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
        /* disable syscall checks */
        regs->orig_ax = -1;

        get_user_ex(tmp, &sc->fpstate);
        buf = compat_ptr(tmp);
        err |= restore_i387_xstate_ia32(buf);

        get_user_ex(*pax, &sc->ax);
    } get_user_catch(err);

    return err;
}
Ejemplo n.º 3
0
static int ia32_restore_sigcontext(struct pt_regs *regs,
				   struct sigcontext_ia32 __user *sc,
				   unsigned int *pax)
{
	unsigned int tmpflags, err = 0;
	void __user *buf;
	u32 tmp;

	
	current_thread_info()->restart_block.fn = do_no_restart_syscall;

	get_user_try {
		RELOAD_SEG(gs);
		RELOAD_SEG(fs);
		RELOAD_SEG(ds);
		RELOAD_SEG(es);

		COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
		COPY(dx); COPY(cx); COPY(ip);
		

		COPY_SEG_CPL3(cs);
		COPY_SEG_CPL3(ss);

		get_user_ex(tmpflags, &sc->flags);
		regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
		
		regs->orig_ax = -1;

		get_user_ex(tmp, &sc->fpstate);
		buf = compat_ptr(tmp);
		err |= restore_i387_xstate_ia32(buf);

		get_user_ex(*pax, &sc->ax);
	} get_user_catch(err);

	return err;
}