| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  *  Kernel Probes (KProbes) | 
 | 3 |  *  arch/ppc64/kernel/kprobes.c | 
 | 4 |  * | 
 | 5 |  * This program is free software; you can redistribute it and/or modify | 
 | 6 |  * it under the terms of the GNU General Public License as published by | 
 | 7 |  * the Free Software Foundation; either version 2 of the License, or | 
 | 8 |  * (at your option) any later version. | 
 | 9 |  * | 
 | 10 |  * This program is distributed in the hope that it will be useful, | 
 | 11 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 | 12 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 | 13 |  * GNU General Public License for more details. | 
 | 14 |  * | 
 | 15 |  * You should have received a copy of the GNU General Public License | 
 | 16 |  * along with this program; if not, write to the Free Software | 
 | 17 |  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 
 | 18 |  * | 
 | 19 |  * Copyright (C) IBM Corporation, 2002, 2004 | 
 | 20 |  * | 
 | 21 |  * 2002-Oct	Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel | 
 | 22 |  *		Probes initial implementation ( includes contributions from | 
 | 23 |  *		Rusty Russell). | 
 | 24 |  * 2004-July	Suparna Bhattacharya <suparna@in.ibm.com> added jumper probes | 
 | 25 |  *		interface to access function arguments. | 
 | 26 |  * 2004-Nov	Ananth N Mavinakayanahalli <ananth@in.ibm.com> kprobes port | 
 | 27 |  *		for PPC64 | 
 | 28 |  */ | 
 | 29 |  | 
 | 30 | #include <linux/config.h> | 
 | 31 | #include <linux/kprobes.h> | 
 | 32 | #include <linux/ptrace.h> | 
 | 33 | #include <linux/spinlock.h> | 
 | 34 | #include <linux/preempt.h> | 
 | 35 | #include <asm/kdebug.h> | 
 | 36 | #include <asm/sstep.h> | 
 | 37 |  | 
 | 38 | /* kprobe_status settings */ | 
 | 39 | #define KPROBE_HIT_ACTIVE	0x00000001 | 
 | 40 | #define KPROBE_HIT_SS		0x00000002 | 
 | 41 |  | 
 | 42 | static struct kprobe *current_kprobe; | 
 | 43 | static unsigned long kprobe_status, kprobe_saved_msr; | 
 | 44 | static struct pt_regs jprobe_saved_regs; | 
 | 45 |  | 
 | 46 | int arch_prepare_kprobe(struct kprobe *p) | 
 | 47 | { | 
| Ananth N Mavinakayanahalli | 63224d1e8 | 2005-06-08 15:49:41 -0700 | [diff] [blame] | 48 | 	int ret = 0; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 49 | 	kprobe_opcode_t insn = *p->addr; | 
 | 50 |  | 
| Ananth N Mavinakayanahalli | 63224d1e8 | 2005-06-08 15:49:41 -0700 | [diff] [blame] | 51 | 	if ((unsigned long)p->addr & 0x03) { | 
 | 52 | 		printk("Attempt to register kprobe at an unaligned address\n"); | 
 | 53 | 		ret = -EINVAL; | 
 | 54 | 	} else if (IS_MTMSRD(insn) || IS_RFID(insn)) { | 
 | 55 | 		printk("Cannot register a kprobe on rfid or mtmsrd\n"); | 
 | 56 | 		ret = -EINVAL; | 
 | 57 | 	} | 
 | 58 | 	return ret; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 59 | } | 
 | 60 |  | 
 | 61 | void arch_copy_kprobe(struct kprobe *p) | 
 | 62 | { | 
 | 63 | 	memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); | 
 | 64 | } | 
 | 65 |  | 
 | 66 | void arch_remove_kprobe(struct kprobe *p) | 
 | 67 | { | 
 | 68 | } | 
 | 69 |  | 
 | 70 | static inline void disarm_kprobe(struct kprobe *p, struct pt_regs *regs) | 
 | 71 | { | 
 | 72 | 	*p->addr = p->opcode; | 
 | 73 | 	regs->nip = (unsigned long)p->addr; | 
 | 74 | } | 
 | 75 |  | 
 | 76 | static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | 
 | 77 | { | 
 | 78 | 	regs->msr |= MSR_SE; | 
 | 79 | 	/*single step inline if it a breakpoint instruction*/ | 
 | 80 | 	if (p->opcode == BREAKPOINT_INSTRUCTION) | 
 | 81 | 		regs->nip = (unsigned long)p->addr; | 
 | 82 | 	else | 
 | 83 | 		regs->nip = (unsigned long)&p->ainsn.insn; | 
 | 84 | } | 
 | 85 |  | 
 | 86 | static inline int kprobe_handler(struct pt_regs *regs) | 
 | 87 | { | 
 | 88 | 	struct kprobe *p; | 
 | 89 | 	int ret = 0; | 
 | 90 | 	unsigned int *addr = (unsigned int *)regs->nip; | 
 | 91 |  | 
 | 92 | 	/* Check we're not actually recursing */ | 
 | 93 | 	if (kprobe_running()) { | 
 | 94 | 		/* We *are* holding lock here, so this is safe. | 
 | 95 | 		   Disarm the probe we just hit, and ignore it. */ | 
 | 96 | 		p = get_kprobe(addr); | 
 | 97 | 		if (p) { | 
 | 98 | 			if (kprobe_status == KPROBE_HIT_SS) { | 
 | 99 | 				regs->msr &= ~MSR_SE; | 
 | 100 | 				regs->msr |= kprobe_saved_msr; | 
 | 101 | 				unlock_kprobes(); | 
 | 102 | 				goto no_kprobe; | 
 | 103 | 			} | 
 | 104 | 			disarm_kprobe(p, regs); | 
 | 105 | 			ret = 1; | 
 | 106 | 		} else { | 
 | 107 | 			p = current_kprobe; | 
 | 108 | 			if (p->break_handler && p->break_handler(p, regs)) { | 
 | 109 | 				goto ss_probe; | 
 | 110 | 			} | 
 | 111 | 		} | 
 | 112 | 		/* If it's not ours, can't be delete race, (we hold lock). */ | 
 | 113 | 		goto no_kprobe; | 
 | 114 | 	} | 
 | 115 |  | 
 | 116 | 	lock_kprobes(); | 
 | 117 | 	p = get_kprobe(addr); | 
 | 118 | 	if (!p) { | 
 | 119 | 		unlock_kprobes(); | 
 | 120 | 		if (*addr != BREAKPOINT_INSTRUCTION) { | 
 | 121 | 			/* | 
 | 122 | 			 * PowerPC has multiple variants of the "trap" | 
 | 123 | 			 * instruction. If the current instruction is a | 
 | 124 | 			 * trap variant, it could belong to someone else | 
 | 125 | 			 */ | 
 | 126 | 			kprobe_opcode_t cur_insn = *addr; | 
 | 127 | 			if (IS_TW(cur_insn) || IS_TD(cur_insn) || | 
 | 128 | 					IS_TWI(cur_insn) || IS_TDI(cur_insn)) | 
 | 129 | 		       		goto no_kprobe; | 
 | 130 | 			/* | 
 | 131 | 			 * The breakpoint instruction was removed right | 
 | 132 | 			 * after we hit it.  Another cpu has removed | 
 | 133 | 			 * either a probepoint or a debugger breakpoint | 
 | 134 | 			 * at this address.  In either case, no further | 
 | 135 | 			 * handling of this interrupt is appropriate. | 
 | 136 | 			 */ | 
 | 137 | 			ret = 1; | 
 | 138 | 		} | 
 | 139 | 		/* Not one of ours: let kernel handle it */ | 
 | 140 | 		goto no_kprobe; | 
 | 141 | 	} | 
 | 142 |  | 
 | 143 | 	kprobe_status = KPROBE_HIT_ACTIVE; | 
 | 144 | 	current_kprobe = p; | 
 | 145 | 	kprobe_saved_msr = regs->msr; | 
 | 146 | 	if (p->pre_handler && p->pre_handler(p, regs)) | 
 | 147 | 		/* handler has already set things up, so skip ss setup */ | 
 | 148 | 		return 1; | 
 | 149 |  | 
 | 150 | ss_probe: | 
 | 151 | 	prepare_singlestep(p, regs); | 
 | 152 | 	kprobe_status = KPROBE_HIT_SS; | 
 | 153 | 	/* | 
 | 154 | 	 * This preempt_disable() matches the preempt_enable_no_resched() | 
 | 155 | 	 * in post_kprobe_handler(). | 
 | 156 | 	 */ | 
 | 157 | 	preempt_disable(); | 
 | 158 | 	return 1; | 
 | 159 |  | 
 | 160 | no_kprobe: | 
 | 161 | 	return ret; | 
 | 162 | } | 
 | 163 |  | 
 | 164 | /* | 
 | 165 |  * Called after single-stepping.  p->addr is the address of the | 
 | 166 |  * instruction whose first byte has been replaced by the "breakpoint" | 
 | 167 |  * instruction.  To avoid the SMP problems that can occur when we | 
 | 168 |  * temporarily put back the original opcode to single-step, we | 
 | 169 |  * single-stepped a copy of the instruction.  The address of this | 
 | 170 |  * copy is p->ainsn.insn. | 
 | 171 |  */ | 
 | 172 | static void resume_execution(struct kprobe *p, struct pt_regs *regs) | 
 | 173 | { | 
 | 174 | 	int ret; | 
 | 175 |  | 
 | 176 | 	regs->nip = (unsigned long)p->addr; | 
 | 177 | 	ret = emulate_step(regs, p->ainsn.insn[0]); | 
 | 178 | 	if (ret == 0) | 
 | 179 | 		regs->nip = (unsigned long)p->addr + 4; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 180 | } | 
 | 181 |  | 
 | 182 | static inline int post_kprobe_handler(struct pt_regs *regs) | 
 | 183 | { | 
 | 184 | 	if (!kprobe_running()) | 
 | 185 | 		return 0; | 
 | 186 |  | 
 | 187 | 	if (current_kprobe->post_handler) | 
 | 188 | 		current_kprobe->post_handler(current_kprobe, regs, 0); | 
 | 189 |  | 
 | 190 | 	resume_execution(current_kprobe, regs); | 
 | 191 | 	regs->msr |= kprobe_saved_msr; | 
 | 192 |  | 
 | 193 | 	unlock_kprobes(); | 
 | 194 | 	preempt_enable_no_resched(); | 
 | 195 |  | 
 | 196 | 	/* | 
 | 197 | 	 * if somebody else is singlestepping across a probe point, msr | 
 | 198 | 	 * will have SE set, in which case, continue the remaining processing | 
 | 199 | 	 * of do_debug, as if this is not a probe hit. | 
 | 200 | 	 */ | 
 | 201 | 	if (regs->msr & MSR_SE) | 
 | 202 | 		return 0; | 
 | 203 |  | 
 | 204 | 	return 1; | 
 | 205 | } | 
 | 206 |  | 
 | 207 | /* Interrupts disabled, kprobe_lock held. */ | 
 | 208 | static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) | 
 | 209 | { | 
 | 210 | 	if (current_kprobe->fault_handler | 
 | 211 | 	    && current_kprobe->fault_handler(current_kprobe, regs, trapnr)) | 
 | 212 | 		return 1; | 
 | 213 |  | 
 | 214 | 	if (kprobe_status & KPROBE_HIT_SS) { | 
 | 215 | 		resume_execution(current_kprobe, regs); | 
| Ananth N Mavinakayanahalli | f829fd2 | 2005-06-08 15:50:00 -0700 | [diff] [blame] | 216 | 		regs->msr &= ~MSR_SE; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 217 | 		regs->msr |= kprobe_saved_msr; | 
 | 218 |  | 
 | 219 | 		unlock_kprobes(); | 
 | 220 | 		preempt_enable_no_resched(); | 
 | 221 | 	} | 
 | 222 | 	return 0; | 
 | 223 | } | 
 | 224 |  | 
 | 225 | /* | 
 | 226 |  * Wrapper routine to for handling exceptions. | 
 | 227 |  */ | 
 | 228 | int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, | 
 | 229 | 			     void *data) | 
 | 230 | { | 
 | 231 | 	struct die_args *args = (struct die_args *)data; | 
 | 232 | 	int ret = NOTIFY_DONE; | 
 | 233 |  | 
 | 234 | 	/* | 
 | 235 | 	 * Interrupts are not disabled here.  We need to disable | 
 | 236 | 	 * preemption, because kprobe_running() uses smp_processor_id(). | 
 | 237 | 	 */ | 
 | 238 | 	preempt_disable(); | 
 | 239 | 	switch (val) { | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 240 | 	case DIE_BPT: | 
 | 241 | 		if (kprobe_handler(args->regs)) | 
 | 242 | 			ret = NOTIFY_STOP; | 
 | 243 | 		break; | 
 | 244 | 	case DIE_SSTEP: | 
 | 245 | 		if (post_kprobe_handler(args->regs)) | 
 | 246 | 			ret = NOTIFY_STOP; | 
 | 247 | 		break; | 
 | 248 | 	case DIE_GPF: | 
 | 249 | 	case DIE_PAGE_FAULT: | 
 | 250 | 		if (kprobe_running() && | 
 | 251 | 		    kprobe_fault_handler(args->regs, args->trapnr)) | 
 | 252 | 			ret = NOTIFY_STOP; | 
 | 253 | 		break; | 
 | 254 | 	default: | 
 | 255 | 		break; | 
 | 256 | 	} | 
 | 257 | 	preempt_enable(); | 
 | 258 | 	return ret; | 
 | 259 | } | 
 | 260 |  | 
 | 261 | int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | 
 | 262 | { | 
 | 263 | 	struct jprobe *jp = container_of(p, struct jprobe, kp); | 
 | 264 |  | 
 | 265 | 	memcpy(&jprobe_saved_regs, regs, sizeof(struct pt_regs)); | 
 | 266 |  | 
 | 267 | 	/* setup return addr to the jprobe handler routine */ | 
 | 268 | 	regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry); | 
 | 269 | 	regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc); | 
 | 270 |  | 
 | 271 | 	return 1; | 
 | 272 | } | 
 | 273 |  | 
 | 274 | void jprobe_return(void) | 
 | 275 | { | 
 | 276 | 	asm volatile("trap" ::: "memory"); | 
 | 277 | } | 
 | 278 |  | 
 | 279 | void jprobe_return_end(void) | 
 | 280 | { | 
 | 281 | }; | 
 | 282 |  | 
 | 283 | int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | 
 | 284 | { | 
 | 285 | 	/* | 
 | 286 | 	 * FIXME - we should ideally be validating that we got here 'cos | 
 | 287 | 	 * of the "trap" in jprobe_return() above, before restoring the | 
 | 288 | 	 * saved regs... | 
 | 289 | 	 */ | 
 | 290 | 	memcpy(regs, &jprobe_saved_regs, sizeof(struct pt_regs)); | 
 | 291 | 	return 1; | 
 | 292 | } |