extern __must_check bool do_notify_parent(struct task_struct *, int);
 extern void __wake_up_parent(struct task_struct *p, struct task_struct *parent);
 extern void force_sig(int);
+extern void force_fatal_sig(int);
 extern int send_sig(int, struct task_struct *, int);
 extern int zap_other_threads(struct task_struct *p);
 extern struct sigqueue *sigqueue_alloc(void);
 
 }
 EXPORT_SYMBOL(force_sig);
 
+void force_fatal_sig(int sig)
+{
+       struct kernel_siginfo info;
+
+       clear_siginfo(&info);
+       info.si_signo = sig;
+       info.si_errno = 0;
+       info.si_code = SI_KERNEL;
+       info.si_pid = 0;
+       info.si_uid = 0;
+       force_sig_info_to_task(&info, current, true);
+}
+
 /*
  * When things go south during signal handling, we
  * will force a SIGSEGV. And if the signal that caused
  */
 void force_sigsegv(int sig)
 {
-       struct task_struct *p = current;
-
-       if (sig == SIGSEGV) {
-               unsigned long flags;
-               spin_lock_irqsave(&p->sighand->siglock, flags);
-               p->sighand->action[sig - 1].sa.sa_handler = SIG_DFL;
-               spin_unlock_irqrestore(&p->sighand->siglock, flags);
-       }
-       force_sig(SIGSEGV);
+       if (sig == SIGSEGV)
+               force_fatal_sig(SIGSEGV);
+       else
+               force_sig(SIGSEGV);
 }
 
 int force_sig_fault_to_task(int sig, int code, void __user *addr