hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/arch/mips/kernel/kprobes.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Kernel Probes (KProbes)
34 * arch/mips/kernel/kprobes.c
....@@ -8,19 +9,6 @@
89 * Some portions copied from the powerpc version.
910 *
1011 * Copyright (C) IBM Corporation, 2002, 2004
11
- *
12
- * This program is free software; you can redistribute it and/or modify
13
- * it under the terms of the GNU General Public License as published by
14
- * the Free Software Foundation; version 2 of the License.
15
- *
16
- * This program is distributed in the hope that it will be useful,
17
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
- * GNU General Public License for more details.
20
- *
21
- * You should have received a copy of the GNU General Public License
22
- * along with this program; if not, write to the Free Software
23
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2412 */
2513
2614 #include <linux/kprobes.h>
....@@ -98,9 +86,9 @@
9886 goto out;
9987 }
10088
101
- if ((probe_kernel_read(&prev_insn, p->addr - 1,
102
- sizeof(mips_instruction)) == 0) &&
103
- insn_has_delayslot(prev_insn)) {
89
+ if (copy_from_kernel_nofault(&prev_insn, p->addr - 1,
90
+ sizeof(mips_instruction)) == 0 &&
91
+ insn_has_delayslot(prev_insn)) {
10492 pr_notice("Kprobes for branch delayslot are not supported\n");
10593 ret = -EINVAL;
10694 goto out;
....@@ -232,7 +220,7 @@
232220
233221 unaligned:
234222 pr_notice("%s: unaligned epc - sending SIGBUS.\n", current->comm);
235
- force_sig(SIGBUS, current);
223
+ force_sig(SIGBUS);
236224 return -EFAULT;
237225
238226 }
....@@ -410,7 +398,7 @@
410398 return 1;
411399 }
412400
413
-static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
401
+int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
414402 {
415403 struct kprobe *cur = kprobe_running();
416404 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
....@@ -489,6 +477,7 @@
489477 struct pt_regs *regs)
490478 {
491479 ri->ret_addr = (kprobe_opcode_t *) regs->regs[31];
480
+ ri->fp = NULL;
492481
493482 /* Replace the return addr with trampoline addr */
494483 regs->regs[31] = (unsigned long)kretprobe_trampoline;
....@@ -500,57 +489,8 @@
500489 static int __kprobes trampoline_probe_handler(struct kprobe *p,
501490 struct pt_regs *regs)
502491 {
503
- struct kretprobe_instance *ri = NULL;
504
- struct hlist_head *head, empty_rp;
505
- struct hlist_node *tmp;
506
- unsigned long flags, orig_ret_address = 0;
507
- unsigned long trampoline_address = (unsigned long)kretprobe_trampoline;
508
-
509
- INIT_HLIST_HEAD(&empty_rp);
510
- kretprobe_hash_lock(current, &head, &flags);
511
-
512
- /*
513
- * It is possible to have multiple instances associated with a given
514
- * task either because an multiple functions in the call path
515
- * have a return probe installed on them, and/or more than one return
516
- * return probe was registered for a target function.
517
- *
518
- * We can handle this because:
519
- * - instances are always inserted at the head of the list
520
- * - when multiple return probes are registered for the same
521
- * function, the first instance's ret_addr will point to the
522
- * real return address, and all the rest will point to
523
- * kretprobe_trampoline
524
- */
525
- hlist_for_each_entry_safe(ri, tmp, head, hlist) {
526
- if (ri->task != current)
527
- /* another task is sharing our hash bucket */
528
- continue;
529
-
530
- if (ri->rp && ri->rp->handler)
531
- ri->rp->handler(ri, regs);
532
-
533
- orig_ret_address = (unsigned long)ri->ret_addr;
534
- recycle_rp_inst(ri, &empty_rp);
535
-
536
- if (orig_ret_address != trampoline_address)
537
- /*
538
- * This is the real return address. Any other
539
- * instances associated with this task are for
540
- * other calls deeper on the call stack
541
- */
542
- break;
543
- }
544
-
545
- kretprobe_assert(ri, orig_ret_address, trampoline_address);
546
- instruction_pointer(regs) = orig_ret_address;
547
-
548
- kretprobe_hash_unlock(current, &flags);
549
-
550
- hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
551
- hlist_del(&ri->hlist);
552
- kfree(ri);
553
- }
492
+ instruction_pointer(regs) = __kretprobe_trampoline_handler(regs,
493
+ kretprobe_trampoline, NULL);
554494 /*
555495 * By returning a non-zero value, we are telling
556496 * kprobe_handler() that we don't want the post_handler