[S390] get rid of kprobes notifier call chain.

And here's a port of the powerpc patch to get rid of the notifier
chain completely to s390.  It's ontop of Martins patch as that one
is in mainline already.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
Christoph Hellwig 2007-05-04 18:47:46 +02:00 committed by Martin Schwidefsky
parent dc87c3985e
commit 33464e3b57
4 changed files with 33 additions and 44 deletions

View File

@ -516,7 +516,7 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
return 1; return 1;
} }
static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
{ {
struct kprobe *cur = kprobe_running(); struct kprobe *cur = kprobe_running();
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@ -603,7 +603,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
ret = NOTIFY_STOP; ret = NOTIFY_STOP;
break; break;
case DIE_TRAP: case DIE_TRAP:
case DIE_PAGE_FAULT:
/* kprobe_running() needs smp_processor_id() */ /* kprobe_running() needs smp_processor_id() */
preempt_disable(); preempt_disable();
if (kprobe_running() && if (kprobe_running() &&

View File

@ -52,38 +52,24 @@ extern int sysctl_userprocess_debug;
extern void die(const char *,struct pt_regs *,long); extern void die(const char *,struct pt_regs *,long);
#ifdef CONFIG_KPROBES #ifdef CONFIG_KPROBES
static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain);
int register_page_fault_notifier(struct notifier_block *nb)
{
return atomic_notifier_chain_register(&notify_page_fault_chain, nb);
}
int unregister_page_fault_notifier(struct notifier_block *nb)
{
return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
}
static int __kprobes __notify_page_fault(struct pt_regs *regs, long err)
{
struct die_args args = { .str = "page fault",
.trapnr = 14,
.signr = SIGSEGV };
args.regs = regs;
args.err = err;
return atomic_notifier_call_chain(&notify_page_fault_chain,
DIE_PAGE_FAULT, &args);
}
static inline int notify_page_fault(struct pt_regs *regs, long err) static inline int notify_page_fault(struct pt_regs *regs, long err)
{ {
if (unlikely(kprobe_running())) int ret = 0;
return __notify_page_fault(regs, err);
return NOTIFY_DONE; /* kprobe_running() needs smp_processor_id() */
if (!user_mode(regs)) {
preempt_disable();
if (kprobe_running() && kprobe_fault_handler(regs, 14))
ret = 1;
preempt_enable();
}
return ret;
} }
#else #else
static inline int notify_page_fault(struct pt_regs *regs, long err) static inline int notify_page_fault(struct pt_regs *regs, long err)
{ {
return NOTIFY_DONE; return 0;
} }
#endif #endif
@ -319,7 +305,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int write)
int space; int space;
int si_code; int si_code;
if (notify_page_fault(regs, error_code) == NOTIFY_STOP) if (notify_page_fault(regs, error_code))
return; return;
tsk = current; tsk = current;

View File

@ -22,8 +22,21 @@ struct die_args {
*/ */
extern int register_die_notifier(struct notifier_block *); extern int register_die_notifier(struct notifier_block *);
extern int unregister_die_notifier(struct notifier_block *); extern int unregister_die_notifier(struct notifier_block *);
extern int register_page_fault_notifier(struct notifier_block *);
extern int unregister_page_fault_notifier(struct notifier_block *); /*
* These are only here because kprobes.c wants them to implement a
* blatant layering violation. Will hopefully go away soon once all
* architectures are updated.
*/
static inline int register_page_fault_notifier(struct notifier_block *nb)
{
return 0;
}
static inline int unregister_page_fault_notifier(struct notifier_block *nb)
{
return 0;
}
extern struct atomic_notifier_head s390die_chain; extern struct atomic_notifier_head s390die_chain;
enum die_val { enum die_val {
@ -39,7 +52,6 @@ enum die_val {
DIE_GPF, DIE_GPF,
DIE_CALL, DIE_CALL,
DIE_NMI_IPI, DIE_NMI_IPI,
DIE_PAGE_FAULT,
}; };
static inline int notify_die(enum die_val val, const char *str, static inline int notify_die(enum die_val val, const char *str,

View File

@ -97,18 +97,10 @@ void kretprobe_trampoline(void);
int is_prohibited_opcode(kprobe_opcode_t *instruction); int is_prohibited_opcode(kprobe_opcode_t *instruction);
void get_instruction_type(struct arch_specific_insn *ainsn); void get_instruction_type(struct arch_specific_insn *ainsn);
int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
int kprobe_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data);
#define flush_insn_slot(p) do { } while (0) #define flush_insn_slot(p) do { } while (0)
#endif /* _ASM_S390_KPROBES_H */ #endif /* _ASM_S390_KPROBES_H */
#ifdef CONFIG_KPROBES
extern int kprobe_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data);
#else /* !CONFIG_KPROBES */
static inline int kprobe_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data)
{
return 0;
}
#endif