]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'tip/auto-latest'
authorStephen Rothwell <sfr@canb.auug.org.au>
Thu, 9 Apr 2015 05:13:12 +0000 (15:13 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Thu, 9 Apr 2015 05:13:16 +0000 (15:13 +1000)
Conflicts:
include/linux/bpf.h
include/uapi/linux/bpf.h
samples/bpf/Makefile

28 files changed:
1  2 
Documentation/kernel-parameters.txt
MAINTAINERS
arch/arm/kernel/vdso.c
arch/arm/mach-omap2/cpuidle44xx.c
arch/arm/mach-tegra/cpuidle-tegra20.c
arch/arm/mach-tegra/cpuidle-tegra30.c
arch/mips/lasat/sysctl.c
arch/powerpc/perf/core-book3s.c
arch/x86/Kconfig
arch/x86/include/uapi/asm/msr-index.h
arch/x86/lguest/boot.c
drivers/acpi/processor_idle.c
drivers/clocksource/arm_arch_timer.c
drivers/idle/intel_idle.c
include/linux/clocksource.h
include/linux/tick.h
include/linux/vfio.h
include/uapi/linux/bpf.h
init/Kconfig
kernel/bpf/syscall.c
kernel/events/core.c
kernel/sched/fair.c
lib/Kconfig.debug
samples/bpf/Makefile
samples/bpf/bpf_helpers.h
samples/bpf/libbpf.h
samples/bpf/test_verifier.c
tools/perf/util/probe-finder.c

Simple merge
diff --cc MAINTAINERS
Simple merge
index 0d31d3ccab81efbc1937a0cc730210d9ce6406f5,0000000000000000000000000000000000000000..efe17dd9b9218b7ef16299700a0f2a6d74ca61c1
mode 100644,000000..100644
--- /dev/null
@@@ -1,337 -1,0 +1,337 @@@
-       if (strcmp(tk->tkr.clock->name, "arch_sys_counter") != 0)
 +/*
 + * Adapted from arm64 version.
 + *
 + * Copyright (C) 2012 ARM Limited
 + * Copyright (C) 2015 Mentor Graphics Corporation.
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License version 2 as
 + * published by the Free Software Foundation.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 + */
 +
 +#include <linux/elf.h>
 +#include <linux/err.h>
 +#include <linux/kernel.h>
 +#include <linux/mm.h>
 +#include <linux/of.h>
 +#include <linux/printk.h>
 +#include <linux/slab.h>
 +#include <linux/timekeeper_internal.h>
 +#include <linux/vmalloc.h>
 +#include <asm/arch_timer.h>
 +#include <asm/barrier.h>
 +#include <asm/cacheflush.h>
 +#include <asm/page.h>
 +#include <asm/vdso.h>
 +#include <asm/vdso_datapage.h>
 +#include <clocksource/arm_arch_timer.h>
 +
 +#define MAX_SYMNAME   64
 +
 +static struct page **vdso_text_pagelist;
 +
 +/* Total number of pages needed for the data and text portions of the VDSO. */
 +unsigned int vdso_total_pages __read_mostly;
 +
 +/*
 + * The VDSO data page.
 + */
 +static union vdso_data_store vdso_data_store __page_aligned_data;
 +static struct vdso_data *vdso_data = &vdso_data_store.data;
 +
 +static struct page *vdso_data_page;
 +static struct vm_special_mapping vdso_data_mapping = {
 +      .name = "[vvar]",
 +      .pages = &vdso_data_page,
 +};
 +
 +static struct vm_special_mapping vdso_text_mapping = {
 +      .name = "[vdso]",
 +};
 +
 +struct elfinfo {
 +      Elf32_Ehdr      *hdr;           /* ptr to ELF */
 +      Elf32_Sym       *dynsym;        /* ptr to .dynsym section */
 +      unsigned long   dynsymsize;     /* size of .dynsym section */
 +      char            *dynstr;        /* ptr to .dynstr section */
 +};
 +
 +/* Cached result of boot-time check for whether the arch timer exists,
 + * and if so, whether the virtual counter is useable.
 + */
 +static bool cntvct_ok __read_mostly;
 +
 +static bool __init cntvct_functional(void)
 +{
 +      struct device_node *np;
 +      bool ret = false;
 +
 +      if (!IS_ENABLED(CONFIG_ARM_ARCH_TIMER))
 +              goto out;
 +
 +      /* The arm_arch_timer core should export
 +       * arch_timer_use_virtual or similar so we don't have to do
 +       * this.
 +       */
 +      np = of_find_compatible_node(NULL, NULL, "arm,armv7-timer");
 +      if (!np)
 +              goto out_put;
 +
 +      if (of_property_read_bool(np, "arm,cpu-registers-not-fw-configured"))
 +              goto out_put;
 +
 +      ret = true;
 +
 +out_put:
 +      of_node_put(np);
 +out:
 +      return ret;
 +}
 +
 +static void * __init find_section(Elf32_Ehdr *ehdr, const char *name,
 +                                unsigned long *size)
 +{
 +      Elf32_Shdr *sechdrs;
 +      unsigned int i;
 +      char *secnames;
 +
 +      /* Grab section headers and strings so we can tell who is who */
 +      sechdrs = (void *)ehdr + ehdr->e_shoff;
 +      secnames = (void *)ehdr + sechdrs[ehdr->e_shstrndx].sh_offset;
 +
 +      /* Find the section they want */
 +      for (i = 1; i < ehdr->e_shnum; i++) {
 +              if (strcmp(secnames + sechdrs[i].sh_name, name) == 0) {
 +                      if (size)
 +                              *size = sechdrs[i].sh_size;
 +                      return (void *)ehdr + sechdrs[i].sh_offset;
 +              }
 +      }
 +
 +      if (size)
 +              *size = 0;
 +      return NULL;
 +}
 +
 +static Elf32_Sym * __init find_symbol(struct elfinfo *lib, const char *symname)
 +{
 +      unsigned int i;
 +
 +      for (i = 0; i < (lib->dynsymsize / sizeof(Elf32_Sym)); i++) {
 +              char name[MAX_SYMNAME], *c;
 +
 +              if (lib->dynsym[i].st_name == 0)
 +                      continue;
 +              strlcpy(name, lib->dynstr + lib->dynsym[i].st_name,
 +                      MAX_SYMNAME);
 +              c = strchr(name, '@');
 +              if (c)
 +                      *c = 0;
 +              if (strcmp(symname, name) == 0)
 +                      return &lib->dynsym[i];
 +      }
 +      return NULL;
 +}
 +
 +static void __init vdso_nullpatch_one(struct elfinfo *lib, const char *symname)
 +{
 +      Elf32_Sym *sym;
 +
 +      sym = find_symbol(lib, symname);
 +      if (!sym)
 +              return;
 +
 +      sym->st_name = 0;
 +}
 +
 +static void __init patch_vdso(void *ehdr)
 +{
 +      struct elfinfo einfo;
 +
 +      einfo = (struct elfinfo) {
 +              .hdr = ehdr,
 +      };
 +
 +      einfo.dynsym = find_section(einfo.hdr, ".dynsym", &einfo.dynsymsize);
 +      einfo.dynstr = find_section(einfo.hdr, ".dynstr", NULL);
 +
 +      /* If the virtual counter is absent or non-functional we don't
 +       * want programs to incur the slight additional overhead of
 +       * dispatching through the VDSO only to fall back to syscalls.
 +       */
 +      if (!cntvct_ok) {
 +              vdso_nullpatch_one(&einfo, "__vdso_gettimeofday");
 +              vdso_nullpatch_one(&einfo, "__vdso_clock_gettime");
 +      }
 +}
 +
 +static int __init vdso_init(void)
 +{
 +      unsigned int text_pages;
 +      int i;
 +
 +      if (memcmp(&vdso_start, "\177ELF", 4)) {
 +              pr_err("VDSO is not a valid ELF object!\n");
 +              return -ENOEXEC;
 +      }
 +
 +      text_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
 +      pr_debug("vdso: %i text pages at base %p\n", text_pages, &vdso_start);
 +
 +      /* Allocate the VDSO text pagelist */
 +      vdso_text_pagelist = kcalloc(text_pages, sizeof(struct page *),
 +                                   GFP_KERNEL);
 +      if (vdso_text_pagelist == NULL)
 +              return -ENOMEM;
 +
 +      /* Grab the VDSO data page. */
 +      vdso_data_page = virt_to_page(vdso_data);
 +
 +      /* Grab the VDSO text pages. */
 +      for (i = 0; i < text_pages; i++) {
 +              struct page *page;
 +
 +              page = virt_to_page(&vdso_start + i * PAGE_SIZE);
 +              vdso_text_pagelist[i] = page;
 +      }
 +
 +      vdso_text_mapping.pages = vdso_text_pagelist;
 +
 +      vdso_total_pages = 1; /* for the data/vvar page */
 +      vdso_total_pages += text_pages;
 +
 +      cntvct_ok = cntvct_functional();
 +
 +      patch_vdso(&vdso_start);
 +
 +      return 0;
 +}
 +arch_initcall(vdso_init);
 +
 +static int install_vvar(struct mm_struct *mm, unsigned long addr)
 +{
 +      struct vm_area_struct *vma;
 +
 +      vma = _install_special_mapping(mm, addr, PAGE_SIZE,
 +                                     VM_READ | VM_MAYREAD,
 +                                     &vdso_data_mapping);
 +
 +      return IS_ERR(vma) ? PTR_ERR(vma) : 0;
 +}
 +
 +/* assumes mmap_sem is write-locked */
 +void arm_install_vdso(struct mm_struct *mm, unsigned long addr)
 +{
 +      struct vm_area_struct *vma;
 +      unsigned long len;
 +
 +      mm->context.vdso = 0;
 +
 +      if (vdso_text_pagelist == NULL)
 +              return;
 +
 +      if (install_vvar(mm, addr))
 +              return;
 +
 +      /* Account for vvar page. */
 +      addr += PAGE_SIZE;
 +      len = (vdso_total_pages - 1) << PAGE_SHIFT;
 +
 +      vma = _install_special_mapping(mm, addr, len,
 +              VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
 +              &vdso_text_mapping);
 +
 +      if (!IS_ERR(vma))
 +              mm->context.vdso = addr;
 +}
 +
 +static void vdso_write_begin(struct vdso_data *vdata)
 +{
 +      ++vdso_data->seq_count;
 +      smp_wmb(); /* Pairs with smp_rmb in vdso_read_retry */
 +}
 +
 +static void vdso_write_end(struct vdso_data *vdata)
 +{
 +      smp_wmb(); /* Pairs with smp_rmb in vdso_read_begin */
 +      ++vdso_data->seq_count;
 +}
 +
 +static bool tk_is_cntvct(const struct timekeeper *tk)
 +{
 +      if (!IS_ENABLED(CONFIG_ARM_ARCH_TIMER))
 +              return false;
 +
-               vdso_data->cs_cycle_last        = tk->tkr.cycle_last;
++      if (strcmp(tk->tkr_mono.clock->name, "arch_sys_counter") != 0)
 +              return false;
 +
 +      return true;
 +}
 +
 +/**
 + * update_vsyscall - update the vdso data page
 + *
 + * Increment the sequence counter, making it odd, indicating to
 + * userspace that an update is in progress.  Update the fields used
 + * for coarse clocks and, if the architected system timer is in use,
 + * the fields used for high precision clocks.  Increment the sequence
 + * counter again, making it even, indicating to userspace that the
 + * update is finished.
 + *
 + * Userspace is expected to sample seq_count before reading any other
 + * fields from the data page.  If seq_count is odd, userspace is
 + * expected to wait until it becomes even.  After copying data from
 + * the page, userspace must sample seq_count again; if it has changed
 + * from its previous value, userspace must retry the whole sequence.
 + *
 + * Calls to update_vsyscall are serialized by the timekeeping core.
 + */
 +void update_vsyscall(struct timekeeper *tk)
 +{
 +      struct timespec xtime_coarse;
 +      struct timespec64 *wtm = &tk->wall_to_monotonic;
 +
 +      if (!cntvct_ok) {
 +              /* The entry points have been zeroed, so there is no
 +               * point in updating the data page.
 +               */
 +              return;
 +      }
 +
 +      vdso_write_begin(vdso_data);
 +
 +      xtime_coarse = __current_kernel_time();
 +      vdso_data->tk_is_cntvct                 = tk_is_cntvct(tk);
 +      vdso_data->xtime_coarse_sec             = xtime_coarse.tv_sec;
 +      vdso_data->xtime_coarse_nsec            = xtime_coarse.tv_nsec;
 +      vdso_data->wtm_clock_sec                = wtm->tv_sec;
 +      vdso_data->wtm_clock_nsec               = wtm->tv_nsec;
 +
 +      if (vdso_data->tk_is_cntvct) {
-               vdso_data->xtime_clock_snsec    = tk->tkr.xtime_nsec;
-               vdso_data->cs_mult              = tk->tkr.mult;
-               vdso_data->cs_shift             = tk->tkr.shift;
-               vdso_data->cs_mask              = tk->tkr.mask;
++              vdso_data->cs_cycle_last        = tk->tkr_mono.cycle_last;
 +              vdso_data->xtime_clock_sec      = tk->xtime_sec;
++              vdso_data->xtime_clock_snsec    = tk->tkr_mono.xtime_nsec;
++              vdso_data->cs_mult              = tk->tkr_mono.mult;
++              vdso_data->cs_shift             = tk->tkr_mono.shift;
++              vdso_data->cs_mask              = tk->tkr_mono.mask;
 +      }
 +
 +      vdso_write_end(vdso_data);
 +
 +      flush_dcache_page(virt_to_page(vdso_data));
 +}
 +
 +void update_vsyscall_tz(void)
 +{
 +      vdso_data->tz_minuteswest       = sys_tz.tz_minuteswest;
 +      vdso_data->tz_dsttime           = sys_tz.tz_dsttime;
 +      flush_dcache_page(virt_to_page(vdso_data));
 +}
index 7622dbb050833bd99936648200073a1dd2b26b7a,57d429830e09b4ceffa71efc3b3b88f6a88c68cd..4b8e9f4d59eaddff4aebc18c4b404e9206bd41db
  #include <linux/cpuidle.h>
  #include <linux/cpu_pm.h>
  #include <linux/export.h>
- #include <linux/clockchips.h>
+ #include <linux/tick.h>
  
  #include <asm/cpuidle.h>
 -#include <asm/proc-fns.h>
  
  #include "common.h"
  #include "pm.h"
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 23df3e7f8e7d2eee7b196bff4c825d38ab284043,cc47ef41076a04039e60fffad990da3443f77729..3df89a908ad6e006cdcd287acc3365cd4965db4f
@@@ -118,12 -118,9 +118,13 @@@ enum bpf_map_type 
  enum bpf_prog_type {
        BPF_PROG_TYPE_UNSPEC,
        BPF_PROG_TYPE_SOCKET_FILTER,
 +      BPF_PROG_TYPE_SCHED_CLS,
 +      BPF_PROG_TYPE_SCHED_ACT,
+       BPF_PROG_TYPE_KPROBE,
  };
  
 +#define BPF_PSEUDO_MAP_FD     1
 +
  /* flags for BPF_MAP_UPDATE_ELEM command */
  #define BPF_ANY               0 /* create new element or update existing */
  #define BPF_NOEXIST   1 /* create new element if it didn't exist */
@@@ -166,45 -164,9 +168,48 @@@ enum bpf_func_id 
        BPF_FUNC_map_lookup_elem, /* void *map_lookup_elem(&map, &key) */
        BPF_FUNC_map_update_elem, /* int map_update_elem(&map, &key, &value, flags) */
        BPF_FUNC_map_delete_elem, /* int map_delete_elem(&map, &key) */
 +      BPF_FUNC_get_prandom_u32, /* u32 prandom_u32(void) */
 +      BPF_FUNC_get_smp_processor_id, /* u32 raw_smp_processor_id(void) */
 +
 +      /**
 +       * skb_store_bytes(skb, offset, from, len, flags) - store bytes into packet
 +       * @skb: pointer to skb
 +       * @offset: offset within packet from skb->data
 +       * @from: pointer where to copy bytes from
 +       * @len: number of bytes to store into packet
 +       * @flags: bit 0 - if true, recompute skb->csum
 +       *         other bits - reserved
 +       * Return: 0 on success
 +       */
 +      BPF_FUNC_skb_store_bytes,
 +
 +      /**
 +       * l3_csum_replace(skb, offset, from, to, flags) - recompute IP checksum
 +       * @skb: pointer to skb
 +       * @offset: offset within packet where IP checksum is located
 +       * @from: old value of header field
 +       * @to: new value of header field
 +       * @flags: bits 0-3 - size of header field
 +       *         other bits - reserved
 +       * Return: 0 on success
 +       */
 +      BPF_FUNC_l3_csum_replace,
 +
 +      /**
 +       * l4_csum_replace(skb, offset, from, to, flags) - recompute TCP/UDP checksum
 +       * @skb: pointer to skb
 +       * @offset: offset within packet where TCP/UDP checksum is located
 +       * @from: old value of header field
 +       * @to: new value of header field
 +       * @flags: bits 0-3 - size of header field
 +       *         bit 4 - is pseudo header
 +       *         other bits - reserved
 +       * Return: 0 on success
 +       */
 +      BPF_FUNC_l4_csum_replace,
+       BPF_FUNC_probe_read,      /* int bpf_probe_read(void *dst, int size, void *src) */
+       BPF_FUNC_ktime_get_ns,    /* u64 bpf_ktime_get_ns(void) */
+       BPF_FUNC_trace_printk,    /* int bpf_trace_printk(const char *fmt, int fmt_size, ...) */
        __BPF_FUNC_MAX_ID,
  };
  
diff --cc init/Kconfig
Simple merge
index ea75c654af1b0011ecf3efdd481822ce9f073a63,504c10b990efe9c21d32e33f01747e99294f69a1..3bae6c59191483d48eb5934ad216cc952abaf9b1
@@@ -467,10 -466,9 +468,10 @@@ struct bpf_prog *bpf_prog_get(u32 ufd
        fdput(f);
        return prog;
  }
 +EXPORT_SYMBOL_GPL(bpf_prog_get);
  
  /* last field in 'union bpf_attr' used by this command */
- #define       BPF_PROG_LOAD_LAST_FIELD log_buf
+ #define       BPF_PROG_LOAD_LAST_FIELD kern_version
  
  static int bpf_prog_load(union bpf_attr *attr)
  {
index 2fabc062716591e960dbab2c9cfc16a755895773,06917d537302b6de0dca1254d5ef6dabb9c6228d..81aa3a4ece9f787038027bb4e5a1e456312c1182
@@@ -6449,6 -6711,49 +6711,49 @@@ static void perf_event_free_filter(stru
        ftrace_profile_free_filter(event);
  }
  
 -      if (prog->aux->prog_type != BPF_PROG_TYPE_KPROBE) {
+ static int perf_event_set_bpf_prog(struct perf_event *event, u32 prog_fd)
+ {
+       struct bpf_prog *prog;
+       if (event->attr.type != PERF_TYPE_TRACEPOINT)
+               return -EINVAL;
+       if (event->tp_event->prog)
+               return -EEXIST;
+       if (!(event->tp_event->flags & TRACE_EVENT_FL_KPROBE))
+               /* bpf programs can only be attached to kprobes */
+               return -EINVAL;
+       prog = bpf_prog_get(prog_fd);
+       if (IS_ERR(prog))
+               return PTR_ERR(prog);
++      if (prog->type != BPF_PROG_TYPE_KPROBE) {
+               /* valid fd, but invalid bpf program type */
+               bpf_prog_put(prog);
+               return -EINVAL;
+       }
+       event->tp_event->prog = prog;
+       return 0;
+ }
+ static void perf_event_free_bpf_prog(struct perf_event *event)
+ {
+       struct bpf_prog *prog;
+       if (!event->tp_event)
+               return;
+       prog = event->tp_event->prog;
+       if (prog) {
+               event->tp_event->prog = NULL;
+               bpf_prog_put(prog);
+       }
+ }
  #else
  
  static inline void perf_tp_register(void)
Simple merge
Simple merge
index d24f51bca465798cfcff96307eaf4aa101ad5833,fe98fb226e6e1af21dae6feb5684ebc30faffb50..cd0a93ffdd9645f1ad9dedd7de831c726c8e4016
@@@ -17,7 -25,10 +25,11 @@@ tracex4-objs := bpf_load.o libbpf.o tra
  always := $(hostprogs-y)
  always += sockex1_kern.o
  always += sockex2_kern.o
 +always += tcbpf1_kern.o
+ always += tracex1_kern.o
+ always += tracex2_kern.o
+ always += tracex3_kern.o
+ always += tracex4_kern.o
  
  HOSTCFLAGS += -I$(objtree)/usr/include
  
Simple merge
Simple merge
index 75d561f9fd6ae430b49248214608c00e588dd594,740ce97cda5e6a19ab86b3370d98e6e9c7e5dc39..9ab645698ffb4374ec6d9597d9f82b8207fe4cda
@@@ -767,9 -687,9 +767,9 @@@ static int test(void
                }
                printf("#%d %s ", i, tests[i].descr);
  
 -              prog_fd = bpf_prog_load(BPF_PROG_TYPE_UNSPEC, prog,
 +              prog_fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, prog,
                                        prog_len * sizeof(struct bpf_insn),
-                                       "GPL");
+                                       "GPL", 0);
  
                if (tests[i].result == ACCEPT) {
                        if (prog_fd < 0) {
Simple merge