hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/arch/s390/kernel/kprobes.c
....@@ -7,6 +7,7 @@
77 * s390 port, used ppc64 as template. Mike Grundy <grundym@us.ibm.com>
88 */
99
10
+#include <linux/moduleloader.h>
1011 #include <linux/kprobes.h>
1112 #include <linux/ptrace.h>
1213 #include <linux/preempt.h>
....@@ -21,70 +22,78 @@
2122 #include <asm/set_memory.h>
2223 #include <asm/sections.h>
2324 #include <asm/dis.h>
25
+#include "entry.h"
2426
2527 DEFINE_PER_CPU(struct kprobe *, current_kprobe);
2628 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
2729
2830 struct kretprobe_blackpoint kretprobe_blacklist[] = { };
2931
30
-DEFINE_INSN_CACHE_OPS(dmainsn);
32
+DEFINE_INSN_CACHE_OPS(s390_insn);
3133
32
-static void *alloc_dmainsn_page(void)
34
+static int insn_page_in_use;
35
+
36
+void *alloc_insn_page(void)
3337 {
3438 void *page;
3539
36
- page = (void *) __get_free_page(GFP_KERNEL | GFP_DMA);
37
- if (page)
38
- set_memory_x((unsigned long) page, 1);
40
+ page = module_alloc(PAGE_SIZE);
41
+ if (!page)
42
+ return NULL;
43
+ __set_memory((unsigned long) page, 1, SET_MEMORY_RO | SET_MEMORY_X);
3944 return page;
4045 }
4146
42
-static void free_dmainsn_page(void *page)
47
+void free_insn_page(void *page)
4348 {
44
- set_memory_nx((unsigned long) page, 1);
45
- free_page((unsigned long)page);
49
+ module_memfree(page);
4650 }
4751
48
-struct kprobe_insn_cache kprobe_dmainsn_slots = {
49
- .mutex = __MUTEX_INITIALIZER(kprobe_dmainsn_slots.mutex),
50
- .alloc = alloc_dmainsn_page,
51
- .free = free_dmainsn_page,
52
- .pages = LIST_HEAD_INIT(kprobe_dmainsn_slots.pages),
52
+static void *alloc_s390_insn_page(void)
53
+{
54
+ if (xchg(&insn_page_in_use, 1) == 1)
55
+ return NULL;
56
+ return &kprobes_insn_page;
57
+}
58
+
59
+static void free_s390_insn_page(void *page)
60
+{
61
+ xchg(&insn_page_in_use, 0);
62
+}
63
+
64
+struct kprobe_insn_cache kprobe_s390_insn_slots = {
65
+ .mutex = __MUTEX_INITIALIZER(kprobe_s390_insn_slots.mutex),
66
+ .alloc = alloc_s390_insn_page,
67
+ .free = free_s390_insn_page,
68
+ .pages = LIST_HEAD_INIT(kprobe_s390_insn_slots.pages),
5369 .insn_size = MAX_INSN_SIZE,
5470 };
5571
5672 static void copy_instruction(struct kprobe *p)
5773 {
58
- unsigned long ip = (unsigned long) p->addr;
74
+ kprobe_opcode_t insn[MAX_INSN_SIZE];
5975 s64 disp, new_disp;
6076 u64 addr, new_addr;
77
+ unsigned int len;
6178
62
- if (ftrace_location(ip) == ip) {
79
+ len = insn_length(*p->addr >> 8);
80
+ memcpy(&insn, p->addr, len);
81
+ p->opcode = insn[0];
82
+ if (probe_is_insn_relative_long(&insn[0])) {
6383 /*
64
- * If kprobes patches the instruction that is morphed by
65
- * ftrace make sure that kprobes always sees the branch
66
- * "jg .+24" that skips the mcount block or the "brcl 0,0"
67
- * in case of hotpatch.
84
+ * For pc-relative instructions in RIL-b or RIL-c format patch
85
+ * the RI2 displacement field. We have already made sure that
86
+ * the insn slot for the patched instruction is within the same
87
+ * 2GB area as the original instruction (either kernel image or
88
+ * module area). Therefore the new displacement will always fit.
6889 */
69
- ftrace_generate_nop_insn((struct ftrace_insn *)p->ainsn.insn);
70
- p->ainsn.is_ftrace_insn = 1;
71
- } else
72
- memcpy(p->ainsn.insn, p->addr, insn_length(*p->addr >> 8));
73
- p->opcode = p->ainsn.insn[0];
74
- if (!probe_is_insn_relative_long(p->ainsn.insn))
75
- return;
76
- /*
77
- * For pc-relative instructions in RIL-b or RIL-c format patch the
78
- * RI2 displacement field. We have already made sure that the insn
79
- * slot for the patched instruction is within the same 2GB area
80
- * as the original instruction (either kernel image or module area).
81
- * Therefore the new displacement will always fit.
82
- */
83
- disp = *(s32 *)&p->ainsn.insn[1];
84
- addr = (u64)(unsigned long)p->addr;
85
- new_addr = (u64)(unsigned long)p->ainsn.insn;
86
- new_disp = ((addr + (disp * 2)) - new_addr) / 2;
87
- *(s32 *)&p->ainsn.insn[1] = new_disp;
90
+ disp = *(s32 *)&insn[1];
91
+ addr = (u64)(unsigned long)p->addr;
92
+ new_addr = (u64)(unsigned long)p->ainsn.insn;
93
+ new_disp = ((addr + (disp * 2)) - new_addr) / 2;
94
+ *(s32 *)&insn[1] = new_disp;
95
+ }
96
+ s390_kernel_write(p->ainsn.insn, &insn, len);
8897 }
8998 NOKPROBE_SYMBOL(copy_instruction);
9099
....@@ -102,7 +111,7 @@
102111 */
103112 p->ainsn.insn = NULL;
104113 if (is_kernel_addr(p->addr))
105
- p->ainsn.insn = get_dmainsn_slot();
114
+ p->ainsn.insn = get_s390_insn_slot();
106115 else if (is_module_addr(p->addr))
107116 p->ainsn.insn = get_insn_slot();
108117 return p->ainsn.insn ? 0 : -ENOMEM;
....@@ -114,7 +123,7 @@
114123 if (!p->ainsn.insn)
115124 return;
116125 if (is_kernel_addr(p->addr))
117
- free_dmainsn_slot(p->ainsn.insn, 0);
126
+ free_s390_insn_slot(p->ainsn.insn, 0);
118127 else
119128 free_insn_slot(p->ainsn.insn, 0);
120129 p->ainsn.insn = NULL;
....@@ -135,11 +144,6 @@
135144 }
136145 NOKPROBE_SYMBOL(arch_prepare_kprobe);
137146
138
-int arch_check_ftrace_location(struct kprobe *p)
139
-{
140
- return 0;
141
-}
142
-
143147 struct swap_insn_args {
144148 struct kprobe *p;
145149 unsigned int arm_kprobe : 1;
....@@ -148,28 +152,11 @@
148152 static int swap_instruction(void *data)
149153 {
150154 struct swap_insn_args *args = data;
151
- struct ftrace_insn new_insn, *insn;
152155 struct kprobe *p = args->p;
153
- size_t len;
156
+ u16 opc;
154157
155
- new_insn.opc = args->arm_kprobe ? BREAKPOINT_INSTRUCTION : p->opcode;
156
- len = sizeof(new_insn.opc);
157
- if (!p->ainsn.is_ftrace_insn)
158
- goto skip_ftrace;
159
- len = sizeof(new_insn);
160
- insn = (struct ftrace_insn *) p->addr;
161
- if (args->arm_kprobe) {
162
- if (is_ftrace_nop(insn))
163
- new_insn.disp = KPROBE_ON_FTRACE_NOP;
164
- else
165
- new_insn.disp = KPROBE_ON_FTRACE_CALL;
166
- } else {
167
- ftrace_generate_call_insn(&new_insn, (unsigned long)p->addr);
168
- if (insn->disp == KPROBE_ON_FTRACE_NOP)
169
- ftrace_generate_nop_insn(&new_insn);
170
- }
171
-skip_ftrace:
172
- s390_kernel_write(p->addr, &new_insn, len);
158
+ opc = args->arm_kprobe ? BREAKPOINT_INSTRUCTION : p->opcode;
159
+ s390_kernel_write(p->addr, &opc, sizeof(opc));
173160 return 0;
174161 }
175162 NOKPROBE_SYMBOL(swap_instruction);
....@@ -254,12 +241,14 @@
254241 {
255242 __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
256243 kcb->kprobe_status = kcb->prev_kprobe.status;
244
+ kcb->prev_kprobe.kp = NULL;
257245 }
258246 NOKPROBE_SYMBOL(pop_kprobe);
259247
260248 void arch_prepare_kretprobe(struct kretprobe_instance *ri, struct pt_regs *regs)
261249 {
262250 ri->ret_addr = (kprobe_opcode_t *) regs->gprs[14];
251
+ ri->fp = NULL;
263252
264253 /* Replace the return addr with trampoline addr */
265254 regs->gprs[14] = (unsigned long) &kretprobe_trampoline;
....@@ -363,83 +352,7 @@
363352 */
364353 static int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
365354 {
366
- struct kretprobe_instance *ri;
367
- struct hlist_head *head, empty_rp;
368
- struct hlist_node *tmp;
369
- unsigned long flags, orig_ret_address;
370
- unsigned long trampoline_address;
371
- kprobe_opcode_t *correct_ret_addr;
372
-
373
- INIT_HLIST_HEAD(&empty_rp);
374
- kretprobe_hash_lock(current, &head, &flags);
375
-
376
- /*
377
- * It is possible to have multiple instances associated with a given
378
- * task either because an multiple functions in the call path
379
- * have a return probe installed on them, and/or more than one return
380
- * return probe was registered for a target function.
381
- *
382
- * We can handle this because:
383
- * - instances are always inserted at the head of the list
384
- * - when multiple return probes are registered for the same
385
- * function, the first instance's ret_addr will point to the
386
- * real return address, and all the rest will point to
387
- * kretprobe_trampoline
388
- */
389
- ri = NULL;
390
- orig_ret_address = 0;
391
- correct_ret_addr = NULL;
392
- trampoline_address = (unsigned long) &kretprobe_trampoline;
393
- hlist_for_each_entry_safe(ri, tmp, head, hlist) {
394
- if (ri->task != current)
395
- /* another task is sharing our hash bucket */
396
- continue;
397
-
398
- orig_ret_address = (unsigned long) ri->ret_addr;
399
-
400
- if (orig_ret_address != trampoline_address)
401
- /*
402
- * This is the real return address. Any other
403
- * instances associated with this task are for
404
- * other calls deeper on the call stack
405
- */
406
- break;
407
- }
408
-
409
- kretprobe_assert(ri, orig_ret_address, trampoline_address);
410
-
411
- correct_ret_addr = ri->ret_addr;
412
- hlist_for_each_entry_safe(ri, tmp, head, hlist) {
413
- if (ri->task != current)
414
- /* another task is sharing our hash bucket */
415
- continue;
416
-
417
- orig_ret_address = (unsigned long) ri->ret_addr;
418
-
419
- if (ri->rp && ri->rp->handler) {
420
- ri->ret_addr = correct_ret_addr;
421
- ri->rp->handler(ri, regs);
422
- }
423
-
424
- recycle_rp_inst(ri, &empty_rp);
425
-
426
- if (orig_ret_address != trampoline_address)
427
- /*
428
- * This is the real return address. Any other
429
- * instances associated with this task are for
430
- * other calls deeper on the call stack
431
- */
432
- break;
433
- }
434
-
435
- regs->psw.addr = orig_ret_address;
436
-
437
- kretprobe_hash_unlock(current, &flags);
438
-
439
- hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
440
- hlist_del(&ri->hlist);
441
- kfree(ri);
442
- }
355
+ regs->psw.addr = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL);
443356 /*
444357 * By returning a non-zero value, we are telling
445358 * kprobe_handler() that we don't want the post_handler
....@@ -462,24 +375,6 @@
462375 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
463376 unsigned long ip = regs->psw.addr;
464377 int fixup = probe_get_fixup_type(p->ainsn.insn);
465
-
466
- /* Check if the kprobes location is an enabled ftrace caller */
467
- if (p->ainsn.is_ftrace_insn) {
468
- struct ftrace_insn *insn = (struct ftrace_insn *) p->addr;
469
- struct ftrace_insn call_insn;
470
-
471
- ftrace_generate_call_insn(&call_insn, (unsigned long) p->addr);
472
- /*
473
- * A kprobe on an enabled ftrace call site actually single
474
- * stepped an unconditional branch (ftrace nop equivalent).
475
- * Now we need to fixup things and pretend that a brasl r0,...
476
- * was executed instead.
477
- */
478
- if (insn->disp == KPROBE_ON_FTRACE_CALL) {
479
- ip += call_insn.disp * 2 - MCOUNT_INSN_SIZE;
480
- regs->gprs[0] = (unsigned long)p->addr + sizeof(*insn);
481
- }
482
- }
483378
484379 if (fixup & FIXUP_PSW_NORMAL)
485380 ip += (unsigned long) p->addr - (unsigned long) p->ainsn.insn;
....@@ -508,12 +403,11 @@
508403 if (!p)
509404 return 0;
510405
406
+ resume_execution(p, regs);
511407 if (kcb->kprobe_status != KPROBE_REENTER && p->post_handler) {
512408 kcb->kprobe_status = KPROBE_HIT_SSDONE;
513409 p->post_handler(p, regs, 0);
514410 }
515
-
516
- resume_execution(p, regs);
517411 pop_kprobe(kcb);
518412 preempt_enable_no_resched();
519413
....@@ -572,11 +466,9 @@
572466 * In case the user-specified fault handler returned
573467 * zero, try to fix up.
574468 */
575
- entry = search_exception_tables(regs->psw.addr);
576
- if (entry) {
577
- regs->psw.addr = extable_fixup(entry);
469
+ entry = s390_search_extables(regs->psw.addr);
470
+ if (entry && ex_handle(entry, regs))
578471 return 1;
579
- }
580472
581473 /*
582474 * fixup_exception() could not handle it,