|
@@ -112,6 +112,7 @@ static struct kprobe_blackpoint kprobe_blacklist[] = {
|
|
|
struct kprobe_insn_page {
|
|
|
struct list_head list;
|
|
|
kprobe_opcode_t *insns; /* Page of instruction slots */
|
|
|
+ struct kprobe_insn_cache *cache;
|
|
|
int nused;
|
|
|
int ngarbage;
|
|
|
char slot_used[];
|
|
@@ -132,8 +133,20 @@ enum kprobe_slot_state {
|
|
|
SLOT_USED = 2,
|
|
|
};
|
|
|
|
|
|
+static void *alloc_insn_page(void)
|
|
|
+{
|
|
|
+ return module_alloc(PAGE_SIZE);
|
|
|
+}
|
|
|
+
|
|
|
+static void free_insn_page(void *page)
|
|
|
+{
|
|
|
+ module_free(NULL, page);
|
|
|
+}
|
|
|
+
|
|
|
struct kprobe_insn_cache kprobe_insn_slots = {
|
|
|
.mutex = __MUTEX_INITIALIZER(kprobe_insn_slots.mutex),
|
|
|
+ .alloc = alloc_insn_page,
|
|
|
+ .free = free_insn_page,
|
|
|
.pages = LIST_HEAD_INIT(kprobe_insn_slots.pages),
|
|
|
.insn_size = MAX_INSN_SIZE,
|
|
|
.nr_garbage = 0,
|
|
@@ -182,7 +195,7 @@ kprobe_opcode_t __kprobes *__get_insn_slot(struct kprobe_insn_cache *c)
|
|
|
* kernel image and loaded module images reside. This is required
|
|
|
* so x86_64 can correctly handle the %rip-relative fixups.
|
|
|
*/
|
|
|
- kip->insns = module_alloc(PAGE_SIZE);
|
|
|
+ kip->insns = c->alloc();
|
|
|
if (!kip->insns) {
|
|
|
kfree(kip);
|
|
|
goto out;
|
|
@@ -192,6 +205,7 @@ kprobe_opcode_t __kprobes *__get_insn_slot(struct kprobe_insn_cache *c)
|
|
|
kip->slot_used[0] = SLOT_USED;
|
|
|
kip->nused = 1;
|
|
|
kip->ngarbage = 0;
|
|
|
+ kip->cache = c;
|
|
|
list_add(&kip->list, &c->pages);
|
|
|
slot = kip->insns;
|
|
|
out:
|
|
@@ -213,7 +227,7 @@ static int __kprobes collect_one_slot(struct kprobe_insn_page *kip, int idx)
|
|
|
*/
|
|
|
if (!list_is_singular(&kip->list)) {
|
|
|
list_del(&kip->list);
|
|
|
- module_free(NULL, kip->insns);
|
|
|
+ kip->cache->free(kip->insns);
|
|
|
kfree(kip);
|
|
|
}
|
|
|
return 1;
|
|
@@ -274,6 +288,8 @@ out:
|
|
|
/* For optimized_kprobe buffer */
|
|
|
struct kprobe_insn_cache kprobe_optinsn_slots = {
|
|
|
.mutex = __MUTEX_INITIALIZER(kprobe_optinsn_slots.mutex),
|
|
|
+ .alloc = alloc_insn_page,
|
|
|
+ .free = free_insn_page,
|
|
|
.pages = LIST_HEAD_INIT(kprobe_optinsn_slots.pages),
|
|
|
/* .insn_size is initialized later */
|
|
|
.nr_garbage = 0,
|