Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 18365
b: refs/heads/master
c: d3ef1f5
h: refs/heads/master
i:
  18363: 500790c
v: v3
  • Loading branch information
Zhang Yanmin authored and Tony Luck committed Jan 13, 2006
1 parent 197553c commit 29c5365
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e026cca0f2c09c4c28c902db6384fd8a412671d6
refs/heads/master: d3ef1f5aafcf7a4129eb2078c70bc9e577bc3af1
27 changes: 27 additions & 0 deletions trunk/arch/ia64/kernel/jprobes.S
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,30 @@ END(jprobe_break)
GLOBAL_ENTRY(jprobe_inst_return)
br.call.sptk.many b0=jprobe_break
END(jprobe_inst_return)

GLOBAL_ENTRY(invalidate_stacked_regs)
movl r16=invalidate_restore_cfm
;;
mov b6=r16
;;
br.ret.sptk.many b6
;;
invalidate_restore_cfm:
mov r16=ar.rsc
;;
mov ar.rsc=r0
;;
loadrs
;;
mov ar.rsc=r16
;;
br.cond.sptk.many rp
END(invalidate_stacked_regs)

GLOBAL_ENTRY(flush_register_stack)
// flush dirty regs to backing store (must be first in insn group)
flushrs
;;
br.ret.sptk.many rp
END(flush_register_stack)

57 changes: 57 additions & 0 deletions trunk/arch/ia64/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -766,11 +766,56 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
return ret;
}

struct param_bsp_cfm {
unsigned long ip;
unsigned long *bsp;
unsigned long cfm;
};

static void ia64_get_bsp_cfm(struct unw_frame_info *info, void *arg)
{
unsigned long ip;
struct param_bsp_cfm *lp = arg;

do {
unw_get_ip(info, &ip);
if (ip == 0)
break;
if (ip == lp->ip) {
unw_get_bsp(info, (unsigned long*)&lp->bsp);
unw_get_cfm(info, (unsigned long*)&lp->cfm);
return;
}
} while (unw_unwind(info) >= 0);
lp->bsp = 0;
lp->cfm = 0;
return;
}

int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
{
struct jprobe *jp = container_of(p, struct jprobe, kp);
unsigned long addr = ((struct fnptr *)(jp->entry))->ip;
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
struct param_bsp_cfm pa;
int bytes;

/*
* Callee owns the argument space and could overwrite it, eg
* tail call optimization. So to be absolutely safe
* we save the argument space before transfering the control
* to instrumented jprobe function which runs in
* the process context
*/
pa.ip = regs->cr_iip;
unw_init_running(ia64_get_bsp_cfm, &pa);
bytes = (char *)ia64_rse_skip_regs(pa.bsp, pa.cfm & 0x3f)
- (char *)pa.bsp;
memcpy( kcb->jprobes_saved_stacked_regs,
pa.bsp,
bytes );
kcb->bsp = pa.bsp;
kcb->cfm = pa.cfm;

/* save architectural state */
kcb->jprobe_saved_regs = *regs;
Expand All @@ -792,8 +837,20 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
{
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
int bytes;

/* restoring architectural state */
*regs = kcb->jprobe_saved_regs;

/* restoring the original argument space */
flush_register_stack();
bytes = (char *)ia64_rse_skip_regs(kcb->bsp, kcb->cfm & 0x3f)
- (char *)kcb->bsp;
memcpy( kcb->bsp,
kcb->jprobes_saved_stacked_regs,
bytes );
invalidate_stacked_regs();

preempt_enable_no_resched();
return 1;
}
Expand Down
6 changes: 6 additions & 0 deletions trunk/include/asm-ia64/kprobes.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,14 @@ struct prev_kprobe {
unsigned long status;
};

#define MAX_PARAM_RSE_SIZE (0x60+0x60/0x3f)
/* per-cpu kprobe control block */
struct kprobe_ctlblk {
unsigned long kprobe_status;
struct pt_regs jprobe_saved_regs;
unsigned long jprobes_saved_stacked_regs[MAX_PARAM_RSE_SIZE];
unsigned long *bsp;
unsigned long cfm;
struct prev_kprobe prev_kprobe;
};

Expand Down Expand Up @@ -118,5 +122,7 @@ extern int kprobe_exceptions_notify(struct notifier_block *self,
static inline void jprobe_return(void)
{
}
extern void invalidate_stacked_regs(void);
extern void flush_register_stack(void);

#endif /* _ASM_KPROBES_H */

0 comments on commit 29c5365

Please sign in to comment.