]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge commit 'v2.6.32-rc5' into perf/probes
authorIngo Molnar <mingo@elte.hu>
Sat, 17 Oct 2009 07:58:25 +0000 (09:58 +0200)
committerIngo Molnar <mingo@elte.hu>
Sat, 17 Oct 2009 07:58:25 +0000 (09:58 +0200)
Conflicts:
kernel/trace/trace_event_profile.c

Merge reason: update to -rc5 and resolve conflict.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
1  2 
arch/x86/Makefile
arch/x86/lib/Makefile
arch/x86/mm/fault.c
kernel/kprobes.c
kernel/trace/trace_event_profile.c
kernel/trace/trace_events.c
kernel/trace/trace_syscalls.c
tools/perf/Makefile

diff --combined arch/x86/Makefile
index 4aefc034e9a0a869593a88b7aaf2423f6aaf618b,a012ee8ef803302642a5eac1daa791fe8f7c617a..ba7a6df4db92d389580da32f0bd4b4582abe5f31
@@@ -156,9 -156,6 +156,9 @@@ all: bzImag
  KBUILD_IMAGE := $(boot)/bzImage
  
  bzImage: vmlinux
 +ifeq ($(CONFIG_X86_DECODER_SELFTEST),y)
 +      $(Q)$(MAKE) $(build)=arch/x86/tools posttest
 +endif
        $(Q)$(MAKE) $(build)=$(boot) $(KBUILD_IMAGE)
        $(Q)mkdir -p $(objtree)/arch/$(UTS_MACHINE)/boot
        $(Q)ln -fsn ../../x86/boot/bzImage $(objtree)/arch/$(UTS_MACHINE)/boot/$@
@@@ -182,8 -179,8 +182,8 @@@ archclean
  define archhelp
    echo  '* bzImage      - Compressed kernel image (arch/x86/boot/bzImage)'
    echo  '  install      - Install kernel using'
-   echo  '                  (your) ~/bin/installkernel or'
-   echo  '                  (distribution) /sbin/installkernel or'
+   echo  '                  (your) ~/bin/$(INSTALLKERNEL) or'
+   echo  '                  (distribution) /sbin/$(INSTALLKERNEL) or'
    echo  '                  install to $$(INSTALL_PATH) and run lilo'
    echo  '  fdimage      - Create 1.4MB boot floppy image (arch/x86/boot/fdimage)'
    echo  '  fdimage144   - Create 1.4MB boot floppy image (arch/x86/boot/fdimage)'
diff --combined arch/x86/lib/Makefile
index 965026472c717914e86e4c164c557bf825df4861,85f5db95c60f03718f292080587f7faa337ef570..a2d6472895fb309884d442b100502447fcb4c5e9
@@@ -2,25 -2,12 +2,25 @@@
  # Makefile for x86 specific library files.
  #
  
 +inat_tables_script = $(srctree)/arch/x86/tools/gen-insn-attr-x86.awk
 +inat_tables_maps = $(srctree)/arch/x86/lib/x86-opcode-map.txt
 +quiet_cmd_inat_tables = GEN     $@
 +      cmd_inat_tables = $(AWK) -f $(inat_tables_script) $(inat_tables_maps) > $@
 +
 +$(obj)/inat-tables.c: $(inat_tables_script) $(inat_tables_maps)
 +      $(call cmd,inat_tables)
 +
 +$(obj)/inat.o: $(obj)/inat-tables.c
 +
 +clean-files := inat-tables.c
 +
  obj-$(CONFIG_SMP) := msr.o
  
  lib-y := delay.o
  lib-y += thunk_$(BITS).o
  lib-y += usercopy_$(BITS).o getuser.o putuser.o
  lib-y += memcpy_$(BITS).o
 +lib-y += insn.o inat.o
  
  obj-y += msr-reg.o msr-reg-export.o
  
@@@ -29,7 -16,9 +29,9 @@@ ifeq ($(CONFIG_X86_32),y
          lib-y += checksum_32.o
          lib-y += strstr_32.o
          lib-y += semaphore_32.o string_32.o
+ ifneq ($(CONFIG_X86_CMPXCHG64),y)
+         lib-y += cmpxchg8b_emu.o
+ endif
          lib-$(CONFIG_X86_USE_3DNOW) += mmx_32.o
  else
          obj-y += io_64.o iomap_copy_64.o
diff --combined arch/x86/mm/fault.c
index 923ea3fb7037111b004a7d715d5108c1d97c2668,f4cee9028cf0b01e11951662b625f63371f627e6..8f4e2ac93928edd82f4b34ac3bdead37eea289d4
@@@ -38,8 -38,7 +38,8 @@@ enum x86_pf_error_code 
   * Returns 0 if mmiotrace is disabled, or if the fault is not
   * handled by mmiotrace:
   */
 -static inline int kmmio_fault(struct pt_regs *regs, unsigned long addr)
 +static inline int __kprobes
 +kmmio_fault(struct pt_regs *regs, unsigned long addr)
  {
        if (unlikely(is_kmmio_active()))
                if (kmmio_handler(regs, addr) == 1)
@@@ -47,7 -46,7 +47,7 @@@
        return 0;
  }
  
 -static inline int notify_page_fault(struct pt_regs *regs)
 +static inline int __kprobes notify_page_fault(struct pt_regs *regs)
  {
        int ret = 0;
  
@@@ -168,6 -167,7 +168,7 @@@ force_sig_info_fault(int si_signo, int 
        info.si_errno   = 0;
        info.si_code    = si_code;
        info.si_addr    = (void __user *)address;
+       info.si_addr_lsb = si_code == BUS_MCEERR_AR ? PAGE_SHIFT : 0;
  
        force_sig_info(si_signo, &info, tsk);
  }
@@@ -240,7 -240,7 +241,7 @@@ void vmalloc_sync_all(void
   *
   *   Handle a fault on the vmalloc or module mapping area
   */
 -static noinline int vmalloc_fault(unsigned long address)
 +static noinline __kprobes int vmalloc_fault(unsigned long address)
  {
        unsigned long pgd_paddr;
        pmd_t *pmd_k;
@@@ -357,7 -357,7 +358,7 @@@ void vmalloc_sync_all(void
   *
   * This assumes no large pages in there.
   */
 -static noinline int vmalloc_fault(unsigned long address)
 +static noinline __kprobes int vmalloc_fault(unsigned long address)
  {
        pgd_t *pgd, *pgd_ref;
        pud_t *pud, *pud_ref;
@@@ -791,10 -791,12 +792,12 @@@ out_of_memory(struct pt_regs *regs, uns
  }
  
  static void
- do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address)
+ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address,
+         unsigned int fault)
  {
        struct task_struct *tsk = current;
        struct mm_struct *mm = tsk->mm;
+       int code = BUS_ADRERR;
  
        up_read(&mm->mmap_sem);
  
        tsk->thread.error_code  = error_code;
        tsk->thread.trap_no     = 14;
  
-       force_sig_info_fault(SIGBUS, BUS_ADRERR, address, tsk);
+ #ifdef CONFIG_MEMORY_FAILURE
+       if (fault & VM_FAULT_HWPOISON) {
+               printk(KERN_ERR
+       "MCE: Killing %s:%d due to hardware memory corruption fault at %lx\n",
+                       tsk->comm, tsk->pid, address);
+               code = BUS_MCEERR_AR;
+       }
+ #endif
+       force_sig_info_fault(SIGBUS, code, address, tsk);
  }
  
  static noinline void
@@@ -820,8 -830,8 +831,8 @@@ mm_fault_error(struct pt_regs *regs, un
        if (fault & VM_FAULT_OOM) {
                out_of_memory(regs, error_code, address);
        } else {
-               if (fault & VM_FAULT_SIGBUS)
-                       do_sigbus(regs, error_code, address);
+               if (fault & (VM_FAULT_SIGBUS|VM_FAULT_HWPOISON))
+                       do_sigbus(regs, error_code, address, fault);
                else
                        BUG();
        }
@@@ -850,7 -860,7 +861,7 @@@ static int spurious_fault_check(unsigne
   * There are no security implications to leaving a stale TLB when
   * increasing the permissions on a page.
   */
 -static noinline int
 +static noinline __kprobes int
  spurious_fault(unsigned long error_code, unsigned long address)
  {
        pgd_t *pgd;
diff --combined kernel/kprobes.c
index b466afa4e1481e394ef493752cc3e9badf3bf25d,5240d75f4c60e95f95eb55e0cc46b448e2d6eb7c..84495958e703366eef86906d1e0ff4aa1cb2d2cd
@@@ -90,9 -90,6 +90,9 @@@ static spinlock_t *kretprobe_table_lock
   */
  static struct kprobe_blackpoint kprobe_blacklist[] = {
        {"preempt_schedule",},
 +      {"native_get_debugreg",},
 +      {"irq_entries_start",},
 +      {"common_interrupt",},
        {NULL}    /* Terminator */
  };
  
@@@ -676,40 -673,6 +676,40 @@@ static kprobe_opcode_t __kprobes *kprob
        return (kprobe_opcode_t *)(((char *)addr) + p->offset);
  }
  
 +/* Check passed kprobe is valid and return kprobe in kprobe_table. */
 +static struct kprobe * __kprobes __get_valid_kprobe(struct kprobe *p)
 +{
 +      struct kprobe *old_p, *list_p;
 +
 +      old_p = get_kprobe(p->addr);
 +      if (unlikely(!old_p))
 +              return NULL;
 +
 +      if (p != old_p) {
 +              list_for_each_entry_rcu(list_p, &old_p->list, list)
 +                      if (list_p == p)
 +                      /* kprobe p is a valid probe */
 +                              goto valid;
 +              return NULL;
 +      }
 +valid:
 +      return old_p;
 +}
 +
 +/* Return error if the kprobe is being re-registered */
 +static inline int check_kprobe_rereg(struct kprobe *p)
 +{
 +      int ret = 0;
 +      struct kprobe *old_p;
 +
 +      mutex_lock(&kprobe_mutex);
 +      old_p = __get_valid_kprobe(p);
 +      if (old_p)
 +              ret = -EINVAL;
 +      mutex_unlock(&kprobe_mutex);
 +      return ret;
 +}
 +
  int __kprobes register_kprobe(struct kprobe *p)
  {
        int ret = 0;
                return -EINVAL;
        p->addr = addr;
  
 +      ret = check_kprobe_rereg(p);
 +      if (ret)
 +              return ret;
 +
        preempt_disable();
        if (!kernel_text_address((unsigned long) p->addr) ||
            in_kprobes_functions((unsigned long) p->addr)) {
@@@ -795,6 -754,26 +795,6 @@@ out
  }
  EXPORT_SYMBOL_GPL(register_kprobe);
  
 -/* Check passed kprobe is valid and return kprobe in kprobe_table. */
 -static struct kprobe * __kprobes __get_valid_kprobe(struct kprobe *p)
 -{
 -      struct kprobe *old_p, *list_p;
 -
 -      old_p = get_kprobe(p->addr);
 -      if (unlikely(!old_p))
 -              return NULL;
 -
 -      if (p != old_p) {
 -              list_for_each_entry_rcu(list_p, &old_p->list, list)
 -                      if (list_p == p)
 -                      /* kprobe p is a valid probe */
 -                              goto valid;
 -              return NULL;
 -      }
 -valid:
 -      return old_p;
 -}
 -
  /*
   * Unregister a kprobe without a scheduler synchronization.
   */
@@@ -1162,13 -1141,6 +1162,13 @@@ static void __kprobes kill_kprobe(struc
        arch_remove_kprobe(p);
  }
  
 +void __kprobes dump_kprobe(struct kprobe *kp)
 +{
 +      printk(KERN_WARNING "Dumping kprobe:\n");
 +      printk(KERN_WARNING "Name: %s\nAddress: %p\nOffset: %x\n",
 +             kp->symbol_name, kp->addr, kp->offset);
 +}
 +
  /* Module notifier call back, checking kprobes on the module */
  static int __kprobes kprobes_module_callback(struct notifier_block *nb,
                                             unsigned long val, void *data)
@@@ -1361,7 -1333,7 +1361,7 @@@ static int __kprobes kprobes_open(struc
        return seq_open(filp, &kprobes_seq_ops);
  }
  
- static struct file_operations debugfs_kprobes_operations = {
+ static const struct file_operations debugfs_kprobes_operations = {
        .open           = kprobes_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
@@@ -1543,7 -1515,7 +1543,7 @@@ static ssize_t write_enabled_file_bool(
        return count;
  }
  
- static struct file_operations fops_kp = {
+ static const struct file_operations fops_kp = {
        .read =         read_enabled_file_bool,
        .write =        write_enabled_file_bool,
  };
index e812f1c1264cffb4ca36803dd0b11fc87f90d450,8d5c171cc9987d924f9fcfd3328fcb966288b9a0..c9f687ab0d4fcd208327aad09f33971cd2726e64
@@@ -31,7 -31,7 +31,7 @@@ static int ftrace_profile_enable_event(
        if (atomic_inc_return(&event->profile_count))
                return 0;
  
-       if (!total_profile_count++) {
+       if (!total_profile_count) {
                buf = (char *)alloc_percpu(profile_buf_t);
                if (!buf)
                        goto fail_buf;
                rcu_assign_pointer(trace_profile_buf_nmi, buf);
        }
  
 -      ret = event->profile_enable();
 +      ret = event->profile_enable(event);
-       if (!ret)
+       if (!ret) {
+               total_profile_count++;
                return 0;
+       }
  
-       kfree(trace_profile_buf_nmi);
  fail_buf_nmi:
-       kfree(trace_profile_buf);
+       if (!total_profile_count) {
+               free_percpu(trace_profile_buf_nmi);
+               free_percpu(trace_profile_buf);
+               trace_profile_buf_nmi = NULL;
+               trace_profile_buf = NULL;
+       }
  fail_buf:
-       total_profile_count--;
        atomic_dec(&event->profile_count);
  
        return ret;
@@@ -84,7 -89,7 +89,7 @@@ static void ftrace_profile_disable_even
        if (!atomic_add_negative(-1, &event->profile_count))
                return;
  
 -      event->profile_disable();
 +      event->profile_disable(event);
  
        if (!--total_profile_count) {
                buf = trace_profile_buf;
index 155b5d5a4e45d61ce3f449a7a933da7995a34c12,d128f65778e69654207c6d8d7b987bc7837f7541..f2f5064701e53e02e56e22bdcc1c5f07a1f04706
@@@ -93,7 -93,9 +93,7 @@@ int trace_define_common_fields(struct f
  }
  EXPORT_SYMBOL_GPL(trace_define_common_fields);
  
 -#ifdef CONFIG_MODULES
 -
 -static void trace_destroy_fields(struct ftrace_event_call *call)
 +void trace_destroy_fields(struct ftrace_event_call *call)
  {
        struct ftrace_event_field *field, *next;
  
        }
  }
  
 -#endif /* CONFIG_MODULES */
 -
  static void ftrace_event_enable_disable(struct ftrace_event_call *call,
                                        int enable)
  {
                if (call->enabled) {
                        call->enabled = 0;
                        tracing_stop_cmdline_record();
 -                      call->unregfunc(call->data);
 +                      call->unregfunc(call);
                }
                break;
        case 1:
                if (!call->enabled) {
                        call->enabled = 1;
                        tracing_start_cmdline_record();
 -                      call->regfunc(call->data);
 +                      call->regfunc(call);
                }
                break;
        }
@@@ -228,10 -232,9 +228,9 @@@ ftrace_event_write(struct file *file, c
                   size_t cnt, loff_t *ppos)
  {
        struct trace_parser parser;
-       size_t read = 0;
-       ssize_t ret;
+       ssize_t read, ret;
  
-       if (!cnt || cnt < 0)
+       if (!cnt)
                return 0;
  
        ret = tracing_update_buffers();
  
        read = trace_get_user(&parser, ubuf, cnt, ppos);
  
-       if (trace_parser_loaded((&parser))) {
+       if (read >= 0 && trace_parser_loaded((&parser))) {
                int set = 1;
  
                if (*parser.buffer == '!')
@@@ -935,46 -938,27 +934,46 @@@ event_create_dir(struct ftrace_event_ca
        return 0;
  }
  
 -#define for_each_event(event, start, end)                     \
 -      for (event = start;                                     \
 -           (unsigned long)event < (unsigned long)end;         \
 -           event++)
 +static int __trace_add_event_call(struct ftrace_event_call *call)
 +{
 +      struct dentry *d_events;
 +      int ret;
  
 -#ifdef CONFIG_MODULES
 +      if (!call->name)
 +              return -EINVAL;
  
 -static LIST_HEAD(ftrace_module_file_list);
 +      if (call->raw_init) {
 +              ret = call->raw_init(call);
 +              if (ret < 0) {
 +                      if (ret != -ENOSYS)
 +                              pr_warning("Could not initialize trace "
 +                              "events/%s\n", call->name);
 +                      return ret;
 +              }
 +      }
  
 -/*
 - * Modules must own their file_operations to keep up with
 - * reference counting.
 - */
 -struct ftrace_module_file_ops {
 -      struct list_head                list;
 -      struct module                   *mod;
 -      struct file_operations          id;
 -      struct file_operations          enable;
 -      struct file_operations          format;
 -      struct file_operations          filter;
 -};
 +      d_events = event_trace_events_dir();
 +      if (!d_events)
 +              return -ENOENT;
 +
 +      ret = event_create_dir(call, d_events, &ftrace_event_id_fops,
 +                              &ftrace_enable_fops, &ftrace_event_filter_fops,
 +                              &ftrace_event_format_fops);
 +      if (!ret)
 +              list_add(&call->list, &ftrace_events);
 +
 +      return ret;
 +}
 +
 +/* Add an additional event_call dynamically */
 +int trace_add_event_call(struct ftrace_event_call *call)
 +{
 +      int ret;
 +      mutex_lock(&event_mutex);
 +      ret = __trace_add_event_call(call);
 +      mutex_unlock(&event_mutex);
 +      return ret;
 +}
  
  static void remove_subsystem_dir(const char *name)
  {
        }
  }
  
 +/*
 + * Must be called under locking both of event_mutex and trace_event_mutex.
 + */
 +static void __trace_remove_event_call(struct ftrace_event_call *call)
 +{
 +      ftrace_event_enable_disable(call, 0);
 +      if (call->event)
 +              __unregister_ftrace_event(call->event);
 +      debugfs_remove_recursive(call->dir);
 +      list_del(&call->list);
 +      trace_destroy_fields(call);
 +      destroy_preds(call);
 +      remove_subsystem_dir(call->system);
 +}
 +
 +/* Remove an event_call */
 +void trace_remove_event_call(struct ftrace_event_call *call)
 +{
 +      mutex_lock(&event_mutex);
 +      down_write(&trace_event_mutex);
 +      __trace_remove_event_call(call);
 +      up_write(&trace_event_mutex);
 +      mutex_unlock(&event_mutex);
 +}
 +
 +#define for_each_event(event, start, end)                     \
 +      for (event = start;                                     \
 +           (unsigned long)event < (unsigned long)end;         \
 +           event++)
 +
 +#ifdef CONFIG_MODULES
 +
 +static LIST_HEAD(ftrace_module_file_list);
 +
 +/*
 + * Modules must own their file_operations to keep up with
 + * reference counting.
 + */
 +struct ftrace_module_file_ops {
 +      struct list_head                list;
 +      struct module                   *mod;
 +      struct file_operations          id;
 +      struct file_operations          enable;
 +      struct file_operations          format;
 +      struct file_operations          filter;
 +};
 +
  static struct ftrace_module_file_ops *
  trace_create_file_ops(struct module *mod)
  {
@@@ -1106,7 -1043,7 +1105,7 @@@ static void trace_module_add_events(str
                if (!call->name)
                        continue;
                if (call->raw_init) {
 -                      ret = call->raw_init();
 +                      ret = call->raw_init(call);
                        if (ret < 0) {
                                if (ret != -ENOSYS)
                                        pr_warning("Could not initialize trace "
                                return;
                }
                call->mod = mod;
 -              list_add(&call->list, &ftrace_events);
 -              event_create_dir(call, d_events,
 -                               &file_ops->id, &file_ops->enable,
 -                               &file_ops->filter, &file_ops->format);
 +              ret = event_create_dir(call, d_events,
 +                                     &file_ops->id, &file_ops->enable,
 +                                     &file_ops->filter, &file_ops->format);
 +              if (!ret)
 +                      list_add(&call->list, &ftrace_events);
        }
  }
  
@@@ -1142,7 -1078,14 +1141,7 @@@ static void trace_module_remove_events(
        list_for_each_entry_safe(call, p, &ftrace_events, list) {
                if (call->mod == mod) {
                        found = true;
 -                      ftrace_event_enable_disable(call, 0);
 -                      if (call->event)
 -                              __unregister_ftrace_event(call->event);
 -                      debugfs_remove_recursive(call->dir);
 -                      list_del(&call->list);
 -                      trace_destroy_fields(call);
 -                      destroy_preds(call);
 -                      remove_subsystem_dir(call->system);
 +                      __trace_remove_event_call(call);
                }
        }
  
@@@ -1260,7 -1203,7 +1259,7 @@@ static __init int event_trace_init(void
                if (!call->name)
                        continue;
                if (call->raw_init) {
 -                      ret = call->raw_init();
 +                      ret = call->raw_init(call);
                        if (ret < 0) {
                                if (ret != -ENOSYS)
                                        pr_warning("Could not initialize trace "
                                continue;
                        }
                }
 -              list_add(&call->list, &ftrace_events);
 -              event_create_dir(call, d_events, &ftrace_event_id_fops,
 -                               &ftrace_enable_fops, &ftrace_event_filter_fops,
 -                               &ftrace_event_format_fops);
 +              ret = event_create_dir(call, d_events, &ftrace_event_id_fops,
 +                                     &ftrace_enable_fops,
 +                                     &ftrace_event_filter_fops,
 +                                     &ftrace_event_format_fops);
 +              if (!ret)
 +                      list_add(&call->list, &ftrace_events);
        }
  
        while (true) {
index 1b050ab471200169bd8385b854bbd4a4aa853a1e,527e17eae57516a1f36932d13e1799d1244ef03f..9ade66389d5a4532174ba917335abb14bf21aef1
@@@ -166,7 -166,7 +166,7 @@@ int syscall_exit_format(struct ftrace_e
                               "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
                               "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n",
                               SYSCALL_FIELD(int, nr),
-                              SYSCALL_FIELD(unsigned long, ret));
+                              SYSCALL_FIELD(long, ret));
        if (!ret)
                return 0;
  
@@@ -212,7 -212,7 +212,7 @@@ int syscall_exit_define_fields(struct f
        if (ret)
                return ret;
  
-       ret = trace_define_field(call, SYSCALL_FIELD(unsigned long, ret), 0,
+       ret = trace_define_field(call, SYSCALL_FIELD(long, ret), 0,
                                 FILTER_OTHER);
  
        return ret;
@@@ -285,13 -285,13 +285,13 @@@ void ftrace_syscall_exit(struct pt_reg
                trace_current_buffer_unlock_commit(buffer, event, 0, 0);
  }
  
 -int reg_event_syscall_enter(void *ptr)
 +int reg_event_syscall_enter(struct ftrace_event_call *call)
  {
        int ret = 0;
        int num;
        char *name;
  
 -      name = (char *)ptr;
 +      name = (char *)call->data;
        num = syscall_name_to_nr(name);
        if (num < 0 || num >= NR_syscalls)
                return -ENOSYS;
        return ret;
  }
  
 -void unreg_event_syscall_enter(void *ptr)
 +void unreg_event_syscall_enter(struct ftrace_event_call *call)
  {
        int num;
        char *name;
  
 -      name = (char *)ptr;
 +      name = (char *)call->data;
        num = syscall_name_to_nr(name);
        if (num < 0 || num >= NR_syscalls)
                return;
        mutex_unlock(&syscall_trace_lock);
  }
  
 -int reg_event_syscall_exit(void *ptr)
 +int reg_event_syscall_exit(struct ftrace_event_call *call)
  {
        int ret = 0;
        int num;
        char *name;
  
 -      name = (char *)ptr;
 +      name = call->data;
        num = syscall_name_to_nr(name);
        if (num < 0 || num >= NR_syscalls)
                return -ENOSYS;
        return ret;
  }
  
 -void unreg_event_syscall_exit(void *ptr)
 +void unreg_event_syscall_exit(struct ftrace_event_call *call)
  {
        int num;
        char *name;
  
 -      name = (char *)ptr;
 +      name = call->data;
        num = syscall_name_to_nr(name);
        if (num < 0 || num >= NR_syscalls)
                return;
diff --combined tools/perf/Makefile
index 1abbf9a5ee57f07d983196338437cd50d035fe11,742a32eee8fc6180f8c2ad070b53731aaca8bdfd..1811a7015f9caab3f8f3dac0e6ae05ce11537c1f
@@@ -157,11 -157,18 +157,18 @@@ uname_R := $(shell sh -c 'uname -r 2>/d
  uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not')
  uname_V := $(shell sh -c 'uname -v 2>/dev/null || echo not')
  
- # If we're on a 64-bit kernel, use -m64
- ifndef NO_64BIT
-       ifneq ($(patsubst %64,%,$(uname_M)),$(uname_M))
-         M64 := -m64
-       endif
+ #
+ # Add -m32 for cross-builds:
+ #
+ ifdef NO_64BIT
+   MBITS := -m32
+ else
+   #
+   # If we're on a 64-bit kernel, use -m64:
+   #
+   ifneq ($(patsubst %64,%,$(uname_M)),$(uname_M))
+     MBITS := -m64
+   endif
  endif
  
  # CFLAGS and LDFLAGS are for the users to override from the command line.
@@@ -194,7 -201,7 +201,7 @@@ EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wo
  EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wstrict-prototypes
  EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wdeclaration-after-statement
  
- CFLAGS = $(M64) -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -fstack-protector-all -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS)
+ CFLAGS = $(MBITS) -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -fstack-protector-all -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS)
  LDFLAGS = -lpthread -lrt -lelf -lm
  ALL_CFLAGS = $(CFLAGS)
  ALL_LDFLAGS = $(LDFLAGS)
@@@ -321,7 -328,6 +328,7 @@@ LIB_FILE=libperf.
  LIB_H += ../../include/linux/perf_event.h
  LIB_H += ../../include/linux/rbtree.h
  LIB_H += ../../include/linux/list.h
 +LIB_H += ../../include/linux/stringify.h
  LIB_H += util/include/linux/list.h
  LIB_H += perf.h
  LIB_H += util/types.h
@@@ -386,7 -392,6 +393,7 @@@ BUILTIN_OBJS += builtin-stat.
  BUILTIN_OBJS += builtin-timechart.o
  BUILTIN_OBJS += builtin-top.o
  BUILTIN_OBJS += builtin-trace.o
 +BUILTIN_OBJS += builtin-probe.o
  
  PERFLIBS = $(LIB_FILE)
  
@@@ -418,18 -423,9 +425,18 @@@ ifeq ($(uname_S),Darwin
  endif
  
  ifneq ($(shell sh -c "(echo '\#include <libelf.h>'; echo 'int main(void) { Elf * elf = elf_begin(0, ELF_C_READ_MMAP, 0); return (long)elf; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
-       msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel);
+       msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel and glibc-dev[el]);
  endif
  
 +ifneq ($(shell sh -c "(echo '\#include <libdwarf/dwarf.h>'; echo '\#include <libdwarf/libdwarf.h>'; echo 'int main(void) { Dwarf_Debug dbg; Dwarf_Error err; Dwarf_Ranges *rng; dwarf_init(0, DW_DLC_READ, 0, 0, &dbg, &err); dwarf_get_ranges(dbg, 0, &rng, 0, 0, &err); return (long)dbg; }') | $(CC) -x c - $(ALL_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -ldwarf -lelf -o /dev/null $(ALL_LDFLAGS) > /dev/null 2>&1 && echo y"), y)
 +      msg := $(warning No libdwarf.h found or old libdwarf.h found, disables dwarf support. Please install libdwarf-dev/libdwarf-devel >= 20081231);
 +      BASIC_CFLAGS += -DNO_LIBDWARF
 +else
 +      EXTLIBS += -lelf -ldwarf
 +      LIB_H += util/probe-finder.h
 +      LIB_OBJS += util/probe-finder.o
 +endif
 +
  ifdef NO_DEMANGLE
        BASIC_CFLAGS += -DNO_DEMANGLE
  else
@@@ -739,7 -735,7 +746,7 @@@ $(BUILT_INS): perf$
  common-cmds.h: util/generate-cmdlist.sh command-list.txt
  
  common-cmds.h: $(wildcard Documentation/perf-*.txt)
-       $(QUIET_GEN)util/generate-cmdlist.sh > $@+ && mv $@+ $@
+       $(QUIET_GEN)util/generate-cmdlist.sh > $@+ && mv $@+ $@
  
  $(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
        $(QUIET_GEN)$(RM) $@ $@+ && \