Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm64: KVM: VHE: Make __fpsimd_enabled VHE aware

As non-VHE and VHE have different ways to express the trapping of
FPSIMD registers to EL2, make __fpsimd_enabled a patchable predicate
and provide a VHE implementation.

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

+23 -4
+3
arch/arm64/include/asm/kvm_arm.h
··· 216 216 ECN(SOFTSTP_CUR), ECN(WATCHPT_LOW), ECN(WATCHPT_CUR), \ 217 217 ECN(BKPT32), ECN(VECTOR32), ECN(BRK64) 218 218 219 + #define CPACR_EL1_FPEN (3 << 20) 220 + #define CPACR_EL1_TTA (1 << 28) 221 + 219 222 #endif /* __ARM64_KVM_ARM_H__ */
+1 -4
arch/arm64/kvm/hyp/hyp.h
··· 171 171 172 172 void __fpsimd_save_state(struct user_fpsimd_state *fp_regs); 173 173 void __fpsimd_restore_state(struct user_fpsimd_state *fp_regs); 174 - static inline bool __fpsimd_enabled(void) 175 - { 176 - return !(read_sysreg(cptr_el2) & CPTR_EL2_TFP); 177 - } 174 + bool __fpsimd_enabled(void); 178 175 179 176 u64 __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host_ctxt); 180 177 void __noreturn __hyp_do_panic(unsigned long, ...);
+19
arch/arm64/kvm/hyp/switch.c
··· 17 17 18 18 #include "hyp.h" 19 19 20 + static bool __hyp_text __fpsimd_enabled_nvhe(void) 21 + { 22 + return !(read_sysreg(cptr_el2) & CPTR_EL2_TFP); 23 + } 24 + 25 + static bool __hyp_text __fpsimd_enabled_vhe(void) 26 + { 27 + return !!(read_sysreg(cpacr_el1) & CPACR_EL1_FPEN); 28 + } 29 + 30 + static hyp_alternate_select(__fpsimd_is_enabled, 31 + __fpsimd_enabled_nvhe, __fpsimd_enabled_vhe, 32 + ARM64_HAS_VIRT_HOST_EXTN); 33 + 34 + bool __hyp_text __fpsimd_enabled(void) 35 + { 36 + return __fpsimd_is_enabled()(); 37 + } 38 + 20 39 static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu) 21 40 { 22 41 u64 val;