mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-11 03:48:00 +00:00
s390/kprobes: make use of NOKPROBE_SYMBOL()
Use NOKPROBE_SYMBOL() instead of __kprobes annotation. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
c933146a5e
commit
7a5388de5c
@ -152,8 +152,7 @@ device_initcall(ftrace_plt_init);
|
|||||||
* Hook the return address and push it in the stack of return addresses
|
* Hook the return address and push it in the stack of return addresses
|
||||||
* in current thread info.
|
* in current thread info.
|
||||||
*/
|
*/
|
||||||
unsigned long __kprobes prepare_ftrace_return(unsigned long parent,
|
unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip)
|
||||||
unsigned long ip)
|
|
||||||
{
|
{
|
||||||
struct ftrace_graph_ent trace;
|
struct ftrace_graph_ent trace;
|
||||||
|
|
||||||
@ -171,6 +170,7 @@ unsigned long __kprobes prepare_ftrace_return(unsigned long parent,
|
|||||||
out:
|
out:
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(prepare_ftrace_return);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Patch the kernel code at ftrace_graph_caller location. The instruction
|
* Patch the kernel code at ftrace_graph_caller location. The instruction
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
static DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
|
static DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
|
||||||
|
|
||||||
void __kprobes enabled_wait(void)
|
void enabled_wait(void)
|
||||||
{
|
{
|
||||||
struct s390_idle_data *idle = this_cpu_ptr(&s390_idle);
|
struct s390_idle_data *idle = this_cpu_ptr(&s390_idle);
|
||||||
unsigned long long idle_time;
|
unsigned long long idle_time;
|
||||||
@ -46,6 +46,7 @@ void __kprobes enabled_wait(void)
|
|||||||
smp_wmb();
|
smp_wmb();
|
||||||
idle->sequence++;
|
idle->sequence++;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(enabled_wait);
|
||||||
|
|
||||||
static ssize_t show_idle_count(struct device *dev,
|
static ssize_t show_idle_count(struct device *dev,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
|
@ -59,7 +59,7 @@ struct kprobe_insn_cache kprobe_dmainsn_slots = {
|
|||||||
.insn_size = MAX_INSN_SIZE,
|
.insn_size = MAX_INSN_SIZE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void __kprobes copy_instruction(struct kprobe *p)
|
static void copy_instruction(struct kprobe *p)
|
||||||
{
|
{
|
||||||
unsigned long ip = (unsigned long) p->addr;
|
unsigned long ip = (unsigned long) p->addr;
|
||||||
s64 disp, new_disp;
|
s64 disp, new_disp;
|
||||||
@ -91,13 +91,14 @@ static void __kprobes copy_instruction(struct kprobe *p)
|
|||||||
new_disp = ((addr + (disp * 2)) - new_addr) / 2;
|
new_disp = ((addr + (disp * 2)) - new_addr) / 2;
|
||||||
*(s32 *)&p->ainsn.insn[1] = new_disp;
|
*(s32 *)&p->ainsn.insn[1] = new_disp;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(copy_instruction);
|
||||||
|
|
||||||
static inline int is_kernel_addr(void *addr)
|
static inline int is_kernel_addr(void *addr)
|
||||||
{
|
{
|
||||||
return addr < (void *)_end;
|
return addr < (void *)_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __kprobes s390_get_insn_slot(struct kprobe *p)
|
static int s390_get_insn_slot(struct kprobe *p)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Get an insn slot that is within the same 2GB area like the original
|
* Get an insn slot that is within the same 2GB area like the original
|
||||||
@ -111,8 +112,9 @@ static int __kprobes s390_get_insn_slot(struct kprobe *p)
|
|||||||
p->ainsn.insn = get_insn_slot();
|
p->ainsn.insn = get_insn_slot();
|
||||||
return p->ainsn.insn ? 0 : -ENOMEM;
|
return p->ainsn.insn ? 0 : -ENOMEM;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(s390_get_insn_slot);
|
||||||
|
|
||||||
static void __kprobes s390_free_insn_slot(struct kprobe *p)
|
static void s390_free_insn_slot(struct kprobe *p)
|
||||||
{
|
{
|
||||||
if (!p->ainsn.insn)
|
if (!p->ainsn.insn)
|
||||||
return;
|
return;
|
||||||
@ -122,8 +124,9 @@ static void __kprobes s390_free_insn_slot(struct kprobe *p)
|
|||||||
free_insn_slot(p->ainsn.insn, 0);
|
free_insn_slot(p->ainsn.insn, 0);
|
||||||
p->ainsn.insn = NULL;
|
p->ainsn.insn = NULL;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(s390_free_insn_slot);
|
||||||
|
|
||||||
int __kprobes arch_prepare_kprobe(struct kprobe *p)
|
int arch_prepare_kprobe(struct kprobe *p)
|
||||||
{
|
{
|
||||||
if ((unsigned long) p->addr & 0x01)
|
if ((unsigned long) p->addr & 0x01)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -135,6 +138,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
|
|||||||
copy_instruction(p);
|
copy_instruction(p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(arch_prepare_kprobe);
|
||||||
|
|
||||||
int arch_check_ftrace_location(struct kprobe *p)
|
int arch_check_ftrace_location(struct kprobe *p)
|
||||||
{
|
{
|
||||||
@ -146,7 +150,7 @@ struct swap_insn_args {
|
|||||||
unsigned int arm_kprobe : 1;
|
unsigned int arm_kprobe : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __kprobes swap_instruction(void *data)
|
static int swap_instruction(void *data)
|
||||||
{
|
{
|
||||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||||
unsigned long status = kcb->kprobe_status;
|
unsigned long status = kcb->kprobe_status;
|
||||||
@ -177,29 +181,33 @@ skip_ftrace:
|
|||||||
kcb->kprobe_status = status;
|
kcb->kprobe_status = status;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(swap_instruction);
|
||||||
|
|
||||||
void __kprobes arch_arm_kprobe(struct kprobe *p)
|
void arch_arm_kprobe(struct kprobe *p)
|
||||||
{
|
{
|
||||||
struct swap_insn_args args = {.p = p, .arm_kprobe = 1};
|
struct swap_insn_args args = {.p = p, .arm_kprobe = 1};
|
||||||
|
|
||||||
stop_machine(swap_instruction, &args, NULL);
|
stop_machine(swap_instruction, &args, NULL);
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(arch_arm_kprobe);
|
||||||
|
|
||||||
void __kprobes arch_disarm_kprobe(struct kprobe *p)
|
void arch_disarm_kprobe(struct kprobe *p)
|
||||||
{
|
{
|
||||||
struct swap_insn_args args = {.p = p, .arm_kprobe = 0};
|
struct swap_insn_args args = {.p = p, .arm_kprobe = 0};
|
||||||
|
|
||||||
stop_machine(swap_instruction, &args, NULL);
|
stop_machine(swap_instruction, &args, NULL);
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(arch_disarm_kprobe);
|
||||||
|
|
||||||
void __kprobes arch_remove_kprobe(struct kprobe *p)
|
void arch_remove_kprobe(struct kprobe *p)
|
||||||
{
|
{
|
||||||
s390_free_insn_slot(p);
|
s390_free_insn_slot(p);
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(arch_remove_kprobe);
|
||||||
|
|
||||||
static void __kprobes enable_singlestep(struct kprobe_ctlblk *kcb,
|
static void enable_singlestep(struct kprobe_ctlblk *kcb,
|
||||||
struct pt_regs *regs,
|
struct pt_regs *regs,
|
||||||
unsigned long ip)
|
unsigned long ip)
|
||||||
{
|
{
|
||||||
struct per_regs per_kprobe;
|
struct per_regs per_kprobe;
|
||||||
|
|
||||||
@ -219,10 +227,11 @@ static void __kprobes enable_singlestep(struct kprobe_ctlblk *kcb,
|
|||||||
regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT);
|
regs->psw.mask &= ~(PSW_MASK_IO | PSW_MASK_EXT);
|
||||||
regs->psw.addr = ip | PSW_ADDR_AMODE;
|
regs->psw.addr = ip | PSW_ADDR_AMODE;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(enable_singlestep);
|
||||||
|
|
||||||
static void __kprobes disable_singlestep(struct kprobe_ctlblk *kcb,
|
static void disable_singlestep(struct kprobe_ctlblk *kcb,
|
||||||
struct pt_regs *regs,
|
struct pt_regs *regs,
|
||||||
unsigned long ip)
|
unsigned long ip)
|
||||||
{
|
{
|
||||||
/* Restore control regs and psw mask, set new psw address */
|
/* Restore control regs and psw mask, set new psw address */
|
||||||
__ctl_load(kcb->kprobe_saved_ctl, 9, 11);
|
__ctl_load(kcb->kprobe_saved_ctl, 9, 11);
|
||||||
@ -230,41 +239,43 @@ static void __kprobes disable_singlestep(struct kprobe_ctlblk *kcb,
|
|||||||
regs->psw.mask |= kcb->kprobe_saved_imask;
|
regs->psw.mask |= kcb->kprobe_saved_imask;
|
||||||
regs->psw.addr = ip | PSW_ADDR_AMODE;
|
regs->psw.addr = ip | PSW_ADDR_AMODE;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(disable_singlestep);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Activate a kprobe by storing its pointer to current_kprobe. The
|
* Activate a kprobe by storing its pointer to current_kprobe. The
|
||||||
* previous kprobe is stored in kcb->prev_kprobe. A stack of up to
|
* previous kprobe is stored in kcb->prev_kprobe. A stack of up to
|
||||||
* two kprobes can be active, see KPROBE_REENTER.
|
* two kprobes can be active, see KPROBE_REENTER.
|
||||||
*/
|
*/
|
||||||
static void __kprobes push_kprobe(struct kprobe_ctlblk *kcb, struct kprobe *p)
|
static void push_kprobe(struct kprobe_ctlblk *kcb, struct kprobe *p)
|
||||||
{
|
{
|
||||||
kcb->prev_kprobe.kp = __this_cpu_read(current_kprobe);
|
kcb->prev_kprobe.kp = __this_cpu_read(current_kprobe);
|
||||||
kcb->prev_kprobe.status = kcb->kprobe_status;
|
kcb->prev_kprobe.status = kcb->kprobe_status;
|
||||||
__this_cpu_write(current_kprobe, p);
|
__this_cpu_write(current_kprobe, p);
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(push_kprobe);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Deactivate a kprobe by backing up to the previous state. If the
|
* Deactivate a kprobe by backing up to the previous state. If the
|
||||||
* current state is KPROBE_REENTER prev_kprobe.kp will be non-NULL,
|
* current state is KPROBE_REENTER prev_kprobe.kp will be non-NULL,
|
||||||
* for any other state prev_kprobe.kp will be NULL.
|
* for any other state prev_kprobe.kp will be NULL.
|
||||||
*/
|
*/
|
||||||
static void __kprobes pop_kprobe(struct kprobe_ctlblk *kcb)
|
static void pop_kprobe(struct kprobe_ctlblk *kcb)
|
||||||
{
|
{
|
||||||
__this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
|
__this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
|
||||||
kcb->kprobe_status = kcb->prev_kprobe.status;
|
kcb->kprobe_status = kcb->prev_kprobe.status;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(pop_kprobe);
|
||||||
|
|
||||||
void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
|
void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs)
|
||||||
struct pt_regs *regs)
|
|
||||||
{
|
{
|
||||||
ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14];
|
ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14];
|
||||||
|
|
||||||
/* Replace the return addr with trampoline addr */
|
/* Replace the return addr with trampoline addr */
|
||||||
regs->gprs[14] = (unsigned long) &kretprobe_trampoline;
|
regs->gprs[14] = (unsigned long) &kretprobe_trampoline;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(arch_prepare_kretprobe);
|
||||||
|
|
||||||
static void __kprobes kprobe_reenter_check(struct kprobe_ctlblk *kcb,
|
static void kprobe_reenter_check(struct kprobe_ctlblk *kcb, struct kprobe *p)
|
||||||
struct kprobe *p)
|
|
||||||
{
|
{
|
||||||
switch (kcb->kprobe_status) {
|
switch (kcb->kprobe_status) {
|
||||||
case KPROBE_HIT_SSDONE:
|
case KPROBE_HIT_SSDONE:
|
||||||
@ -284,8 +295,9 @@ static void __kprobes kprobe_reenter_check(struct kprobe_ctlblk *kcb,
|
|||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(kprobe_reenter_check);
|
||||||
|
|
||||||
static int __kprobes kprobe_handler(struct pt_regs *regs)
|
static int kprobe_handler(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
struct kprobe_ctlblk *kcb;
|
struct kprobe_ctlblk *kcb;
|
||||||
struct kprobe *p;
|
struct kprobe *p;
|
||||||
@ -359,6 +371,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
|
|||||||
preempt_enable_no_resched();
|
preempt_enable_no_resched();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(kprobe_handler);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function return probe trampoline:
|
* Function return probe trampoline:
|
||||||
@ -375,8 +388,7 @@ static void __used kretprobe_trampoline_holder(void)
|
|||||||
/*
|
/*
|
||||||
* Called when the probe at kretprobe trampoline is hit
|
* Called when the probe at kretprobe trampoline is hit
|
||||||
*/
|
*/
|
||||||
static int __kprobes trampoline_probe_handler(struct kprobe *p,
|
static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
|
||||||
struct pt_regs *regs)
|
|
||||||
{
|
{
|
||||||
struct kretprobe_instance *ri;
|
struct kretprobe_instance *ri;
|
||||||
struct hlist_head *head, empty_rp;
|
struct hlist_head *head, empty_rp;
|
||||||
@ -464,6 +476,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
|
|||||||
*/
|
*/
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(trampoline_probe_handler);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called after single-stepping. p->addr is the address of the
|
* Called after single-stepping. p->addr is the address of the
|
||||||
@ -473,7 +486,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe *p,
|
|||||||
* single-stepped a copy of the instruction. The address of this
|
* single-stepped a copy of the instruction. The address of this
|
||||||
* copy is p->ainsn.insn.
|
* copy is p->ainsn.insn.
|
||||||
*/
|
*/
|
||||||
static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
|
static void resume_execution(struct kprobe *p, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||||
unsigned long ip = regs->psw.addr & PSW_ADDR_INSN;
|
unsigned long ip = regs->psw.addr & PSW_ADDR_INSN;
|
||||||
@ -514,8 +527,9 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
|
|||||||
|
|
||||||
disable_singlestep(kcb, regs, ip);
|
disable_singlestep(kcb, regs, ip);
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(resume_execution);
|
||||||
|
|
||||||
static int __kprobes post_kprobe_handler(struct pt_regs *regs)
|
static int post_kprobe_handler(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||||
struct kprobe *p = kprobe_running();
|
struct kprobe *p = kprobe_running();
|
||||||
@ -542,8 +556,9 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(post_kprobe_handler);
|
||||||
|
|
||||||
static int __kprobes kprobe_trap_handler(struct pt_regs *regs, int trapnr)
|
static int kprobe_trap_handler(struct pt_regs *regs, int trapnr)
|
||||||
{
|
{
|
||||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||||
struct kprobe *p = kprobe_running();
|
struct kprobe *p = kprobe_running();
|
||||||
@ -605,8 +620,9 @@ static int __kprobes kprobe_trap_handler(struct pt_regs *regs, int trapnr)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(kprobe_trap_handler);
|
||||||
|
|
||||||
int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
|
int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -617,12 +633,13 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
|
|||||||
local_irq_restore(regs->psw.mask & ~PSW_MASK_PER);
|
local_irq_restore(regs->psw.mask & ~PSW_MASK_PER);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(kprobe_fault_handler);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wrapper routine to for handling exceptions.
|
* Wrapper routine to for handling exceptions.
|
||||||
*/
|
*/
|
||||||
int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
|
int kprobe_exceptions_notify(struct notifier_block *self,
|
||||||
unsigned long val, void *data)
|
unsigned long val, void *data)
|
||||||
{
|
{
|
||||||
struct die_args *args = (struct die_args *) data;
|
struct die_args *args = (struct die_args *) data;
|
||||||
struct pt_regs *regs = args->regs;
|
struct pt_regs *regs = args->regs;
|
||||||
@ -654,8 +671,9 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(kprobe_exceptions_notify);
|
||||||
|
|
||||||
int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||||
@ -673,13 +691,15 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
|||||||
memcpy(kcb->jprobes_stack, (void *) stack, MIN_STACK_SIZE(stack));
|
memcpy(kcb->jprobes_stack, (void *) stack, MIN_STACK_SIZE(stack));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(setjmp_pre_handler);
|
||||||
|
|
||||||
void __kprobes jprobe_return(void)
|
void jprobe_return(void)
|
||||||
{
|
{
|
||||||
asm volatile(".word 0x0002");
|
asm volatile(".word 0x0002");
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(jprobe_return);
|
||||||
|
|
||||||
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||||
unsigned long stack;
|
unsigned long stack;
|
||||||
@ -693,6 +713,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
|||||||
preempt_enable_no_resched();
|
preempt_enable_no_resched();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(longjmp_break_handler);
|
||||||
|
|
||||||
static struct kprobe trampoline = {
|
static struct kprobe trampoline = {
|
||||||
.addr = (kprobe_opcode_t *) &kretprobe_trampoline,
|
.addr = (kprobe_opcode_t *) &kretprobe_trampoline,
|
||||||
@ -704,7 +725,8 @@ int __init arch_init_kprobes(void)
|
|||||||
return register_kprobe(&trampoline);
|
return register_kprobe(&trampoline);
|
||||||
}
|
}
|
||||||
|
|
||||||
int __kprobes arch_trampoline_kprobe(struct kprobe *p)
|
int arch_trampoline_kprobe(struct kprobe *p)
|
||||||
{
|
{
|
||||||
return p->addr == (kprobe_opcode_t *) &kretprobe_trampoline;
|
return p->addr == (kprobe_opcode_t *) &kretprobe_trampoline;
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(arch_trampoline_kprobe);
|
||||||
|
@ -61,7 +61,7 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
|
|||||||
return sf->gprs[8];
|
return sf->gprs[8];
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void __kprobes kernel_thread_starter(void);
|
extern void kernel_thread_starter(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free current thread data structures etc..
|
* Free current thread data structures etc..
|
||||||
|
@ -61,10 +61,11 @@ static DEFINE_PER_CPU(struct clock_event_device, comparators);
|
|||||||
/*
|
/*
|
||||||
* Scheduler clock - returns current time in nanosec units.
|
* Scheduler clock - returns current time in nanosec units.
|
||||||
*/
|
*/
|
||||||
unsigned long long notrace __kprobes sched_clock(void)
|
unsigned long long notrace sched_clock(void)
|
||||||
{
|
{
|
||||||
return tod_to_ns(get_tod_clock_monotonic());
|
return tod_to_ns(get_tod_clock_monotonic());
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(sched_clock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Monotonic_clock - returns # of nanoseconds passed since time_init()
|
* Monotonic_clock - returns # of nanoseconds passed since time_init()
|
||||||
|
@ -87,16 +87,16 @@ void do_report_trap(struct pt_regs *regs, int si_signo, int si_code, char *str)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __kprobes do_trap(struct pt_regs *regs, int si_signo, int si_code,
|
static void do_trap(struct pt_regs *regs, int si_signo, int si_code, char *str)
|
||||||
char *str)
|
|
||||||
{
|
{
|
||||||
if (notify_die(DIE_TRAP, str, regs, 0,
|
if (notify_die(DIE_TRAP, str, regs, 0,
|
||||||
regs->int_code, si_signo) == NOTIFY_STOP)
|
regs->int_code, si_signo) == NOTIFY_STOP)
|
||||||
return;
|
return;
|
||||||
do_report_trap(regs, si_signo, si_code, str);
|
do_report_trap(regs, si_signo, si_code, str);
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(do_trap);
|
||||||
|
|
||||||
void __kprobes do_per_trap(struct pt_regs *regs)
|
void do_per_trap(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
siginfo_t info;
|
siginfo_t info;
|
||||||
|
|
||||||
@ -111,6 +111,7 @@ void __kprobes do_per_trap(struct pt_regs *regs)
|
|||||||
(void __force __user *) current->thread.per_event.address;
|
(void __force __user *) current->thread.per_event.address;
|
||||||
force_sig_info(SIGTRAP, &info, current);
|
force_sig_info(SIGTRAP, &info, current);
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(do_per_trap);
|
||||||
|
|
||||||
void default_trap_handler(struct pt_regs *regs)
|
void default_trap_handler(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
@ -179,7 +180,7 @@ static inline void do_fp_trap(struct pt_regs *regs, int fpc)
|
|||||||
do_trap(regs, SIGFPE, si_code, "floating point exception");
|
do_trap(regs, SIGFPE, si_code, "floating point exception");
|
||||||
}
|
}
|
||||||
|
|
||||||
void __kprobes illegal_op(struct pt_regs *regs)
|
void illegal_op(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
siginfo_t info;
|
siginfo_t info;
|
||||||
__u8 opcode[6];
|
__u8 opcode[6];
|
||||||
@ -252,7 +253,7 @@ void __kprobes illegal_op(struct pt_regs *regs)
|
|||||||
if (signal)
|
if (signal)
|
||||||
do_trap(regs, signal, ILL_ILLOPC, "illegal operation");
|
do_trap(regs, signal, ILL_ILLOPC, "illegal operation");
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(illegal_op);
|
||||||
|
|
||||||
#ifdef CONFIG_MATHEMU
|
#ifdef CONFIG_MATHEMU
|
||||||
void specification_exception(struct pt_regs *regs)
|
void specification_exception(struct pt_regs *regs)
|
||||||
@ -469,7 +470,7 @@ void space_switch_exception(struct pt_regs *regs)
|
|||||||
do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event");
|
do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event");
|
||||||
}
|
}
|
||||||
|
|
||||||
void __kprobes kernel_stack_overflow(struct pt_regs * regs)
|
void kernel_stack_overflow(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
bust_spinlocks(1);
|
bust_spinlocks(1);
|
||||||
printk("Kernel stack overflow.\n");
|
printk("Kernel stack overflow.\n");
|
||||||
@ -477,6 +478,7 @@ void __kprobes kernel_stack_overflow(struct pt_regs * regs)
|
|||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
panic("Corrupt kernel stack, can't continue.");
|
panic("Corrupt kernel stack, can't continue.");
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(kernel_stack_overflow);
|
||||||
|
|
||||||
void __init trap_init(void)
|
void __init trap_init(void)
|
||||||
{
|
{
|
||||||
|
@ -548,7 +548,7 @@ out:
|
|||||||
return fault;
|
return fault;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __kprobes do_protection_exception(struct pt_regs *regs)
|
void do_protection_exception(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
unsigned long trans_exc_code;
|
unsigned long trans_exc_code;
|
||||||
int fault;
|
int fault;
|
||||||
@ -574,8 +574,9 @@ void __kprobes do_protection_exception(struct pt_regs *regs)
|
|||||||
if (unlikely(fault))
|
if (unlikely(fault))
|
||||||
do_fault_error(regs, fault);
|
do_fault_error(regs, fault);
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(do_protection_exception);
|
||||||
|
|
||||||
void __kprobes do_dat_exception(struct pt_regs *regs)
|
void do_dat_exception(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
int access, fault;
|
int access, fault;
|
||||||
|
|
||||||
@ -584,6 +585,7 @@ void __kprobes do_dat_exception(struct pt_regs *regs)
|
|||||||
if (unlikely(fault))
|
if (unlikely(fault))
|
||||||
do_fault_error(regs, fault);
|
do_fault_error(regs, fault);
|
||||||
}
|
}
|
||||||
|
NOKPROBE_SYMBOL(do_dat_exception);
|
||||||
|
|
||||||
#ifdef CONFIG_PFAULT
|
#ifdef CONFIG_PFAULT
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user