diff options
Diffstat (limited to 'kernel/kprobes.c')
| -rw-r--r-- | kernel/kprobes.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 17ec4afb0994..6fcf8dd148d0 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
| @@ -87,6 +87,12 @@ struct kprobe_insn_page { | |||
| 87 | int ngarbage; | 87 | int ngarbage; |
| 88 | }; | 88 | }; |
| 89 | 89 | ||
| 90 | enum kprobe_slot_state { | ||
| 91 | SLOT_CLEAN = 0, | ||
| 92 | SLOT_DIRTY = 1, | ||
| 93 | SLOT_USED = 2, | ||
| 94 | }; | ||
| 95 | |||
| 90 | static struct hlist_head kprobe_insn_pages; | 96 | static struct hlist_head kprobe_insn_pages; |
| 91 | static int kprobe_garbage_slots; | 97 | static int kprobe_garbage_slots; |
| 92 | static int collect_garbage_slots(void); | 98 | static int collect_garbage_slots(void); |
| @@ -130,8 +136,8 @@ kprobe_opcode_t __kprobes *get_insn_slot(void) | |||
| 130 | if (kip->nused < INSNS_PER_PAGE) { | 136 | if (kip->nused < INSNS_PER_PAGE) { |
| 131 | int i; | 137 | int i; |
| 132 | for (i = 0; i < INSNS_PER_PAGE; i++) { | 138 | for (i = 0; i < INSNS_PER_PAGE; i++) { |
| 133 | if (!kip->slot_used[i]) { | 139 | if (kip->slot_used[i] == SLOT_CLEAN) { |
| 134 | kip->slot_used[i] = 1; | 140 | kip->slot_used[i] = SLOT_USED; |
| 135 | kip->nused++; | 141 | kip->nused++; |
| 136 | return kip->insns + (i * MAX_INSN_SIZE); | 142 | return kip->insns + (i * MAX_INSN_SIZE); |
| 137 | } | 143 | } |
| @@ -163,8 +169,8 @@ kprobe_opcode_t __kprobes *get_insn_slot(void) | |||
| 163 | } | 169 | } |
| 164 | INIT_HLIST_NODE(&kip->hlist); | 170 | INIT_HLIST_NODE(&kip->hlist); |
| 165 | hlist_add_head(&kip->hlist, &kprobe_insn_pages); | 171 | hlist_add_head(&kip->hlist, &kprobe_insn_pages); |
| 166 | memset(kip->slot_used, 0, INSNS_PER_PAGE); | 172 | memset(kip->slot_used, SLOT_CLEAN, INSNS_PER_PAGE); |
| 167 | kip->slot_used[0] = 1; | 173 | kip->slot_used[0] = SLOT_USED; |
| 168 | kip->nused = 1; | 174 | kip->nused = 1; |
| 169 | kip->ngarbage = 0; | 175 | kip->ngarbage = 0; |
| 170 | return kip->insns; | 176 | return kip->insns; |
| @@ -173,7 +179,7 @@ kprobe_opcode_t __kprobes *get_insn_slot(void) | |||
| 173 | /* Return 1 if all garbages are collected, otherwise 0. */ | 179 | /* Return 1 if all garbages are collected, otherwise 0. */ |
| 174 | static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx) | 180 | static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx) |
| 175 | { | 181 | { |
| 176 | kip->slot_used[idx] = 0; | 182 | kip->slot_used[idx] = SLOT_CLEAN; |
| 177 | kip->nused--; | 183 | kip->nused--; |
| 178 | if (kip->nused == 0) { | 184 | if (kip->nused == 0) { |
| 179 | /* | 185 | /* |
| @@ -212,7 +218,7 @@ static int __kprobes collect_garbage_slots(void) | |||
| 212 | continue; | 218 | continue; |
| 213 | kip->ngarbage = 0; /* we will collect all garbages */ | 219 | kip->ngarbage = 0; /* we will collect all garbages */ |
| 214 | for (i = 0; i < INSNS_PER_PAGE; i++) { | 220 | for (i = 0; i < INSNS_PER_PAGE; i++) { |
| 215 | if (kip->slot_used[i] == -1 && | 221 | if (kip->slot_used[i] == SLOT_DIRTY && |
| 216 | collect_one_slot(kip, i)) | 222 | collect_one_slot(kip, i)) |
| 217 | break; | 223 | break; |
| 218 | } | 224 | } |
| @@ -232,7 +238,7 @@ void __kprobes free_insn_slot(kprobe_opcode_t * slot, int dirty) | |||
| 232 | slot < kip->insns + (INSNS_PER_PAGE * MAX_INSN_SIZE)) { | 238 | slot < kip->insns + (INSNS_PER_PAGE * MAX_INSN_SIZE)) { |
| 233 | int i = (slot - kip->insns) / MAX_INSN_SIZE; | 239 | int i = (slot - kip->insns) / MAX_INSN_SIZE; |
| 234 | if (dirty) { | 240 | if (dirty) { |
| 235 | kip->slot_used[i] = -1; | 241 | kip->slot_used[i] = SLOT_DIRTY; |
| 236 | kip->ngarbage++; | 242 | kip->ngarbage++; |
| 237 | } else { | 243 | } else { |
| 238 | collect_one_slot(kip, i); | 244 | collect_one_slot(kip, i); |
