linux/arch/arc/include/asm/jump_label.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _ASM_ARC_JUMP_LABEL_H
   3#define _ASM_ARC_JUMP_LABEL_H
   4
   5#ifndef __ASSEMBLY__
   6
   7#include <linux/stringify.h>
   8#include <linux/types.h>
   9
  10#define JUMP_LABEL_NOP_SIZE 4
  11
  12/*
  13 * NOTE about '.balign 4':
  14 *
  15 * To make atomic update of patched instruction available we need to guarantee
  16 * that this instruction doesn't cross L1 cache line boundary.
  17 *
  18 * As of today we simply align instruction which can be patched by 4 byte using
  19 * ".balign 4" directive. In that case patched instruction is aligned with one
  20 * 16-bit NOP_S if this is required.
  21 * However 'align by 4' directive is much stricter than it actually required.
  22 * It's enough that our 32-bit instruction don't cross L1 cache line boundary /
  23 * L1 I$ fetch block boundary which can be achieved by using
  24 * ".bundle_align_mode" assembler directive. That will save us from adding
  25 * useless NOP_S padding in most of the cases.
  26 *
  27 * TODO: switch to ".bundle_align_mode" directive using whin it will be
  28 * supported by ARC toolchain.
  29 */
  30
  31static __always_inline bool arch_static_branch(struct static_key *key,
  32                                               bool branch)
  33{
  34        asm_volatile_goto(".balign "__stringify(JUMP_LABEL_NOP_SIZE)"   \n"
  35                 "1:                                                    \n"
  36                 "nop                                                   \n"
  37                 ".pushsection __jump_table, \"aw\"                     \n"
  38                 ".word 1b, %l[l_yes], %c0                              \n"
  39                 ".popsection                                           \n"
  40                 : : "i" (&((char *)key)[branch]) : : l_yes);
  41
  42        return false;
  43l_yes:
  44        return true;
  45}
  46
  47static __always_inline bool arch_static_branch_jump(struct static_key *key,
  48                                                    bool branch)
  49{
  50        asm_volatile_goto(".balign "__stringify(JUMP_LABEL_NOP_SIZE)"   \n"
  51                 "1:                                                    \n"
  52                 "b %l[l_yes]                                           \n"
  53                 ".pushsection __jump_table, \"aw\"                     \n"
  54                 ".word 1b, %l[l_yes], %c0                              \n"
  55                 ".popsection                                           \n"
  56                 : : "i" (&((char *)key)[branch]) : : l_yes);
  57
  58        return false;
  59l_yes:
  60        return true;
  61}
  62
  63typedef u32 jump_label_t;
  64
  65struct jump_entry {
  66        jump_label_t code;
  67        jump_label_t target;
  68        jump_label_t key;
  69};
  70
  71#endif  /* __ASSEMBLY__ */
  72#endif
  73