kprobes.c 12.8 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7
/* arch/sparc64/kernel/kprobes.c
 *
 * Copyright (C) 2004 David S. Miller <davem@davemloft.net>
 */

#include <linux/kernel.h>
#include <linux/kprobes.h>
8
#include <linux/module.h>
L
Linus Torvalds 已提交
9 10
#include <asm/kdebug.h>
#include <asm/signal.h>
11
#include <asm/cacheflush.h>
12
#include <asm/uaccess.h>
L
Linus Torvalds 已提交
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

/* We do not have hardware single-stepping on sparc64.
 * So we implement software single-stepping with breakpoint
 * traps.  The top-level scheme is similar to that used
 * in the x86 kprobes implementation.
 *
 * In the kprobe->ainsn.insn[] array we store the original
 * instruction at index zero and a break instruction at
 * index one.
 *
 * When we hit a kprobe we:
 * - Run the pre-handler
 * - Remember "regs->tnpc" and interrupt level stored in
 *   "regs->tstate" so we can restore them later
 * - Disable PIL interrupts
 * - Set regs->tpc to point to kprobe->ainsn.insn[0]
 * - Set regs->tnpc to point to kprobe->ainsn.insn[1]
 * - Mark that we are actively in a kprobe
 *
 * At this point we wait for the second breakpoint at
 * kprobe->ainsn.insn[1] to hit.  When it does we:
 * - Run the post-handler
 * - Set regs->tpc to "remembered" regs->tnpc stored above,
 *   restore the PIL interrupt level in "regs->tstate" as well
 * - Make any adjustments necessary to regs->tnpc in order
 *   to handle relative branches correctly.  See below.
 * - Mark that we are no longer actively in a kprobe.
 */

42 43 44
DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);

45
int __kprobes arch_prepare_kprobe(struct kprobe *p)
L
Linus Torvalds 已提交
46 47
{
	p->ainsn.insn[0] = *p->addr;
48 49
	flushi(&p->ainsn.insn[0]);

L
Linus Torvalds 已提交
50
	p->ainsn.insn[1] = BREAKPOINT_INSTRUCTION_2;
51 52
	flushi(&p->ainsn.insn[1]);

53
	p->opcode = *p->addr;
54
	return 0;
55 56
}

57
void __kprobes arch_arm_kprobe(struct kprobe *p)
58 59 60 61 62
{
	*p->addr = BREAKPOINT_INSTRUCTION;
	flushi(p->addr);
}

63
void __kprobes arch_disarm_kprobe(struct kprobe *p)
64 65 66
{
	*p->addr = p->opcode;
	flushi(p->addr);
L
Linus Torvalds 已提交
67 68
}

69
static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
70
{
71 72 73 74
	kcb->prev_kprobe.kp = kprobe_running();
	kcb->prev_kprobe.status = kcb->kprobe_status;
	kcb->prev_kprobe.orig_tnpc = kcb->kprobe_orig_tnpc;
	kcb->prev_kprobe.orig_tstate_pil = kcb->kprobe_orig_tstate_pil;
75 76
}

77
static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
78
{
79 80 81 82
	__get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
	kcb->kprobe_status = kcb->prev_kprobe.status;
	kcb->kprobe_orig_tnpc = kcb->prev_kprobe.orig_tnpc;
	kcb->kprobe_orig_tstate_pil = kcb->prev_kprobe.orig_tstate_pil;
83 84
}

85
static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
86
				struct kprobe_ctlblk *kcb)
L
Linus Torvalds 已提交
87
{
88 89 90
	__get_cpu_var(current_kprobe) = p;
	kcb->kprobe_orig_tnpc = regs->tnpc;
	kcb->kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL);
91 92
}

93
static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs,
94
			struct kprobe_ctlblk *kcb)
95
{
L
Linus Torvalds 已提交
96 97 98 99 100
	regs->tstate |= TSTATE_PIL;

	/*single step inline, if it a breakpoint instruction*/
	if (p->opcode == BREAKPOINT_INSTRUCTION) {
		regs->tpc = (unsigned long) p->addr;
101
		regs->tnpc = kcb->kprobe_orig_tnpc;
L
Linus Torvalds 已提交
102 103 104 105 106 107
	} else {
		regs->tpc = (unsigned long) &p->ainsn.insn[0];
		regs->tnpc = (unsigned long) &p->ainsn.insn[1];
	}
}

108
static int __kprobes kprobe_handler(struct pt_regs *regs)
L
Linus Torvalds 已提交
109 110 111 112
{
	struct kprobe *p;
	void *addr = (void *) regs->tpc;
	int ret = 0;
113 114 115 116 117 118 119 120
	struct kprobe_ctlblk *kcb;

	/*
	 * We don't want to be preempted for the entire
	 * duration of kprobe processing
	 */
	preempt_disable();
	kcb = get_kprobe_ctlblk();
L
Linus Torvalds 已提交
121 122 123 124

	if (kprobe_running()) {
		p = get_kprobe(addr);
		if (p) {
125
			if (kcb->kprobe_status == KPROBE_HIT_SS) {
L
Linus Torvalds 已提交
126
				regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
127
					kcb->kprobe_orig_tstate_pil);
L
Linus Torvalds 已提交
128 129
				goto no_kprobe;
			}
130 131 132 133 134 135
			/* We have reentered the kprobe_handler(), since
			 * another probe was hit while within the handler.
			 * We here save the original kprobes variables and
			 * just single step on the instruction of the new probe
			 * without calling any user handlers.
			 */
136 137
			save_previous_kprobe(kcb);
			set_current_kprobe(p, regs, kcb);
138
			kprobes_inc_nmissed_count(p);
139 140
			kcb->kprobe_status = KPROBE_REENTER;
			prepare_singlestep(p, regs, kcb);
141
			return 1;
L
Linus Torvalds 已提交
142
		} else {
143 144 145 146 147 148 149 150
			if (*(u32 *)addr != BREAKPOINT_INSTRUCTION) {
			/* The breakpoint instruction was removed by
			 * another cpu right after we hit, no further
			 * handling of this interrupt is appropriate
			 */
				ret = 1;
				goto no_kprobe;
			}
151
			p = __get_cpu_var(current_kprobe);
L
Linus Torvalds 已提交
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
			if (p->break_handler && p->break_handler(p, regs))
				goto ss_probe;
		}
		goto no_kprobe;
	}

	p = get_kprobe(addr);
	if (!p) {
		if (*(u32 *)addr != BREAKPOINT_INSTRUCTION) {
			/*
			 * The breakpoint instruction was removed right
			 * after we hit it.  Another cpu has removed
			 * either a probepoint or a debugger breakpoint
			 * at this address.  In either case, no further
			 * handling of this interrupt is appropriate.
			 */
			ret = 1;
		}
		/* Not one of ours: let kernel handle it */
		goto no_kprobe;
	}

174 175
	set_current_kprobe(p, regs, kcb);
	kcb->kprobe_status = KPROBE_HIT_ACTIVE;
L
Linus Torvalds 已提交
176 177 178 179
	if (p->pre_handler && p->pre_handler(p, regs))
		return 1;

ss_probe:
180 181
	prepare_singlestep(p, regs, kcb);
	kcb->kprobe_status = KPROBE_HIT_SS;
L
Linus Torvalds 已提交
182 183 184
	return 1;

no_kprobe:
185
	preempt_enable_no_resched();
L
Linus Torvalds 已提交
186 187 188 189 190 191
	return ret;
}

/* If INSN is a relative control transfer instruction,
 * return the corrected branch destination value.
 *
192 193 194 195
 * regs->tpc and regs->tnpc still hold the values of the
 * program counters at the time of trap due to the execution
 * of the BREAKPOINT_INSTRUCTION_2 at p->ainsn.insn[1]
 * 
L
Linus Torvalds 已提交
196
 */
197 198
static unsigned long __kprobes relbranch_fixup(u32 insn, struct kprobe *p,
					       struct pt_regs *regs)
L
Linus Torvalds 已提交
199
{
200 201
	unsigned long real_pc = (unsigned long) p->addr;

L
Linus Torvalds 已提交
202
	/* Branch not taken, no mods necessary.  */
203 204
	if (regs->tnpc == regs->tpc + 0x4UL)
		return real_pc + 0x8UL;
L
Linus Torvalds 已提交
205 206 207 208 209 210 211

	/* The three cases are call, branch w/prediction,
	 * and traditional branch.
	 */
	if ((insn & 0xc0000000) == 0x40000000 ||
	    (insn & 0xc1c00000) == 0x00400000 ||
	    (insn & 0xc1c00000) == 0x00800000) {
212 213 214 215
		unsigned long ainsn_addr;

		ainsn_addr = (unsigned long) &p->ainsn.insn[0];

L
Linus Torvalds 已提交
216 217 218 219
		/* The instruction did all the work for us
		 * already, just apply the offset to the correct
		 * instruction location.
		 */
220
		return (real_pc + (regs->tnpc - ainsn_addr));
L
Linus Torvalds 已提交
221 222
	}

223 224 225 226
	/* It is jmpl or some other absolute PC modification instruction,
	 * leave NPC as-is.
	 */
	return regs->tnpc;
L
Linus Torvalds 已提交
227 228 229 230 231
}

/* If INSN is an instruction which writes it's PC location
 * into a destination register, fix that up.
 */
232 233
static void __kprobes retpc_fixup(struct pt_regs *regs, u32 insn,
				  unsigned long real_pc)
L
Linus Torvalds 已提交
234 235 236
{
	unsigned long *slot = NULL;

237
	/* Simplest case is 'call', which always uses %o7 */
L
Linus Torvalds 已提交
238 239 240 241
	if ((insn & 0xc0000000) == 0x40000000) {
		slot = &regs->u_regs[UREG_I7];
	}

242
	/* 'jmpl' encodes the register inside of the opcode */
L
Linus Torvalds 已提交
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
	if ((insn & 0xc1f80000) == 0x81c00000) {
		unsigned long rd = ((insn >> 25) & 0x1f);

		if (rd <= 15) {
			slot = &regs->u_regs[rd];
		} else {
			/* Hard case, it goes onto the stack. */
			flushw_all();

			rd -= 16;
			slot = (unsigned long *)
				(regs->u_regs[UREG_FP] + STACK_BIAS);
			slot += rd;
		}
	}
	if (slot != NULL)
		*slot = real_pc;
}

/*
 * Called after single-stepping.  p->addr is the address of the
264
 * instruction which has been replaced by the breakpoint
L
Linus Torvalds 已提交
265 266 267
 * instruction.  To avoid the SMP problems that can occur when we
 * temporarily put back the original opcode to single-step, we
 * single-stepped a copy of the instruction.  The address of this
268
 * copy is &p->ainsn.insn[0].
L
Linus Torvalds 已提交
269 270 271 272
 *
 * This function prepares to return from the post-single-step
 * breakpoint trap.
 */
273 274
static void __kprobes resume_execution(struct kprobe *p,
		struct pt_regs *regs, struct kprobe_ctlblk *kcb)
L
Linus Torvalds 已提交
275 276 277
{
	u32 insn = p->ainsn.insn[0];

278 279 280
	regs->tnpc = relbranch_fixup(insn, p, regs);

	/* This assignment must occur after relbranch_fixup() */
281
	regs->tpc = kcb->kprobe_orig_tnpc;
282

L
Linus Torvalds 已提交
283 284 285
	retpc_fixup(regs, insn, (unsigned long) p->addr);

	regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
286
			kcb->kprobe_orig_tstate_pil);
L
Linus Torvalds 已提交
287 288
}

289
static int __kprobes post_kprobe_handler(struct pt_regs *regs)
L
Linus Torvalds 已提交
290
{
291 292 293 294
	struct kprobe *cur = kprobe_running();
	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();

	if (!cur)
L
Linus Torvalds 已提交
295 296
		return 0;

297 298 299
	if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) {
		kcb->kprobe_status = KPROBE_HIT_SSDONE;
		cur->post_handler(cur, regs, 0);
300
	}
L
Linus Torvalds 已提交
301

302
	resume_execution(cur, regs, kcb);
L
Linus Torvalds 已提交
303

304
	/*Restore back the original saved kprobes variables and continue. */
305 306
	if (kcb->kprobe_status == KPROBE_REENTER) {
		restore_previous_kprobe(kcb);
307 308
		goto out;
	}
309
	reset_current_kprobe();
310
out:
L
Linus Torvalds 已提交
311 312 313 314 315
	preempt_enable_no_resched();

	return 1;
}

316
static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
L
Linus Torvalds 已提交
317
{
318 319
	struct kprobe *cur = kprobe_running();
	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359
	const struct exception_table_entry *entry;

	switch(kcb->kprobe_status) {
	case KPROBE_HIT_SS:
	case KPROBE_REENTER:
		/*
		 * We are here because the instruction being single
		 * stepped caused a page fault. We reset the current
		 * kprobe and the tpc points back to the probe address
		 * and allow the page fault handler to continue as a
		 * normal page fault.
		 */
		regs->tpc = (unsigned long)cur->addr;
		regs->tnpc = kcb->kprobe_orig_tnpc;
		regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
				kcb->kprobe_orig_tstate_pil);
		if (kcb->kprobe_status == KPROBE_REENTER)
			restore_previous_kprobe(kcb);
		else
			reset_current_kprobe();
		preempt_enable_no_resched();
		break;
	case KPROBE_HIT_ACTIVE:
	case KPROBE_HIT_SSDONE:
		/*
		 * We increment the nmissed count for accounting,
		 * we can also use npre/npostfault count for accouting
		 * these specific fault cases.
		 */
		kprobes_inc_nmissed_count(cur);

		/*
		 * We come here because instructions in the pre/post
		 * handler caused the page_fault, this could happen
		 * if handler tries to access user space by
		 * copy_from_user(), get_user() etc. Let the
		 * user-specified handler try to fix it first.
		 */
		if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr))
			return 1;
360

361 362 363 364
		/*
		 * In case the user-specified fault handler returned
		 * zero, try to fix up.
		 */
L
Linus Torvalds 已提交
365

366 367 368 369 370 371
		entry = search_exception_tables(regs->tpc);
		if (entry) {
			regs->tpc = entry->fixup;
			regs->tnpc = regs->tpc + 4;
			return 1;
		}
L
Linus Torvalds 已提交
372

373 374 375 376 377 378 379
		/*
		 * fixup_exception() could not handle it,
		 * Let do_page_fault() fix it.
		 */
		break;
	default:
		break;
L
Linus Torvalds 已提交
380
	}
381

L
Linus Torvalds 已提交
382 383 384 385 386 387
	return 0;
}

/*
 * Wrapper routine to for handling exceptions.
 */
388 389
int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
				       unsigned long val, void *data)
L
Linus Torvalds 已提交
390 391
{
	struct die_args *args = (struct die_args *)data;
392 393
	int ret = NOTIFY_DONE;

394 395 396
	if (args->regs && user_mode(args->regs))
		return ret;

L
Linus Torvalds 已提交
397 398 399
	switch (val) {
	case DIE_DEBUG:
		if (kprobe_handler(args->regs))
400
			ret = NOTIFY_STOP;
L
Linus Torvalds 已提交
401 402 403
		break;
	case DIE_DEBUG_2:
		if (post_kprobe_handler(args->regs))
404
			ret = NOTIFY_STOP;
L
Linus Torvalds 已提交
405 406 407
		break;
	case DIE_GPF:
	case DIE_PAGE_FAULT:
408 409
		/* kprobe_running() needs smp_processor_id() */
		preempt_disable();
L
Linus Torvalds 已提交
410 411
		if (kprobe_running() &&
		    kprobe_fault_handler(args->regs, args->trapnr))
412
			ret = NOTIFY_STOP;
413
		preempt_enable();
L
Linus Torvalds 已提交
414 415 416 417
		break;
	default:
		break;
	}
418
	return ret;
L
Linus Torvalds 已提交
419 420
}

421 422
asmlinkage void __kprobes kprobe_trap(unsigned long trap_level,
				      struct pt_regs *regs)
L
Linus Torvalds 已提交
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441
{
	BUG_ON(trap_level != 0x170 && trap_level != 0x171);

	if (user_mode(regs)) {
		local_irq_enable();
		bad_trap(regs, trap_level);
		return;
	}

	/* trap_level == 0x170 --> ta 0x70
	 * trap_level == 0x171 --> ta 0x71
	 */
	if (notify_die((trap_level == 0x170) ? DIE_DEBUG : DIE_DEBUG_2,
		       (trap_level == 0x170) ? "debug" : "debug_2",
		       regs, 0, trap_level, SIGTRAP) != NOTIFY_STOP)
		bad_trap(regs, trap_level);
}

/* Jprobes support.  */
442
int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
L
Linus Torvalds 已提交
443 444
{
	struct jprobe *jp = container_of(p, struct jprobe, kp);
445
	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
L
Linus Torvalds 已提交
446

447
	memcpy(&(kcb->jprobe_saved_regs), regs, sizeof(*regs));
L
Linus Torvalds 已提交
448 449 450 451 452 453 454 455

	regs->tpc  = (unsigned long) jp->entry;
	regs->tnpc = ((unsigned long) jp->entry) + 0x4UL;
	regs->tstate |= TSTATE_PIL;

	return 1;
}

456
void __kprobes jprobe_return(void)
L
Linus Torvalds 已提交
457
{
458 459 460 461 462 463 464 465 466
	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
	register unsigned long orig_fp asm("g1");

	orig_fp = kcb->jprobe_saved_regs.u_regs[UREG_FP];
	__asm__ __volatile__("\n"
"1:	cmp		%%sp, %0\n\t"
	"blu,a,pt	%%xcc, 1b\n\t"
	" restore\n\t"
	".globl		jprobe_return_trap_instruction\n"
L
Linus Torvalds 已提交
467
"jprobe_return_trap_instruction:\n\t"
468 469 470
	"ta		0x70"
	: /* no outputs */
	: "r" (orig_fp));
L
Linus Torvalds 已提交
471 472 473 474 475 476
}

extern void jprobe_return_trap_instruction(void);

extern void __show_regs(struct pt_regs * regs);

477
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
L
Linus Torvalds 已提交
478 479
{
	u32 *addr = (u32 *) regs->tpc;
480
	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
L
Linus Torvalds 已提交
481 482

	if (addr == (u32 *) jprobe_return_trap_instruction) {
483
		memcpy(regs, &(kcb->jprobe_saved_regs), sizeof(*regs));
484
		preempt_enable_no_resched();
L
Linus Torvalds 已提交
485 486 487 488
		return 1;
	}
	return 0;
}
489

490 491 492 493 494
/* architecture specific initialization */
int arch_init_kprobes(void)
{
	return 0;
}