All of lore.kernel.org
 help / color / mirror / Atom feed
diff for duplicates of <54B7EF3C.8060909@redhat.com>

diff --git a/a/1.txt b/N1/1.txt
index c13d97f..746bc35 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -127,10 +127,3 @@ printk debug messages with comments
      [   60.974681] kprobe_handler called at 465
 
 ~Pratyush
--------------- next part --------------
-A non-text attachment was scrubbed...
-Name: 0001-Debug-kprobe-insertion-at-uprobe_breakpoint_handler.patch
-Type: text/x-patch
-Size: 33060 bytes
-Desc: not available
-URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150115/ba388265/attachment-0001.bin>
diff --git a/N1/2.hdr b/N1/2.hdr
new file mode 100644
index 0000000..7a0b2fe
--- /dev/null
+++ b/N1/2.hdr
@@ -0,0 +1,6 @@
+Content-Type: text/x-patch;
+ name="0001-Debug-kprobe-insertion-at-uprobe_breakpoint_handler.patch"
+Content-Transfer-Encoding: 7bit
+Content-Disposition: attachment;
+ filename*0="0001-Debug-kprobe-insertion-at-uprobe_breakpoint_handler.pat";
+ filename*1="ch"
diff --git a/N1/2.txt b/N1/2.txt
new file mode 100644
index 0000000..7b73f0c
--- /dev/null
+++ b/N1/2.txt
@@ -0,0 +1,1111 @@
+>From cfe62741e100060ee4165fa662689b3220312823 Mon Sep 17 00:00:00 2001
+Message-Id: <cfe62741e100060ee4165fa662689b3220312823.1421340459.git.panand@redhat.com>
+From: Pratyush Anand <panand@redhat.com>
+Date: Wed, 7 Jan 2015 21:40:49 +0530
+Subject: [PATCH] Debug kprobe insertion at uprobe_breakpoint_handler
+
+Step at user level:
+================================
+
+//inserting kprobe at 1st instruction of  uprobe_breakpoint_handler. So
+//1st instruction of uprobe_breakpoint_handler has been replaced by
+//BRK64_OPCODE_KPROBES when kprobe enabled.
+
+    echo 'p:myprobe uprobe_breakpoint_handler' >
+/sys/kernel/debug/tracing/kprobe_events
+
+//enabling kprobe
+
+    echo 1 > /sys/kernel/debug/tracing/events/kprobes/enable
+
+//run test application
+
+    ./test&
+
+//inserting uprobe at offset 0x5d0 of  uprobe_breakpoint_handler. So
+//instruction at this offset has been replaced by BRK64_OPCODE_UPROBES,
+//when uprobe enabled.
+
+    echo 'p:test_entry test:0x5d0' >
+/sys/kernel/debug/tracing/uprobe_events
+
+//enabling uprobe
+
+    echo 1 > /sys/kernel/debug/tracing/events/uprobes/enable
+
+observed flow summary
+========================
+    kprobe has been inserted at 1st instruction of
+uprobe_breakpoint_handler and
+    uprobe has been inserted at offset 0x5d0 of test application.
+    Observation is that execution flow is as under:
+    -- Application executes  BRK64_OPCODE_UPROBES.
+    -- el0_sync is raised.
+    -- el0_sync
+        -> kernel_entry 0
+        -> el0_dbg
+            -> do_debug_exception
+                ->brk_handler
+                    ->call_break_hook
+                        ->uprobe_breakpoint_handler
+    (1st instruction of uprobe_breakpoint_handler has been modified as
+    BRK64_OPCODE_KPROBES)
+    -- el1_sync is raised.
+    -- el1_sync
+        -> kernel_entry 1
+        -> el1_dbg
+            -> do_debug_exception
+                ->brk_handler
+                    ->call_break_hook
+                        ->kprobe_breakpoint_handler
+
+    Following printk messages confirms above flow. printk messages has
+been
+    avoided into el0_dbg and el1_dbg execution path. All the tap points
+for
+    these path have been written into per_cpu array and then they have
+been
+    printed when kprobe_breakpoint_handler is executed.
+    tap points have been instrumented wherever we are calling macro
+    enable_dbg and also in uprobe/kprobe break/single step exception
+path.
+
+printk debug messages with comments
+============================================
+
+    [   60.846047] arch_prepare_kprobe called at 89
+    [   60.850344] arch_prepare_kprobe called at 97
+    [   60.854595] arch_prepare_kprobe called at 110
+    [   60.858959] arch_prepare_kprobe called at 114 with slot
+    fffffdfffc000004
+    [   60.865633] arch_prepare_ss_slot called at 46
+    [   60.874466] arch_arm_kprobe called at 143
+    [   60.878487] patch_text called at 136
+    [   60.904226] arch_uprobe_analyze_insn called at 54
+    [   60.908939] arch_uprobe_analyze_insn called at 68
+    [   60.914155] 0.0: event 0 syndrom 0 @cpu 0
+    [   60.918151] 0.0: event 0 syndrom 0 @cpu 1
+    [   60.922143] 0.0: event 0 syndrom 0 @cpu 2
+    [   60.926134] 1421337852.798722179: event 19 syndrom f2000008 @cpu
+3
+
+    [1][Pratyush]: ESR = f2000008 and event 19 says its uprobe
+breakpoint
+    exception
+
+    [   60.932286] 1421337852.798722179: event 19 syndrom f2000004 @cpu
+3
+
+    [2][Pratyush]: ESR = f2000004 and event 19 says its kprobe
+breakpoint
+    exception
+
+    [   60.938438] 1421337852.798722179: event 23 syndrom f2000004 @cpu
+3
+
+    [3][Pratyush]: ESR = f2000004 and event 23 says that we are in
+function
+    kprobe_breakpoint_handler
+
+    Since we did not receive any event corresponding to calling of
+    enable_dbg macro
+    or execution of either uprobe_breakpoint_handler or
+    uprobe_single_step_handler, so it is confirmed that,
+    we received el1_dbg while executing el0_dbg
+
+    [   60.944590] 0.0: event 0 syndrom 0 @cpu 3
+    [   60.948579] 0.0: event 0 syndrom 0 @cpu 4
+    [   60.952569] 0.0: event 0 syndrom 0 @cpu 5
+    [   60.956558] 0.0: event 0 syndrom 0 @cpu 6
+    [   60.960547] 0.0: event 0 syndrom 0 @cpu 7
+    [   60.964539] kprobe_handler called at 453 with addr
+fffffe000009fd80
+    [   60.970778] kprobe_handler called at 456
+    [   60.974681] kprobe_handler called at 465
+
+Signed-off-by: Pratyush Anand <panand@redhat.com>
+---
+ arch/arm64/include/asm/probes.h    |   2 +
+ arch/arm64/kernel/debug-monitors.c |  91 +++++++++++++++++++++++++++++++
+ arch/arm64/kernel/entry.S          | 108 +++++++++++++++++++++++++++++++++++++
+ arch/arm64/kernel/kprobes.c        |  81 ++++++++++++++++++++++++++++
+ arch/arm64/kernel/uprobes.c        |  26 +++++++--
+ 5 files changed, 304 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/include/asm/probes.h b/arch/arm64/include/asm/probes.h
+index 54c253ba2d25..aebcf37a64f9 100644
+--- a/arch/arm64/include/asm/probes.h
++++ b/arch/arm64/include/asm/probes.h
+@@ -15,6 +15,8 @@
+ #ifndef _ARM_PROBES_H
+ #define _ARM_PROBES_H
+ 
++void print_debug_log_buf(void);
++void c_log_debug_entry(u64 pt, u64 syn);
+ struct kprobe;
+ struct arch_specific_insn;
+ 
+diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
+index aaa0e87d52f1..4643a5243750 100644
+--- a/arch/arm64/kernel/debug-monitors.c
++++ b/arch/arm64/kernel/debug-monitors.c
+@@ -30,6 +30,91 @@
+ #include <asm/cputype.h>
+ #include <asm/system_misc.h>
+ 
++struct debug_log_buf {
++	u64	pt;
++	u64	syn;
++	struct timespec now;
++};
++
++#define MAX_DEBUG_LOG_COUNT	1000
++
++/*
++ * Debug point
++ * 1(el1_sync)
++ * 2(el1_irq)
++ * 3(el0_sync)
++ * 4(el0_irq)
++ * 5(el1_da)
++ * 6(el1_sp_pc)
++ * 7(el1_undef)
++ * 8(el1_inv)
++ * 9(el0_da)
++ * 10(el0_ia)
++ * 11(el0_fpsimd_acc)
++ * 12(el0_fpsimd_exc)
++ * 13(el0_sp_pc)
++ * 14(el0_undef)
++ * 15(el0_dbg)
++ * 16(el0_inv)
++ * 17(el0_irq_nacked)
++ * 18(el0_svc_nacked)
++ * 19 brk_handler
++ * 20 single_step
++ * 21 uprobe_breakpoint_handler
++ * 22 uprobe_single_step_handler
++ * 23 kprobe_breakpoint_handler
++ * 24 kprobe_single_step_handler
++ */
++
++static DEFINE_PER_CPU(struct debug_log_buf[MAX_DEBUG_LOG_COUNT], debug_log_events);
++static DEFINE_PER_CPU(u32, debug_log_counts);
++bool start_log_event;
++
++void print_debug_log_buf(void)
++{
++	u32 cpu;
++	u32 count, c;
++	struct debug_log_buf *log_buf;
++
++	if (!start_log_event)
++		return;
++
++	start_log_event = false;
++
++	for_each_possible_cpu(cpu) {
++		count = per_cpu(debug_log_counts, cpu);
++		log_buf = per_cpu(debug_log_events, cpu);
++		/* if last log is wrong, it means we did not overflow */
++		for (c = 0; c <= count; c++) {
++			printk("%ld.%ld: event %lld syndrom %llx @cpu %d\n",
++					(log_buf + c)->now.tv_sec, (log_buf + c)->now.tv_nsec,
++					(log_buf + c)->pt, (log_buf + c)->syn, cpu);
++		}
++	}
++}
++
++void c_log_debug_entry(u64 pt, u64 syn)
++{
++	u32 cpu;
++	u32 count;
++	struct debug_log_buf *log_buf;
++
++	if (!start_log_event)
++		return;
++
++	cpu = get_cpu();
++	count = per_cpu(debug_log_counts, cpu);
++	/* reset count when overflow */
++	if (count == MAX_DEBUG_LOG_COUNT)
++		per_cpu(debug_log_counts, cpu) = 0;
++	log_buf = per_cpu(debug_log_events, cpu);
++	(log_buf + count)->pt = pt;
++	(log_buf + count)->syn = syn;
++	(log_buf + count)->now = current_kernel_time();
++	per_cpu(debug_log_counts, cpu)++;
++	put_cpu();
++}
++
+ /* Determine debug architecture. */
+ u8 debug_monitors_arch(void)
+ {
+@@ -229,6 +314,7 @@ static int single_step_handler(unsigned long addr, unsigned int esr,
+ {
+ 	siginfo_t info;
+ 
++	c_log_debug_entry(20, esr);
+ 	/*
+ 	 * If we are stepping a pending breakpoint, call the hw_breakpoint
+ 	 * handler first.
+@@ -306,6 +392,11 @@ static int brk_handler(unsigned long addr, unsigned int esr,
+ {
+ 	siginfo_t info;
+ 
++	/* start log when uprobe bkpt exception is received */
++	if (esr == 0xf2000008)
++		start_log_event = true;
++	c_log_debug_entry(19, esr);
++
+ 	if (call_break_hook(regs, esr) == DBG_HOOK_HANDLED)
+ 		return 0;
+ 
+diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
+index 726b910fe6ec..271b8d9f7a9a 100644
+--- a/arch/arm64/kernel/entry.S
++++ b/arch/arm64/kernel/entry.S
+@@ -28,6 +28,96 @@
+ #include <asm/thread_info.h>
+ #include <asm/unistd.h>
+ 
++	.macro log_debug_entry, pt
++	push	x28, x29
++	push	x26, x27
++	push	x24, x25
++	push	x22, x23
++	push	x20, x21
++	push	x18, x19
++	push	x16, x17
++	push	x14, x15
++	push	x12, x13
++	push	x10, x11
++	push	x8, x9
++	push	x6, x7
++	push	x4, x5
++	push	x2, x3
++	push	x0, x1
++	push	x29, x30
++	.if \pt == 1
++	mov	x0, #1
++	.endif
++	.if \pt == 2
++	mov	x0, #2
++	.endif
++	.if \pt == 3
++	mov	x0, #3
++	.endif
++	.if \pt == 4
++	mov	x0, #4
++	.endif
++	.if \pt == 5
++	mov	x0, #5
++	.endif
++	.if \pt == 6
++	mov	x0, #6
++	.endif
++	.if \pt == 7
++	mov	x0, #7
++	.endif
++	.if \pt == 8
++	mov	x0, #8
++	.endif
++	.if \pt == 9
++	mov	x0, #9
++	.endif
++	.if \pt == 10
++	mov	x0, #10
++	.endif
++	.if \pt == 11
++	mov	x0, #11
++	.endif
++	.if \pt == 12
++	mov	x0, #12
++	.endif
++	.if \pt == 13
++	mov	x0, #13
++	.endif
++	.if \pt == 14
++	mov	x0, #14
++	.endif
++	.if \pt == 15
++	mov	x0, #15
++	.endif
++	.if \pt == 16
++	mov	x0, #16
++	.endif
++	.if \pt == 17
++	mov	x0, #17
++	.endif
++	.if \pt == 18
++	mov	x0, #18
++	.endif
++	mrs	x1, esr_el1			// read the syndrome register
++	bl	c_log_debug_entry
++	pop	x29, x30
++	pop	x0, x1
++	pop	x2, x3
++	pop	x4, x5
++	pop	x6, x7
++	pop	x8, x9
++	pop	x10, x11
++	pop	x12, x13
++	pop	x14, x15
++	pop	x16, x17
++	pop	x18, x19
++	pop	x20, x21
++	pop	x22, x23
++	pop	x24, x25
++	pop	x26, x27
++	pop	x28, x29
++	.endm
+ /*
+  * Context tracking subsystem.  Used to instrument transitions
+  * between user and kernel mode.
+@@ -269,6 +359,7 @@ ENDPROC(el1_error_invalid)
+ el1_sync:
+ 	kernel_entry 1
+ 	mrs	x1, esr_el1			// read the syndrome register
++	//log_debug_entry 1
+ 	lsr	x24, x1, #ESR_EL1_EC_SHIFT	// exception class
+ 	cmp	x24, #ESR_EL1_EC_DABT_EL1	// data abort in EL1
+ 	b.eq	el1_da
+@@ -288,6 +379,7 @@ el1_da:
+ 	 * Data abort handling
+ 	 */
+ 	mrs	x0, far_el1
++	log_debug_entry 5
+ 	enable_dbg
+ 	// re-enable interrupts if they were enabled in the aborted context
+ 	tbnz	x23, #7, 1f			// PSR_I_BIT
+@@ -304,6 +396,7 @@ el1_sp_pc:
+ 	 * Stack or PC alignment exception handling
+ 	 */
+ 	mrs	x0, far_el1
++	log_debug_entry 6
+ 	enable_dbg
+ 	mov	x2, sp
+ 	b	do_sp_pc_abort
+@@ -311,6 +404,7 @@ el1_undef:
+ 	/*
+ 	 * Undefined instruction
+ 	 */
++	log_debug_entry 7
+ 	enable_dbg
+ 	mov	x0, sp
+ 	b	do_undefinstr
+@@ -327,6 +421,7 @@ el1_dbg:
+ 	kernel_exit 1
+ el1_inv:
+ 	// TODO: add support for undefined instructions in kernel mode
++	log_debug_entry 8
+ 	enable_dbg
+ 	mov	x0, sp
+ 	mov	x1, #BAD_SYNC
+@@ -337,6 +432,7 @@ ENDPROC(el1_sync)
+ 	.align	6
+ el1_irq:
+ 	kernel_entry 1
++	log_debug_entry 2
+ 	enable_dbg
+ #ifdef CONFIG_TRACE_IRQFLAGS
+ 	bl	trace_hardirqs_off
+@@ -375,6 +471,7 @@ el1_preempt:
+ el0_sync:
+ 	kernel_entry 0
+ 	mrs	x25, esr_el1			// read the syndrome register
++	//log_debug_entry 3
+ 	lsr	x24, x25, #ESR_EL1_EC_SHIFT	// exception class
+ 	cmp	x24, #ESR_EL1_EC_SVC64		// SVC in 64-bit state
+ 	b.eq	el0_svc
+@@ -450,6 +547,7 @@ el0_da:
+ 	 */
+ 	mrs	x26, far_el1
+ 	// enable interrupts before calling the main handler
++	log_debug_entry 9
+ 	enable_dbg_and_irq
+ 	ct_user_exit
+ 	bic	x0, x26, #(0xff << 56)
+@@ -463,6 +561,7 @@ el0_ia:
+ 	 */
+ 	mrs	x26, far_el1
+ 	// enable interrupts before calling the main handler
++	log_debug_entry 10
+ 	enable_dbg_and_irq
+ 	ct_user_exit
+ 	mov	x0, x26
+@@ -474,6 +573,7 @@ el0_fpsimd_acc:
+ 	/*
+ 	 * Floating Point or Advanced SIMD access
+ 	 */
++	log_debug_entry 11
+ 	enable_dbg
+ 	ct_user_exit
+ 	mov	x0, x25
+@@ -484,6 +584,7 @@ el0_fpsimd_exc:
+ 	/*
+ 	 * Floating Point or Advanced SIMD exception
+ 	 */
++	log_debug_entry 12
+ 	enable_dbg
+ 	ct_user_exit
+ 	mov	x0, x25
+@@ -496,6 +597,7 @@ el0_sp_pc:
+ 	 */
+ 	mrs	x26, far_el1
+ 	// enable interrupts before calling the main handler
++	log_debug_entry 13
+ 	enable_dbg_and_irq
+ 	mov	x0, x26
+ 	mov	x1, x25
+@@ -507,6 +609,7 @@ el0_undef:
+ 	 * Undefined instruction
+ 	 */
+ 	// enable interrupts before calling the main handler
++	log_debug_entry 14
+ 	enable_dbg_and_irq
+ 	ct_user_exit
+ 	mov	x0, sp
+@@ -521,10 +624,12 @@ el0_dbg:
+ 	mov	x1, x25
+ 	mov	x2, sp
+ 	bl	do_debug_exception
++	log_debug_entry 15
+ 	enable_dbg
+ 	ct_user_exit
+ 	b	ret_to_user
+ el0_inv:
++	log_debug_entry 16
+ 	enable_dbg
+ 	ct_user_exit
+ 	mov	x0, sp
+@@ -537,7 +642,9 @@ ENDPROC(el0_sync)
+ 	.align	6
+ el0_irq:
+ 	kernel_entry 0
++	//log_debug_entry 4
+ el0_irq_naked:
++	log_debug_entry 17
+ 	enable_dbg
+ #ifdef CONFIG_TRACE_IRQFLAGS
+ 	bl	trace_hardirqs_off
+@@ -647,6 +754,7 @@ el0_svc:
+ 	mov	sc_nr, #__NR_syscalls
+ el0_svc_naked:					// compat entry point
+ 	stp	x0, scno, [sp, #S_ORIG_X0]	// save the original x0 and syscall number
++	log_debug_entry 18
+ 	enable_dbg_and_irq
+ 	ct_user_exit 1
+ 
+diff --git a/arch/arm64/kernel/kprobes.c b/arch/arm64/kernel/kprobes.c
+index 514e11411a67..651b0e6b19d1 100644
+--- a/arch/arm64/kernel/kprobes.c
++++ b/arch/arm64/kernel/kprobes.c
+@@ -43,6 +43,7 @@ post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *);
+ 
+ static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
+ {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	/* prepare insn slot */
+ 	p->ainsn.insn[0] = p->opcode;
+ 
+@@ -59,6 +60,7 @@ static void __kprobes arch_prepare_ss_slot(struct kprobe *p)
+ 
+ static void __kprobes arch_prepare_simulate(struct kprobe *p)
+ {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	if (p->ainsn.prepare)
+ 		p->ainsn.prepare(p->opcode, &p->ainsn);
+ 
+@@ -71,6 +73,7 @@ static void __kprobes arch_simulate_insn(struct kprobe *p, struct pt_regs *regs)
+ {
+ 	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	if (p->ainsn.handler)
+ 		p->ainsn.handler((u32)p->opcode, (long)p->addr, regs);
+ 
+@@ -83,6 +86,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
+ 	kprobe_opcode_t insn;
+ 	unsigned long probe_addr = (unsigned long)p->addr;
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	/* copy instruction */
+ 	insn = *p->addr;
+ 	p->opcode = insn;
+@@ -90,19 +94,25 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
+ 	if (in_exception_text(probe_addr))
+ 		return -EINVAL;
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	/* decode instruction */
+ 	switch (arm_kprobe_decode_insn(insn, &p->ainsn)) {
+ 	case INSN_REJECTED:	/* insn not supported */
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		return -EINVAL;
+ 
+ 	case INSN_GOOD_NO_SLOT:	/* insn need simulation */
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		p->ainsn.insn = NULL;
+ 		break;
+ 
+ 	case INSN_GOOD:	/* instruction uses slot */
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		p->ainsn.insn = get_insn_slot();
+ 		if (!p->ainsn.insn)
+ 			return -ENOMEM;
++	printk("%s called at %d with slot %p\n", __func__, __LINE__,
++			p->ainsn.insn);
+ 		break;
+ 	};
+ 
+@@ -123,43 +133,51 @@ static int __kprobes patch_text(kprobe_opcode_t *addr, u32 opcode)
+ 	addrs[0] = (void *)addr;
+ 	insns[0] = (u32)opcode;
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	return aarch64_insn_patch_text_sync(addrs, insns, 1);
+ }
+ 
+ /* arm kprobe: install breakpoint in text */
+ void __kprobes arch_arm_kprobe(struct kprobe *p)
+ {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	patch_text(p->addr, BRK64_OPCODE_KPROBES);
+ }
+ 
+ /* disarm kprobe: remove breakpoint from text */
+ void __kprobes arch_disarm_kprobe(struct kprobe *p)
+ {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	patch_text(p->addr, p->opcode);
+ }
+ 
+ void __kprobes arch_remove_kprobe(struct kprobe *p)
+ {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	if (p->ainsn.insn) {
+ 		free_insn_slot(p->ainsn.insn, 0);
+ 		p->ainsn.insn = NULL;
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	}
+ }
+ 
+ static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
+ {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	kcb->prev_kprobe.kp = kprobe_running();
+ 	kcb->prev_kprobe.status = kcb->kprobe_status;
+ }
+ 
+ static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
+ {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	__this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);
+ 	kcb->kprobe_status = kcb->prev_kprobe.status;
+ }
+ 
+ static void __kprobes set_current_kprobe(struct kprobe *p)
+ {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	__this_cpu_write(current_kprobe, p);
+ }
+ 
+@@ -177,6 +195,7 @@ spsr_set_debug_flag(struct pt_regs *regs, int mask)
+ {
+ 	unsigned long spsr = regs->pstate;
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	if (mask)
+ 		spsr |= PSR_D_BIT;
+ 	else
+@@ -197,6 +216,7 @@ static void __kprobes kprobes_save_local_irqflag(struct pt_regs *regs)
+ {
+ 	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	kcb->saved_irqflag = regs->pstate;
+ 	regs->pstate |= PSR_I_BIT;
+ }
+@@ -205,6 +225,7 @@ static void __kprobes kprobes_restore_local_irqflag(struct pt_regs *regs)
+ {
+ 	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	if (kcb->saved_irqflag & PSR_I_BIT)
+ 		regs->pstate |= PSR_I_BIT;
+ 	else
+@@ -216,10 +237,12 @@ set_ss_context(struct kprobe_ctlblk *kcb, unsigned long addr)
+ {
+ 	kcb->ss_ctx.ss_status = KPROBES_STEP_PENDING;
+ 	kcb->ss_ctx.match_addr = addr + sizeof(kprobe_opcode_t);
++	printk("%s called at %d with match_addr %lx\n", __func__, __LINE__, kcb->ss_ctx.match_addr);
+ }
+ 
+ static void __kprobes clear_ss_context(struct kprobe_ctlblk *kcb)
+ {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	kcb->ss_ctx.ss_status = KPROBES_STEP_NONE;
+ 	kcb->ss_ctx.match_addr = 0;
+ }
+@@ -227,6 +250,7 @@ static void __kprobes clear_ss_context(struct kprobe_ctlblk *kcb)
+ static void __kprobes
+ skip_singlestep_missed(struct kprobe_ctlblk *kcb, struct pt_regs *regs)
+ {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	/* set return addr to next pc to continue */
+ 	instruction_pointer_set(regs,
+ 			instruction_pointer(regs) + sizeof(kprobe_opcode_t));
+@@ -238,15 +262,19 @@ static void __kprobes setup_singlestep(struct kprobe *p,
+ {
+ 	unsigned long slot;
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	if (reenter) {
+ 		save_previous_kprobe(kcb);
+ 		set_current_kprobe(p);
+ 		kcb->kprobe_status = KPROBE_REENTER;
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	} else {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		kcb->kprobe_status = KPROBE_HIT_SS;
+ 	}
+ 
+ 	if (p->ainsn.insn) {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		/* prepare for single stepping */
+ 		slot = (unsigned long)p->ainsn.insn;
+ 
+@@ -259,7 +287,10 @@ static void __kprobes setup_singlestep(struct kprobe *p,
+ 		kprobes_save_local_irqflag(regs);
+ 		kernel_enable_single_step(regs);
+ 		instruction_pointer_set(regs, slot);
++	printk("%s called at %d with slot %lx\n", __func__, __LINE__,
++			slot);
+ 	} else	{
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		/* insn simulation */
+ 		arch_simulate_insn(p, regs);
+ 	}
+@@ -269,15 +300,19 @@ static int __kprobes reenter_kprobe(struct kprobe *p,
+ 				    struct pt_regs *regs,
+ 				    struct kprobe_ctlblk *kcb)
+ {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	switch (kcb->kprobe_status) {
+ 	case KPROBE_HIT_SSDONE:
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	case KPROBE_HIT_ACTIVE:
+ 		if (!p->ainsn.check_condn ||
+ 				p->ainsn.check_condn((u32)p->opcode, &p->ainsn,
+ 					regs)) {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 			kprobes_inc_nmissed_count(p);
+ 			setup_singlestep(p, regs, kcb, 1);
+ 		} else	{
++	printk("%s called at %d\n", __func__, __LINE__);
+ 			/* condition check failed, skip stepping */
+ 			skip_singlestep_missed(kcb, regs);
+ 		}
+@@ -292,6 +327,7 @@ static int __kprobes reenter_kprobe(struct kprobe *p,
+ 		return 0;
+ 	}
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	return 1;
+ }
+ 
+@@ -300,30 +336,36 @@ post_kprobe_handler(struct kprobe_ctlblk *kcb, struct pt_regs *regs)
+ {
+ 	struct kprobe *cur = kprobe_running();
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	if (!cur)
+ 		return;
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	/* return addr restore if non-branching insn */
+ 	if (cur->ainsn.restore.type == RESTORE_PC) {
+ 		instruction_pointer_set(regs, cur->ainsn.restore.addr);
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		if (!instruction_pointer(regs))
+ 			BUG();
+ 	}
+ 
+ 	/* restore back original saved kprobe variables and continue */
+ 	if (kcb->kprobe_status == KPROBE_REENTER) {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		restore_previous_kprobe(kcb);
+ 		return;
+ 	}
+ 	/* call post handler */
+ 	kcb->kprobe_status = KPROBE_HIT_SSDONE;
+ 	if (cur->post_handler)	{
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		/* post_handler can hit breakpoint and single step
+ 		 * again, so we enable D-flag for recursive exception.
+ 		 */
+ 		cur->post_handler(cur, regs, 0);
+ 	}
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	reset_current_kprobe();
+ }
+ 
+@@ -332,9 +374,12 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
+ 	struct kprobe *cur = kprobe_running();
+ 	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	switch (kcb->kprobe_status) {
+ 	case KPROBE_HIT_SS:
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	case KPROBE_REENTER:
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		/*
+ 		 * We are here because the instruction being single
+ 		 * stepped caused a page fault. We reset the current
+@@ -352,7 +397,9 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
+ 
+ 		break;
+ 	case KPROBE_HIT_ACTIVE:
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	case KPROBE_HIT_SSDONE:
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		/*
+ 		 * We increment the nmissed count for accounting,
+ 		 * we can also use npre/npostfault count for accounting
+@@ -367,8 +414,10 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
+ 		 * copy_from_user(), get_user() etc. Let the
+ 		 * user-specified handler try to fix it first.
+ 		 */
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		if (cur->fault_handler && cur->fault_handler(cur, regs, fsr))
+ 			return 1;
++	printk("%s called at %d\n", __func__, __LINE__);
+ 
+ 		/*
+ 		 * In case the user-specified fault handler returned
+@@ -376,6 +425,7 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
+ 		 */
+ 		if (fixup_exception(regs))
+ 			return 1;
++	printk("%s called at %d\n", __func__, __LINE__);
+ 
+ 		break;
+ 	}
+@@ -385,6 +435,7 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
+ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
+ 				       unsigned long val, void *data)
+ {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	return NOTIFY_DONE;
+ }
+ 
+@@ -399,13 +450,19 @@ void __kprobes kprobe_handler(struct pt_regs *regs)
+ 
+ 	p = get_kprobe((kprobe_opcode_t *) addr);
+ 
++	printk("%s called at %d with addr %lx\n", __func__, __LINE__,
++			addr);
+ 	if (p) {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		if (cur) {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 			if (reenter_kprobe(p, regs, kcb))
+ 				return;
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		} else if (!p->ainsn.check_condn ||
+ 				p->ainsn.check_condn((u32)p->opcode, &p->ainsn,
+ 					regs)) {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 			/* Probe hit and conditional execution check ok. */
+ 			set_current_kprobe(p);
+ 			kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+@@ -424,6 +481,7 @@ void __kprobes kprobe_handler(struct pt_regs *regs)
+ 			if (!p->pre_handler || !p->pre_handler(p, regs)) {
+ 				kcb->kprobe_status = KPROBE_HIT_SS;
+ 				setup_singlestep(p, regs, kcb, 0);
++	printk("%s called at %d\n", __func__, __LINE__);
+ 				return;
+ 			}
+ 		} else {
+@@ -431,6 +489,7 @@ void __kprobes kprobe_handler(struct pt_regs *regs)
+ 			 * Breakpoint hit but conditional check failed,
+ 			 * so just skip the instruction (NOP behaviour)
+ 			 */
++	printk("%s called at %d\n", __func__, __LINE__);
+ 			skip_singlestep_missed(kcb, regs);
+ 			return;
+ 		}
+@@ -443,30 +502,37 @@ void __kprobes kprobe_handler(struct pt_regs *regs)
+ 		 * handling of this interrupt is appropriate.
+ 		 * Return back to original instruction, and continue.
+ 		 */
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		return;
+ 	} else if (cur) {
+ 		/* We probably hit a jprobe.  Call its break handler. */
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		if (cur->break_handler && cur->break_handler(cur, regs)) {
+ 			kcb->kprobe_status = KPROBE_HIT_SS;
+ 			setup_singlestep(cur, regs, kcb, 0);
++	printk("%s called at %d\n", __func__, __LINE__);
+ 			return;
+ 		}
+ 	} else {
+ 		/* breakpoint is removed, now in a race
+ 		 * Return back to original instruction & continue.
+ 		 */
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	}
+ }
+ 
+ static int __kprobes
+ kprobe_ss_hit(struct kprobe_ctlblk *kcb, unsigned long addr)
+ {
++	printk("%s called at %d with match_addr %lx and addr %lx\n", __func__, __LINE__, kcb->ss_ctx.match_addr, addr);
+ 	if ((kcb->ss_ctx.ss_status == KPROBES_STEP_PENDING)
+ 	    && (kcb->ss_ctx.match_addr == addr)) {
+ 		clear_ss_context(kcb);	/* clear pending ss */
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		return DBG_HOOK_HANDLED;
+ 	}
+ 	/* not ours, kprobes should ignore it */
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	return DBG_HOOK_ERROR;
+ }
+ 
+@@ -480,6 +546,7 @@ kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr)
+ 	retval = kprobe_ss_hit(kcb, instruction_pointer(regs));
+ 
+ 	if (retval == DBG_HOOK_HANDLED) {
++		c_log_debug_entry(24, esr);
+ 		kprobes_restore_local_irqflag(regs);
+ 		kernel_disable_single_step();
+ 
+@@ -495,6 +562,8 @@ kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr)
+ static int __kprobes
+ kprobe_breakpoint_handler(struct pt_regs *regs, unsigned int esr)
+ {
++	c_log_debug_entry(23, esr);
++	print_debug_log_buf();
+ 	kprobe_handler(regs);
+ 	return DBG_HOOK_HANDLED;
+ }
+@@ -505,12 +574,14 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+ 	struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+ 	long stack_ptr = stack_pointer(regs);
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	kcb->jprobe_saved_regs = *regs;
+ 	memcpy(kcb->jprobes_stack, (void *)stack_ptr,
+ 	       MIN_STACK_SIZE(stack_ptr));
+ 
+ 	instruction_pointer_set(regs, (long)jp->entry);
+ 	preempt_disable();
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	return 1;
+ }
+ 
+@@ -533,6 +604,7 @@ void __kprobes jprobe_return(void)
+ 		      : "r"(&kcb->jprobe_saved_regs.sp),
+ 		      "I"(BRK64_ESR_KPROBES)
+ 		      : "memory");
++	printk("%s called at %d\n", __func__, __LINE__);
+ }
+ 
+ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+@@ -542,10 +614,13 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+ 	long orig_sp = stack_pointer(regs);
+ 	struct jprobe *jp = container_of(p, struct jprobe, kp);
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	if (regs->regs[0] == JPROBES_MAGIC_NUM) {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		if (orig_sp != stack_addr) {
+ 			struct pt_regs *saved_regs =
+ 			    (struct pt_regs *)kcb->jprobe_saved_regs.sp;
++	printk("%s called at %d\n", __func__, __LINE__);
+ 			pr_err("current sp %lx does not match saved sp %lx\n",
+ 			       orig_sp, stack_addr);
+ 			pr_err("Saved registers for jprobe %p\n", jp);
+@@ -558,8 +633,10 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
+ 		memcpy((void *)stack_addr, kcb->jprobes_stack,
+ 		       MIN_STACK_SIZE(stack_addr));
+ 		preempt_enable_no_resched();
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		return 1;
+ 	}
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	return 0;
+ }
+ 
+@@ -586,6 +663,7 @@ static void __used kretprobe_trampoline_holder(void)
+ 			"kretprobe_trampoline:\n"
+ 			"NOP\n\t"
+ 			"NOP\n\t");
++	printk("%s called at %d\n", __func__, __LINE__);
+ }
+ 
+ static int __kprobes
+@@ -614,6 +692,7 @@ trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+ 	 *       real return address, and all the rest will point to
+ 	 *       kretprobe_trampoline
+ 	 */
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	hlist_for_each_entry_safe(ri, tmp, head, hlist) {
+ 		if (ri->task != current)
+ 			/* another task is sharing our hash bucket */
+@@ -652,12 +731,14 @@ trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
+ 	kprobes_restore_local_irqflag(regs);
+ 
+ 	/* return 1 so that post handlers not called */
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	return 1;
+ }
+ 
+ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
+ 				      struct pt_regs *regs)
+ {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	ri->ret_addr = (kprobe_opcode_t *)regs->regs[30];
+ 
+ 	/* replace return addr (x30) with trampoline */
+diff --git a/arch/arm64/kernel/uprobes.c b/arch/arm64/kernel/uprobes.c
+index 97e9d17d22b6..ad891d17faee 100644
+--- a/arch/arm64/kernel/uprobes.c
++++ b/arch/arm64/kernel/uprobes.c
+@@ -19,6 +19,7 @@ void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
+ 	void *xol_page_kaddr = kmap_atomic(page);
+ 	void *dst = xol_page_kaddr + (vaddr & ~PAGE_MASK);
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	preempt_disable();
+ 
+ 	/* Initialize the slot */
+@@ -34,6 +35,7 @@ void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
+ 
+ unsigned long uprobe_get_swbp_addr(struct pt_regs *regs)
+ {
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	return instruction_pointer(regs);
+ }
+ 
+@@ -49,17 +51,21 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm,
+ 
+ 	insn = *(kprobe_opcode_t *)(&auprobe->insn[0]);
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	switch (arm_kprobe_decode_insn(insn, &auprobe->ainsn)) {
+ 	case INSN_REJECTED:
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		return -EINVAL;
+ 
+ 	case INSN_GOOD_NO_SLOT:
++	printk("%s called at %d\n", __func__, __LINE__);
+ 		auprobe->simulate = true;
+ 		if (auprobe->ainsn.prepare)
+ 			auprobe->ainsn.prepare(insn, &auprobe->ainsn);
+ 		break;
+ 
+ 	case INSN_GOOD:
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	default:
+ 		break;
+ 	}
+@@ -71,6 +77,7 @@ int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
+ {
+ 	struct uprobe_task *utask = current->utask;
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	/* saved fault code is restored in post_xol */
+ 	utask->autask.saved_fault_code = current->thread.fault_code;
+ 
+@@ -99,6 +106,7 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
+ 
+ 	user_disable_single_step(current);
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	return 0;
+ }
+ bool arch_uprobe_xol_was_trapped(struct task_struct *t)
+@@ -109,9 +117,11 @@ bool arch_uprobe_xol_was_trapped(struct task_struct *t)
+ 	 * invalid fault code which is being set in arch_uprobe_pre_xol and
+ 	 * restored in arch_uprobe_post_xol.
+ 	 */
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	if (t->thread.fault_code != UPROBE_INV_FAULT_CODE)
+ 		return true;
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	return false;
+ }
+ 
+@@ -120,6 +130,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
+ 	kprobe_opcode_t insn;
+ 	unsigned long addr;
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	if (!auprobe->simulate)
+ 		return false;
+ 
+@@ -129,6 +140,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
+ 	if (auprobe->ainsn.handler)
+ 		auprobe->ainsn.handler(insn, addr, regs);
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	return true;
+ }
+ 
+@@ -136,6 +148,7 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
+ {
+ 	struct uprobe_task *utask = current->utask;
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	current->thread.fault_code = utask->autask.saved_fault_code;
+ 	/*
+ 	 * Task has received a fatal signal, so reset back to probbed
+@@ -152,6 +165,7 @@ arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr,
+ {
+ 	unsigned long orig_ret_vaddr;
+ 
++	printk("%s called at %d\n", __func__, __LINE__);
+ 	orig_ret_vaddr = procedure_link_pointer(regs);
+ 	/* Replace the return addr with trampoline addr */
+ 	procedure_link_pointer_set(regs, trampoline_vaddr);
+@@ -165,24 +179,28 @@ int arch_uprobe_exception_notify(struct notifier_block *self,
+ 	return NOTIFY_DONE;
+ }
+ 
+-static int __kprobes uprobe_breakpoint_handler(struct pt_regs *regs,
++static int uprobe_breakpoint_handler(struct pt_regs *regs,
+ 		unsigned int esr)
+ {
+-	if (user_mode(regs) && uprobe_pre_sstep_notifier(regs))
++	if (user_mode(regs) && uprobe_pre_sstep_notifier(regs)) {
++		c_log_debug_entry(21, esr);
+ 		return DBG_HOOK_HANDLED;
++	}
+ 
+ 	return DBG_HOOK_ERROR;
+ }
+ 
+-static int __kprobes uprobe_single_step_handler(struct pt_regs *regs,
++static int uprobe_single_step_handler(struct pt_regs *regs,
+ 		unsigned int esr)
+ {
+ 	if (user_mode(regs)) {
+ 		WARN_ON(instruction_pointer(regs) !=
+ 				current->utask->xol_vaddr + 4);
+ 
+-		if (uprobe_post_sstep_notifier(regs))
++		if (uprobe_post_sstep_notifier(regs)) {
++			c_log_debug_entry(22, esr);
+ 			return DBG_HOOK_HANDLED;
++		}
+ 	}
+ 
+ 	return DBG_HOOK_ERROR;
+-- 
+2.1.0
diff --git a/a/content_digest b/N1/content_digest
index 48ef929..29901c7 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -7,11 +7,18 @@
  "ref\054B4BF4C.2030009@redhat.com\0"
  "ref\020150113155221.GG16524@e104818-lin.cambridge.arm.com\0"
  "ref\054B55B95.1070402@redhat.com\0"
- "From\0panand@redhat.com (Pratyush Anand)\0"
- "Subject\0Query: ARM64: Behavior of el1_dbg exception while executing el0_dbg\0"
+ "From\0Pratyush Anand <panand@redhat.com>\0"
+ "Subject\0Re: Query: ARM64: Behavior of el1_dbg exception while executing el0_dbg\0"
  "Date\0Thu, 15 Jan 2015 22:17:56 +0530\0"
- "To\0linux-arm-kernel@lists.infradead.org\0"
- "\00:1\0"
+ "To\0Catalin Marinas <catalin.marinas@arm.com>"
+ " Will Deacon <Will.Deacon@arm.com>\0"
+ "Cc\0Steve Capper <steve.capper@linaro.org>"
+  Oleg Nesterov <oleg@redhat.com>
+  linux-kernel@vger.kernel.org <linux-kernel@vger.kernel.org>
+  David Long <dave.long@linaro.org>
+  William Cohen <wcohen@redhat.com>
+ " linux-arm-kernel@lists.infradead.org <linux-arm-kernel@lists.infradead.org>\0"
+ "\01:1\0"
  "b\0"
  "Hi Will / Catalin,\n"
  "\n"
@@ -141,13 +148,1120 @@
  "     [   60.970778] kprobe_handler called at 456\n"
  "     [   60.974681] kprobe_handler called at 465\n"
  "\n"
- "~Pratyush\n"
- "-------------- next part --------------\n"
- "A non-text attachment was scrubbed...\n"
- "Name: 0001-Debug-kprobe-insertion-at-uprobe_breakpoint_handler.patch\n"
- "Type: text/x-patch\n"
- "Size: 33060 bytes\n"
- "Desc: not available\n"
- URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20150115/ba388265/attachment-0001.bin>
+ ~Pratyush
+ "\01:2\0"
+ "fn\00001-Debug-kprobe-insertion-at-uprobe_breakpoint_handler.patch\0"
+ "b\0"
+ ">From cfe62741e100060ee4165fa662689b3220312823 Mon Sep 17 00:00:00 2001\n"
+ "Message-Id: <cfe62741e100060ee4165fa662689b3220312823.1421340459.git.panand@redhat.com>\n"
+ "From: Pratyush Anand <panand@redhat.com>\n"
+ "Date: Wed, 7 Jan 2015 21:40:49 +0530\n"
+ "Subject: [PATCH] Debug kprobe insertion at uprobe_breakpoint_handler\n"
+ "\n"
+ "Step at user level:\n"
+ "================================\n"
+ "\n"
+ "//inserting kprobe at 1st instruction of  uprobe_breakpoint_handler. So\n"
+ "//1st instruction of uprobe_breakpoint_handler has been replaced by\n"
+ "//BRK64_OPCODE_KPROBES when kprobe enabled.\n"
+ "\n"
+ "    echo 'p:myprobe uprobe_breakpoint_handler' >\n"
+ "/sys/kernel/debug/tracing/kprobe_events\n"
+ "\n"
+ "//enabling kprobe\n"
+ "\n"
+ "    echo 1 > /sys/kernel/debug/tracing/events/kprobes/enable\n"
+ "\n"
+ "//run test application\n"
+ "\n"
+ "    ./test&\n"
+ "\n"
+ "//inserting uprobe at offset 0x5d0 of  uprobe_breakpoint_handler. So\n"
+ "//instruction at this offset has been replaced by BRK64_OPCODE_UPROBES,\n"
+ "//when uprobe enabled.\n"
+ "\n"
+ "    echo 'p:test_entry test:0x5d0' >\n"
+ "/sys/kernel/debug/tracing/uprobe_events\n"
+ "\n"
+ "//enabling uprobe\n"
+ "\n"
+ "    echo 1 > /sys/kernel/debug/tracing/events/uprobes/enable\n"
+ "\n"
+ "observed flow summary\n"
+ "========================\n"
+ "    kprobe has been inserted at 1st instruction of\n"
+ "uprobe_breakpoint_handler and\n"
+ "    uprobe has been inserted at offset 0x5d0 of test application.\n"
+ "    Observation is that execution flow is as under:\n"
+ "    -- Application executes  BRK64_OPCODE_UPROBES.\n"
+ "    -- el0_sync is raised.\n"
+ "    -- el0_sync\n"
+ "        -> kernel_entry 0\n"
+ "        -> el0_dbg\n"
+ "            -> do_debug_exception\n"
+ "                ->brk_handler\n"
+ "                    ->call_break_hook\n"
+ "                        ->uprobe_breakpoint_handler\n"
+ "    (1st instruction of uprobe_breakpoint_handler has been modified as\n"
+ "    BRK64_OPCODE_KPROBES)\n"
+ "    -- el1_sync is raised.\n"
+ "    -- el1_sync\n"
+ "        -> kernel_entry 1\n"
+ "        -> el1_dbg\n"
+ "            -> do_debug_exception\n"
+ "                ->brk_handler\n"
+ "                    ->call_break_hook\n"
+ "                        ->kprobe_breakpoint_handler\n"
+ "\n"
+ "    Following printk messages confirms above flow. printk messages has\n"
+ "been\n"
+ "    avoided into el0_dbg and el1_dbg execution path. All the tap points\n"
+ "for\n"
+ "    these path have been written into per_cpu array and then they have\n"
+ "been\n"
+ "    printed when kprobe_breakpoint_handler is executed.\n"
+ "    tap points have been instrumented wherever we are calling macro\n"
+ "    enable_dbg and also in uprobe/kprobe break/single step exception\n"
+ "path.\n"
+ "\n"
+ "printk debug messages with comments\n"
+ "============================================\n"
+ "\n"
+ "    [   60.846047] arch_prepare_kprobe called at 89\n"
+ "    [   60.850344] arch_prepare_kprobe called at 97\n"
+ "    [   60.854595] arch_prepare_kprobe called at 110\n"
+ "    [   60.858959] arch_prepare_kprobe called at 114 with slot\n"
+ "    fffffdfffc000004\n"
+ "    [   60.865633] arch_prepare_ss_slot called at 46\n"
+ "    [   60.874466] arch_arm_kprobe called at 143\n"
+ "    [   60.878487] patch_text called at 136\n"
+ "    [   60.904226] arch_uprobe_analyze_insn called at 54\n"
+ "    [   60.908939] arch_uprobe_analyze_insn called at 68\n"
+ "    [   60.914155] 0.0: event 0 syndrom 0 @cpu 0\n"
+ "    [   60.918151] 0.0: event 0 syndrom 0 @cpu 1\n"
+ "    [   60.922143] 0.0: event 0 syndrom 0 @cpu 2\n"
+ "    [   60.926134] 1421337852.798722179: event 19 syndrom f2000008 @cpu\n"
+ "3\n"
+ "\n"
+ "    [1][Pratyush]: ESR = f2000008 and event 19 says its uprobe\n"
+ "breakpoint\n"
+ "    exception\n"
+ "\n"
+ "    [   60.932286] 1421337852.798722179: event 19 syndrom f2000004 @cpu\n"
+ "3\n"
+ "\n"
+ "    [2][Pratyush]: ESR = f2000004 and event 19 says its kprobe\n"
+ "breakpoint\n"
+ "    exception\n"
+ "\n"
+ "    [   60.938438] 1421337852.798722179: event 23 syndrom f2000004 @cpu\n"
+ "3\n"
+ "\n"
+ "    [3][Pratyush]: ESR = f2000004 and event 23 says that we are in\n"
+ "function\n"
+ "    kprobe_breakpoint_handler\n"
+ "\n"
+ "    Since we did not receive any event corresponding to calling of\n"
+ "    enable_dbg macro\n"
+ "    or execution of either uprobe_breakpoint_handler or\n"
+ "    uprobe_single_step_handler, so it is confirmed that,\n"
+ "    we received el1_dbg while executing el0_dbg\n"
+ "\n"
+ "    [   60.944590] 0.0: event 0 syndrom 0 @cpu 3\n"
+ "    [   60.948579] 0.0: event 0 syndrom 0 @cpu 4\n"
+ "    [   60.952569] 0.0: event 0 syndrom 0 @cpu 5\n"
+ "    [   60.956558] 0.0: event 0 syndrom 0 @cpu 6\n"
+ "    [   60.960547] 0.0: event 0 syndrom 0 @cpu 7\n"
+ "    [   60.964539] kprobe_handler called at 453 with addr\n"
+ "fffffe000009fd80\n"
+ "    [   60.970778] kprobe_handler called at 456\n"
+ "    [   60.974681] kprobe_handler called at 465\n"
+ "\n"
+ "Signed-off-by: Pratyush Anand <panand@redhat.com>\n"
+ "---\n"
+ " arch/arm64/include/asm/probes.h    |   2 +\n"
+ " arch/arm64/kernel/debug-monitors.c |  91 +++++++++++++++++++++++++++++++\n"
+ " arch/arm64/kernel/entry.S          | 108 +++++++++++++++++++++++++++++++++++++\n"
+ " arch/arm64/kernel/kprobes.c        |  81 ++++++++++++++++++++++++++++\n"
+ " arch/arm64/kernel/uprobes.c        |  26 +++++++--\n"
+ " 5 files changed, 304 insertions(+), 4 deletions(-)\n"
+ "\n"
+ "diff --git a/arch/arm64/include/asm/probes.h b/arch/arm64/include/asm/probes.h\n"
+ "index 54c253ba2d25..aebcf37a64f9 100644\n"
+ "--- a/arch/arm64/include/asm/probes.h\n"
+ "+++ b/arch/arm64/include/asm/probes.h\n"
+ "@@ -15,6 +15,8 @@\n"
+ " #ifndef _ARM_PROBES_H\n"
+ " #define _ARM_PROBES_H\n"
+ " \n"
+ "+void print_debug_log_buf(void);\n"
+ "+void c_log_debug_entry(u64 pt, u64 syn);\n"
+ " struct kprobe;\n"
+ " struct arch_specific_insn;\n"
+ " \n"
+ "diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c\n"
+ "index aaa0e87d52f1..4643a5243750 100644\n"
+ "--- a/arch/arm64/kernel/debug-monitors.c\n"
+ "+++ b/arch/arm64/kernel/debug-monitors.c\n"
+ "@@ -30,6 +30,91 @@\n"
+ " #include <asm/cputype.h>\n"
+ " #include <asm/system_misc.h>\n"
+ " \n"
+ "+struct debug_log_buf {\n"
+ "+\tu64\tpt;\n"
+ "+\tu64\tsyn;\n"
+ "+\tstruct timespec now;\n"
+ "+};\n"
+ "+\n"
+ "+#define MAX_DEBUG_LOG_COUNT\t1000\n"
+ "+\n"
+ "+/*\n"
+ "+ * Debug point\n"
+ "+ * 1(el1_sync)\n"
+ "+ * 2(el1_irq)\n"
+ "+ * 3(el0_sync)\n"
+ "+ * 4(el0_irq)\n"
+ "+ * 5(el1_da)\n"
+ "+ * 6(el1_sp_pc)\n"
+ "+ * 7(el1_undef)\n"
+ "+ * 8(el1_inv)\n"
+ "+ * 9(el0_da)\n"
+ "+ * 10(el0_ia)\n"
+ "+ * 11(el0_fpsimd_acc)\n"
+ "+ * 12(el0_fpsimd_exc)\n"
+ "+ * 13(el0_sp_pc)\n"
+ "+ * 14(el0_undef)\n"
+ "+ * 15(el0_dbg)\n"
+ "+ * 16(el0_inv)\n"
+ "+ * 17(el0_irq_nacked)\n"
+ "+ * 18(el0_svc_nacked)\n"
+ "+ * 19 brk_handler\n"
+ "+ * 20 single_step\n"
+ "+ * 21 uprobe_breakpoint_handler\n"
+ "+ * 22 uprobe_single_step_handler\n"
+ "+ * 23 kprobe_breakpoint_handler\n"
+ "+ * 24 kprobe_single_step_handler\n"
+ "+ */\n"
+ "+\n"
+ "+static DEFINE_PER_CPU(struct debug_log_buf[MAX_DEBUG_LOG_COUNT], debug_log_events);\n"
+ "+static DEFINE_PER_CPU(u32, debug_log_counts);\n"
+ "+bool start_log_event;\n"
+ "+\n"
+ "+void print_debug_log_buf(void)\n"
+ "+{\n"
+ "+\tu32 cpu;\n"
+ "+\tu32 count, c;\n"
+ "+\tstruct debug_log_buf *log_buf;\n"
+ "+\n"
+ "+\tif (!start_log_event)\n"
+ "+\t\treturn;\n"
+ "+\n"
+ "+\tstart_log_event = false;\n"
+ "+\n"
+ "+\tfor_each_possible_cpu(cpu) {\n"
+ "+\t\tcount = per_cpu(debug_log_counts, cpu);\n"
+ "+\t\tlog_buf = per_cpu(debug_log_events, cpu);\n"
+ "+\t\t/* if last log is wrong, it means we did not overflow */\n"
+ "+\t\tfor (c = 0; c <= count; c++) {\n"
+ "+\t\t\tprintk(\"%ld.%ld: event %lld syndrom %llx @cpu %d\\n\",\n"
+ "+\t\t\t\t\t(log_buf + c)->now.tv_sec, (log_buf + c)->now.tv_nsec,\n"
+ "+\t\t\t\t\t(log_buf + c)->pt, (log_buf + c)->syn, cpu);\n"
+ "+\t\t}\n"
+ "+\t}\n"
+ "+}\n"
+ "+\n"
+ "+void c_log_debug_entry(u64 pt, u64 syn)\n"
+ "+{\n"
+ "+\tu32 cpu;\n"
+ "+\tu32 count;\n"
+ "+\tstruct debug_log_buf *log_buf;\n"
+ "+\n"
+ "+\tif (!start_log_event)\n"
+ "+\t\treturn;\n"
+ "+\n"
+ "+\tcpu = get_cpu();\n"
+ "+\tcount = per_cpu(debug_log_counts, cpu);\n"
+ "+\t/* reset count when overflow */\n"
+ "+\tif (count == MAX_DEBUG_LOG_COUNT)\n"
+ "+\t\tper_cpu(debug_log_counts, cpu) = 0;\n"
+ "+\tlog_buf = per_cpu(debug_log_events, cpu);\n"
+ "+\t(log_buf + count)->pt = pt;\n"
+ "+\t(log_buf + count)->syn = syn;\n"
+ "+\t(log_buf + count)->now = current_kernel_time();\n"
+ "+\tper_cpu(debug_log_counts, cpu)++;\n"
+ "+\tput_cpu();\n"
+ "+}\n"
+ "+\n"
+ " /* Determine debug architecture. */\n"
+ " u8 debug_monitors_arch(void)\n"
+ " {\n"
+ "@@ -229,6 +314,7 @@ static int single_step_handler(unsigned long addr, unsigned int esr,\n"
+ " {\n"
+ " \tsiginfo_t info;\n"
+ " \n"
+ "+\tc_log_debug_entry(20, esr);\n"
+ " \t/*\n"
+ " \t * If we are stepping a pending breakpoint, call the hw_breakpoint\n"
+ " \t * handler first.\n"
+ "@@ -306,6 +392,11 @@ static int brk_handler(unsigned long addr, unsigned int esr,\n"
+ " {\n"
+ " \tsiginfo_t info;\n"
+ " \n"
+ "+\t/* start log when uprobe bkpt exception is received */\n"
+ "+\tif (esr == 0xf2000008)\n"
+ "+\t\tstart_log_event = true;\n"
+ "+\tc_log_debug_entry(19, esr);\n"
+ "+\n"
+ " \tif (call_break_hook(regs, esr) == DBG_HOOK_HANDLED)\n"
+ " \t\treturn 0;\n"
+ " \n"
+ "diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S\n"
+ "index 726b910fe6ec..271b8d9f7a9a 100644\n"
+ "--- a/arch/arm64/kernel/entry.S\n"
+ "+++ b/arch/arm64/kernel/entry.S\n"
+ "@@ -28,6 +28,96 @@\n"
+ " #include <asm/thread_info.h>\n"
+ " #include <asm/unistd.h>\n"
+ " \n"
+ "+\t.macro log_debug_entry, pt\n"
+ "+\tpush\tx28, x29\n"
+ "+\tpush\tx26, x27\n"
+ "+\tpush\tx24, x25\n"
+ "+\tpush\tx22, x23\n"
+ "+\tpush\tx20, x21\n"
+ "+\tpush\tx18, x19\n"
+ "+\tpush\tx16, x17\n"
+ "+\tpush\tx14, x15\n"
+ "+\tpush\tx12, x13\n"
+ "+\tpush\tx10, x11\n"
+ "+\tpush\tx8, x9\n"
+ "+\tpush\tx6, x7\n"
+ "+\tpush\tx4, x5\n"
+ "+\tpush\tx2, x3\n"
+ "+\tpush\tx0, x1\n"
+ "+\tpush\tx29, x30\n"
+ "+\t.if \\pt == 1\n"
+ "+\tmov\tx0, #1\n"
+ "+\t.endif\n"
+ "+\t.if \\pt == 2\n"
+ "+\tmov\tx0, #2\n"
+ "+\t.endif\n"
+ "+\t.if \\pt == 3\n"
+ "+\tmov\tx0, #3\n"
+ "+\t.endif\n"
+ "+\t.if \\pt == 4\n"
+ "+\tmov\tx0, #4\n"
+ "+\t.endif\n"
+ "+\t.if \\pt == 5\n"
+ "+\tmov\tx0, #5\n"
+ "+\t.endif\n"
+ "+\t.if \\pt == 6\n"
+ "+\tmov\tx0, #6\n"
+ "+\t.endif\n"
+ "+\t.if \\pt == 7\n"
+ "+\tmov\tx0, #7\n"
+ "+\t.endif\n"
+ "+\t.if \\pt == 8\n"
+ "+\tmov\tx0, #8\n"
+ "+\t.endif\n"
+ "+\t.if \\pt == 9\n"
+ "+\tmov\tx0, #9\n"
+ "+\t.endif\n"
+ "+\t.if \\pt == 10\n"
+ "+\tmov\tx0, #10\n"
+ "+\t.endif\n"
+ "+\t.if \\pt == 11\n"
+ "+\tmov\tx0, #11\n"
+ "+\t.endif\n"
+ "+\t.if \\pt == 12\n"
+ "+\tmov\tx0, #12\n"
+ "+\t.endif\n"
+ "+\t.if \\pt == 13\n"
+ "+\tmov\tx0, #13\n"
+ "+\t.endif\n"
+ "+\t.if \\pt == 14\n"
+ "+\tmov\tx0, #14\n"
+ "+\t.endif\n"
+ "+\t.if \\pt == 15\n"
+ "+\tmov\tx0, #15\n"
+ "+\t.endif\n"
+ "+\t.if \\pt == 16\n"
+ "+\tmov\tx0, #16\n"
+ "+\t.endif\n"
+ "+\t.if \\pt == 17\n"
+ "+\tmov\tx0, #17\n"
+ "+\t.endif\n"
+ "+\t.if \\pt == 18\n"
+ "+\tmov\tx0, #18\n"
+ "+\t.endif\n"
+ "+\tmrs\tx1, esr_el1\t\t\t// read the syndrome register\n"
+ "+\tbl\tc_log_debug_entry\n"
+ "+\tpop\tx29, x30\n"
+ "+\tpop\tx0, x1\n"
+ "+\tpop\tx2, x3\n"
+ "+\tpop\tx4, x5\n"
+ "+\tpop\tx6, x7\n"
+ "+\tpop\tx8, x9\n"
+ "+\tpop\tx10, x11\n"
+ "+\tpop\tx12, x13\n"
+ "+\tpop\tx14, x15\n"
+ "+\tpop\tx16, x17\n"
+ "+\tpop\tx18, x19\n"
+ "+\tpop\tx20, x21\n"
+ "+\tpop\tx22, x23\n"
+ "+\tpop\tx24, x25\n"
+ "+\tpop\tx26, x27\n"
+ "+\tpop\tx28, x29\n"
+ "+\t.endm\n"
+ " /*\n"
+ "  * Context tracking subsystem.  Used to instrument transitions\n"
+ "  * between user and kernel mode.\n"
+ "@@ -269,6 +359,7 @@ ENDPROC(el1_error_invalid)\n"
+ " el1_sync:\n"
+ " \tkernel_entry 1\n"
+ " \tmrs\tx1, esr_el1\t\t\t// read the syndrome register\n"
+ "+\t//log_debug_entry 1\n"
+ " \tlsr\tx24, x1, #ESR_EL1_EC_SHIFT\t// exception class\n"
+ " \tcmp\tx24, #ESR_EL1_EC_DABT_EL1\t// data abort in EL1\n"
+ " \tb.eq\tel1_da\n"
+ "@@ -288,6 +379,7 @@ el1_da:\n"
+ " \t * Data abort handling\n"
+ " \t */\n"
+ " \tmrs\tx0, far_el1\n"
+ "+\tlog_debug_entry 5\n"
+ " \tenable_dbg\n"
+ " \t// re-enable interrupts if they were enabled in the aborted context\n"
+ " \ttbnz\tx23, #7, 1f\t\t\t// PSR_I_BIT\n"
+ "@@ -304,6 +396,7 @@ el1_sp_pc:\n"
+ " \t * Stack or PC alignment exception handling\n"
+ " \t */\n"
+ " \tmrs\tx0, far_el1\n"
+ "+\tlog_debug_entry 6\n"
+ " \tenable_dbg\n"
+ " \tmov\tx2, sp\n"
+ " \tb\tdo_sp_pc_abort\n"
+ "@@ -311,6 +404,7 @@ el1_undef:\n"
+ " \t/*\n"
+ " \t * Undefined instruction\n"
+ " \t */\n"
+ "+\tlog_debug_entry 7\n"
+ " \tenable_dbg\n"
+ " \tmov\tx0, sp\n"
+ " \tb\tdo_undefinstr\n"
+ "@@ -327,6 +421,7 @@ el1_dbg:\n"
+ " \tkernel_exit 1\n"
+ " el1_inv:\n"
+ " \t// TODO: add support for undefined instructions in kernel mode\n"
+ "+\tlog_debug_entry 8\n"
+ " \tenable_dbg\n"
+ " \tmov\tx0, sp\n"
+ " \tmov\tx1, #BAD_SYNC\n"
+ "@@ -337,6 +432,7 @@ ENDPROC(el1_sync)\n"
+ " \t.align\t6\n"
+ " el1_irq:\n"
+ " \tkernel_entry 1\n"
+ "+\tlog_debug_entry 2\n"
+ " \tenable_dbg\n"
+ " #ifdef CONFIG_TRACE_IRQFLAGS\n"
+ " \tbl\ttrace_hardirqs_off\n"
+ "@@ -375,6 +471,7 @@ el1_preempt:\n"
+ " el0_sync:\n"
+ " \tkernel_entry 0\n"
+ " \tmrs\tx25, esr_el1\t\t\t// read the syndrome register\n"
+ "+\t//log_debug_entry 3\n"
+ " \tlsr\tx24, x25, #ESR_EL1_EC_SHIFT\t// exception class\n"
+ " \tcmp\tx24, #ESR_EL1_EC_SVC64\t\t// SVC in 64-bit state\n"
+ " \tb.eq\tel0_svc\n"
+ "@@ -450,6 +547,7 @@ el0_da:\n"
+ " \t */\n"
+ " \tmrs\tx26, far_el1\n"
+ " \t// enable interrupts before calling the main handler\n"
+ "+\tlog_debug_entry 9\n"
+ " \tenable_dbg_and_irq\n"
+ " \tct_user_exit\n"
+ " \tbic\tx0, x26, #(0xff << 56)\n"
+ "@@ -463,6 +561,7 @@ el0_ia:\n"
+ " \t */\n"
+ " \tmrs\tx26, far_el1\n"
+ " \t// enable interrupts before calling the main handler\n"
+ "+\tlog_debug_entry 10\n"
+ " \tenable_dbg_and_irq\n"
+ " \tct_user_exit\n"
+ " \tmov\tx0, x26\n"
+ "@@ -474,6 +573,7 @@ el0_fpsimd_acc:\n"
+ " \t/*\n"
+ " \t * Floating Point or Advanced SIMD access\n"
+ " \t */\n"
+ "+\tlog_debug_entry 11\n"
+ " \tenable_dbg\n"
+ " \tct_user_exit\n"
+ " \tmov\tx0, x25\n"
+ "@@ -484,6 +584,7 @@ el0_fpsimd_exc:\n"
+ " \t/*\n"
+ " \t * Floating Point or Advanced SIMD exception\n"
+ " \t */\n"
+ "+\tlog_debug_entry 12\n"
+ " \tenable_dbg\n"
+ " \tct_user_exit\n"
+ " \tmov\tx0, x25\n"
+ "@@ -496,6 +597,7 @@ el0_sp_pc:\n"
+ " \t */\n"
+ " \tmrs\tx26, far_el1\n"
+ " \t// enable interrupts before calling the main handler\n"
+ "+\tlog_debug_entry 13\n"
+ " \tenable_dbg_and_irq\n"
+ " \tmov\tx0, x26\n"
+ " \tmov\tx1, x25\n"
+ "@@ -507,6 +609,7 @@ el0_undef:\n"
+ " \t * Undefined instruction\n"
+ " \t */\n"
+ " \t// enable interrupts before calling the main handler\n"
+ "+\tlog_debug_entry 14\n"
+ " \tenable_dbg_and_irq\n"
+ " \tct_user_exit\n"
+ " \tmov\tx0, sp\n"
+ "@@ -521,10 +624,12 @@ el0_dbg:\n"
+ " \tmov\tx1, x25\n"
+ " \tmov\tx2, sp\n"
+ " \tbl\tdo_debug_exception\n"
+ "+\tlog_debug_entry 15\n"
+ " \tenable_dbg\n"
+ " \tct_user_exit\n"
+ " \tb\tret_to_user\n"
+ " el0_inv:\n"
+ "+\tlog_debug_entry 16\n"
+ " \tenable_dbg\n"
+ " \tct_user_exit\n"
+ " \tmov\tx0, sp\n"
+ "@@ -537,7 +642,9 @@ ENDPROC(el0_sync)\n"
+ " \t.align\t6\n"
+ " el0_irq:\n"
+ " \tkernel_entry 0\n"
+ "+\t//log_debug_entry 4\n"
+ " el0_irq_naked:\n"
+ "+\tlog_debug_entry 17\n"
+ " \tenable_dbg\n"
+ " #ifdef CONFIG_TRACE_IRQFLAGS\n"
+ " \tbl\ttrace_hardirqs_off\n"
+ "@@ -647,6 +754,7 @@ el0_svc:\n"
+ " \tmov\tsc_nr, #__NR_syscalls\n"
+ " el0_svc_naked:\t\t\t\t\t// compat entry point\n"
+ " \tstp\tx0, scno, [sp, #S_ORIG_X0]\t// save the original x0 and syscall number\n"
+ "+\tlog_debug_entry 18\n"
+ " \tenable_dbg_and_irq\n"
+ " \tct_user_exit 1\n"
+ " \n"
+ "diff --git a/arch/arm64/kernel/kprobes.c b/arch/arm64/kernel/kprobes.c\n"
+ "index 514e11411a67..651b0e6b19d1 100644\n"
+ "--- a/arch/arm64/kernel/kprobes.c\n"
+ "+++ b/arch/arm64/kernel/kprobes.c\n"
+ "@@ -43,6 +43,7 @@ post_kprobe_handler(struct kprobe_ctlblk *, struct pt_regs *);\n"
+ " \n"
+ " static void __kprobes arch_prepare_ss_slot(struct kprobe *p)\n"
+ " {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t/* prepare insn slot */\n"
+ " \tp->ainsn.insn[0] = p->opcode;\n"
+ " \n"
+ "@@ -59,6 +60,7 @@ static void __kprobes arch_prepare_ss_slot(struct kprobe *p)\n"
+ " \n"
+ " static void __kprobes arch_prepare_simulate(struct kprobe *p)\n"
+ " {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tif (p->ainsn.prepare)\n"
+ " \t\tp->ainsn.prepare(p->opcode, &p->ainsn);\n"
+ " \n"
+ "@@ -71,6 +73,7 @@ static void __kprobes arch_simulate_insn(struct kprobe *p, struct pt_regs *regs)\n"
+ " {\n"
+ " \tstruct kprobe_ctlblk *kcb = get_kprobe_ctlblk();\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tif (p->ainsn.handler)\n"
+ " \t\tp->ainsn.handler((u32)p->opcode, (long)p->addr, regs);\n"
+ " \n"
+ "@@ -83,6 +86,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)\n"
+ " \tkprobe_opcode_t insn;\n"
+ " \tunsigned long probe_addr = (unsigned long)p->addr;\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t/* copy instruction */\n"
+ " \tinsn = *p->addr;\n"
+ " \tp->opcode = insn;\n"
+ "@@ -90,19 +94,25 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)\n"
+ " \tif (in_exception_text(probe_addr))\n"
+ " \t\treturn -EINVAL;\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t/* decode instruction */\n"
+ " \tswitch (arm_kprobe_decode_insn(insn, &p->ainsn)) {\n"
+ " \tcase INSN_REJECTED:\t/* insn not supported */\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\treturn -EINVAL;\n"
+ " \n"
+ " \tcase INSN_GOOD_NO_SLOT:\t/* insn need simulation */\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\tp->ainsn.insn = NULL;\n"
+ " \t\tbreak;\n"
+ " \n"
+ " \tcase INSN_GOOD:\t/* instruction uses slot */\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\tp->ainsn.insn = get_insn_slot();\n"
+ " \t\tif (!p->ainsn.insn)\n"
+ " \t\t\treturn -ENOMEM;\n"
+ "+\tprintk(\"%s called at %d with slot %p\\n\", __func__, __LINE__,\n"
+ "+\t\t\tp->ainsn.insn);\n"
+ " \t\tbreak;\n"
+ " \t};\n"
+ " \n"
+ "@@ -123,43 +133,51 @@ static int __kprobes patch_text(kprobe_opcode_t *addr, u32 opcode)\n"
+ " \taddrs[0] = (void *)addr;\n"
+ " \tinsns[0] = (u32)opcode;\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \treturn aarch64_insn_patch_text_sync(addrs, insns, 1);\n"
+ " }\n"
+ " \n"
+ " /* arm kprobe: install breakpoint in text */\n"
+ " void __kprobes arch_arm_kprobe(struct kprobe *p)\n"
+ " {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tpatch_text(p->addr, BRK64_OPCODE_KPROBES);\n"
+ " }\n"
+ " \n"
+ " /* disarm kprobe: remove breakpoint from text */\n"
+ " void __kprobes arch_disarm_kprobe(struct kprobe *p)\n"
+ " {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tpatch_text(p->addr, p->opcode);\n"
+ " }\n"
+ " \n"
+ " void __kprobes arch_remove_kprobe(struct kprobe *p)\n"
+ " {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tif (p->ainsn.insn) {\n"
+ " \t\tfree_insn_slot(p->ainsn.insn, 0);\n"
+ " \t\tp->ainsn.insn = NULL;\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t}\n"
+ " }\n"
+ " \n"
+ " static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)\n"
+ " {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tkcb->prev_kprobe.kp = kprobe_running();\n"
+ " \tkcb->prev_kprobe.status = kcb->kprobe_status;\n"
+ " }\n"
+ " \n"
+ " static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)\n"
+ " {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t__this_cpu_write(current_kprobe, kcb->prev_kprobe.kp);\n"
+ " \tkcb->kprobe_status = kcb->prev_kprobe.status;\n"
+ " }\n"
+ " \n"
+ " static void __kprobes set_current_kprobe(struct kprobe *p)\n"
+ " {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t__this_cpu_write(current_kprobe, p);\n"
+ " }\n"
+ " \n"
+ "@@ -177,6 +195,7 @@ spsr_set_debug_flag(struct pt_regs *regs, int mask)\n"
+ " {\n"
+ " \tunsigned long spsr = regs->pstate;\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tif (mask)\n"
+ " \t\tspsr |= PSR_D_BIT;\n"
+ " \telse\n"
+ "@@ -197,6 +216,7 @@ static void __kprobes kprobes_save_local_irqflag(struct pt_regs *regs)\n"
+ " {\n"
+ " \tstruct kprobe_ctlblk *kcb = get_kprobe_ctlblk();\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tkcb->saved_irqflag = regs->pstate;\n"
+ " \tregs->pstate |= PSR_I_BIT;\n"
+ " }\n"
+ "@@ -205,6 +225,7 @@ static void __kprobes kprobes_restore_local_irqflag(struct pt_regs *regs)\n"
+ " {\n"
+ " \tstruct kprobe_ctlblk *kcb = get_kprobe_ctlblk();\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tif (kcb->saved_irqflag & PSR_I_BIT)\n"
+ " \t\tregs->pstate |= PSR_I_BIT;\n"
+ " \telse\n"
+ "@@ -216,10 +237,12 @@ set_ss_context(struct kprobe_ctlblk *kcb, unsigned long addr)\n"
+ " {\n"
+ " \tkcb->ss_ctx.ss_status = KPROBES_STEP_PENDING;\n"
+ " \tkcb->ss_ctx.match_addr = addr + sizeof(kprobe_opcode_t);\n"
+ "+\tprintk(\"%s called at %d with match_addr %lx\\n\", __func__, __LINE__, kcb->ss_ctx.match_addr);\n"
+ " }\n"
+ " \n"
+ " static void __kprobes clear_ss_context(struct kprobe_ctlblk *kcb)\n"
+ " {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tkcb->ss_ctx.ss_status = KPROBES_STEP_NONE;\n"
+ " \tkcb->ss_ctx.match_addr = 0;\n"
+ " }\n"
+ "@@ -227,6 +250,7 @@ static void __kprobes clear_ss_context(struct kprobe_ctlblk *kcb)\n"
+ " static void __kprobes\n"
+ " skip_singlestep_missed(struct kprobe_ctlblk *kcb, struct pt_regs *regs)\n"
+ " {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t/* set return addr to next pc to continue */\n"
+ " \tinstruction_pointer_set(regs,\n"
+ " \t\t\tinstruction_pointer(regs) + sizeof(kprobe_opcode_t));\n"
+ "@@ -238,15 +262,19 @@ static void __kprobes setup_singlestep(struct kprobe *p,\n"
+ " {\n"
+ " \tunsigned long slot;\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tif (reenter) {\n"
+ " \t\tsave_previous_kprobe(kcb);\n"
+ " \t\tset_current_kprobe(p);\n"
+ " \t\tkcb->kprobe_status = KPROBE_REENTER;\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t} else {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\tkcb->kprobe_status = KPROBE_HIT_SS;\n"
+ " \t}\n"
+ " \n"
+ " \tif (p->ainsn.insn) {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\t/* prepare for single stepping */\n"
+ " \t\tslot = (unsigned long)p->ainsn.insn;\n"
+ " \n"
+ "@@ -259,7 +287,10 @@ static void __kprobes setup_singlestep(struct kprobe *p,\n"
+ " \t\tkprobes_save_local_irqflag(regs);\n"
+ " \t\tkernel_enable_single_step(regs);\n"
+ " \t\tinstruction_pointer_set(regs, slot);\n"
+ "+\tprintk(\"%s called at %d with slot %lx\\n\", __func__, __LINE__,\n"
+ "+\t\t\tslot);\n"
+ " \t} else\t{\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\t/* insn simulation */\n"
+ " \t\tarch_simulate_insn(p, regs);\n"
+ " \t}\n"
+ "@@ -269,15 +300,19 @@ static int __kprobes reenter_kprobe(struct kprobe *p,\n"
+ " \t\t\t\t    struct pt_regs *regs,\n"
+ " \t\t\t\t    struct kprobe_ctlblk *kcb)\n"
+ " {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tswitch (kcb->kprobe_status) {\n"
+ " \tcase KPROBE_HIT_SSDONE:\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tcase KPROBE_HIT_ACTIVE:\n"
+ " \t\tif (!p->ainsn.check_condn ||\n"
+ " \t\t\t\tp->ainsn.check_condn((u32)p->opcode, &p->ainsn,\n"
+ " \t\t\t\t\tregs)) {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\t\tkprobes_inc_nmissed_count(p);\n"
+ " \t\t\tsetup_singlestep(p, regs, kcb, 1);\n"
+ " \t\t} else\t{\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\t\t/* condition check failed, skip stepping */\n"
+ " \t\t\tskip_singlestep_missed(kcb, regs);\n"
+ " \t\t}\n"
+ "@@ -292,6 +327,7 @@ static int __kprobes reenter_kprobe(struct kprobe *p,\n"
+ " \t\treturn 0;\n"
+ " \t}\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \treturn 1;\n"
+ " }\n"
+ " \n"
+ "@@ -300,30 +336,36 @@ post_kprobe_handler(struct kprobe_ctlblk *kcb, struct pt_regs *regs)\n"
+ " {\n"
+ " \tstruct kprobe *cur = kprobe_running();\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tif (!cur)\n"
+ " \t\treturn;\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t/* return addr restore if non-branching insn */\n"
+ " \tif (cur->ainsn.restore.type == RESTORE_PC) {\n"
+ " \t\tinstruction_pointer_set(regs, cur->ainsn.restore.addr);\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\tif (!instruction_pointer(regs))\n"
+ " \t\t\tBUG();\n"
+ " \t}\n"
+ " \n"
+ " \t/* restore back original saved kprobe variables and continue */\n"
+ " \tif (kcb->kprobe_status == KPROBE_REENTER) {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\trestore_previous_kprobe(kcb);\n"
+ " \t\treturn;\n"
+ " \t}\n"
+ " \t/* call post handler */\n"
+ " \tkcb->kprobe_status = KPROBE_HIT_SSDONE;\n"
+ " \tif (cur->post_handler)\t{\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\t/* post_handler can hit breakpoint and single step\n"
+ " \t\t * again, so we enable D-flag for recursive exception.\n"
+ " \t\t */\n"
+ " \t\tcur->post_handler(cur, regs, 0);\n"
+ " \t}\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \treset_current_kprobe();\n"
+ " }\n"
+ " \n"
+ "@@ -332,9 +374,12 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)\n"
+ " \tstruct kprobe *cur = kprobe_running();\n"
+ " \tstruct kprobe_ctlblk *kcb = get_kprobe_ctlblk();\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tswitch (kcb->kprobe_status) {\n"
+ " \tcase KPROBE_HIT_SS:\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tcase KPROBE_REENTER:\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\t/*\n"
+ " \t\t * We are here because the instruction being single\n"
+ " \t\t * stepped caused a page fault. We reset the current\n"
+ "@@ -352,7 +397,9 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)\n"
+ " \n"
+ " \t\tbreak;\n"
+ " \tcase KPROBE_HIT_ACTIVE:\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tcase KPROBE_HIT_SSDONE:\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\t/*\n"
+ " \t\t * We increment the nmissed count for accounting,\n"
+ " \t\t * we can also use npre/npostfault count for accounting\n"
+ "@@ -367,8 +414,10 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)\n"
+ " \t\t * copy_from_user(), get_user() etc. Let the\n"
+ " \t\t * user-specified handler try to fix it first.\n"
+ " \t\t */\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\tif (cur->fault_handler && cur->fault_handler(cur, regs, fsr))\n"
+ " \t\t\treturn 1;\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \n"
+ " \t\t/*\n"
+ " \t\t * In case the user-specified fault handler returned\n"
+ "@@ -376,6 +425,7 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)\n"
+ " \t\t */\n"
+ " \t\tif (fixup_exception(regs))\n"
+ " \t\t\treturn 1;\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \n"
+ " \t\tbreak;\n"
+ " \t}\n"
+ "@@ -385,6 +435,7 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)\n"
+ " int __kprobes kprobe_exceptions_notify(struct notifier_block *self,\n"
+ " \t\t\t\t       unsigned long val, void *data)\n"
+ " {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \treturn NOTIFY_DONE;\n"
+ " }\n"
+ " \n"
+ "@@ -399,13 +450,19 @@ void __kprobes kprobe_handler(struct pt_regs *regs)\n"
+ " \n"
+ " \tp = get_kprobe((kprobe_opcode_t *) addr);\n"
+ " \n"
+ "+\tprintk(\"%s called at %d with addr %lx\\n\", __func__, __LINE__,\n"
+ "+\t\t\taddr);\n"
+ " \tif (p) {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\tif (cur) {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\t\tif (reenter_kprobe(p, regs, kcb))\n"
+ " \t\t\t\treturn;\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\t} else if (!p->ainsn.check_condn ||\n"
+ " \t\t\t\tp->ainsn.check_condn((u32)p->opcode, &p->ainsn,\n"
+ " \t\t\t\t\tregs)) {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\t\t/* Probe hit and conditional execution check ok. */\n"
+ " \t\t\tset_current_kprobe(p);\n"
+ " \t\t\tkcb->kprobe_status = KPROBE_HIT_ACTIVE;\n"
+ "@@ -424,6 +481,7 @@ void __kprobes kprobe_handler(struct pt_regs *regs)\n"
+ " \t\t\tif (!p->pre_handler || !p->pre_handler(p, regs)) {\n"
+ " \t\t\t\tkcb->kprobe_status = KPROBE_HIT_SS;\n"
+ " \t\t\t\tsetup_singlestep(p, regs, kcb, 0);\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\t\t\treturn;\n"
+ " \t\t\t}\n"
+ " \t\t} else {\n"
+ "@@ -431,6 +489,7 @@ void __kprobes kprobe_handler(struct pt_regs *regs)\n"
+ " \t\t\t * Breakpoint hit but conditional check failed,\n"
+ " \t\t\t * so just skip the instruction (NOP behaviour)\n"
+ " \t\t\t */\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\t\tskip_singlestep_missed(kcb, regs);\n"
+ " \t\t\treturn;\n"
+ " \t\t}\n"
+ "@@ -443,30 +502,37 @@ void __kprobes kprobe_handler(struct pt_regs *regs)\n"
+ " \t\t * handling of this interrupt is appropriate.\n"
+ " \t\t * Return back to original instruction, and continue.\n"
+ " \t\t */\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\treturn;\n"
+ " \t} else if (cur) {\n"
+ " \t\t/* We probably hit a jprobe.  Call its break handler. */\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\tif (cur->break_handler && cur->break_handler(cur, regs)) {\n"
+ " \t\t\tkcb->kprobe_status = KPROBE_HIT_SS;\n"
+ " \t\t\tsetup_singlestep(cur, regs, kcb, 0);\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\t\treturn;\n"
+ " \t\t}\n"
+ " \t} else {\n"
+ " \t\t/* breakpoint is removed, now in a race\n"
+ " \t\t * Return back to original instruction & continue.\n"
+ " \t\t */\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t}\n"
+ " }\n"
+ " \n"
+ " static int __kprobes\n"
+ " kprobe_ss_hit(struct kprobe_ctlblk *kcb, unsigned long addr)\n"
+ " {\n"
+ "+\tprintk(\"%s called at %d with match_addr %lx and addr %lx\\n\", __func__, __LINE__, kcb->ss_ctx.match_addr, addr);\n"
+ " \tif ((kcb->ss_ctx.ss_status == KPROBES_STEP_PENDING)\n"
+ " \t    && (kcb->ss_ctx.match_addr == addr)) {\n"
+ " \t\tclear_ss_context(kcb);\t/* clear pending ss */\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\treturn DBG_HOOK_HANDLED;\n"
+ " \t}\n"
+ " \t/* not ours, kprobes should ignore it */\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \treturn DBG_HOOK_ERROR;\n"
+ " }\n"
+ " \n"
+ "@@ -480,6 +546,7 @@ kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr)\n"
+ " \tretval = kprobe_ss_hit(kcb, instruction_pointer(regs));\n"
+ " \n"
+ " \tif (retval == DBG_HOOK_HANDLED) {\n"
+ "+\t\tc_log_debug_entry(24, esr);\n"
+ " \t\tkprobes_restore_local_irqflag(regs);\n"
+ " \t\tkernel_disable_single_step();\n"
+ " \n"
+ "@@ -495,6 +562,8 @@ kprobe_single_step_handler(struct pt_regs *regs, unsigned int esr)\n"
+ " static int __kprobes\n"
+ " kprobe_breakpoint_handler(struct pt_regs *regs, unsigned int esr)\n"
+ " {\n"
+ "+\tc_log_debug_entry(23, esr);\n"
+ "+\tprint_debug_log_buf();\n"
+ " \tkprobe_handler(regs);\n"
+ " \treturn DBG_HOOK_HANDLED;\n"
+ " }\n"
+ "@@ -505,12 +574,14 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)\n"
+ " \tstruct kprobe_ctlblk *kcb = get_kprobe_ctlblk();\n"
+ " \tlong stack_ptr = stack_pointer(regs);\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tkcb->jprobe_saved_regs = *regs;\n"
+ " \tmemcpy(kcb->jprobes_stack, (void *)stack_ptr,\n"
+ " \t       MIN_STACK_SIZE(stack_ptr));\n"
+ " \n"
+ " \tinstruction_pointer_set(regs, (long)jp->entry);\n"
+ " \tpreempt_disable();\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \treturn 1;\n"
+ " }\n"
+ " \n"
+ "@@ -533,6 +604,7 @@ void __kprobes jprobe_return(void)\n"
+ " \t\t      : \"r\"(&kcb->jprobe_saved_regs.sp),\n"
+ " \t\t      \"I\"(BRK64_ESR_KPROBES)\n"
+ " \t\t      : \"memory\");\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " }\n"
+ " \n"
+ " int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)\n"
+ "@@ -542,10 +614,13 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)\n"
+ " \tlong orig_sp = stack_pointer(regs);\n"
+ " \tstruct jprobe *jp = container_of(p, struct jprobe, kp);\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tif (regs->regs[0] == JPROBES_MAGIC_NUM) {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\tif (orig_sp != stack_addr) {\n"
+ " \t\t\tstruct pt_regs *saved_regs =\n"
+ " \t\t\t    (struct pt_regs *)kcb->jprobe_saved_regs.sp;\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\t\tpr_err(\"current sp %lx does not match saved sp %lx\\n\",\n"
+ " \t\t\t       orig_sp, stack_addr);\n"
+ " \t\t\tpr_err(\"Saved registers for jprobe %p\\n\", jp);\n"
+ "@@ -558,8 +633,10 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)\n"
+ " \t\tmemcpy((void *)stack_addr, kcb->jprobes_stack,\n"
+ " \t\t       MIN_STACK_SIZE(stack_addr));\n"
+ " \t\tpreempt_enable_no_resched();\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\treturn 1;\n"
+ " \t}\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \treturn 0;\n"
+ " }\n"
+ " \n"
+ "@@ -586,6 +663,7 @@ static void __used kretprobe_trampoline_holder(void)\n"
+ " \t\t\t\"kretprobe_trampoline:\\n\"\n"
+ " \t\t\t\"NOP\\n\\t\"\n"
+ " \t\t\t\"NOP\\n\\t\");\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " }\n"
+ " \n"
+ " static int __kprobes\n"
+ "@@ -614,6 +692,7 @@ trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)\n"
+ " \t *       real return address, and all the rest will point to\n"
+ " \t *       kretprobe_trampoline\n"
+ " \t */\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \thlist_for_each_entry_safe(ri, tmp, head, hlist) {\n"
+ " \t\tif (ri->task != current)\n"
+ " \t\t\t/* another task is sharing our hash bucket */\n"
+ "@@ -652,12 +731,14 @@ trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)\n"
+ " \tkprobes_restore_local_irqflag(regs);\n"
+ " \n"
+ " \t/* return 1 so that post handlers not called */\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \treturn 1;\n"
+ " }\n"
+ " \n"
+ " void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,\n"
+ " \t\t\t\t      struct pt_regs *regs)\n"
+ " {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tri->ret_addr = (kprobe_opcode_t *)regs->regs[30];\n"
+ " \n"
+ " \t/* replace return addr (x30) with trampoline */\n"
+ "diff --git a/arch/arm64/kernel/uprobes.c b/arch/arm64/kernel/uprobes.c\n"
+ "index 97e9d17d22b6..ad891d17faee 100644\n"
+ "--- a/arch/arm64/kernel/uprobes.c\n"
+ "+++ b/arch/arm64/kernel/uprobes.c\n"
+ "@@ -19,6 +19,7 @@ void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,\n"
+ " \tvoid *xol_page_kaddr = kmap_atomic(page);\n"
+ " \tvoid *dst = xol_page_kaddr + (vaddr & ~PAGE_MASK);\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tpreempt_disable();\n"
+ " \n"
+ " \t/* Initialize the slot */\n"
+ "@@ -34,6 +35,7 @@ void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,\n"
+ " \n"
+ " unsigned long uprobe_get_swbp_addr(struct pt_regs *regs)\n"
+ " {\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \treturn instruction_pointer(regs);\n"
+ " }\n"
+ " \n"
+ "@@ -49,17 +51,21 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm,\n"
+ " \n"
+ " \tinsn = *(kprobe_opcode_t *)(&auprobe->insn[0]);\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tswitch (arm_kprobe_decode_insn(insn, &auprobe->ainsn)) {\n"
+ " \tcase INSN_REJECTED:\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\treturn -EINVAL;\n"
+ " \n"
+ " \tcase INSN_GOOD_NO_SLOT:\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t\tauprobe->simulate = true;\n"
+ " \t\tif (auprobe->ainsn.prepare)\n"
+ " \t\t\tauprobe->ainsn.prepare(insn, &auprobe->ainsn);\n"
+ " \t\tbreak;\n"
+ " \n"
+ " \tcase INSN_GOOD:\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tdefault:\n"
+ " \t\tbreak;\n"
+ " \t}\n"
+ "@@ -71,6 +77,7 @@ int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)\n"
+ " {\n"
+ " \tstruct uprobe_task *utask = current->utask;\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \t/* saved fault code is restored in post_xol */\n"
+ " \tutask->autask.saved_fault_code = current->thread.fault_code;\n"
+ " \n"
+ "@@ -99,6 +106,7 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)\n"
+ " \n"
+ " \tuser_disable_single_step(current);\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \treturn 0;\n"
+ " }\n"
+ " bool arch_uprobe_xol_was_trapped(struct task_struct *t)\n"
+ "@@ -109,9 +117,11 @@ bool arch_uprobe_xol_was_trapped(struct task_struct *t)\n"
+ " \t * invalid fault code which is being set in arch_uprobe_pre_xol and\n"
+ " \t * restored in arch_uprobe_post_xol.\n"
+ " \t */\n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tif (t->thread.fault_code != UPROBE_INV_FAULT_CODE)\n"
+ " \t\treturn true;\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \treturn false;\n"
+ " }\n"
+ " \n"
+ "@@ -120,6 +130,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)\n"
+ " \tkprobe_opcode_t insn;\n"
+ " \tunsigned long addr;\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tif (!auprobe->simulate)\n"
+ " \t\treturn false;\n"
+ " \n"
+ "@@ -129,6 +140,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)\n"
+ " \tif (auprobe->ainsn.handler)\n"
+ " \t\tauprobe->ainsn.handler(insn, addr, regs);\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \treturn true;\n"
+ " }\n"
+ " \n"
+ "@@ -136,6 +148,7 @@ void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)\n"
+ " {\n"
+ " \tstruct uprobe_task *utask = current->utask;\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \tcurrent->thread.fault_code = utask->autask.saved_fault_code;\n"
+ " \t/*\n"
+ " \t * Task has received a fatal signal, so reset back to probbed\n"
+ "@@ -152,6 +165,7 @@ arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr,\n"
+ " {\n"
+ " \tunsigned long orig_ret_vaddr;\n"
+ " \n"
+ "+\tprintk(\"%s called at %d\\n\", __func__, __LINE__);\n"
+ " \torig_ret_vaddr = procedure_link_pointer(regs);\n"
+ " \t/* Replace the return addr with trampoline addr */\n"
+ " \tprocedure_link_pointer_set(regs, trampoline_vaddr);\n"
+ "@@ -165,24 +179,28 @@ int arch_uprobe_exception_notify(struct notifier_block *self,\n"
+ " \treturn NOTIFY_DONE;\n"
+ " }\n"
+ " \n"
+ "-static int __kprobes uprobe_breakpoint_handler(struct pt_regs *regs,\n"
+ "+static int uprobe_breakpoint_handler(struct pt_regs *regs,\n"
+ " \t\tunsigned int esr)\n"
+ " {\n"
+ "-\tif (user_mode(regs) && uprobe_pre_sstep_notifier(regs))\n"
+ "+\tif (user_mode(regs) && uprobe_pre_sstep_notifier(regs)) {\n"
+ "+\t\tc_log_debug_entry(21, esr);\n"
+ " \t\treturn DBG_HOOK_HANDLED;\n"
+ "+\t}\n"
+ " \n"
+ " \treturn DBG_HOOK_ERROR;\n"
+ " }\n"
+ " \n"
+ "-static int __kprobes uprobe_single_step_handler(struct pt_regs *regs,\n"
+ "+static int uprobe_single_step_handler(struct pt_regs *regs,\n"
+ " \t\tunsigned int esr)\n"
+ " {\n"
+ " \tif (user_mode(regs)) {\n"
+ " \t\tWARN_ON(instruction_pointer(regs) !=\n"
+ " \t\t\t\tcurrent->utask->xol_vaddr + 4);\n"
+ " \n"
+ "-\t\tif (uprobe_post_sstep_notifier(regs))\n"
+ "+\t\tif (uprobe_post_sstep_notifier(regs)) {\n"
+ "+\t\t\tc_log_debug_entry(22, esr);\n"
+ " \t\t\treturn DBG_HOOK_HANDLED;\n"
+ "+\t\t}\n"
+ " \t}\n"
+ " \n"
+ " \treturn DBG_HOOK_ERROR;\n"
+ "-- \n"
+ 2.1.0
 
-4c3ea0f2d1b2ab13edb41feab6068f0b596b47dc23fb4aa779667f713853a84d
+acdb85dccde06ce70e66b4019a662234d5d430573df8e20caca8401781a35add

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.