jump_label.h 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (C) 2013 Huawei Ltd.
  4. * Author: Jiang Liu <liuj97@gmail.com>
  5. *
  6. * Based on arch/arm/include/asm/jump_label.h
  7. */
  8. #ifndef __ASM_JUMP_LABEL_H
  9. #define __ASM_JUMP_LABEL_H
  10. #ifndef __ASSEMBLER__
  11. #include <linux/types.h>
  12. #include <asm/insn.h>
  13. #define HAVE_JUMP_LABEL_BATCH
  14. #define JUMP_LABEL_NOP_SIZE AARCH64_INSN_SIZE
  15. #define JUMP_TABLE_ENTRY(key, label) \
  16. ".pushsection __jump_table, \"aw\"\n\t" \
  17. ".align 3\n\t" \
  18. ".long 1b - ., " label " - .\n\t" \
  19. ".quad " key " - .\n\t" \
  20. ".popsection\n\t"
  21. /* This macro is also expanded on the Rust side. */
  22. #define ARCH_STATIC_BRANCH_ASM(key, label) \
  23. "1: nop\n\t" \
  24. JUMP_TABLE_ENTRY(key, label)
  25. static __always_inline bool arch_static_branch(struct static_key * const key,
  26. const bool branch)
  27. {
  28. char *k = &((char *)key)[branch];
  29. asm goto(
  30. ARCH_STATIC_BRANCH_ASM("%c0", "%l[l_yes]")
  31. : : "i"(k) : : l_yes
  32. );
  33. return false;
  34. l_yes:
  35. return true;
  36. }
  37. static __always_inline bool arch_static_branch_jump(struct static_key * const key,
  38. const bool branch)
  39. {
  40. char *k = &((char *)key)[branch];
  41. asm goto(
  42. "1: b %l[l_yes] \n\t"
  43. JUMP_TABLE_ENTRY("%c0", "%l[l_yes]")
  44. : : "i"(k) : : l_yes
  45. );
  46. return false;
  47. l_yes:
  48. return true;
  49. }
  50. #endif /* __ASSEMBLER__ */
  51. #endif /* __ASM_JUMP_LABEL_H */