diff options
Diffstat (limited to 'fs/signalfd.c')
-rw-r--r-- | fs/signalfd.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/fs/signalfd.c b/fs/signalfd.c index f652249f59f9..cbb42f77a2bd 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c @@ -112,19 +112,27 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo, new.ssi_band = kinfo->si_band; new.ssi_fd = kinfo->si_fd; break; + case SIL_FAULT_BNDERR: + case SIL_FAULT_PKUERR: + /* + * Fall through to the SIL_FAULT case. Both SIL_FAULT_BNDERR + * and SIL_FAULT_PKUERR are only generated by faults that + * deliver them synchronously to userspace. In case someone + * injects one of these signals and signalfd catches it treat + * it as SIL_FAULT. + */ case SIL_FAULT: new.ssi_addr = (long) kinfo->si_addr; #ifdef __ARCH_SI_TRAPNO new.ssi_trapno = kinfo->si_trapno; #endif - /* - * Other callers might not initialize the si_lsb field, - * so check explicitly for the right codes here. - */ - if (kinfo->si_signo == SIGBUS && - ((kinfo->si_code == BUS_MCEERR_AR) || - (kinfo->si_code == BUS_MCEERR_AO))) - new.ssi_addr_lsb = (short) kinfo->si_addr_lsb; + break; + case SIL_FAULT_MCEERR: + new.ssi_addr = (long) kinfo->si_addr; +#ifdef __ARCH_SI_TRAPNO + new.ssi_trapno = kinfo->si_trapno; +#endif + new.ssi_addr_lsb = (short) kinfo->si_addr_lsb; break; case SIL_CHLD: new.ssi_pid = kinfo->si_pid; |