]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
manual merge of perf/uprobes
authorIngo Molnar <mingo@kernel.org>
Thu, 22 May 2014 11:54:29 +0000 (13:54 +0200)
committerIngo Molnar <mingo@kernel.org>
Thu, 22 May 2014 11:54:29 +0000 (13:54 +0200)
Signed-off-by: Ingo Molnar <mingo@kernel.org>
1  2 
arch/x86/include/asm/traps.h
arch/x86/kernel/process_64.c
arch/x86/kernel/traps.c
kernel/trace/trace_uprobe.c

Simple merge
Simple merge
index fdbaa5a715f1f38c5106408a3f5e1d503a0e3558,3fdb20548c4b5e3a7c41fee3e77b9f646fd9d16d..c6eb418c562779f4383a9c17b737e748f5394c7e
@@@ -136,7 -137,38 +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