Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 126341
b: refs/heads/master
c: 1294156
h: refs/heads/master
i:
  126339: a748b6b
v: v3
  • Loading branch information
Masami Hiramatsu authored and Linus Torvalds committed Jan 6, 2009
1 parent e5385d9 commit aa5223e
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 20 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: a06f6211ef9b1785922f9d0e8766d63ac4e66de1
refs/heads/master: 129415607845d4daea11ddcba706005c69dcb942
2 changes: 0 additions & 2 deletions trunk/arch/arm/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
void __kprobes arch_remove_kprobe(struct kprobe *p)
{
if (p->ainsn.insn) {
mutex_lock(&kprobe_mutex);
free_insn_slot(p->ainsn.insn, 0);
mutex_unlock(&kprobe_mutex);
p->ainsn.insn = NULL;
}
}
Expand Down
8 changes: 5 additions & 3 deletions trunk/arch/ia64/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -670,9 +670,11 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)

void __kprobes arch_remove_kprobe(struct kprobe *p)
{
mutex_lock(&kprobe_mutex);
free_insn_slot(p->ainsn.insn, p->ainsn.inst_flag & INST_FLAG_BOOSTABLE);
mutex_unlock(&kprobe_mutex);
if (p->ainsn.insn) {
free_insn_slot(p->ainsn.insn,
p->ainsn.inst_flag & INST_FLAG_BOOSTABLE);
p->ainsn.insn = NULL;
}
}
/*
* We are resuming execution after a single step fault, so the pt_regs
Expand Down
7 changes: 4 additions & 3 deletions trunk/arch/powerpc/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,10 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)

void __kprobes arch_remove_kprobe(struct kprobe *p)
{
mutex_lock(&kprobe_mutex);
free_insn_slot(p->ainsn.insn, 0);
mutex_unlock(&kprobe_mutex);
if (p->ainsn.insn) {
free_insn_slot(p->ainsn.insn, 0);
p->ainsn.insn = NULL;
}
}

static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
Expand Down
7 changes: 4 additions & 3 deletions trunk/arch/s390/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,10 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)

void __kprobes arch_remove_kprobe(struct kprobe *p)
{
mutex_lock(&kprobe_mutex);
free_insn_slot(p->ainsn.insn, 0);
mutex_unlock(&kprobe_mutex);
if (p->ainsn.insn) {
free_insn_slot(p->ainsn.insn, 0);
p->ainsn.insn = NULL;
}
}

static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
Expand Down
7 changes: 4 additions & 3 deletions trunk/arch/x86/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,9 +376,10 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)

void __kprobes arch_remove_kprobe(struct kprobe *p)
{
mutex_lock(&kprobe_mutex);
free_insn_slot(p->ainsn.insn, (p->ainsn.boostable == 1));
mutex_unlock(&kprobe_mutex);
if (p->ainsn.insn) {
free_insn_slot(p->ainsn.insn, (p->ainsn.boostable == 1));
p->ainsn.insn = NULL;
}
}

static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
Expand Down
1 change: 0 additions & 1 deletion trunk/include/linux/kprobes.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,6 @@ static inline int init_test_probes(void)
}
#endif /* CONFIG_KPROBES_SANITY_TEST */

extern struct mutex kprobe_mutex;
extern int arch_prepare_kprobe(struct kprobe *p);
extern void arch_arm_kprobe(struct kprobe *p);
extern void arch_disarm_kprobe(struct kprobe *p);
Expand Down
25 changes: 21 additions & 4 deletions trunk/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
/* NOTE: change this value only with kprobe_mutex held */
static bool kprobe_enabled;

DEFINE_MUTEX(kprobe_mutex); /* Protects kprobe_table */
static DEFINE_MUTEX(kprobe_mutex); /* Protects kprobe_table */
static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL;
static struct {
spinlock_t lock ____cacheline_aligned_in_smp;
Expand Down Expand Up @@ -115,6 +115,7 @@ enum kprobe_slot_state {
SLOT_USED = 2,
};

static DEFINE_MUTEX(kprobe_insn_mutex); /* Protects kprobe_insn_pages */
static struct hlist_head kprobe_insn_pages;
static int kprobe_garbage_slots;
static int collect_garbage_slots(void);
Expand Down Expand Up @@ -144,10 +145,10 @@ static int __kprobes check_safety(void)
}

/**
* get_insn_slot() - Find a slot on an executable page for an instruction.
* __get_insn_slot() - Find a slot on an executable page for an instruction.
* We allocate an executable page if there's no room on existing ones.
*/
kprobe_opcode_t __kprobes *get_insn_slot(void)
static kprobe_opcode_t __kprobes *__get_insn_slot(void)
{
struct kprobe_insn_page *kip;
struct hlist_node *pos;
Expand Down Expand Up @@ -196,6 +197,15 @@ kprobe_opcode_t __kprobes *get_insn_slot(void)
return kip->insns;
}

kprobe_opcode_t __kprobes *get_insn_slot(void)
{
kprobe_opcode_t *ret;
mutex_lock(&kprobe_insn_mutex);
ret = __get_insn_slot();
mutex_unlock(&kprobe_insn_mutex);
return ret;
}

/* Return 1 if all garbages are collected, otherwise 0. */
static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx)
{
Expand Down Expand Up @@ -226,9 +236,13 @@ static int __kprobes collect_garbage_slots(void)
{
struct kprobe_insn_page *kip;
struct hlist_node *pos, *next;
int safety;

/* Ensure no-one is preepmted on the garbages */
if (check_safety() != 0)
mutex_unlock(&kprobe_insn_mutex);
safety = check_safety();
mutex_lock(&kprobe_insn_mutex);
if (safety != 0)
return -EAGAIN;

hlist_for_each_entry_safe(kip, pos, next, &kprobe_insn_pages, hlist) {
Expand All @@ -251,6 +265,7 @@ void __kprobes free_insn_slot(kprobe_opcode_t * slot, int dirty)
struct kprobe_insn_page *kip;
struct hlist_node *pos;

mutex_lock(&kprobe_insn_mutex);
hlist_for_each_entry(kip, pos, &kprobe_insn_pages, hlist) {
if (kip->insns <= slot &&
slot < kip->insns + (INSNS_PER_PAGE * MAX_INSN_SIZE)) {
Expand All @@ -267,6 +282,8 @@ void __kprobes free_insn_slot(kprobe_opcode_t * slot, int dirty)

if (dirty && ++kprobe_garbage_slots > INSNS_PER_PAGE)
collect_garbage_slots();

mutex_unlock(&kprobe_insn_mutex);
}
#endif

Expand Down

0 comments on commit aa5223e

Please sign in to comment.