kvm_hyp.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*
  2. * Copyright (C) 2015 - ARM Ltd
  3. * Author: Marc Zyngier <marc.zyngier@arm.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #ifndef __ARM64_KVM_HYP_H__
  18. #define __ARM64_KVM_HYP_H__
  19. #include <linux/compiler.h>
  20. #include <linux/kvm_host.h>
  21. #include <asm/sysreg.h>
  22. #define __hyp_text __section(.hyp.text) notrace
  23. #define read_sysreg_elx(r,nvh,vh) \
  24. ({ \
  25. u64 reg; \
  26. asm volatile(ALTERNATIVE("mrs %0, " __stringify(r##nvh),\
  27. "mrs_s %0, " __stringify(r##vh),\
  28. ARM64_HAS_VIRT_HOST_EXTN) \
  29. : "=r" (reg)); \
  30. reg; \
  31. })
  32. #define write_sysreg_elx(v,r,nvh,vh) \
  33. do { \
  34. u64 __val = (u64)(v); \
  35. asm volatile(ALTERNATIVE("msr " __stringify(r##nvh) ", %x0",\
  36. "msr_s " __stringify(r##vh) ", %x0",\
  37. ARM64_HAS_VIRT_HOST_EXTN) \
  38. : : "rZ" (__val)); \
  39. } while (0)
  40. /*
  41. * Unified accessors for registers that have a different encoding
  42. * between VHE and non-VHE. They must be specified without their "ELx"
  43. * encoding.
  44. */
  45. #define read_sysreg_el2(r) \
  46. ({ \
  47. u64 reg; \
  48. asm volatile(ALTERNATIVE("mrs %0, " __stringify(r##_EL2),\
  49. "mrs %0, " __stringify(r##_EL1),\
  50. ARM64_HAS_VIRT_HOST_EXTN) \
  51. : "=r" (reg)); \
  52. reg; \
  53. })
  54. #define write_sysreg_el2(v,r) \
  55. do { \
  56. u64 __val = (u64)(v); \
  57. asm volatile(ALTERNATIVE("msr " __stringify(r##_EL2) ", %x0",\
  58. "msr " __stringify(r##_EL1) ", %x0",\
  59. ARM64_HAS_VIRT_HOST_EXTN) \
  60. : : "rZ" (__val)); \
  61. } while (0)
  62. #define read_sysreg_el0(r) read_sysreg_elx(r, _EL0, _EL02)
  63. #define write_sysreg_el0(v,r) write_sysreg_elx(v, r, _EL0, _EL02)
  64. #define read_sysreg_el1(r) read_sysreg_elx(r, _EL1, _EL12)
  65. #define write_sysreg_el1(v,r) write_sysreg_elx(v, r, _EL1, _EL12)
  66. /* The VHE specific system registers and their encoding */
  67. #define sctlr_EL12 sys_reg(3, 5, 1, 0, 0)
  68. #define cpacr_EL12 sys_reg(3, 5, 1, 0, 2)
  69. #define ttbr0_EL12 sys_reg(3, 5, 2, 0, 0)
  70. #define ttbr1_EL12 sys_reg(3, 5, 2, 0, 1)
  71. #define tcr_EL12 sys_reg(3, 5, 2, 0, 2)
  72. #define afsr0_EL12 sys_reg(3, 5, 5, 1, 0)
  73. #define afsr1_EL12 sys_reg(3, 5, 5, 1, 1)
  74. #define esr_EL12 sys_reg(3, 5, 5, 2, 0)
  75. #define far_EL12 sys_reg(3, 5, 6, 0, 0)
  76. #define mair_EL12 sys_reg(3, 5, 10, 2, 0)
  77. #define amair_EL12 sys_reg(3, 5, 10, 3, 0)
  78. #define vbar_EL12 sys_reg(3, 5, 12, 0, 0)
  79. #define contextidr_EL12 sys_reg(3, 5, 13, 0, 1)
  80. #define cntkctl_EL12 sys_reg(3, 5, 14, 1, 0)
  81. #define cntp_tval_EL02 sys_reg(3, 5, 14, 2, 0)
  82. #define cntp_ctl_EL02 sys_reg(3, 5, 14, 2, 1)
  83. #define cntp_cval_EL02 sys_reg(3, 5, 14, 2, 2)
  84. #define cntv_tval_EL02 sys_reg(3, 5, 14, 3, 0)
  85. #define cntv_ctl_EL02 sys_reg(3, 5, 14, 3, 1)
  86. #define cntv_cval_EL02 sys_reg(3, 5, 14, 3, 2)
  87. #define spsr_EL12 sys_reg(3, 5, 4, 0, 0)
  88. #define elr_EL12 sys_reg(3, 5, 4, 0, 1)
  89. /**
  90. * hyp_alternate_select - Generates patchable code sequences that are
  91. * used to switch between two implementations of a function, depending
  92. * on the availability of a feature.
  93. *
  94. * @fname: a symbol name that will be defined as a function returning a
  95. * function pointer whose type will match @orig and @alt
  96. * @orig: A pointer to the default function, as returned by @fname when
  97. * @cond doesn't hold
  98. * @alt: A pointer to the alternate function, as returned by @fname
  99. * when @cond holds
  100. * @cond: a CPU feature (as described in asm/cpufeature.h)
  101. */
  102. #define hyp_alternate_select(fname, orig, alt, cond) \
  103. typeof(orig) * __hyp_text fname(void) \
  104. { \
  105. typeof(alt) *val = orig; \
  106. asm volatile(ALTERNATIVE("nop \n", \
  107. "mov %0, %1 \n", \
  108. cond) \
  109. : "+r" (val) : "r" (alt)); \
  110. return val; \
  111. }
  112. int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu);
  113. void __vgic_v3_save_state(struct kvm_vcpu *vcpu);
  114. void __vgic_v3_restore_state(struct kvm_vcpu *vcpu);
  115. void __vgic_v3_activate_traps(struct kvm_vcpu *vcpu);
  116. void __vgic_v3_deactivate_traps(struct kvm_vcpu *vcpu);
  117. void __vgic_v3_save_aprs(struct kvm_vcpu *vcpu);
  118. void __vgic_v3_restore_aprs(struct kvm_vcpu *vcpu);
  119. int __vgic_v3_perform_cpuif_access(struct kvm_vcpu *vcpu);
  120. void __timer_enable_traps(struct kvm_vcpu *vcpu);
  121. void __timer_disable_traps(struct kvm_vcpu *vcpu);
  122. void __sysreg_save_state_nvhe(struct kvm_cpu_context *ctxt);
  123. void __sysreg_restore_state_nvhe(struct kvm_cpu_context *ctxt);
  124. void sysreg_save_host_state_vhe(struct kvm_cpu_context *ctxt);
  125. void sysreg_restore_host_state_vhe(struct kvm_cpu_context *ctxt);
  126. void sysreg_save_guest_state_vhe(struct kvm_cpu_context *ctxt);
  127. void sysreg_restore_guest_state_vhe(struct kvm_cpu_context *ctxt);
  128. void __sysreg32_save_state(struct kvm_vcpu *vcpu);
  129. void __sysreg32_restore_state(struct kvm_vcpu *vcpu);
  130. void __debug_switch_to_guest(struct kvm_vcpu *vcpu);
  131. void __debug_switch_to_host(struct kvm_vcpu *vcpu);
  132. void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu);
  133. void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu);
  134. void __fpsimd_save_state(struct user_fpsimd_state *fp_regs);
  135. void __fpsimd_restore_state(struct user_fpsimd_state *fp_regs);
  136. bool __fpsimd_enabled(void);
  137. void activate_traps_vhe_load(struct kvm_vcpu *vcpu);
  138. void deactivate_traps_vhe_put(void);
  139. u64 __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host_ctxt);
  140. void __noreturn __hyp_do_panic(unsigned long, ...);
  141. #endif /* __ARM64_KVM_HYP_H__ */