Skip to content

Commit f8ec660

Browse files
committed
signal: Add send_sig_fault and force_sig_fault
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]>
1 parent 3b10db2 commit f8ec660

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

include/linux/sched/signal.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,26 @@ static inline void kernel_signal_stop(void)
285285

286286
schedule();
287287
}
288+
#ifdef __ARCH_SI_TRAPNO
289+
# define ___ARCH_SI_TRAPNO(_a1) , _a1
290+
#else
291+
# define ___ARCH_SI_TRAPNO(_a1)
292+
#endif
293+
#ifdef __ia64__
294+
# define ___ARCH_SI_IA64(_a1, _a2, _a3) , _a1, _a2, _a3
295+
#else
296+
# define ___ARCH_SI_IA64(_a1, _a2, _a3)
297+
#endif
298+
299+
int force_sig_fault(int sig, int code, void __user *addr
300+
___ARCH_SI_TRAPNO(int trapno)
301+
___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
302+
, struct task_struct *t);
303+
int send_sig_fault(int sig, int code, void __user *addr
304+
___ARCH_SI_TRAPNO(int trapno)
305+
___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
306+
, struct task_struct *t);
307+
288308
extern int send_sig_info(int, struct siginfo *, struct task_struct *);
289309
extern int force_sigsegv(int, struct task_struct *);
290310
extern int force_sig_info(int, struct siginfo *, struct task_struct *);

kernel/signal.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,6 +1491,53 @@ force_sigsegv(int sig, struct task_struct *p)
14911491
return 0;
14921492
}
14931493

1494+
int force_sig_fault(int sig, int code, void __user *addr
1495+
___ARCH_SI_TRAPNO(int trapno)
1496+
___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
1497+
, struct task_struct *t)
1498+
{
1499+
struct siginfo info;
1500+
1501+
clear_siginfo(&info);
1502+
info.si_signo = sig;
1503+
info.si_errno = 0;
1504+
info.si_code = code;
1505+
info.si_addr = addr;
1506+
#ifdef __ARCH_SI_TRAPNO
1507+
info.si_trapno = trapno;
1508+
#endif
1509+
#ifdef __ia64__
1510+
info.si_imm = imm;
1511+
info.si_flags = flags;
1512+
info.si_isr = isr;
1513+
#endif
1514+
return force_sig_info(info.si_signo, &info, t);
1515+
}
1516+
1517+
int send_sig_fault(int sig, int code, void __user *addr
1518+
___ARCH_SI_TRAPNO(int trapno)
1519+
___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
1520+
, struct task_struct *t)
1521+
{
1522+
struct siginfo info;
1523+
1524+
clear_siginfo(&info);
1525+
info.si_signo = sig;
1526+
info.si_errno = 0;
1527+
info.si_code = code;
1528+
info.si_addr = addr;
1529+
#ifdef __ARCH_SI_TRAPNO
1530+
info.si_trapno = trapno;
1531+
#endif
1532+
#ifdef __ia64__
1533+
info.si_imm = imm;
1534+
info.si_flags = flags;
1535+
info.si_isr = isr;
1536+
#endif
1537+
return send_sig_info(info.si_signo, &info, t);
1538+
}
1539+
1540+
14941541
int kill_pgrp(struct pid *pid, int sig, int priv)
14951542
{
14961543
int ret;

0 commit comments

Comments
 (0)