Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 2931
b: refs/heads/master
c: 7e1048b
h: refs/heads/master
i:
  2929: 079af4d
  2927: 940c71e
v: v3
  • Loading branch information
Rusty Lynch authored and Linus Torvalds committed Jun 23, 2005
1 parent 8d8d303 commit 97b0ba0
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 38 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 73649dab0fd524cb8545a8cb83c6eaf77b107105
refs/heads/master: 7e1048b11c5afe79aac46a42e3ccec86b8365c6d
19 changes: 15 additions & 4 deletions trunk/arch/i386/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <linux/ptrace.h>
#include <linux/spinlock.h>
#include <linux/preempt.h>
#include <asm/cacheflush.h>
#include <asm/kdebug.h>
#include <asm/desc.h>

Expand Down Expand Up @@ -71,16 +72,25 @@ int arch_prepare_kprobe(struct kprobe *p)
void arch_copy_kprobe(struct kprobe *p)
{
memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
p->opcode = *p->addr;
}

void arch_remove_kprobe(struct kprobe *p)
void arch_arm_kprobe(struct kprobe *p)
{
*p->addr = BREAKPOINT_INSTRUCTION;
flush_icache_range((unsigned long) p->addr,
(unsigned long) p->addr + sizeof(kprobe_opcode_t));
}

static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
void arch_disarm_kprobe(struct kprobe *p)
{
*p->addr = p->opcode;
regs->eip = (unsigned long)p->addr;
flush_icache_range((unsigned long) p->addr,
(unsigned long) p->addr + sizeof(kprobe_opcode_t));
}

void arch_remove_kprobe(struct kprobe *p)
{
}

static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
Expand Down Expand Up @@ -177,7 +187,8 @@ static int kprobe_handler(struct pt_regs *regs)
unlock_kprobes();
goto no_kprobe;
}
disarm_kprobe(p, regs);
arch_disarm_kprobe(p);
regs->eip = (unsigned long)p->addr;
ret = 1;
} else {
p = current_kprobe;
Expand Down
19 changes: 15 additions & 4 deletions trunk/arch/ppc64/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <linux/ptrace.h>
#include <linux/spinlock.h>
#include <linux/preempt.h>
#include <asm/cacheflush.h>
#include <asm/kdebug.h>
#include <asm/sstep.h>

Expand Down Expand Up @@ -61,16 +62,25 @@ int arch_prepare_kprobe(struct kprobe *p)
void arch_copy_kprobe(struct kprobe *p)
{
memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
p->opcode = *p->addr;
}

void arch_remove_kprobe(struct kprobe *p)
void arch_arm_kprobe(struct kprobe *p)
{
*p->addr = BREAKPOINT_INSTRUCTION;
flush_icache_range((unsigned long) p->addr,
(unsigned long) p->addr + sizeof(kprobe_opcode_t));
}

static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
void arch_disarm_kprobe(struct kprobe *p)
{
*p->addr = p->opcode;
regs->nip = (unsigned long)p->addr;
flush_icache_range((unsigned long) p->addr,
(unsigned long) p->addr + sizeof(kprobe_opcode_t));
}

void arch_remove_kprobe(struct kprobe *p)
{
}

static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
Expand Down Expand Up @@ -101,7 +111,8 @@ static inline int kprobe_handler(struct pt_regs *regs)
unlock_kprobes();
goto no_kprobe;
}
disarm_kprobe(p, regs);
arch_disarm_kprobe(p);
regs->nip = (unsigned long)p->addr;
ret = 1;
} else {
p = current_kprobe;
Expand Down
31 changes: 18 additions & 13 deletions trunk/arch/sparc64/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/kprobes.h>

#include <asm/kdebug.h>
#include <asm/signal.h>

Expand Down Expand Up @@ -47,6 +46,19 @@ void arch_copy_kprobe(struct kprobe *p)
{
p->ainsn.insn[0] = *p->addr;
p->ainsn.insn[1] = BREAKPOINT_INSTRUCTION_2;
p->opcode = *p->addr;
}

void arch_arm_kprobe(struct kprobe *p)
{
*p->addr = BREAKPOINT_INSTRUCTION;
flushi(p->addr);
}

void arch_disarm_kprobe(struct kprobe *p)
{
*p->addr = p->opcode;
flushi(p->addr);
}

void arch_remove_kprobe(struct kprobe *p)
Expand Down Expand Up @@ -78,17 +90,6 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
}
}

static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
{
*p->addr = p->opcode;
flushi(p->addr);

regs->tpc = (unsigned long) p->addr;
regs->tnpc = current_kprobe_orig_tnpc;
regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
current_kprobe_orig_tstate_pil);
}

static int kprobe_handler(struct pt_regs *regs)
{
struct kprobe *p;
Expand All @@ -109,7 +110,11 @@ static int kprobe_handler(struct pt_regs *regs)
unlock_kprobes();
goto no_kprobe;
}
disarm_kprobe(p, regs);
arch_disarm_kprobe(p);
regs->tpc = (unsigned long) p->addr;
regs->tnpc = current_kprobe_orig_tnpc;
regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
current_kprobe_orig_tstate_pil);
ret = 1;
} else {
p = current_kprobe;
Expand Down
26 changes: 18 additions & 8 deletions trunk/arch/x86_64/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
#include <linux/slab.h>
#include <linux/preempt.h>
#include <linux/moduleloader.h>

#include <asm/cacheflush.h>
#include <asm/pgtable.h>
#include <asm/kdebug.h>

Expand Down Expand Up @@ -216,19 +216,28 @@ void arch_copy_kprobe(struct kprobe *p)
BUG_ON((s64) (s32) disp != disp); /* Sanity check. */
*ripdisp = disp;
}
p->opcode = *p->addr;
}

void arch_remove_kprobe(struct kprobe *p)
void arch_arm_kprobe(struct kprobe *p)
{
up(&kprobe_mutex);
free_insn_slot(p->ainsn.insn);
down(&kprobe_mutex);
*p->addr = BREAKPOINT_INSTRUCTION;
flush_icache_range((unsigned long) p->addr,
(unsigned long) p->addr + sizeof(kprobe_opcode_t));
}

static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs)
void arch_disarm_kprobe(struct kprobe *p)
{
*p->addr = p->opcode;
regs->rip = (unsigned long)p->addr;
flush_icache_range((unsigned long) p->addr,
(unsigned long) p->addr + sizeof(kprobe_opcode_t));
}

void arch_remove_kprobe(struct kprobe *p)
{
up(&kprobe_mutex);
free_insn_slot(p->ainsn.insn);
down(&kprobe_mutex);
}

static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
Expand Down Expand Up @@ -311,7 +320,8 @@ int kprobe_handler(struct pt_regs *regs)
unlock_kprobes();
goto no_kprobe;
}
disarm_kprobe(p, regs);
arch_disarm_kprobe(p);
regs->rip = (unsigned long)p->addr;
ret = 1;
} else {
p = current_kprobe;
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/kprobes.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ static inline int kprobe_running(void)

extern int arch_prepare_kprobe(struct kprobe *p);
extern void arch_copy_kprobe(struct kprobe *p);
extern void arch_arm_kprobe(struct kprobe *p);
extern void arch_disarm_kprobe(struct kprobe *p);
extern void arch_remove_kprobe(struct kprobe *p);
extern void show_registers(struct pt_regs *regs);

Expand Down
12 changes: 4 additions & 8 deletions trunk/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ static inline void free_rp_inst(struct kretprobe *rp)
static inline void add_aggr_kprobe(struct kprobe *ap, struct kprobe *p)
{
ap->addr = p->addr;
ap->opcode = p->opcode;
memcpy(&ap->opcode, &p->opcode, sizeof(kprobe_opcode_t));
memcpy(&ap->ainsn, &p->ainsn, sizeof(struct arch_specific_insn));

ap->pre_handler = aggr_pre_handler;
Expand Down Expand Up @@ -304,10 +304,8 @@ static int register_aggr_kprobe(struct kprobe *old_p, struct kprobe *p)
/* kprobe removal house-keeping routines */
static inline void cleanup_kprobe(struct kprobe *p, unsigned long flags)
{
*p->addr = p->opcode;
arch_disarm_kprobe(p);
hlist_del(&p->hlist);
flush_icache_range((unsigned long) p->addr,
(unsigned long) p->addr + sizeof(kprobe_opcode_t));
spin_unlock_irqrestore(&kprobe_lock, flags);
arch_remove_kprobe(p);
}
Expand Down Expand Up @@ -344,10 +342,8 @@ int register_kprobe(struct kprobe *p)
hlist_add_head(&p->hlist,
&kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);

p->opcode = *p->addr;
*p->addr = BREAKPOINT_INSTRUCTION;
flush_icache_range((unsigned long) p->addr,
(unsigned long) p->addr + sizeof(kprobe_opcode_t));
arch_arm_kprobe(p);

out:
spin_unlock_irqrestore(&kprobe_lock, flags);
rm_kprobe:
Expand Down

0 comments on commit 97b0ba0

Please sign in to comment.