Merge tag 'trace-v5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 20 Jun 2020 20:17:47 +0000 (13:17 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 20 Jun 2020 20:17:47 +0000 (13:17 -0700)
Pull tracing fixes from Steven Rostedt:

 - Have recordmcount work with > 64K sections (to support LTO)

 - kprobe RCU fixes

 - Correct a kprobe critical section with missing mutex

 - Remove redundant arch_disarm_kprobe() call

 - Fix lockup when kretprobe triggers within kprobe_flush_task()

 - Fix memory leak in fetch_op_data operations

 - Fix sleep in atomic in ftrace trace array sample code

 - Free up memory on failure in sample trace array code

 - Fix incorrect reporting of function_graph fields in format file

 - Fix quote within quote parsing in bootconfig

 - Fix return value of bootconfig tool

 - Add testcases for bootconfig tool

 - Fix maybe uninitialized warning in ftrace pid file code

 - Remove unused variable in tracing_iter_reset()

 - Fix some typos

* tag 'trace-v5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace:
  ftrace: Fix maybe-uninitialized compiler warning
  tools/bootconfig: Add testcase for show-command and quotes test
  tools/bootconfig: Fix to return 0 if succeeded to show the bootconfig
  tools/bootconfig: Fix to use correct quotes for value
  proc/bootconfig: Fix to use correct quotes for value
  tracing: Remove unused event variable in tracing_iter_reset
  tracing/probe: Fix memleak in fetch_op_data operations
  trace: Fix typo in allocate_ftrace_ops()'s comment
  tracing: Make ftrace packed events have align of 1
  sample-trace-array: Remove trace_array 'sample-instance'
  sample-trace-array: Fix sleeping function called from invalid context
  kretprobe: Prevent triggering kretprobe from within kprobe_flush_task
  kprobes: Remove redundant arch_disarm_kprobe() call
  kprobes: Fix to protect kick_kprobe_optimizer() by kprobe_mutex
  kprobes: Use non RCU traversal APIs on kprobe_tables if possible
  kprobes: Suppress the suspicious RCU warning on kprobes
  recordmcount: support >64k sections

1  2 
arch/x86/kernel/kprobes/core.c
include/linux/kprobes.h

index f09985c87d7331edf3008a73461c64a1aa314b14,8a5ec10e95dcc46cc97b4d7103cd684089ca42c4..ada39ddbc9220d8ab7c9f590d8b73640ccae5f2c
@@@ -243,7 -243,7 +243,7 @@@ __recover_probed_insn(kprobe_opcode_t *
         * Fortunately, we know that the original code is the ideal 5-byte
         * long NOP.
         */
 -      if (probe_kernel_read(buf, (void *)addr,
 +      if (copy_from_kernel_nofault(buf, (void *)addr,
                MAX_INSN_SIZE * sizeof(kprobe_opcode_t)))
                return 0UL;
  
@@@ -346,8 -346,7 +346,8 @@@ int __copy_instruction(u8 *dest, u8 *sr
                return 0;
  
        /* This can access kernel text if given address is not recovered */
 -      if (probe_kernel_read(dest, (void *)recovered_insn, MAX_INSN_SIZE))
 +      if (copy_from_kernel_nofault(dest, (void *)recovered_insn,
 +                      MAX_INSN_SIZE))
                return 0;
  
        kernel_insn_init(insn, dest, MAX_INSN_SIZE);
@@@ -754,16 -753,11 +754,11 @@@ asm
  NOKPROBE_SYMBOL(kretprobe_trampoline);
  STACK_FRAME_NON_STANDARD(kretprobe_trampoline);
  
- static struct kprobe kretprobe_kprobe = {
-       .addr = (void *)kretprobe_trampoline,
- };
  /*
   * Called from kretprobe_trampoline
   */
  __used __visible void *trampoline_handler(struct pt_regs *regs)
  {
-       struct kprobe_ctlblk *kcb;
        struct kretprobe_instance *ri = NULL;
        struct hlist_head *head, empty_rp;
        struct hlist_node *tmp;
        void *frame_pointer;
        bool skipped = false;
  
-       preempt_disable();
        /*
         * Set a dummy kprobe for avoiding kretprobe recursion.
         * Since kretprobe never run in kprobe handler, kprobe must not
         * be running at this point.
         */
-       kcb = get_kprobe_ctlblk();
-       __this_cpu_write(current_kprobe, &kretprobe_kprobe);
-       kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+       kprobe_busy_begin();
  
        INIT_HLIST_HEAD(&empty_rp);
        kretprobe_hash_lock(current, &head, &flags);
                        __this_cpu_write(current_kprobe, &ri->rp->kp);
                        ri->ret_addr = correct_ret_addr;
                        ri->rp->handler(ri, regs);
-                       __this_cpu_write(current_kprobe, &kretprobe_kprobe);
+                       __this_cpu_write(current_kprobe, &kprobe_busy);
                }
  
                recycle_rp_inst(ri, &empty_rp);
  
        kretprobe_hash_unlock(current, &flags);
  
-       __this_cpu_write(current_kprobe, NULL);
-       preempt_enable();
+       kprobe_busy_end();
  
        hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
                hlist_del(&ri->hlist);
diff --combined include/linux/kprobes.h
index e210af75ee387cffa841779f9ea590b9c67bed54,05ed663e6c7b8fe2cb4ab010cf3c9840f994c513..6adf90f248d701a63f537644feb8ccee15174878
@@@ -161,7 -161,7 +161,7 @@@ struct kretprobe_instance 
        kprobe_opcode_t *ret_addr;
        struct task_struct *task;
        void *fp;
 -      char data[0];
 +      char data[];
  };
  
  struct kretprobe_blackpoint {
@@@ -350,6 -350,10 +350,10 @@@ static inline struct kprobe_ctlblk *get
        return this_cpu_ptr(&kprobe_ctlblk);
  }
  
+ extern struct kprobe kprobe_busy;
+ void kprobe_busy_begin(void);
+ void kprobe_busy_end(void);
  kprobe_opcode_t *kprobe_lookup_name(const char *name, unsigned int offset);
  int register_kprobe(struct kprobe *p);
  void unregister_kprobe(struct kprobe *p);