From mboxrd@z Thu Jan 1 00:00:00 1970 From: dave.long@linaro.org (David Long) Date: Fri, 20 May 2016 01:16:33 -0400 Subject: [PATCH v12 05/10] arm64: Kprobes with single stepping support In-Reply-To: <57349AE2.3060507@arm.com> References: <1461783185-9056-1-git-send-email-dave.long@linaro.org> <1461783185-9056-6-git-send-email-dave.long@linaro.org> <57349AE2.3060507@arm.com> Message-ID: <573E9DB1.4070109@linaro.org> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On 05/12/2016 11:01 AM, James Morse wrote: > Hi David, Sandeepa, > > On 27/04/16 19:53, David Long wrote: >> From: Sandeepa Prabhu > >> diff --git a/arch/arm64/kernel/kprobes.c b/arch/arm64/kernel/kprobes.c >> new file mode 100644 >> index 0000000..dfa1b1f >> --- /dev/null >> +++ b/arch/arm64/kernel/kprobes.c >> @@ -0,0 +1,520 @@ >> +/* >> + * arch/arm64/kernel/kprobes.c >> + * >> + * Kprobes support for ARM64 >> + * >> + * Copyright (C) 2013 Linaro Limited. >> + * Author: Sandeepa Prabhu >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License version 2 as >> + * published by the Free Software Foundation. >> + * >> + * This program is distributed in the hope that it will be useful, >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + * General Public License for more details. >> + * >> + */ >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include "kprobes-arm64.h" >> + >> +#define MIN_STACK_SIZE(addr) min((unsigned long)MAX_STACK_SIZE, \ >> + (unsigned long)current_thread_info() + THREAD_START_SP - (addr)) > > What if we probe something called on the irq stack? > This needs the on_irq_stack() checks too, the start/end can be found from the > per-cpu irq_stack value. > > [ ... ] > OK. >> +int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) >> +{ >> + struct jprobe *jp = container_of(p, struct jprobe, kp); >> + struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); >> + long stack_ptr = kernel_stack_pointer(regs); >> + >> + kcb->jprobe_saved_regs = *regs; >> + memcpy(kcb->jprobes_stack, (void *)stack_ptr, >> + MIN_STACK_SIZE(stack_ptr)); > > I wonder if we need this stack save/restore? > > The comment next to the equivalent code for x86 says: >> gcc assumes that the callee owns the argument space and could overwrite it, >> e.g. tailcall optimization. So, to be absolutely safe we also save and >> restore enough stack bytes to cover the argument area. > > On arm64 the first eight arguments are passed in registers, so we might not need > this stack copy. (sparc and powerpc work like this too, their versions of this > function don't copy chunks of the stack). > > ... then I went looking for functions with >8 arguments... > > Looking at the arm64 defconfig dwarf debug data, there are 71 of these that > don't get inlined, picking at random: >> rockchip_clk_register_pll() has 13 >> fib_dump_info() has 11 >> vma_merge() has 10 >> vring_create_virtqueue() has 10 > etc... > > So we do need this stack copying, so that we can probe these function without > risking the arguments being modified. > > It may be worth including a comment to the effect that this stack save/restore > is needed for functions that pass >8 arguments where the pre-handler may change > these values on the stack. > > I can add a comment. >> + preempt_enable_no_resched(); >> + return 1; >> +} >> + > > > Thanks, > > James > Thanks, -dl