spectre.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Interface for managing mitigations for Spectre vulnerabilities.
  4. *
  5. * Copyright (C) 2020 Google LLC
  6. * Author: Will Deacon <will@kernel.org>
  7. */
  8. #ifndef __ASM_SPECTRE_H
  9. #define __ASM_SPECTRE_H
  10. #define BP_HARDEN_EL2_SLOTS 4
  11. #define __BP_HARDEN_HYP_VECS_SZ ((BP_HARDEN_EL2_SLOTS - 1) * SZ_2K)
  12. #ifndef __ASSEMBLY__
  13. #include <linux/smp.h>
  14. #include <asm/percpu.h>
  15. #include <asm/cpufeature.h>
  16. #include <asm/virt.h>
  17. /* Watch out, ordering is important here. */
  18. enum mitigation_state {
  19. SPECTRE_UNAFFECTED,
  20. SPECTRE_MITIGATED,
  21. SPECTRE_VULNERABLE,
  22. };
  23. struct pt_regs;
  24. struct task_struct;
  25. /*
  26. * Note: the order of this enum corresponds to __bp_harden_hyp_vecs and
  27. * we rely on having the direct vectors first.
  28. */
  29. enum arm64_hyp_spectre_vector {
  30. /*
  31. * Take exceptions directly to __kvm_hyp_vector. This must be
  32. * 0 so that it used by default when mitigations are not needed.
  33. */
  34. HYP_VECTOR_DIRECT,
  35. /*
  36. * Bounce via a slot in the hypervisor text mapping of
  37. * __bp_harden_hyp_vecs, which contains an SMC call.
  38. */
  39. HYP_VECTOR_SPECTRE_DIRECT,
  40. /*
  41. * Bounce via a slot in a special mapping of __bp_harden_hyp_vecs
  42. * next to the idmap page.
  43. */
  44. HYP_VECTOR_INDIRECT,
  45. /*
  46. * Bounce via a slot in a special mapping of __bp_harden_hyp_vecs
  47. * next to the idmap page, which contains an SMC call.
  48. */
  49. HYP_VECTOR_SPECTRE_INDIRECT,
  50. };
  51. typedef void (*bp_hardening_cb_t)(void);
  52. struct bp_hardening_data {
  53. enum arm64_hyp_spectre_vector slot;
  54. bp_hardening_cb_t fn;
  55. };
  56. DECLARE_PER_CPU_READ_MOSTLY(struct bp_hardening_data, bp_hardening_data);
  57. /* Called during entry so must be __always_inline */
  58. static __always_inline void arm64_apply_bp_hardening(void)
  59. {
  60. struct bp_hardening_data *d;
  61. if (!alternative_has_cap_unlikely(ARM64_SPECTRE_V2))
  62. return;
  63. d = this_cpu_ptr(&bp_hardening_data);
  64. if (d->fn)
  65. d->fn();
  66. }
  67. enum mitigation_state arm64_get_spectre_v2_state(void);
  68. bool has_spectre_v2(const struct arm64_cpu_capabilities *cap, int scope);
  69. void spectre_v2_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
  70. bool has_spectre_v3a(const struct arm64_cpu_capabilities *cap, int scope);
  71. void spectre_v3a_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
  72. enum mitigation_state arm64_get_spectre_v4_state(void);
  73. bool has_spectre_v4(const struct arm64_cpu_capabilities *cap, int scope);
  74. void spectre_v4_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
  75. void spectre_v4_enable_task_mitigation(struct task_struct *tsk);
  76. enum mitigation_state arm64_get_meltdown_state(void);
  77. enum mitigation_state arm64_get_spectre_bhb_state(void);
  78. bool is_spectre_bhb_affected(const struct arm64_cpu_capabilities *entry, int scope);
  79. u8 spectre_bhb_loop_affected(int scope);
  80. void spectre_bhb_enable_mitigation(const struct arm64_cpu_capabilities *__unused);
  81. bool try_emulate_el1_ssbs(struct pt_regs *regs, u32 instr);
  82. void spectre_v4_patch_fw_mitigation_enable(struct alt_instr *alt, __le32 *origptr,
  83. __le32 *updptr, int nr_inst);
  84. void smccc_patch_fw_mitigation_conduit(struct alt_instr *alt, __le32 *origptr,
  85. __le32 *updptr, int nr_inst);
  86. void spectre_bhb_patch_loop_mitigation_enable(struct alt_instr *alt, __le32 *origptr,
  87. __le32 *updptr, int nr_inst);
  88. void spectre_bhb_patch_fw_mitigation_enabled(struct alt_instr *alt, __le32 *origptr,
  89. __le32 *updptr, int nr_inst);
  90. void spectre_bhb_patch_loop_iter(struct alt_instr *alt,
  91. __le32 *origptr, __le32 *updptr, int nr_inst);
  92. void spectre_bhb_patch_wa3(struct alt_instr *alt,
  93. __le32 *origptr, __le32 *updptr, int nr_inst);
  94. void spectre_bhb_patch_clearbhb(struct alt_instr *alt,
  95. __le32 *origptr, __le32 *updptr, int nr_inst);
  96. #endif /* __ASSEMBLY__ */
  97. #endif /* __ASM_SPECTRE_H */