Skip to content

Commit

Permalink
signal: Add send_sig_fault and force_sig_fault
Browse files Browse the repository at this point in the history
The vast majority of signals sent from architecture specific code are
simple faults.  Encapsulate this reality with two helper functions so
that the nit-picky implementation of preparing a siginfo does not need
to be repeated many times on each architecture.

As only some architectures support the trapno field, make the trapno
arguement only present on those architectures.

Similary as ia64 has three fields: imm, flags, and isr that
are specific to it.  Have those arguments always present on ia64
and no where else.

This ensures the architecture specific code always remembers which
fields it needs to pass into the siginfo structure.

Signed-off-by: "Eric W. Biederman" <[email protected]>
  • Loading branch information
ebiederm committed Jan 23, 2018
1 parent 3b10db2 commit f8ec660
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 0 deletions.
20 changes: 20 additions & 0 deletions include/linux/sched/signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,26 @@ static inline void kernel_signal_stop(void)

schedule();
}
#ifdef __ARCH_SI_TRAPNO
# define ___ARCH_SI_TRAPNO(_a1) , _a1
#else
# define ___ARCH_SI_TRAPNO(_a1)
#endif
#ifdef __ia64__
# define ___ARCH_SI_IA64(_a1, _a2, _a3) , _a1, _a2, _a3
#else
# define ___ARCH_SI_IA64(_a1, _a2, _a3)
#endif

int force_sig_fault(int sig, int code, void __user *addr
___ARCH_SI_TRAPNO(int trapno)
___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
, struct task_struct *t);
int send_sig_fault(int sig, int code, void __user *addr
___ARCH_SI_TRAPNO(int trapno)
___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
, struct task_struct *t);

extern int send_sig_info(int, struct siginfo *, struct task_struct *);
extern int force_sigsegv(int, struct task_struct *);
extern int force_sig_info(int, struct siginfo *, struct task_struct *);
Expand Down
47 changes: 47 additions & 0 deletions kernel/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1491,6 +1491,53 @@ force_sigsegv(int sig, struct task_struct *p)
return 0;
}

int force_sig_fault(int sig, int code, void __user *addr
___ARCH_SI_TRAPNO(int trapno)
___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
, struct task_struct *t)
{
struct siginfo info;

clear_siginfo(&info);
info.si_signo = sig;
info.si_errno = 0;
info.si_code = code;
info.si_addr = addr;
#ifdef __ARCH_SI_TRAPNO
info.si_trapno = trapno;
#endif
#ifdef __ia64__
info.si_imm = imm;
info.si_flags = flags;
info.si_isr = isr;
#endif
return force_sig_info(info.si_signo, &info, t);
}

int send_sig_fault(int sig, int code, void __user *addr
___ARCH_SI_TRAPNO(int trapno)
___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
, struct task_struct *t)
{
struct siginfo info;

clear_siginfo(&info);
info.si_signo = sig;
info.si_errno = 0;
info.si_code = code;
info.si_addr = addr;
#ifdef __ARCH_SI_TRAPNO
info.si_trapno = trapno;
#endif
#ifdef __ia64__
info.si_imm = imm;
info.si_flags = flags;
info.si_isr = isr;
#endif
return send_sig_info(info.si_signo, &info, t);
}


int kill_pgrp(struct pid *pid, int sig, int priv)
{
int ret;
Expand Down

0 comments on commit f8ec660

Please sign in to comment.