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

Commit b927b3e2 authored by Richard Henderson's avatar Richard Henderson Committed by Linus Torvalds
Browse files

alpha: support new syscalls



Some of the new syscalls require supporting TIF_RESTORE_SIGMASK.

Signed-off-by: default avatarRichard Henderson <rth@twiddle.net>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 74fd1b68
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -391,11 +391,10 @@ $work_resched:
	bne	$2, $work_resched

$work_notifysig:
	mov	$sp, $17
	mov	$sp, $16
	br	$1, do_switch_stack
	mov	$5, $21
	mov	$sp, $18
	mov	$31, $16
	mov	$sp, $17
	mov	$5, $18
	jsr	$26, do_notify_resume
	bsr	$1, undo_switch_stack
	br	restore_all
+63 −47
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))

asmlinkage void ret_from_sys_call(void);
static int do_signal(sigset_t *, struct pt_regs *, struct switch_stack *,
static void do_signal(struct pt_regs *, struct switch_stack *,
		      unsigned long, unsigned long);


@@ -146,11 +146,9 @@ sys_rt_sigaction(int sig, const struct sigaction __user *act,
asmlinkage int
do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw)
{
	sigset_t oldset;

	mask &= _BLOCKABLE;
	spin_lock_irq(&current->sighand->siglock);
	oldset = current->blocked;
	current->saved_sigmask = current->blocked;
	siginitset(&current->blocked, mask);
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);
@@ -160,19 +158,17 @@ do_sigsuspend(old_sigset_t mask, struct pt_regs *regs, struct switch_stack *sw)
	regs->r0 = EINTR;
	regs->r19 = 1;

	while (1) {
	current->state = TASK_INTERRUPTIBLE;
	schedule();
		if (do_signal(&oldset, regs, sw, 0, 0))
			return -EINTR;
	}
	set_thread_flag(TIF_RESTORE_SIGMASK);
	return -ERESTARTNOHAND;
}

asmlinkage int
do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize,
		 struct pt_regs *regs, struct switch_stack *sw)
{
	sigset_t oldset, set;
	sigset_t set;

	/* XXX: Don't preclude handling different sized sigset_t's.  */
	if (sigsetsize != sizeof(sigset_t))
@@ -182,7 +178,7 @@ do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize,

	sigdelsetmask(&set, ~_BLOCKABLE);
	spin_lock_irq(&current->sighand->siglock);
	oldset = current->blocked;
	current->saved_sigmask = current->blocked;
	current->blocked = set;
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);
@@ -192,12 +188,10 @@ do_rt_sigsuspend(sigset_t __user *uset, size_t sigsetsize,
	regs->r0 = EINTR;
	regs->r19 = 1;

	while (1) {
	current->state = TASK_INTERRUPTIBLE;
	schedule();
		if (do_signal(&oldset, regs, sw, 0, 0))
			return -EINTR;
	}
	set_thread_flag(TIF_RESTORE_SIGMASK);
	return -ERESTARTNOHAND;
}

asmlinkage int
@@ -436,7 +430,7 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
	return err;
}

static void
static int
setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
	    struct pt_regs *regs, struct switch_stack * sw)
{
@@ -481,13 +475,14 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
		current->comm, current->pid, frame, regs->pc, regs->r26);
#endif

	return;
	return 0;

give_sigsegv:
	force_sigsegv(sig, current);
	return -EFAULT;
}

static void
static int
setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
	       sigset_t *set, struct pt_regs *regs, struct switch_stack * sw)
{
@@ -543,28 +538,29 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
		current->comm, current->pid, frame, regs->pc, regs->r26);
#endif

	return;
	return 0;

give_sigsegv:
	force_sigsegv(sig, current);
	return -EFAULT;
}


/*
 * OK, we're invoking a handler.
 */
static inline void
static inline int
handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
	      sigset_t *oldset, struct pt_regs * regs, struct switch_stack *sw)
{
	int ret;

	if (ka->sa.sa_flags & SA_SIGINFO)
		setup_rt_frame(sig, ka, info, oldset, regs, sw);
		ret = setup_rt_frame(sig, ka, info, oldset, regs, sw);
	else
		setup_frame(sig, ka, oldset, regs, sw);

	if (ka->sa.sa_flags & SA_RESETHAND)
		ka->sa.sa_handler = SIG_DFL;
		ret = setup_frame(sig, ka, oldset, regs, sw);

	if (ret == 0) {
		spin_lock_irq(&current->sighand->siglock);
		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
		if (!(ka->sa.sa_flags & SA_NODEFER)) 
@@ -573,6 +569,9 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
		spin_unlock_irq(&current->sighand->siglock);
	}

	return ret;
}

static inline void
syscall_restart(unsigned long r0, unsigned long r19,
		struct pt_regs *regs, struct k_sigaction *ka)
@@ -611,30 +610,42 @@ syscall_restart(unsigned long r0, unsigned long r19,
 * restart. "r0" is also used as an indicator whether we can restart at
 * all (if we get here from anything but a syscall return, it will be 0)
 */
static int
do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw,
static void
do_signal(struct pt_regs * regs, struct switch_stack * sw,
	  unsigned long r0, unsigned long r19)
{
	siginfo_t info;
	int signr;
	unsigned long single_stepping = ptrace_cancel_bpt(current);
	struct k_sigaction ka;
	sigset_t *oldset;

	if (!oldset)
	if (test_thread_flag(TIF_RESTORE_SIGMASK))
		oldset = &current->saved_sigmask;
	else
		oldset = &current->blocked;

	/* This lets the debugger run, ... */
	signr = get_signal_to_deliver(&info, &ka, regs, NULL);

	/* ... so re-check the single stepping. */
	single_stepping |= ptrace_cancel_bpt(current);

	if (signr > 0) {
		/* Whee!  Actually deliver the signal.  */
		if (r0) syscall_restart(r0, r19, regs, &ka);
		handle_signal(signr, &ka, &info, oldset, regs, sw);
		if (r0)
			syscall_restart(r0, r19, regs, &ka);
		if (handle_signal(signr, &ka, &info, oldset, regs, sw) == 0) {
			/* A signal was successfully delivered, and the
			   saved sigmask was stored on the signal frame,
			   and will be restored by sigreturn.  So we can
			   simply clear the restore sigmask flag.  */
			if (test_thread_flag(TIF_RESTORE_SIGMASK))
				clear_thread_flag(TIF_RESTORE_SIGMASK);
		}
		if (single_stepping) 
			ptrace_set_bpt(current); /* re-set bpt */
		return 1;
		return;
	}

	if (r0) {
@@ -654,17 +665,22 @@ do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw,
			break;
		}
	}

	/* If there's no signal to deliver, we just restore the saved mask.  */
	if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
		clear_thread_flag(TIF_RESTORE_SIGMASK);
		sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
	}

	if (single_stepping)
		ptrace_set_bpt(current);	/* re-set breakpoint */

	return 0;
}

void
do_notify_resume(sigset_t *oldset, struct pt_regs *regs,
		 struct switch_stack *sw, unsigned long r0,
		 unsigned long r19, unsigned long thread_info_flags)
do_notify_resume(struct pt_regs *regs, struct switch_stack *sw,
		 unsigned long thread_info_flags,
		 unsigned long r0, unsigned long r19)
{
	if (thread_info_flags & _TIF_SIGPENDING)
		do_signal(oldset, regs, sw, r0, r19);
	if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
		do_signal(regs, sw, r0, r19);
}
+32 −0
Original line number Diff line number Diff line
@@ -465,6 +465,38 @@ sys_call_table:
	.quad sys_inotify_init
	.quad sys_inotify_add_watch		/* 445 */
	.quad sys_inotify_rm_watch
	.quad sys_fdatasync
	.quad sys_kexec_load
	.quad sys_migrate_pages
	.quad sys_openat			/* 450 */
	.quad sys_mkdirat
	.quad sys_mknodat
	.quad sys_fchownat
	.quad sys_futimesat
	.quad sys_fstatat64			/* 455 */
	.quad sys_unlinkat
	.quad sys_renameat
	.quad sys_linkat
	.quad sys_symlinkat
	.quad sys_readlinkat			/* 460 */
	.quad sys_fchmodat
	.quad sys_faccessat
	.quad sys_pselect6
	.quad sys_ppoll
	.quad sys_unshare			/* 465 */
	.quad sys_set_robust_list
	.quad sys_get_robust_list
	.quad sys_splice
	.quad sys_sync_file_range
	.quad sys_tee				/* 470 */
	.quad sys_vmsplice
	.quad sys_move_pages
	.quad sys_getcpu
	.quad sys_epoll_pwait
	.quad sys_utimensat			/* 475 */
	.quad sys_signalfd
	.quad sys_timerfd
	.quad sys_eventfd

	.size sys_call_table, . - sys_call_table
	.type sys_call_table, @object
+2 −0
Original line number Diff line number Diff line
@@ -76,12 +76,14 @@ register struct thread_info *__current_thread_info __asm__("$8");
#define TIF_UAC_NOFIX		7
#define TIF_UAC_SIGBUS		8
#define TIF_MEMDIE		9
#define TIF_RESTORE_SIGMASK	10	/* restore signal mask in do_signal */

#define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
#define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
#define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)
#define _TIF_RESTORE_SIGMASK	(1<<TIF_RESTORE_SIGMASK)

/* Work to do on interrupt/exception return.  */
#define _TIF_WORK_MASK		(_TIF_NOTIFY_RESUME	\
+47 −1
Original line number Diff line number Diff line
@@ -233,6 +233,20 @@
#define __NR_osf_memcntl	260	/* not implemented */
#define __NR_osf_fdatasync	261	/* not implemented */

/*
 * Ignore legacy syscalls that we don't use.
 */
#define __IGNORE_alarm
#define __IGNORE_creat
#define __IGNORE_getegid
#define __IGNORE_geteuid
#define __IGNORE_getgid
#define __IGNORE_getpid
#define __IGNORE_getppid
#define __IGNORE_getuid
#define __IGNORE_pause
#define __IGNORE_time
#define __IGNORE_utime

/*
 * Linux-specific system calls begin at 300
@@ -387,10 +401,42 @@
#define __NR_inotify_init		444
#define __NR_inotify_add_watch		445
#define __NR_inotify_rm_watch		446
#define __NR_fdatasync			447
#define __NR_kexec_load			448
#define __NR_migrate_pages		449
#define __NR_openat			450
#define __NR_mkdirat			451
#define __NR_mknodat			452
#define __NR_fchownat			453
#define __NR_futimesat			454
#define __NR_fstatat64			455
#define __NR_unlinkat			456
#define __NR_renameat			457
#define __NR_linkat			458
#define __NR_symlinkat			459
#define __NR_readlinkat			460
#define __NR_fchmodat			461
#define __NR_faccessat			462
#define __NR_pselect6			463
#define __NR_ppoll			464
#define __NR_unshare			465
#define __NR_set_robust_list		466
#define __NR_get_robust_list		467
#define __NR_splice			468
#define __NR_sync_file_range		469
#define __NR_tee			470
#define __NR_vmsplice			471
#define __NR_move_pages			472
#define __NR_getcpu			473
#define __NR_epoll_pwait		474
#define __NR_utimensat			475
#define __NR_signalfd			476
#define __NR_timerfd			477
#define __NR_eventfd			478

#ifdef __KERNEL__

#define NR_SYSCALLS			447
#define NR_SYSCALLS			479

#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR