lbt.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Author: Qi Hu <huqi@loongson.cn>
  4. * Huacai Chen <chenhuacai@loongson.cn>
  5. * Copyright (C) 2020-2023 Loongson Technology Corporation Limited
  6. */
  7. #ifndef _ASM_LBT_H
  8. #define _ASM_LBT_H
  9. #include <asm/cpu.h>
  10. #include <asm/current.h>
  11. #include <asm/loongarch.h>
  12. #include <asm/processor.h>
  13. asmlinkage void _init_lbt(void);
  14. asmlinkage void _save_lbt(struct loongarch_lbt *);
  15. asmlinkage void _restore_lbt(struct loongarch_lbt *);
  16. asmlinkage int _save_lbt_context(void __user *regs, void __user *eflags);
  17. asmlinkage int _restore_lbt_context(void __user *regs, void __user *eflags);
  18. asmlinkage int _save_ftop_context(void __user *ftop);
  19. asmlinkage int _restore_ftop_context(void __user *ftop);
  20. static inline int is_lbt_enabled(void)
  21. {
  22. if (!cpu_has_lbt)
  23. return 0;
  24. return (csr_read32(LOONGARCH_CSR_EUEN) & CSR_EUEN_LBTEN) ?
  25. 1 : 0;
  26. }
  27. static inline int is_lbt_owner(void)
  28. {
  29. return test_thread_flag(TIF_USEDLBT);
  30. }
  31. #ifdef CONFIG_CPU_HAS_LBT
  32. static inline void enable_lbt(void)
  33. {
  34. if (cpu_has_lbt)
  35. csr_xchg32(CSR_EUEN_LBTEN, CSR_EUEN_LBTEN, LOONGARCH_CSR_EUEN);
  36. }
  37. static inline void disable_lbt(void)
  38. {
  39. if (cpu_has_lbt)
  40. csr_xchg32(0, CSR_EUEN_LBTEN, LOONGARCH_CSR_EUEN);
  41. }
  42. static inline void __own_lbt(void)
  43. {
  44. enable_lbt();
  45. set_thread_flag(TIF_USEDLBT);
  46. KSTK_EUEN(current) |= CSR_EUEN_LBTEN;
  47. }
  48. static inline void own_lbt_inatomic(int restore)
  49. {
  50. if (cpu_has_lbt && !is_lbt_owner()) {
  51. __own_lbt();
  52. if (restore)
  53. _restore_lbt(&current->thread.lbt);
  54. }
  55. }
  56. static inline void own_lbt(int restore)
  57. {
  58. preempt_disable();
  59. own_lbt_inatomic(restore);
  60. preempt_enable();
  61. }
  62. static inline void lose_lbt_inatomic(int save, struct task_struct *tsk)
  63. {
  64. if (cpu_has_lbt && is_lbt_owner()) {
  65. if (save)
  66. _save_lbt(&tsk->thread.lbt);
  67. disable_lbt();
  68. clear_tsk_thread_flag(tsk, TIF_USEDLBT);
  69. }
  70. KSTK_EUEN(tsk) &= ~(CSR_EUEN_LBTEN);
  71. }
  72. static inline void lose_lbt(int save)
  73. {
  74. preempt_disable();
  75. lose_lbt_inatomic(save, current);
  76. preempt_enable();
  77. }
  78. static inline void init_lbt(void)
  79. {
  80. __own_lbt();
  81. _init_lbt();
  82. }
  83. #else
  84. static inline void own_lbt_inatomic(int restore) {}
  85. static inline void lose_lbt_inatomic(int save, struct task_struct *tsk) {}
  86. static inline void init_lbt(void) {}
  87. static inline void lose_lbt(int save) {}
  88. #endif
  89. static inline int thread_lbt_context_live(void)
  90. {
  91. if (!cpu_has_lbt)
  92. return 0;
  93. return test_thread_flag(TIF_LBT_CTX_LIVE);
  94. }
  95. #endif /* _ASM_LBT_H */