1 #include <linux/slab.h>
2 #include <linux/hardirq.h>
3 #include <linux/sched.h>
5 #include <linux/mman.h>
6 #include <linux/list.h>
7 #include <dbi_insn_slots.h>
8 #include <asm/dbi_kprobes.h>
10 static unsigned long alloc_user_pages(struct task_struct *task, unsigned long len, unsigned long prot, unsigned long flags)
12 unsigned long ret = 0;
13 struct task_struct *otask = current;
15 int atomic = in_atomic();
17 mm = atomic ? task->active_mm : get_task_mm(task);
20 if (!down_write_trylock(&mm->mmap_sem)) {
23 up_read(&mm->mmap_sem);
24 down_write(&mm->mmap_sem);
29 // FIXME: its seems to be bad decision to replace 'current' pointer temporarily
30 current_thread_info()->task = task;
31 ret = do_mmap_pgoff(NULL, 0, len, prot, flags, 0);
32 current_thread_info()->task = otask;
34 downgrade_write (&mm->mmap_sem);
38 printk("proc %d has no mm", task->tgid);
44 static void *sm_alloc_us(struct slot_manager *sm)
46 struct task_struct *task = sm->data;
48 return (void *)alloc_user_pages(task, PAGE_SIZE,
49 PROT_EXEC|PROT_READ|PROT_WRITE,
50 MAP_ANONYMOUS|MAP_PRIVATE);
53 static void sm_free_us(struct slot_manager *sm, void *ptr)
55 struct task_struct *task = sm->data;
58 * E. G.: This code provides kernel dump because of rescheduling while atomic.
59 * As workaround, this code was commented. In this case we will have memory leaks
60 * for instrumented process, but instrumentation process should functionate correctly.
61 * Planned that good solution for this problem will be done during redesigning KProbe
62 * for improving supportability and performance.
65 mm = get_task_mm(task);
67 down_write(&mm->mmap_sem);
68 do_munmap(mm, (unsigned long)(ptr), PAGE_SIZE);
69 up_write(&mm->mmap_sem);
73 /* FIXME: implement the removal of memory for task */
76 struct slot_manager *create_sm_us(struct task_struct *task)
78 struct slot_manager *sm = kmalloc(sizeof(*sm), GFP_ATOMIC);
79 sm->slot_size = UPROBES_TRAMP_LEN;
80 sm->alloc = sm_alloc_us;
81 sm->free = sm_free_us;
82 INIT_HLIST_NODE(&sm->page_list);
88 void free_sm_us(struct slot_manager *sm)