Merge branch 'perf/kprobes' into perf/core
authorIngo Molnar <mingo@kernel.org>
Thu, 5 Jun 2014 09:18:34 +0000 (11:18 +0200)
committerIngo Molnar <mingo@kernel.org>
Thu, 5 Jun 2014 10:26:50 +0000 (12:26 +0200)
Conflicts:
arch/x86/kernel/traps.c

The kprobes enhancements are fully cooked, ship them upstream.

Signed-off-by: Ingo Molnar <mingo@kernel.org>
1  2 
arch/x86/include/asm/traps.h
arch/x86/kernel/cpu/perf_event.c
arch/x86/kernel/traps.c
kernel/trace/trace_uprobe.c

Simple merge
Simple merge
@@@ -137,38 -136,7 +137,38 @@@ do_trap_no_signal(struct task_struct *t
        return -1;
  }
  
- static void __kprobes
 +static siginfo_t *fill_trap_info(struct pt_regs *regs, int signr, int trapnr,
 +                              siginfo_t *info)
 +{
 +      unsigned long siaddr;
 +      int sicode;
 +
 +      switch (trapnr) {
 +      default:
 +              return SEND_SIG_PRIV;
 +
 +      case X86_TRAP_DE:
 +              sicode = FPE_INTDIV;
 +              siaddr = uprobe_get_trap_addr(regs);
 +              break;
 +      case X86_TRAP_UD:
 +              sicode = ILL_ILLOPN;
 +              siaddr = uprobe_get_trap_addr(regs);
 +              break;
 +      case X86_TRAP_AC:
 +              sicode = BUS_ADRALN;
 +              siaddr = 0;
 +              break;
 +      }
 +
 +      info->si_signo = signr;
 +      info->si_errno = 0;
 +      info->si_code = sicode;
 +      info->si_addr = (void __user *)siaddr;
 +      return info;
 +}
 +
+ static void
  do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
        long error_code, siginfo_t *info)
  {
        }
  #endif
  
 -      if (info)
 -              force_sig_info(signr, info, tsk);
 -      else
 -              force_sig(signr, tsk);
 +      force_sig_info(signr, info ?: SEND_SIG_PRIV, tsk);
  }
+ NOKPROBE_SYMBOL(do_trap);
  
 -#define DO_ERROR(trapnr, signr, str, name)                            \
 -dotraplinkage void do_##name(struct pt_regs *regs, long error_code)   \
 -{                                                                     \
 -      enum ctx_state prev_state;                                      \
 -                                                                      \
 -      prev_state = exception_enter();                                 \
 -      if (notify_die(DIE_TRAP, str, regs, error_code,                 \
 -                      trapnr, signr) == NOTIFY_STOP) {                \
 -              exception_exit(prev_state);                             \
 -              return;                                                 \
 -      }                                                               \
 -      conditional_sti(regs);                                          \
 -      do_trap(trapnr, signr, str, regs, error_code, NULL);            \
 -      exception_exit(prev_state);                                     \
 +static void do_error_trap(struct pt_regs *regs, long error_code, char *str,
 +                        unsigned long trapnr, int signr)
 +{
 +      enum ctx_state prev_state = exception_enter();
 +      siginfo_t info;
 +
 +      if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) !=
 +                      NOTIFY_STOP) {
 +              conditional_sti(regs);
 +              do_trap(trapnr, signr, str, regs, error_code,
 +                      fill_trap_info(regs, signr, trapnr, &info));
 +      }
 +
 +      exception_exit(prev_state);
  }
  
 -#define DO_ERROR_INFO(trapnr, signr, str, name, sicode, siaddr)               \
 +#define DO_ERROR(trapnr, signr, str, name)                            \
  dotraplinkage void do_##name(struct pt_regs *regs, long error_code)   \
  {                                                                     \
 -      siginfo_t info;                                                 \
 -      enum ctx_state prev_state;                                      \
 -                                                                      \
 -      info.si_signo = signr;                                          \
 -      info.si_errno = 0;                                              \
 -      info.si_code = sicode;                                          \
 -      info.si_addr = (void __user *)siaddr;                           \
 -      prev_state = exception_enter();                                 \
 -      if (notify_die(DIE_TRAP, str, regs, error_code,                 \
 -                      trapnr, signr) == NOTIFY_STOP) {                \
 -              exception_exit(prev_state);                             \
 -              return;                                                 \
 -      }                                                               \
 -      conditional_sti(regs);                                          \
 -      do_trap(trapnr, signr, str, regs, error_code, &info);           \
 -      exception_exit(prev_state);                                     \
 +      do_error_trap(regs, error_code, str, trapnr, signr);            \
  }
  
 -DO_ERROR_INFO(X86_TRAP_DE,     SIGFPE,  "divide error",                       divide_error,                FPE_INTDIV, regs->ip )
 -DO_ERROR     (X86_TRAP_OF,     SIGSEGV, "overflow",                   overflow                                          )
 -DO_ERROR     (X86_TRAP_BR,     SIGSEGV, "bounds",                     bounds                                            )
 -DO_ERROR_INFO(X86_TRAP_UD,     SIGILL,  "invalid opcode",             invalid_op,                  ILL_ILLOPN, regs->ip )
 -DO_ERROR     (X86_TRAP_OLD_MF, SIGFPE,  "coprocessor segment overrun",        coprocessor_segment_overrun                       )
 -DO_ERROR     (X86_TRAP_TS,     SIGSEGV, "invalid TSS",                        invalid_TSS                                       )
 -DO_ERROR     (X86_TRAP_NP,     SIGBUS,  "segment not present",                segment_not_present                               )
 +DO_ERROR(X86_TRAP_DE,     SIGFPE,  "divide error",            divide_error)
 +DO_ERROR(X86_TRAP_OF,     SIGSEGV, "overflow",                        overflow)
 +DO_ERROR(X86_TRAP_BR,     SIGSEGV, "bounds",                  bounds)
 +DO_ERROR(X86_TRAP_UD,     SIGILL,  "invalid opcode",          invalid_op)
 +DO_ERROR(X86_TRAP_OLD_MF, SIGFPE,  "coprocessor segment overrun",coprocessor_segment_overrun)
 +DO_ERROR(X86_TRAP_TS,     SIGSEGV, "invalid TSS",             invalid_TSS)
 +DO_ERROR(X86_TRAP_NP,     SIGBUS,  "segment not present",     segment_not_present)
  #ifdef CONFIG_X86_32
 -DO_ERROR     (X86_TRAP_SS,     SIGBUS,  "stack segment",              stack_segment                                     )
 +DO_ERROR(X86_TRAP_SS,     SIGBUS,  "stack segment",           stack_segment)
  #endif
 -DO_ERROR_INFO(X86_TRAP_AC,     SIGBUS,  "alignment check",            alignment_check,             BUS_ADRALN, 0        )
 +DO_ERROR(X86_TRAP_AC,     SIGBUS,  "alignment check",         alignment_check)
  
  #ifdef CONFIG_X86_64
  /* Runs on IST stack */
Simple merge