Merge branch 'x86/debug' into core/urgent
authorThomas Gleixner <tglx@linutronix.de>
Thu, 18 Jul 2019 18:50:48 +0000 (20:50 +0200)
committerThomas Gleixner <tglx@linutronix.de>
Thu, 18 Jul 2019 18:50:48 +0000 (20:50 +0200)
Pick up the two pending objtool patches as the next round of objtool fixes
depend on them.

1  2 
kernel/bpf/core.c
tools/objtool/check.c

diff --combined kernel/bpf/core.c
@@@ -1299,7 -1299,7 +1299,7 @@@ static u64 ___bpf_prog_run(u64 *regs, c
  {
  #define BPF_INSN_2_LBL(x, y)    [BPF_##x | BPF_##y] = &&x##_##y
  #define BPF_INSN_3_LBL(x, y, z) [BPF_##x | BPF_##y | BPF_##z] = &&x##_##y##_##z
-       static const void *jumptable[256] = {
+       static const void * const jumptable[256] __annotate_jump_table = {
                [0 ... 255] = &&default_label,
                /* Now overwrite non-defaults ... */
                BPF_INSN_MAP(BPF_INSN_2_LBL, BPF_INSN_3_LBL),
@@@ -1364,10 -1364,10 +1364,10 @@@ select_insn
                insn++;
                CONT;
        ALU_ARSH_X:
 -              DST = (u64) (u32) ((*(s32 *) &DST) >> SRC);
 +              DST = (u64) (u32) (((s32) DST) >> SRC);
                CONT;
        ALU_ARSH_K:
 -              DST = (u64) (u32) ((*(s32 *) &DST) >> IMM);
 +              DST = (u64) (u32) (((s32) DST) >> IMM);
                CONT;
        ALU64_ARSH_X:
                (*(s64 *) &DST) >>= SRC;
@@@ -1558,7 -1558,6 +1558,6 @@@ out
                BUG_ON(1);
                return 0;
  }
- STACK_FRAME_NON_STANDARD(___bpf_prog_run); /* jump table */
  
  #define PROG_NAME(stack_size) __bpf_prog_run##stack_size
  #define DEFINE_BPF_PROG_RUN(stack_size) \
@@@ -1791,42 -1790,38 +1790,42 @@@ struct bpf_prog_array *bpf_prog_array_a
        return &empty_prog_array.hdr;
  }
  
 -void bpf_prog_array_free(struct bpf_prog_array __rcu *progs)
 +void bpf_prog_array_free(struct bpf_prog_array *progs)
  {
 -      if (!progs ||
 -          progs == (struct bpf_prog_array __rcu *)&empty_prog_array.hdr)
 +      if (!progs || progs == &empty_prog_array.hdr)
                return;
        kfree_rcu(progs, rcu);
  }
  
 -int bpf_prog_array_length(struct bpf_prog_array __rcu *array)
 +int bpf_prog_array_length(struct bpf_prog_array *array)
  {
        struct bpf_prog_array_item *item;
        u32 cnt = 0;
  
 -      rcu_read_lock();
 -      item = rcu_dereference(array)->items;
 -      for (; item->prog; item++)
 +      for (item = array->items; item->prog; item++)
                if (item->prog != &dummy_bpf_prog.prog)
                        cnt++;
 -      rcu_read_unlock();
        return cnt;
  }
  
 +bool bpf_prog_array_is_empty(struct bpf_prog_array *array)
 +{
 +      struct bpf_prog_array_item *item;
 +
 +      for (item = array->items; item->prog; item++)
 +              if (item->prog != &dummy_bpf_prog.prog)
 +                      return false;
 +      return true;
 +}
  
 -static bool bpf_prog_array_copy_core(struct bpf_prog_array __rcu *array,
 +static bool bpf_prog_array_copy_core(struct bpf_prog_array *array,
                                     u32 *prog_ids,
                                     u32 request_cnt)
  {
        struct bpf_prog_array_item *item;
        int i = 0;
  
 -      item = rcu_dereference_check(array, 1)->items;
 -      for (; item->prog; item++) {
 +      for (item = array->items; item->prog; item++) {
                if (item->prog == &dummy_bpf_prog.prog)
                        continue;
                prog_ids[i] = item->prog->aux->id;
        return !!(item->prog);
  }
  
 -int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *array,
 +int bpf_prog_array_copy_to_user(struct bpf_prog_array *array,
                                __u32 __user *prog_ids, u32 cnt)
  {
        unsigned long err = 0;
         * cnt = bpf_prog_array_length();
         * if (cnt > 0)
         *     bpf_prog_array_copy_to_user(..., cnt);
 -       * so below kcalloc doesn't need extra cnt > 0 check, but
 -       * bpf_prog_array_length() releases rcu lock and
 -       * prog array could have been swapped with empty or larger array,
 -       * so always copy 'cnt' prog_ids to the user.
 -       * In a rare race the user will see zero prog_ids
 +       * so below kcalloc doesn't need extra cnt > 0 check.
         */
        ids = kcalloc(cnt, sizeof(u32), GFP_USER | __GFP_NOWARN);
        if (!ids)
                return -ENOMEM;
 -      rcu_read_lock();
        nospc = bpf_prog_array_copy_core(array, ids, cnt);
 -      rcu_read_unlock();
        err = copy_to_user(prog_ids, ids, cnt * sizeof(u32));
        kfree(ids);
        if (err)
        return 0;
  }
  
 -void bpf_prog_array_delete_safe(struct bpf_prog_array __rcu *array,
 +void bpf_prog_array_delete_safe(struct bpf_prog_array *array,
                                struct bpf_prog *old_prog)
  {
 -      struct bpf_prog_array_item *item = array->items;
 +      struct bpf_prog_array_item *item;
  
 -      for (; item->prog; item++)
 +      for (item = array->items; item->prog; item++)
                if (item->prog == old_prog) {
                        WRITE_ONCE(item->prog, &dummy_bpf_prog.prog);
                        break;
                }
  }
  
 -int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,
 +int bpf_prog_array_copy(struct bpf_prog_array *old_array,
                        struct bpf_prog *exclude_prog,
                        struct bpf_prog *include_prog,
                        struct bpf_prog_array **new_array)
        return 0;
  }
  
 -int bpf_prog_array_copy_info(struct bpf_prog_array __rcu *array,
 +int bpf_prog_array_copy_info(struct bpf_prog_array *array,
                             u32 *prog_ids, u32 request_cnt,
                             u32 *prog_cnt)
  {
@@@ -2084,15 -2085,6 +2083,15 @@@ bool __weak bpf_helper_changes_pkt_data
        return false;
  }
  
 +/* Return TRUE if the JIT backend wants verifier to enable sub-register usage
 + * analysis code and wants explicit zero extension inserted by verifier.
 + * Otherwise, return FALSE.
 + */
 +bool __weak bpf_jit_needs_zext(void)
 +{
 +      return false;
 +}
 +
  /* To execute LD_ABS/LD_IND instructions __bpf_prog_run() may call
   * skb_copy_bits(), so provide a weak definition of it for NET-less config.
   */
@@@ -2110,4 -2102,3 +2109,4 @@@ EXPORT_SYMBOL(bpf_stats_enabled_key)
  #include <linux/bpf_trace.h>
  
  EXPORT_TRACEPOINT_SYMBOL_GPL(xdp_exception);
 +EXPORT_TRACEPOINT_SYMBOL_GPL(xdp_bulk_tx);
diff --combined tools/objtool/check.c
@@@ -18,6 -18,8 +18,8 @@@
  
  #define FAKE_JUMP_OFFSET -1
  
+ #define C_JUMP_TABLE_SECTION ".rodata..c_jump_table"
  struct alternative {
        struct list_head list;
        struct instruction *insn;
@@@ -1035,9 -1037,15 +1037,15 @@@ static struct rela *find_switch_table(s
  
                /*
                 * Make sure the .rodata address isn't associated with a
-                * symbol.  gcc jump tables are anonymous data.
+                * symbol.  GCC jump tables are anonymous data.
+                *
+                * Also support C jump tables which are in the same format as
+                * switch jump tables.  For objtool to recognize them, they
+                * need to be placed in the C_JUMP_TABLE_SECTION section.  They
+                * have symbols associated with them.
                 */
-               if (find_symbol_containing(rodata_sec, table_offset))
+               if (find_symbol_containing(rodata_sec, table_offset) &&
+                   strcmp(rodata_sec->name, C_JUMP_TABLE_SECTION))
                        continue;
  
                rodata_rela = find_rela_by_dest(rodata_sec, table_offset);
@@@ -1277,13 -1285,18 +1285,18 @@@ static void mark_rodata(struct objtool_
        bool found = false;
  
        /*
-        * This searches for the .rodata section or multiple .rodata.func_name
-        * sections if -fdata-sections is being used. The .str.1.1 and .str.1.8
-        * rodata sections are ignored as they don't contain jump tables.
+        * Search for the following rodata sections, each of which can
+        * potentially contain jump tables:
+        *
+        * - .rodata: can contain GCC switch tables
+        * - .rodata.<func>: same, if -fdata-sections is being used
+        * - .rodata..c_jump_table: contains C annotated jump tables
+        *
+        * .rodata.str1.* sections are ignored; they don't contain jump tables.
         */
        for_each_sec(file, sec) {
-               if (!strncmp(sec->name, ".rodata", 7) &&
-                   !strstr(sec->name, ".str1.")) {
+               if ((!strncmp(sec->name, ".rodata", 7) && !strstr(sec->name, ".str1.")) ||
+                   !strcmp(sec->name, C_JUMP_TABLE_SECTION)) {
                        sec->rodata = true;
                        found = true;
                }
@@@ -2407,7 -2420,7 +2420,7 @@@ int check(const char *_objname, bool or
  
        objname = _objname;
  
 -      file.elf = elf_open(objname, orc ? O_RDWR : O_RDONLY);
 +      file.elf = elf_read(objname, orc ? O_RDWR : O_RDONLY);
        if (!file.elf)
                return 1;