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

Commit 4a177cbf authored by Alexey Dobriyan's avatar Alexey Dobriyan Committed by Tony Luck
Browse files

[IA64] Add TIF_RESTORE_SIGMASK



Preparation for pselect and ppoll.
ia32 compat code not tested. :-(

Signed-off-by: default avatarAlexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Signed-off-by: default avatarAlexey Dobriyan <adobriyan@openvz.org>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent 690def21
Loading
Loading
Loading
Loading
+1 −38
Original line number Diff line number Diff line
@@ -52,43 +52,6 @@ ENTRY(ia32_clone)
	br.ret.sptk.many rp
END(ia32_clone)

ENTRY(sys32_rt_sigsuspend)
	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
	alloc loc1=ar.pfs,8,2,3,0		// preserve all eight input regs
	mov loc0=rp
	mov out0=in0				// mask
	mov out1=in1				// sigsetsize
	mov out2=sp				// out2 = &sigscratch
	.fframe 16
	adds sp=-16,sp				// allocate dummy "sigscratch"
	;;
	.body
	br.call.sptk.many rp=ia32_rt_sigsuspend
1:	.restore sp
	adds sp=16,sp
	mov rp=loc0
	mov ar.pfs=loc1
	br.ret.sptk.many rp
END(sys32_rt_sigsuspend)

ENTRY(sys32_sigsuspend)
	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
	alloc loc1=ar.pfs,8,2,3,0		// preserve all eight input regs
	mov loc0=rp
	mov out0=in2				// mask (first two args are ignored)
	;;
	mov out1=sp				// out1 = &sigscratch
	.fframe 16
	adds sp=-16,sp				// allocate dummy "sigscratch"
	.body
	br.call.sptk.many rp=ia32_sigsuspend
1:	.restore sp
	adds sp=16,sp
	mov rp=loc0
	mov ar.pfs=loc1
	br.ret.sptk.many rp
END(sys32_sigsuspend)

GLOBAL_ENTRY(ia32_ret_from_clone)
	PT_REGS_UNWIND_INFO(0)
{	/*
@@ -389,7 +352,7 @@ ia32_syscall_table:
	data8 sys_rt_sigpending
	data8 compat_sys_rt_sigtimedwait
	data8 sys32_rt_sigqueueinfo
	data8 sys32_rt_sigsuspend
	data8 compat_sys_rt_sigsuspend
	data8 sys32_pread	  /* 180 */
	data8 sys32_pwrite
	data8 sys_chown	/* 16-bit version */
+10 −49
Original line number Diff line number Diff line
@@ -452,59 +452,20 @@ sigact_set_handler (struct k_sigaction *sa, unsigned int handler, unsigned int r
		sa->sa.sa_handler = (__sighandler_t) (((unsigned long) restorer << 32) | handler);
}

long
__ia32_rt_sigsuspend (compat_sigset_t *sset, unsigned int sigsetsize, struct sigscratch *scr)
asmlinkage long
sys32_sigsuspend (int history0, int history1, old_sigset_t mask)
{
	extern long ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall);
	sigset_t oldset, set;

	scr->scratch_unat = 0;	/* avoid leaking kernel bits to user level */
	memset(&set, 0, sizeof(set));

	memcpy(&set.sig, &sset->sig, sigsetsize);

	sigdelsetmask(&set, ~_BLOCKABLE);

	mask &= _BLOCKABLE;
	spin_lock_irq(&current->sighand->siglock);
	{
		oldset = current->blocked;
		current->blocked = set;
	current->saved_sigmask = current->blocked;
	siginitset(&current->blocked, mask);
	recalc_sigpending();
	}
	spin_unlock_irq(&current->sighand->siglock);

	/*
	 * The return below usually returns to the signal handler.  We need to pre-set the
	 * correct error code here to ensure that the right values get saved in sigcontext
	 * by ia64_do_signal.
	 */
	scr->pt.r8 = -EINTR;
	while (1) {
	current->state = TASK_INTERRUPTIBLE;
	schedule();
		if (ia64_do_signal(&oldset, scr, 1))
			return -EINTR;
	}
}

asmlinkage long
ia32_rt_sigsuspend (compat_sigset_t __user *uset, unsigned int sigsetsize, struct sigscratch *scr)
{
	compat_sigset_t set;

	if (sigsetsize > sizeof(compat_sigset_t))
		return -EINVAL;

	if (copy_from_user(&set.sig, &uset->sig, sigsetsize))
		return -EFAULT;

	return __ia32_rt_sigsuspend(&set, sigsetsize, scr);
}

asmlinkage long
ia32_sigsuspend (unsigned int mask, struct sigscratch *scr)
{
	return __ia32_rt_sigsuspend((compat_sigset_t *) &mask, sizeof(mask), scr);
	set_thread_flag(TIF_RESTORE_SIGMASK);
	return -ERESTARTNOHAND;
}

asmlinkage long
+0 −26
Original line number Diff line number Diff line
@@ -1199,32 +1199,6 @@ ENTRY(notify_resume_user)
	br.ret.sptk.many rp
END(notify_resume_user)

GLOBAL_ENTRY(sys_rt_sigsuspend)
	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
	alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall restart!
	mov r9=ar.unat
	mov loc0=rp				// save return address
	mov out0=in0				// mask
	mov out1=in1				// sigsetsize
	adds out2=8,sp				// out2=&sigscratch->ar_pfs
	;;
	.fframe 16
	.spillsp ar.unat, 16
	st8 [sp]=r9,-16				// allocate space for ar.unat and save it
	st8 [out2]=loc1,-8			// save ar.pfs, out2=&sigscratch
	.body
	br.call.sptk.many rp=ia64_rt_sigsuspend
.ret17:	.restore sp
	adds sp=16,sp				// pop scratch stack space
	;;
	ld8 r9=[sp]				// load new unat from sw->caller_unat
	mov rp=loc0
	;;
	mov ar.unat=r9
	mov ar.pfs=loc1
	br.ret.sptk.many rp
END(sys_rt_sigsuspend)

ENTRY(sys_rt_sigreturn)
	PT_REGS_UNWIND_INFO(0)
	/*
+3 −3
Original line number Diff line number Diff line
@@ -156,7 +156,7 @@ show_regs (struct pt_regs *regs)
}

void
do_notify_resume_user (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
do_notify_resume_user (sigset_t *unused, struct sigscratch *scr, long in_syscall)
{
	if (fsys_mode(current, &scr->pt)) {
		/* defer signal-handling etc. until we return to privilege-level 0.  */
@@ -171,8 +171,8 @@ do_notify_resume_user (sigset_t *oldset, struct sigscratch *scr, long in_syscall
#endif

	/* deal with pending signal delivery */
	if (test_thread_flag(TIF_SIGPENDING))
		ia64_do_signal(oldset, scr, in_syscall);
	if (test_thread_flag(TIF_SIGPENDING)||test_thread_flag(TIF_RESTORE_SIGMASK))
		ia64_do_signal(scr, in_syscall);
}

static int pal_halt        = 1;
+1 −1
Original line number Diff line number Diff line
@@ -22,4 +22,4 @@ struct sigframe {
	struct sigcontext sc;
};

extern long ia64_do_signal (sigset_t *, struct sigscratch *, long);
extern void ia64_do_signal (struct sigscratch *, long);
Loading