Re: [PATCH v4 14/15] kprobes: remove dependency on CONFIG_MODULES

2024-04-17 Thread Masami Hiramatsu
ace_kprobe.c
> +++ b/kernel/trace/trace_kprobe.c
> @@ -111,6 +111,7 @@ static nokprobe_inline bool 
> trace_kprobe_within_module(struct trace_kprobe *tk,
>   return strncmp(module_name(mod), name, len) == 0 && name[len] == ':';
>  }
>  
> +#ifdef CONFIG_MODULES
>  static nokprobe_inline bool trace_kprobe_module_exist(struct trace_kprobe 
> *tk)
>  {
>   char *p;
> @@ -129,6 +130,12 @@ static nokprobe_inline bool 
> trace_kprobe_module_exist(struct trace_kprobe *tk)
>  
>   return ret;
>  }
> +#else
> +static inline bool trace_kprobe_module_exist(struct trace_kprobe *tk)
> +{
> + return false;
> +}
> +#endif
>  
>  static bool trace_kprobe_is_busy(struct dyn_event *ev)
>  {
> @@ -670,6 +677,7 @@ static int register_trace_kprobe(struct trace_kprobe *tk)
>   return ret;
>  }
>  
> +#ifdef CONFIG_MODULES
>  /* Module notifier call back, checking event on the module */
>  static int trace_kprobe_module_callback(struct notifier_block *nb,
>  unsigned long val, void *data)
> @@ -704,6 +712,7 @@ static struct notifier_block trace_kprobe_module_nb = {
>   .notifier_call = trace_kprobe_module_callback,
>   .priority = 1   /* Invoked after kprobe module callback */
>  };
> +#endif
>  
>  static int count_symbols(void *data, unsigned long unused)
>  {
> @@ -1933,8 +1942,10 @@ static __init int init_kprobe_trace_early(void)
>   if (ret)
>   return ret;
>  
> +#ifdef CONFIG_MODULES
>   if (register_module_notifier(_kprobe_module_nb))
>   return -EINVAL;
> +#endif
>  
>   return 0;
>  }
> -- 
> 2.43.0
> 
> 


-- 
Masami Hiramatsu


Re: [PATCH 3/3] kprobes: Allow probing on any address belonging to ftrace

2022-02-20 Thread Masami Hiramatsu
On Thu, 17 Feb 2022 17:06:25 +0530
"Naveen N. Rao"  wrote:

> On certain architectures, ftrace can reserve multiple instructions at
> function entry. Rather than rejecting kprobe on addresses other than the
> exact ftrace call instruction, use the address returned by ftrace to
> probe at the correct address when CONFIG_KPROBES_ON_FTRACE is enabled.
> 
> Signed-off-by: Naveen N. Rao 
> ---
>  kernel/kprobes.c | 12 
>  1 file changed, 12 insertions(+)
> 
> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> index 94cab8c9ce56cc..0a797ede3fdf37 100644
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -1497,6 +1497,10 @@ bool within_kprobe_blacklist(unsigned long addr)
>  static kprobe_opcode_t *_kprobe_addr(kprobe_opcode_t *addr,
>   const char *symbol_name, unsigned int offset)
>  {
> +#ifdef CONFIG_KPROBES_ON_FTRACE
> + unsigned long ftrace_addr = 0;
> +#endif
> +
>   if ((symbol_name && addr) || (!symbol_name && !addr))
>   goto invalid;
>  
> @@ -1507,6 +1511,14 @@ static kprobe_opcode_t *_kprobe_addr(kprobe_opcode_t 
> *addr,
>   }
>  
>   addr = (kprobe_opcode_t *)(((char *)addr) + offset);
> +
> +#ifdef CONFIG_KPROBES_ON_FTRACE
> + if (addr)
> + ftrace_addr = ftrace_location((unsigned long)addr);
> + if (ftrace_addr)
> + return (kprobe_opcode_t *)ftrace_addr;

As I said, this must be

if (ftrace_addr != addr)
return -EILSEQ;

This will prevent users from being confused by the results of probing
that 'func' and 'func+4' are the same. (now only 'func' is allowed to
be probed.)

Thank you,

> +#endif
> +
>   if (addr)
>   return addr;
>  
> -- 
> 2.35.1
> 


-- 
Masami Hiramatsu 


Re: [PATCH 1/3] powerpc/ftrace: Reserve instructions from function entry for ftrace

2022-02-20 Thread Masami Hiramatsu
 __ftrace_modify_call(struct dyn_ftrace *rec, unsigned 
> long old_addr,
>   ppc_inst_t op;
>   unsigned long ip = rec->ip;
>   unsigned long entry, ptr, tramp;
> - struct module *mod = rec->arch.mod;
> + struct module *mod = ftrace_mod_addr_get(rec);
>  
>   /* If we never set up ftrace trampolines, then bail */
>   if (!mod->arch.tramp || !mod->arch.tramp_regs) {
> @@ -814,7 +904,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned 
> long old_addr,
>   /*
>* Out of range jumps are called from modules.
>*/
> - if (!rec->arch.mod) {
> + if (!ftrace_mod_addr_get(rec)) {
>   pr_err("No module loaded\n");
>   return -EINVAL;
>   }
> diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> index f9feb197b2daaf..68f20cf34b0c47 100644
> --- a/kernel/trace/ftrace.c
> +++ b/kernel/trace/ftrace.c
> @@ -1510,6 +1510,7 @@ ftrace_ops_test(struct ftrace_ops *ops, unsigned long 
> ip, void *regs)
>   }
>  
>  
> +#ifndef ftrace_cmp_recs
>  static int ftrace_cmp_recs(const void *a, const void *b)
>  {
>   const struct dyn_ftrace *key = a;
> @@ -1521,6 +1522,7 @@ static int ftrace_cmp_recs(const void *a, const void *b)
>   return 1;
>   return 0;
>  }
> +#endif
>  
>  static struct dyn_ftrace *lookup_rec(unsigned long start, unsigned long end)
>  {
> -- 
> 2.35.1
> 


-- 
Masami Hiramatsu 


Re: [PATCH 1/2] kprobes: Allow architectures to override optinsn page allocation

2021-05-12 Thread Masami Hiramatsu
On Thu, 13 May 2021 03:04:51 +0800
kernel test robot  wrote:

> Hi Christophe,
> 
> I love your patch! Perhaps something to improve:
> 
> [auto build test WARNING on powerpc/next]
> [also build test WARNING on linus/master v5.13-rc1 next-20210512]
> [If your patch is applied to the wrong git tree, kindly drop us a note.
> And when submitting patch, we suggest to use '--base' as documented in
> https://git-scm.com/docs/git-format-patch]
> 
> url:
> https://github.com/0day-ci/linux/commits/Christophe-Leroy/kprobes-Allow-architectures-to-override-optinsn-page-allocation/20210512-223121
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
> config: i386-randconfig-r012-20210512 (attached as .config)
> compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
> reproduce (this is a W=1 build):
> # 
> https://github.com/0day-ci/linux/commit/2a1f135a9ce3c4d86d3bdefed561aa17760f430f
> git remote add linux-review https://github.com/0day-ci/linux
> git fetch --no-tags linux-review 
> Christophe-Leroy/kprobes-Allow-architectures-to-override-optinsn-page-allocation/20210512-223121
> git checkout 2a1f135a9ce3c4d86d3bdefed561aa17760f430f
> # save the attached .config to linux build tree
> make W=1 W=1 ARCH=i386 
> 
> If you fix the issue, kindly add following tag as appropriate
> Reported-by: kernel test robot 
> 
> All warnings (new ones prefixed by >>):
> 
> >> kernel/kprobes.c:324:14: warning: no previous prototype for 
> >> 'alloc_optinsn_page' [-Wmissing-prototypes]
>  324 | void __weak *alloc_optinsn_page(void)
>  |  ^~
> >> kernel/kprobes.c:329:13: warning: no previous prototype for 
> >> 'free_optinsn_page' [-Wmissing-prototypes]
>  329 | void __weak free_optinsn_page(void *page)
>  | ^~~~~~~~~

Ah, we need a prototype for those in include/linux/kprobes.h
as same as alloc_insn_page() and free_insn_page().

Thank you,

-- 
Masami Hiramatsu 


Re: [PATCH 2/2] powerpc/kprobes: Replace ppc_optinsn by common optinsn

2021-05-12 Thread Masami Hiramatsu
On Wed, 12 May 2021 14:29:27 + (UTC)
Christophe Leroy  wrote:

> Commit 51c9c0843993 ("powerpc/kprobes: Implement Optprobes")
> implemented a powerpc specific version of optinsn in order
> to workaround the 32Mb limitation for direct branches.
> 
> Instead of implementing a dedicated powerpc version, use the
> common optinsn and override the allocation and freeing functions.
> 
> This also indirectly remove the CLANG warning about
> is_kprobe_ppc_optinsn_slot() not being use, and the powerpc will
> now benefit from commit 5b485629ba0d ("kprobes, extable: Identify
> kprobes trampolines as kernel text area")
> 

This looks good to me.

Acked-by: Masami Hiramatsu 

> Suggested-by: Masami Hiramatsu 
> Signed-off-by: Christophe Leroy 
> ---
>  arch/powerpc/kernel/optprobes.c | 23 +--
>  1 file changed, 5 insertions(+), 18 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c
> index cdf87086fa33..a370190cd02a 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -31,11 +31,9 @@
>  #define TMPL_END_IDX \
>   (optprobe_template_end - optprobe_template_entry)
>  
> -DEFINE_INSN_CACHE_OPS(ppc_optinsn);
> -
>  static bool insn_page_in_use;
>  
> -static void *__ppc_alloc_insn_page(void)
> +void *alloc_optinsn_page(void)
>  {
>   if (insn_page_in_use)
>   return NULL;
> @@ -43,20 +41,11 @@ static void *__ppc_alloc_insn_page(void)
>   return _slot;
>  }
>  
> -static void __ppc_free_insn_page(void *page __maybe_unused)
> +void free_optinsn_page(void *page)
>  {
>   insn_page_in_use = false;
>  }
>  
> -struct kprobe_insn_cache kprobe_ppc_optinsn_slots = {
> - .mutex = __MUTEX_INITIALIZER(kprobe_ppc_optinsn_slots.mutex),
> - .pages = LIST_HEAD_INIT(kprobe_ppc_optinsn_slots.pages),
> - /* insn_size initialized later */
> - .alloc = __ppc_alloc_insn_page,
> - .free = __ppc_free_insn_page,
> - .nr_garbage = 0,
> -};
> -
>  /*
>   * Check if we can optimize this probe. Returns NIP post-emulation if this 
> can
>   * be optimized and 0 otherwise.
> @@ -136,7 +125,7 @@ NOKPROBE_SYMBOL(optimized_callback);
>  void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
>  {
>   if (op->optinsn.insn) {
> - free_ppc_optinsn_slot(op->optinsn.insn, 1);
> + free_optinsn_slot(op->optinsn.insn, 1);
>   op->optinsn.insn = NULL;
>   }
>  }
> @@ -203,14 +192,12 @@ int arch_prepare_optimized_kprobe(struct 
> optimized_kprobe *op, struct kprobe *p)
>   unsigned long nip, size;
>   int rc, i;
>  
> - kprobe_ppc_optinsn_slots.insn_size = MAX_OPTINSN_SIZE;
> -
>   nip = can_optimize(p);
>   if (!nip)
>   return -EILSEQ;
>  
>   /* Allocate instruction slot for detour buffer */
> - buff = get_ppc_optinsn_slot();
> + buff = get_optinsn_slot();
>   if (!buff)
>   return -ENOMEM;
>  
> @@ -297,7 +284,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe 
> *op, struct kprobe *p)
>   return 0;
>  
>  error:
> - free_ppc_optinsn_slot(buff, 0);
> + free_optinsn_slot(buff, 0);
>   return -ERANGE;
>  
>  }
> -- 
> 2.25.0
> 


-- 
Masami Hiramatsu 


Re: [PATCH 1/2] kprobes: Allow architectures to override optinsn page allocation

2021-05-12 Thread Masami Hiramatsu
On Wed, 12 May 2021 14:29:26 + (UTC)
Christophe Leroy  wrote:

> Some architectures like powerpc require a non standard
> allocation of optinsn page, because module pages are
> too far from the kernel for direct branches.
> 
> Define weak alloc_optinsn_page() and free_optinsn_page(), that
> fall back on alloc_insn_page() and free_insn_page() when not
> overriden by the architecture.
> 

Looks good to me :)

Acked-by: Masami Hiramatsu 

> Suggested-by: Masami Hiramatsu 
> Signed-off-by: Christophe Leroy 
> ---
>  kernel/kprobes.c | 14 --
>  1 file changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> index 745f08fdd7a6..8c0a6fdef771 100644
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -321,11 +321,21 @@ int kprobe_cache_get_kallsym(struct kprobe_insn_cache 
> *c, unsigned int *symnum,
>  }
>  
>  #ifdef CONFIG_OPTPROBES
> +void __weak *alloc_optinsn_page(void)
> +{
> + return alloc_insn_page();
> +}
> +
> +void __weak free_optinsn_page(void *page)
> +{
> + free_insn_page(page);
> +}
> +
>  /* For optimized_kprobe buffer */
>  struct kprobe_insn_cache kprobe_optinsn_slots = {
>   .mutex = __MUTEX_INITIALIZER(kprobe_optinsn_slots.mutex),
> - .alloc = alloc_insn_page,
> - .free = free_insn_page,
> + .alloc = alloc_optinsn_page,
> + .free = free_optinsn_page,
>   .sym = KPROBE_OPTINSN_PAGE_SYM,
>   .pages = LIST_HEAD_INIT(kprobe_optinsn_slots.pages),
>   /* .insn_size is initialized later */
> -- 
> 2.25.0
> 


-- 
Masami Hiramatsu 


Re: [PATCH 05/11 v3] kprobes/ftrace: Add recursion protection to the ftrace callback

2020-11-06 Thread Masami Hiramatsu
On Thu, 05 Nov 2020 21:32:40 -0500
Steven Rostedt (VMware)  wrote:

> From: "Steven Rostedt (VMware)" 
> 
> If a ftrace callback does not supply its own recursion protection and
> does not set the RECURSION_SAFE flag in its ftrace_ops, then ftrace will
> make a helper trampoline to do so before calling the callback instead of
> just calling the callback directly.
> 
> The default for ftrace_ops is going to change. It will expect that handlers
> provide their own recursion protection, unless its ftrace_ops states
> otherwise.
> 
> Link: https://lkml.kernel.org/r/20201028115613.140212...@goodmis.org
> 

Looks good to me.

Acked-by: Masami Hiramatsu 

Thank you!

> Cc: Andrew Morton 
> Cc: Masami Hiramatsu 
> Cc: Guo Ren 
> Cc: "James E.J. Bottomley" 
> Cc: Helge Deller 
> Cc: Michael Ellerman 
> Cc: Benjamin Herrenschmidt 
> Cc: Paul Mackerras 
> Cc: Heiko Carstens 
> Cc: Vasily Gorbik 
> Cc: Christian Borntraeger 
> Cc: Thomas Gleixner 
> Cc: Borislav Petkov 
> Cc: x...@kernel.org
> Cc: "H. Peter Anvin" 
> Cc: "Naveen N. Rao" 
> Cc: Anil S Keshavamurthy 
> Cc: "David S. Miller" 
> Cc: linux-c...@vger.kernel.org
> Cc: linux-par...@vger.kernel.org
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: linux-s...@vger.kernel.org
> Signed-off-by: Steven Rostedt (VMware) 
> ---
> 
> Changes since v2:
> 
>  - Move get_kprobe() into preempt disabled sections for various archs
> 
> 
>  arch/csky/kernel/probes/ftrace.c | 12 ++--
>  arch/parisc/kernel/ftrace.c  | 16 +---
>  arch/powerpc/kernel/kprobes-ftrace.c | 11 ++-
>  arch/s390/kernel/ftrace.c| 16 +---
>  arch/x86/kernel/kprobes/ftrace.c | 12 ++--
>  5 files changed, 56 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/csky/kernel/probes/ftrace.c 
> b/arch/csky/kernel/probes/ftrace.c
> index 5264763d05be..5eb2604fdf71 100644
> --- a/arch/csky/kernel/probes/ftrace.c
> +++ b/arch/csky/kernel/probes/ftrace.c
> @@ -13,16 +13,21 @@ int arch_check_ftrace_location(struct kprobe *p)
>  void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
>  struct ftrace_ops *ops, struct pt_regs *regs)
>  {
> + int bit;
>   bool lr_saver = false;
>   struct kprobe *p;
>   struct kprobe_ctlblk *kcb;
>  
> - /* Preempt is disabled by ftrace */
> + bit = ftrace_test_recursion_trylock();
> + if (bit < 0)
> + return;
> +
> + preempt_disable_notrace();
>   p = get_kprobe((kprobe_opcode_t *)ip);
>   if (!p) {
>   p = get_kprobe((kprobe_opcode_t *)(ip - MCOUNT_INSN_SIZE));
>   if (unlikely(!p) || kprobe_disabled(p))
> - return;
> + goto out;
>   lr_saver = true;
>   }
>  
> @@ -56,6 +61,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long 
> parent_ip,
>*/
>   __this_cpu_write(current_kprobe, NULL);
>   }
> +out:
> + preempt_enable_notrace();
> + ftrace_test_recursion_unlock(bit);
>  }
>  NOKPROBE_SYMBOL(kprobe_ftrace_handler);
>  
> diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c
> index 63e3ecb9da81..13d85042810a 100644
> --- a/arch/parisc/kernel/ftrace.c
> +++ b/arch/parisc/kernel/ftrace.c
> @@ -207,14 +207,21 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned 
> long parent_ip,
>  struct ftrace_ops *ops, struct pt_regs *regs)
>  {
>   struct kprobe_ctlblk *kcb;
> - struct kprobe *p = get_kprobe((kprobe_opcode_t *)ip);
> + struct kprobe *p;
> + int bit;
>  
> - if (unlikely(!p) || kprobe_disabled(p))
> + bit = ftrace_test_recursion_trylock();
> + if (bit < 0)
>   return;
>  
> + preempt_disable_notrace();
> + p = get_kprobe((kprobe_opcode_t *)ip);
> + if (unlikely(!p) || kprobe_disabled(p))
> + goto out;
> +
>   if (kprobe_running()) {
>   kprobes_inc_nmissed_count(p);
> - return;
> + goto out;
>   }
>  
>   __this_cpu_write(current_kprobe, p);
> @@ -235,6 +242,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned 
> long parent_ip,
>   }
>   }
>   __this_cpu_write(current_kprobe, NULL);
> +out:
> + preempt_enable_notrace();
> + ftrace_test_recursion_unlock(bit);
>  }
>  NOKPROBE_SYMBOL(kprobe_ftrace_handler);
>  
> diff --git a/arch/powerpc/kernel/kprobes-ftrace.c 
> b/arch/powerpc/kernel/kprobes-ftrace.c
> index 972cb28174b2..5df8d50c65ae 100644
> --- a/arch

Re: [PATCH 05/11 v2] kprobes/ftrace: Add recursion protection to the ftrace callback

2020-11-03 Thread Masami Hiramatsu
On Fri, 30 Oct 2020 17:31:47 -0400
Steven Rostedt  wrote:

> From: "Steven Rostedt (VMware)" 
> 
> If a ftrace callback does not supply its own recursion protection and
> does not set the RECURSION_SAFE flag in its ftrace_ops, then ftrace will
> make a helper trampoline to do so before calling the callback instead of
> just calling the callback directly.
> 
> The default for ftrace_ops is going to change. It will expect that handlers
> provide their own recursion protection, unless its ftrace_ops states
> otherwise.
> 
> Link: https://lkml.kernel.org/r/20201028115613.140212...@goodmis.org
> 
> Cc: Andrew Morton 
> Cc: Masami Hiramatsu 
> Cc: Guo Ren 
> Cc: "James E.J. Bottomley" 
> Cc: Helge Deller 
> Cc: Michael Ellerman 
> Cc: Benjamin Herrenschmidt 
> Cc: Paul Mackerras 
> Cc: Heiko Carstens 
> Cc: Vasily Gorbik 
> Cc: Christian Borntraeger 
> Cc: Thomas Gleixner 
> Cc: Borislav Petkov 
> Cc: x...@kernel.org
> Cc: "H. Peter Anvin" 
> Cc: "Naveen N. Rao" 
> Cc: Anil S Keshavamurthy 
> Cc: "David S. Miller" 
> Cc: linux-c...@vger.kernel.org
> Cc: linux-par...@vger.kernel.org
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: linux-s...@vger.kernel.org
> Signed-off-by: Steven Rostedt (VMware) 
> ---
>  arch/csky/kernel/probes/ftrace.c | 12 ++--
>  arch/parisc/kernel/ftrace.c  | 13 +++--
>  arch/powerpc/kernel/kprobes-ftrace.c | 11 ++-
>  arch/s390/kernel/ftrace.c| 13 +++--
>  arch/x86/kernel/kprobes/ftrace.c | 12 ++--
>  5 files changed, 52 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/csky/kernel/probes/ftrace.c 
> b/arch/csky/kernel/probes/ftrace.c
> index 5264763d05be..5eb2604fdf71 100644
> --- a/arch/csky/kernel/probes/ftrace.c
> +++ b/arch/csky/kernel/probes/ftrace.c
> @@ -13,16 +13,21 @@ int arch_check_ftrace_location(struct kprobe *p)
>  void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
>  struct ftrace_ops *ops, struct pt_regs *regs)
>  {
> + int bit;
>   bool lr_saver = false;
>   struct kprobe *p;
>   struct kprobe_ctlblk *kcb;
>  
> - /* Preempt is disabled by ftrace */
> + bit = ftrace_test_recursion_trylock();
> + if (bit < 0)
> + return;
> +
> + preempt_disable_notrace();
>   p = get_kprobe((kprobe_opcode_t *)ip);
>   if (!p) {
>   p = get_kprobe((kprobe_opcode_t *)(ip - MCOUNT_INSN_SIZE));
>   if (unlikely(!p) || kprobe_disabled(p))
> - return;
> + goto out;
>   lr_saver = true;
>   }
>  
> @@ -56,6 +61,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long 
> parent_ip,
>*/
>   __this_cpu_write(current_kprobe, NULL);
>   }
> +out:
> + preempt_enable_notrace();
> + ftrace_test_recursion_unlock(bit);
>  }
>  NOKPROBE_SYMBOL(kprobe_ftrace_handler);
>  
> diff --git a/arch/parisc/kernel/ftrace.c b/arch/parisc/kernel/ftrace.c
> index 63e3ecb9da81..4b1fdf15662c 100644
> --- a/arch/parisc/kernel/ftrace.c
> +++ b/arch/parisc/kernel/ftrace.c
> @@ -208,13 +208,19 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned 
> long parent_ip,
>  {
>   struct kprobe_ctlblk *kcb;
>   struct kprobe *p = get_kprobe((kprobe_opcode_t *)ip);
> + int bit;
>  
> - if (unlikely(!p) || kprobe_disabled(p))
> + bit = ftrace_test_recursion_trylock();
> + if (bit < 0)
>   return;
>  
> + preempt_disable_notrace();

If we disable preempt here, we also move the get_kprobe() here as below.
(get_kprobe() accesses percpu variable)

p = get_kprobe((kprobe_opcode_t *)ip);


> + if (unlikely(!p) || kprobe_disabled(p))
> + goto out;
> +
>   if (kprobe_running()) {
>   kprobes_inc_nmissed_count(p);
> - return;
> + goto out;
>   }
>  
>   __this_cpu_write(current_kprobe, p);
> @@ -235,6 +241,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned 
> long parent_ip,
>   }
>   }
>   __this_cpu_write(current_kprobe, NULL);
> +out:
> + preempt_enable_notrace();
> + ftrace_test_recursion_unlock(bit);
>  }
>  NOKPROBE_SYMBOL(kprobe_ftrace_handler);
>  
> diff --git a/arch/powerpc/kernel/kprobes-ftrace.c 
> b/arch/powerpc/kernel/kprobes-ftrace.c
> index 972cb28174b2..5df8d50c65ae 100644
> --- a/arch/powerpc/kernel/kprobes-ftrace.c
> +++ b/arch/powerpc/kernel/kprobes-ftrace.c
> @@ -18,10 +18,16 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned 
> long parent_nip,
&g

Re: [PATCH 5/9] kprobes/ftrace: Add recursion protection to the ftrace callback

2020-11-01 Thread Masami Hiramatsu
On Thu, 29 Oct 2020 09:40:01 -0400
Steven Rostedt  wrote:

> On Thu, 29 Oct 2020 16:58:03 +0900
> Masami Hiramatsu  wrote:
> 
> > Hi Steve,
> > 
> > On Wed, 28 Oct 2020 07:52:49 -0400
> > Steven Rostedt  wrote:
> > 
> > > From: "Steven Rostedt (VMware)" 
> > > 
> > > If a ftrace callback does not supply its own recursion protection and
> > > does not set the RECURSION_SAFE flag in its ftrace_ops, then ftrace will
> > > make a helper trampoline to do so before calling the callback instead of
> > > just calling the callback directly.  
> > 
> > So in that case the handlers will be called without preempt disabled?
> > 
> > 
> > > The default for ftrace_ops is going to assume recursion protection unless
> > > otherwise specified.  
> > 
> > This seems to skip entier handler if ftrace finds recursion.
> > I would like to increment the missed counter even in that case.
> 
> Note, this code does not change the functionality at this point, because
> without having the FL_RECURSION flag set (which kprobes does not even in
> this patch), it always gets called from the helper function that does this:
> 
>   bit = trace_test_and_set_recursion(TRACE_LIST_START, TRACE_LIST_MAX);
>   if (bit < 0)
>   return;
> 
>   preempt_disable_notrace();
> 
>   op->func(ip, parent_ip, op, regs);
> 
>   preempt_enable_notrace();
>   trace_clear_recursion(bit);
> 
> Where this function gets called by op->func().
> 
> In other words, you don't get that count anyway, and I don't think you want
> it. Because it means you traced something that your callback calls.

Got it. So nmissed count increment will be an improvement.

> 
> That bit check is basically a nop, because the last patch in this series
> will make the default that everything has recursion protection, but at this
> patch the test does this:
> 
>   /* A previous recursion check was made */
>   if ((val & TRACE_CONTEXT_MASK) > max)
>   return 0;
> 
> Which would always return true, because this function is called via the
> helper that already did the trace_test_and_set_recursion() which, if it
> made it this far, the val would always be greater than max.

OK, let me check the last patch too.

> 
> > 
> > [...]
> > e.g.
> > 
> > > diff --git a/arch/csky/kernel/probes/ftrace.c 
> > > b/arch/csky/kernel/probes/ftrace.c
> > > index 5264763d05be..5eb2604fdf71 100644
> > > --- a/arch/csky/kernel/probes/ftrace.c
> > > +++ b/arch/csky/kernel/probes/ftrace.c
> > > @@ -13,16 +13,21 @@ int arch_check_ftrace_location(struct kprobe *p)
> > >  void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
> > >  struct ftrace_ops *ops, struct pt_regs *regs)
> > >  {
> > > + int bit;
> > >   bool lr_saver = false;
> > >   struct kprobe *p;
> > >   struct kprobe_ctlblk *kcb;
> > >  
> > > - /* Preempt is disabled by ftrace */
> > > + bit = ftrace_test_recursion_trylock();  
> > 
> > > +
> > > + preempt_disable_notrace();
> > >   p = get_kprobe((kprobe_opcode_t *)ip);
> > >   if (!p) {
> > >   p = get_kprobe((kprobe_opcode_t *)(ip - MCOUNT_INSN_SIZE));
> > >   if (unlikely(!p) || kprobe_disabled(p))
> > > - return;
> > > + goto out;
> > >   lr_saver = true;
> > >   }  
> > 
> > if (bit < 0) {
> > kprobes_inc_nmissed_count(p);
> > goto out;
> > }
> 
> If anything called in get_kprobe() or kprobes_inc_nmissed_count() gets
> traced here, you have zero recursion protection, and this will crash the
> machine with a likely reboot (triple fault).

Oops, ok, those can be traced. 

> 
> Note, the recursion handles interrupts and wont stop them. bit < 0 only
> happens if you recurse because this function called something that ends up
> calling itself. Really, why would you care about missing a kprobe on the
> same kprobe?

Usually, sw-breakpoint based kprobes will count that case. Moreover, kprobes
shares one ftrace_ops among all kprobes. I guess in that case any kprobes
in kprobes (e.g. recursive call inside kprobe pre_handlers) will be skipped
by ftrace_test_recursion_trylock(), is that correct?

Thank you,

> 
> -- Steve


-- 
Masami Hiramatsu 


Re: [PATCH 5/9] kprobes/ftrace: Add recursion protection to the ftrace callback

2020-10-29 Thread Masami Hiramatsu
 __this_cpu_write(current_kprobe, NULL);
>   }
> +out:
> + preempt_enable_notrace();
> + ftrace_test_recursion_unlock(bit);
>  }
>  NOKPROBE_SYMBOL(kprobe_ftrace_handler);
>  
> diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
> index b388e87a08bf..88466d7fb6b2 100644
> --- a/arch/s390/kernel/ftrace.c
> +++ b/arch/s390/kernel/ftrace.c
> @@ -202,13 +202,19 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned 
> long parent_ip,
>  {
>   struct kprobe_ctlblk *kcb;
>   struct kprobe *p = get_kprobe((kprobe_opcode_t *)ip);
> + int bit;
>  
> - if (unlikely(!p) || kprobe_disabled(p))
> + bit = ftrace_test_recursion_trylock();
> + if (bit < 0)
>   return;
>  
> + preempt_disable_notrace();
> + if (unlikely(!p) || kprobe_disabled(p))
> + goto out;
> +
>   if (kprobe_running()) {
>   kprobes_inc_nmissed_count(p);
> - return;
> + goto out;
>   }
>  
>   __this_cpu_write(current_kprobe, p);
> @@ -228,6 +234,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned 
> long parent_ip,
>   }
>   }
>   __this_cpu_write(current_kprobe, NULL);
> +out:
> + preempt_enable_notrace();
> + ftrace_test_recursion_unlock(bit);
>  }
>  NOKPROBE_SYMBOL(kprobe_ftrace_handler);
>  
> diff --git a/arch/x86/kernel/kprobes/ftrace.c 
> b/arch/x86/kernel/kprobes/ftrace.c
> index 681a4b36e9bb..a40a6cdfcca3 100644
> --- a/arch/x86/kernel/kprobes/ftrace.c
> +++ b/arch/x86/kernel/kprobes/ftrace.c
> @@ -18,11 +18,16 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned 
> long parent_ip,
>  {
>   struct kprobe *p;
>   struct kprobe_ctlblk *kcb;
> + int bit;
>  
> - /* Preempt is disabled by ftrace */
> + bit = ftrace_test_recursion_trylock();
> + if (bit < 0)
> + return;
> +
> + preempt_disable_notrace();
>   p = get_kprobe((kprobe_opcode_t *)ip);
>   if (unlikely(!p) || kprobe_disabled(p))
> - return;
> + goto out;
>  
>   kcb = get_kprobe_ctlblk();
>   if (kprobe_running()) {
> @@ -52,6 +57,9 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long 
> parent_ip,
>*/
>   __this_cpu_write(current_kprobe, NULL);
>   }
> +out:
> + preempt_enable_notrace();
> + ftrace_test_recursion_unlock(bit);
>  }
>  NOKPROBE_SYMBOL(kprobe_ftrace_handler);
>  
> -- 
> 2.28.0
> 
> 


-- 
Masami Hiramatsu 


Re: [PATCH v2 1/3] module: Rename module_alloc() to text_alloc() and move to kernel proper

2020-07-14 Thread Masami Hiramatsu
On Tue, 14 Jul 2020 10:03:45 -0400
Steven Rostedt  wrote:

> On Tue, 14 Jul 2020 14:33:14 +0100
> Mark Rutland  wrote:
> 
> > > Should work for all cases. Yes, we might then want something like a per
> > > arch:
> > > 
> > >   {BPF,FTRACE,KPROBE}_TEXT_TYPE  
> > 
> > ... at that point why not:
> > 
> >   text_alloc_ftrace();
> >   text_alloc_module();
> >   text_alloc_bpf();
> >   text_alloc_kprobe();
> 
> I don't know about bpf and kprobes, but for ftrace, the only place that
> it allocates text happens to be in arch specific code.
> 
> If you want something special for ftrace, you could just add your own
> function. But for x86, a text_alloc_immediate() would work.
> (BTW, I like the function names over the enums)

kprobes will need the text_alloc_immediate() too, since it will use
the trampoline buffer where jumps to/from kernel code/modules.

Thanks,

-- 
Masami Hiramatsu 


Re: [PATCH v3] powerpc/kprobes: Ignore traps that happened in real mode

2020-02-18 Thread Masami Hiramatsu
On Tue, 18 Feb 2020 19:38:27 + (UTC)
Christophe Leroy  wrote:

> When a program check exception happens while MMU translation is
> disabled, following Oops happens in kprobe_handler() in the following
> code:
> 
>   } else if (*addr != BREAKPOINT_INSTRUCTION) {
> 
> [   33.098554] BUG: Unable to handle kernel data access on read at 0xe268
> [   33.105091] Faulting instruction address: 0xc000ec34
> [   33.110010] Oops: Kernel access of bad area, sig: 11 [#1]
> [   33.115348] BE PAGE_SIZE=16K PREEMPT CMPC885
> [   33.119540] Modules linked in:
> [   33.122591] CPU: 0 PID: 429 Comm: cat Not tainted 
> 5.6.0-rc1-s3k-dev-00824-g84195dc6c58a #3267
> [   33.131005] NIP:  c000ec34 LR: c000ecd8 CTR: c019cab8
> [   33.136002] REGS: ca4d3b58 TRAP: 0300   Not tainted  
> (5.6.0-rc1-s3k-dev-00824-g84195dc6c58a)
> [   33.144324] MSR:  1032   CR: 2a4d3c52  XER: 
> [   33.150699] DAR: e268 DSISR: c000
> [   33.150699] GPR00: c000b09c ca4d3c10 c66d0620  ca4d3c60  
> 9032 
> [   33.150699] GPR08: 0002  c087de44 c000afe0 c66d0ad0 100d3dd6 
> fff3 
> [   33.150699] GPR16:  0041  ca4d3d70   
> 416d 
> [   33.150699] GPR24: 0004 c53b6128  e268  c07c 
> c07bb6fc ca4d3c60
> [   33.188015] NIP [c000ec34] kprobe_handler+0x128/0x290
> [   33.192989] LR [c000ecd8] kprobe_handler+0x1cc/0x290
> [   33.197854] Call Trace:
> [   33.200340] [ca4d3c30] [c000b09c] program_check_exception+0xbc/0x6fc
> [   33.206590] [ca4d3c50] [c000e43c] ret_from_except_full+0x0/0x4
> [   33.212392] --- interrupt: 700 at 0xe268
> [   33.270401] Instruction dump:
> [   33.273335] 913e0008 8122 3861 3929 9122 80010024 bb410008 
> 7c0803a6
> [   33.280992] 38210020 4e800020 3860 4e800020 <813b> 6d2a7fe0 
> 2f8a0008 419e0154
> [   33.288841] ---[ end trace 5b9152d4cdadd06d ]---
> 
> kprobe is not prepared to handle events in real mode and functions
> running in real mode should have been blacklisted, so kprobe_handler()
> can safely bail out telling 'this trap is not mine' for any trap that
> happened while in real-mode.
> 
> If the trap happened with MSR_IR or MSR_DR cleared, return 0 immediately.
> 

Looks good to me.

Reviewed-by: Masami Hiramatsu 

Thank you!


> Reported-by: Larry Finger 
> Fixes: 6cc89bad60a6 ("powerpc/kprobes: Invoke handlers directly")
> Cc: sta...@vger.kernel.org
> Cc: Naveen N. Rao 
> Cc: Masami Hiramatsu 
> Signed-off-by: Christophe Leroy 
> 
> ---
> v3: Also bail out if MSR_DR is cleared.
> 
> Resending v2 with a more appropriate name
> 
> v2: bailing out instead of converting real-time address to virtual and 
> continuing.
> 
> The bug might have existed even before that commit from Naveen.
> 
> Signed-off-by: Christophe Leroy 
> ---
>  arch/powerpc/kernel/kprobes.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index 2d27ec4feee4..9b340af02c38 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -264,6 +264,9 @@ int kprobe_handler(struct pt_regs *regs)
>   if (user_mode(regs))
>   return 0;
>  
> + if (!(regs->msr & MSR_IR) || !(regs->msr & MSR_DR))
> + return 0;
> +
>   /*
>* We don't want to be preempted for the entire
>* duration of kprobe processing
> -- 
> 2.25.0
> 


-- 
Masami Hiramatsu 


Re: [PATCH] powerpc/kprobes: Fix trap address when trap happened in real mode

2020-02-18 Thread Masami Hiramatsu
On Tue, 18 Feb 2020 12:04:41 +0100
Christophe Leroy  wrote:

> >> Nevertheless, if one symbol has been forgotten in the blacklist, I think
> >> it is a problem if it generate Oopses.
> > 
> > There is a long history also on x86 to make a blacklist. Anyway, how did
> > you get this error on PPC32? Somewhere would you like to probe and
> > it is a real mode function? Or, it happened unexpectedly?
> 
> The first Oops I got was triggered by a WARN_ON() kind of trap in real 
> mode. The trap exception handler called kprobe_handler() which tried to 
> read the instruction at the trap address (which was a real-mode address) 
> so it triggered a Bad Access Fault.
> 
> This was initially the purpose of my patch.

OK, then filtering the trap reason in kprobe handler is a bit strange.
It should be done in the previous stage (maybe in trap.c)
Can we filter it by exception flag or only by checking the instruction
which causes the exception, or needs get_kprobe()...?

> After discussion with you, I started looking at what would be the effect 
> of setting a kprobe event in a function which runs in real mode.

If the kprobe single-stepping (or emulation) works in real mode, just
ignore the kprobes pre/post_handlers and increment nmissed count.

If that doesn't work, we have to call a BUG_ON, because we can not
continue the code execution. And also, you have to find a way to make
a blacklist for real mode code.

> >>
> >>> Or, some parts are possble to run under both real mode and kernel mode?
> >>
> >> I don't think so, at least on PPC32
> > 
> > OK, that's a good news. Also, are there any independent section where such
> > real mode functions are stored? (I can see start_real_trampolines in
> > sections.h) If that kind of sections are defined, it is easy to make
> > a blacklist in arch_populate_kprobe_blacklist(). See 
> > arch/arm64/kernel/probes/kprobes.c.
> 
> Part of them are in .head.text, and this section is already blacklisted 
> throught function arch_within_kprobe_blacklist()

Then, those are OK.

> 
> But there are several other functions which are not there. For instance, 
> many things within entry_32.S, and also things in hash_low.S
> On PPC64 (ie in entry_64.S) they were explicitely blacklisted with 
> _ASM_NOKPROBE_SYMBOL(). We have to do the same on PPC64

Agreed. Some of such unstable state code must not be probed.

> >>>> So the 'program check' exception handler doesn't find the owner of the
> >>>> trap hence generate an Oops.
> >>>>
> >>>> Even if we don't want kprobe() to proceed with the event entirely
> >>>> (allthough it works at least for simple events), I'd expect it to fail
> >>>> gracefully.
> >>>
> >>> Agreed. I thought it was easy to identify real mode code. But if it is
> >>> hard, we should apply your first patch and also skip user handlers
> >>> if we are in the real mode (and increment missed count).
> >>
> >> user handlers are already skipped.
> > 
> > Yes, if you don't put a kprobes on real mode code. However, if user
> > (accidentally) puts a probe on real mode code, it might call a
> > user handler?
> 
> Are we talking about the same thing ?

Ah, sorry about that. "user handler" here I meant was "kprobe pre/post_handler
function defined by the user of kprobes".

> 
> Only kernel code can run in real mode, so the following code at the 
> beginning of kprobe_handler() does the job ?
> 
>   if (user_mode(regs))
>   return 0;

Yes, you're right.

> >> What do you think about my latest proposal below ? If a trap is
> >> encoutered in real mode, if checks if the matching virtual address
> >> corresponds to a valid kprobe. If it is, it skips it. If not, it returns
> >> 0 to tell "it's no me". You are also talking about incrementing the
> >> missed count. Who do we do that ?
> > 
> > I rather like your first patch. If there is a kprobes, we can not skip
> > the instruction, because there is an instruction which must be executed.
> > (or single-skipped, but I'm not sure the emulator works correctly on
> > real mode)
> 
> Oops, yes of course.

Thank you,

-- 
Masami Hiramatsu 


Re: [PATCH] powerpc/kprobes: Fix trap address when trap happened in real mode

2020-02-18 Thread Masami Hiramatsu
On Tue, 18 Feb 2020 06:58:06 +0100
Christophe Leroy  wrote:

> >>>>
> >>>> What do you mean by 'there' ? At the entry of kprobe_handler() ?
> >>>>
> >>>> That's what my patch does, it checks whether MMU is disabled or not. If
> >>>> it is, it converts the address to a virtual address.
> >>>>
> >>>> Do you mean kprobe_handler() should bail out early as it does when the
> >>>> trap happens in user mode ?
> >>>
> >>> Yes, that is what I meant.
> >>>
> >>>> Of course we can do that, I don't know
> >>>> enough about kprobe to know if kprobe_handler() should manage events
> >>>> that happened in real-mode or just ignore them. But I tested adding an
> >>>> event on a function that runs in real-mode, and it (now) works.
> >>>>
> >>>> So, what should we do really ?
> >>>
> >>> I'm not sure how the powerpc kernel runs in real mode.
> >>> But clearly, at least kprobe event can not handle that case because
> >>> it tries to access memory by probe_kernel_read(). Unless that function
> >>> correctly handles the address translation, I want to prohibit kprobes
> >>> on such address.
> >>>
> >>> So what I would like to see is, something like below.
> >>>
> >>> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> >>> index 2d27ec4feee4..4771be152416 100644
> >>> --- a/arch/powerpc/kernel/kprobes.c
> >>> +++ b/arch/powerpc/kernel/kprobes.c
> >>> @@ -261,7 +261,7 @@ int kprobe_handler(struct pt_regs *regs)
> >>>   unsigned int *addr = (unsigned int *)regs->nip;
> >>>   struct kprobe_ctlblk *kcb;
> >>>
> >>> -   if (user_mode(regs))
> >>> +   if (user_mode(regs) || !(regs->msr & MSR_IR))
> >>>   return 0;
> >>>
> >>>   /*
> >>>
> >>>
> >>
> >> With this instead change of my patch, I get an Oops everytime a kprobe
> >> event occurs in real-mode.
> >>
> >> This is because kprobe_handler() is now saying 'this trap doesn't belong
> >> to me' for a trap that has been installed by it.
> > 
> > Hmm, on powerpc, kprobes is allowed to probe on the code which runs
> > in the real mode? I think we should also prohibit it by blacklisting.
> > (It is easy to add blacklist by NOKPROBE_SYMBOL(func))
> 
> Yes, I see a lot of them tagged with _ASM_NOKPROBE_SYMBOL() on PPC64, 
> but none on PPC32. I suppose that's missing and have to be added. 

Ah, you are using PPC32. 

> Nevertheless, if one symbol has been forgotten in the blacklist, I think 
> it is a problem if it generate Oopses.

There is a long history also on x86 to make a blacklist. Anyway, how did
you get this error on PPC32? Somewhere would you like to probe and
it is a real mode function? Or, it happened unexpectedly?

> 
> > Or, some parts are possble to run under both real mode and kernel mode?
> 
> I don't think so, at least on PPC32

OK, that's a good news. Also, are there any independent section where such
real mode functions are stored? (I can see start_real_trampolines in
sections.h) If that kind of sections are defined, it is easy to make
a blacklist in arch_populate_kprobe_blacklist(). See 
arch/arm64/kernel/probes/kprobes.c.


> >> So the 'program check' exception handler doesn't find the owner of the
> >> trap hence generate an Oops.
> >>
> >> Even if we don't want kprobe() to proceed with the event entirely
> >> (allthough it works at least for simple events), I'd expect it to fail
> >> gracefully.
> > 
> > Agreed. I thought it was easy to identify real mode code. But if it is
> > hard, we should apply your first patch and also skip user handlers
> > if we are in the real mode (and increment missed count).
> 
> user handlers are already skipped.

Yes, if you don't put a kprobes on real mode code. However, if user
(accidentally) puts a probe on real mode code, it might call a
user handler?

> 
> What do you think about my latest proposal below ? If a trap is 
> encoutered in real mode, if checks if the matching virtual address 
> corresponds to a valid kprobe. If it is, it skips it. If not, it returns 
> 0 to tell "it's no me". You are also talking about incrementing the 
> missed count. Who do we do that ?

I rather like your first patch. If there is a kprobes, we can not skip
the instruction, because there is an instruction which must be executed.
(or single-skipped, but I'm not sure the emulator works correctly on
real mode)

Thank you,

> 
> 
> 
> @@ -264,6 +265,13 @@ int kprobe_handler(struct pt_regs *regs)
>   if (user_mode(regs))
>   return 0;
> 
> +if (!(regs->msr & MSR_IR)) {
> +if (!get_kprobe(phys_to_virt(regs->nip)))
> +return 0;
> +regs->nip += 4;
> +return 1;
> +}
> +
>   /*
>* We don't want to be preempted for the entire
>* duration of kprobe processing
> 
> 
> > 
> > BTW, can the emulater handle the real mode code correctly?
> 
> I don't know, how do I test that ?
> 
> Christophe


-- 
Masami Hiramatsu 


Re: [PATCH] powerpc/kprobes: Fix trap address when trap happened in real mode

2020-02-17 Thread Masami Hiramatsu
On Mon, 17 Feb 2020 16:38:50 +0100
Christophe Leroy  wrote:

> 
> 
> Le 17/02/2020 à 11:27, Masami Hiramatsu a écrit :
> > On Mon, 17 Feb 2020 10:03:22 +0100
> > Christophe Leroy  wrote:
> > 
> >>
> >>
> >> Le 16/02/2020 à 13:34, Masami Hiramatsu a écrit :
> >>> On Sat, 15 Feb 2020 11:28:49 +0100
> >>> Christophe Leroy  wrote:
> >>>
> >>>> Hi,
> >>>>
> >>>> Le 14/02/2020 à 14:54, Masami Hiramatsu a écrit :
> >>>>> Hi,
> >>>>>
> >>>>> On Fri, 14 Feb 2020 12:47:49 + (UTC)
> >>>>> Christophe Leroy  wrote:
> >>>>>
> >>>>>> When a program check exception happens while MMU translation is
> >>>>>> disabled, following Oops happens in kprobe_handler() in the following
> >>>>>> test:
> >>>>>>
> >>>>>>} else if (*addr != BREAKPOINT_INSTRUCTION) {
> >>>>>
> >>>>> Thanks for the report and patch. I'm not so sure about powerpc 
> >>>>> implementation
> >>>>> but at where the MMU translation is disabled, can the handler work 
> >>>>> correctly?
> >>>>> (And where did you put the probe on?)
> >>>>>
> >>>>> Your fix may fix this Oops, but if the handler needs special care, it 
> >>>>> is an
> >>>>> option to blacklist such place (if possible).
> >>>>
> >>>> I guess that's another story. Here we are not talking about a place
> >>>> where kprobe has been illegitimately activated, but a place where there
> >>>> is a valid trap, which generated a valid 'program check exception'. And
> >>>> kprobe was off at that time.
> >>>
> >>> Ah, I got it. It is not a kprobe breakpoint, but to check that correctly,
> >>> it has to know the address where the breakpoint happens. OK.
> >>>
> >>>>
> >>>> As any 'program check exception' due to a trap (ie a BUG_ON, a WARN_ON,
> >>>> a debugger breakpoint, a perf breakpoint, etc...) calls
> >>>> kprobe_handler(), kprobe_handler() must be prepared to handle the case
> >>>> where the MMU translation is disabled, even if probes are not supposed
> >>>> to be set for functions running with MMU translation disabled.
> >>>
> >>> Can't we check the MMU is disabled there (as same as checking the 
> >>> exception
> >>> happened in user space or not)?
> >>>
> >>
> >> What do you mean by 'there' ? At the entry of kprobe_handler() ?
> >>
> >> That's what my patch does, it checks whether MMU is disabled or not. If
> >> it is, it converts the address to a virtual address.
> >>
> >> Do you mean kprobe_handler() should bail out early as it does when the
> >> trap happens in user mode ?
> > 
> > Yes, that is what I meant.
> > 
> >> Of course we can do that, I don't know
> >> enough about kprobe to know if kprobe_handler() should manage events
> >> that happened in real-mode or just ignore them. But I tested adding an
> >> event on a function that runs in real-mode, and it (now) works.
> >>
> >> So, what should we do really ?
> > 
> > I'm not sure how the powerpc kernel runs in real mode.
> > But clearly, at least kprobe event can not handle that case because
> > it tries to access memory by probe_kernel_read(). Unless that function
> > correctly handles the address translation, I want to prohibit kprobes
> > on such address.
> > 
> > So what I would like to see is, something like below.
> > 
> > diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> > index 2d27ec4feee4..4771be152416 100644
> > --- a/arch/powerpc/kernel/kprobes.c
> > +++ b/arch/powerpc/kernel/kprobes.c
> > @@ -261,7 +261,7 @@ int kprobe_handler(struct pt_regs *regs)
> >  unsigned int *addr = (unsigned int *)regs->nip;
> >  struct kprobe_ctlblk *kcb;
> >   
> > -   if (user_mode(regs))
> > +   if (user_mode(regs) || !(regs->msr & MSR_IR))
> >  return 0;
> >   
> >  /*
> > 
> > 
> 
> With this instead change of my patch, I get an Oops everytime a kprobe 
> event occurs in real-mode.
> 
> This is because kprobe_handler() is now saying 'this trap doesn't belong 
> to me' for a trap that has been installed by it.

Hmm, on powerpc, kprobes is allowed to probe on the code which runs
in the real mode? I think we should also prohibit it by blacklisting.
(It is easy to add blacklist by NOKPROBE_SYMBOL(func))
Or, some parts are possble to run under both real mode and kernel mode?

> 
> So the 'program check' exception handler doesn't find the owner of the 
> trap hence generate an Oops.
> 
> Even if we don't want kprobe() to proceed with the event entirely 
> (allthough it works at least for simple events), I'd expect it to fail 
> gracefully.

Agreed. I thought it was easy to identify real mode code. But if it is
hard, we should apply your first patch and also skip user handlers
if we are in the real mode (and increment missed count).

BTW, can the emulater handle the real mode code correctly?

Thank you,

-- 
Masami Hiramatsu 


Re: [PATCH] powerpc/kprobes: Fix trap address when trap happened in real mode

2020-02-17 Thread Masami Hiramatsu
On Mon, 17 Feb 2020 10:03:22 +0100
Christophe Leroy  wrote:

> 
> 
> Le 16/02/2020 à 13:34, Masami Hiramatsu a écrit :
> > On Sat, 15 Feb 2020 11:28:49 +0100
> > Christophe Leroy  wrote:
> > 
> >> Hi,
> >>
> >> Le 14/02/2020 à 14:54, Masami Hiramatsu a écrit :
> >>> Hi,
> >>>
> >>> On Fri, 14 Feb 2020 12:47:49 + (UTC)
> >>> Christophe Leroy  wrote:
> >>>
> >>>> When a program check exception happens while MMU translation is
> >>>> disabled, following Oops happens in kprobe_handler() in the following
> >>>> test:
> >>>>
> >>>>  } else if (*addr != BREAKPOINT_INSTRUCTION) {
> >>>
> >>> Thanks for the report and patch. I'm not so sure about powerpc 
> >>> implementation
> >>> but at where the MMU translation is disabled, can the handler work 
> >>> correctly?
> >>> (And where did you put the probe on?)
> >>>
> >>> Your fix may fix this Oops, but if the handler needs special care, it is 
> >>> an
> >>> option to blacklist such place (if possible).
> >>
> >> I guess that's another story. Here we are not talking about a place
> >> where kprobe has been illegitimately activated, but a place where there
> >> is a valid trap, which generated a valid 'program check exception'. And
> >> kprobe was off at that time.
> > 
> > Ah, I got it. It is not a kprobe breakpoint, but to check that correctly,
> > it has to know the address where the breakpoint happens. OK.
> > 
> >>
> >> As any 'program check exception' due to a trap (ie a BUG_ON, a WARN_ON,
> >> a debugger breakpoint, a perf breakpoint, etc...) calls
> >> kprobe_handler(), kprobe_handler() must be prepared to handle the case
> >> where the MMU translation is disabled, even if probes are not supposed
> >> to be set for functions running with MMU translation disabled.
> > 
> > Can't we check the MMU is disabled there (as same as checking the exception
> > happened in user space or not)?
> > 
> 
> What do you mean by 'there' ? At the entry of kprobe_handler() ?
> 
> That's what my patch does, it checks whether MMU is disabled or not. If 
> it is, it converts the address to a virtual address.
> 
> Do you mean kprobe_handler() should bail out early as it does when the 
> trap happens in user mode ?

Yes, that is what I meant.

> Of course we can do that, I don't know 
> enough about kprobe to know if kprobe_handler() should manage events 
> that happened in real-mode or just ignore them. But I tested adding an 
> event on a function that runs in real-mode, and it (now) works.
> 
> So, what should we do really ?

I'm not sure how the powerpc kernel runs in real mode.
But clearly, at least kprobe event can not handle that case because
it tries to access memory by probe_kernel_read(). Unless that function
correctly handles the address translation, I want to prohibit kprobes
on such address.

So what I would like to see is, something like below.

diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 2d27ec4feee4..4771be152416 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -261,7 +261,7 @@ int kprobe_handler(struct pt_regs *regs)
unsigned int *addr = (unsigned int *)regs->nip;
struct kprobe_ctlblk *kcb;
 
-   if (user_mode(regs))
+   if (user_mode(regs) || !(regs->msr & MSR_IR))
return 0;
 
/*


Thank you,

-- 
Masami Hiramatsu 


Re: [PATCH] powerpc/kprobes: Fix trap address when trap happened in real mode

2020-02-16 Thread Masami Hiramatsu
On Sat, 15 Feb 2020 11:28:49 +0100
Christophe Leroy  wrote:

> Hi,
> 
> Le 14/02/2020 à 14:54, Masami Hiramatsu a écrit :
> > Hi,
> > 
> > On Fri, 14 Feb 2020 12:47:49 + (UTC)
> > Christophe Leroy  wrote:
> > 
> >> When a program check exception happens while MMU translation is
> >> disabled, following Oops happens in kprobe_handler() in the following
> >> test:
> >>
> >>} else if (*addr != BREAKPOINT_INSTRUCTION) {
> > 
> > Thanks for the report and patch. I'm not so sure about powerpc 
> > implementation
> > but at where the MMU translation is disabled, can the handler work 
> > correctly?
> > (And where did you put the probe on?)
> > 
> > Your fix may fix this Oops, but if the handler needs special care, it is an
> > option to blacklist such place (if possible).
> 
> I guess that's another story. Here we are not talking about a place 
> where kprobe has been illegitimately activated, but a place where there 
> is a valid trap, which generated a valid 'program check exception'. And 
> kprobe was off at that time.

Ah, I got it. It is not a kprobe breakpoint, but to check that correctly,
it has to know the address where the breakpoint happens. OK.

> 
> As any 'program check exception' due to a trap (ie a BUG_ON, a WARN_ON, 
> a debugger breakpoint, a perf breakpoint, etc...) calls 
> kprobe_handler(), kprobe_handler() must be prepared to handle the case 
> where the MMU translation is disabled, even if probes are not supposed 
> to be set for functions running with MMU translation disabled.

Can't we check the MMU is disabled there (as same as checking the exception
happened in user space or not)?

Thank you,

-- 
Masami Hiramatsu 


Re: [PATCH] powerpc/kprobes: Fix trap address when trap happened in real mode

2020-02-14 Thread Masami Hiramatsu
Hi,

On Fri, 14 Feb 2020 12:47:49 + (UTC)
Christophe Leroy  wrote:

> When a program check exception happens while MMU translation is
> disabled, following Oops happens in kprobe_handler() in the following
> test:
> 
>   } else if (*addr != BREAKPOINT_INSTRUCTION) {

Thanks for the report and patch. I'm not so sure about powerpc implementation
but at where the MMU translation is disabled, can the handler work correctly?
(And where did you put the probe on?)

Your fix may fix this Oops, but if the handler needs special care, it is an
option to blacklist such place (if possible).

Anyway, Naveen, can you review it?

Thank you,

> 
> [   33.098554] BUG: Unable to handle kernel data access on read at 0xe268
> [   33.105091] Faulting instruction address: 0xc000ec34
> [   33.110010] Oops: Kernel access of bad area, sig: 11 [#1]
> [   33.115348] BE PAGE_SIZE=16K PREEMPT CMPC885
> [   33.119540] Modules linked in:
> [   33.122591] CPU: 0 PID: 429 Comm: cat Not tainted 
> 5.6.0-rc1-s3k-dev-00824-g84195dc6c58a #3267
> [   33.131005] NIP:  c000ec34 LR: c000ecd8 CTR: c019cab8
> [   33.136002] REGS: ca4d3b58 TRAP: 0300   Not tainted  
> (5.6.0-rc1-s3k-dev-00824-g84195dc6c58a)
> [   33.144324] MSR:  1032   CR: 2a4d3c52  XER: 
> [   33.150699] DAR: e268 DSISR: c000
> [   33.150699] GPR00: c000b09c ca4d3c10 c66d0620  ca4d3c60  
> 9032 
> [   33.150699] GPR08: 0002  c087de44 c000afe0 c66d0ad0 100d3dd6 
> fff3 
> [   33.150699] GPR16:  0041  ca4d3d70   
> 416d 
> [   33.150699] GPR24: 0004 c53b6128  e268  c07c 
> c07bb6fc ca4d3c60
> [   33.188015] NIP [c000ec34] kprobe_handler+0x128/0x290
> [   33.192989] LR [c000ecd8] kprobe_handler+0x1cc/0x290
> [   33.197854] Call Trace:
> [   33.200340] [ca4d3c30] [c000b09c] program_check_exception+0xbc/0x6fc
> [   33.206590] [ca4d3c50] [c000e43c] ret_from_except_full+0x0/0x4
> [   33.212392] --- interrupt: 700 at 0xe268
> [   33.270401] Instruction dump:
> [   33.273335] 913e0008 8122 3861 3929 9122 80010024 bb410008 
> 7c0803a6
> [   33.280992] 38210020 4e800020 3860 4e800020 <813b> 6d2a7fe0 
> 2f8a0008 419e0154
> [   33.288841] ---[ end trace 5b9152d4cdadd06d ]---
> 
> Check MSR and convert regs->nip to virtual address if the trap
> happened with MSR_IR cleared.
> 
> Reported-by: Larry Finger 
> Fixes: 6cc89bad60a6 ("powerpc/kprobes: Invoke handlers directly")
> Cc: sta...@kernel.vger.org
> Cc: Naveen N. Rao 
> Signed-off-by: Christophe Leroy 
> 
> ---
> The bug might have existed even before that commit from Naveen.
> 
> Signed-off-by: Christophe Leroy 
> ---
>  arch/powerpc/kernel/kprobes.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index 2d27ec4feee4..f8b848aa65bd 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -23,6 +23,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  
>  DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
> @@ -264,6 +265,9 @@ int kprobe_handler(struct pt_regs *regs)
>   if (user_mode(regs))
>   return 0;
>  
> + if (!(regs->msr & MSR_IR))
> + addr = phys_to_virt(regs->nip);
> +
>   /*
>* We don't want to be preempted for the entire
>* duration of kprobe processing
> -- 
> 2.25.0
> 


-- 
Masami Hiramatsu 


Re: [PATCH v4 2/9] perf/core: open access for CAP_SYS_PERFMON privileged process

2020-01-11 Thread Masami Hiramatsu
On Fri, 10 Jan 2020 21:35:12 -0300
arnaldo.m...@gmail.com wrote:

> ,Jann Horn ,Thomas Gleixner 
> ,Tvrtko Ursulin ,Lionel 
> Landwerlin ,linux-kernel 
> ,"linux-security-mod...@vger.kernel.org" 
> ,"seli...@vger.kernel.org" 
> ,"intel-...@lists.freedesktop.org" 
> ,"b...@vger.kernel.org" 
> ,"linux-par...@vger.kernel.org" 
> ,"linuxppc-dev@lists.ozlabs.org" 
> ,"linux-perf-us...@vger.kernel.org" 
> ,"linux-arm-ker...@lists.infradead.org" 
> ,"oprofile-l...@lists.sf.net" 
> 
> From: Arnaldo Carvalho de Melo 
> Message-ID: 
> 
> On January 10, 2020 9:23:27 PM GMT-03:00, Song Liu  
> wrote:
> >
> >
> >> On Jan 10, 2020, at 3:47 PM, Masami Hiramatsu 
> >wrote:
> >> 
> >> On Fri, 10 Jan 2020 13:45:31 -0300
> >> Arnaldo Carvalho de Melo  wrote:
> >> 
> >>> Em Sat, Jan 11, 2020 at 12:52:13AM +0900, Masami Hiramatsu escreveu:
> >>>> On Fri, 10 Jan 2020 15:02:34 +0100 Peter Zijlstra
> > wrote:
> >>>>> Again, this only allows attaching to previously created kprobes,
> >it does
> >>>>> not allow creating kprobes, right?
> >>> 
> >>>>> That is; I don't think CAP_SYS_PERFMON should be allowed to create
> >>>>> kprobes.
> >>> 
> >>>>> As might be clear; I don't actually know what the user-ABI is for
> >>>>> creating kprobes.
> >>> 
> >>>> There are 2 ABIs nowadays, ftrace and ebpf. perf-probe uses ftrace
> >interface to
> >>>> define new kprobe events, and those events are treated as
> >completely same as
> >>>> tracepoint events. On the other hand, ebpf tries to define new
> >probe event
> >>>> via perf_event interface. Above one is that interface. IOW, it
> >creates new kprobe.
> >>> 
> >>> Masami, any plans to make 'perf probe' use the perf_event_open()
> >>> interface for creating kprobes/uprobes?
> >> 
> >> Would you mean perf probe to switch to perf_event_open()?
> >> No, perf probe is for setting up the ftrace probe events. I think we
> >can add an
> >> option to use perf_event_open(). But current kprobe creation from
> >perf_event_open()
> >> is separated from ftrace by design.
> >
> >I guess we can extend event parser to understand kprobe directly.
> >Instead of
> >
> > perf probe kernel_func
> > perf stat/record -e probe:kernel_func ...
> >
> >We can just do 
> >
> > perf stat/record -e kprobe:kernel_func ...
> 
> 
> You took the words from my mouth, exactly, that is a perfect use case, an 
> alternative to the 'perf probe' one of making a disabled event that then gets 
> activated via record/stat/trace, in many cases it's better, removes the 
> explicit probe setup case.

Ah, I got it. If the perf event parser just kicks perf's kprobe creation
interface, it will be easy. In that case, there should be following differences.

- perf * -e "kprobe":kernel_func will put a local (hidden) kprobe
  events. So ftrace user can not access it.
- perf * -e "kprobe":kernel_func may not support inline/function-body
  nor trace local variables etc.

Hm, if we support inline function via -e "kprobe" interface, we have to
expand perf_event_open() to support multi-probe event.

Thanks,

> 
> Regards, 
> 
> - Arnaldo
> 
> >
> >Thanks,
> >Song
> 


-- 
Masami Hiramatsu 


Re: [PATCH v4 2/9] perf/core: open access for CAP_SYS_PERFMON privileged process

2020-01-10 Thread Masami Hiramatsu
On Fri, 10 Jan 2020 13:45:31 -0300
Arnaldo Carvalho de Melo  wrote:

> Em Sat, Jan 11, 2020 at 12:52:13AM +0900, Masami Hiramatsu escreveu:
> > On Fri, 10 Jan 2020 15:02:34 +0100 Peter Zijlstra  
> > wrote:
> > > Again, this only allows attaching to previously created kprobes, it does
> > > not allow creating kprobes, right?
> 
> > > That is; I don't think CAP_SYS_PERFMON should be allowed to create
> > > kprobes.
> 
> > > As might be clear; I don't actually know what the user-ABI is for
> > > creating kprobes.
> 
> > There are 2 ABIs nowadays, ftrace and ebpf. perf-probe uses ftrace 
> > interface to
> > define new kprobe events, and those events are treated as completely same as
> > tracepoint events. On the other hand, ebpf tries to define new probe event
> > via perf_event interface. Above one is that interface. IOW, it creates new 
> > kprobe.
> 
> Masami, any plans to make 'perf probe' use the perf_event_open()
> interface for creating kprobes/uprobes?

Would you mean perf probe to switch to perf_event_open()?
No, perf probe is for setting up the ftrace probe events. I think we can add an
option to use perf_event_open(). But current kprobe creation from 
perf_event_open()
is separated from ftrace by design.

I think the reason why ebpf uses perf_event_open() interface is to avoid 
conflict
with ftrace users. Those probes are temporally used by ebpf, but if it is 
appeared on
ftrace, it is easy to be used by ftrace. In that case, it can not be removed 
when
the ebpf exits.

Thank you,

-- 
Masami Hiramatsu 


Re: [PATCH v4 2/9] perf/core: open access for CAP_SYS_PERFMON privileged process

2020-01-10 Thread Masami Hiramatsu
On Fri, 10 Jan 2020 15:02:34 +0100
Peter Zijlstra  wrote:

> On Thu, Jan 09, 2020 at 02:36:50PM +0300, Alexey Budankov wrote:
> > On 08.01.2020 19:07, Peter Zijlstra wrote:
> > > On Wed, Dec 18, 2019 at 12:25:35PM +0300, Alexey Budankov wrote:
> 
> > >> diff --git a/kernel/events/core.c b/kernel/events/core.c
> > >> index 059ee7116008..d9db414f2197 100644
> > >> --- a/kernel/events/core.c
> > >> +++ b/kernel/events/core.c
> > >> @@ -9056,7 +9056,7 @@ static int perf_kprobe_event_init(struct 
> > >> perf_event *event)
> > >>  if (event->attr.type != perf_kprobe.type)
> > >>  return -ENOENT;
> > >>  
> > >> -if (!capable(CAP_SYS_ADMIN))
> > >> +if (!perfmon_capable())
> > >>  return -EACCES;
> > >>  
> > >>  /*
> > > 
> > > This one only allows attaching to already extant kprobes, right? It does
> > > not allow creation of kprobes.
> > 
> > This unblocks creation of local trace kprobes and uprobes by 
> > CAP_SYS_PERFMON 
> > privileged process, exactly the same as for CAP_SYS_ADMIN privileged 
> > process.
> 
> I've no idea what you just said; it's just words.
> 
> Again, this only allows attaching to previously created kprobes, it does
> not allow creating kprobes, right?
> 
> That is; I don't think CAP_SYS_PERFMON should be allowed to create
> kprobes.
> 
> As might be clear; I don't actually know what the user-ABI is for
> creating kprobes.

There are 2 ABIs nowadays, ftrace and ebpf. perf-probe uses ftrace interface to
define new kprobe events, and those events are treated as completely same as
tracepoint events. On the other hand, ebpf tries to define new probe event
via perf_event interface. Above one is that interface. IOW, it creates new 
kprobe.

Thank you,


-- 
Masami Hiramatsu 


Re: [PATCH v2 0/3] arm/arm64: Add support for function error injection

2019-08-06 Thread Masami Hiramatsu
On Tue,  6 Aug 2019 18:00:12 +0800
Leo Yan  wrote:

> This small patch set is to add support for function error injection;
> this can be used to eanble more advanced debugging feature, e.g.
> CONFIG_BPF_KPROBE_OVERRIDE.
> 
> The patch 01/03 is to consolidate the function definition which can be
> suared cross architectures, patches 02,03/03 are used for enabling
> function error injection on arm64 and arm architecture respectively.
> 
> I tested on arm64 platform Juno-r2 and one of my laptop with x86
> architecture with below steps; I don't test for Arm architecture so
> only pass compilation.
> 
> - Enable kernel configuration:
>   CONFIG_BPF_KPROBE_OVERRIDE
>   CONFIG_BTRFS_FS
>   CONFIG_BPF_EVENTS=y
>   CONFIG_KPROBES=y
>   CONFIG_KPROBE_EVENTS=y
>   CONFIG_BPF_KPROBE_OVERRIDE=y
> 
> - Build samples/bpf on with Debian rootFS:
>   # cd $kernel
>   # make headers_install
>   # make samples/bpf/ LLC=llc-7 CLANG=clang-7
> 
> - Run the sample tracex7:
>   # dd if=/dev/zero of=testfile.img bs=1M seek=1000 count=1
>   # DEVICE=$(losetup --show -f testfile.img)
>   # mkfs.btrfs -f $DEVICE
>   # ./tracex7 testfile.img
>   [ 1975.211781] BTRFS error (device (efault)): open_ctree failed
>   mount: /mnt/linux-kernel/linux-cs-dev/samples/bpf/tmpmnt: mount(2) system 
> call failed: Cannot allocate memory.
> 
> Changes from v1:
> * Consolidated the function definition into asm-generic header (Will);
> * Used APIs to access pt_regs elements (Will);
> * Fixed typos in the comments (Will).

This looks good to me.

Reviewed-by: Masami Hiramatsu 

Thank you!

> 
> 
> Leo Yan (3):
>   error-injection: Consolidate override function definition
>   arm64: Add support for function error injection
>   arm: Add support for function error injection
> 
>  arch/arm/Kconfig   |  1 +
>  arch/arm/include/asm/ptrace.h  |  5 +
>  arch/arm/lib/Makefile  |  2 ++
>  arch/arm/lib/error-inject.c| 19 +++
>  arch/arm64/Kconfig |  1 +
>  arch/arm64/include/asm/ptrace.h|  5 +
>  arch/arm64/lib/Makefile|  2 ++
>  arch/arm64/lib/error-inject.c  | 18 ++
>  arch/powerpc/include/asm/error-injection.h | 13 -
>  arch/x86/include/asm/error-injection.h | 13 -
>  include/asm-generic/error-injection.h  |  6 ++
>  include/linux/error-injection.h|  6 +++---
>  12 files changed, 62 insertions(+), 29 deletions(-)
>  create mode 100644 arch/arm/lib/error-inject.c
>  create mode 100644 arch/arm64/lib/error-inject.c
>  delete mode 100644 arch/powerpc/include/asm/error-injection.h
>  delete mode 100644 arch/x86/include/asm/error-injection.h
> 
> -- 
> 2.17.1
> 


-- 
Masami Hiramatsu 


Re: [PATCH] mm/kprobes: Add generic kprobe_fault_handler() fallback definition

2019-07-11 Thread Masami Hiramatsu
e changes. Hence choose to go with a macro in each header.
> 
> arch/arc/include/asm/kprobes.h:int kprobe_fault_handler(struct pt_regs *regs, 
> unsigned long cause);
> arch/arm/include/asm/kprobes.h:int kprobe_fault_handler(struct pt_regs *regs, 
> unsigned int fsr);
> arch/arm64/include/asm/kprobes.h:int kprobe_fault_handler(struct pt_regs 
> *regs, unsigned int fsr);
> arch/ia64/include/asm/kprobes.h:extern int kprobe_fault_handler(struct 
> pt_regs *regs, int trapnr);
> arch/powerpc/include/asm/kprobes.h:extern int kprobe_fault_handler(struct 
> pt_regs *regs, int trapnr);
> arch/s390/include/asm/kprobes.h:int kprobe_fault_handler(struct pt_regs 
> *regs, int trapnr);
> arch/sh/include/asm/kprobes.h:extern int kprobe_fault_handler(struct pt_regs 
> *regs, int trapnr);
> arch/sparc/include/asm/kprobes.h:int kprobe_fault_handler(struct pt_regs 
> *regs, int trapnr);
> arch/x86/include/asm/kprobes.h:extern int kprobe_fault_handler(struct pt_regs 
> *regs, int trapnr);

OK, in that case, original commit is wrong way. it should be reverted and
should introduce something like below


/* Returns true if arch should call kprobes_fault_handler() */
static nokprobe_inline bool is_kprobe_page_fault(struct pt_regs *regs)
{
if (!kprobes_built_in())
return false;
if (user_mode(regs))
return false;
/*
 * To be potentially processing a kprobe fault and to be allowed
 * to call kprobe_running(), we have to be non-preemptible.
 */
if (preemptible())
return false;
if (!kprobe_running())
return false;
return true;
}

Since it silently casts the type of trapnr, which is strongly depends
on architecture.

> >> While here wrap kprobe_page_fault() in CONFIG_KPROBES. This enables stud
> >> definitions for generic kporbe_fault_handler() and kprobes_built_in() can
> >> just be dropped. Only on x86 it needs to be added back locally as it gets
> >> used in a !CONFIG_KPROBES function do_general_protection().
> > 
> > If you want to remove kprobes_built_in(), you should replace it with
> > IS_ENABLED(CONFIG_KPROBES), instead of this...
> 
> Apart from kprobes_built_in() the intent was to remove !CONFIG_KPROBES
> stub for kprobe_fault_handler() as well which required making generic
> kprobe_page_fault() to be empty in such case.

No, I meant that "IS_ENABLED(CONFIG_KPROBES)" is generic and is equal to
what kprobes_built_in() does.

Thank you,

-- 
Masami Hiramatsu 


Re: [PATCH] mm/kprobes: Add generic kprobe_fault_handler() fallback definition

2019-07-05 Thread Masami Hiramatsu
Hi Anshuman,

On Fri,  5 Jul 2019 11:00:29 +0530
Anshuman Khandual  wrote:

> Architectures like parisc enable CONFIG_KROBES without having a definition
> for kprobe_fault_handler() which results in a build failure.

Hmm, as far as I can see, kprobe_fault_handler() is closed inside each arch
specific code. The reason why include/linux/kprobes.h defines
dummy inline function is only for !CONFIG_KPROBES case.

> Arch needs to
> provide kprobe_fault_handler() as it is platform specific and cannot have
> a generic working alternative. But in the event when platform lacks such a
> definition there needs to be a fallback.

Wait, indeed that each arch need to implement it, but that is for calling
kprobe->fault_handler() as user expected.
Hmm, why not fixing those architecture implementations?

> This adds a stub kprobe_fault_handler() definition which not only prevents
> a build failure but also makes sure that kprobe_page_fault() if called will
> always return negative in absence of a sane platform specific alternative.

I don't like introducing this complicated macro only for avoiding (not fixing)
build error. To fix that, kprobes on parisc should implement 
kprobe_fault_handler
correctly (and call kprobe->fault_handler).

BTW, even if you need such generic stub, please use a weak function instead
of macros for every arch headers.

> While here wrap kprobe_page_fault() in CONFIG_KPROBES. This enables stud
> definitions for generic kporbe_fault_handler() and kprobes_built_in() can
> just be dropped. Only on x86 it needs to be added back locally as it gets
> used in a !CONFIG_KPROBES function do_general_protection().

If you want to remove kprobes_built_in(), you should replace it with
IS_ENABLED(CONFIG_KPROBES), instead of this...

Thank you,

> 
> Cc: Vineet Gupta 
> Cc: Russell King 
> Cc: Catalin Marinas 
> Cc: Will Deacon 
> Cc: Tony Luck 
> Cc: Fenghua Yu 
> Cc: Ralf Baechle 
> Cc: Paul Burton 
> Cc: James Hogan 
> Cc: Benjamin Herrenschmidt 
> Cc: Paul Mackerras 
> Cc: Michael Ellerman 
> Cc: Heiko Carstens 
> Cc: Vasily Gorbik 
> Cc: Christian Borntraeger 
> Cc: Yoshinori Sato 
> Cc: Rich Felker 
> Cc: "David S. Miller" 
> Cc: Thomas Gleixner 
> Cc: Ingo Molnar 
> Cc: Borislav Petkov 
> Cc: "H. Peter Anvin" 
> Cc: "Naveen N. Rao" 
> Cc: Anil S Keshavamurthy 
> Cc: Masami Hiramatsu 
> Cc: Allison Randal 
> Cc: Greg Kroah-Hartman 
> Cc: Enrico Weigelt 
> Cc: Richard Fontana 
> Cc: Kate Stewart 
> Cc: Mark Rutland 
> Cc: Andrew Morton 
> Cc: Guenter Roeck 
> Cc: x...@kernel.org
> Cc: linux-snps-...@lists.infradead.org
> Cc: linux-ker...@vger.kernel.org
> Cc: linux-arm-ker...@lists.infradead.org
> Cc: linux-i...@vger.kernel.org
> Cc: linux-m...@vger.kernel.org
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: linux-s...@vger.kernel.org
> Cc: linux...@vger.kernel.org
> Cc: sparcli...@vger.kernel.org
> 
> Signed-off-by: Anshuman Khandual 
> ---
>  arch/arc/include/asm/kprobes.h |  1 +
>  arch/arm/include/asm/kprobes.h |  1 +
>  arch/arm64/include/asm/kprobes.h   |  1 +
>  arch/ia64/include/asm/kprobes.h|  1 +
>  arch/mips/include/asm/kprobes.h|  1 +
>  arch/powerpc/include/asm/kprobes.h |  1 +
>  arch/s390/include/asm/kprobes.h|  1 +
>  arch/sh/include/asm/kprobes.h  |  1 +
>  arch/sparc/include/asm/kprobes.h   |  1 +
>  arch/x86/include/asm/kprobes.h |  6 ++
>  include/linux/kprobes.h| 32 ++
>  11 files changed, 34 insertions(+), 13 deletions(-)
> 
> diff --git a/arch/arc/include/asm/kprobes.h b/arch/arc/include/asm/kprobes.h
> index 2134721dce44..ee8efe256675 100644
> --- a/arch/arc/include/asm/kprobes.h
> +++ b/arch/arc/include/asm/kprobes.h
> @@ -45,6 +45,7 @@ struct kprobe_ctlblk {
>   struct prev_kprobe prev_kprobe;
>  };
>  
> +#define kprobe_fault_handler kprobe_fault_handler
>  int kprobe_fault_handler(struct pt_regs *regs, unsigned long cause);
>  void kretprobe_trampoline(void);
>  void trap_is_kprobe(unsigned long address, struct pt_regs *regs);
> diff --git a/arch/arm/include/asm/kprobes.h b/arch/arm/include/asm/kprobes.h
> index 213607a1f45c..660f877b989f 100644
> --- a/arch/arm/include/asm/kprobes.h
> +++ b/arch/arm/include/asm/kprobes.h
> @@ -38,6 +38,7 @@ struct kprobe_ctlblk {
>   struct prev_kprobe prev_kprobe;
>  };
>  
> +#define kprobe_fault_handler kprobe_fault_handler
>  void arch_remove_kprobe(struct kprobe *);
>  int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
>  int kprobe_exceptions_notify(struct notifier_block *self,
> diff --git a/arch/arm64/include/asm/kprobes.h 
> b/arch/arm64/include/asm/kprobes.h
> index 97e511d645a2..667773f75616 100644
> --- a/

Re: [PATCH v2 7/7] powerpc/kprobes: Allow probing on any ftrace address

2019-06-27 Thread Masami Hiramatsu
On Thu, 27 Jun 2019 16:53:55 +0530
"Naveen N. Rao"  wrote:

> With KPROBES_ON_FTRACE, kprobe is allowed to be inserted on instructions
> that branch to _mcount (referred to as ftrace location). With
> -mprofile-kernel, we now include the preceding 'mflr r0' as being part
> of the ftrace location.
> 
> However, by default, probing on an instruction that is not actually the
> branch to _mcount() is prohibited, as that is considered to not be at an
> instruction boundary. This is not the case on powerpc, so allow the same
> by overriding arch_check_ftrace_location()
> 
> In addition, we update kprobe_ftrace_handler() to detect this scenarios
> and to pass the proper nip to the pre and post probe handlers.
> 
> Signed-off-by: Naveen N. Rao 

Looks good to me.

Reviewed-by: Masami Hiramatsu 

Thank you!

> ---
>  arch/powerpc/kernel/kprobes-ftrace.c | 32 +++-
>  1 file changed, 31 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/kernel/kprobes-ftrace.c 
> b/arch/powerpc/kernel/kprobes-ftrace.c
> index 972cb28174b2..23c840748183 100644
> --- a/arch/powerpc/kernel/kprobes-ftrace.c
> +++ b/arch/powerpc/kernel/kprobes-ftrace.c
> @@ -12,15 +12,35 @@
>  #include 
>  #include 
>  
> +/*
> + * With -mprofile-kernel, we patch two instructions -- the branch to _mcount
> + * as well as the preceding 'mflr r0'. Both these instructions are claimed
> + * by ftrace and we should allow probing on either instruction.
> + */
> +int arch_check_ftrace_location(struct kprobe *p)
> +{
> + if (ftrace_location((unsigned long)p->addr))
> + p->flags |= KPROBE_FLAG_FTRACE;
> + return 0;
> +}
> +
>  /* Ftrace callback handler for kprobes */
>  void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,
>  struct ftrace_ops *ops, struct pt_regs *regs)
>  {
>   struct kprobe *p;
> + int mflr_kprobe = 0;
>   struct kprobe_ctlblk *kcb;
>  
>   p = get_kprobe((kprobe_opcode_t *)nip);
> - if (unlikely(!p) || kprobe_disabled(p))
> + if (!p) {
> + p = get_kprobe((kprobe_opcode_t *)(nip - MCOUNT_INSN_SIZE));
> + if (unlikely(!p))
> + return;
> + mflr_kprobe = 1;
> + }
> +
> + if (kprobe_disabled(p))
>   return;
>  
>   kcb = get_kprobe_ctlblk();
> @@ -33,6 +53,9 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long 
> parent_nip,
>*/
>   regs->nip -= MCOUNT_INSN_SIZE;
>  
> + if (mflr_kprobe)
> + regs->nip -= MCOUNT_INSN_SIZE;
> +
>   __this_cpu_write(current_kprobe, p);
>   kcb->kprobe_status = KPROBE_HIT_ACTIVE;
>   if (!p->pre_handler || !p->pre_handler(p, regs)) {
> @@ -45,6 +68,8 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long 
> parent_nip,
>   kcb->kprobe_status = KPROBE_HIT_SSDONE;
>   p->post_handler(p, regs, 0);
>   }
> + if (mflr_kprobe)
> + regs->nip += MCOUNT_INSN_SIZE;
>   }
>   /*
>* If pre_handler returns !0, it changes regs->nip. We have to
> @@ -57,6 +82,11 @@ NOKPROBE_SYMBOL(kprobe_ftrace_handler);
>  
>  int arch_prepare_kprobe_ftrace(struct kprobe *p)
>  {
> + if ((unsigned long)p->addr & 0x03) {
> + pr_err("Attempt to register kprobe at an unaligned address\n");
> + return -EILSEQ;
> + }
> +
>   p->ainsn.insn = NULL;
>   p->ainsn.boostable = -1;
>   return 0;
> -- 
> 2.22.0
> 


-- 
Masami Hiramatsu 


Re: [PATCH 7/7] powerpc/kprobes: Allow probing on any ftrace address

2019-06-21 Thread Masami Hiramatsu
On Tue, 18 Jun 2019 20:17:06 +0530
"Naveen N. Rao"  wrote:

> With KPROBES_ON_FTRACE, kprobe is allowed to be inserted on instructions
> that branch to _mcount (referred to as ftrace location). With
> -mprofile-kernel, we now include the preceding 'mflr r0' as being part
> of the ftrace location.
> 
> However, by default, probing on an instruction that is not actually the
> branch to _mcount() is prohibited, as that is considered to not be at an
> instruction boundary. This is not the case on powerpc, so allow the same
> by overriding arch_check_ftrace_location()
> 
> In addition, we update kprobe_ftrace_handler() to detect this scenarios
> and to pass the proper nip to the pre and post probe handlers.
> 
> Signed-off-by: Naveen N. Rao 
> ---
>  arch/powerpc/kernel/kprobes-ftrace.c | 30 
>  1 file changed, 30 insertions(+)
> 
> diff --git a/arch/powerpc/kernel/kprobes-ftrace.c 
> b/arch/powerpc/kernel/kprobes-ftrace.c
> index 972cb28174b2..6a0bd3c16cb6 100644
> --- a/arch/powerpc/kernel/kprobes-ftrace.c
> +++ b/arch/powerpc/kernel/kprobes-ftrace.c
> @@ -12,14 +12,34 @@
>  #include 
>  #include 
>  
> +/*
> + * With -mprofile-kernel, we patch two instructions -- the branch to _mcount
> + * as well as the preceding 'mflr r0'. Both these instructions are claimed
> + * by ftrace and we should allow probing on either instruction.
> + */
> +int arch_check_ftrace_location(struct kprobe *p)
> +{
> + if (ftrace_location((unsigned long)p->addr))
> + p->flags |= KPROBE_FLAG_FTRACE;
> + return 0;
> +}
> +
>  /* Ftrace callback handler for kprobes */
>  void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,
>  struct ftrace_ops *ops, struct pt_regs *regs)
>  {
>   struct kprobe *p;
> + int mflr_kprobe = 0;
>   struct kprobe_ctlblk *kcb;
>  
>   p = get_kprobe((kprobe_opcode_t *)nip);
> + if (unlikely(!p)) {

Hmm, is this really unlikely? If we put a kprobe on the second instruction 
address,
we will see p == NULL always.

> + p = get_kprobe((kprobe_opcode_t *)(nip - MCOUNT_INSN_SIZE));
> + if (!p)

Here will be unlikely, because we can not find kprobe at both of nip and
nip - MCOUNT_INSN_SIZE.

> + return;
> + mflr_kprobe = 1;
> + }
> +
>   if (unlikely(!p) || kprobe_disabled(p))

"unlikely(!p)" is not needed here.

Thank you,

>   return;
>  
> @@ -33,6 +53,9 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long 
> parent_nip,
>*/
>   regs->nip -= MCOUNT_INSN_SIZE;
>  
> + if (mflr_kprobe)
> + regs->nip -= MCOUNT_INSN_SIZE;
> +
>   __this_cpu_write(current_kprobe, p);
>   kcb->kprobe_status = KPROBE_HIT_ACTIVE;
>   if (!p->pre_handler || !p->pre_handler(p, regs)) {
> @@ -45,6 +68,8 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long 
> parent_nip,
>   kcb->kprobe_status = KPROBE_HIT_SSDONE;
>   p->post_handler(p, regs, 0);
>   }
> + if (mflr_kprobe)
> + regs->nip += MCOUNT_INSN_SIZE;
>   }
>   /*
>* If pre_handler returns !0, it changes regs->nip. We have to
> @@ -57,6 +82,11 @@ NOKPROBE_SYMBOL(kprobe_ftrace_handler);
>  
>  int arch_prepare_kprobe_ftrace(struct kprobe *p)
>  {
> + if ((unsigned long)p->addr & 0x03) {
> + printk("Attempt to register kprobe at an unaligned address\n");
> + return -EILSEQ;
> + }
> +
>   p->ainsn.insn = NULL;
>   p->ainsn.boostable = -1;
>   return 0;
> -- 
> 2.22.0
> 


-- 
Masami Hiramatsu 


Re: [PATCH 6/7] kprobes/ftrace: Use ftrace_location() when [dis]arming probes

2019-06-21 Thread Masami Hiramatsu
On Tue, 18 Jun 2019 20:17:05 +0530
"Naveen N. Rao"  wrote:

> Ftrace location could include more than a single instruction in case of
> some architectures (powerpc64, for now). In this case, kprobe is
> permitted on any of those instructions, and uses ftrace infrastructure
> for functioning.
> 
> However, [dis]arm_kprobe_ftrace() uses the kprobe address when setting
> up ftrace filter IP. This won't work if the address points to any
> instruction apart from the one that has a branch to _mcount(). To
> resolve this, have [dis]arm_kprobe_ftrace() use ftrace_function() to
> identify the filter IP.

This looks good to me.

Acked-by: Masami Hiramatsu 

Thank you!

> 
> Signed-off-by: Naveen N. Rao 
> ---
>  kernel/kprobes.c | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> index 445337c107e0..282ee704e2d8 100644
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -978,10 +978,10 @@ static int prepare_kprobe(struct kprobe *p)
>  /* Caller must lock kprobe_mutex */
>  static int arm_kprobe_ftrace(struct kprobe *p)
>  {
> + unsigned long ftrace_ip = ftrace_location((unsigned long)p->addr);
>   int ret = 0;
>  
> - ret = ftrace_set_filter_ip(_ftrace_ops,
> -(unsigned long)p->addr, 0, 0);
> + ret = ftrace_set_filter_ip(_ftrace_ops, ftrace_ip, 0, 0);
>   if (ret) {
>   pr_debug("Failed to arm kprobe-ftrace at %pS (%d)\n",
>p->addr, ret);
> @@ -1005,13 +1005,14 @@ static int arm_kprobe_ftrace(struct kprobe *p)
>* non-empty filter_hash for IPMODIFY ops, we're safe from an accidental
>* empty filter_hash which would undesirably trace all functions.
>*/
> - ftrace_set_filter_ip(_ftrace_ops, (unsigned long)p->addr, 1, 0);
> + ftrace_set_filter_ip(_ftrace_ops, ftrace_ip, 1, 0);
>   return ret;
>  }
>  
>  /* Caller must lock kprobe_mutex */
>  static int disarm_kprobe_ftrace(struct kprobe *p)
>  {
> + unsigned long ftrace_ip = ftrace_location((unsigned long)p->addr);
>   int ret = 0;
>  
>   if (kprobe_ftrace_enabled == 1) {
> @@ -1022,8 +1023,7 @@ static int disarm_kprobe_ftrace(struct kprobe *p)
>  
>   kprobe_ftrace_enabled--;
>  
> - ret = ftrace_set_filter_ip(_ftrace_ops,
> -(unsigned long)p->addr, 1, 0);
> + ret = ftrace_set_filter_ip(_ftrace_ops, ftrace_ip, 1, 0);
>   WARN_ONCE(ret < 0, "Failed to disarm kprobe-ftrace at %pS (%d)\n",
> p->addr, ret);
>   return ret;
> -- 
> 2.22.0
> 


-- 
Masami Hiramatsu 


[PATCH -tip v6 24/27] bpf: error-inject: kprobes: Clear current_kprobe and enable preempt in kprobe

2018-06-19 Thread Masami Hiramatsu
Clear current_kprobe and enable preemption in kprobe
even if pre_handler returns !0.

This simplifies function override using kprobes.

Jprobe used to require to keep the preemption disabled and
keep current_kprobe until it returned to original function
entry. For this reason kprobe_int3_handler() and similar
arch dependent kprobe handers checks pre_handler result
and exit without enabling preemption if the result is !0.

After removing the jprobe, Kprobes does not need to
keep preempt disabled even if user handler returns !0
anymore.

But since the function override handler in error-inject
and bpf is also returns !0 if it overrides a function,
to balancing the preempt count, it enables preemption
and reset current kprobe by itself.

That is a bad design that is very buggy. This fixes
such unbalanced preempt-count and current_kprobes setting
in kprobes, bpf and error-inject.

Note: for powerpc and x86, this removes all preempt_disable
from kprobe_ftrace_handler because ftrace callbacks are
called under preempt disabled.

Signed-off-by: Masami Hiramatsu 
Acked-by: "Naveen N. Rao" 
Cc: Vineet Gupta 
Cc: Russell King 
Cc: Catalin Marinas 
Cc: Will Deacon 
Cc: Tony Luck 
Cc: Fenghua Yu 
Cc: Ralf Baechle 
Cc: James Hogan 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Michael Ellerman 
Cc: Martin Schwidefsky 
Cc: Heiko Carstens 
Cc: Yoshinori Sato 
Cc: Rich Felker 
Cc: "David S. Miller" 
Cc: Josef Bacik 
Cc: Alexei Starovoitov 
Cc: x...@kernel.org
Cc: linux-snps-...@lists.infradead.org
Cc: linux-ker...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-i...@vger.kernel.org
Cc: linux-m...@linux-mips.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-s...@vger.kernel.org
Cc: linux...@vger.kernel.org
Cc: sparcli...@vger.kernel.org
---
 Changes in v6:
  - Simplify kprobe_ftrace_handler change on x86 and powerpc code.
 Changes in v5:
  - Fix kprobe_ftrace_handler in arch/powerpc too.
---
 arch/arc/kernel/kprobes.c|5 +++--
 arch/arm/probes/kprobes/core.c   |   10 +-
 arch/arm64/kernel/probes/kprobes.c   |   10 +-
 arch/ia64/kernel/kprobes.c   |   13 -
 arch/mips/kernel/kprobes.c   |4 ++--
 arch/powerpc/kernel/kprobes-ftrace.c |   19 ++-
 arch/powerpc/kernel/kprobes.c|7 +--
 arch/s390/kernel/kprobes.c   |7 ---
 arch/sh/kernel/kprobes.c |7 ---
 arch/sparc/kernel/kprobes.c  |7 ---
 arch/x86/kernel/kprobes/core.c   |4 
 arch/x86/kernel/kprobes/ftrace.c |9 +++--
 kernel/fail_function.c   |3 ---
 kernel/trace/trace_kprobe.c  |   11 +++
 14 files changed, 52 insertions(+), 64 deletions(-)

diff --git a/arch/arc/kernel/kprobes.c b/arch/arc/kernel/kprobes.c
index 465365696c91..df35d4c0b0b8 100644
--- a/arch/arc/kernel/kprobes.c
+++ b/arch/arc/kernel/kprobes.c
@@ -231,6 +231,9 @@ int __kprobes arc_kprobe_handler(unsigned long addr, struct 
pt_regs *regs)
if (!p->pre_handler || !p->pre_handler(p, regs)) {
setup_singlestep(p, regs);
kcb->kprobe_status = KPROBE_HIT_SS;
+   } else {
+   reset_current_kprobe();
+   preempt_enable_no_resched();
}
 
return 1;
@@ -442,9 +445,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe 
*p,
kretprobe_assert(ri, orig_ret_address, trampoline_address);
regs->ret = orig_ret_address;
 
-   reset_current_kprobe();
kretprobe_hash_unlock(current, );
-   preempt_enable_no_resched();
 
hlist_for_each_entry_safe(ri, tmp, _rp, hlist) {
hlist_del(>hlist);
diff --git a/arch/arm/probes/kprobes/core.c b/arch/arm/probes/kprobes/core.c
index 3192350f389d..8d37601fdb20 100644
--- a/arch/arm/probes/kprobes/core.c
+++ b/arch/arm/probes/kprobes/core.c
@@ -300,10 +300,10 @@ void __kprobes kprobe_handler(struct pt_regs *regs)
 
/*
 * If we have no pre-handler or it returned 0, we
-* continue with normal processing.  If we have a
-* pre-handler and it returned non-zero, it prepped
-* for calling the break_handler below on re-entry,
-* so get out doing nothing more here.
+* continue with normal processing. If we have a
+* pre-handler and it returned non-zero, it will
+* modify the execution path and no need to single
+* stepping. Let's just reset current kprobe and exit.
 */
if (!p->pre_handler || !p->pre_handler(p, regs)) {
kcb->kprobe_status = KPROBE_HIT_SS;
@@ -312,8 +312,8 @@ void _

[PATCH -tip v6 18/27] powerpc/kprobes: Don't call the ->break_handler() in powerpc kprobes code

2018-06-19 Thread Masami Hiramatsu
Don't call the ->break_handler() from the powerpc kprobes code,
because it was only used by jprobes which got removed.

This also removes skip_singlestep() and embeds it in the
caller, kprobe_ftrace_handler(), which simplifies regs->nip
operation around there.

Signed-off-by: Masami Hiramatsu 
Acked-by: "Naveen N. Rao" 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Michael Ellerman 
Cc: linuxppc-dev@lists.ozlabs.org
---
 Changes in v6
   - Fix patch description
   - Move post handler emulation into kprobe_ftrace_handler().
---
 arch/powerpc/include/asm/kprobes.h   |   10 ---
 arch/powerpc/kernel/kprobes-ftrace.c |   46 +-
 arch/powerpc/kernel/kprobes.c|   31 ---
 3 files changed, 23 insertions(+), 64 deletions(-)

diff --git a/arch/powerpc/include/asm/kprobes.h 
b/arch/powerpc/include/asm/kprobes.h
index 674036db558b..785c464b6588 100644
--- a/arch/powerpc/include/asm/kprobes.h
+++ b/arch/powerpc/include/asm/kprobes.h
@@ -102,16 +102,6 @@ extern int kprobe_exceptions_notify(struct notifier_block 
*self,
 extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
 extern int kprobe_handler(struct pt_regs *regs);
 extern int kprobe_post_handler(struct pt_regs *regs);
-#ifdef CONFIG_KPROBES_ON_FTRACE
-extern int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
-  struct kprobe_ctlblk *kcb);
-#else
-static inline int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
- struct kprobe_ctlblk *kcb)
-{
-   return 0;
-}
-#endif
 #else
 static inline int kprobe_handler(struct pt_regs *regs) { return 0; }
 static inline int kprobe_post_handler(struct pt_regs *regs) { return 0; }
diff --git a/arch/powerpc/kernel/kprobes-ftrace.c 
b/arch/powerpc/kernel/kprobes-ftrace.c
index 1b316331c2d9..070d1d862444 100644
--- a/arch/powerpc/kernel/kprobes-ftrace.c
+++ b/arch/powerpc/kernel/kprobes-ftrace.c
@@ -25,35 +25,6 @@
 #include 
 #include 
 
-static nokprobe_inline
-int __skip_singlestep(struct kprobe *p, struct pt_regs *regs,
- struct kprobe_ctlblk *kcb, unsigned long orig_nip)
-{
-   /*
-* Emulate singlestep (and also recover regs->nip)
-* as if there is a nop
-*/
-   regs->nip = (unsigned long)p->addr + MCOUNT_INSN_SIZE;
-   if (unlikely(p->post_handler)) {
-   kcb->kprobe_status = KPROBE_HIT_SSDONE;
-   p->post_handler(p, regs, 0);
-   }
-   __this_cpu_write(current_kprobe, NULL);
-   if (orig_nip)
-   regs->nip = orig_nip;
-   return 1;
-}
-
-int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
-   struct kprobe_ctlblk *kcb)
-{
-   if (kprobe_ftrace(p))
-   return __skip_singlestep(p, regs, kcb, 0);
-   else
-   return 0;
-}
-NOKPROBE_SYMBOL(skip_singlestep);
-
 /* Ftrace callback handler for kprobes */
 void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,
   struct ftrace_ops *ops, struct pt_regs *regs)
@@ -71,8 +42,6 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long 
parent_nip,
if (kprobe_running()) {
kprobes_inc_nmissed_count(p);
} else {
-   unsigned long orig_nip = regs->nip;
-
/*
 * On powerpc, NIP is *before* this instruction for the
 * pre handler
@@ -81,9 +50,18 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long 
parent_nip,
 
__this_cpu_write(current_kprobe, p);
kcb->kprobe_status = KPROBE_HIT_ACTIVE;
-   if (!p->pre_handler || !p->pre_handler(p, regs))
-   __skip_singlestep(p, regs, kcb, orig_nip);
-   else {
+   if (!p->pre_handler || !p->pre_handler(p, regs)) {
+   /*
+* Emulate singlestep (and also recover regs->nip)
+* as if there is a nop
+*/
+   regs->nip += MCOUNT_INSN_SIZE;
+   if (unlikely(p->post_handler)) {
+   kcb->kprobe_status = KPROBE_HIT_SSDONE;
+   p->post_handler(p, regs, 0);
+   }
+   __this_cpu_write(current_kprobe, NULL);
+   } else {
/*
 * If pre_handler returns !0, it sets regs->nip and
 * resets current kprobe. In this case, we should not
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 600678fce0a8..f06747e2e70d 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -317,25 +317,17 @@ int kprobe_handler(struct pt_regs *regs)
}
prepare_sing

[PATCH -tip v6 07/27] powerpc/kprobes: Remove jprobe powerpc implementation

2018-06-19 Thread Masami Hiramatsu
Remove arch dependent setjump/longjump functions
and unused fields in kprobe_ctlblk for jprobes
from arch/powerpc. This also reverts commits
related __is_active_jprobe() function.

Signed-off-by: Masami Hiramatsu 
Acked-by: "Naveen N. Rao" 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Michael Ellerman 
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/include/asm/kprobes.h |2 -
 arch/powerpc/kernel/kprobes-ftrace.c   |   15 ---
 arch/powerpc/kernel/kprobes.c  |   54 
 arch/powerpc/kernel/trace/ftrace_64_mprofile.S |   39 ++---
 4 files changed, 5 insertions(+), 105 deletions(-)

diff --git a/arch/powerpc/include/asm/kprobes.h 
b/arch/powerpc/include/asm/kprobes.h
index 9f3be5c8a4a3..674036db558b 100644
--- a/arch/powerpc/include/asm/kprobes.h
+++ b/arch/powerpc/include/asm/kprobes.h
@@ -88,7 +88,6 @@ struct prev_kprobe {
 struct kprobe_ctlblk {
unsigned long kprobe_status;
unsigned long kprobe_saved_msr;
-   struct pt_regs jprobe_saved_regs;
struct prev_kprobe prev_kprobe;
 };
 
@@ -104,7 +103,6 @@ extern int kprobe_fault_handler(struct pt_regs *regs, int 
trapnr);
 extern int kprobe_handler(struct pt_regs *regs);
 extern int kprobe_post_handler(struct pt_regs *regs);
 #ifdef CONFIG_KPROBES_ON_FTRACE
-extern int __is_active_jprobe(unsigned long addr);
 extern int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
   struct kprobe_ctlblk *kcb);
 #else
diff --git a/arch/powerpc/kernel/kprobes-ftrace.c 
b/arch/powerpc/kernel/kprobes-ftrace.c
index 7a1f99f1b47f..1b316331c2d9 100644
--- a/arch/powerpc/kernel/kprobes-ftrace.c
+++ b/arch/powerpc/kernel/kprobes-ftrace.c
@@ -25,21 +25,6 @@
 #include 
 #include 
 
-/*
- * This is called from ftrace code after invoking registered handlers to
- * disambiguate regs->nip changes done by jprobes and livepatch. We check if
- * there is an active jprobe at the provided address (mcount location).
- */
-int __is_active_jprobe(unsigned long addr)
-{
-   if (!preemptible()) {
-   struct kprobe *p = raw_cpu_read(current_kprobe);
-   return (p && (unsigned long)p->addr == addr) ? 1 : 0;
-   }
-
-   return 0;
-}
-
 static nokprobe_inline
 int __skip_singlestep(struct kprobe *p, struct pt_regs *regs,
  struct kprobe_ctlblk *kcb, unsigned long orig_nip)
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index e4c5bf33970b..600678fce0a8 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -611,60 +611,6 @@ unsigned long arch_deref_entry_point(void *entry)
 }
 NOKPROBE_SYMBOL(arch_deref_entry_point);
 
-int 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();
-
-   memcpy(>jprobe_saved_regs, regs, sizeof(struct pt_regs));
-
-   /* setup return addr to the jprobe handler routine */
-   regs->nip = arch_deref_entry_point(jp->entry);
-#ifdef PPC64_ELF_ABI_v2
-   regs->gpr[12] = (unsigned long)jp->entry;
-#elif defined(PPC64_ELF_ABI_v1)
-   regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
-#endif
-
-   /*
-* jprobes use jprobe_return() which skips the normal return
-* path of the function, and this messes up the accounting of the
-* function graph tracer.
-*
-* Pause function graph tracing while performing the jprobe function.
-*/
-   pause_graph_tracing();
-
-   return 1;
-}
-NOKPROBE_SYMBOL(setjmp_pre_handler);
-
-void __used jprobe_return(void)
-{
-   asm volatile("jprobe_return_trap:\n"
-"trap\n"
-::: "memory");
-}
-NOKPROBE_SYMBOL(jprobe_return);
-
-int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
-{
-   struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
-
-   if (regs->nip != ppc_kallsyms_lookup_name("jprobe_return_trap")) {
-   pr_debug("longjmp_break_handler NIP (0x%lx) does not match 
jprobe_return_trap (0x%lx)\n",
-   regs->nip, 
ppc_kallsyms_lookup_name("jprobe_return_trap"));
-   return 0;
-   }
-
-   memcpy(regs, >jprobe_saved_regs, sizeof(struct pt_regs));
-   /* It's OK to start function graph tracing again */
-   unpause_graph_tracing();
-   preempt_enable_no_resched();
-   return 1;
-}
-NOKPROBE_SYMBOL(longjmp_break_handler);
-
 static struct kprobe trampoline_p = {
.addr = (kprobe_opcode_t *) _trampoline,
.pre_handler = trampoline_probe_handler
diff --git a/arch/powerpc/kernel/trace/ftrace_64_mprofile.S 
b/arch/powerpc/kernel/trace/ftrace_64_mprofile.S
index 9a5b5a513604..32476a6e4e9c 100644
--- a/arch/powerpc/kernel/t

Re: [RFC PATCH -tip v5 18/27] powerpc/kprobes: Don't call the ->break_handler() in arm kprobes code

2018-06-07 Thread Masami Hiramatsu
On Thu, 07 Jun 2018 22:07:26 +0530
"Naveen N. Rao"  wrote:

> Masami Hiramatsu wrote:
> > On Thu, 07 Jun 2018 17:07:00 +0530
> > "Naveen N. Rao"  wrote:
> > 
> >> Masami Hiramatsu wrote:
> >> > Don't call the ->break_handler() from the arm kprobes code,
> >>^^^ powerpc
> >> 
> >> > because it was only used by jprobes which got removed.
> >> > 
> >> > This also makes skip_singlestep() a static function since
> >> > only ftrace-kprobe.c is using this function.
> >> > 
> >> > Signed-off-by: Masami Hiramatsu 
> >> > Cc: Benjamin Herrenschmidt 
> >> > Cc: Paul Mackerras 
> >> > Cc: Michael Ellerman 
> >> > Cc: "Naveen N. Rao" 
> >> > Cc: linuxppc-dev@lists.ozlabs.org
> >> > ---
> >> >  arch/powerpc/include/asm/kprobes.h   |   10 --
> >> >  arch/powerpc/kernel/kprobes-ftrace.c |   16 +++-
> >> >  arch/powerpc/kernel/kprobes.c|   31 
> >> > +++++++----
> >> >  3 files changed, 14 insertions(+), 43 deletions(-)
> >> 
> >> With 2 small comments...
> > 
> > 2 ? or 1 ?
> 
> Two, with one in the commit log above :)

Oops, sorry I missed it. yeah, the comment above is my mistake. I'll fix it.

Thanks!


-- 
Masami Hiramatsu 


Re: [RFC PATCH -tip v5 18/27] powerpc/kprobes: Don't call the ->break_handler() in arm kprobes code

2018-06-07 Thread Masami Hiramatsu
On Thu, 07 Jun 2018 17:07:00 +0530
"Naveen N. Rao"  wrote:

> Masami Hiramatsu wrote:
> > Don't call the ->break_handler() from the arm kprobes code,
>   ^^^ powerpc
> 
> > because it was only used by jprobes which got removed.
> > 
> > This also makes skip_singlestep() a static function since
> > only ftrace-kprobe.c is using this function.
> > 
> > Signed-off-by: Masami Hiramatsu 
> > Cc: Benjamin Herrenschmidt 
> > Cc: Paul Mackerras 
> > Cc: Michael Ellerman 
> > Cc: "Naveen N. Rao" 
> > Cc: linuxppc-dev@lists.ozlabs.org
> > ---
> >  arch/powerpc/include/asm/kprobes.h   |   10 --
> >  arch/powerpc/kernel/kprobes-ftrace.c |   16 +++-
> >  arch/powerpc/kernel/kprobes.c|   31 +++
> >  3 files changed, 14 insertions(+), 43 deletions(-)
> 
> With 2 small comments...

2 ? or 1 ?

> Acked-by: Naveen N. Rao 
> 
> - Naveen
> 
> > 
> > diff --git a/arch/powerpc/include/asm/kprobes.h 
> > b/arch/powerpc/include/asm/kprobes.h
> > index 674036db558b..785c464b6588 100644
> > --- a/arch/powerpc/include/asm/kprobes.h
> > +++ b/arch/powerpc/include/asm/kprobes.h
> > @@ -102,16 +102,6 @@ extern int kprobe_exceptions_notify(struct 
> > notifier_block *self,
> >  extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
> >  extern int kprobe_handler(struct pt_regs *regs);
> >  extern int kprobe_post_handler(struct pt_regs *regs);
> > -#ifdef CONFIG_KPROBES_ON_FTRACE
> > -extern int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
> > -  struct kprobe_ctlblk *kcb);
> > -#else
> > -static inline int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
> > - struct kprobe_ctlblk *kcb)
> > -{
> > -   return 0;
> > -}
> > -#endif
> >  #else
> >  static inline int kprobe_handler(struct pt_regs *regs) { return 0; }
> >  static inline int kprobe_post_handler(struct pt_regs *regs) { return 0; }
> > diff --git a/arch/powerpc/kernel/kprobes-ftrace.c 
> > b/arch/powerpc/kernel/kprobes-ftrace.c
> > index 1b316331c2d9..3869b0e5d5c7 100644
> > --- a/arch/powerpc/kernel/kprobes-ftrace.c
> > +++ b/arch/powerpc/kernel/kprobes-ftrace.c
> > @@ -26,8 +26,8 @@
> >  #include 
> > 
> >  static nokprobe_inline
> > -int __skip_singlestep(struct kprobe *p, struct pt_regs *regs,
> > - struct kprobe_ctlblk *kcb, unsigned long orig_nip)
> > +int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
> > +   struct kprobe_ctlblk *kcb, unsigned long orig_nip)
> >  {
> > /*
> >  * Emulate singlestep (and also recover regs->nip)
> > @@ -44,16 +44,6 @@ int __skip_singlestep(struct kprobe *p, struct pt_regs 
> > *regs,
> > return 1;
> >  }
> > 
> > -int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
> > -   struct kprobe_ctlblk *kcb)
> > -{
> > -   if (kprobe_ftrace(p))
> > -   return __skip_singlestep(p, regs, kcb, 0);
> > -   else
> > -   return 0;
> > -}
> > -NOKPROBE_SYMBOL(skip_singlestep);
> > -
> >  /* Ftrace callback handler for kprobes */
> >  void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,
> >struct ftrace_ops *ops, struct pt_regs *regs)
> > @@ -82,7 +72,7 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned 
> > long parent_nip,
> > __this_cpu_write(current_kprobe, p);
> > kcb->kprobe_status = KPROBE_HIT_ACTIVE;
> > if (!p->pre_handler || !p->pre_handler(p, regs))
> > -   __skip_singlestep(p, regs, kcb, orig_nip);
> > +   skip_singlestep(p, regs, kcb, orig_nip);
> 
> We can probably get rid of skip_singlestep() completely along with 
> orig_nip since instructions are always 4 bytes on powerpc. So, the 
> changes we do to nip should help to recover the value automatically.

Good point! Yes, skip_singlestep() is no more exported, so we just consolidate
it into kprobe_ftrace_handler() for simplifying operation.

Thank you!
> 
> - Naveen
> 
> 


-- 
Masami Hiramatsu 


Re: [RFC PATCH -tip v5 07/27] powerpc/kprobes: Remove jprobe powerpc implementation

2018-06-07 Thread Masami Hiramatsu
On Thu, 07 Jun 2018 17:01:23 +0530
"Naveen N. Rao"  wrote:

> Masami Hiramatsu wrote:
> > Remove arch dependent setjump/longjump functions
> > and unused fields in kprobe_ctlblk for jprobes
> > from arch/powerpc. This also reverts commits
> > related __is_active_jprobe() function.
> > 
> > Signed-off-by: Masami Hiramatsu 
> > 
> > Cc: Benjamin Herrenschmidt 
> > Cc: Paul Mackerras 
> > Cc: Michael Ellerman 
> > Cc: "Naveen N. Rao" 
> > Cc: linuxppc-dev@lists.ozlabs.org
> > ---
> >  arch/powerpc/include/asm/kprobes.h |2 -
> >  arch/powerpc/kernel/kprobes-ftrace.c   |   15 ---
> >  arch/powerpc/kernel/kprobes.c  |   54 
> > 
> >  arch/powerpc/kernel/trace/ftrace_64_mprofile.S |   39 ++---
> >  4 files changed, 5 insertions(+), 105 deletions(-)
> 
> LGTM.
> 
> Acked-by: Naveen N. Rao 

Thanks Naveen!

> 
> - Naveen
> 
> 


-- 
Masami Hiramatsu 


[RFC PATCH -tip v5 24/27] bpf: error-inject: kprobes: Clear current_kprobe and enable preempt in kprobe

2018-06-04 Thread Masami Hiramatsu
Clear current_kprobe and enable preemption in kprobe
even if pre_handler returns !0.

This simplifies function override using kprobes.

Jprobe used to require to keep the preemption disabled and
keep current_kprobe until it returned to original function
entry. For this reason kprobe_int3_handler() and similar
arch dependent kprobe handers checks pre_handler result
and exit without enabling preemption if the result is !0.

After removing the jprobe, Kprobes does not need to
keep preempt disabled even if user handler returns !0
anymore.

But since the function override handler in error-inject
and bpf is also returns !0 if it overrides a function,
to balancing the preempt count, it enables preemption
and reset current kprobe by itself.

That is a bad design that is very buggy. This fixes
such unbalanced preempt-count and current_kprobes setting
in kprobes, bpf and error-inject.

Note: for powerpc and x86, this removes all preempt_disable
from kprobe_ftrace_handler because ftrace callbacks are
called under preempt disabled.

Signed-off-by: Masami Hiramatsu 
Cc: Vineet Gupta 
Cc: Russell King 
Cc: Catalin Marinas 
Cc: Will Deacon 
Cc: Tony Luck 
Cc: Fenghua Yu 
Cc: Ralf Baechle 
Cc: James Hogan 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Michael Ellerman 
Cc: Martin Schwidefsky 
Cc: Heiko Carstens 
Cc: Yoshinori Sato 
Cc: Rich Felker 
Cc: "David S. Miller" 
Cc: "Naveen N. Rao" 
Cc: Josef Bacik 
Cc: Alexei Starovoitov 
Cc: x...@kernel.org
Cc: linux-snps-...@lists.infradead.org
Cc: linux-ker...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-i...@vger.kernel.org
Cc: linux-m...@linux-mips.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-s...@vger.kernel.org
Cc: linux...@vger.kernel.org
Cc: sparcli...@vger.kernel.org
---
 Changes in v5:
  - Fix kprobe_ftrace_handler in arch/powerpc too.
---
 arch/arc/kernel/kprobes.c|5 +++--
 arch/arm/probes/kprobes/core.c   |   10 +-
 arch/arm64/kernel/probes/kprobes.c   |   10 +-
 arch/ia64/kernel/kprobes.c   |   13 -
 arch/mips/kernel/kprobes.c   |4 ++--
 arch/powerpc/kernel/kprobes-ftrace.c |   15 ++-
 arch/powerpc/kernel/kprobes.c|7 +--
 arch/s390/kernel/kprobes.c   |7 ---
 arch/sh/kernel/kprobes.c |7 ---
 arch/sparc/kernel/kprobes.c  |7 ---
 arch/x86/kernel/kprobes/core.c   |4 
 arch/x86/kernel/kprobes/ftrace.c |   15 ---
 kernel/fail_function.c   |3 ---
 kernel/trace/trace_kprobe.c  |   11 +++
 14 files changed, 57 insertions(+), 61 deletions(-)

diff --git a/arch/arc/kernel/kprobes.c b/arch/arc/kernel/kprobes.c
index 465365696c91..df35d4c0b0b8 100644
--- a/arch/arc/kernel/kprobes.c
+++ b/arch/arc/kernel/kprobes.c
@@ -231,6 +231,9 @@ int __kprobes arc_kprobe_handler(unsigned long addr, struct 
pt_regs *regs)
if (!p->pre_handler || !p->pre_handler(p, regs)) {
setup_singlestep(p, regs);
kcb->kprobe_status = KPROBE_HIT_SS;
+   } else {
+   reset_current_kprobe();
+   preempt_enable_no_resched();
}
 
return 1;
@@ -442,9 +445,7 @@ static int __kprobes trampoline_probe_handler(struct kprobe 
*p,
kretprobe_assert(ri, orig_ret_address, trampoline_address);
regs->ret = orig_ret_address;
 
-   reset_current_kprobe();
kretprobe_hash_unlock(current, );
-   preempt_enable_no_resched();
 
hlist_for_each_entry_safe(ri, tmp, _rp, hlist) {
hlist_del(>hlist);
diff --git a/arch/arm/probes/kprobes/core.c b/arch/arm/probes/kprobes/core.c
index 3192350f389d..8d37601fdb20 100644
--- a/arch/arm/probes/kprobes/core.c
+++ b/arch/arm/probes/kprobes/core.c
@@ -300,10 +300,10 @@ void __kprobes kprobe_handler(struct pt_regs *regs)
 
/*
 * If we have no pre-handler or it returned 0, we
-* continue with normal processing.  If we have a
-* pre-handler and it returned non-zero, it prepped
-* for calling the break_handler below on re-entry,
-* so get out doing nothing more here.
+* continue with normal processing. If we have a
+* pre-handler and it returned non-zero, it will
+* modify the execution path and no need to single
+* stepping. Let's just reset current kprobe and exit.
 */
if (!p->pre_handler || !p->pre_handler(p, regs)) {
kcb->kprobe_status = KPROBE_HIT_SS;
@@ -312,8 +312,8 @@ void __kprobes kprobe_handler(struct pt_regs *regs)
kcb->kprobe_status = KPROBE_HIT_SS

[RFC PATCH -tip v5 18/27] powerpc/kprobes: Don't call the ->break_handler() in arm kprobes code

2018-06-04 Thread Masami Hiramatsu
Don't call the ->break_handler() from the arm kprobes code,
because it was only used by jprobes which got removed.

This also makes skip_singlestep() a static function since
only ftrace-kprobe.c is using this function.

Signed-off-by: Masami Hiramatsu 
Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Michael Ellerman 
Cc: "Naveen N. Rao" 
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/include/asm/kprobes.h   |   10 --
 arch/powerpc/kernel/kprobes-ftrace.c |   16 +++-
 arch/powerpc/kernel/kprobes.c|   31 +++
 3 files changed, 14 insertions(+), 43 deletions(-)

diff --git a/arch/powerpc/include/asm/kprobes.h 
b/arch/powerpc/include/asm/kprobes.h
index 674036db558b..785c464b6588 100644
--- a/arch/powerpc/include/asm/kprobes.h
+++ b/arch/powerpc/include/asm/kprobes.h
@@ -102,16 +102,6 @@ extern int kprobe_exceptions_notify(struct notifier_block 
*self,
 extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
 extern int kprobe_handler(struct pt_regs *regs);
 extern int kprobe_post_handler(struct pt_regs *regs);
-#ifdef CONFIG_KPROBES_ON_FTRACE
-extern int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
-  struct kprobe_ctlblk *kcb);
-#else
-static inline int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
- struct kprobe_ctlblk *kcb)
-{
-   return 0;
-}
-#endif
 #else
 static inline int kprobe_handler(struct pt_regs *regs) { return 0; }
 static inline int kprobe_post_handler(struct pt_regs *regs) { return 0; }
diff --git a/arch/powerpc/kernel/kprobes-ftrace.c 
b/arch/powerpc/kernel/kprobes-ftrace.c
index 1b316331c2d9..3869b0e5d5c7 100644
--- a/arch/powerpc/kernel/kprobes-ftrace.c
+++ b/arch/powerpc/kernel/kprobes-ftrace.c
@@ -26,8 +26,8 @@
 #include 
 
 static nokprobe_inline
-int __skip_singlestep(struct kprobe *p, struct pt_regs *regs,
- struct kprobe_ctlblk *kcb, unsigned long orig_nip)
+int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
+   struct kprobe_ctlblk *kcb, unsigned long orig_nip)
 {
/*
 * Emulate singlestep (and also recover regs->nip)
@@ -44,16 +44,6 @@ int __skip_singlestep(struct kprobe *p, struct pt_regs *regs,
return 1;
 }
 
-int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
-   struct kprobe_ctlblk *kcb)
-{
-   if (kprobe_ftrace(p))
-   return __skip_singlestep(p, regs, kcb, 0);
-   else
-   return 0;
-}
-NOKPROBE_SYMBOL(skip_singlestep);
-
 /* Ftrace callback handler for kprobes */
 void kprobe_ftrace_handler(unsigned long nip, unsigned long parent_nip,
   struct ftrace_ops *ops, struct pt_regs *regs)
@@ -82,7 +72,7 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long 
parent_nip,
__this_cpu_write(current_kprobe, p);
kcb->kprobe_status = KPROBE_HIT_ACTIVE;
if (!p->pre_handler || !p->pre_handler(p, regs))
-   __skip_singlestep(p, regs, kcb, orig_nip);
+   skip_singlestep(p, regs, kcb, orig_nip);
else {
/*
 * If pre_handler returns !0, it sets regs->nip and
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 600678fce0a8..f06747e2e70d 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -317,25 +317,17 @@ int kprobe_handler(struct pt_regs *regs)
}
prepare_singlestep(p, regs);
return 1;
-   } else {
-   if (*addr != BREAKPOINT_INSTRUCTION) {
-   /* If trap variant, then it belongs not to us */
-   kprobe_opcode_t cur_insn = *addr;
-   if (is_trap(cur_insn))
-   goto no_kprobe;
-   /* The breakpoint instruction was removed by
-* another cpu right after we hit, no further
-* handling of this interrupt is appropriate
-*/
-   ret = 1;
+   } else if (*addr != BREAKPOINT_INSTRUCTION) {
+   /* If trap variant, then it belongs not to us */
+   kprobe_opcode_t cur_insn = *addr;
+
+   if (is_trap(cur_insn))
goto no_kprobe;
-   }
-   p = __this_cpu_read(current_kprobe);
-   if (p->break_handler && p->break_handler(p, regs)) {
-   if (!skip_singlestep(p, regs, kcb))
-   goto ss_probe;
-   ret = 1;
-   }

[RFC PATCH -tip v5 07/27] powerpc/kprobes: Remove jprobe powerpc implementation

2018-06-04 Thread Masami Hiramatsu
Remove arch dependent setjump/longjump functions
and unused fields in kprobe_ctlblk for jprobes
from arch/powerpc. This also reverts commits
related __is_active_jprobe() function.

Signed-off-by: Masami Hiramatsu 

Cc: Benjamin Herrenschmidt 
Cc: Paul Mackerras 
Cc: Michael Ellerman 
Cc: "Naveen N. Rao" 
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/include/asm/kprobes.h |2 -
 arch/powerpc/kernel/kprobes-ftrace.c   |   15 ---
 arch/powerpc/kernel/kprobes.c  |   54 
 arch/powerpc/kernel/trace/ftrace_64_mprofile.S |   39 ++---
 4 files changed, 5 insertions(+), 105 deletions(-)

diff --git a/arch/powerpc/include/asm/kprobes.h 
b/arch/powerpc/include/asm/kprobes.h
index 9f3be5c8a4a3..674036db558b 100644
--- a/arch/powerpc/include/asm/kprobes.h
+++ b/arch/powerpc/include/asm/kprobes.h
@@ -88,7 +88,6 @@ struct prev_kprobe {
 struct kprobe_ctlblk {
unsigned long kprobe_status;
unsigned long kprobe_saved_msr;
-   struct pt_regs jprobe_saved_regs;
struct prev_kprobe prev_kprobe;
 };
 
@@ -104,7 +103,6 @@ extern int kprobe_fault_handler(struct pt_regs *regs, int 
trapnr);
 extern int kprobe_handler(struct pt_regs *regs);
 extern int kprobe_post_handler(struct pt_regs *regs);
 #ifdef CONFIG_KPROBES_ON_FTRACE
-extern int __is_active_jprobe(unsigned long addr);
 extern int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
   struct kprobe_ctlblk *kcb);
 #else
diff --git a/arch/powerpc/kernel/kprobes-ftrace.c 
b/arch/powerpc/kernel/kprobes-ftrace.c
index 7a1f99f1b47f..1b316331c2d9 100644
--- a/arch/powerpc/kernel/kprobes-ftrace.c
+++ b/arch/powerpc/kernel/kprobes-ftrace.c
@@ -25,21 +25,6 @@
 #include 
 #include 
 
-/*
- * This is called from ftrace code after invoking registered handlers to
- * disambiguate regs->nip changes done by jprobes and livepatch. We check if
- * there is an active jprobe at the provided address (mcount location).
- */
-int __is_active_jprobe(unsigned long addr)
-{
-   if (!preemptible()) {
-   struct kprobe *p = raw_cpu_read(current_kprobe);
-   return (p && (unsigned long)p->addr == addr) ? 1 : 0;
-   }
-
-   return 0;
-}
-
 static nokprobe_inline
 int __skip_singlestep(struct kprobe *p, struct pt_regs *regs,
  struct kprobe_ctlblk *kcb, unsigned long orig_nip)
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index e4c5bf33970b..600678fce0a8 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -611,60 +611,6 @@ unsigned long arch_deref_entry_point(void *entry)
 }
 NOKPROBE_SYMBOL(arch_deref_entry_point);
 
-int 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();
-
-   memcpy(>jprobe_saved_regs, regs, sizeof(struct pt_regs));
-
-   /* setup return addr to the jprobe handler routine */
-   regs->nip = arch_deref_entry_point(jp->entry);
-#ifdef PPC64_ELF_ABI_v2
-   regs->gpr[12] = (unsigned long)jp->entry;
-#elif defined(PPC64_ELF_ABI_v1)
-   regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
-#endif
-
-   /*
-* jprobes use jprobe_return() which skips the normal return
-* path of the function, and this messes up the accounting of the
-* function graph tracer.
-*
-* Pause function graph tracing while performing the jprobe function.
-*/
-   pause_graph_tracing();
-
-   return 1;
-}
-NOKPROBE_SYMBOL(setjmp_pre_handler);
-
-void __used jprobe_return(void)
-{
-   asm volatile("jprobe_return_trap:\n"
-"trap\n"
-::: "memory");
-}
-NOKPROBE_SYMBOL(jprobe_return);
-
-int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
-{
-   struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
-
-   if (regs->nip != ppc_kallsyms_lookup_name("jprobe_return_trap")) {
-   pr_debug("longjmp_break_handler NIP (0x%lx) does not match 
jprobe_return_trap (0x%lx)\n",
-   regs->nip, 
ppc_kallsyms_lookup_name("jprobe_return_trap"));
-   return 0;
-   }
-
-   memcpy(regs, >jprobe_saved_regs, sizeof(struct pt_regs));
-   /* It's OK to start function graph tracing again */
-   unpause_graph_tracing();
-   preempt_enable_no_resched();
-   return 1;
-}
-NOKPROBE_SYMBOL(longjmp_break_handler);
-
 static struct kprobe trampoline_p = {
.addr = (kprobe_opcode_t *) _trampoline,
.pre_handler = trampoline_probe_handler
diff --git a/arch/powerpc/kernel/trace/ftrace_64_mprofile.S 
b/arch/powerpc/kernel/trace/ftrace_64_mprofile.S
index 3f3e81852422..4e84a713e80a 100644
--- a/arch/powerpc/kernel/trace/

Re: [PATCH 1/2] error-injection: Simplify arch specific helpers

2018-06-01 Thread Masami Hiramatsu
On Thu, 31 May 2018 15:39:03 +0530
"Naveen N. Rao"  wrote:

> Masami Hiramatsu wrote:
> > On Tue, 29 May 2018 18:06:02 +0530
> > "Naveen N. Rao"  wrote:
> > 
> >> We already have an arch-independent way to set the instruction pointer
> >> with instruction_pointer_set(). Using this allows us to get rid of the
> >> need for override_function_with_return() that each architecture has to
> >> implement.
> >> 
> >> Furthermore, just_return_func() only has to encode arch-specific
> >> assembly instructions to return from a function. Introduce a macro
> >> ARCH_FUNC_RET to provide the arch-specific instruction and move over
> >> just_return_func() to generic code.
> >> 
> >> With these changes, architectures that already support kprobes, only
> >> just need to ensure they provide regs_set_return_value(), GET_IP() (for
> >> instruction_pointer_set()), and ARCH_FUNC_RET to support error
> >> injection.
> > 
> > Nice! the code basically good to me. Just one comment, ARCH_FUNC_RET sounds
> > like a function. Maybe ARCH_RETURN_INSTRUCTION will be better name, isn't 
> > it? :)
> 
> Sure -- I thought of writing ARCH_FUNCTION_RETURN, but felt that was too 
> verbose. How about ARCH_FUNC_RET_INST?

It is OK if we can recognize it is an instruction.

Thank you,

-- 
Masami Hiramatsu 


Re: [PATCH 1/2] error-injection: Simplify arch specific helpers

2018-05-30 Thread Masami Hiramatsu
tion_list(unsigned long addr);
> diff --git a/kernel/fail_function.c b/kernel/fail_function.c
> index 1d5632d8bbcc..0ae2ca4a29e8 100644
> --- a/kernel/fail_function.c
> +++ b/kernel/fail_function.c
> @@ -183,7 +183,7 @@ static int fei_kprobe_handler(struct kprobe *kp, struct 
> pt_regs *regs)
>  
>   if (should_fail(_fault_attr, 1)) {
>   regs_set_return_value(regs, attr->retval);
> - override_function_with_return(regs);
> + instruction_pointer_set(regs, (unsigned long)_return_func);
>   /* Kprobe specific fixup */
>   reset_current_kprobe();
>   preempt_enable_no_resched();
> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> index 56ba0f2a01db..23f1f4ffda6c 100644
> --- a/kernel/trace/bpf_trace.c
> +++ b/kernel/trace/bpf_trace.c
> @@ -84,7 +84,7 @@ EXPORT_SYMBOL_GPL(trace_call_bpf);
>  BPF_CALL_2(bpf_override_return, struct pt_regs *, regs, unsigned long, rc)
>  {
>   regs_set_return_value(regs, rc);
> - override_function_with_return(regs);
> + instruction_pointer_set(regs, (unsigned long)_return_func);
>   return 0;
>  }
>  
> diff --git a/lib/error-inject.c b/lib/error-inject.c
> index c0d4600f4896..7fdc92b5babc 100644
> --- a/lib/error-inject.c
> +++ b/lib/error-inject.c
> @@ -20,6 +20,14 @@ struct ei_entry {
>   void *priv;
>  };
>  
> +asm(
> + ".type just_return_func, @function\n"
> + ".globl just_return_func\n"
> + "just_return_func:\n"
> + ARCH_FUNC_RET "\n"
> + ".size just_return_func, .-just_return_func\n"
> +);
> +
>  bool within_error_injection_list(unsigned long addr)
>  {
>   struct ei_entry *ent;
> -- 
> 2.17.0
> 


-- 
Masami Hiramatsu 


Re: [PATCH 3/4] powerpc/kprobes: Blacklist emulate_update_regs() from kprobes

2017-10-25 Thread Masami Hiramatsu
On Mon, 23 Oct 2017 22:07:40 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> Commit 3cdfcbfd32b9d ("powerpc: Change analyse_instr so it doesn't
> modify *regs") introduced emulate_update_regs() to perform part of what
> emulate_step() was doing earlier. However, this function was not added
> to the kprobes blacklist. Add it so as to prevent it from being probed.
> 

Looks good to me.

Acked-by: Masami Hiramatsu <mhira...@kernel.org>

Thank you!

> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  arch/powerpc/lib/sstep.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index 8c3955e183d4..70274b7b4773 100644
> --- a/arch/powerpc/lib/sstep.c
> +++ b/arch/powerpc/lib/sstep.c
> @@ -2717,6 +2717,7 @@ void emulate_update_regs(struct pt_regs *regs, struct 
> instruction_op *op)
>   }
>   regs->nip = next_pc;
>  }
> +NOKPROBE_SYMBOL(emulate_update_regs);
>  
>  /*
>   * Emulate a previously-analysed load or store instruction.
> -- 
> 2.14.2
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 4/4] powerpc/kprobes: refactor kprobe_lookup_name for safer string operations

2017-10-25 Thread Masami Hiramatsu
On Mon, 23 Oct 2017 22:07:41 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> Use safer string manipulation functions when dealing with a
> user-provided string in kprobe_lookup_name().
> 

What would you mean "safer" here? using strnchr()?
Could you please show at least an example case that causes problem in original 
code.
And have one comment below:

> Reported-by: David Laight <david.lai...@aculab.com>
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  arch/powerpc/kernel/kprobes.c | 47 
> ++-
>  1 file changed, 20 insertions(+), 27 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index a14c61855705..bbb4795660f8 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -53,7 +53,7 @@ bool arch_within_kprobe_blacklist(unsigned long addr)
>  
>  kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset)
>  {
> - kprobe_opcode_t *addr;
> + kprobe_opcode_t *addr = NULL;
>  
>  #ifdef PPC64_ELF_ABI_v2
>   /* PPC64 ABIv2 needs local entry point */
> @@ -85,36 +85,29 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name, 
> unsigned int offset)
>* Also handle  format.
>*/
>   char dot_name[MODULE_NAME_LEN + 1 + KSYM_NAME_LEN];
> - const char *modsym;
>   bool dot_appended = false;
> - if ((modsym = strchr(name, ':')) != NULL) {
> - modsym++;
> - if (*modsym != '\0' && *modsym != '.') {
> - /* Convert to  */
> - strncpy(dot_name, name, modsym - name);
> - dot_name[modsym - name] = '.';
> - dot_name[modsym - name + 1] = '\0';
> - strncat(dot_name, modsym,
> - sizeof(dot_name) - (modsym - name) - 2);
> - dot_appended = true;
> - } else {
> - dot_name[0] = '\0';
> - strncat(dot_name, name, sizeof(dot_name) - 1);
> - }
> - } else if (name[0] != '.') {
> - dot_name[0] = '.';
> - dot_name[1] = '\0';
> - strncat(dot_name, name, KSYM_NAME_LEN - 2);
> + const char *c;
> + ssize_t ret = 0;
> + int len = 0;
> +
> + if ((c = strnchr(name, MODULE_NAME_LEN, ':')) != NULL) {
> + c++;
> + len = c - name;
> + memcpy(dot_name, name, len);
> + } else
> + c = name;
> +
> + if (*c != '\0' && *c != '.') {
> + dot_name[len++] = '.';
>   dot_appended = true;

It is odd, you can call kallsyms_lookup_name(dot_name) here.

> - } else {
> - dot_name[0] = '\0';
> - strncat(dot_name, name, KSYM_NAME_LEN - 1);
>   }
> - addr = (kprobe_opcode_t *)kallsyms_lookup_name(dot_name);
> - if (!addr && dot_appended) {
> - /* Let's try the original non-dot symbol lookup */
> + ret = strscpy(dot_name + len, c, KSYM_NAME_LEN);
> + if (ret > 0)
> + addr = (kprobe_opcode_t *)kallsyms_lookup_name(dot_name);
> +
> + /* Fallback to the original non-dot symbol lookup */
> + if (!addr && dot_appended)
>   addr = (kprobe_opcode_t *)kallsyms_lookup_name(name);

Then we can remove dot_appended.

Thank you,

> - }
>  #else
>   addr = (kprobe_opcode_t *)kallsyms_lookup_name(name);
>  #endif
> -- 
> 2.14.2
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 2/4] powerpc/kprobes: Do not disable interrupts for optprobes and kprobes_on_ftrace

2017-10-24 Thread Masami Hiramatsu
On Mon, 23 Oct 2017 22:07:39 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> Per Documentation/kprobes.txt, we don't necessarily need to disable
> interrupts before invoking the kprobe handlers. Masami submitted
> similar changes for x86 via commit a19b2e3d783964 ("kprobes/x86: Remove
> IRQ disabling from ftrace-based/optimized kprobes"). Do the same for
> powerpc.

Yes, and this requires to make preempt disable :)

Acked-by: Masami Hiramatsu <mhira...@kernel.org>

Thank you!

> 
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  arch/powerpc/kernel/kprobes-ftrace.c | 10 ++
>  arch/powerpc/kernel/optprobes.c  | 10 --
>  2 files changed, 2 insertions(+), 18 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/kprobes-ftrace.c 
> b/arch/powerpc/kernel/kprobes-ftrace.c
> index 4b1f34f685b1..7a1f99f1b47f 100644
> --- a/arch/powerpc/kernel/kprobes-ftrace.c
> +++ b/arch/powerpc/kernel/kprobes-ftrace.c
> @@ -75,11 +75,7 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned 
> long parent_nip,
>  {
>   struct kprobe *p;
>   struct kprobe_ctlblk *kcb;
> - unsigned long flags;
>  
> - /* Disable irq for emulating a breakpoint and avoiding preempt */
> - local_irq_save(flags);
> - hard_irq_disable();
>   preempt_disable();
>  
>   p = get_kprobe((kprobe_opcode_t *)nip);
> @@ -105,16 +101,14 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned 
> long parent_nip,
>   else {
>   /*
>* If pre_handler returns !0, it sets regs->nip and
> -  * resets current kprobe. In this case, we still need
> -  * to restore irq, but not preemption.
> +  * resets current kprobe. In this case, we should not
> +  * re-enable preemption.
>*/
> - local_irq_restore(flags);
>   return;
>   }
>   }
>  end:
>   preempt_enable_no_resched();
> - local_irq_restore(flags);
>  }
>  NOKPROBE_SYMBOL(kprobe_ftrace_handler);
>  
> diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c
> index 60ba7f1370a8..8237884ca389 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -115,14 +115,10 @@ static unsigned long can_optimize(struct kprobe *p)
>  static void optimized_callback(struct optimized_kprobe *op,
>  struct pt_regs *regs)
>  {
> - unsigned long flags;
> -
>   /* This is possible if op is under delayed unoptimizing */
>   if (kprobe_disabled(>kp))
>   return;
>  
> - local_irq_save(flags);
> - hard_irq_disable();
>   preempt_disable();
>  
>   if (kprobe_running()) {
> @@ -135,13 +131,7 @@ static void optimized_callback(struct optimized_kprobe 
> *op,
>   __this_cpu_write(current_kprobe, NULL);
>   }
>  
> - /*
> -  * No need for an explicit __hard_irq_enable() here.
> -  * local_irq_restore() will re-enable interrupts,
> -  * if they were hard disabled.
> -  */
>   preempt_enable_no_resched();
> - local_irq_restore(flags);
>  }
>  NOKPROBE_SYMBOL(optimized_callback);
>  
> -- 
> 2.14.2
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 1/4] powerpc/kprobes: Disable preemption before invoking probe handler for optprobes

2017-10-24 Thread Masami Hiramatsu
On Mon, 23 Oct 2017 22:07:38 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> Per Documentation/kprobes.txt, probe handlers need to be invoked with
> preemption disabled. Update optimized_callback() to do so. Also move
> get_kprobe_ctlblk() invocation post preemption disable, since it
> accesses pre-cpu data.
> 
> This was not an issue so far since optprobes wasn't selected if
> CONFIG_PREEMPT was enabled. Commit a30b85df7d599f ("kprobes: Use
> synchronize_rcu_tasks() for optprobe with CONFIG_PREEMPT=y") changes
> this.

Actually, if you local_irq_save(), it also disables preempt. So unless you
enables irqs, it should be safe.

Acked-by: Masami Hiramatsu <mhira...@kernel.org>

Thank you,


> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  arch/powerpc/kernel/optprobes.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c
> index 91e037ab20a1..60ba7f1370a8 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -115,7 +115,6 @@ static unsigned long can_optimize(struct kprobe *p)
>  static void optimized_callback(struct optimized_kprobe *op,
>  struct pt_regs *regs)
>  {
> - struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
>   unsigned long flags;
>  
>   /* This is possible if op is under delayed unoptimizing */
> @@ -124,13 +123,14 @@ static void optimized_callback(struct optimized_kprobe 
> *op,
>  
>   local_irq_save(flags);
>   hard_irq_disable();
> + preempt_disable();
>  
>   if (kprobe_running()) {
>   kprobes_inc_nmissed_count(>kp);
>   } else {
>   __this_cpu_write(current_kprobe, >kp);
>   regs->nip = (unsigned long)op->kp.addr;
> - kcb->kprobe_status = KPROBE_HIT_ACTIVE;
> + get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
>   opt_pre_handler(>kp, regs);
>   __this_cpu_write(current_kprobe, NULL);
>   }
> @@ -140,6 +140,7 @@ static void optimized_callback(struct optimized_kprobe 
> *op,
>* local_irq_restore() will re-enable interrupts,
>    * if they were hard disabled.
>*/
> + preempt_enable_no_resched();
>   local_irq_restore(flags);
>  }
>  NOKPROBE_SYMBOL(optimized_callback);
> -- 
> 2.14.2
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 4/5] powerpc/jprobes: Disable preemption when triggered through ftrace

2017-09-14 Thread Masami Hiramatsu
On Thu, 14 Sep 2017 15:55:39 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> On 2017/09/13 05:05PM, Masami Hiramatsu wrote:
> > On Thu, 14 Sep 2017 02:50:35 +0530
> > "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:
> > 
> > > KPROBES_SANITY_TEST throws the below splat when CONFIG_PREEMPT is
> > > enabled:
> > > 
> > > [3.140410] Kprobe smoke test: started
> > > [3.149680] DEBUG_LOCKS_WARN_ON(val > preempt_count())
> > > [3.149684] [ cut here ]
> > > [3.149695] WARNING: CPU: 19 PID: 1 at kernel/sched/core.c:3094 
> > > preempt_count_sub+0xcc/0x140
> > > [3.149699] Modules linked in:
> > > [3.149705] CPU: 19 PID: 1 Comm: swapper/0 Not tainted 4.13.0-rc7-nnr+ 
> > > #97
> > > [3.149709] task: c000fea8 task.stack: c000feb0
> > > [3.149713] NIP:  c011d3dc LR: c011d3d8 CTR: 
> > > c0a090d0
> > > [3.149718] REGS: c000feb03400 TRAP: 0700   Not tainted  
> > > (4.13.0-rc7-nnr+)
> > > [3.149722] MSR:  80021033 <SF,ME,IR,DR,RI,LE>  CR: 28000282  
> > > XER: 
> > > [3.149732] CFAR: c015aa18 SOFTE: 0
> > > 
> > > [3.149786] NIP [c011d3dc] preempt_count_sub+0xcc/0x140
> > > [3.149790] LR [c011d3d8] preempt_count_sub+0xc8/0x140
> > > [3.149794] Call Trace:
> > > [3.149798] [c000feb03680] [c011d3d8] 
> > > preempt_count_sub+0xc8/0x140 (unreliable)
> > > [3.149804] [c000feb036e0] [c0046198] 
> > > kprobe_handler+0x228/0x4b0
> > > [3.149810] [c000feb03750] [c00269c8] 
> > > program_check_exception+0x58/0x3b0
> > > [3.149816] [c000feb037c0] [c000903c] 
> > > program_check_common+0x16c/0x170
> > > [3.149822] --- interrupt: 0 at kprobe_target+0x8/0x20
> > >LR = init_test_probes+0x248/0x7d0
> > > [3.149829] [c000feb03ab0] [c0e4f048] kp+0x0/0x80 
> > > (unreliable)
> > > [3.149835] [c000feb03b10] [c004ea60] 
> > > livepatch_handler+0x38/0x74
> > > [3.149841] [c000feb03ba0] [c0d0de54] 
> > > init_kprobes+0x1d8/0x208
> > > [3.149846] [c000feb03c40] [c000daa8] 
> > > do_one_initcall+0x68/0x1d0
> > > [3.149852] [c000feb03d00] [c0ce44f0] 
> > > kernel_init_freeable+0x298/0x374
> > > [3.149857] [c000feb03dc0] [c000dd84] 
> > > kernel_init+0x24/0x160
> > > [3.149863] [c000feb03e30] [c000bfec] 
> > > ret_from_kernel_thread+0x5c/0x70
> > > [3.149867] Instruction dump:
> > > [3.149871] 419effdc 3d22001b 39299240 8129 2f89 409effc8 
> > > 3c82ffcb 3c62ffcb
> > > [3.149879] 3884bc68 3863bc18 4803d5fd 6000 <0fe0> 4ba8 
> > > 6000 6000
> > > [3.149890] ---[ end trace 432dd46b4ce3d29f ]---
> > > [3.166003] Kprobe smoke test: passed successfully
> > > 
> > > The issue is that we aren't disabling preemption in
> > > kprobe_ftrace_handler(). Disable it.
> > 
> > Oops, right! Similar patch may need for x86 too.
> 
> Indeed, I will send a patch for that.
> 
> On a related note, I've been looking into why we have !PREEMPT for 
> CONFIG_OPTPROBES. It looks like the primary reason is x86 having to deal 
> with replacing multiple instructions. However, that isn't true with arm 
> and powerpc. So, does it make sense to move 'depends on !PREEMPT' to the 
> x86 code? Are there other scenarios where it might cause issues for 
> arm/powerpc?

Indeed! Whuat I expected was to replace several instructions in RISC processors
for jumping far site (like load & jump), but you chose different approach.
So there is no reason to prehibit that.

Thanks!


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 3/5] powerpc/kprobes: Fix warnings from __this_cpu_read() on preempt kernels

2017-09-14 Thread Masami Hiramatsu
On Thu, 14 Sep 2017 12:17:20 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> On 2017/09/13 05:36PM, Masami Hiramatsu wrote:
> > On Thu, 14 Sep 2017 02:50:34 +0530
> > "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:
> > 
> > > Kamalesh pointed out that we are getting the below call traces with
> > > livepatched functions when we enable CONFIG_PREEMPT:
> > > 
> > > [  495.470721] BUG: using __this_cpu_read() in preemptible [] 
> > > code: cat/8394
> > > [  495.471167] caller is is_current_kprobe_addr+0x30/0x90
> > > [  495.471171] CPU: 4 PID: 8394 Comm: cat Tainted: G  K 
> > > 4.13.0-rc7-nnr+ #95
> > > [  495.471173] Call Trace:
> > > [  495.471178] [c0008fd9b960] [c09f039c] 
> > > dump_stack+0xec/0x160 (unreliable)
> > > [  495.471184] [c0008fd9b9a0] [c059169c] 
> > > check_preemption_disabled+0x15c/0x170
> > > [  495.471187] [c0008fd9ba30] [c0046460] 
> > > is_current_kprobe_addr+0x30/0x90
> > > [  495.471191] [c0008fd9ba60] [c004e9a0] ftrace_call+0x1c/0xb8
> > > [  495.471195] [c0008fd9bc30] [c0376fd8] seq_read+0x238/0x5c0
> > > [  495.471199] [c0008fd9bcd0] [c03cfd78] 
> > > proc_reg_read+0x88/0xd0
> > > [  495.471203] [c0008fd9bd00] [c033e5d4] __vfs_read+0x44/0x1b0
> > > [  495.471206] [c0008fd9bd90] [c03402ec] vfs_read+0xbc/0x1b0
> > > [  495.471210] [c0008fd9bde0] [c0342138] SyS_read+0x68/0x110
> > > [  495.471214] [c0008fd9be30] [c000bc6c] system_call+0x58/0x6c
> > > 
> > > Commit c05b8c4474c030 ("powerpc/kprobes: Skip livepatch_handler() for
> > > jprobes") introduced a helper is_current_kprobe_addr() to help determine
> > > if the current function has been livepatched or if it has a jprobe
> > > installed, both of which modify the NIP.
> > > 
> > > In the case of a jprobe, kprobe_ftrace_handler() disables pre-emption
> > > before calling into setjmp_pre_handler() which returns without disabling
> > > pre-emption. This is done to ensure that the jprobe han dler won't
> > > disappear beneath us if the jprobe is unregistered between the
> > > setjmp_pre_handler() and the subsequent longjmp_break_handler() called
> > > from the jprobe handler. Due to this, we can use __this_cpu_read() in
> > > is_current_kprobe_addr() with the pre-emption check as we know that
> > > pre-emption will be disabled.
> > > 
> > > However, if this function has been livepatched, we are still doing this
> > > check and when we do so, pre-emption won't necessarily be disabled. This
> > > results in the call trace shown above.
> > > 
> > > Fix this by only invoking is_current_kprobe_addr() when pre-emption is
> > > disabled. And since we now guard this within a pre-emption check, we can
> > > instead use raw_cpu_read() to get the current_kprobe value skipping the
> > > check done by __this_cpu_read().
> > 
> > Hmm, can you disable preempt temporary at this function and read it?
> 
> Yes, but I felt this approach is more optimal specifically for live 
> patching. We don't normally expect preemption to be disabled while 
> handling a livepatched function, so the simple 'if (!preemptible())'
> check helps us bypass looking at current_kprobe.

Ah, I see. this is for checking "jprobes", since kprobes/kretprobes
usually already done there.

> 
> The check also ensures we can use raw_cpu_read() safely in other 
> scenarios. Do you see any other concerns with this approach?

Yes, there are 2 reasons.

At first, if user's custom kprobe pre-handler changes NIP for their
custom handwriting livepatching, such handler will enable preemption
before return. We don't prohibit it. I think this function can not
detect it.

And also, the function "name" is very confusing :)
Especially, since this symbol is exported, if you are checking jprobes
context, it should be renamed, at least it starts with "__" so that
show it as local use.

Thank you,


> 
> Thanks,
> Naveen
> 
> > 
> > Thank you,
> > 
> > > 
> > > Fixes: c05b8c4474c030 ("powerpc/kprobes: Skip livepatch_handler() for 
> > > jprobes")
> > > Reported-by: Kamalesh Babulal <kamal...@linux.vnet.ibm.com>
> > > Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> > > ---
> > >  arch/powerpc/kernel/kprobes.c | 8 ++--
> > >  1 file changed, 6 insertions(+), 2 d

Re: [PATCH 2/5] powerpc/kprobes: Do not suppress instruction emulation if a single run failed

2017-09-14 Thread Masami Hiramatsu
On Thu, 14 Sep 2017 12:08:07 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> On 2017/09/13 04:53PM, Masami Hiramatsu wrote:
> > On Thu, 14 Sep 2017 02:50:33 +0530
> > "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:
> > 
> > > Currently, we disable instruction emulation if emulate_step() fails for
> > > any reason. However, such failures could be transient and specific to a
> > > particular run. Instead, only disable instruction emulation if we have
> > > never been able to emulate this. If we had emulated this instruction
> > > successfully at least once, then we single step only this probe hit and
> > > continue to try emulating the instruction in subsequent probe hits.
> > 
> > Hmm, would this mean that the instruction is emulatable or not depends
> > on context? What kind of situation is considerable?
> 
> Yes, as an example, a load/store instruction can cause exceptions 
> depending on the address. In some of those cases, we will have to single 
> step the instruction, but we will be able to emulate in most scenarios.

OK, I got it.
Could you add this example as comment in the code so that readers can
easily understand?

Thank you,

> 
> Thanks for the review!
> - Naveen
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 5/5] powerpc/jprobes: Validate break handler invocation as being due to a jprobe_return()

2017-09-13 Thread Masami Hiramatsu
On Thu, 14 Sep 2017 02:50:36 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> Fix a circa 2005 FIXME by implementing a check to ensure that we
> actually got into the jprobe break handler() due to the trap in
> jprobe_return().
> 

Looks good to me.

Acked-by: Masami Hiramatsu <mhira...@kernel.org>

Thanks!

> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
> This is v2 of the patch posted previously (*) to change the WARN() to a 
> pr_debug() as suggested by Masami.
> (*) https://patchwork.ozlabs.org/patch/762670/
> 
> - Naveen
> 
>  arch/powerpc/kernel/kprobes.c | 20 +---
>  1 file changed, 9 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index db40b13fd3d1..5b26d5202273 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -648,24 +648,22 @@ NOKPROBE_SYMBOL(setjmp_pre_handler);
>  
>  void __used jprobe_return(void)
>  {
> - asm volatile("trap" ::: "memory");
> + asm volatile("jprobe_return_trap:\n"
> +  "trap\n"
> +  ::: "memory");
>  }
>  NOKPROBE_SYMBOL(jprobe_return);
>  
> -static void __used jprobe_return_end(void)
> -{
> -}
> -NOKPROBE_SYMBOL(jprobe_return_end);
> -
>  int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
>  {
>   struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
>  
> - /*
> -  * FIXME - we should ideally be validating that we got here 'cos
> -  * of the "trap" in jprobe_return() above, before restoring the
> -  * saved regs...
> -  */
> + if (regs->nip != ppc_kallsyms_lookup_name("jprobe_return_trap")) {
> + pr_debug("longjmp_break_handler NIP (0x%lx) does not match 
> jprobe_return_trap (0x%lx)\n",
> + regs->nip, 
> ppc_kallsyms_lookup_name("jprobe_return_trap"));
> + return 0;
> + }
> +
>   memcpy(regs, >jprobe_saved_regs, sizeof(struct pt_regs));
>   /* It's OK to start function graph tracing again */
>   unpause_graph_tracing();
> -- 
> 2.14.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 3/5] powerpc/kprobes: Fix warnings from __this_cpu_read() on preempt kernels

2017-09-13 Thread Masami Hiramatsu
On Thu, 14 Sep 2017 02:50:34 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> Kamalesh pointed out that we are getting the below call traces with
> livepatched functions when we enable CONFIG_PREEMPT:
> 
> [  495.470721] BUG: using __this_cpu_read() in preemptible [] code: 
> cat/8394
> [  495.471167] caller is is_current_kprobe_addr+0x30/0x90
> [  495.471171] CPU: 4 PID: 8394 Comm: cat Tainted: G  K 
> 4.13.0-rc7-nnr+ #95
> [  495.471173] Call Trace:
> [  495.471178] [c0008fd9b960] [c09f039c] dump_stack+0xec/0x160 
> (unreliable)
> [  495.471184] [c0008fd9b9a0] [c059169c] 
> check_preemption_disabled+0x15c/0x170
> [  495.471187] [c0008fd9ba30] [c0046460] 
> is_current_kprobe_addr+0x30/0x90
> [  495.471191] [c0008fd9ba60] [c004e9a0] ftrace_call+0x1c/0xb8
> [  495.471195] [c0008fd9bc30] [c0376fd8] seq_read+0x238/0x5c0
> [  495.471199] [c0008fd9bcd0] [c03cfd78] proc_reg_read+0x88/0xd0
> [  495.471203] [c0008fd9bd00] [c033e5d4] __vfs_read+0x44/0x1b0
> [  495.471206] [c0008fd9bd90] [c03402ec] vfs_read+0xbc/0x1b0
> [  495.471210] [c0008fd9bde0] [c0342138] SyS_read+0x68/0x110
> [  495.471214] [c0008fd9be30] [c000bc6c] system_call+0x58/0x6c
> 
> Commit c05b8c4474c030 ("powerpc/kprobes: Skip livepatch_handler() for
> jprobes") introduced a helper is_current_kprobe_addr() to help determine
> if the current function has been livepatched or if it has a jprobe
> installed, both of which modify the NIP.
> 
> In the case of a jprobe, kprobe_ftrace_handler() disables pre-emption
> before calling into setjmp_pre_handler() which returns without disabling
> pre-emption. This is done to ensure that the jprobe han dler won't
> disappear beneath us if the jprobe is unregistered between the
> setjmp_pre_handler() and the subsequent longjmp_break_handler() called
> from the jprobe handler. Due to this, we can use __this_cpu_read() in
> is_current_kprobe_addr() with the pre-emption check as we know that
> pre-emption will be disabled.
> 
> However, if this function has been livepatched, we are still doing this
> check and when we do so, pre-emption won't necessarily be disabled. This
> results in the call trace shown above.
> 
> Fix this by only invoking is_current_kprobe_addr() when pre-emption is
> disabled. And since we now guard this within a pre-emption check, we can
> instead use raw_cpu_read() to get the current_kprobe value skipping the
> check done by __this_cpu_read().

Hmm, can you disable preempt temporary at this function and read it?

Thank you,

> 
> Fixes: c05b8c4474c030 ("powerpc/kprobes: Skip livepatch_handler() for 
> jprobes")
> Reported-by: Kamalesh Babulal <kamal...@linux.vnet.ibm.com>
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  arch/powerpc/kernel/kprobes.c | 8 ++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index e848fe2c93fb..db40b13fd3d1 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -45,8 +45,12 @@ struct kretprobe_blackpoint kretprobe_blacklist[] = 
> {{NULL, NULL}};
>  
>  int is_current_kprobe_addr(unsigned long addr)
>  {
> - struct kprobe *p = kprobe_running();
> - return (p && (unsigned long)p->addr == addr) ? 1 : 0;
> + if (!preemptible()) {
> +     struct kprobe *p = raw_cpu_read(current_kprobe);
> + return (p && (unsigned long)p->addr == addr) ? 1 : 0;
> + }
> +
> + return 0;
>  }
>  
>  bool arch_within_kprobe_blacklist(unsigned long addr)
> -- 
> 2.14.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 4/5] powerpc/jprobes: Disable preemption when triggered through ftrace

2017-09-13 Thread Masami Hiramatsu
On Thu, 14 Sep 2017 02:50:35 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> KPROBES_SANITY_TEST throws the below splat when CONFIG_PREEMPT is
> enabled:
> 
> [3.140410] Kprobe smoke test: started
> [3.149680] DEBUG_LOCKS_WARN_ON(val > preempt_count())
> [3.149684] [ cut here ]
> [3.149695] WARNING: CPU: 19 PID: 1 at kernel/sched/core.c:3094 
> preempt_count_sub+0xcc/0x140
> [3.149699] Modules linked in:
> [3.149705] CPU: 19 PID: 1 Comm: swapper/0 Not tainted 4.13.0-rc7-nnr+ #97
> [3.149709] task: c000fea8 task.stack: c000feb0
> [3.149713] NIP:  c011d3dc LR: c011d3d8 CTR: 
> c0a090d0
> [3.149718] REGS: c000feb03400 TRAP: 0700   Not tainted  
> (4.13.0-rc7-nnr+)
> [3.149722] MSR:  80021033 <SF,ME,IR,DR,RI,LE>  CR: 28000282  XER: 
> 
> [3.149732] CFAR: c015aa18 SOFTE: 0
> 
> [3.149786] NIP [c011d3dc] preempt_count_sub+0xcc/0x140
> [3.149790] LR [c011d3d8] preempt_count_sub+0xc8/0x140
> [3.149794] Call Trace:
> [3.149798] [c000feb03680] [c011d3d8] 
> preempt_count_sub+0xc8/0x140 (unreliable)
> [3.149804] [c000feb036e0] [c0046198] 
> kprobe_handler+0x228/0x4b0
> [3.149810] [c000feb03750] [c00269c8] 
> program_check_exception+0x58/0x3b0
> [3.149816] [c000feb037c0] [c000903c] 
> program_check_common+0x16c/0x170
> [3.149822] --- interrupt: 0 at kprobe_target+0x8/0x20
>LR = init_test_probes+0x248/0x7d0
> [3.149829] [c000feb03ab0] [c0e4f048] kp+0x0/0x80 (unreliable)
> [3.149835] [c000feb03b10] [c004ea60] 
> livepatch_handler+0x38/0x74
> [3.149841] [c000feb03ba0] [c0d0de54] init_kprobes+0x1d8/0x208
> [3.149846] [c000feb03c40] [c000daa8] 
> do_one_initcall+0x68/0x1d0
> [3.149852] [c000feb03d00] [c0ce44f0] 
> kernel_init_freeable+0x298/0x374
> [3.149857] [c000feb03dc0] [c000dd84] kernel_init+0x24/0x160
> [3.149863] [c000feb03e30] [c000bfec] 
> ret_from_kernel_thread+0x5c/0x70
> [3.149867] Instruction dump:
> [3.149871] 419effdc 3d22001b 39299240 8129 2f89 409effc8 3c82ffcb 
> 3c62ffcb
> [3.149879] 3884bc68 3863bc18 4803d5fd 6000 <0fe0> 4ba8 
> 6000 6000
> [3.149890] ---[ end trace 432dd46b4ce3d29f ]---
> [3.166003] Kprobe smoke test: passed successfully
> 
> The issue is that we aren't disabling preemption in
> kprobe_ftrace_handler(). Disable it.

Oops, right! Similar patch may need for x86 too.

Acked-by: Masami Hiramatsu <mhira...@kernel.org>

Thanks!

> Fixes: ead514d5fb30a0 ("powerpc/kprobes: Add support for KPROBES_ON_FTRACE")
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  arch/powerpc/kernel/kprobes-ftrace.c | 15 +++
>  1 file changed, 11 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/kprobes-ftrace.c 
> b/arch/powerpc/kernel/kprobes-ftrace.c
> index 6c089d9757c9..2d81404f818c 100644
> --- a/arch/powerpc/kernel/kprobes-ftrace.c
> +++ b/arch/powerpc/kernel/kprobes-ftrace.c
> @@ -65,6 +65,7 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned long 
> parent_nip,
>   /* Disable irq for emulating a breakpoint and avoiding preempt */
>   local_irq_save(flags);
>   hard_irq_disable();
> + preempt_disable();
>  
>   p = get_kprobe((kprobe_opcode_t *)nip);
>   if (unlikely(!p) || kprobe_disabled(p))
> @@ -86,12 +87,18 @@ void kprobe_ftrace_handler(unsigned long nip, unsigned 
> long parent_nip,
>   kcb->kprobe_status = KPROBE_HIT_ACTIVE;
>   if (!p->pre_handler || !p->pre_handler(p, regs))
>   __skip_singlestep(p, regs, kcb, orig_nip);
> - /*
> -  * If pre_handler returns !0, it sets regs->nip and
> -  * resets current kprobe.
> -  */
> + else {
> + /*
> +  * If pre_handler returns !0, it sets regs->nip and
> +  * resets current kprobe. In this case, we still need
> +  * to restore irq, but not preemption.
> +  */
> + local_irq_restore(flags);
> + return;
> + }
>   }
>  end:
> + preempt_enable_no_resched();
>   local_irq_restore(flags);
>  }
>  NOKPROBE_SYMBOL(kprobe_ftrace_handler);
> -- 
> 2.14.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 2/5] powerpc/kprobes: Do not suppress instruction emulation if a single run failed

2017-09-13 Thread Masami Hiramatsu
On Thu, 14 Sep 2017 02:50:33 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> Currently, we disable instruction emulation if emulate_step() fails for
> any reason. However, such failures could be transient and specific to a
> particular run. Instead, only disable instruction emulation if we have
> never been able to emulate this. If we had emulated this instruction
> successfully at least once, then we single step only this probe hit and
> continue to try emulating the instruction in subsequent probe hits.

Hmm, would this mean that the instruction is emulatable or not depends
on context? What kind of situation is considerable?

Thank you,

> 
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  arch/powerpc/kernel/kprobes.c | 16 +---
>  1 file changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index c2a6ab38a67f..e848fe2c93fb 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -261,9 +261,19 @@ static int try_to_emulate(struct kprobe *p, struct 
> pt_regs *regs)
>*/
>   printk("Can't step on instruction %x\n", insn);
>   BUG();
> - } else
> - /* This instruction can't be boosted */
> - p->ainsn.boostable = -1;
> + } else {
> + /*
> +  * If we haven't previously emulated this instruction, then it
> +  * can't be boosted. Note it down so we don't try to do so 
> again.
> +  *
> +  * If, however, we had emulated this instruction in the past,
> +  * then this is just an error with the current run. We return
> +  * 0 so that this is now single-stepped, but continue to try
> +  * emulating it in subsequent probe hits.
> +  */
> + if (unlikely(p->ainsn.boostable != 1))
> + p->ainsn.boostable = -1;
> + }
>  
>   return ret;
>  }
> -- 
> 2.14.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 1/5] powerpc/kprobes: Some cosmetic updates to try_to_emulate()

2017-09-13 Thread Masami Hiramatsu
On Thu, 14 Sep 2017 02:50:32 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> 1. This is only used in kprobes.c, so make it static.
> 2. Remove the un-necessary (ret == 0) comparison in the else clause.
> 
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>

Reviewed-by: Masami Hiramatsu <mhira...@kernel.org>

Thanks!

> ---
>  arch/powerpc/kernel/kprobes.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index 367494dc67d9..c2a6ab38a67f 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -239,7 +239,7 @@ void arch_prepare_kretprobe(struct kretprobe_instance 
> *ri, struct pt_regs *regs)
>  }
>  NOKPROBE_SYMBOL(arch_prepare_kretprobe);
>  
> -int try_to_emulate(struct kprobe *p, struct pt_regs *regs)
> +static int try_to_emulate(struct kprobe *p, struct pt_regs *regs)
>  {
>   int ret;
>   unsigned int insn = *p->ainsn.insn;
> @@ -261,7 +261,7 @@ int try_to_emulate(struct kprobe *p, struct pt_regs *regs)
>*/
>   printk("Can't step on instruction %x\n", insn);
>   BUG();
> - } else if (ret == 0)
> + } else
>       /* This instruction can't be boosted */
>   p->ainsn.boostable = -1;
>  
> -- 
> 2.14.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v2 2/4] selftests/ftrace: Add a test to probe module functions

2017-07-02 Thread Masami Hiramatsu
On Mon, 3 Jul 2017 12:27:33 +0900
Masami Hiramatsu <mhira...@kernel.org> wrote:

> On Thu, 29 Jun 2017 19:05:37 +0530
> "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:
> 
> > Add a kprobes test to ensure that we are able to add a probe on a
> > module function using 'p :' format, without having to
> > specify a probe name.
> > 
> > Suggested-by: Masami Hiramatsu <mhira...@kernel.org>
> > Acked-by: Masami Hiramatsu <mhira...@kernel.org>
> > Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> > ---
> >  .../testing/selftests/ftrace/test.d/kprobe/probe_module.tc | 14 
> > ++
> >  1 file changed, 14 insertions(+)
> >  create mode 100644 
> > tools/testing/selftests/ftrace/test.d/kprobe/probe_module.tc
> > 
> > diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/probe_module.tc 
> > b/tools/testing/selftests/ftrace/test.d/kprobe/probe_module.tc
> > new file mode 100644
> > index ..ea7657041ba6
> > --- /dev/null
> > +++ b/tools/testing/selftests/ftrace/test.d/kprobe/probe_module.tc
> > @@ -0,0 +1,14 @@
> > +#!/bin/sh
> > +# description: Kprobe dynamic event - probing module
> > +
> > +[ -f kprobe_events ] || exit_unsupported # this is configurable
> > +
> > +echo 0 > events/enable
> > +echo > kprobe_events
> > +export MOD=`lsmod | head -n 2 | tail -n 1 | cut -f1 -d" "`
> > +export FUNC=`grep -m 1 ".* t .*\\[$MOD\\]" /proc/kallsyms | xargs | cut 
> > -f3 -d" "`
> > +[ "x" != "x$MOD" -a "y" != "y$FUNC" ] || exit_untested
> 
> Could you also add below case?
> 
> echo p:probe_$MOD/$FUNC $MOD/$FUNC > kprobe_events 

Oops, it should be something like

echo "p:test_${MOD}_${FUNC} $MOD/$FUNC" > kprobe_events

since we would like to avoid adding new group name for it.

(Adding new group name should be a separated one.)

Thank you,

> 
> This is for "new event with name on module" case, your one is for "new event 
> without name on module (automatic name generation)"
> 
> We should have different test case, because those kicks slightly different 
> parts in kprobe tracer.
> 
> Thank you,
> 
> > +echo p $MOD:$FUNC > kprobe_events
> > +grep $MOD kprobe_events
> > +echo > kprobe_events
> > +clear_trace
> > -- 
> > 2.13.1
> > 
> 
> 
> -- 
> Masami Hiramatsu <mhira...@kernel.org>


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v2 4/4] selftests/ftrace: Add a testcase for kprobe event naming

2017-07-02 Thread Masami Hiramatsu
On Thu, 29 Jun 2017 19:05:39 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> From: Masami Hiramatsu <mhira...@kernel.org>
> 
> Add a testcase for kprobe event naming. This testcase
> checks whether the kprobe events can automatically ganerate
> its event name on normal function and dot-suffixed function.
> Also it checks whether the kprobe events can correctly
> define new event with given event name and group name.
> 
> Signed-off-by: Masami Hiramatsu <mhira...@kernel.org>
> [Updated tests to use vfs_read and symbols with '.isra.',
> added check for kprobe_events and a command to clear it on exit]
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  .../ftrace/test.d/kprobe/kprobe_eventname.tc   | 32 
> ++
>  1 file changed, 32 insertions(+)
>  create mode 100644 
> tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc
> 
> diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc 
> b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc
> new file mode 100644
> index ..182e5a78ef4b
> --- /dev/null
> +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc
> @@ -0,0 +1,32 @@
> +#!/bin/sh
> +# description: Kprobe event auto/manual naming
> +
> +[ -f kprobe_events ] || exit_unsupported # this is configurable
> +
> +disable_events
> +echo > kprobe_events
> +
> +:;: "Add an event on function without name" ;:
> +
> +FUNC=`grep " [tT] .*vfs_read$" /proc/kallsyms | tail -n 1 | cut -f 3 -d " "`
> +echo p $FUNC > kprobe_events
> +FUNC_NAME=`echo $FUNC | tr ".:" "_"`
> +test -d events/kprobes/p_${FUNC_NAME}_0 || exit_failure
> +
> +:;: "Add an event on function with new name" ;:
> +
> +echo p:event1 $FUNC > kprobe_events
> +test -d events/kprobes/event1 || exit_failure
> +
> +:;: "Add an event on function with new name and group" ;:
> +
> +echo p:kprobes2/event2 $FUNC > kprobe_events
> +test -d events/kprobes2/event2 || exit_failure
> +
> +:;: "Add an event on dot function without name" ;:
> +
> +FUNC=`grep -m 10 " [tT] .*\.isra\..*$" /proc/kallsyms | tail -n 1 | cut -f 3 
> -d " "`

Since in some case we may not be able to find the function(e.g. build with old 
gcc or not optimized), we should check this is exist. I suggested to return 
UNRESOLVED for that case instead of FAIL, as below.

FUNC=`grep -m 10 " [tT] .*\.isra\..*$" /proc/kallsyms | tail -n 1 | cut -f 3 -d 
" "` || exit_unresolved

Thank you,

> +echo p $FUNC > kprobe_events
> +EVENT=`grep $FUNC kprobe_events | cut -f 1 -d " " | cut -f 2 -d:` || 
> exit_failure
> +test -d events/$EVENT || exit_failure
> +echo > kprobe_events
> -- 
> 2.13.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v2 3/4] selftests/ftrace: Update multiple kprobes test for powerpc

2017-07-02 Thread Masami Hiramatsu
On Thu, 29 Jun 2017 19:05:38 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> KPROBES_ON_FTRACE is only available on powerpc64le. Update comment to
> clarify this.
> 
> Also, we should use an offset of 8 to ensure that the probe does not
> fall on ftrace location. The current offset of 4 will fall before the
> function local entry point and won't fire, while an offset of 12 or 16
> will fall on ftrace location. Offset 8 is currently guaranteed to not be
> the ftrace location.

OK, looks good to me.

Acked-by: Masami Hiramatsu <mhira...@kernel.org>

Thanks!

> 
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc 
> b/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc
> index f4d1ff785d67..2a1cb9908746 100644
> --- a/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc
> +++ b/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc
> @@ -2,10 +2,10 @@
>  # description: Register/unregister many kprobe events
>  
>  # ftrace fentry skip size depends on the machine architecture.
> -# Currently HAVE_KPROBES_ON_FTRACE defined on x86 and powerpc
> +# Currently HAVE_KPROBES_ON_FTRACE defined on x86 and powerpc64le
>  case `uname -m` in
>x86_64|i[3456]86) OFFS=5;;
> -  ppc*) OFFS=4;;
> +  ppc64le) OFFS=8;;
>*) OFFS=0;;
>  esac
>  
> -- 
> 2.13.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v2 2/4] selftests/ftrace: Add a test to probe module functions

2017-07-02 Thread Masami Hiramatsu
On Thu, 29 Jun 2017 19:05:37 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> Add a kprobes test to ensure that we are able to add a probe on a
> module function using 'p :' format, without having to
> specify a probe name.
> 
> Suggested-by: Masami Hiramatsu <mhira...@kernel.org>
> Acked-by: Masami Hiramatsu <mhira...@kernel.org>
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  .../testing/selftests/ftrace/test.d/kprobe/probe_module.tc | 14 
> ++
>  1 file changed, 14 insertions(+)
>  create mode 100644 
> tools/testing/selftests/ftrace/test.d/kprobe/probe_module.tc
> 
> diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/probe_module.tc 
> b/tools/testing/selftests/ftrace/test.d/kprobe/probe_module.tc
> new file mode 100644
> index ..ea7657041ba6
> --- /dev/null
> +++ b/tools/testing/selftests/ftrace/test.d/kprobe/probe_module.tc
> @@ -0,0 +1,14 @@
> +#!/bin/sh
> +# description: Kprobe dynamic event - probing module
> +
> +[ -f kprobe_events ] || exit_unsupported # this is configurable
> +
> +echo 0 > events/enable
> +echo > kprobe_events
> +export MOD=`lsmod | head -n 2 | tail -n 1 | cut -f1 -d" "`
> +export FUNC=`grep -m 1 ".* t .*\\[$MOD\\]" /proc/kallsyms | xargs | cut -f3 
> -d" "`
> +[ "x" != "x$MOD" -a "y" != "y$FUNC" ] || exit_untested

Could you also add below case?

echo p:probe_$MOD/$FUNC $MOD/$FUNC > kprobe_events 

This is for "new event with name on module" case, your one is for "new event 
without name on module (automatic name generation)"

We should have different test case, because those kicks slightly different 
parts in kprobe tracer.

Thank you,

> +echo p $MOD:$FUNC > kprobe_events
> +grep $MOD kprobe_events
> +echo > kprobe_events
> +clear_trace
> -- 
> 2.13.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 2/2] selftests/ftrace: Update multiple kprobes test for powerpc

2017-06-28 Thread Masami Hiramatsu
On Thu, 29 Jun 2017 00:13:24 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> On 2017/06/28 11:16PM, Masami Hiramatsu wrote:
> > > > diff --git 
> > > > a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc 
> > > > b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc
> > > > new file mode 100644
> > > > index 000..d259031
> > > > --- /dev/null
> > > > +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc
> > > > @@ -0,0 +1,28 @@
> > > > +#!/bin/sh
> > > > +# description: Kprobe event auto/manual naming
> > > > +
> > > > +disable_events
> > > > +echo > kprobe_events
> > > > +
> > > > +:;: "Add an event on function without name" ;:
> > > > +
> > > > +FUNC=`grep -m 10 " [tT] [^.]*$" /proc/kallsyms | tail -n 1 | cut -f 3 
> > > > -d " "`
> > > 
> > > On powerpc, this always ends up using a blacklisted function. So, I 
> > > think we need a way to find a function that is not black listed.  
> > 
> > Hmm, if we increase the -m argument, like -m 100, is that still
> > in a blacklisted function?
> 
> Yes, most of the initial symbols are exception vectors which are 
> blacklisted.

Hmm, then how about this? :)

grep _stext -A 1000 | grep -m 10 " [tT] [^.]*$" /proc/kallsyms

> 
> > 
> > > However, one of the issues is that debugfs does not show all the address 
> > > ranges that are blacklisted. I am coming up with a way to address that 
> > > and will post patches once I have it working.
> > 
> > Would you find that is only on powerpc or generic issue?
> 
> I meant the address _ranges_ that are blacklisted such as the ones with 
> __kprobes annotation and __entry_text and so on.

I see, but we can also check the address by comparing the address
of symbols, which also can be retrieved from kallsyms.
Since the test case is also applied to stable kernel, I don't want
to make it depending on some special kernel tweaks.

> > 
> > > 
> > > With those patches, we should be able to select symbols that are not 
> > > blacklisted.
> > 
> > Or, maybe we can use generic function, like "schedule" or "vfs_read"
> > etc.
> 
> Yes, I think this will be good for the generic test, but may not help 
> selecting a dot symbol on powerpc.

Right, and it depends on what gcc version and option is specified.
So, maybe we can skip the test if there is no such symbols.

I intended to test the symbols with some dot-suffix, but it seems
ppc64 has dot-started symbols, right? If there is no dot-suffixed
symbols, I think this test should skip the test case.

Thank you,



-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 2/2] selftests/ftrace: Update multiple kprobes test for powerpc

2017-06-28 Thread Masami Hiramatsu
On Wed, 28 Jun 2017 14:58:46 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> On 2017/06/24 08:06PM, Masami Hiramatsu wrote:
> > On Sat, 24 Jun 2017 02:30:21 +0900
> > Masami Hiramatsu <mhira...@kernel.org> wrote:
> > 
> > > On Thu, 22 Jun 2017 22:33:25 +0530
> > > "Naveen N. Rao" <naveen.n....@linux.vnet.ibm.com> wrote:
> > > 
> > > > On 2017/06/22 06:07PM, Masami Hiramatsu wrote:
> > > > > On Thu, 22 Jun 2017 00:20:28 +0530
> > > > > "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:
> > > > > 
> > > > > > KPROBES_ON_FTRACE is only available on powerpc64le. Update comment 
> > > > > > to
> > > > > > clarify this.
> > > > > > 
> > > > > > Also, we should use an offset of 8 to ensure that the probe does not
> > > > > > fall on ftrace location. The current offset of 4 will fall before 
> > > > > > the
> > > > > > function local entry point and won't fire, while an offset of 12 or 
> > > > > > 16
> > > > > > will fall on ftrace location. Offset 8 is currently guaranteed to 
> > > > > > not be
> > > > > > the ftrace location.
> > > > > 
> > > > > OK, these part seems good to me.
> > > > > 
> > > > > > 
> > > > > > Finally, do not filter out symbols with a dot. Powerpc Elfv1 uses 
> > > > > > dot
> > > > > > prefix for all functions and this prevents us from testing some of 
> > > > > > those
> > > > > > symbols. Furthermore, with the patch to derive event names properly 
> > > > > > in
> > > > > > the presence of ':' and '.', such names are accepted by 
> > > > > > kprobe_events
> > > > > > and constitutes a good test for those symbols.
> > > > > 
> > > > > Hmm, the reason why I added such filter was to avoid symbols including
> > > > > gcc-generated suffixes like as .constprop or .isra etc.
> > > > 
> > > > I see.
> > > > 
> > > > I do wonder -- is there a problem if we try probing those symbols? On 
> > > > my 
> > > > local x86 vm, I don't see an issue probing it especially with the 
> > > > previous patch to enable probing with symbols having a '.' or ':'.
> > > > 
> > > > Furthermore, since this is for testing kprobe_events, I feel it is good 
> > > > to try probing those symbols too to catch any weird errors we may hit.
> > > 
> > > Yes, and that is not what this testcase is aiming to. That testcase should
> > > be a separated one, with correct error handling.
> 
> Ok, I will re-send the patch by changing the pattern.
> 
> > 
> > Hi Naveen,
> > 
> > Here is the testcase which I meant above. This may help if there is any
> > regression related to this specific issue.
> 
> Nice!
> I tested this and there are a few small issues on powerpc...
> 
> > 
> > Thank you,
> > 
> > -
> > 
> > selftests: ftrace: Add a testcase for kprobe event naming
> > 
> > From: Masami Hiramatsu <mhira...@kernel.org>
> > 
> > Add a testcase for kprobe event naming. This testcase
> > checks whether the kprobe events can automatically ganerate
> > its event name on normal function and dot-suffixed function.
> > Also it checks whether the kprobe events can correctly
> > define new event with given event name and group name.
> > 
> > Signed-off-by: Masami Hiramatsu <mhira...@kernel.org>
> > ---
> >  .../ftrace/test.d/kprobe/kprobe_eventname.tc   |   28 
> > 
> >  1 file changed, 28 insertions(+)
> >  create mode 100644 
> > tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc
> > 
> > diff --git 
> > a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc 
> > b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc
> > new file mode 100644
> > index 000..d259031
> > --- /dev/null
> > +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc
> > @@ -0,0 +1,28 @@
> > +#!/bin/sh
> > +# description: Kprobe event auto/manual naming
> > +
> > +disable_events
> > +echo > kprobe_events
> > +
> > +:;: "Add an event on function without name" ;:
> > +
>

Re: [PATCH 2/2] selftests/ftrace: Update multiple kprobes test for powerpc

2017-06-24 Thread Masami Hiramatsu
On Sat, 24 Jun 2017 02:30:21 +0900
Masami Hiramatsu <mhira...@kernel.org> wrote:

> On Thu, 22 Jun 2017 22:33:25 +0530
> "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:
> 
> > On 2017/06/22 06:07PM, Masami Hiramatsu wrote:
> > > On Thu, 22 Jun 2017 00:20:28 +0530
> > > "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:
> > > 
> > > > KPROBES_ON_FTRACE is only available on powerpc64le. Update comment to
> > > > clarify this.
> > > > 
> > > > Also, we should use an offset of 8 to ensure that the probe does not
> > > > fall on ftrace location. The current offset of 4 will fall before the
> > > > function local entry point and won't fire, while an offset of 12 or 16
> > > > will fall on ftrace location. Offset 8 is currently guaranteed to not be
> > > > the ftrace location.
> > > 
> > > OK, these part seems good to me.
> > > 
> > > > 
> > > > Finally, do not filter out symbols with a dot. Powerpc Elfv1 uses dot
> > > > prefix for all functions and this prevents us from testing some of those
> > > > symbols. Furthermore, with the patch to derive event names properly in
> > > > the presence of ':' and '.', such names are accepted by kprobe_events
> > > > and constitutes a good test for those symbols.
> > > 
> > > Hmm, the reason why I added such filter was to avoid symbols including
> > > gcc-generated suffixes like as .constprop or .isra etc.
> > 
> > I see.
> > 
> > I do wonder -- is there a problem if we try probing those symbols? On my 
> > local x86 vm, I don't see an issue probing it especially with the 
> > previous patch to enable probing with symbols having a '.' or ':'.
> > 
> > Furthermore, since this is for testing kprobe_events, I feel it is good 
> > to try probing those symbols too to catch any weird errors we may hit.
> 
> Yes, and that is not what this testcase is aiming to. That testcase should
> be a separated one, with correct error handling.

Hi Naveen,

Here is the testcase which I meant above. This may help if there is any
regression related to this specific issue.

Thank you,

-

selftests: ftrace: Add a testcase for kprobe event naming

From: Masami Hiramatsu <mhira...@kernel.org>

Add a testcase for kprobe event naming. This testcase
checks whether the kprobe events can automatically ganerate
its event name on normal function and dot-suffixed function.
Also it checks whether the kprobe events can correctly
define new event with given event name and group name.

Signed-off-by: Masami Hiramatsu <mhira...@kernel.org>
---
 .../ftrace/test.d/kprobe/kprobe_eventname.tc   |   28 
 1 file changed, 28 insertions(+)
 create mode 100644 
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc

diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc 
b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc
new file mode 100644
index 000..d259031
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc
@@ -0,0 +1,28 @@
+#!/bin/sh
+# description: Kprobe event auto/manual naming
+
+disable_events
+echo > kprobe_events
+
+:;: "Add an event on function without name" ;:
+
+FUNC=`grep -m 10 " [tT] [^.]*$" /proc/kallsyms | tail -n 1 | cut -f 3 -d " "`
+echo p $FUNC > kprobe_events
+test -d events/kprobes/p_${FUNC}_0 || exit_failure
+
+:;: "Add an event on function with new name" ;:
+
+echo p:event1 $FUNC > kprobe_events
+test -d events/kprobes/event1 || exit_failure
+
+:;: "Add an event on function with new name and group" ;:
+
+echo p:kprobes2/event2 $FUNC > kprobe_events
+test -d events/kprobes2/event2 || exit_failure
+
+:;: "Add an event on dot function without name" ;:
+
+FUNC=`grep -m 10 " [tT] .*\..*$" /proc/kallsyms | tail -n 1 | cut -f 3 -d " "`
+echo p $FUNC > kprobe_events
+EVENT=`grep $FUNC kprobe_events | cut -f 1 -d " " | cut -f 2 -d:` || 
exit_failure
+test -d events/$EVENT || exit_failure
-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 1/2] trace/kprobes: Sanitize derived event names

2017-06-23 Thread Masami Hiramatsu
On Fri, 23 Jun 2017 00:33:45 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> On 2017/06/22 06:29PM, Masami Hiramatsu wrote:
> > On Thu, 22 Jun 2017 00:20:27 +0530
> > "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:
> > 
> > > When we derive event names, convert some expected symbols (such as ':'
> > > used to specify module:name and '.' present in some symbols) into
> > > underscores so that the event name is not rejected.
> > 
> > Oops, ok, this is my mistake.
> > 
> > Acked-by: Masami Hiramatsu <mhira...@kernel.org>
> > 
> > This must be marked as bugfix for stable trees.
> > 
> > Could you also add a testcase for this (module name) bug?
> > 
> > MODNAME=`lsmod | head -n 2 | tail -n 1 | cut -f 1 -d " "`
> > FUNCNAME=`grep -m 1 "\\[$MODNAME\\]" /proc/kallsyms | xargs | cut -f 3 -d " 
> > "`
> > 
> > May gives you a target name :)
> 
> Sure. Here is a test.
> 
> Thanks for the review,
> Naveen
> 
> -
> [PATCH] selftests/ftrace: Add a test to probe module functions
> 
> Add a kprobes test to ensure that we are able to add a probe on a
> module function using 'p :' format, without having to
> specify a probe name.
> 
> Suggested-by: Masami Hiramatsu <mhira...@kernel.org>
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>

Perfect! :)

Acked-by: Masami Hiramatsu <mhira...@kernel.org>

Thanks!

> ---
>  .../testing/selftests/ftrace/test.d/kprobe/probe_module.tc | 14 
> ++
>  1 file changed, 14 insertions(+)
>  create mode 100644 
> tools/testing/selftests/ftrace/test.d/kprobe/probe_module.tc
> 
> diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/probe_module.tc 
> b/tools/testing/selftests/ftrace/test.d/kprobe/probe_module.tc
> new file mode 100644
> index ..ea7657041ba6
> --- /dev/null
> +++ b/tools/testing/selftests/ftrace/test.d/kprobe/probe_module.tc
> @@ -0,0 +1,14 @@
> +#!/bin/sh
> +# description: Kprobe dynamic event - probing module
> +
> +[ -f kprobe_events ] || exit_unsupported # this is configurable
> +
> +echo 0 > events/enable
> +echo > kprobe_events
> +export MOD=`lsmod | head -n 2 | tail -n 1 | cut -f1 -d" "`
> +export FUNC=`grep -m 1 ".* t .*\\[$MOD\\]" /proc/kallsyms | xargs | cut -f3 
> -d" "`
> +[ "x" != "x$MOD" -a "y" != "y$FUNC" ] || exit_untested
> +echo p $MOD:$FUNC > kprobe_events
> +grep $MOD kprobe_events
> +echo > kprobe_events
> +clear_trace
> -- 
> 2.13.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 2/2] selftests/ftrace: Update multiple kprobes test for powerpc

2017-06-23 Thread Masami Hiramatsu
On Thu, 22 Jun 2017 22:33:25 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> On 2017/06/22 06:07PM, Masami Hiramatsu wrote:
> > On Thu, 22 Jun 2017 00:20:28 +0530
> > "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:
> > 
> > > KPROBES_ON_FTRACE is only available on powerpc64le. Update comment to
> > > clarify this.
> > > 
> > > Also, we should use an offset of 8 to ensure that the probe does not
> > > fall on ftrace location. The current offset of 4 will fall before the
> > > function local entry point and won't fire, while an offset of 12 or 16
> > > will fall on ftrace location. Offset 8 is currently guaranteed to not be
> > > the ftrace location.
> > 
> > OK, these part seems good to me.
> > 
> > > 
> > > Finally, do not filter out symbols with a dot. Powerpc Elfv1 uses dot
> > > prefix for all functions and this prevents us from testing some of those
> > > symbols. Furthermore, with the patch to derive event names properly in
> > > the presence of ':' and '.', such names are accepted by kprobe_events
> > > and constitutes a good test for those symbols.
> > 
> > Hmm, the reason why I added such filter was to avoid symbols including
> > gcc-generated suffixes like as .constprop or .isra etc.
> 
> I see.
> 
> I do wonder -- is there a problem if we try probing those symbols? On my 
> local x86 vm, I don't see an issue probing it especially with the 
> previous patch to enable probing with symbols having a '.' or ':'.
> 
> Furthermore, since this is for testing kprobe_events, I feel it is good 
> to try probing those symbols too to catch any weird errors we may hit.

Yes, and that is not what this testcase is aiming to. That testcase should
be a separated one, with correct error handling.

Thank you,

> 
> Thanks for the review!
> - Naveen
> 
> 
> > So if the Powerpc Elfv1 use dot prefix, that is OK, in that case,
> > could you update the filter as "^.*\\..*" ?
> > 
> > Thank you,
> > 
> > > 
> > > Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> > > ---
> > >  tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc | 8 
> > > 
> > >  1 file changed, 4 insertions(+), 4 deletions(-)
> > > 
> > > diff --git 
> > > a/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc 
> > > b/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc
> > > index f4d1ff785d67..d209c071b2c0 100644
> > > --- a/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc
> > > +++ b/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc
> > > @@ -2,16 +2,16 @@
> > >  # description: Register/unregister many kprobe events
> > >  
> > >  # ftrace fentry skip size depends on the machine architecture.
> > > -# Currently HAVE_KPROBES_ON_FTRACE defined on x86 and powerpc
> > > +# Currently HAVE_KPROBES_ON_FTRACE defined on x86 and powerpc64le
> > >  case `uname -m` in
> > >x86_64|i[3456]86) OFFS=5;;
> > > -  ppc*) OFFS=4;;
> > > +  ppc64le) OFFS=8;;
> > >*) OFFS=0;;
> > >  esac
> > >  
> > >  echo "Setup up to 256 kprobes"
> > > -grep t /proc/kallsyms | cut -f3 -d" " | grep -v .*\\..* | \
> > > -head -n 256 | while read i; do echo p ${i}+${OFFS} ; done > 
> > > kprobe_events ||:
> > > +grep t /proc/kallsyms | cut -f3 -d" " | head -n 256 | \
> > > +while read i; do echo p ${i}+${OFFS} ; done > kprobe_events ||:
> > >  
> > >  echo 1 > events/kprobes/enable
> > >  echo 0 > events/kprobes/enable
> > > -- 
> > > 2.13.1
> > > 
> > 
> > 
> > -- 
> > Masami Hiramatsu <mhira...@kernel.org>
> > 
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 1/2] trace/kprobes: Sanitize derived event names

2017-06-22 Thread Masami Hiramatsu
On Thu, 22 Jun 2017 00:20:27 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> When we derive event names, convert some expected symbols (such as ':'
> used to specify module:name and '.' present in some symbols) into
> underscores so that the event name is not rejected.

Oops, ok, this is my mistake.

Acked-by: Masami Hiramatsu <mhira...@kernel.org>

This must be marked as bugfix for stable trees.

Could you also add a testcase for this (module name) bug?

MODNAME=`lsmod | head -n 2 | tail -n 1 | cut -f 1 -d " "`
FUNCNAME=`grep -m 1 "\\[$MODNAME\\]" /proc/kallsyms | xargs | cut -f 3 -d " "`

May gives you a target name :)

Thank you,

> 
> Before this patch:
> # echo 'p kobject_example:foo_store' > kprobe_events
> trace_kprobe: Failed to allocate trace_probe.(-22)
> -sh: write error: Invalid argument
> 
> After this patch:
> # echo 'p kobject_example:foo_store' > kprobe_events
> # cat kprobe_events
> p:kprobes/p_kobject_example_foo_store_0 kobject_example:foo_store
> 
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  kernel/trace/trace_kprobe.c | 9 +
>  1 file changed, 9 insertions(+)
> 
> diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
> index c129fca6ec99..44fd819aa33d 100644
> --- a/kernel/trace/trace_kprobe.c
> +++ b/kernel/trace/trace_kprobe.c
> @@ -598,6 +598,14 @@ static struct notifier_block trace_kprobe_module_nb = {
>   .priority = 1   /* Invoked after kprobe module callback */
>  };
>  
> +/* Convert certain expected symbols into '_' when generating event names */
> +static inline void sanitize_event_name(char *name)
> +{
> + while (*name++ != '\0')
> + if (*name == ':' || *name == '.')
> + *name = '_';
> +}
> +
>  static int create_trace_kprobe(int argc, char **argv)
>  {
>   /*
> @@ -740,6 +748,7 @@ static int create_trace_kprobe(int argc, char **argv)
>   else
>   snprintf(buf, MAX_EVENT_NAME_LEN, "%c_0x%p",
>is_return ? 'r' : 'p', addr);
> + sanitize_event_name(buf);
>   event = buf;
>   }
>   tk = alloc_trace_kprobe(group, event, addr, symbol, offset, maxactive,
> -- 
> 2.13.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 2/2] selftests/ftrace: Update multiple kprobes test for powerpc

2017-06-22 Thread Masami Hiramatsu
On Thu, 22 Jun 2017 00:20:28 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> KPROBES_ON_FTRACE is only available on powerpc64le. Update comment to
> clarify this.
> 
> Also, we should use an offset of 8 to ensure that the probe does not
> fall on ftrace location. The current offset of 4 will fall before the
> function local entry point and won't fire, while an offset of 12 or 16
> will fall on ftrace location. Offset 8 is currently guaranteed to not be
> the ftrace location.

OK, these part seems good to me.

> 
> Finally, do not filter out symbols with a dot. Powerpc Elfv1 uses dot
> prefix for all functions and this prevents us from testing some of those
> symbols. Furthermore, with the patch to derive event names properly in
> the presence of ':' and '.', such names are accepted by kprobe_events
> and constitutes a good test for those symbols.

Hmm, the reason why I added such filter was to avoid symbols including
gcc-generated suffixes like as .constprop or .isra etc.
So if the Powerpc Elfv1 use dot prefix, that is OK, in that case,
could you update the filter as "^.*\\..*" ?

Thank you,

> 
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc | 8 
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc 
> b/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc
> index f4d1ff785d67..d209c071b2c0 100644
> --- a/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc
> +++ b/tools/testing/selftests/ftrace/test.d/kprobe/multiple_kprobes.tc
> @@ -2,16 +2,16 @@
>  # description: Register/unregister many kprobe events
>  
>  # ftrace fentry skip size depends on the machine architecture.
> -# Currently HAVE_KPROBES_ON_FTRACE defined on x86 and powerpc
> +# Currently HAVE_KPROBES_ON_FTRACE defined on x86 and powerpc64le
>  case `uname -m` in
>x86_64|i[3456]86) OFFS=5;;
> -  ppc*) OFFS=4;;
> +  ppc64le) OFFS=8;;
>*) OFFS=0;;
>  esac
>  
>  echo "Setup up to 256 kprobes"
> -grep t /proc/kallsyms | cut -f3 -d" " | grep -v .*\\..* | \
> -head -n 256 | while read i; do echo p ${i}+${OFFS} ; done > kprobe_events ||:
> +grep t /proc/kallsyms | cut -f3 -d" " | head -n 256 | \
> +while read i; do echo p ${i}+${OFFS} ; done > kprobe_events ||:
>  
>  echo 1 > events/kprobes/enable
>  echo 0 > events/kprobes/enable
> -- 
> 2.13.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH] kernel/kprobes: Add test to validate pt_regs

2017-06-13 Thread Masami Hiramatsu
On Wed, 14 Jun 2017 11:40:08 +0900
Masami Hiramatsu <mhira...@kernel.org> wrote:

> On Fri,  9 Jun 2017 00:53:08 +0530
> "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:
> 
> > Add a test to verify that the registers passed in pt_regs on kprobe
> > (trap), optprobe (jump) and kprobe_on_ftrace (ftrace_caller) are
> > accurate. The tests are exercized if KPROBES_SANITY_TEST is enabled.
> 
> Great!
> 
> > 
> > Implemented for powerpc64. Other architectures will have to implement
> > the relevant arch_* helpers and define HAVE_KPROBES_REGS_SANITY_TEST.
> 
> Hmm, why don't you define that in arch/powerpc/Kconfig ?
> Also, could you split this into 3 patches for each case ?
> 
> > 
> > Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> > ---
> >  arch/powerpc/include/asm/kprobes.h  |   4 +
> >  arch/powerpc/lib/Makefile   |   3 +-
> >  arch/powerpc/lib/test_kprobe_regs.S |  62 
> >  arch/powerpc/lib/test_kprobes.c | 115 ++
> >  include/linux/kprobes.h |  11 +++
> >  kernel/test_kprobes.c   | 183 
> > 
> >  6 files changed, 377 insertions(+), 1 deletion(-)
> >  create mode 100644 arch/powerpc/lib/test_kprobe_regs.S
> >  create mode 100644 arch/powerpc/lib/test_kprobes.c
> > 
> > diff --git a/arch/powerpc/include/asm/kprobes.h 
> > b/arch/powerpc/include/asm/kprobes.h
> > index 566da372e02b..10c91d3132a1 100644
> > --- a/arch/powerpc/include/asm/kprobes.h
> > +++ b/arch/powerpc/include/asm/kprobes.h
> > @@ -124,6 +124,10 @@ static inline int skip_singlestep(struct kprobe *p, 
> > struct pt_regs *regs,
> > return 0;
> >  }
> >  #endif
> > +#if defined(CONFIG_KPROBES_SANITY_TEST) && defined(CONFIG_PPC64)
> > +#define HAVE_KPROBES_REGS_SANITY_TEST
> > +void arch_kprobe_regs_set_ptregs(struct pt_regs *regs);
> > +#endif
> >  #else
> >  static inline int kprobe_handler(struct pt_regs *regs) { return 0; }
> >  static inline int kprobe_post_handler(struct pt_regs *regs) { return 0; }
> > diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
> > index 3c3146ba62da..8a0bb8e20179 100644
> > --- a/arch/powerpc/lib/Makefile
> > +++ b/arch/powerpc/lib/Makefile
> > @@ -27,7 +27,8 @@ obj64-y   += copypage_64.o copyuser_64.o mem_64.o 
> > hweight_64.o \
> >  
> >  obj64-$(CONFIG_SMP)+= locks.o
> >  obj64-$(CONFIG_ALTIVEC)+= vmx-helper.o
> > -obj64-$(CONFIG_KPROBES_SANITY_TEST) += test_emulate_step.o
> > +obj64-$(CONFIG_KPROBES_SANITY_TEST) += test_emulate_step.o 
> > test_kprobe_regs.o \
> > +  test_kprobes.o
> >  
> >  obj-y  += checksum_$(BITS).o checksum_wrappers.o
> >  
> > diff --git a/arch/powerpc/lib/test_kprobe_regs.S 
> > b/arch/powerpc/lib/test_kprobe_regs.S
> > new file mode 100644
> > index ..4e95eca6dcd3
> > --- /dev/null
> > +++ b/arch/powerpc/lib/test_kprobe_regs.S
> > @@ -0,0 +1,62 @@
> > +/*
> > + * test_kprobe_regs: architectural helpers for validating pt_regs
> > + *  received on a kprobe.
> > + *
> > + * Copyright 2017 Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> > + *   IBM Corporation
> > + *
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License
> > + * as published by the Free Software Foundation; version 2
> > + * of the License.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +
> > +_GLOBAL(arch_kprobe_regs_function)
> > +   mflrr0
> > +   std r0, LRSAVE(r1)
> > +   stdur1, -SWITCH_FRAME_SIZE(r1)
> > +
> > +   /* Tell pre handler about our pt_regs location */
> > +   addir3, r1, STACK_FRAME_OVERHEAD
> > +   bl  arch_kprobe_regs_set_ptregs
> > +
> > +   /* Load back our true LR */
> > +   ld  r0, (SWITCH_FRAME_SIZE + LRSAVE)(r1)
> > +   mtlrr0
> > +
> > +   /* Save all SPRs that we care about */
> > +   mfctr   r0
> > +   std r0, _CTR(r1)
> > +   mflrr0
> > +   std r0, _LINK(r1)
> > +   mfspr   r0, SPRN_XER
> > +   std r0, _XER(r1)
> > +   mfcrr0
> > +   std r0, _CCR(r1)
> > +
> > +   /* Now, save all GPRs */
> > +   SAVE_2GPRS(0, r1)
> > +   SAVE_10GPRS(2, r1)
> > +   SAVE_10GPRS(12, r1)
> > +   SAVE_10GPRS(22, r1)
> 

Re: [PATCH] kernel/kprobes: Add test to validate pt_regs

2017-06-13 Thread Masami Hiramatsu
errors++;
> + goto summary;
> + }
> +
> + /* Let's see if this probe was optimized */
> + addr = kprobe_lookup_name(kpor.symbol_name, 0);
> + if (addr && *addr == BREAKPOINT_INSTRUCTION) {
> + pr_info("kprobe not optimized yet... skipping optprobe test\n");

Yes, this may take a while... you may need to wait for optimizer,
like wait_for_kprobe_optimizer().

Thank you,

> +     unregister_kprobe();
> + goto summary;
> + }
> +
> + preh_val = 0;
> + arch_kprobe_regs_function();
> + unregister_kprobe();
> +
> + if (preh_val == 0) {
> + pr_err("optprobe pre_handler regs validation failed\n");
> + handler_errors++;
> + }
> +
> +summary:
> + if (errors)
> + pr_err("BUG: %d out of %d tests failed\n", errors, num_tests);
> + else if (handler_errors)
> + pr_err("BUG: %d error(s) running handlers\n", handler_errors);
> + else
> + pr_info("passed successfully\n");
> +}
> +#endif
> +#endif
> +
>  int init_test_probes(void)
>  {
>   int ret;
> @@ -378,12 +539,34 @@ int init_test_probes(void)
>   errors++;
>  #endif /* CONFIG_KRETPROBES */
>  
> +#ifdef HAVE_KPROBES_REGS_SANITY_TEST
> + num_tests++;
> + ret = test_kprobe_regs();
> + if (ret < 0)
> + errors++;
> +
> +#ifdef CONFIG_KPROBES_ON_FTRACE
> + num_tests++;
> + ret = test_kp_on_ftrace_regs();
> + if (ret < 0)
> + errors++;
> +#endif
> +
> +#ifdef CONFIG_OPTPROBES
> + num_tests++;
> + test_optprobe_regs_setup();
> + schedule_delayed_work(_optprobe_regs_work, 10);
> +#endif
> +#endif
> +
> +#if !defined(HAVE_KPROBES_REGS_SANITY_TEST) || !defined(CONFIG_OPTPROBES)
>   if (errors)
>   pr_err("BUG: %d out of %d tests failed\n", errors, num_tests);
>   else if (handler_errors)
>   pr_err("BUG: %d error(s) running handlers\n", handler_errors);
>   else
>   pr_info("passed successfully\n");
> +#endif
>  
>   return 0;
>  }
> -- 
> 2.12.2
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v2 3/4] powerpc/kprobes_on_ftrace: Skip livepatch_handler() for jprobes

2017-06-08 Thread Masami Hiramatsu
On Thu,  1 Jun 2017 16:18:17 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> ftrace_caller() depends on a modified regs->nip to detect if a certain
> function has been livepatched. However, with KPROBES_ON_FTRACE, it is
> possible for regs->nip to have been modified by the kprobes pre_handler
> (jprobes, for instance). In this case, we do not want to invoke the
> livepatch_handler so as not to consume the livepatch stack.
> 
> To distinguish between the two (kprobes and livepatch), we check if
> there is an active kprobe on the current function. If there is, then we
> know for sure that it must have modified the NIP as we don't support
> livepatching a kprobe'd function. In this case, we simply skip the
> livepatch_handler and branch to the new NIP. Otherwise, the
> livepatch_handler is invoked.

OK, this logic seems good to me, but I weould like to leave it for
PPC64 maintainer too.

Reviewed-by: Masami Hiramatsu <mhira...@kernel.org>

Thanks!
> 
> Fixes: ead514d5fb30a ("powerpc/kprobes: Add support for
> KPROBES_ON_FTRACE")
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
> v2: Changed to use current_kprobe->addr to determine jprobe vs.
> livepatch.
> 
>  arch/powerpc/include/asm/kprobes.h |  1 +
>  arch/powerpc/kernel/kprobes.c  |  6 +
>  arch/powerpc/kernel/trace/ftrace_64_mprofile.S | 32 
> ++
>  3 files changed, 35 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/kprobes.h 
> b/arch/powerpc/include/asm/kprobes.h
> index a83821f33ea3..8814a7249ceb 100644
> --- a/arch/powerpc/include/asm/kprobes.h
> +++ b/arch/powerpc/include/asm/kprobes.h
> @@ -103,6 +103,7 @@ extern int kprobe_exceptions_notify(struct notifier_block 
> *self,
>  extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
>  extern int kprobe_handler(struct pt_regs *regs);
>  extern int kprobe_post_handler(struct pt_regs *regs);
> +extern int is_current_kprobe_addr(unsigned long addr);
>  #ifdef CONFIG_KPROBES_ON_FTRACE
>  extern int skip_singlestep(struct kprobe *p, struct pt_regs *regs,
>  struct kprobe_ctlblk *kcb);
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index 0554d6e66194..ec9d94c82fbd 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -43,6 +43,12 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
>  
>  struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
>  
> +int is_current_kprobe_addr(unsigned long addr)
> +{
> + struct kprobe *p = kprobe_running();
> + return (p && (unsigned long)p->addr == addr) ? 1 : 0;
> +}
> +
>  bool arch_within_kprobe_blacklist(unsigned long addr)
>  {
>   return  (addr >= (unsigned long)__kprobes_text_start &&
> diff --git a/arch/powerpc/kernel/trace/ftrace_64_mprofile.S 
> b/arch/powerpc/kernel/trace/ftrace_64_mprofile.S
> index fa0921410fa4..e6837e85ec28 100644
> --- a/arch/powerpc/kernel/trace/ftrace_64_mprofile.S
> +++ b/arch/powerpc/kernel/trace/ftrace_64_mprofile.S
> @@ -99,13 +99,37 @@ ftrace_call:
>   bl  ftrace_stub
>   nop
>  
> - /* Load ctr with the possibly modified NIP */
> - ld  r3, _NIP(r1)
> - mtctr   r3
> + /* Load the possibly modified NIP */
> + ld  r15, _NIP(r1)
> +
>  #ifdef CONFIG_LIVEPATCH
> - cmpdr14,r3  /* has NIP been altered? */
> + cmpdr14, r15/* has NIP been altered? */
> +#endif
> +
> +#if defined(CONFIG_LIVEPATCH) && defined(CONFIG_KPROBES_ON_FTRACE)
> + beq 1f
> +
> + /* Check if there is an active kprobe on us */
> + subir3, r14, 4
> + bl  is_current_kprobe_addr
> + nop
> +
> + /*
> +  * If r3 == 1, then this is a kprobe/jprobe.
> +  * else, this is livepatched function.
> +  *
> +  * The subsequent conditional branch for livepatch_handler
> +  * will use the result of this compare. For kprobe/jprobe,
> +  * we just need to branch to the new NIP, so nothing special
> +  * is needed.
> +  */
> + cmpdi   r3, 1
> +1:
>  #endif
>  
> + /* Load CTR with the possibly modified NIP */
> + mtctr   r15
> +
>   /* Restore gprs */
>   REST_GPR(0,r1)
>   REST_10GPRS(2,r1)
> -- 
> 2.12.2
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v2 1/4] powerpc/kprobes: Pause function_graph tracing during jprobes handling

2017-06-08 Thread Masami Hiramatsu
On Thu,  1 Jun 2017 16:18:15 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> This fixes a crash when function_graph and jprobes are used together.
> This is essentially commit 237d28db036e ("ftrace/jprobes/x86: Fix
> conflict between jprobes and function graph tracing"), but for powerpc.
> 
> Jprobes breaks function_graph tracing since the jprobe hook needs to use
> jprobe_return(), which never returns back to the hook, but instead to
> the original jprobe'd function. The solution is to momentarily pause
> function_graph tracing before invoking the jprobe hook and re-enable it
> when returning back to the original jprobe'd function.
> 
> Fixes: 6794c78243bfd ("powerpc64: port of the function graph tracer")
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>

Acked-by: Masami Hiramatsu <mhira...@kernel.org>

Thanks!

> ---
> v2: No changes since v1.
> 
>  arch/powerpc/kernel/kprobes.c | 11 +++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index e1fb95385a9e..0554d6e66194 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -610,6 +610,15 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs 
> *regs)
>   regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
>  #endif
>  
> + /*
> +  * jprobes use jprobe_return() which skips the normal return
> +  * path of the function, and this messes up the accounting of the
> +  * function graph tracer.
> +  *
> +  * Pause function graph tracing while performing the jprobe function.
> +  */
> + pause_graph_tracing();
> +
>   return 1;
>  }
>  NOKPROBE_SYMBOL(setjmp_pre_handler);
> @@ -635,6 +644,8 @@ int longjmp_break_handler(struct kprobe *p, struct 
> pt_regs *regs)
>* saved regs...
>*/
>   memcpy(regs, >jprobe_saved_regs, sizeof(struct pt_regs));
> + /* It's OK to start function graph tracing again */
> + unpause_graph_tracing();
>   preempt_enable_no_resched();
>   return 1;
>  }
> -- 
> 2.12.2
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 2/2] powerpc/jprobes: Validate break handler invocation as being due to a jprobe_return()

2017-05-16 Thread Masami Hiramatsu
On Mon, 15 May 2017 23:35:04 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> Fix a circa 2005 FIXME by implementing a check to ensure that we
> actually got into the jprobe break handler() due to the trap in
> jprobe_return().
> 
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  arch/powerpc/kernel/kprobes.c | 20 +---
>  1 file changed, 9 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index 19b053475758..1ebeb8c482db 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -627,25 +627,23 @@ NOKPROBE_SYMBOL(setjmp_pre_handler);
>  
>  void __used jprobe_return(void)
>  {
> - asm volatile("trap" ::: "memory");
> + asm volatile("jprobe_return_trap:\n"
> +  "trap\n"
> +  ::: "memory");
>  }
>  NOKPROBE_SYMBOL(jprobe_return);
>  
> -static void __used jprobe_return_end(void)
> -{
> -}
> -NOKPROBE_SYMBOL(jprobe_return_end);
> -
>  int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
>  {
>   struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
>   unsigned long sp;
>  
> - /*
> -  * FIXME - we should ideally be validating that we got here 'cos
> -  * of the "trap" in jprobe_return() above, before restoring the
> -  * saved regs...
> -  */
> + if (regs->nip != ppc_kallsyms_lookup_name("jprobe_return_trap")) {
> + WARN(1, "longjmp_break_handler NIP (0x%lx) does not match 
> jprobe_return_trap (0x%lx)\n",
> + regs->nip, 
> ppc_kallsyms_lookup_name("jprobe_return_trap"));
> + return 0;

If you don't handle this break, you shouldn't warn it, because
program_check_exception() will continue to find how to handle it
by notify_die(). IOW, please return silently, or just add a
debug message.

Thank you,

> + }
> +
>   memcpy(regs, >jprobe_saved_regs, sizeof(struct pt_regs));
>   sp = kernel_stack_pointer(regs);
>   memcpy((void *)sp, >jprobes_stack, MIN_STACK_SIZE(sp));
> -- 
> 2.12.2
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 1/2] powerpc/jprobes: Save and restore the parameter save area

2017-05-16 Thread Masami Hiramatsu
On Mon, 15 May 2017 23:35:03 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:
> diff --git a/arch/powerpc/include/asm/kprobes.h 
> b/arch/powerpc/include/asm/kprobes.h
> index a83821f33ea3..b6960ef213ac 100644
> --- a/arch/powerpc/include/asm/kprobes.h
> +++ b/arch/powerpc/include/asm/kprobes.h
> @@ -61,6 +61,15 @@ extern kprobe_opcode_t optprobe_template_end[];
>  #define MAX_OPTINSN_SIZE (optprobe_template_end - 
> optprobe_template_entry)
>  #define RELATIVEJUMP_SIZEsizeof(kprobe_opcode_t) /* 4 bytes */
>  
> +/* Save upto 16 parameters along with the stack frame header */
> +#define MAX_STACK_SIZE   (STACK_FRAME_PARM_SAVE + (16 * 
> sizeof(unsigned long)))
> +#define MIN_STACK_SIZE(ADDR)\
> + (((MAX_STACK_SIZE) < (((unsigned long)current_thread_info()) + \
> +   THREAD_SIZE - (unsigned long)(ADDR)))\
> +  ? (MAX_STACK_SIZE)\
> +  : (((unsigned long)current_thread_info()) +   \
> + THREAD_SIZE - (unsigned long)(ADDR)))

Could you add CUR_STACK_SIZE(addr) as x86 does instead of repeating similar 
code?

Thank you,


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 0/4] powerpc: build out kprobes blacklist

2017-04-26 Thread Masami Hiramatsu
Hello Naveen,

On Tue, 25 Apr 2017 22:04:05 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> This is the second in the series of patches to build out an appropriate
> kprobes blacklist. This series blacklists system_call() and functions
> involved when handling the trap itself. Not everything is covered, but
> this is the first set of functions that I have tested with. More
> patches to follow once I expand my tests.

OK, btw, have you tested to put kprobes on these functions and
saw kernel panic happened?

> I have converted many labels into private -- these are labels that I
> felt are not necessary to read stack traces. If any of those are
> important to have, please let me know.

At least from the viewpoint of kprobe-blacklist macros, it seems
good to me :)

Reviewed-by: Masami Hiramatsu <mhira...@kernel.org>

for this series.

Thank you,

> 
> - Naveen
> 
> Naveen N. Rao (4):
>   powerpc/kprobes: cleanup system_call_common and blacklist it from
> kprobes
>   powerpc/kprobes: un-blacklist system_call() from kprobes
>   powerpc/kprobes: blacklist functions invoked on a trap
>   powerpc/kprobes: blacklist functions involved when returning from
> exception
> 
>  arch/powerpc/kernel/entry_64.S   | 94 
> +++-
>  arch/powerpc/kernel/exceptions-64s.S |  1 +
>  arch/powerpc/kernel/time.c   |  3 ++
>  arch/powerpc/kernel/traps.c  |  3 ++
>  arch/powerpc/platforms/pseries/dtl.c |  2 +
>  5 files changed, 60 insertions(+), 43 deletions(-)
> 
> -- 
> 2.12.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH] kallsyms: optimize kallsyms_lookup_name() for a few cases

2017-04-26 Thread Masami Hiramatsu
On Thu, 27 Apr 2017 01:38:10 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> Michael Ellerman wrote:
> > "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> writes:
> >> diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
> >> index 6a3b249a2ae1..d134b060564f 100644
> >> --- a/kernel/kallsyms.c
> >> +++ b/kernel/kallsyms.c
> >> @@ -205,6 +205,12 @@ unsigned long kallsyms_lookup_name(const char *name)
> >>unsigned long i;
> >>unsigned int off;
> >>  
> >> +  if (!name || *name == '\0')
> >> +  return false;
> >> +
> >> +  if (strnchr(name, MODULE_NAME_LEN, ':'))
> >> +  return module_kallsyms_lookup_name(name);
> >> +
> >>for (i = 0, off = 0; i < kallsyms_num_syms; i++) {
> >>off = kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf));
> > ... 
> > }
> > return module_kallsyms_lookup_name(name);
> > 
> > Is the rest of the context.
> > 
> > Which looks a bit odd, we already did module lookup previously?
> > 
> > But it's correct, because you can lookup a symbol in a module without a
> > module prefix, it just looks in every module.
> 
> Yes.
> 
> > 
> > You could invert the logic, ie. check that there isn't a ":" in the name
> > and only in that case do the for loop, always falling back to module
> > lookup.
> > 
> > Or just add a comment explaining why we call module lookup in two places.
> 
> Good point. Here's a v2 - I'm using a goto so as to not indent the code too 
> much.
> 
> Thanks for the review!
> - Naveen
> 
> --
> [PATCH v2] kallsyms: optimize kallsyms_lookup_name() for a few cases
> 
> 1. Fail early for invalid/zero length symbols.
> 2. Detect names of the form  and skip checking for kernel
> symbols in that case.
> 

Looks good to me.

Reviewed-by: Masami Hiramatsu <mhira...@kernel.org>

Thanks,


> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  kernel/kallsyms.c | 8 
>  1 file changed, 8 insertions(+)
> 
> diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c
> index 6a3b249a2ae1..f7558dc5c6ac 100644
> --- a/kernel/kallsyms.c
> +++ b/kernel/kallsyms.c
> @@ -205,12 +205,20 @@ unsigned long kallsyms_lookup_name(const char *name)
>   unsigned long i;
>   unsigned int off;
>  
> + if (!name || *name == '\0')
> + return 0;
> +
> + /* For symbols of the form :, only check the modules */
> + if (strnchr(name, MODULE_NAME_LEN, ':'))
> +     goto mod;
> +
>   for (i = 0, off = 0; i < kallsyms_num_syms; i++) {
>   off = kallsyms_expand_symbol(off, namebuf, ARRAY_SIZE(namebuf));
>  
>   if (strcmp(namebuf, name) == 0)
>   return kallsyms_sym_address(i);
>   }
> +mod:
>   return module_kallsyms_lookup_name(name);
>  }
>  EXPORT_SYMBOL_GPL(kallsyms_lookup_name);
> -- 
> 2.12.2
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH] powerpc/kprobes: refactor kprobe_lookup_name for safer string operations

2017-04-25 Thread Masami Hiramatsu
On Tue, 25 Apr 2017 21:37:11 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> Use safer string manipulation functions when dealing with a
> user-provided string in kprobe_lookup_name().
> 
> Reported-by: David Laight <david.lai...@aculab.com>
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  arch/powerpc/kernel/kprobes.c | 47 
> ++-
>  1 file changed, 20 insertions(+), 27 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index 160ae0fa7d0d..5a17e6467be9 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -53,7 +53,7 @@ bool arch_within_kprobe_blacklist(unsigned long addr)
>  
>  kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset)
>  {
> - kprobe_opcode_t *addr;
> + kprobe_opcode_t *addr = NULL;
>  
>  #ifdef PPC64_ELF_ABI_v2
>   /* PPC64 ABIv2 needs local entry point */
> @@ -85,36 +85,29 @@ kprobe_opcode_t *kprobe_lookup_name(const char *name, 
> unsigned int offset)
>* Also handle  format.
>*/
>   char dot_name[MODULE_NAME_LEN + 1 + KSYM_NAME_LEN];
> - const char *modsym;
>   bool dot_appended = false;
> - if ((modsym = strchr(name, ':')) != NULL) {
> - modsym++;
> - if (*modsym != '\0' && *modsym != '.') {
> - /* Convert to  */
> - strncpy(dot_name, name, modsym - name);
> - dot_name[modsym - name] = '.';
> - dot_name[modsym - name + 1] = '\0';
> - strncat(dot_name, modsym,
> - sizeof(dot_name) - (modsym - name) - 2);
> - dot_appended = true;
> - } else {
> - dot_name[0] = '\0';
> - strncat(dot_name, name, sizeof(dot_name) - 1);
> - }
> - } else if (name[0] != '.') {
> - dot_name[0] = '.';
> - dot_name[1] = '\0';
> - strncat(dot_name, name, KSYM_NAME_LEN - 2);
> + const char *c;
> + ssize_t ret = 0;
> + int len = 0;
> +
> + if ((c = strnchr(name, MODULE_NAME_LEN, ':')) != NULL) {
> + c++;
> + len = c - name;
> + memcpy(dot_name, name, len);
> + } else
> + c = name;
> +
> + if (*c != '\0' && *c != '.') {
> + dot_name[len++] = '.';
>   dot_appended = true;
> - } else {
> - dot_name[0] = '\0';
> - strncat(dot_name, name, KSYM_NAME_LEN - 1);
>   }
> - addr = (kprobe_opcode_t *)kallsyms_lookup_name(dot_name);
> - if (!addr && dot_appended) {
> - /* Let's try the original non-dot symbol lookup */
> + ret = strscpy(dot_name + len, c, KSYM_NAME_LEN);
> + if (ret >= 0)

Here, maybe you can skip the case of ret == 0. (Or, would we have
a symbol which only has "."?)

Others look good to me.

Thank you,

> + addr = (kprobe_opcode_t *)kallsyms_lookup_name(dot_name);
> +
> + /* Fallback to the original non-dot symbol lookup */
> + if (!addr && dot_appended)
>   addr = (kprobe_opcode_t *)kallsyms_lookup_name(name);
> - }
>  #else
>   addr = (kprobe_opcode_t *)kallsyms_lookup_name(name);
>  #endif
> -- 
> 2.12.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v3 3/7] kprobes: validate the symbol name length

2017-04-24 Thread Masami Hiramatsu
On Sun, 23 Apr 2017 15:44:32 +
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> >> >> +bool is_valid_kprobe_symbol_name(const char *name)
> >> > 
> >> > This just check the length of symbol_name buffer, and can contain
> >> > some invalid chars.
> >> 
> >> Yes, I kept the function name generic incase we would like to do more 
> >> validation in future, plus it's shorter than 
> >> is_valid_kprobe_symbol_name_len() ;-)
> > 
> > OK, if this is enough general, we'd better define this in
> > kernel/kallsyms.c or in kallsyms.h. Of course the function
> > should be called is_valid_symbol_name(). :-)
> 
> I actually think this should be done in kprobes itself. The primary 
> intent is to perform such validation right when we first obtain the 
> input from the user. In this case, however, kallsyms_lookup_name() is 
> also an exported symbol, so I do think some validation there would be 
> good to have as well.

IMHO, it is natural that kallsyms will know what is valid symbols.
Providing validation function by kprobes means kprobes also knows
that, and I concerns that may lead a double standard.

Thanks,

> >> >> +{
> >> >> +   size_t sym_len;
> >> >> +   char *s;
> >> >> +
> >> >> +   s = strchr(name, ':');
> >> 
> >> Hmm.. this should be strnchr(). I re-factored the code that moved the 
> >> strnlen() above this below. I'll fix this.
> >> 
> >> >> +   if (s) {
> >> >> +   sym_len = strnlen(s+1, KSYM_NAME_LEN);
> >> > 
> >> > If you use strnlen() here, you just need to ensure sym_len < 
> >> > KSYM_NAME_LEN.
> >> 
> >> Hmm.. not sure I follow. Are you saying the check for sym_len <= 0 is 
> >> not needed?
> > 
> > You can check sym_len != 0, but anyway, here we concern about
> > "longer" string (for performance reason), we can focus on
> > such case.
> > (BTW, could you also check the name != NULL at first?)
> > 
> > So, what I think it can be;
> > 
> > if (strnlen(s+1, KSYM_NAME_LEN) == KSYM_NAME_LEN ||
> > (size_t)(s - name) >= MODULE_NAME_LEN)
> > return false;
> 
> Sure, thanks. I clearly need to refactor this code better!
> 
> - Naveen
> 
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v4 3/7] kprobes: validate the symbol name provided during probe registration

2017-04-21 Thread Masami Hiramatsu
On Fri, 21 Apr 2017 18:02:33 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> When a kprobe is being registered, we use the symbol_name field to
> lookup the address where the probe should be placed. Since this is a
> user-provided field, let's ensure that the length of the string is
> within expected limits.
> 
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
> Masami, Michael,
> Here's a simplified version that should hopefully be fine. I have
> simplified the logic to keep the code compact and simple.

Ok, so as I replied to older version,
 - Ensure name != NULL at first.
 - Define it in kernel/kallsyms.c as a general routine.

Since this validate the string which will be passed to kallsyms,
I think it should be provided by kallsyms.

Thanks, 

> 
> - Naveen
> 
> 
>  include/linux/kprobes.h |  1 +
>  kernel/kprobes.c| 30 ++
>  kernel/trace/trace_kprobe.c |  4 
>  3 files changed, 35 insertions(+)
> 
> diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
> index 1f82a3db00b1..4ee10fef5135 100644
> --- a/include/linux/kprobes.h
> +++ b/include/linux/kprobes.h
> @@ -405,6 +405,7 @@ int disable_kprobe(struct kprobe *kp);
>  int enable_kprobe(struct kprobe *kp);
>  
>  void dump_kprobe(struct kprobe *kp);
> +bool is_valid_kprobe_symbol_name(const char *name);
>  
>  #else /* !CONFIG_KPROBES: */
>  
> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> index 6a128f3a7ed1..ff9b1ac72a38 100644
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -1383,6 +1383,34 @@ bool within_kprobe_blacklist(unsigned long addr)
>  }
>  
>  /*
> + * We mainly want to ensure that the provided string is of a reasonable 
> length
> + * and is of the form [:], so that this is safe to 
> process
> + * further.
> + * We don't worry about invalid characters as those will just prevent
> + * matching existing kallsyms.
> + */
> +bool is_valid_kprobe_symbol_name(const char *name)
> +{
> + size_t sym_len;
> + const char *s;
> +
> + s = strnchr(name, ':', MODULE_NAME_LEN + KSYM_NAME_LEN + 1);
> + if (s) {
> + sym_len = (size_t)(s - name);
> + if (sym_len <= 0  || sym_len >= MODULE_NAME_LEN)
> + return false;
> + s++;
> + } else
> + s = name;
> +
> + sym_len = strnlen(s, KSYM_NAME_LEN);
> + if (sym_len <= 0 || sym_len >= KSYM_NAME_LEN)
> + return false;
> +
> + return true;
> +}
> +
> +/*
>   * If we have a symbol_name argument, look it up and add the offset field
>   * to it. This way, we can specify a relative address to a symbol.
>   * This returns encoded errors if it fails to look up symbol or invalid
> @@ -1397,6 +1425,8 @@ static kprobe_opcode_t *kprobe_addr(struct kprobe *p)
>   goto invalid;
>  
>   if (p->symbol_name) {
> + if (!is_valid_kprobe_symbol_name(p->symbol_name))
> + return ERR_PTR(-EINVAL);
>   addr = kprobe_lookup_name(p->symbol_name, p->offset);
>   if (!addr)
>   return ERR_PTR(-ENOENT);
> diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
> index 5f688cc724f0..bf73e5f31128 100644
> --- a/kernel/trace/trace_kprobe.c
> +++ b/kernel/trace/trace_kprobe.c
> @@ -704,6 +704,10 @@ static int create_trace_kprobe(int argc, char **argv)
>   pr_info("Return probe must be used without offset.\n");
>   return -EINVAL;
>   }
> + if (!is_valid_kprobe_symbol_name(symbol)) {
> + pr_info("Symbol name is too long.\n");
> + return -EINVAL;
> + }
>   }
>   argc -= 2; argv += 2;
>  
> -- 
> 2.12.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v3 6/7] powerpc: kprobes: emulate instructions on kprobe handler re-entry

2017-04-21 Thread Masami Hiramatsu
On Thu, 20 Apr 2017 16:11:10 +1000
Michael Ellerman <m...@ellerman.id.au> wrote:

> "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> writes:
> 
> > Excerpts from Masami Hiramatsu's message of April 19, 2017 20:13:
> >> 
> >> BTW, as I pointed, 5/7 and 6/7 should be merged since this actually
> >> makes meaningful change.
> >
> > Yes, sorry if I wasn't clear in my previous reply in the (!) previous 
> > patch series.
> >
> > Since this has to go through the powerpc tree, I followed this since I 
> > felt that Michael Ellerman prefers to keep functional changes separate 
> > from refactoring. I'm fine with either approach.
> >
> > Michael?
> 
> Yeah I'd definitely like this to be two patches. Otherwise when reading
> the combined diff it's much harder to see the change.

OK, let it be so.

Reviewed-by: Masami Hiramatsu <mhira...@kernel.org>

Thanks,

-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v3 3/7] kprobes: validate the symbol name length

2017-04-21 Thread Masami Hiramatsu
On Wed, 19 Apr 2017 16:38:22 +
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> Excerpts from Masami Hiramatsu's message of April 19, 2017 20:07:
> > On Wed, 19 Apr 2017 18:21:02 +0530
> > "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:
> > 
> >> When a kprobe is being registered, we use the symbol_name field to
> >> lookup the address where the probe should be placed. Since this is a
> >> user-provided field, let's ensure that the length of the string is
> >> within expected limits.
> > 
> > Would we really need this? Of course it may filter out longer
> > strings... anyway such name should be rejected by kallsyms.
> 
> I felt this would be good to have generically, as kallsyms does many 
> string operations on the symbol name, including an unbounded strchr().

OK, so this is actually for performance reason.

> 
> > 
> > [...]
> >> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> >> index 6a128f3a7ed1..bb86681c8a10 100644
> >> --- a/kernel/kprobes.c
> >> +++ b/kernel/kprobes.c
> >> @@ -1382,6 +1382,28 @@ bool within_kprobe_blacklist(unsigned long addr)
> >>return false;
> >>  }
> >>  
> >> +bool is_valid_kprobe_symbol_name(const char *name)
> > 
> > This just check the length of symbol_name buffer, and can contain
> > some invalid chars.
> 
> Yes, I kept the function name generic incase we would like to do more 
> validation in future, plus it's shorter than 
> is_valid_kprobe_symbol_name_len() ;-)

OK, if this is enough general, we'd better define this in
kernel/kallsyms.c or in kallsyms.h. Of course the function
should be called is_valid_symbol_name(). :-)

> >> +{
> >> +  size_t sym_len;
> >> +  char *s;
> >> +
> >> +  s = strchr(name, ':');
> 
> Hmm.. this should be strnchr(). I re-factored the code that moved the 
> strnlen() above this below. I'll fix this.
> 
> >> +  if (s) {
> >> +  sym_len = strnlen(s+1, KSYM_NAME_LEN);
> > 
> > If you use strnlen() here, you just need to ensure sym_len < KSYM_NAME_LEN.
> 
> Hmm.. not sure I follow. Are you saying the check for sym_len <= 0 is 
> not needed?

You can check sym_len != 0, but anyway, here we concern about
"longer" string (for performance reason), we can focus on
such case.
(BTW, could you also check the name != NULL at first?)

So, what I think it can be;

if (strnlen(s+1, KSYM_NAME_LEN) == KSYM_NAME_LEN ||
(size_t)(s - name) >= MODULE_NAME_LEN)
return false;

Thanks,

> >> +  if (sym_len <= 0 || sym_len >= KSYM_NAME_LEN)
> >> +  return false;
> >> +  sym_len = (size_t)(s - name);
> >> +  if (sym_len <= 0 || sym_len >= MODULE_NAME_LEN)
> >> +  return false;
> >> +  } else {
> >> +  sym_len = strnlen(name, MODULE_NAME_LEN);
> >> +  if (sym_len <= 0 || sym_len >= MODULE_NAME_LEN)
> > 
> > Would you mean KSYM_NAME_LEN here?
> 
> Oops... nice catch, Thanks!
> 
> - Naveen
> 
> > 
> >> +  return false;
> >> +  }
> >> +
> >> +  return true;
> >> +}
> >> +
> >>  /*
> >>   * If we have a symbol_name argument, look it up and add the offset field
> >>   * to it. This way, we can specify a relative address to a symbol.
> >> @@ -1397,6 +1419,8 @@ static kprobe_opcode_t *kprobe_addr(struct kprobe *p)
> >>goto invalid;
> >>  
> >>if (p->symbol_name) {
> >> +  if (!is_valid_kprobe_symbol_name(p->symbol_name))
> >> +  return ERR_PTR(-EINVAL);
> >>addr = kprobe_lookup_name(p->symbol_name, p->offset);
> >>if (!addr)
> >>return ERR_PTR(-ENOENT);
> >> diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
> >> index 5f688cc724f0..bf73e5f31128 100644
> >> --- a/kernel/trace/trace_kprobe.c
> >> +++ b/kernel/trace/trace_kprobe.c
> >> @@ -704,6 +704,10 @@ static int create_trace_kprobe(int argc, char **argv)
> >>pr_info("Return probe must be used without offset.\n");
> >>return -EINVAL;
> >>}
> >> +  if (!is_valid_kprobe_symbol_name(symbol)) {
> >> +  pr_info("Symbol name is too long.\n");
> >> +  return -EINVAL;
> >> +  }
> >>}
> >>argc -= 2; argv += 2;
> >>  
> >> -- 
> >> 2.12.1
> >> 
> > 
> > Thanks,
> > 
> > -- 
> > Masami Hiramatsu <mhira...@kernel.org>
> > 
> > 
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v3 5/7] powerpc: kprobes: factor out code to emulate instruction into a helper

2017-04-19 Thread Masami Hiramatsu
On Wed, 19 Apr 2017 18:21:04 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

Factor out code to emulate instruction into a try_to_emulate()
helper function. This makes ...

> No functional changes.

Thanks,

> 
> Acked-by: Ananth N Mavinakayanahalli <ana...@linux.vnet.ibm.com>
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  arch/powerpc/kernel/kprobes.c | 52 
> ++-
>  1 file changed, 31 insertions(+), 21 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index d743bacefa8c..46e8c1e03ce4 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -206,6 +206,35 @@ void __kprobes arch_prepare_kretprobe(struct 
> kretprobe_instance *ri,
>   regs->link = (unsigned long)kretprobe_trampoline;
>  }
>  
> +int __kprobes try_to_emulate(struct kprobe *p, struct pt_regs *regs)
> +{
> + int ret;
> + unsigned int insn = *p->ainsn.insn;
> +
> + /* regs->nip is also adjusted if emulate_step returns 1 */
> + ret = emulate_step(regs, insn);
> + if (ret > 0) {
> + /*
> +  * Once this instruction has been boosted
> +  * successfully, set the boostable flag
> +  */
> + if (unlikely(p->ainsn.boostable == 0))
> + p->ainsn.boostable = 1;
> + } else if (ret < 0) {
> + /*
> +  * We don't allow kprobes on mtmsr(d)/rfi(d), etc.
> +  * So, we should never get here... but, its still
> +  * good to catch them, just in case...
> +  */
> + printk("Can't step on instruction %x\n", insn);
> + BUG();
> + } else if (ret == 0)
> + /* This instruction can't be boosted */
> + p->ainsn.boostable = -1;
> +
> + return ret;
> +}
> +
>  int __kprobes kprobe_handler(struct pt_regs *regs)
>  {
>   struct kprobe *p;
> @@ -301,18 +330,9 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
>  
>  ss_probe:
>   if (p->ainsn.boostable >= 0) {
> - unsigned int insn = *p->ainsn.insn;
> + ret = try_to_emulate(p, regs);
>  
> - /* regs->nip is also adjusted if emulate_step returns 1 */
> - ret = emulate_step(regs, insn);
>   if (ret > 0) {
> - /*
> -  * Once this instruction has been boosted
> -  * successfully, set the boostable flag
> -  */
> - if (unlikely(p->ainsn.boostable == 0))
> - p->ainsn.boostable = 1;
> -
>   if (p->post_handler)
>   p->post_handler(p, regs, 0);
>  
> @@ -320,17 +340,7 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
>   reset_current_kprobe();
>   preempt_enable_no_resched();
>   return 1;
> - } else if (ret < 0) {
> - /*
> -  * We don't allow kprobes on mtmsr(d)/rfi(d), etc.
> -  * So, we should never get here... but, its still
> -  * good to catch them, just in case...
> -  */
> - printk("Can't step on instruction %x\n", insn);
> - BUG();
> - } else if (ret == 0)
> - /* This instruction can't be boosted */
> - p->ainsn.boostable = -1;
> + }
>   }
>   prepare_singlestep(p, regs);
>   kcb->kprobe_status = KPROBE_HIT_SS;
> -- 
> 2.12.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v3 7/7] powerpc: kprobes: remove duplicate saving of msr

2017-04-19 Thread Masami Hiramatsu
On Wed, 19 Apr 2017 18:21:06 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> set_current_kprobe() already saves regs->msr into kprobe_saved_msr. Remove
> the redundant save.
> 

Looks good to me.

Reviewed-by: Masami Hiramatsu <mhira...@kernel.org>

Thank you,

> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  arch/powerpc/kernel/kprobes.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index 067e9863bfdf..5c0a1ffcbcf9 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -272,7 +272,6 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
>*/
>   save_previous_kprobe(kcb);
>   set_current_kprobe(p, regs, kcb);
> - kcb->kprobe_saved_msr = regs->msr;
>   kprobes_inc_nmissed_count(p);
>   prepare_singlestep(p, regs);
>   kcb->kprobe_status = KPROBE_REENTER;
> -- 
> 2.12.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v3 6/7] powerpc: kprobes: emulate instructions on kprobe handler re-entry

2017-04-19 Thread Masami Hiramatsu

BTW, as I pointed, 5/7 and 6/7 should be merged since this actually
makes meaningful change.

Thank you,

On Wed, 19 Apr 2017 18:21:05 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> On kprobe handler re-entry, try to emulate the instruction rather than
> single stepping always.
> 
> Acked-by: Ananth N Mavinakayanahalli <ana...@linux.vnet.ibm.com>
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  arch/powerpc/kernel/kprobes.c | 8 
>  1 file changed, 8 insertions(+)
> 
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index 46e8c1e03ce4..067e9863bfdf 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -276,6 +276,14 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
>   kprobes_inc_nmissed_count(p);
>   prepare_singlestep(p, regs);
>   kcb->kprobe_status = KPROBE_REENTER;
> + if (p->ainsn.boostable >= 0) {
> + ret = try_to_emulate(p, regs);
> +
> + if (ret > 0) {
> + restore_previous_kprobe(kcb);
> + return 1;
> + }
> + }
>   return 1;
>   } else {
>   if (*addr != BREAKPOINT_INSTRUCTION) {
> -- 
> 2.12.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v3 3/7] kprobes: validate the symbol name length

2017-04-19 Thread Masami Hiramatsu
On Wed, 19 Apr 2017 18:21:02 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> When a kprobe is being registered, we use the symbol_name field to
> lookup the address where the probe should be placed. Since this is a
> user-provided field, let's ensure that the length of the string is
> within expected limits.

Would we really need this? Of course it may filter out longer
strings... anyway such name should be rejected by kallsyms.

[...]
> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> index 6a128f3a7ed1..bb86681c8a10 100644
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -1382,6 +1382,28 @@ bool within_kprobe_blacklist(unsigned long addr)
>   return false;
>  }
>  
> +bool is_valid_kprobe_symbol_name(const char *name)

This just check the length of symbol_name buffer, and can contain
some invalid chars.

> +{
> + size_t sym_len;
> + char *s;
> +
> + s = strchr(name, ':');
> + if (s) {
> + sym_len = strnlen(s+1, KSYM_NAME_LEN);

If you use strnlen() here, you just need to ensure sym_len < KSYM_NAME_LEN.

> + if (sym_len <= 0 || sym_len >= KSYM_NAME_LEN)
> + return false;
> + sym_len = (size_t)(s - name);
> + if (sym_len <= 0 || sym_len >= MODULE_NAME_LEN)
> + return false;
> + } else {
> + sym_len = strnlen(name, MODULE_NAME_LEN);
> + if (sym_len <= 0 || sym_len >= MODULE_NAME_LEN)

Would you mean KSYM_NAME_LEN here?

> + return false;
> + }
> +
> + return true;
> +}
> +
>  /*
>   * If we have a symbol_name argument, look it up and add the offset field
>   * to it. This way, we can specify a relative address to a symbol.
> @@ -1397,6 +1419,8 @@ static kprobe_opcode_t *kprobe_addr(struct kprobe *p)
>   goto invalid;
>  
>   if (p->symbol_name) {
> + if (!is_valid_kprobe_symbol_name(p->symbol_name))
> + return ERR_PTR(-EINVAL);
>   addr = kprobe_lookup_name(p->symbol_name, p->offset);
>   if (!addr)
>   return ERR_PTR(-ENOENT);
> diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
> index 5f688cc724f0..bf73e5f31128 100644
> --- a/kernel/trace/trace_kprobe.c
> +++ b/kernel/trace/trace_kprobe.c
> @@ -704,6 +704,10 @@ static int create_trace_kprobe(int argc, char **argv)
>   pr_info("Return probe must be used without offset.\n");
>   return -EINVAL;
>   }
> + if (!is_valid_kprobe_symbol_name(symbol)) {
> + pr_info("Symbol name is too long.\n");
> + return -EINVAL;
> + }
>   }
>   argc -= 2; argv += 2;
>  
> -- 
> 2.12.1
> 

Thanks,

-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v2 5/5] powerpc: kprobes: emulate instructions on kprobe handler re-entry

2017-04-12 Thread Masami Hiramatsu
On Wed, 12 Apr 2017 16:28:28 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> On kprobe handler re-entry, try to emulate the instruction rather than
> single stepping always.
> 

> As a related change, remove the duplicate saving of msr as that is
> already done in set_current_kprobe()

If so, this part might be separated as a cleanup patch...

Thanks,

> 
> Acked-by: Ananth N Mavinakayanahalli <ana...@linux.vnet.ibm.com>
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  arch/powerpc/kernel/kprobes.c | 9 -
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index 8b48f7d046bd..005bd4a75902 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -273,10 +273,17 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
>*/
>   save_previous_kprobe(kcb);
>   set_current_kprobe(p, regs, kcb);
> - kcb->kprobe_saved_msr = regs->msr;
>   kprobes_inc_nmissed_count(p);
>   prepare_singlestep(p, regs);
>   kcb->kprobe_status = KPROBE_REENTER;
> + if (p->ainsn.boostable >= 0) {
> + ret = try_to_emulate(p, regs);
> +
> + if (ret > 0) {
> + restore_previous_kprobe(kcb);
> + return 1;
> + }
> + }
>       return 1;
>   } else {
>   if (*addr != BREAKPOINT_INSTRUCTION) {
> -- 
> 2.12.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v2 4/5] powerpc: kprobes: factor out code to emulate instruction into a helper

2017-04-12 Thread Masami Hiramatsu
On Wed, 12 Apr 2017 16:28:27 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> This helper will be used in a subsequent patch to emulate instructions
> on re-entering the kprobe handler. No functional change.

In this case, please merge this patch into the next patch which
actually uses the factored out function unless that changes
too much.

Thank you,

> 
> Acked-by: Ananth N Mavinakayanahalli <ana...@linux.vnet.ibm.com>
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  arch/powerpc/kernel/kprobes.c | 52 
> ++-
>  1 file changed, 31 insertions(+), 21 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index 0732a0291ace..8b48f7d046bd 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -207,6 +207,35 @@ void __kprobes arch_prepare_kretprobe(struct 
> kretprobe_instance *ri,
>   regs->link = (unsigned long)kretprobe_trampoline;
>  }
>  
> +int __kprobes try_to_emulate(struct kprobe *p, struct pt_regs *regs)
> +{
> + int ret;
> + unsigned int insn = *p->ainsn.insn;
> +
> + /* regs->nip is also adjusted if emulate_step returns 1 */
> + ret = emulate_step(regs, insn);
> + if (ret > 0) {
> + /*
> +  * Once this instruction has been boosted
> +  * successfully, set the boostable flag
> +  */
> + if (unlikely(p->ainsn.boostable == 0))
> + p->ainsn.boostable = 1;
> + } else if (ret < 0) {
> + /*
> +  * We don't allow kprobes on mtmsr(d)/rfi(d), etc.
> +  * So, we should never get here... but, its still
> +  * good to catch them, just in case...
> +  */
> + printk("Can't step on instruction %x\n", insn);
> + BUG();
> + } else if (ret == 0)
> + /* This instruction can't be boosted */
> + p->ainsn.boostable = -1;
> +
> + return ret;
> +}
> +
>  int __kprobes kprobe_handler(struct pt_regs *regs)
>  {
>   struct kprobe *p;
> @@ -302,18 +331,9 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
>  
>  ss_probe:
>   if (p->ainsn.boostable >= 0) {
> - unsigned int insn = *p->ainsn.insn;
> + ret = try_to_emulate(p, regs);
>  
> - /* regs->nip is also adjusted if emulate_step returns 1 */
> - ret = emulate_step(regs, insn);
>   if (ret > 0) {
> - /*
> -  * Once this instruction has been boosted
> -  * successfully, set the boostable flag
> -  */
> - if (unlikely(p->ainsn.boostable == 0))
> - p->ainsn.boostable = 1;
> -
>   if (p->post_handler)
>   p->post_handler(p, regs, 0);
>  
> @@ -321,17 +341,7 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
>   reset_current_kprobe();
>   preempt_enable_no_resched();
>   return 1;
> - } else if (ret < 0) {
> - /*
> -  * We don't allow kprobes on mtmsr(d)/rfi(d), etc.
> -  * So, we should never get here... but, its still
> -  * good to catch them, just in case...
> -  */
> - printk("Can't step on instruction %x\n", insn);
> - BUG();
> - } else if (ret == 0)
> - /* This instruction can't be boosted */
> - p->ainsn.boostable = -1;
> + }
>   }
>   prepare_singlestep(p, regs);
>   kcb->kprobe_status = KPROBE_HIT_SS;
> -- 
> 2.12.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v2 3/5] powerpc: introduce a new helper to obtain function entry points

2017-04-12 Thread Masami Hiramatsu
On Wed, 12 Apr 2017 16:28:26 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> kprobe_lookup_name() is specific to the kprobe subsystem and may not
> always return the function entry point (in a subsequent patch for
> KPROBES_ON_FTRACE).

If so, please move this patch into that series. It is hard to review
patches which requires for other series.

Thank you,

> For looking up function entry points, introduce a
> separate helper and use the same in optprobes.c
> 
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  arch/powerpc/include/asm/code-patching.h | 37 
> 
>  arch/powerpc/kernel/optprobes.c  |  6 +++---
>  2 files changed, 40 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/code-patching.h 
> b/arch/powerpc/include/asm/code-patching.h
> index 8ab937771068..3e994f404434 100644
> --- a/arch/powerpc/include/asm/code-patching.h
> +++ b/arch/powerpc/include/asm/code-patching.h
> @@ -12,6 +12,8 @@
>  
>  #include 
>  #include 
> +#include 
> +#include 
>  
>  /* Flags for create_branch:
>   * "b"   == create_branch(addr, target, 0);
> @@ -99,6 +101,41 @@ static inline unsigned long 
> ppc_global_function_entry(void *func)
>  #endif
>  }
>  
> +/*
> + * Wrapper around kallsyms_lookup() to return function entry address:
> + * - For ABIv1, we lookup the dot variant.
> + * - For ABIv2, we return the local entry point.
> + */
> +static inline unsigned long ppc_kallsyms_lookup_name(const char *name)
> +{
> + unsigned long addr;
> +#ifdef PPC64_ELF_ABI_v1
> + /* check for dot variant */
> + char dot_name[1 + KSYM_NAME_LEN];
> + bool dot_appended = false;
> + if (name[0] != '.') {
> + dot_name[0] = '.';
> + dot_name[1] = '\0';
> + strncat(dot_name, name, KSYM_NAME_LEN - 2);
> + dot_appended = true;
> + } else {
> + dot_name[0] = '\0';
> + strncat(dot_name, name, KSYM_NAME_LEN - 1);
> + }
> + addr = kallsyms_lookup_name(dot_name);
> + if (!addr && dot_appended)
> + /* Let's try the original non-dot symbol lookup */
> + addr = kallsyms_lookup_name(name);
> +#elif defined(PPC64_ELF_ABI_v2)
> + addr = kallsyms_lookup_name(name);
> + if (addr)
> + addr = ppc_function_entry((void *)addr);
> +#else
> + addr = kallsyms_lookup_name(name);
> +#endif
> + return addr;
> +}
> +
>  #ifdef CONFIG_PPC64
>  /*
>   * Some instruction encodings commonly used in dynamic ftracing
> diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c
> index ce81a322251c..ec60ed0d4aad 100644
> --- a/arch/powerpc/kernel/optprobes.c
> +++ b/arch/powerpc/kernel/optprobes.c
> @@ -243,10 +243,10 @@ int arch_prepare_optimized_kprobe(struct 
> optimized_kprobe *op, struct kprobe *p)
>   /*
>* 2. branch to optimized_callback() and emulate_step()
>*/
> - op_callback_addr = kprobe_lookup_name("optimized_callback", 0);
> - emulate_step_addr = kprobe_lookup_name("emulate_step", 0);
> + op_callback_addr = (kprobe_opcode_t 
> *)ppc_kallsyms_lookup_name("optimized_callback");
> + emulate_step_addr = (kprobe_opcode_t 
> *)ppc_kallsyms_lookup_name("emulate_step");
>   if (!op_callback_addr || !emulate_step_addr) {
> - WARN(1, "kprobe_lookup_name() failed\n");
> + WARN(1, "Unable to lookup 
> optimized_callback()/emulate_step()\n");
>   goto error;
>   }
>  
> -- 
> 2.12.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v2 2/5] powerpc: kprobes: fix handling of function offsets on ABIv2

2017-04-12 Thread Masami Hiramatsu
On Wed, 12 Apr 2017 16:28:25 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> commit 239aeba76409 ("perf powerpc: Fix kprobe and kretprobe handling
> with kallsyms on ppc64le") changed how we use the offset field in struct
> kprobe on ABIv2. perf now offsets from the GEP (Global entry point) if an
> offset is specified and otherwise chooses the LEP (Local entry point).
> 
> Fix the same in kernel for kprobe API users. We do this by extending
> kprobe_lookup_name() to accept an additional parameter to indicate the
> offset specified with the kprobe registration. If offset is 0, we return
> the local function entry and return the global entry point otherwise.
> 
> With:
>   # cd /sys/kernel/debug/tracing/
>   # echo "p _do_fork" >> kprobe_events
>   # echo "p _do_fork+0x10" >> kprobe_events
> 
> before this patch:
>   # cat ../kprobes/list
>   c00d0748  k  _do_fork+0x8[DISABLED]
>   c00d0758  k  _do_fork+0x18[DISABLED]
>   c00412b0  k  kretprobe_trampoline+0x0[OPTIMIZED]
> 
> and after:
>   # cat ../kprobes/list
>   c00d04c8  k  _do_fork+0x8[DISABLED]
>   c00d04d0  k  _do_fork+0x10[DISABLED]
>   c00412b0  k  kretprobe_trampoline+0x0[OPTIMIZED]
> 
> Acked-by: Ananth N Mavinakayanahalli <ana...@linux.vnet.ibm.com>
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  arch/powerpc/kernel/kprobes.c   | 4 ++--
>  arch/powerpc/kernel/optprobes.c | 4 ++--
>  include/linux/kprobes.h | 2 +-
>  kernel/kprobes.c| 7 ---
>  4 files changed, 9 insertions(+), 8 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index a7aa7394954d..0732a0291ace 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -42,14 +42,14 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
>  
>  struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
>  
> -kprobe_opcode_t *kprobe_lookup_name(const char *name)
> +kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset)

Hmm, if we do this change, it is natural that kprobe_lookup_name()
returns the address + offset.

Thank you,



-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v2 1/5] kprobes: convert kprobe_lookup_name() to a function

2017-04-12 Thread Masami Hiramatsu
On Wed, 12 Apr 2017 16:28:24 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> The macro is now pretty long and ugly on powerpc. In the light of
> further changes needed here, convert it to a __weak variant to be
> over-ridden with a nicer looking function.

Looks good to me.

Acked-by: Masami Hiramatsu <mhira...@kernel.org>

Thanks!

> 
> Suggested-by: Masami Hiramatsu <mhira...@kernel.org>
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  arch/powerpc/include/asm/kprobes.h | 53 --
>  arch/powerpc/kernel/kprobes.c  | 58 
> ++
>  arch/powerpc/kernel/optprobes.c|  4 +--
>  include/linux/kprobes.h|  1 +
>  kernel/kprobes.c   | 20 ++---
>  5 files changed, 69 insertions(+), 67 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/kprobes.h 
> b/arch/powerpc/include/asm/kprobes.h
> index 0503c98b2117..a843884aafaf 100644
> --- a/arch/powerpc/include/asm/kprobes.h
> +++ b/arch/powerpc/include/asm/kprobes.h
> @@ -61,59 +61,6 @@ extern kprobe_opcode_t optprobe_template_end[];
>  #define MAX_OPTINSN_SIZE (optprobe_template_end - 
> optprobe_template_entry)
>  #define RELATIVEJUMP_SIZEsizeof(kprobe_opcode_t) /* 4 bytes */
>  
> -#ifdef PPC64_ELF_ABI_v2
> -/* PPC64 ABIv2 needs local entry point */
> -#define kprobe_lookup_name(name, addr)   
> \
> -{\
> - addr = (kprobe_opcode_t *)kallsyms_lookup_name(name);   \
> - if (addr)   \
> - addr = (kprobe_opcode_t *)ppc_function_entry(addr); \
> -}
> -#elif defined(PPC64_ELF_ABI_v1)
> -/*
> - * 64bit powerpc ABIv1 uses function descriptors:
> - * - Check for the dot variant of the symbol first.
> - * - If that fails, try looking up the symbol provided.
> - *
> - * This ensures we always get to the actual symbol and not the descriptor.
> - * Also handle  format.
> - */
> -#define kprobe_lookup_name(name, addr)   
> \
> -{\
> - char dot_name[MODULE_NAME_LEN + 1 + KSYM_NAME_LEN]; \
> - const char *modsym; 
> \
> - bool dot_appended = false;  \
> - if ((modsym = strchr(name, ':')) != NULL) { \
> - modsym++;   \
> - if (*modsym != '\0' && *modsym != '.') {\
> - /* Convert to  */   \
> - strncpy(dot_name, name, modsym - name); \
> - dot_name[modsym - name] = '.';  \
> - dot_name[modsym - name + 1] = '\0'; \
> - strncat(dot_name, modsym,   \
> - sizeof(dot_name) - (modsym - name) - 2);\
> - dot_appended = true;\
> - } else {\
> - dot_name[0] = '\0'; \
> - strncat(dot_name, name, sizeof(dot_name) - 1);  \
> - }   \
> - } else if (name[0] != '.') {\
> - dot_name[0] = '.';  \
> - dot_name[1] = '\0'; \
> - strncat(dot_name, name, KSYM_NAME_LEN - 2); \
> - dot_appended = true;\
> - } else {\
> - dot_name[0] = '\0'; \
> - strncat(dot_name, name, KSYM_NAME_LEN - 1); \
> - }   \
> - addr = (kprobe_opcode_t *)kallsyms_lookup_name(dot_name);   \
> - if (!addr && dot_appended) {\
> - /* Let's try the original non-dot symbol lookup */  \
> - addr = (kprobe_opcode_t *)kallsyms_lookup_name(name);   \
> - }   \
> -}
> -#endif
> -
>  #define flush_insn_slot(p)   do { } while (0)
>  #define kretprobe_blacklist_size 0
>  
> diff --git a/arch/powerpc/kernel/

Re: [PATCH v2 0/5] powerpc: a few kprobe fixes and refactoring

2017-04-12 Thread Masami Hiramatsu
Hi Naveen,

BTW, I saw you sent 3 different series, are there any
conflict each other? or can we pick those independently?

Thanks,

On Wed, 12 Apr 2017 16:28:23 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> v1:
> https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1334843.html
> 
> For v2, this series has been re-ordered and rebased on top of
> powerpc/next so as to make it easier to resolve conflicts with -tip. No
> other changes.
> 
> - Naveen
> 
> 
> Naveen N. Rao (5):
>   kprobes: convert kprobe_lookup_name() to a function
>   powerpc: kprobes: fix handling of function offsets on ABIv2
>   powerpc: introduce a new helper to obtain function entry points
>   powerpc: kprobes: factor out code to emulate instruction into a helper
>   powerpc: kprobes: emulate instructions on kprobe handler re-entry
> 
>  arch/powerpc/include/asm/code-patching.h |  37 ++
>  arch/powerpc/include/asm/kprobes.h   |  53 --
>  arch/powerpc/kernel/kprobes.c| 119 
> +--
>  arch/powerpc/kernel/optprobes.c  |   6 +-
>  include/linux/kprobes.h  |   1 +
>  kernel/kprobes.c |  21 +++---
>  6 files changed, 147 insertions(+), 90 deletions(-)
> 
> -- 
> 2.12.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v5 5/5] perf: powerpc: choose local entry point with kretprobes

2017-03-08 Thread Masami Hiramatsu
On Wed,  8 Mar 2017 13:56:10 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> perf now uses an offset from _text/_stext for kretprobes if the kernel
> supports it, rather than the actual function name. As such, let's choose
> the LEP for powerpc ABIv2 so as to ensure the probe gets hit. Do it only
> if the kernel supports specifying offsets with kretprobes.

Acked-by: Masami Hiramatsu <mhira...@kernel.org>

This patch is OK. And I found that most of functions in sym-handling.c
are used only when libelf is supported. (e.g. probe-event.c itself
is not built when we have no libelf)
So, for the next cleanup, this file should not be compiled without
libelf.

Thanks!

> 
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  tools/perf/arch/powerpc/util/sym-handling.c | 14 ++
>  1 file changed, 10 insertions(+), 4 deletions(-)
> 
> diff --git a/tools/perf/arch/powerpc/util/sym-handling.c 
> b/tools/perf/arch/powerpc/util/sym-handling.c
> index 1030a6e504bb..39dbe512b9fc 100644
> --- a/tools/perf/arch/powerpc/util/sym-handling.c
> +++ b/tools/perf/arch/powerpc/util/sym-handling.c
> @@ -10,6 +10,7 @@
>  #include "symbol.h"
>  #include "map.h"
>  #include "probe-event.h"
> +#include "probe-file.h"
>  
>  #ifdef HAVE_LIBELF_SUPPORT
>  bool elf__needs_adjust_symbols(GElf_Ehdr ehdr)
> @@ -79,13 +80,18 @@ void arch__fix_tev_from_maps(struct perf_probe_event *pev,
>* However, if the user specifies an offset, we fall back to using the
>* GEP since all userspace applications (objdump/readelf) show function
>* disassembly with offsets from the GEP.
> -  *
> -  * In addition, we shouldn't specify an offset for kretprobes.
>*/
> - if (pev->point.offset || (!pev->uprobes && pev->point.retprobe) ||
> - !map || !sym)
> + if (pev->point.offset || !map || !sym)
>   return;
>  
> + /* For kretprobes, add an offset only if the kernel supports it */
> + if (!pev->uprobes && pev->point.retprobe) {
> +#ifdef HAVE_LIBELF_SUPPORT
> + if (!kretprobe_offset_is_supported())
> +#endif
> + return;
> + }
> +
>   lep_offset = PPC64_LOCAL_ENTRY_OFFSET(sym->arch_sym);
>  
>   if (map->dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS)
> -- 
> 2.11.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH] powerpc: kprobes: convert __kprobes to NOKPROBE_SYMBOL()

2017-03-08 Thread Masami Hiramatsu
On Wed,  8 Mar 2017 02:09:29 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> Along similar lines as commit 9326638cbee2 ("kprobes, x86: Use
> NOKPROBE_SYMBOL() instead of __kprobes annotation"), convert __kprobes
> annotation to either NOKPROBE_SYMBOL() or nokprobe_inline. The latter
> forces inlining, in which case the caller needs to be added to
> NOKPROBE_SYMBOL().

Acked-by: Masami Hiramatsu <mhira...@kernel.org>

OK, this is a good starting point so far. please consider that those
functions really have to be protected by kprobes. As you can see on x86,
I allowed some functions to be kprobed by commit 7ec8a97a990d ("kprobes/x86:
Allow probe on some kprobe preparation functions").
Maybe on powerpc, those arch_* functions also be probed safely, since
those are not kicked in the context of breakpoint interruption.

Thank you,

> 
> Also:
> - blacklist kretprobe_trampoline
> - blacklist arch_deref_entry_point, and
> - convert a few regular inlines to nokprobe_inline in lib/sstep.c
> 
> A key benefit is the ability to detect such symbols as being
> blacklisted. Before this patch:
> 
>   naveen@ubuntu:~/linux/tools/perf$ sudo cat 
> /sys/kernel/debug/kprobes/blacklist | grep read_mem
>   naveen@ubuntu:~/linux/tools/perf$ sudo ./perf probe read_mem
>   Failed to write event: Invalid argument
> Error: Failed to add events.
>   naveen@ubuntu:~/linux/tools/perf$ dmesg | tail -1
>   [ 3736.112815] Could not insert probe at _text+10014968: -22
> 
> After patch:
>   naveen@ubuntu:~/linux/tools/perf$ sudo cat 
> /sys/kernel/debug/kprobes/blacklist | grep read_mem
>   0xc0072b50-0xc0072d20   read_mem
>   naveen@ubuntu:~/linux/tools/perf$ sudo ./perf probe read_mem
>   read_mem is blacklisted function, skip it.
>   Added new events:
> (null):(null)(on read_mem)
> probe:read_mem   (on read_mem)
> 
>   You can now use it in all perf tools, such as:
> 
> perf record -e probe:read_mem -aR sleep 1
> 
>   naveen@ubuntu:~/linux/tools/perf$ sudo grep " read_mem" /proc/kallsyms
>   c0072b50 t read_mem
>   c05f3b40 t read_mem
>   naveen@ubuntu:~/linux/tools/perf$ sudo cat /sys/kernel/debug/kprobes/list
>   c05f3b48  k  read_mem+0x8[DISABLED]
> 
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  arch/powerpc/kernel/kprobes.c| 56 +--
>  arch/powerpc/lib/code-patching.c |  4 +-
>  arch/powerpc/lib/sstep.c | 82 
> +---
>  3 files changed, 82 insertions(+), 60 deletions(-)
> 
> diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
> index fce05a38851c..6d2d464900c4 100644
> --- a/arch/powerpc/kernel/kprobes.c
> +++ b/arch/powerpc/kernel/kprobes.c
> @@ -42,7 +42,7 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
>  
>  struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
>  
> -int __kprobes arch_prepare_kprobe(struct kprobe *p)
> +int arch_prepare_kprobe(struct kprobe *p)
>  {
>   int ret = 0;
>   kprobe_opcode_t insn = *p->addr;
> @@ -74,30 +74,34 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
>   p->ainsn.boostable = 0;
>   return ret;
>  }
> +NOKPROBE_SYMBOL(arch_prepare_kprobe);
>  
> -void __kprobes arch_arm_kprobe(struct kprobe *p)
> +void arch_arm_kprobe(struct kprobe *p)
>  {
>   *p->addr = BREAKPOINT_INSTRUCTION;
>   flush_icache_range((unsigned long) p->addr,
>  (unsigned long) p->addr + sizeof(kprobe_opcode_t));
>  }
> +NOKPROBE_SYMBOL(arch_arm_kprobe);
>  
> -void __kprobes arch_disarm_kprobe(struct kprobe *p)
> +void arch_disarm_kprobe(struct kprobe *p)
>  {
>   *p->addr = p->opcode;
>   flush_icache_range((unsigned long) p->addr,
>  (unsigned long) p->addr + sizeof(kprobe_opcode_t));
>  }
> +NOKPROBE_SYMBOL(arch_disarm_kprobe);
>  
> -void __kprobes arch_remove_kprobe(struct kprobe *p)
> +void arch_remove_kprobe(struct kprobe *p)
>  {
>   if (p->ainsn.insn) {
>   free_insn_slot(p->ainsn.insn, 0);
>   p->ainsn.insn = NULL;
>   }
>  }
> +NOKPROBE_SYMBOL(arch_remove_kprobe);
>  
> -static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs 
> *regs)
> +static nokprobe_inline void prepare_singlestep(struct kprobe *p, struct 
> pt_regs *regs)
>  {
>   enable_single_step(regs);
>  
> @@ -110,37 +114,37 @@ static void __kprobes prepare_singlestep(struct kprobe 
> *p, struct pt_regs *regs)
>   regs->nip = (unsigned long)p->ainsn.insn;
&

Re: [PATCH 5/6] perf: probes: move ftrace README parsing logic into trace-event-parse.c

2017-03-07 Thread Masami Hiramatsu
t; - return scan_ftrace_readme(FTRACE_README_KRETPROBE_OFFSET);
> -}
> diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
> index dbf95a00864a..eba44c3e9dca 100644
> --- a/tools/perf/util/probe-file.h
> +++ b/tools/perf/util/probe-file.h
> @@ -35,7 +35,6 @@ enum probe_type {
>  
>  /* probe-file.c depends on libelf */
>  #ifdef HAVE_LIBELF_SUPPORT
> -int open_trace_file(const char *trace_file, bool readwrite);
>  int probe_file__open(int flag);
>  int probe_file__open_both(int *kfd, int *ufd, int flag);
>  struct strlist *probe_file__get_namelist(int fd);
> @@ -65,7 +64,6 @@ struct probe_cache_entry *probe_cache__find_by_name(struct 
> probe_cache *pcache,
>   const char *group, const char *event);
>  int probe_cache__show_all_caches(struct strfilter *filter);
>  bool probe_type_is_available(enum probe_type type);
> -bool kretprobe_offset_is_supported(void);
>  #else/* ! HAVE_LIBELF_SUPPORT */
>  static inline struct probe_cache *probe_cache__new(const char *tgt 
> __maybe_unused)
>  {
> diff --git a/tools/perf/util/trace-event-parse.c 
> b/tools/perf/util/trace-event-parse.c
> index de0078e21408..77697c446cbd 100644
> --- a/tools/perf/util/trace-event-parse.c
> +++ b/tools/perf/util/trace-event-parse.c
> @@ -23,10 +23,12 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "../perf.h"
>  #include "util.h"
>  #include "trace-event.h"
> +#include "debug.h"
>  
>  static int get_common_field(struct scripting_context *context,
>   int *offset, int *size, const char *type)
> @@ -254,3 +256,90 @@ unsigned long long eval_flag(const char *flag)
>  
>   return 0;
>  }
> +
> +int open_trace_file(const char *trace_file, bool readwrite)
> +{
> + char buf[PATH_MAX];
> + int ret;
> +
> + ret = snprintf(buf, PATH_MAX, "%s/%s",
> +  tracing_path, trace_file);
> + if (ret >= PATH_MAX)
> + ret = -E2BIG;
> + if (ret >= 0) {
> + pr_debug("Opening %s write=%d\n", buf, readwrite);
> + if (readwrite)
> + ret = open(buf, O_RDWR | O_APPEND, 0);
> + else
> + ret = open(buf, O_RDONLY, 0);
> +
> + if (ret < 0)
> + ret = -errno;
> + }
> + return ret;
> +}
> +
> +enum ftrace_readme {
> + FTRACE_README_PROBE_TYPE_X = 0,
> + FTRACE_README_KRETPROBE_OFFSET,
> + FTRACE_README_END,
> +};
> +
> +static struct {
> + const char *pattern;
> + bool avail;
> +} ftrace_readme_table[] = {
> +#define DEFINE_TYPE(idx, pat)\
> + [idx] = {.pattern = pat, .avail = false}
> + DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"),
> + DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"),
> +};
> +
> +static bool scan_ftrace_readme(enum ftrace_readme type)
> +{
> + int fd;
> + FILE *fp;
> + char *buf = NULL;
> + size_t len = 0;
> + bool ret = false;
> + static bool scanned = false;
> +
> + if (scanned)
> + goto result;
> +
> + fd = open_trace_file("README", false);
> + if (fd < 0)
> + return ret;
> +
> + fp = fdopen(fd, "r");
> + if (!fp) {
> + close(fd);
> + return ret;
> + }
> +
> + while (getline(, , fp) > 0)
> + for (enum ftrace_readme i = 0; i < FTRACE_README_END; i++)
> + if (!ftrace_readme_table[i].avail)
> + ftrace_readme_table[i].avail =
> + strglobmatch(buf, 
> ftrace_readme_table[i].pattern);
> + scanned = true;
> +
> + fclose(fp);
> + free(buf);
> +
> +result:
> + if (type >= FTRACE_README_END)
> + return false;
> +
> + return ftrace_readme_table[type].avail;
> +}
> +
> +bool kretprobe_offset_is_supported(void)
> +{
> + return scan_ftrace_readme(FTRACE_README_KRETPROBE_OFFSET);
> +}
> +
> +bool probe_type_x_is_supported(void)
> +{
> + return scan_ftrace_readme(FTRACE_README_PROBE_TYPE_X);
> +}
> diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
> index 1fbc044f9eb0..ecda2d822daf 100644
> --- a/tools/perf/util/trace-event.h
> +++ b/tools/perf/util/trace-event.h
> @@ -37,6 +37,10 @@ int parse_ftrace_file(struct pevent *pevent, char *buf, 
> unsigned long size);
>  int parse_event_file(struct pevent *pevent,
>char *buf, unsigned long size, char *sys);
>  
> +int open_trace_file(const char *trace_file, bool readwrite);
> +bool kretprobe_offset_is_supported(void);
> +bool probe_type_x_is_supported(void);
> +
>  unsigned long long
>  raw_field_value(struct event_format *event, const char *name, void *data);
>  
> -- 
> 2.11.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH 5/6] perf: probes: move ftrace README parsing logic into trace-event-parse.c

2017-03-07 Thread Masami Hiramatsu
/util/probe-file.h b/tools/perf/util/probe-file.h
> index dbf95a00864a..eba44c3e9dca 100644
> --- a/tools/perf/util/probe-file.h
> +++ b/tools/perf/util/probe-file.h
> @@ -35,7 +35,6 @@ enum probe_type {
>  
>  /* probe-file.c depends on libelf */
>  #ifdef HAVE_LIBELF_SUPPORT
> -int open_trace_file(const char *trace_file, bool readwrite);
>  int probe_file__open(int flag);
>  int probe_file__open_both(int *kfd, int *ufd, int flag);
>  struct strlist *probe_file__get_namelist(int fd);
> @@ -65,7 +64,6 @@ struct probe_cache_entry *probe_cache__find_by_name(struct 
> probe_cache *pcache,
>   const char *group, const char *event);
>  int probe_cache__show_all_caches(struct strfilter *filter);
>  bool probe_type_is_available(enum probe_type type);
> -bool kretprobe_offset_is_supported(void);
>  #else/* ! HAVE_LIBELF_SUPPORT */
>  static inline struct probe_cache *probe_cache__new(const char *tgt 
> __maybe_unused)
>  {
> diff --git a/tools/perf/util/trace-event-parse.c 
> b/tools/perf/util/trace-event-parse.c
> index de0078e21408..77697c446cbd 100644
> --- a/tools/perf/util/trace-event-parse.c
> +++ b/tools/perf/util/trace-event-parse.c
> @@ -23,10 +23,12 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "../perf.h"
>  #include "util.h"
>  #include "trace-event.h"
> +#include "debug.h"
>  
>  static int get_common_field(struct scripting_context *context,
>   int *offset, int *size, const char *type)
> @@ -254,3 +256,90 @@ unsigned long long eval_flag(const char *flag)
>  
>   return 0;
>  }
> +
> +int open_trace_file(const char *trace_file, bool readwrite)
> +{
> + char buf[PATH_MAX];
> + int ret;
> +
> + ret = snprintf(buf, PATH_MAX, "%s/%s",
> +  tracing_path, trace_file);
> + if (ret >= PATH_MAX)
> + ret = -E2BIG;
> + if (ret >= 0) {
> + pr_debug("Opening %s write=%d\n", buf, readwrite);
> + if (readwrite)
> + ret = open(buf, O_RDWR | O_APPEND, 0);
> + else
> + ret = open(buf, O_RDONLY, 0);
> +
> + if (ret < 0)
> + ret = -errno;
> + }
> + return ret;
> +}
> +
> +enum ftrace_readme {
> + FTRACE_README_PROBE_TYPE_X = 0,
> + FTRACE_README_KRETPROBE_OFFSET,
> + FTRACE_README_END,
> +};
> +
> +static struct {
> + const char *pattern;
> + bool avail;
> +} ftrace_readme_table[] = {
> +#define DEFINE_TYPE(idx, pat)\
> + [idx] = {.pattern = pat, .avail = false}
> + DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"),
> + DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"),
> +};
> +
> +static bool scan_ftrace_readme(enum ftrace_readme type)
> +{
> + int fd;
> + FILE *fp;
> + char *buf = NULL;
> + size_t len = 0;
> + bool ret = false;
> + static bool scanned = false;
> +
> + if (scanned)
> + goto result;
> +
> + fd = open_trace_file("README", false);
> + if (fd < 0)
> + return ret;
> +
> + fp = fdopen(fd, "r");
> + if (!fp) {
> + close(fd);
> + return ret;
> + }
> +
> + while (getline(, , fp) > 0)
> + for (enum ftrace_readme i = 0; i < FTRACE_README_END; i++)
> + if (!ftrace_readme_table[i].avail)
> + ftrace_readme_table[i].avail =
> + strglobmatch(buf, 
> ftrace_readme_table[i].pattern);
> + scanned = true;
> +
> + fclose(fp);
> + free(buf);
> +
> +result:
> + if (type >= FTRACE_README_END)
> + return false;
> +
> + return ftrace_readme_table[type].avail;
> +}
> +
> +bool kretprobe_offset_is_supported(void)
> +{
> + return scan_ftrace_readme(FTRACE_README_KRETPROBE_OFFSET);
> +}
> +
> +bool probe_type_x_is_supported(void)
> +{
> + return scan_ftrace_readme(FTRACE_README_PROBE_TYPE_X);
> +}
> diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
> index 1fbc044f9eb0..ecda2d822daf 100644
> --- a/tools/perf/util/trace-event.h
> +++ b/tools/perf/util/trace-event.h
> @@ -37,6 +37,10 @@ int parse_ftrace_file(struct pevent *pevent, char *buf, 
> unsigned long size);
>  int parse_event_file(struct pevent *pevent,
>char *buf, unsigned long size, char *sys);
>  
> +int open_trace_file(const char *trace_file, bool readwrite);
> +bool kretprobe_offset_is_supported(void);
> +bool probe_type_x_is_supported(void);
> +
>  unsigned long long
>  raw_field_value(struct event_format *event, const char *name, void *data);
>  
> -- 
> 2.11.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v4 2/3] perf: kretprobes: offset from reloc_sym if kernel supports it

2017-03-06 Thread Masami Hiramatsu
On Mon, 6 Mar 2017 20:34:10 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> On 2017/03/04 09:49AM, Masami Hiramatsu wrote:
> > On Thu,  2 Mar 2017 23:25:06 +0530
> > "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:
> > 
> > > We indicate support for accepting sym+offset with kretprobes through a
> > > line in ftrace README. Parse the same to identify support and choose the
> > > appropriate format for kprobe_events.
> > 
> > Could you give us an example of this change here? :)
> > for example, comment of commit 613f050d68a8 .
> > 
> > I think the code is OK, but we need actual example of result.
> 
> Sure :)
> As an example, without this perf patch, but with the ftrace changes:
> 
>   naveen@ubuntu:~/linux/tools/perf$ sudo cat /sys/kernel/debug/tracing/README 
> | grep kretprobe
>   place (kretprobe): [:][+]|
>   naveen@ubuntu:~/linux/tools/perf$ 
>   naveen@ubuntu:~/linux/tools/perf$ sudo ./perf probe -v do_open%return
>   probe-definition(0): do_open%return 
>   symbol:do_open file:(null) line:0 offset:0 return:1 lazy:(null)
>   0 arguments
>   Looking at the vmlinux_path (8 entries long)
>   Using /boot/vmlinux for symbols
>   Open Debuginfo file: /boot/vmlinux
>   Try to find probe point from debuginfo.
>   Matched function: do_open [2d0c7d8]
>   Probe point found: do_open+0
>   Matched function: do_open [35d76b5]
>   found inline addr: 0xc04ba984
>   Failed to find "do_open%return",
>because do_open is an inlined function and has no return point.
>   An error occurred in debuginfo analysis (-22).
>   Trying to use symbols.
>   Opening /sys/kernel/debug/tracing//kprobe_events write=1
>   Writing event: r:probe/do_open do_open+0
>   Writing event: r:probe/do_open_1 do_open+0
>   Added new events:
> probe:do_open(on do_open%return)
> probe:do_open_1  (on do_open%return)
> 
>   You can now use it in all perf tools, such as:
> 
> perf record -e probe:do_open_1 -aR sleep 1
> 
>   naveen@ubuntu:~/linux/tools/perf$ sudo cat /sys/kernel/debug/kprobes/list
>   c0041370  k  kretprobe_trampoline+0x0[OPTIMIZED]
>   c04433d0  r  do_open+0x0[DISABLED]
>   c04433d0  r  do_open+0x0[DISABLED]
> 
> And after this patch (and the subsequent powerpc patch):
> 
>   naveen@ubuntu:~/linux/tools/perf$ sudo ./perf probe -v do_open%return
>   probe-definition(0): do_open%return 
>   symbol:do_open file:(null) line:0 offset:0 return:1 lazy:(null)
>   0 arguments
>   Looking at the vmlinux_path (8 entries long)
>   Using /boot/vmlinux for symbols
>   Open Debuginfo file: /boot/vmlinux
>   Try to find probe point from debuginfo.
>   Matched function: do_open [2d0c7d8]
>   Probe point found: do_open+0
>   Matched function: do_open [35d76b5]
>   found inline addr: 0xc04ba984
>   Failed to find "do_open%return",
>because do_open is an inlined function and has no return point.
>   An error occurred in debuginfo analysis (-22).
>   Trying to use symbols.
>   Opening /sys/kernel/debug/tracing//README write=0
>   Opening /sys/kernel/debug/tracing//kprobe_events write=1
>   Writing event: r:probe/do_open _text+4469712
>   Writing event: r:probe/do_open_1 _text+4956248
>   Added new events:
> probe:do_open(on do_open%return)
> probe:do_open_1  (on do_open%return)
> 
>   You can now use it in all perf tools, such as:
> 
> perf record -e probe:do_open_1 -aR sleep 1
> 
>   naveen@ubuntu:~/linux/tools/perf$ sudo cat /sys/kernel/debug/kprobes/list
>   c0041370  k  kretprobe_trampoline+0x0[OPTIMIZED]
>   c04433d0  r  do_open+0x0[DISABLED]
>   c04ba058  r  do_open+0x8[DISABLED]

Ok, with this usage example.

Acked-by: Masami Hiramatsu <mhira...@kernel.org>

Thanks,

> 
> 
> Thanks,
> - Naveen
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v4 2/3] perf: kretprobes: offset from reloc_sym if kernel supports it

2017-03-06 Thread Masami Hiramatsu
On Mon,  6 Mar 2017 23:19:09 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> Masami,
> Your patch works, thanks! However, I felt we could refactor and reuse
> some of the code across kprobes.c for this purpose. Can you please see
> if the below patch is fine?

OK, looks good to me:)

Acked-by: Masami Hiramatsu <mhira...@kernel.org>

Thanks!

> 
> Thanks,
> Naveen
> 
> --
> trace/kprobes: fix check for kretprobe offset within function entry
> 
> perf specifies an offset from _text and since this offset is fed
> directly into the arch-specific helper, kprobes tracer rejects
> installation of kretprobes through perf. Fix this by looking up the
> actual offset from a function for the specified sym+offset.
> 
> Refactor and reuse existing routines to limit code duplication -- we
> repurpose kprobe_addr() for determining final kprobe address and we
> split out the function entry offset determination into a separate
> generic helper.
> 
> Before patch:
> 
>   naveen@ubuntu:~/linux/tools/perf$ sudo ./perf probe -v do_open%return
>   probe-definition(0): do_open%return
>   symbol:do_open file:(null) line:0 offset:0 return:1 lazy:(null)
>   0 arguments
>   Looking at the vmlinux_path (8 entries long)
>   Using /boot/vmlinux for symbols
>   Open Debuginfo file: /boot/vmlinux
>   Try to find probe point from debuginfo.
>   Matched function: do_open [2d0c7ff]
>   Probe point found: do_open+0
>   Matched function: do_open [35d76dc]
>   found inline addr: 0xc04ba9c4
>   Failed to find "do_open%return",
>because do_open is an inlined function and has no return point.
>   An error occurred in debuginfo analysis (-22).
>   Trying to use symbols.
>   Opening /sys/kernel/debug/tracing//README write=0
>   Opening /sys/kernel/debug/tracing//kprobe_events write=1
>   Writing event: r:probe/do_open _text+4469776
>   Failed to write event: Invalid argument
> Error: Failed to add events. Reason: Invalid argument (Code: -22)
>   naveen@ubuntu:~/linux/tools/perf$ dmesg | tail
>   
>   [   33.568656] Given offset is not valid for return probe.
> 
> After patch:
> 
>   naveen@ubuntu:~/linux/tools/perf$ sudo ./perf probe -v do_open%return
>   probe-definition(0): do_open%return
>   symbol:do_open file:(null) line:0 offset:0 return:1 lazy:(null)
>   0 arguments
>   Looking at the vmlinux_path (8 entries long)
>   Using /boot/vmlinux for symbols
>   Open Debuginfo file: /boot/vmlinux
>   Try to find probe point from debuginfo.
>   Matched function: do_open [2d0c7d6]
>   Probe point found: do_open+0
>   Matched function: do_open [35d76b3]
>   found inline addr: 0xc04ba9e4
>   Failed to find "do_open%return",
>because do_open is an inlined function and has no return point.
>   An error occurred in debuginfo analysis (-22).
>   Trying to use symbols.
>   Opening /sys/kernel/debug/tracing//README write=0
>   Opening /sys/kernel/debug/tracing//kprobe_events write=1
>   Writing event: r:probe/do_open _text+4469808
>   Writing event: r:probe/do_open_1 _text+4956344
>   Added new events:
> probe:do_open(on do_open%return)
> probe:do_open_1  (on do_open%return)
> 
>   You can now use it in all perf tools, such as:
> 
> perf record -e probe:do_open_1 -aR sleep 1
> 
>   naveen@ubuntu:~/linux/tools/perf$ sudo cat /sys/kernel/debug/kprobes/list
>   c0041370  k  kretprobe_trampoline+0x0[OPTIMIZED]
>   c04ba0b8  r  do_open+0x8[DISABLED]
>   c0443430  r  do_open+0x0[DISABLED]
> 
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  include/linux/kprobes.h |  1 +
>  kernel/kprobes.c| 40 ++--
>  kernel/trace/trace_kprobe.c |  2 +-
>  3 files changed, 28 insertions(+), 15 deletions(-)
> 
> diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
> index 862f87adcbb4..6888c9f29cb6 100644
> --- a/include/linux/kprobes.h
> +++ b/include/linux/kprobes.h
> @@ -267,6 +267,7 @@ extern void show_registers(struct pt_regs *regs);
>  extern void kprobes_inc_nmissed_count(struct kprobe *p);
>  extern bool arch_within_kprobe_blacklist(unsigned long addr);
>  extern bool arch_function_offset_within_entry(unsigned long offset);
> +extern bool function_offset_within_entry(kprobe_opcode_t *addr, const char 
> *sym, unsigned long offset);
>  
>  extern bool within_kprobe_blacklist(unsigned long addr);
>  
> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> index 524766563896..49f870ea4070 100644
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -1391,21 +1391,19 @@ bool within_kprobe_blacklist(unsigned long add

Re: [PATCH v4 2/3] perf: kretprobes: offset from reloc_sym if kernel supports it

2017-03-03 Thread Masami Hiramatsu
On Sat, 4 Mar 2017 11:35:51 +0900
Masami Hiramatsu <mhira...@kernel.org> wrote:

> On Sat, 4 Mar 2017 09:49:11 +0900
> Masami Hiramatsu <mhira...@kernel.org> wrote:
> 
> > On Thu,  2 Mar 2017 23:25:06 +0530
> > "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:
> > 
> > > We indicate support for accepting sym+offset with kretprobes through a
> > > line in ftrace README. Parse the same to identify support and choose the
> > > appropriate format for kprobe_events.
> > 
> > Could you give us an example of this change here? :)
> > for example, comment of commit 613f050d68a8 .
> > 
> > I think the code is OK, but we need actual example of result.
> 
> Hi Naveen,
> 
> I've tried following commands
> 
> $ grep "[Tt] user_read$" /proc/kallsyms  
>  T user_read
>  t user_read
> $ sudo ./perf probe -D user_read%return
> r:probe/user_read _text+3539616
> r:probe/user_read_1 _text+3653408
> 
> OK, looks good. However, when I set the retprobes, I got an error.
> 
> $ sudo ./perf probe -a user_read%return
> Failed to write event: Invalid argument
>   Error: Failed to add events.
> 
> And kernel rejected that.
> 
> $ dmesg -k | tail -n 1
> [  850.315068] Given offset is not valid for return probe.
> 
> Hmm, curious..

Ah, I see.

static int create_trace_kprobe(int argc, char **argv)
...
} else {
/* a symbol specified */
symbol = argv[1];
/* TODO: support .init module functions */
ret = traceprobe_split_symbol_offset(symbol, );
if (ret) {
pr_info("Failed to parse symbol.\n");
return ret;
}
if (offset && is_return &&
!arch_function_offset_within_entry(offset)) {
pr_info("Given offset is not valid for return 
probe.\n");
return -EINVAL;
}
}

So, actually, traceprobe_split_symbol_offset() just split out symbol
and offset from symbol string (e.g. "_text+3539616").
So, you should use kallsyms_lookup_size_offset() here again to check
offset.

Please try attached patch (I've already tested on x86-64).

$ sudo ./perf probe -a user_read%return
Added new events:
  probe:user_read  (on user_read%return)
  probe:user_read_1(on user_read%return)

You can now use it in all perf tools, such as:

perf record -e probe:user_read_1 -aR sleep 1

$ sudo ./perf probe -l
  probe:user_read  (on user_read%return@security/keys/user_defined.c)
  probe:user_read_1(on user_read%return@selinux/ss/policydb.c)
$ sudo cat /sys/kernel/debug/kprobes/list
9637bf70  r  user_read+0x0[DISABLED][FTRACE]
963602f0  r  user_read+0x0[DISABLED][FTRACE]

Thank you,


-- 
Masami Hiramatsu <mhira...@kernel.org>


tracing-kprobe-check-kretprobe
Description: Binary data


Re: [PATCH v4 2/3] perf: kretprobes: offset from reloc_sym if kernel supports it

2017-03-03 Thread Masami Hiramatsu
On Sat, 4 Mar 2017 11:35:51 +0900
Masami Hiramatsu <mhira...@kernel.org> wrote:

> On Sat, 4 Mar 2017 09:49:11 +0900
> Masami Hiramatsu <mhira...@kernel.org> wrote:
> 
> > On Thu,  2 Mar 2017 23:25:06 +0530
> > "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:
> > 
> > > We indicate support for accepting sym+offset with kretprobes through a
> > > line in ftrace README. Parse the same to identify support and choose the
> > > appropriate format for kprobe_events.
> > 
> > Could you give us an example of this change here? :)
> > for example, comment of commit 613f050d68a8 .
> > 
> > I think the code is OK, but we need actual example of result.
> 
> Hi Naveen,
> 
> I've tried following commands
> 
> $ grep "[Tt] user_read$" /proc/kallsyms  
>  T user_read
>  t user_read
> $ sudo ./perf probe -D user_read%return
> r:probe/user_read _text+3539616
> r:probe/user_read_1 _text+3653408
> 
> OK, looks good. However, when I set the retprobes, I got an error.
> 
> $ sudo ./perf probe -a user_read%return
> Failed to write event: Invalid argument
>   Error: Failed to add events.
> 
> And kernel rejected that.
> 
> $ dmesg -k | tail -n 1
> [  850.315068] Given offset is not valid for return probe.
> 
> Hmm, curious..
> 
> I tried normal probes
> 
> $ sudo ./perf probe -D user_read
> p:probe/user_read _text+3539616
> p:probe/user_read_1 _text+3653408
> $ sudo ./perf probe -a user_read
> Added new events:
>   probe:user_read  (on user_read)
>   probe:user_read_1(on user_read)
> 
> You can now use it in all perf tools, such as:
> 
>   perf record -e probe:user_read_1 -aR sleep 1
> 
> It works!
> 
> $ sudo ./perf probe -l
>   probe:user_read  (on user_read@security/keys/user_defined.c)
>   probe:user_read_1(on user_read@selinux/ss/policydb.c)
> $ sudo cat /sys/kernel/debug/kprobes/list
> 9237bf20  k  user_read+0x0[DISABLED][FTRACE]
> 923602a0  k  user_read+0x0[DISABLED][FTRACE]
> 
> So, the both "_text+3539616" and "_text+3653408" are correctly located
> on the entry address of user_read functions. It seems kernel-side
> symbol+offset check is wrong.

FYI, without this patch, perf probe returns same place for same-name
functions. So this patch itself looks good.

$ sudo ./perf probe -D user_read%return
r:probe/user_read user_read+0
r:probe/user_read_1 user_read+0


Thanks,


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v4 2/3] perf: kretprobes: offset from reloc_sym if kernel supports it

2017-03-03 Thread Masami Hiramatsu
On Sat, 4 Mar 2017 09:49:11 +0900
Masami Hiramatsu <mhira...@kernel.org> wrote:

> On Thu,  2 Mar 2017 23:25:06 +0530
> "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:
> 
> > We indicate support for accepting sym+offset with kretprobes through a
> > line in ftrace README. Parse the same to identify support and choose the
> > appropriate format for kprobe_events.
> 
> Could you give us an example of this change here? :)
> for example, comment of commit 613f050d68a8 .
> 
> I think the code is OK, but we need actual example of result.

Hi Naveen,

I've tried following commands

$ grep "[Tt] user_read$" /proc/kallsyms  
 T user_read
 t user_read
$ sudo ./perf probe -D user_read%return
r:probe/user_read _text+3539616
r:probe/user_read_1 _text+3653408

OK, looks good. However, when I set the retprobes, I got an error.

$ sudo ./perf probe -a user_read%return
Failed to write event: Invalid argument
  Error: Failed to add events.

And kernel rejected that.

$ dmesg -k | tail -n 1
[  850.315068] Given offset is not valid for return probe.

Hmm, curious..

I tried normal probes

$ sudo ./perf probe -D user_read
p:probe/user_read _text+3539616
p:probe/user_read_1 _text+3653408
$ sudo ./perf probe -a user_read
Added new events:
  probe:user_read  (on user_read)
  probe:user_read_1(on user_read)

You can now use it in all perf tools, such as:

perf record -e probe:user_read_1 -aR sleep 1

It works!

$ sudo ./perf probe -l
  probe:user_read  (on user_read@security/keys/user_defined.c)
  probe:user_read_1(on user_read@selinux/ss/policydb.c)
$ sudo cat /sys/kernel/debug/kprobes/list
9237bf20  k  user_read+0x0[DISABLED][FTRACE]
923602a0  k  user_read+0x0[DISABLED][FTRACE]

So, the both "_text+3539616" and "_text+3653408" are correctly located
on the entry address of user_read functions. It seems kernel-side
symbol+offset check is wrong.

Thank you,


> 
> Thanks,
> 
> > 
> > Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> > ---
> >  tools/perf/util/probe-event.c | 12 +---
> >  tools/perf/util/probe-file.c  |  7 +++
> >  tools/perf/util/probe-file.h  |  1 +
> >  3 files changed, 13 insertions(+), 7 deletions(-)
> > 
> > diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> > index 35f5b7b7715c..faf5789902f5 100644
> > --- a/tools/perf/util/probe-event.c
> > +++ b/tools/perf/util/probe-event.c
> > @@ -757,7 +757,9 @@ post_process_kernel_probe_trace_events(struct 
> > probe_trace_event *tevs,
> > }
> >  
> > for (i = 0; i < ntevs; i++) {
> > -   if (!tevs[i].point.address || tevs[i].point.retprobe)
> > +   if (!tevs[i].point.address)
> > +   continue;
> > +   if (tevs[i].point.retprobe && !kretprobe_offset_is_supported())
> > continue;
> > /* If we found a wrong one, mark it by NULL symbol */
> > if (kprobe_warn_out_range(tevs[i].point.symbol,
> > @@ -1528,11 +1530,6 @@ static int parse_perf_probe_point(char *arg, struct 
> > perf_probe_event *pev)
> > return -EINVAL;
> > }
> >  
> > -   if (pp->retprobe && !pp->function) {
> > -   semantic_error("Return probe requires an entry function.\n");
> > -   return -EINVAL;
> > -   }
> > -
> > if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) {
> > semantic_error("Offset/Line/Lazy pattern can't be used with "
> >"return probe.\n");
> > @@ -2841,7 +2838,8 @@ static int find_probe_trace_events_from_map(struct 
> > perf_probe_event *pev,
> > }
> >  
> > /* Note that the symbols in the kmodule are not relocated */
> > -   if (!pev->uprobes && !pp->retprobe && !pev->target) {
> > +   if (!pev->uprobes && !pev->target &&
> > +   (!pp->retprobe || kretprobe_offset_is_supported())) {
> > reloc_sym = kernel_get_ref_reloc_sym();
> > if (!reloc_sym) {
> > pr_warning("Relocated base symbol is not found!\n");
> > diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
> > index 8a219cd831b7..1542cd0d6799 100644
> > --- a/tools/perf/util/probe-file.c
> > +++ b/tools/perf/util/probe-file.c
> > @@ -879,6 +879,7 @@ int probe_cache__show_all_caches(struct strfilter 
> > *filter)
> >  
> >  enum ftrace_readme {
> > FT

Re: [PATCH v4 3/3] perf: powerpc: choose local entry point with kretprobes

2017-03-03 Thread Masami Hiramatsu
On Thu,  2 Mar 2017 23:25:07 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> perf now uses an offset from _text/_stext for kretprobes if the kernel
> supports it, rather than the actual function name. As such, let's choose
> the LEP for powerpc ABIv2 so as to ensure the probe gets hit. Do it only
> if the kernel supports specifying offsets with kretprobes.

Looks good to me.

Acked-by: Masami Hiramatsu <mhira...@kernel.org>

Thanks!

> 
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  tools/perf/arch/powerpc/util/sym-handling.c | 10 ++
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/tools/perf/arch/powerpc/util/sym-handling.c 
> b/tools/perf/arch/powerpc/util/sym-handling.c
> index 1030a6e504bb..cc7c2697c036 100644
> --- a/tools/perf/arch/powerpc/util/sym-handling.c
> +++ b/tools/perf/arch/powerpc/util/sym-handling.c
> @@ -10,6 +10,7 @@
>  #include "symbol.h"
>  #include "map.h"
>  #include "probe-event.h"
> +#include "probe-file.h"
>  
>  #ifdef HAVE_LIBELF_SUPPORT
>  bool elf__needs_adjust_symbols(GElf_Ehdr ehdr)
> @@ -79,11 +80,12 @@ void arch__fix_tev_from_maps(struct perf_probe_event *pev,
>* However, if the user specifies an offset, we fall back to using the
>* GEP since all userspace applications (objdump/readelf) show function
>* disassembly with offsets from the GEP.
> -  *
> -  * In addition, we shouldn't specify an offset for kretprobes.
>*/
> - if (pev->point.offset || (!pev->uprobes && pev->point.retprobe) ||
> - !map || !sym)
> + if (pev->point.offset || !map || !sym)
> + return;
> +
> + /* For kretprobes, add an offset only if the kernel supports it */
> + if (!pev->uprobes && pev->point.retprobe && 
> !kretprobe_offset_is_supported())
>   return;
>  
>   lep_offset = PPC64_LOCAL_ENTRY_OFFSET(sym->arch_sym);
> -- 
> 2.11.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v4 2/3] perf: kretprobes: offset from reloc_sym if kernel supports it

2017-03-03 Thread Masami Hiramatsu
On Thu,  2 Mar 2017 23:25:06 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> We indicate support for accepting sym+offset with kretprobes through a
> line in ftrace README. Parse the same to identify support and choose the
> appropriate format for kprobe_events.

Could you give us an example of this change here? :)
for example, comment of commit 613f050d68a8 .

I think the code is OK, but we need actual example of result.

Thanks,

> 
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  tools/perf/util/probe-event.c | 12 +---
>  tools/perf/util/probe-file.c  |  7 +++
>  tools/perf/util/probe-file.h  |  1 +
>  3 files changed, 13 insertions(+), 7 deletions(-)
> 
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index 35f5b7b7715c..faf5789902f5 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -757,7 +757,9 @@ post_process_kernel_probe_trace_events(struct 
> probe_trace_event *tevs,
>   }
>  
>   for (i = 0; i < ntevs; i++) {
> - if (!tevs[i].point.address || tevs[i].point.retprobe)
> + if (!tevs[i].point.address)
> + continue;
> + if (tevs[i].point.retprobe && !kretprobe_offset_is_supported())
>   continue;
>   /* If we found a wrong one, mark it by NULL symbol */
>   if (kprobe_warn_out_range(tevs[i].point.symbol,
> @@ -1528,11 +1530,6 @@ static int parse_perf_probe_point(char *arg, struct 
> perf_probe_event *pev)
>   return -EINVAL;
>   }
>  
> - if (pp->retprobe && !pp->function) {
> - semantic_error("Return probe requires an entry function.\n");
> - return -EINVAL;
> - }
> -
>   if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) {
>   semantic_error("Offset/Line/Lazy pattern can't be used with "
>  "return probe.\n");
> @@ -2841,7 +2838,8 @@ static int find_probe_trace_events_from_map(struct 
> perf_probe_event *pev,
>   }
>  
>   /* Note that the symbols in the kmodule are not relocated */
> - if (!pev->uprobes && !pp->retprobe && !pev->target) {
> + if (!pev->uprobes && !pev->target &&
> + (!pp->retprobe || kretprobe_offset_is_supported())) {
>   reloc_sym = kernel_get_ref_reloc_sym();
>   if (!reloc_sym) {
>   pr_warning("Relocated base symbol is not found!\n");
> diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
> index 8a219cd831b7..1542cd0d6799 100644
> --- a/tools/perf/util/probe-file.c
> +++ b/tools/perf/util/probe-file.c
> @@ -879,6 +879,7 @@ int probe_cache__show_all_caches(struct strfilter *filter)
>  
>  enum ftrace_readme {
>   FTRACE_README_PROBE_TYPE_X = 0,
> + FTRACE_README_KRETPROBE_OFFSET,
>   FTRACE_README_END,
>  };
>  
> @@ -889,6 +890,7 @@ static struct {
>  #define DEFINE_TYPE(idx, pat)\
>   [idx] = {.pattern = pat, .avail = false}
>   DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"),
> + DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"),
>  };
>  
>  static bool scan_ftrace_readme(enum ftrace_readme type)
> @@ -939,3 +941,8 @@ bool probe_type_is_available(enum probe_type type)
>  
>   return true;
>  }
> +
> +bool kretprobe_offset_is_supported(void)
> +{
> + return scan_ftrace_readme(FTRACE_README_KRETPROBE_OFFSET);
> +}
> diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
> index a17a82eff8a0..dbf95a00864a 100644
> --- a/tools/perf/util/probe-file.h
> +++ b/tools/perf/util/probe-file.h
> @@ -65,6 +65,7 @@ struct probe_cache_entry *probe_cache__find_by_name(struct 
> probe_cache *pcache,
>   const char *group, const char *event);
>  int probe_cache__show_all_caches(struct strfilter *filter);
>  bool probe_type_is_available(enum probe_type type);
> +bool kretprobe_offset_is_supported(void);
>  #else/* ! HAVE_LIBELF_SUPPORT */
>  static inline struct probe_cache *probe_cache__new(const char *tgt 
> __maybe_unused)
>  {
> -- 
> 2.11.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v4 1/3] perf: probe: factor out the ftrace README scanning

2017-03-03 Thread Masami Hiramatsu
On Thu,  2 Mar 2017 23:25:05 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> Simplify and separate out the ftrace README scanning logic into a
> separate helper. This is used subsequently to scan for all patterns of
> interest and to cache the result.
> 
> Since we are only interested in availability of probe argument type x,
> we will only scan for that.

Ah, OK, this can simplify and shorten the actual scanning time.
If there are any needs for checking those in the future, we can
add it again at that moment.

Acked-by: Masami Hiramatsu <mhira...@kernel.org>

Thank you!

> 
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  tools/perf/util/probe-file.c | 70 
> +++-
>  1 file changed, 37 insertions(+), 33 deletions(-)
> 
> diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
> index 1a62daceb028..8a219cd831b7 100644
> --- a/tools/perf/util/probe-file.c
> +++ b/tools/perf/util/probe-file.c
> @@ -877,35 +877,31 @@ int probe_cache__show_all_caches(struct strfilter 
> *filter)
>   return 0;
>  }
>  
> +enum ftrace_readme {
> + FTRACE_README_PROBE_TYPE_X = 0,
> + FTRACE_README_END,
> +};
> +
>  static struct {
>   const char *pattern;
> - boolavail;
> - boolchecked;
> -} probe_type_table[] = {
> -#define DEFINE_TYPE(idx, pat, def_avail) \
> - [idx] = {.pattern = pat, .avail = (def_avail)}
> - DEFINE_TYPE(PROBE_TYPE_U, "* u8/16/32/64,*", true),
> - DEFINE_TYPE(PROBE_TYPE_S, "* s8/16/32/64,*", true),
> - DEFINE_TYPE(PROBE_TYPE_X, "* x8/16/32/64,*", false),
> - DEFINE_TYPE(PROBE_TYPE_STRING, "* string,*", true),
> - DEFINE_TYPE(PROBE_TYPE_BITFIELD,
> - "* b@/", true),
> + bool avail;
> +} ftrace_readme_table[] = {
> +#define DEFINE_TYPE(idx, pat)\
> + [idx] = {.pattern = pat, .avail = false}
> + DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"),
>  };
>  
> -bool probe_type_is_available(enum probe_type type)
> +static bool scan_ftrace_readme(enum ftrace_readme type)
>  {
> + int fd;
>   FILE *fp;
>   char *buf = NULL;
>   size_t len = 0;
> - bool target_line = false;
> - bool ret = probe_type_table[type].avail;
> - int fd;
> + bool ret = false;
> + static bool scanned = false;
>  
> - if (type >= PROBE_TYPE_END)
> - return false;
> - /* We don't have to check the type which supported by default */
> - if (ret || probe_type_table[type].checked)
> - return ret;
> + if (scanned)
> + goto result;
>  
>   fd = open_trace_file("README", false);
>   if (fd < 0)
> @@ -917,21 +913,29 @@ bool probe_type_is_available(enum probe_type type)
>   return ret;
>   }
>  
> - while (getline(, , fp) > 0 && !ret) {
> - if (!target_line) {
> - target_line = !!strstr(buf, " type: ");
> - if (!target_line)
> - continue;
> - } else if (strstr(buf, "\t  ") != buf)
> - break;
> - ret = strglobmatch(buf, probe_type_table[type].pattern);
> - }
> - /* Cache the result */
> - probe_type_table[type].checked = true;
> - probe_type_table[type].avail = ret;
> + while (getline(, , fp) > 0)
> + for (enum ftrace_readme i = 0; i < FTRACE_README_END; i++)
> + if (!ftrace_readme_table[i].avail)
> + ftrace_readme_table[i].avail =
> + strglobmatch(buf, 
> ftrace_readme_table[i].pattern);
> + scanned = true;
>  
>   fclose(fp);
>   free(buf);
>  
> - return ret;
> +result:
> + if (type >= FTRACE_README_END)
> + return false;
> +
> + return ftrace_readme_table[type].avail;
> +}
> +
> +bool probe_type_is_available(enum probe_type type)
> +{
> + if (type >= PROBE_TYPE_END)
> + return false;
> + else if (type == PROBE_TYPE_X)
> + return scan_ftrace_readme(FTRACE_README_PROBE_TYPE_X);
> +
> + return true;
>  }
> -- 
> 2.11.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v2 3.5/5] trace/kprobes: Add back warning about offset in return probes

2017-02-27 Thread Masami Hiramatsu
On Mon, 27 Feb 2017 11:52:04 -0500
"Steven Rostedt (VMware)" <rost...@goodmis.org> wrote:

> Let's not remove the warning about offsets and return probes when the
> offset is invalid.

Agreed, This looks good to me.

Acked-by: Masami Hiramatsu <mhira...@kernel.org>

Thanks!

> 
> Signed-off-by: Steven Rostedt (VMware) <rost...@goodmis.org>
> ---
> diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
> index 3f4f788..f626235 100644
> --- a/kernel/trace/trace_kprobe.c
> +++ b/kernel/trace/trace_kprobe.c
> @@ -695,6 +695,11 @@ static int create_trace_kprobe(int argc, char **argv)
>   pr_info("Failed to parse symbol.\n");
>   return ret;
>   }
> + if (offset && is_return &&
> + !arch_function_offset_within_entry(offset)) {
> + pr_info("Given offset is not valid for return 
> probe.\n");
> +     return -EINVAL;
> + }
>   }
>   argc -= 2; argv += 2;
>  


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v2 4/5] perf: kretprobes: offset from reloc_sym if kernel supports it

2017-02-24 Thread Masami Hiramatsu
On Fri, 24 Feb 2017 17:11:03 -0300
Arnaldo Carvalho de Melo <a...@kernel.org> wrote:

> Em Sat, Feb 25, 2017 at 02:29:17AM +0900, Masami Hiramatsu escreveu:
> > On Fri, 24 Feb 2017 00:46:08 +0530
> > "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:
> > > Thanks. I hope that's an Ack for this patchset?
> > 
> > OK, for 1/5, 2/5, 3/5, and 5/5;
> > 
> > Acked-by: Masami Hiramatsu <mhira...@kernel.org>
> > 
> > And could you make v4 series including all patches? (Not only updates)
> 
> So, to make progress I processed these:
> 
> [acme@jouet linux]$ git log --oneline -3
> eb55608340b7 perf probe: Generalize probe event file open routine
> 859d718fac06 trace/kprobes: Allow return probes with offsets and absolute 
> addresses
> a10489121c81 kretprobes: Ensure probe location is at function entry
> [acme@jouet linux]$
> 
> Waiting for Naveen to react to these last minute considerations from
> Masami and for the Ack from the PPC guys about "[PATCH v2 2/5] powerpc:
> kretprobes: override default function entry offset".

Thanks Arnaldo!!

Naveen, please update your ppc and perf patches and send it to Arnaldo.
I'm happy to review it.

-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v2 4/5] perf: kretprobes: offset from reloc_sym if kernel supports it

2017-02-24 Thread Masami Hiramatsu
On Fri, 24 Feb 2017 00:46:08 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> On 2017/02/23 06:10PM, Masami Hiramatsu wrote:
> > On Wed, 22 Feb 2017 19:23:40 +0530
> > "Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:
> > 
> > > We indicate support for accepting sym+offset with kretprobes through a
> > > line in ftrace README. Parse the same to identify support and choose the
> > > appropriate format for kprobe_events.
> > > 
> > > Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> > > ---
> > >  tools/perf/util/probe-event.c | 47 
> > > ---
> > >  tools/perf/util/probe-event.h |  2 ++
> > >  2 files changed, 42 insertions(+), 7 deletions(-)
> > > 
> 
> [snip]
> 
> > 
> > Could you reuse (refactoring) probe_type_is_available() in probe-file.c to 
> > share
> > opening README file?
> 
> Done. I've sent patches to do that, please review.

OK.

> 
> > 
> > Others looks good to me :)
> 
> Thanks. I hope that's an Ack for this patchset?

OK, for 1/5, 2/5, 3/5, and 5/5;

Acked-by: Masami Hiramatsu <mhira...@kernel.org>

And could you make v4 series including all patches? (Not only updates)

> 
> If so, and if Ingo/Michael agree, would it be ok to take the kernel bits 
> through the powerpc tree like we did for kprobe_exceptions_notify() 
> cleanup?

If it is not urgent (yes, it seems) and since it changes arch independent
parts, I think this series should finally go through Ingo's tree.


Thank you,


-- 
Masami Hiramatsu <mhira...@kernel.org>


Re: [PATCH v3 2/2] perf: kretprobes: offset from reloc_sym if kernel supports it

2017-02-24 Thread Masami Hiramatsu
On Thu, 23 Feb 2017 17:07:24 +0530
"Naveen N. Rao" <naveen.n@linux.vnet.ibm.com> wrote:

> We indicate support for accepting sym+offset with kretprobes through a
> line in ftrace README. Parse the same to identify support and choose the
> appropriate format for kprobe_events.
> 
> Signed-off-by: Naveen N. Rao <naveen.n@linux.vnet.ibm.com>
> ---
>  tools/perf/util/probe-event.c | 49 
> ---
>  tools/perf/util/probe-event.h |  2 ++
>  2 files changed, 44 insertions(+), 7 deletions(-)
> 
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index 35f5b7b7715c..dd6b9ce0eef3 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -737,6 +737,43 @@ post_process_module_probe_trace_events(struct 
> probe_trace_event *tevs,
>   return ret;
>  }
>  
> +bool is_kretprobe_offset_supported(void)
> +{
> + FILE *fp;
> + char *buf = NULL;
> + size_t len = 0;
> + bool target_line = false;
> + static int supported = -1;
> + int fd;
> +
> + if (supported >= 0)
> + return !!supported;
> +
> + fd = open_trace_file("README", false);
> + if (fd < 0)
> + return false;
> +
> + fp = fdopen(fd, "r");
> + if (!fp) {
> + close(fd);
> + return false;
> + }
> +
> + while (getline(, , fp) > 0) {
> + target_line = !!strstr(buf, "place (kretprobe): ");
> + if (!target_line)
> + continue;
> + supported = 1;
> + }
> + if (supported == -1)
> + supported = 0;
> +
> + fclose(fp);
> + free(buf);
> +
> + return !!supported;
> +}

Hmm, I think you can do more than that. 
Can you reuse probe_type_is_available() to scan README?
I think we can have something like scan_ftrace_readme() in probe-file.c
to scan all the options and cache the results. 

probe_type_is_available() and kreprobe_offset_is_available()
just returns cached result or scan it in first call.(I would like to
ask you to do it in probe-file.c too)

Thank you,


> +
>  static int
>  post_process_kernel_probe_trace_events(struct probe_trace_event *tevs,
>  int ntevs)
> @@ -757,7 +794,9 @@ post_process_kernel_probe_trace_events(struct 
> probe_trace_event *tevs,
>   }
>  
>   for (i = 0; i < ntevs; i++) {
> - if (!tevs[i].point.address || tevs[i].point.retprobe)
> + if (!tevs[i].point.address)
> + continue;
> + if (tevs[i].point.retprobe && !is_kretprobe_offset_supported())
>   continue;
>   /* If we found a wrong one, mark it by NULL symbol */
>   if (kprobe_warn_out_range(tevs[i].point.symbol,
> @@ -1528,11 +1567,6 @@ static int parse_perf_probe_point(char *arg, struct 
> perf_probe_event *pev)
>   return -EINVAL;
>   }
>  
> - if (pp->retprobe && !pp->function) {
> - semantic_error("Return probe requires an entry function.\n");
> - return -EINVAL;
> - }
> -
>   if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) {
>   semantic_error("Offset/Line/Lazy pattern can't be used with "
>  "return probe.\n");
> @@ -2841,7 +2875,8 @@ static int find_probe_trace_events_from_map(struct 
> perf_probe_event *pev,
>   }
>  
>   /* Note that the symbols in the kmodule are not relocated */
> - if (!pev->uprobes && !pp->retprobe && !pev->target) {
> + if (!pev->uprobes && !pev->target &&
> + (!pp->retprobe || is_kretprobe_offset_supported())) {
>   reloc_sym = kernel_get_ref_reloc_sym();
>   if (!reloc_sym) {
>   pr_warning("Relocated base symbol is not found!\n");
> diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
> index 5d4e94061402..449d4f311355 100644
> --- a/tools/perf/util/probe-event.h
> +++ b/tools/perf/util/probe-event.h
> @@ -135,6 +135,8 @@ bool perf_probe_with_var(struct perf_probe_event *pev);
>  /* Check the perf_probe_event needs debuginfo */
>  bool perf_probe_event_need_dwarf(struct perf_probe_event *pev);
>  
> +bool is_kretprobe_offset_supported(void);
> +
>  /* Release event contents */
>  void clear_perf_probe_event(struct perf_probe_event *pev);
>  void clear_probe_trace_event(struct probe_trace_event *tev);
> -- 
> 2.11.1
> 


-- 
Masami Hiramatsu <mhira...@kernel.org>


  1   2   >