Commit a6fc012c authored by Linus Torvalds's avatar Linus Torvalds

Merge common signal handling fault handling in generic code.

parent 2355757b
......@@ -469,9 +469,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
static void
......@@ -533,9 +531,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
......
......@@ -639,9 +639,7 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
return;
}
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, tsk);
force_sigsegv(sig, tsk);
}
/*
......
......@@ -465,9 +465,7 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
return;
}
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, tsk);
force_sigsegv(sig, tsk);
}
/*
......
......@@ -409,9 +409,7 @@ static void setup_frame(int sig, struct k_sigaction *ka,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
......@@ -475,9 +473,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
/*
......
......@@ -391,9 +391,7 @@ static void setup_frame (int sig, struct k_sigaction *ka,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
......@@ -443,9 +441,7 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
static inline void
......
......@@ -411,9 +411,7 @@ static void setup_frame(int sig, struct k_sigaction *ka,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
......@@ -492,9 +490,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
/*
......
......@@ -882,9 +882,7 @@ setup_frame_ia32 (int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs
return 1;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
return 0;
}
......@@ -952,9 +950,7 @@ setup_rt_frame_ia32 (int sig, struct k_sigaction *ka, siginfo_t *info,
return 1;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
return 0;
}
......
......@@ -842,9 +842,7 @@ static void setup_frame (int sig, struct k_sigaction *ka,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
goto adjust_stack;
}
......@@ -925,9 +923,7 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
goto adjust_stack;
}
......
......@@ -616,9 +616,7 @@ static void setup_frame (int sig, struct k_sigaction *ka,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
goto adjust_stack;
}
......@@ -685,9 +683,7 @@ static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
goto adjust_stack;
}
......
......@@ -121,9 +121,7 @@ static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs,
return;
segv_and_exit:
if (signr == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(signr, current);
}
static void inline
......
......@@ -406,9 +406,7 @@ static void inline setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
return;
give_sigsegv:
if (signr == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(signr, current);
}
#endif
......@@ -475,9 +473,7 @@ static void inline setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
return;
give_sigsegv:
if (signr == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(signr, current);
}
extern void setup_rt_frame_n32(struct k_sigaction * ka,
......
......@@ -574,9 +574,7 @@ static inline void setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
return;
give_sigsegv:
if (signr == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(signr, current);
}
static inline void setup_rt_frame(struct k_sigaction * ka,
......@@ -647,9 +645,7 @@ static inline void setup_rt_frame(struct k_sigaction * ka,
return;
give_sigsegv:
if (signr == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(signr, current);
}
static inline void handle_signal(unsigned long sig, siginfo_t *info,
......
......@@ -208,7 +208,5 @@ void setup_rt_frame_n32(struct k_sigaction * ka,
return;
give_sigsegv:
if (signr == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(signr, current);
}
......@@ -404,9 +404,7 @@ handle_rt_signal(unsigned long sig, struct k_sigaction *ka,
printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
regs, frame, newsp);
#endif
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int sig)
......@@ -556,9 +554,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
printk("badframe in handle_signal, regs=%p frame=%p newsp=%lx\n",
regs, frame, newsp);
#endif
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
/*
......
......@@ -699,9 +699,7 @@ static void handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
regs, frame, newsp);
#endif
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
static long do_setcontext32(struct ucontext32 __user *ucp, struct pt_regs *regs, int sig)
......@@ -864,9 +862,7 @@ static void handle_signal32(unsigned long sig, struct k_sigaction *ka,
printk("badframe in handle_signal, regs=%p frame=%x newsp=%x\n",
regs, frame, *newspp);
#endif
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
/*
......
......@@ -552,9 +552,7 @@ static void setup_frame32(int sig, struct k_sigaction *ka,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
......@@ -604,9 +602,7 @@ static void setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
/*
......
......@@ -358,9 +358,7 @@ static void setup_frame(int sig, struct k_sigaction *ka,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
......@@ -414,9 +412,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
/*
......
......@@ -413,9 +413,7 @@ static void setup_frame(int sig, struct k_sigaction *ka,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
......@@ -490,9 +488,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
/*
......
......@@ -520,9 +520,7 @@ static void setup_frame(int sig, struct k_sigaction *ka,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
......@@ -628,9 +626,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
/*
......
......@@ -31,17 +31,6 @@
EXPORT_SYMBOL(block_signals);
EXPORT_SYMBOL(unblock_signals);
static void force_segv(int sig)
{
if(sig == SIGSEGV){
struct k_sigaction *ka;
ka = &current->sighand->action[SIGSEGV - 1];
ka->sa.sa_handler = SIG_DFL;
}
force_sig(SIGSEGV, current);
}
#define _S(nr) (1<<((nr)-1))
#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
......@@ -124,7 +113,7 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
return(0);
segv:
force_segv(signr);
force_sigsegv(signr, current);
return(1);
}
......
......@@ -344,9 +344,7 @@ static void setup_frame(int sig, struct k_sigaction *ka,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
......@@ -421,9 +419,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
force_sig(SIGSEGV, current);
force_sigsegv(sig, current);
}
/*
......
......@@ -499,9 +499,7 @@ void ia32_setup_frame(int sig, struct k_sigaction *ka,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
signal_fault(regs,frame,"32bit signal deliver");
force_sigsegv(sig, current);
}
void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
......@@ -595,8 +593,6 @@ void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
signal_fault(regs, frame, "32bit rt signal setup");
force_sigsegv(sig, current);
}
......@@ -329,9 +329,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
return;
give_sigsegv:
if (sig == SIGSEGV)
ka->sa.sa_handler = SIG_DFL;
signal_fault(regs,frame,"signal deliver");
force_sigsegv(sig, current);
}
/*
......
......@@ -718,6 +718,7 @@ extern void unblock_all_signals(void);
extern void release_task(struct task_struct * p);
extern int send_sig_info(int, struct siginfo *, struct task_struct *);
extern int send_group_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 *);
extern int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp);
extern int kill_pg_info(int, struct siginfo *, pid_t);
......
......@@ -1243,6 +1243,25 @@ force_sig(int sig, struct task_struct *p)
force_sig_info(sig, (void*)1L, p);
}
/*
* When things go south during signal handling, we
* will force a SIGSEGV. And if the signal that caused
* the problem was already a SIGSEGV, we'll want to
* make sure we don't even try to deliver the signal..
*/
int
force_sigsegv(int sig, struct task_struct *p)
{
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, p);
return 0;
}
int
kill_pg(pid_t pgrp, int sig, int priv)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment