~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arc/kernel/kprobes.c

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /arch/arc/kernel/kprobes.c (Architecture sparc) and /arch/mips/kernel/kprobes.c (Architecture mips)


  1 // SPDX-License-Identifier: GPL-2.0-only            1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*                                                  2 /*
  3  * Copyright (C) 2004, 2007-2010, 2011-2012 Sy !!   3  *  Kernel Probes (KProbes)
                                                   >>   4  *  arch/mips/kernel/kprobes.c
                                                   >>   5  *
                                                   >>   6  *  Copyright 2006 Sony Corp.
                                                   >>   7  *  Copyright 2010 Cavium Networks
                                                   >>   8  *
                                                   >>   9  *  Some portions copied from the powerpc version.
                                                   >>  10  *
                                                   >>  11  *   Copyright (C) IBM Corporation, 2002, 2004
  4  */                                                12  */
  5                                                    13 
  6 #include <linux/types.h>                       !!  14 #define pr_fmt(fmt) "kprobes: " fmt
                                                   >>  15 
  7 #include <linux/kprobes.h>                         16 #include <linux/kprobes.h>
  8 #include <linux/slab.h>                        !!  17 #include <linux/preempt.h>
  9 #include <linux/module.h>                      << 
 10 #include <linux/kdebug.h>                      << 
 11 #include <linux/sched.h>                       << 
 12 #include <linux/uaccess.h>                         18 #include <linux/uaccess.h>
 13 #include <asm/cacheflush.h>                    !!  19 #include <linux/kdebug.h>
 14 #include <asm/current.h>                       !!  20 #include <linux/slab.h>
 15 #include <asm/disasm.h>                        << 
 16                                                    21 
 17 #define MIN_STACK_SIZE(addr)    min((unsigned  !!  22 #include <asm/ptrace.h>
 18                 (unsigned long)current_thread_ !!  23 #include <asm/branch.h>
                                                   >>  24 #include <asm/break.h>
                                                   >>  25 
                                                   >>  26 #include "probes-common.h"
                                                   >>  27 
                                                   >>  28 static const union mips_instruction breakpoint_insn = {
                                                   >>  29         .b_format = {
                                                   >>  30                 .opcode = spec_op,
                                                   >>  31                 .code = BRK_KPROBE_BP,
                                                   >>  32                 .func = break_op
                                                   >>  33         }
                                                   >>  34 };
                                                   >>  35 
                                                   >>  36 static const union mips_instruction breakpoint2_insn = {
                                                   >>  37         .b_format = {
                                                   >>  38                 .opcode = spec_op,
                                                   >>  39                 .code = BRK_KPROBE_SSTEPBP,
                                                   >>  40                 .func = break_op
                                                   >>  41         }
                                                   >>  42 };
 19                                                    43 
 20 DEFINE_PER_CPU(struct kprobe *, current_kprobe !!  44 DEFINE_PER_CPU(struct kprobe *, current_kprobe);
 21 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ct     45 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 22                                                    46 
 23 int __kprobes arch_prepare_kprobe(struct kprob !!  47 static int insn_has_delayslot(union mips_instruction insn)
 24 {                                                  48 {
 25         /* Attempt to probe at unaligned addre !!  49         return __insn_has_delay_slot(insn);
 26         if ((unsigned long)p->addr & 0x01)     << 
 27                 return -EINVAL;                << 
 28                                                << 
 29         /* Address should not be in exception  << 
 30                                                << 
 31         p->ainsn.is_short = is_short_instr((un << 
 32         p->opcode = *p->addr;                  << 
 33                                                << 
 34         return 0;                              << 
 35 }                                                  50 }
                                                   >>  51 NOKPROBE_SYMBOL(insn_has_delayslot);
 36                                                    52 
 37 void __kprobes arch_arm_kprobe(struct kprobe * !!  53 /*
                                                   >>  54  * insn_has_ll_or_sc function checks whether instruction is ll or sc
                                                   >>  55  * one; putting breakpoint on top of atomic ll/sc pair is bad idea;
                                                   >>  56  * so we need to prevent it and refuse kprobes insertion for such
                                                   >>  57  * instructions; cannot do much about breakpoint in the middle of
                                                   >>  58  * ll/sc pair; it is up to user to avoid those places
                                                   >>  59  */
                                                   >>  60 static int insn_has_ll_or_sc(union mips_instruction insn)
 38 {                                                  61 {
 39         *p->addr = UNIMP_S_INSTRUCTION;        !!  62         int ret = 0;
 40                                                    63 
 41         flush_icache_range((unsigned long)p->a !!  64         switch (insn.i_format.opcode) {
 42                            (unsigned long)p->a !!  65         case ll_op:
                                                   >>  66         case lld_op:
                                                   >>  67         case sc_op:
                                                   >>  68         case scd_op:
                                                   >>  69                 ret = 1;
                                                   >>  70                 break;
                                                   >>  71         default:
                                                   >>  72                 break;
                                                   >>  73         }
                                                   >>  74         return ret;
 43 }                                                  75 }
                                                   >>  76 NOKPROBE_SYMBOL(insn_has_ll_or_sc);
 44                                                    77 
 45 void __kprobes arch_disarm_kprobe(struct kprob !!  78 int arch_prepare_kprobe(struct kprobe *p)
 46 {                                                  79 {
 47         *p->addr = p->opcode;                  !!  80         union mips_instruction insn;
                                                   >>  81         union mips_instruction prev_insn;
                                                   >>  82         int ret = 0;
 48                                                    83 
 49         flush_icache_range((unsigned long)p->a !!  84         insn = p->addr[0];
 50                            (unsigned long)p->a << 
 51 }                                              << 
 52                                                    85 
 53 void __kprobes arch_remove_kprobe(struct kprob !!  86         if (insn_has_ll_or_sc(insn)) {
 54 {                                              !!  87                 pr_notice("Kprobes for ll and sc instructions are not supported\n");
 55         arch_disarm_kprobe(p);                 !!  88                 ret = -EINVAL;
                                                   >>  89                 goto out;
                                                   >>  90         }
 56                                                    91 
 57         /* Can we remove the kprobe in the mid !!  92         if (copy_from_kernel_nofault(&prev_insn, p->addr - 1,
 58         if (p->ainsn.t1_addr) {                !!  93                         sizeof(mips_instruction)) == 0 &&
 59                 *(p->ainsn.t1_addr) = p->ainsn !!  94             insn_has_delayslot(prev_insn)) {
                                                   >>  95                 pr_notice("Kprobes for branch delayslot are not supported\n");
                                                   >>  96                 ret = -EINVAL;
                                                   >>  97                 goto out;
                                                   >>  98         }
 60                                                    99 
 61                 flush_icache_range((unsigned l !! 100         if (__insn_is_compact_branch(insn)) {
 62                                    (unsigned l !! 101                 pr_notice("Kprobes for compact branches are not supported\n");
 63                                    sizeof(kpro !! 102                 ret = -EINVAL;
                                                   >> 103                 goto out;
                                                   >> 104         }
 64                                                   105 
 65                 p->ainsn.t1_addr = NULL;       !! 106         /* insn: must be on special executable page on mips. */
                                                   >> 107         p->ainsn.insn = get_insn_slot();
                                                   >> 108         if (!p->ainsn.insn) {
                                                   >> 109                 ret = -ENOMEM;
                                                   >> 110                 goto out;
 66         }                                         111         }
 67                                                   112 
 68         if (p->ainsn.t2_addr) {                !! 113         /*
 69                 *(p->ainsn.t2_addr) = p->ainsn !! 114          * In the kprobe->ainsn.insn[] array we store the original
                                                   >> 115          * instruction at index zero and a break trap instruction at
                                                   >> 116          * index one.
                                                   >> 117          *
                                                   >> 118          * On MIPS arch if the instruction at probed address is a
                                                   >> 119          * branch instruction, we need to execute the instruction at
                                                   >> 120          * Branch Delayslot (BD) at the time of probe hit. As MIPS also
                                                   >> 121          * doesn't have single stepping support, the BD instruction can
                                                   >> 122          * not be executed in-line and it would be executed on SSOL slot
                                                   >> 123          * using a normal breakpoint instruction in the next slot.
                                                   >> 124          * So, read the instruction and save it for later execution.
                                                   >> 125          */
                                                   >> 126         if (insn_has_delayslot(insn))
                                                   >> 127                 memcpy(&p->ainsn.insn[0], p->addr + 1, sizeof(kprobe_opcode_t));
                                                   >> 128         else
                                                   >> 129                 memcpy(&p->ainsn.insn[0], p->addr, sizeof(kprobe_opcode_t));
 70                                                   130 
 71                 flush_icache_range((unsigned l !! 131         p->ainsn.insn[1] = breakpoint2_insn;
 72                                    (unsigned l !! 132         p->opcode = *p->addr;
 73                                    sizeof(kpro << 
 74                                                   133 
 75                 p->ainsn.t2_addr = NULL;       !! 134 out:
                                                   >> 135         return ret;
                                                   >> 136 }
                                                   >> 137 NOKPROBE_SYMBOL(arch_prepare_kprobe);
                                                   >> 138 
                                                   >> 139 void arch_arm_kprobe(struct kprobe *p)
                                                   >> 140 {
                                                   >> 141         *p->addr = breakpoint_insn;
                                                   >> 142         flush_insn_slot(p);
                                                   >> 143 }
                                                   >> 144 NOKPROBE_SYMBOL(arch_arm_kprobe);
                                                   >> 145 
                                                   >> 146 void arch_disarm_kprobe(struct kprobe *p)
                                                   >> 147 {
                                                   >> 148         *p->addr = p->opcode;
                                                   >> 149         flush_insn_slot(p);
                                                   >> 150 }
                                                   >> 151 NOKPROBE_SYMBOL(arch_disarm_kprobe);
                                                   >> 152 
                                                   >> 153 void arch_remove_kprobe(struct kprobe *p)
                                                   >> 154 {
                                                   >> 155         if (p->ainsn.insn) {
                                                   >> 156                 free_insn_slot(p->ainsn.insn, 0);
                                                   >> 157                 p->ainsn.insn = NULL;
 76         }                                         158         }
 77 }                                                 159 }
                                                   >> 160 NOKPROBE_SYMBOL(arch_remove_kprobe);
 78                                                   161 
 79 static void __kprobes save_previous_kprobe(str !! 162 static void save_previous_kprobe(struct kprobe_ctlblk *kcb)
 80 {                                                 163 {
 81         kcb->prev_kprobe.kp = kprobe_running()    164         kcb->prev_kprobe.kp = kprobe_running();
 82         kcb->prev_kprobe.status = kcb->kprobe_    165         kcb->prev_kprobe.status = kcb->kprobe_status;
                                                   >> 166         kcb->prev_kprobe.old_SR = kcb->kprobe_old_SR;
                                                   >> 167         kcb->prev_kprobe.saved_SR = kcb->kprobe_saved_SR;
                                                   >> 168         kcb->prev_kprobe.saved_epc = kcb->kprobe_saved_epc;
 83 }                                                 169 }
 84                                                   170 
 85 static void __kprobes restore_previous_kprobe( !! 171 static void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 86 {                                                 172 {
 87         __this_cpu_write(current_kprobe, kcb->    173         __this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
 88         kcb->kprobe_status = kcb->prev_kprobe.    174         kcb->kprobe_status = kcb->prev_kprobe.status;
                                                   >> 175         kcb->kprobe_old_SR = kcb->prev_kprobe.old_SR;
                                                   >> 176         kcb->kprobe_saved_SR = kcb->prev_kprobe.saved_SR;
                                                   >> 177         kcb->kprobe_saved_epc = kcb->prev_kprobe.saved_epc;
 89 }                                                 178 }
 90                                                   179 
 91 static inline void __kprobes set_current_kprob !! 180 static void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
                                                   >> 181                                struct kprobe_ctlblk *kcb)
 92 {                                                 182 {
 93         __this_cpu_write(current_kprobe, p);      183         __this_cpu_write(current_kprobe, p);
                                                   >> 184         kcb->kprobe_saved_SR = kcb->kprobe_old_SR = (regs->cp0_status & ST0_IE);
                                                   >> 185         kcb->kprobe_saved_epc = regs->cp0_epc;
 94 }                                                 186 }
 95                                                   187 
 96 static void __kprobes resume_execution(struct  !! 188 /**
 97                                        struct  !! 189  * evaluate_branch_instrucion -
                                                   >> 190  *
                                                   >> 191  * Evaluate the branch instruction at probed address during probe hit. The
                                                   >> 192  * result of evaluation would be the updated epc. The insturction in delayslot
                                                   >> 193  * would actually be single stepped using a normal breakpoint) on SSOL slot.
                                                   >> 194  *
                                                   >> 195  * The result is also saved in the kprobe control block for later use,
                                                   >> 196  * in case we need to execute the delayslot instruction. The latter will be
                                                   >> 197  * false for NOP instruction in dealyslot and the branch-likely instructions
                                                   >> 198  * when the branch is taken. And for those cases we set a flag as
                                                   >> 199  * SKIP_DELAYSLOT in the kprobe control block
                                                   >> 200  */
                                                   >> 201 static int evaluate_branch_instruction(struct kprobe *p, struct pt_regs *regs,
                                                   >> 202                                         struct kprobe_ctlblk *kcb)
 98 {                                                 203 {
 99         /* Remove the trap instructions insert !! 204         union mips_instruction insn = p->opcode;
100          * restore the original instructions   !! 205         long epc;
101          */                                    !! 206         int ret = 0;
102         if (p->ainsn.t1_addr) {                !! 207 
103                 *(p->ainsn.t1_addr) = p->ainsn !! 208         epc = regs->cp0_epc;
                                                   >> 209         if (epc & 3)
                                                   >> 210                 goto unaligned;
                                                   >> 211 
                                                   >> 212         if (p->ainsn.insn->word == 0)
                                                   >> 213                 kcb->flags |= SKIP_DELAYSLOT;
                                                   >> 214         else
                                                   >> 215                 kcb->flags &= ~SKIP_DELAYSLOT;
                                                   >> 216 
                                                   >> 217         ret = __compute_return_epc_for_insn(regs, insn);
                                                   >> 218         if (ret < 0)
                                                   >> 219                 return ret;
104                                                   220 
105                 flush_icache_range((unsigned l !! 221         if (ret == BRANCH_LIKELY_TAKEN)
106                                    (unsigned l !! 222                 kcb->flags |= SKIP_DELAYSLOT;
107                                    sizeof(kpro << 
108                                                   223 
109                 p->ainsn.t1_addr = NULL;       !! 224         kcb->target_epc = regs->cp0_epc;
110         }                                      << 
111                                                   225 
112         if (p->ainsn.t2_addr) {                !! 226         return 0;
113                 *(p->ainsn.t2_addr) = p->ainsn << 
114                                                << 
115                 flush_icache_range((unsigned l << 
116                                    (unsigned l << 
117                                    sizeof(kpro << 
118                                                   227 
119                 p->ainsn.t2_addr = NULL;       !! 228 unaligned:
120         }                                      !! 229         pr_notice("Failed to emulate branch instruction because of unaligned epc - sending SIGBUS to %s.\n", current->comm);
                                                   >> 230         force_sig(SIGBUS);
                                                   >> 231         return -EFAULT;
121                                                   232 
122         return;                                << 
123 }                                                 233 }
124                                                   234 
125 static void __kprobes setup_singlestep(struct  !! 235 static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs,
                                                   >> 236                                                 struct kprobe_ctlblk *kcb)
126 {                                                 237 {
127         unsigned long next_pc;                 !! 238         int ret = 0;
128         unsigned long tgt_if_br = 0;           << 
129         int is_branch;                         << 
130         unsigned long bta;                     << 
131                                                   239 
132         /* Copy the opcode back to the kprobe  !! 240         regs->cp0_status &= ~ST0_IE;
133          * instruction. Because of this we wil << 
134          * same kprobe until this kprobe is do << 
135          */                                    << 
136         *(p->addr) = p->opcode;                << 
137                                                   241 
138         flush_icache_range((unsigned long)p->a !! 242         /* single step inline if the instruction is a break */
139                            (unsigned long)p->a !! 243         if (p->opcode.word == breakpoint_insn.word ||
140                                                !! 244             p->opcode.word == breakpoint2_insn.word)
141         /* Now we insert the trap at the next  !! 245                 regs->cp0_epc = (unsigned long)p->addr;
142          * single step. If it is a branch we i !! 246         else if (insn_has_delayslot(p->opcode)) {
143          * targets                             !! 247                 ret = evaluate_branch_instruction(p, regs, kcb);
144          */                                    !! 248                 if (ret < 0)
145                                                !! 249                         return;
146         bta = regs->bta;                       !! 250         }
147                                                !! 251         regs->cp0_epc = (unsigned long)&p->ainsn.insn[0];
148         if (regs->status32 & 0x40) {           !! 252 }
149                 /* We are in a delay slot with << 
150                                                << 
151                 next_pc = bta & ~0x01;         << 
152                                                << 
153                 if (!p->ainsn.is_short) {      << 
154                         if (bta & 0x01)        << 
155                                 regs->blink += << 
156                         else {                 << 
157                                 /* Branch not  << 
158                                 next_pc += 2;  << 
159                                                << 
160                                 /* next pc is  << 
161                                  * delay slot  << 
162                                  */            << 
163                                 regs->bta += 2 << 
164                         }                      << 
165                 }                              << 
166                                                << 
167                 is_branch = 0;                 << 
168         } else                                 << 
169                 is_branch =                    << 
170                     disasm_next_pc((unsigned l << 
171                         (struct callee_regs *) << 
172                         &next_pc, &tgt_if_br); << 
173                                                << 
174         p->ainsn.t1_addr = (kprobe_opcode_t *) << 
175         p->ainsn.t1_opcode = *(p->ainsn.t1_add << 
176         *(p->ainsn.t1_addr) = TRAP_S_2_INSTRUC << 
177                                                << 
178         flush_icache_range((unsigned long)p->a << 
179                            (unsigned long)p->a << 
180                            sizeof(kprobe_opcod << 
181                                                << 
182         if (is_branch) {                       << 
183                 p->ainsn.t2_addr = (kprobe_opc << 
184                 p->ainsn.t2_opcode = *(p->ains << 
185                 *(p->ainsn.t2_addr) = TRAP_S_2 << 
186                                                   253 
187                 flush_icache_range((unsigned l !! 254 /*
188                                    (unsigned l !! 255  * Called after single-stepping.  p->addr is the address of the
189                                    sizeof(kpro !! 256  * instruction whose first byte has been replaced by the "break 0"
                                                   >> 257  * instruction.  To avoid the SMP problems that can occur when we
                                                   >> 258  * temporarily put back the original opcode to single-step, we
                                                   >> 259  * single-stepped a copy of the instruction.  The address of this
                                                   >> 260  * copy is p->ainsn.insn.
                                                   >> 261  *
                                                   >> 262  * This function prepares to return from the post-single-step
                                                   >> 263  * breakpoint trap. In case of branch instructions, the target
                                                   >> 264  * epc to be restored.
                                                   >> 265  */
                                                   >> 266 static void resume_execution(struct kprobe *p,
                                                   >> 267                                        struct pt_regs *regs,
                                                   >> 268                                        struct kprobe_ctlblk *kcb)
                                                   >> 269 {
                                                   >> 270         if (insn_has_delayslot(p->opcode))
                                                   >> 271                 regs->cp0_epc = kcb->target_epc;
                                                   >> 272         else {
                                                   >> 273                 unsigned long orig_epc = kcb->kprobe_saved_epc;
                                                   >> 274                 regs->cp0_epc = orig_epc + 4;
190         }                                         275         }
191 }                                                 276 }
                                                   >> 277 NOKPROBE_SYMBOL(resume_execution);
192                                                   278 
193 static int                                     !! 279 static int kprobe_handler(struct pt_regs *regs)
194 __kprobes arc_kprobe_handler(unsigned long add << 
195 {                                                 280 {
196         struct kprobe *p;                         281         struct kprobe *p;
                                                   >> 282         int ret = 0;
                                                   >> 283         kprobe_opcode_t *addr;
197         struct kprobe_ctlblk *kcb;                284         struct kprobe_ctlblk *kcb;
198                                                   285 
199         preempt_disable();                     !! 286         addr = (kprobe_opcode_t *) regs->cp0_epc;
200                                                   287 
                                                   >> 288         /*
                                                   >> 289          * We don't want to be preempted for the entire
                                                   >> 290          * duration of kprobe processing
                                                   >> 291          */
                                                   >> 292         preempt_disable();
201         kcb = get_kprobe_ctlblk();                293         kcb = get_kprobe_ctlblk();
202         p = get_kprobe((unsigned long *)addr); << 
203                                                   294 
204         if (p) {                               !! 295         /* Check we're not actually recursing */
205                 /*                             !! 296         if (kprobe_running()) {
206                  * We have reentered the kprob !! 297                 p = get_kprobe(addr);
207                  * was hit while within the ha !! 298                 if (p) {
208                  * kprobes and single step on  !! 299                         if (kcb->kprobe_status == KPROBE_HIT_SS &&
209                  * without calling any user ha !! 300                             p->ainsn.insn->word == breakpoint_insn.word) {
210                  * kprobes.                    !! 301                                 regs->cp0_status &= ~ST0_IE;
211                  */                            !! 302                                 regs->cp0_status |= kcb->kprobe_saved_SR;
212                 if (kprobe_running()) {        !! 303                                 goto no_kprobe;
                                                   >> 304                         }
                                                   >> 305                         /*
                                                   >> 306                          * We have reentered the kprobe_handler(), since
                                                   >> 307                          * another probe was hit while within the handler.
                                                   >> 308                          * We here save the original kprobes variables and
                                                   >> 309                          * just single step on the instruction of the new probe
                                                   >> 310                          * without calling any user handlers.
                                                   >> 311                          */
213                         save_previous_kprobe(k    312                         save_previous_kprobe(kcb);
214                         set_current_kprobe(p); !! 313                         set_current_kprobe(p, regs, kcb);
215                         kprobes_inc_nmissed_co    314                         kprobes_inc_nmissed_count(p);
216                         setup_singlestep(p, re !! 315                         prepare_singlestep(p, regs, kcb);
217                         kcb->kprobe_status = K    316                         kcb->kprobe_status = KPROBE_REENTER;
                                                   >> 317                         if (kcb->flags & SKIP_DELAYSLOT) {
                                                   >> 318                                 resume_execution(p, regs, kcb);
                                                   >> 319                                 restore_previous_kprobe(kcb);
                                                   >> 320                                 preempt_enable_no_resched();
                                                   >> 321                         }
218                         return 1;                 322                         return 1;
                                                   >> 323                 } else if (addr->word != breakpoint_insn.word) {
                                                   >> 324                         /*
                                                   >> 325                          * The breakpoint instruction was removed by
                                                   >> 326                          * another cpu right after we hit, no further
                                                   >> 327                          * handling of this interrupt is appropriate
                                                   >> 328                          */
                                                   >> 329                         ret = 1;
219                 }                                 330                 }
                                                   >> 331                 goto no_kprobe;
                                                   >> 332         }
220                                                   333 
221                 set_current_kprobe(p);         !! 334         p = get_kprobe(addr);
222                 kcb->kprobe_status = KPROBE_HI !! 335         if (!p) {
223                                                !! 336                 if (addr->word != breakpoint_insn.word) {
224                 /* If we have no pre-handler o !! 337                         /*
225                  * normal processing. If we ha !! 338                          * The breakpoint instruction was removed right
226                  * non-zero - which means user !! 339                          * after we hit it.  Another cpu has removed
227                  * to another instruction, we  !! 340                          * either a probepoint or a debugger breakpoint
228                  */                            !! 341                          * at this address.  In either case, no further
229                 if (!p->pre_handler || !p->pre !! 342                          * handling of this interrupt is appropriate.
230                         setup_singlestep(p, re !! 343                          */
231                         kcb->kprobe_status = K !! 344                         ret = 1;
232                 } else {                       << 
233                         reset_current_kprobe() << 
234                         preempt_enable_no_resc << 
235                 }                                 345                 }
                                                   >> 346                 /* Not one of ours: let kernel handle it */
                                                   >> 347                 goto no_kprobe;
                                                   >> 348         }
236                                                   349 
                                                   >> 350         set_current_kprobe(p, regs, kcb);
                                                   >> 351         kcb->kprobe_status = KPROBE_HIT_ACTIVE;
                                                   >> 352 
                                                   >> 353         if (p->pre_handler && p->pre_handler(p, regs)) {
                                                   >> 354                 /* handler has already set things up, so skip ss setup */
                                                   >> 355                 reset_current_kprobe();
                                                   >> 356                 preempt_enable_no_resched();
237                 return 1;                         357                 return 1;
238         }                                         358         }
239                                                   359 
240         /* no_kprobe: */                       !! 360         prepare_singlestep(p, regs, kcb);
                                                   >> 361         if (kcb->flags & SKIP_DELAYSLOT) {
                                                   >> 362                 kcb->kprobe_status = KPROBE_HIT_SSDONE;
                                                   >> 363                 if (p->post_handler)
                                                   >> 364                         p->post_handler(p, regs, 0);
                                                   >> 365                 resume_execution(p, regs, kcb);
                                                   >> 366                 preempt_enable_no_resched();
                                                   >> 367         } else
                                                   >> 368                 kcb->kprobe_status = KPROBE_HIT_SS;
                                                   >> 369 
                                                   >> 370         return 1;
                                                   >> 371 
                                                   >> 372 no_kprobe:
241         preempt_enable_no_resched();              373         preempt_enable_no_resched();
242         return 0;                              !! 374         return ret;
                                                   >> 375 
243 }                                                 376 }
                                                   >> 377 NOKPROBE_SYMBOL(kprobe_handler);
244                                                   378 
245 static int                                     !! 379 static inline int post_kprobe_handler(struct pt_regs *regs)
246 __kprobes arc_post_kprobe_handler(unsigned lon << 
247 {                                                 380 {
248         struct kprobe *cur = kprobe_running();    381         struct kprobe *cur = kprobe_running();
249         struct kprobe_ctlblk *kcb = get_kprobe    382         struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
250                                                   383 
251         if (!cur)                                 384         if (!cur)
252                 return 0;                         385                 return 0;
253                                                   386 
254         resume_execution(cur, addr, regs);     << 
255                                                << 
256         /* Rearm the kprobe */                 << 
257         arch_arm_kprobe(cur);                  << 
258                                                << 
259         /*                                     << 
260          * When we return from trap instructio << 
261          * We restored the actual instruction  << 
262          * return to the same address and exec << 
263          */                                    << 
264         regs->ret = addr;                      << 
265                                                << 
266         if ((kcb->kprobe_status != KPROBE_REEN    387         if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
267                 kcb->kprobe_status = KPROBE_HI    388                 kcb->kprobe_status = KPROBE_HIT_SSDONE;
268                 cur->post_handler(cur, regs, 0    389                 cur->post_handler(cur, regs, 0);
269         }                                         390         }
270                                                   391 
                                                   >> 392         resume_execution(cur, regs, kcb);
                                                   >> 393 
                                                   >> 394         regs->cp0_status |= kcb->kprobe_saved_SR;
                                                   >> 395 
                                                   >> 396         /* Restore back the original saved kprobes variables and continue. */
271         if (kcb->kprobe_status == KPROBE_REENT    397         if (kcb->kprobe_status == KPROBE_REENTER) {
272                 restore_previous_kprobe(kcb);     398                 restore_previous_kprobe(kcb);
273                 goto out;                         399                 goto out;
274         }                                         400         }
275                                                << 
276         reset_current_kprobe();                   401         reset_current_kprobe();
277                                                << 
278 out:                                              402 out:
279         preempt_enable_no_resched();              403         preempt_enable_no_resched();
                                                   >> 404 
280         return 1;                                 405         return 1;
281 }                                                 406 }
282                                                   407 
283 /*                                             !! 408 int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
284  * Fault can be for the instruction being sing << 
285  * pre/post handlers in the module.            << 
286  * This is applicable for applications like us << 
287  * probe in user space and the handlers in the << 
288  */                                            << 
289                                                << 
290 int __kprobes kprobe_fault_handler(struct pt_r << 
291 {                                                 409 {
292         struct kprobe *cur = kprobe_running();    410         struct kprobe *cur = kprobe_running();
293         struct kprobe_ctlblk *kcb = get_kprobe    411         struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
294                                                   412 
295         switch (kcb->kprobe_status) {          !! 413         if (kcb->kprobe_status & KPROBE_HIT_SS) {
296         case KPROBE_HIT_SS:                    !! 414                 resume_execution(cur, regs, kcb);
297         case KPROBE_REENTER:                   !! 415                 regs->cp0_status |= kcb->kprobe_old_SR;
298                 /*                             << 
299                  * We are here because the ins << 
300                  * caused the fault. We reset  << 
301                  * exception handler as if it  << 
302                  * case it doesn't matter beca << 
303                  */                            << 
304                 resume_execution(cur, (unsigne << 
305                                                << 
306                 if (kcb->kprobe_status == KPRO << 
307                         restore_previous_kprob << 
308                 else                           << 
309                         reset_current_kprobe() << 
310                                                   416 
                                                   >> 417                 reset_current_kprobe();
311                 preempt_enable_no_resched();      418                 preempt_enable_no_resched();
312                 break;                         << 
313                                                << 
314         case KPROBE_HIT_ACTIVE:                << 
315         case KPROBE_HIT_SSDONE:                << 
316                 /*                             << 
317                  * We are here because the ins << 
318                  * caused the fault.           << 
319                  */                            << 
320                                                << 
321                 /*                             << 
322                  * In case the user-specified  << 
323                  * try to fix up.              << 
324                  */                            << 
325                 if (fixup_exception(regs))     << 
326                         return 1;              << 
327                                                << 
328                 /*                             << 
329                  * fixup_exception() could not << 
330                  * Let do_page_fault() fix it. << 
331                  */                            << 
332                 break;                         << 
333                                                << 
334         default:                               << 
335                 break;                         << 
336         }                                         419         }
337         return 0;                                 420         return 0;
338 }                                                 421 }
339                                                   422 
340 int __kprobes kprobe_exceptions_notify(struct  !! 423 /*
                                                   >> 424  * Wrapper routine for handling exceptions.
                                                   >> 425  */
                                                   >> 426 int kprobe_exceptions_notify(struct notifier_block *self,
341                                        unsigne    427                                        unsigned long val, void *data)
342 {                                                 428 {
343         struct die_args *args = data;          !! 429 
344         unsigned long addr = args->err;        !! 430         struct die_args *args = (struct die_args *)data;
345         int ret = NOTIFY_DONE;                    431         int ret = NOTIFY_DONE;
346                                                   432 
347         switch (val) {                            433         switch (val) {
348         case DIE_IERR:                         !! 434         case DIE_BREAK:
349                 if (arc_kprobe_handler(addr, a !! 435                 if (kprobe_handler(args->regs))
350                         return NOTIFY_STOP;    !! 436                         ret = NOTIFY_STOP;
351                 break;                            437                 break;
352                                                !! 438         case DIE_SSTEPBP:
353         case DIE_TRAP:                         !! 439                 if (post_kprobe_handler(args->regs))
354                 if (arc_post_kprobe_handler(ad !! 440                         ret = NOTIFY_STOP;
355                         return NOTIFY_STOP;    << 
356                 break;                            441                 break;
357                                                   442 
                                                   >> 443         case DIE_PAGE_FAULT:
                                                   >> 444                 /* kprobe_running() needs smp_processor_id() */
                                                   >> 445                 preempt_disable();
                                                   >> 446 
                                                   >> 447                 if (kprobe_running()
                                                   >> 448                     && kprobe_fault_handler(args->regs, args->trapnr))
                                                   >> 449                         ret = NOTIFY_STOP;
                                                   >> 450                 preempt_enable();
                                                   >> 451                 break;
358         default:                                  452         default:
359                 break;                            453                 break;
360         }                                         454         }
361                                                << 
362         return ret;                               455         return ret;
363 }                                                 456 }
                                                   >> 457 NOKPROBE_SYMBOL(kprobe_exceptions_notify);
364                                                   458 
                                                   >> 459 /*
                                                   >> 460  * Function return probe trampoline:
                                                   >> 461  *      - init_kprobes() establishes a probepoint here
                                                   >> 462  *      - When the probed function returns, this probe causes the
                                                   >> 463  *        handlers to fire
                                                   >> 464  */
365 static void __used kretprobe_trampoline_holder    465 static void __used kretprobe_trampoline_holder(void)
366 {                                                 466 {
367         __asm__ __volatile__(".global __kretpr !! 467         asm volatile(
368                              "__kretprobe_tram !! 468                 ".set push\n\t"
369                              "nop\n");         !! 469                 /* Keep the assembler from reordering and placing JR here. */
                                                   >> 470                 ".set noreorder\n\t"
                                                   >> 471                 "nop\n\t"
                                                   >> 472                 ".global __kretprobe_trampoline\n"
                                                   >> 473                 "__kretprobe_trampoline:\n\t"
                                                   >> 474                 "nop\n\t"
                                                   >> 475                 ".set pop"
                                                   >> 476                 : : : "memory");
370 }                                                 477 }
371                                                   478 
372 void __kprobes arch_prepare_kretprobe(struct k !! 479 void __kretprobe_trampoline(void);
                                                   >> 480 
                                                   >> 481 void arch_prepare_kretprobe(struct kretprobe_instance *ri,
373                                       struct p    482                                       struct pt_regs *regs)
374 {                                                 483 {
375                                                !! 484         ri->ret_addr = (kprobe_opcode_t *) regs->regs[31];
376         ri->ret_addr = (kprobe_opcode_t *) reg << 
377         ri->fp = NULL;                            485         ri->fp = NULL;
378                                                   486 
379         /* Replace the return addr with trampo    487         /* Replace the return addr with trampoline addr */
380         regs->blink = (unsigned long)&__kretpr !! 488         regs->regs[31] = (unsigned long)__kretprobe_trampoline;
381 }                                                 489 }
                                                   >> 490 NOKPROBE_SYMBOL(arch_prepare_kretprobe);
382                                                   491 
383 static int __kprobes trampoline_probe_handler( !! 492 /*
384                                                !! 493  * Called when the probe at kretprobe trampoline is hit
                                                   >> 494  */
                                                   >> 495 static int trampoline_probe_handler(struct kprobe *p,
                                                   >> 496                                                 struct pt_regs *regs)
385 {                                                 497 {
386         regs->ret = __kretprobe_trampoline_han !! 498         instruction_pointer(regs) = __kretprobe_trampoline_handler(regs, NULL);
387                                                !! 499         /*
388         /* By returning a non zero value, we a !! 500          * By returning a non-zero value, we are telling
389          * that we don't want the post_handler !! 501          * kprobe_handler() that we don't want the post_handler
                                                   >> 502          * to run (and have re-enabled preemption)
390          */                                       503          */
391         return 1;                                 504         return 1;
392 }                                                 505 }
                                                   >> 506 NOKPROBE_SYMBOL(trampoline_probe_handler);
393                                                   507 
394 static struct kprobe trampoline_p = {          !! 508 int arch_trampoline_kprobe(struct kprobe *p)
395         .addr = (kprobe_opcode_t *) &__kretpro << 
396         .pre_handler = trampoline_probe_handle << 
397 };                                             << 
398                                                << 
399 int __init arch_init_kprobes(void)             << 
400 {                                                 509 {
401         /* Registering the trampoline code for !! 510         if (p->addr == (kprobe_opcode_t *)__kretprobe_trampoline)
402         return register_kprobe(&trampoline_p); << 
403 }                                              << 
404                                                << 
405 int __kprobes arch_trampoline_kprobe(struct kp << 
406 {                                              << 
407         if (p->addr == (kprobe_opcode_t *) &__ << 
408                 return 1;                         511                 return 1;
409                                                   512 
410         return 0;                                 513         return 0;
411 }                                                 514 }
                                                   >> 515 NOKPROBE_SYMBOL(arch_trampoline_kprobe);
                                                   >> 516 
                                                   >> 517 static struct kprobe trampoline_p = {
                                                   >> 518         .addr = (kprobe_opcode_t *)__kretprobe_trampoline,
                                                   >> 519         .pre_handler = trampoline_probe_handler
                                                   >> 520 };
412                                                   521 
413 void trap_is_kprobe(unsigned long address, str !! 522 int __init arch_init_kprobes(void)
414 {                                                 523 {
415         notify_die(DIE_TRAP, "kprobe_trap", re !! 524         return register_kprobe(&trampoline_p);
416 }                                                 525 }
417                                                   526 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php