18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/* arch/arm64/include/asm/kvm_ptrauth.h: Guest/host ptrauth save/restore
38c2ecf20Sopenharmony_ci * Copyright 2019 Arm Limited
48c2ecf20Sopenharmony_ci * Authors: Mark Rutland <mark.rutland@arm.com>
58c2ecf20Sopenharmony_ci *         Amit Daniel Kachhap <amit.kachhap@arm.com>
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#ifndef __ASM_KVM_PTRAUTH_H
98c2ecf20Sopenharmony_ci#define __ASM_KVM_PTRAUTH_H
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#ifdef __ASSEMBLY__
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include <asm/sysreg.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#ifdef	CONFIG_ARM64_PTR_AUTH
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ci#define PTRAUTH_REG_OFFSET(x)	(x - CPU_APIAKEYLO_EL1)
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci/*
208c2ecf20Sopenharmony_ci * CPU_AP*_EL1 values exceed immediate offset range (512) for stp
218c2ecf20Sopenharmony_ci * instruction so below macros takes CPU_APIAKEYLO_EL1 as base and
228c2ecf20Sopenharmony_ci * calculates the offset of the keys from this base to avoid an extra add
238c2ecf20Sopenharmony_ci * instruction. These macros assumes the keys offsets follow the order of
248c2ecf20Sopenharmony_ci * the sysreg enum in kvm_host.h.
258c2ecf20Sopenharmony_ci */
268c2ecf20Sopenharmony_ci.macro	ptrauth_save_state base, reg1, reg2
278c2ecf20Sopenharmony_ci	mrs_s	\reg1, SYS_APIAKEYLO_EL1
288c2ecf20Sopenharmony_ci	mrs_s	\reg2, SYS_APIAKEYHI_EL1
298c2ecf20Sopenharmony_ci	stp	\reg1, \reg2, [\base, #PTRAUTH_REG_OFFSET(CPU_APIAKEYLO_EL1)]
308c2ecf20Sopenharmony_ci	mrs_s	\reg1, SYS_APIBKEYLO_EL1
318c2ecf20Sopenharmony_ci	mrs_s	\reg2, SYS_APIBKEYHI_EL1
328c2ecf20Sopenharmony_ci	stp	\reg1, \reg2, [\base, #PTRAUTH_REG_OFFSET(CPU_APIBKEYLO_EL1)]
338c2ecf20Sopenharmony_ci	mrs_s	\reg1, SYS_APDAKEYLO_EL1
348c2ecf20Sopenharmony_ci	mrs_s	\reg2, SYS_APDAKEYHI_EL1
358c2ecf20Sopenharmony_ci	stp	\reg1, \reg2, [\base, #PTRAUTH_REG_OFFSET(CPU_APDAKEYLO_EL1)]
368c2ecf20Sopenharmony_ci	mrs_s	\reg1, SYS_APDBKEYLO_EL1
378c2ecf20Sopenharmony_ci	mrs_s	\reg2, SYS_APDBKEYHI_EL1
388c2ecf20Sopenharmony_ci	stp	\reg1, \reg2, [\base, #PTRAUTH_REG_OFFSET(CPU_APDBKEYLO_EL1)]
398c2ecf20Sopenharmony_ci	mrs_s	\reg1, SYS_APGAKEYLO_EL1
408c2ecf20Sopenharmony_ci	mrs_s	\reg2, SYS_APGAKEYHI_EL1
418c2ecf20Sopenharmony_ci	stp	\reg1, \reg2, [\base, #PTRAUTH_REG_OFFSET(CPU_APGAKEYLO_EL1)]
428c2ecf20Sopenharmony_ci.endm
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci.macro	ptrauth_restore_state base, reg1, reg2
458c2ecf20Sopenharmony_ci	ldp	\reg1, \reg2, [\base, #PTRAUTH_REG_OFFSET(CPU_APIAKEYLO_EL1)]
468c2ecf20Sopenharmony_ci	msr_s	SYS_APIAKEYLO_EL1, \reg1
478c2ecf20Sopenharmony_ci	msr_s	SYS_APIAKEYHI_EL1, \reg2
488c2ecf20Sopenharmony_ci	ldp	\reg1, \reg2, [\base, #PTRAUTH_REG_OFFSET(CPU_APIBKEYLO_EL1)]
498c2ecf20Sopenharmony_ci	msr_s	SYS_APIBKEYLO_EL1, \reg1
508c2ecf20Sopenharmony_ci	msr_s	SYS_APIBKEYHI_EL1, \reg2
518c2ecf20Sopenharmony_ci	ldp	\reg1, \reg2, [\base, #PTRAUTH_REG_OFFSET(CPU_APDAKEYLO_EL1)]
528c2ecf20Sopenharmony_ci	msr_s	SYS_APDAKEYLO_EL1, \reg1
538c2ecf20Sopenharmony_ci	msr_s	SYS_APDAKEYHI_EL1, \reg2
548c2ecf20Sopenharmony_ci	ldp	\reg1, \reg2, [\base, #PTRAUTH_REG_OFFSET(CPU_APDBKEYLO_EL1)]
558c2ecf20Sopenharmony_ci	msr_s	SYS_APDBKEYLO_EL1, \reg1
568c2ecf20Sopenharmony_ci	msr_s	SYS_APDBKEYHI_EL1, \reg2
578c2ecf20Sopenharmony_ci	ldp	\reg1, \reg2, [\base, #PTRAUTH_REG_OFFSET(CPU_APGAKEYLO_EL1)]
588c2ecf20Sopenharmony_ci	msr_s	SYS_APGAKEYLO_EL1, \reg1
598c2ecf20Sopenharmony_ci	msr_s	SYS_APGAKEYHI_EL1, \reg2
608c2ecf20Sopenharmony_ci.endm
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci/*
638c2ecf20Sopenharmony_ci * Both ptrauth_switch_to_guest and ptrauth_switch_to_hyp macros will
648c2ecf20Sopenharmony_ci * check for the presence ARM64_HAS_ADDRESS_AUTH, which is defined as
658c2ecf20Sopenharmony_ci * (ARM64_HAS_ADDRESS_AUTH_ARCH || ARM64_HAS_ADDRESS_AUTH_IMP_DEF) and
668c2ecf20Sopenharmony_ci * then proceed ahead with the save/restore of Pointer Authentication
678c2ecf20Sopenharmony_ci * key registers if enabled for the guest.
688c2ecf20Sopenharmony_ci */
698c2ecf20Sopenharmony_ci.macro ptrauth_switch_to_guest g_ctxt, reg1, reg2, reg3
708c2ecf20Sopenharmony_cialternative_if_not ARM64_HAS_ADDRESS_AUTH
718c2ecf20Sopenharmony_ci	b	.L__skip_switch\@
728c2ecf20Sopenharmony_cialternative_else_nop_endif
738c2ecf20Sopenharmony_ci	mrs	\reg1, hcr_el2
748c2ecf20Sopenharmony_ci	and	\reg1, \reg1, #(HCR_API | HCR_APK)
758c2ecf20Sopenharmony_ci	cbz	\reg1, .L__skip_switch\@
768c2ecf20Sopenharmony_ci	add	\reg1, \g_ctxt, #CPU_APIAKEYLO_EL1
778c2ecf20Sopenharmony_ci	ptrauth_restore_state	\reg1, \reg2, \reg3
788c2ecf20Sopenharmony_ci.L__skip_switch\@:
798c2ecf20Sopenharmony_ci.endm
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci.macro ptrauth_switch_to_hyp g_ctxt, h_ctxt, reg1, reg2, reg3
828c2ecf20Sopenharmony_cialternative_if_not ARM64_HAS_ADDRESS_AUTH
838c2ecf20Sopenharmony_ci	b	.L__skip_switch\@
848c2ecf20Sopenharmony_cialternative_else_nop_endif
858c2ecf20Sopenharmony_ci	mrs	\reg1, hcr_el2
868c2ecf20Sopenharmony_ci	and	\reg1, \reg1, #(HCR_API | HCR_APK)
878c2ecf20Sopenharmony_ci	cbz	\reg1, .L__skip_switch\@
888c2ecf20Sopenharmony_ci	add	\reg1, \g_ctxt, #CPU_APIAKEYLO_EL1
898c2ecf20Sopenharmony_ci	ptrauth_save_state	\reg1, \reg2, \reg3
908c2ecf20Sopenharmony_ci	add	\reg1, \h_ctxt, #CPU_APIAKEYLO_EL1
918c2ecf20Sopenharmony_ci	ptrauth_restore_state	\reg1, \reg2, \reg3
928c2ecf20Sopenharmony_ci	isb
938c2ecf20Sopenharmony_ci.L__skip_switch\@:
948c2ecf20Sopenharmony_ci.endm
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci#else /* !CONFIG_ARM64_PTR_AUTH */
978c2ecf20Sopenharmony_ci.macro ptrauth_switch_to_guest g_ctxt, reg1, reg2, reg3
988c2ecf20Sopenharmony_ci.endm
998c2ecf20Sopenharmony_ci.macro ptrauth_switch_to_hyp g_ctxt, h_ctxt, reg1, reg2, reg3
1008c2ecf20Sopenharmony_ci.endm
1018c2ecf20Sopenharmony_ci#endif /* CONFIG_ARM64_PTR_AUTH */
1028c2ecf20Sopenharmony_ci#endif /* __ASSEMBLY__ */
1038c2ecf20Sopenharmony_ci#endif /* __ASM_KVM_PTRAUTH_H */
104