]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 5 Jul 2010 03:20:53 +0000 (20:20 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 5 Jul 2010 03:20:53 +0000 (20:20 -0700)
* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  perf, x86: Fix incorrect branches event on AMD CPUs
  perf tools: Fix find tids routine by excluding "." and ".."
  x86: Send a SIGTRAP for user icebp traps

arch/x86/kernel/cpu/perf_event_amd.c
arch/x86/kernel/traps.c
tools/perf/util/thread.c

index 611df11ba15e7f9145e49f2fa2c7e61b1371d77c..c2897b7b4a3b1c7a6cfe4fe7e70b3d7378432d4c 100644 (file)
@@ -102,8 +102,8 @@ static const u64 amd_perfmon_event_map[] =
   [PERF_COUNT_HW_INSTRUCTIONS]         = 0x00c0,
   [PERF_COUNT_HW_CACHE_REFERENCES]     = 0x0080,
   [PERF_COUNT_HW_CACHE_MISSES]         = 0x0081,
-  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]  = 0x00c4,
-  [PERF_COUNT_HW_BRANCH_MISSES]                = 0x00c5,
+  [PERF_COUNT_HW_BRANCH_INSTRUCTIONS]  = 0x00c2,
+  [PERF_COUNT_HW_BRANCH_MISSES]                = 0x00c3,
 };
 
 static u64 amd_pmu_event_map(int hw_event)
index 142d70c74b027c31512c02dafea1e510d686a2fb..725ef4d17cd5922289b24e515c8b030e86cf6c18 100644 (file)
@@ -526,6 +526,7 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
 dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
 {
        struct task_struct *tsk = current;
+       int user_icebp = 0;
        unsigned long dr6;
        int si_code;
 
@@ -534,6 +535,14 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
        /* Filter out all the reserved bits which are preset to 1 */
        dr6 &= ~DR6_RESERVED;
 
+       /*
+        * If dr6 has no reason to give us about the origin of this trap,
+        * then it's very likely the result of an icebp/int01 trap.
+        * User wants a sigtrap for that.
+        */
+       if (!dr6 && user_mode(regs))
+               user_icebp = 1;
+
        /* Catch kmemcheck conditions first of all! */
        if ((dr6 & DR_STEP) && kmemcheck_trap(regs))
                return;
@@ -575,7 +584,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
                regs->flags &= ~X86_EFLAGS_TF;
        }
        si_code = get_si_code(tsk->thread.debugreg6);
-       if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS))
+       if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS) || user_icebp)
                send_sigtrap(tsk, regs, error_code, si_code);
        preempt_conditional_cli(regs);
 
index 1f7ecd47f49942809d19b0be3f65d9fb1f904ebc..9a448b47400c8ec2305c4d0153d885fe4962a612 100644 (file)
@@ -7,6 +7,15 @@
 #include "util.h"
 #include "debug.h"
 
+/* Skip "." and ".." directories */
+static int filter(const struct dirent *dir)
+{
+       if (dir->d_name[0] == '.')
+               return 0;
+       else
+               return 1;
+}
+
 int find_all_tid(int pid, pid_t ** all_tid)
 {
        char name[256];
@@ -16,7 +25,7 @@ int find_all_tid(int pid, pid_t ** all_tid)
        int i;
 
        sprintf(name, "/proc/%d/task", pid);
-       items = scandir(name, &namelist, NULL, NULL);
+       items = scandir(name, &namelist, filter, NULL);
        if (items <= 0)
                 return -ENOENT;
        *all_tid = malloc(sizeof(pid_t) * items);