18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2015 - ARM Ltd
48c2ecf20Sopenharmony_ci * Author: Marc Zyngier <marc.zyngier@arm.com>
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#ifndef __ARM64_KVM_HYP_H__
88c2ecf20Sopenharmony_ci#define __ARM64_KVM_HYP_H__
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <linux/compiler.h>
118c2ecf20Sopenharmony_ci#include <linux/kvm_host.h>
128c2ecf20Sopenharmony_ci#include <asm/alternative.h>
138c2ecf20Sopenharmony_ci#include <asm/sysreg.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ciDECLARE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
168c2ecf20Sopenharmony_ciDECLARE_PER_CPU(unsigned long, kvm_hyp_vector);
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#define read_sysreg_elx(r,nvh,vh)					\
198c2ecf20Sopenharmony_ci	({								\
208c2ecf20Sopenharmony_ci		u64 reg;						\
218c2ecf20Sopenharmony_ci		asm volatile(ALTERNATIVE(__mrs_s("%0", r##nvh),	\
228c2ecf20Sopenharmony_ci					 __mrs_s("%0", r##vh),		\
238c2ecf20Sopenharmony_ci					 ARM64_HAS_VIRT_HOST_EXTN)	\
248c2ecf20Sopenharmony_ci			     : "=r" (reg));				\
258c2ecf20Sopenharmony_ci		reg;							\
268c2ecf20Sopenharmony_ci	})
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci#define write_sysreg_elx(v,r,nvh,vh)					\
298c2ecf20Sopenharmony_ci	do {								\
308c2ecf20Sopenharmony_ci		u64 __val = (u64)(v);					\
318c2ecf20Sopenharmony_ci		asm volatile(ALTERNATIVE(__msr_s(r##nvh, "%x0"),	\
328c2ecf20Sopenharmony_ci					 __msr_s(r##vh, "%x0"),		\
338c2ecf20Sopenharmony_ci					 ARM64_HAS_VIRT_HOST_EXTN)	\
348c2ecf20Sopenharmony_ci					 : : "rZ" (__val));		\
358c2ecf20Sopenharmony_ci	} while (0)
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci/*
388c2ecf20Sopenharmony_ci * Unified accessors for registers that have a different encoding
398c2ecf20Sopenharmony_ci * between VHE and non-VHE. They must be specified without their "ELx"
408c2ecf20Sopenharmony_ci * encoding, but with the SYS_ prefix, as defined in asm/sysreg.h.
418c2ecf20Sopenharmony_ci */
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci#define read_sysreg_el0(r)	read_sysreg_elx(r, _EL0, _EL02)
448c2ecf20Sopenharmony_ci#define write_sysreg_el0(v,r)	write_sysreg_elx(v, r, _EL0, _EL02)
458c2ecf20Sopenharmony_ci#define read_sysreg_el1(r)	read_sysreg_elx(r, _EL1, _EL12)
468c2ecf20Sopenharmony_ci#define write_sysreg_el1(v,r)	write_sysreg_elx(v, r, _EL1, _EL12)
478c2ecf20Sopenharmony_ci#define read_sysreg_el2(r)	read_sysreg_elx(r, _EL2, _EL1)
488c2ecf20Sopenharmony_ci#define write_sysreg_el2(v,r)	write_sysreg_elx(v, r, _EL2, _EL1)
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci/*
518c2ecf20Sopenharmony_ci * Without an __arch_swab32(), we fall back to ___constant_swab32(), but the
528c2ecf20Sopenharmony_ci * static inline can allow the compiler to out-of-line this. KVM always wants
538c2ecf20Sopenharmony_ci * the macro version as its always inlined.
548c2ecf20Sopenharmony_ci */
558c2ecf20Sopenharmony_ci#define __kvm_swab32(x)	___constant_swab32(x)
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ciint __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu);
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_civoid __vgic_v3_save_state(struct vgic_v3_cpu_if *cpu_if);
608c2ecf20Sopenharmony_civoid __vgic_v3_restore_state(struct vgic_v3_cpu_if *cpu_if);
618c2ecf20Sopenharmony_civoid __vgic_v3_activate_traps(struct vgic_v3_cpu_if *cpu_if);
628c2ecf20Sopenharmony_civoid __vgic_v3_deactivate_traps(struct vgic_v3_cpu_if *cpu_if);
638c2ecf20Sopenharmony_civoid __vgic_v3_save_aprs(struct vgic_v3_cpu_if *cpu_if);
648c2ecf20Sopenharmony_civoid __vgic_v3_restore_aprs(struct vgic_v3_cpu_if *cpu_if);
658c2ecf20Sopenharmony_ciint __vgic_v3_perform_cpuif_access(struct kvm_vcpu *vcpu);
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci#ifdef __KVM_NVHE_HYPERVISOR__
688c2ecf20Sopenharmony_civoid __timer_enable_traps(struct kvm_vcpu *vcpu);
698c2ecf20Sopenharmony_civoid __timer_disable_traps(struct kvm_vcpu *vcpu);
708c2ecf20Sopenharmony_ci#endif
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci#ifdef __KVM_NVHE_HYPERVISOR__
738c2ecf20Sopenharmony_civoid __sysreg_save_state_nvhe(struct kvm_cpu_context *ctxt);
748c2ecf20Sopenharmony_civoid __sysreg_restore_state_nvhe(struct kvm_cpu_context *ctxt);
758c2ecf20Sopenharmony_ci#else
768c2ecf20Sopenharmony_civoid sysreg_save_host_state_vhe(struct kvm_cpu_context *ctxt);
778c2ecf20Sopenharmony_civoid sysreg_restore_host_state_vhe(struct kvm_cpu_context *ctxt);
788c2ecf20Sopenharmony_civoid sysreg_save_guest_state_vhe(struct kvm_cpu_context *ctxt);
798c2ecf20Sopenharmony_civoid sysreg_restore_guest_state_vhe(struct kvm_cpu_context *ctxt);
808c2ecf20Sopenharmony_ci#endif
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_civoid __debug_switch_to_guest(struct kvm_vcpu *vcpu);
838c2ecf20Sopenharmony_civoid __debug_switch_to_host(struct kvm_vcpu *vcpu);
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci#ifdef __KVM_NVHE_HYPERVISOR__
868c2ecf20Sopenharmony_civoid __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu);
878c2ecf20Sopenharmony_civoid __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu);
888c2ecf20Sopenharmony_ci#endif
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_civoid __fpsimd_save_state(struct user_fpsimd_state *fp_regs);
918c2ecf20Sopenharmony_civoid __fpsimd_restore_state(struct user_fpsimd_state *fp_regs);
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci#ifndef __KVM_NVHE_HYPERVISOR__
948c2ecf20Sopenharmony_civoid activate_traps_vhe_load(struct kvm_vcpu *vcpu);
958c2ecf20Sopenharmony_civoid deactivate_traps_vhe_put(void);
968c2ecf20Sopenharmony_ci#endif
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ciu64 __guest_enter(struct kvm_vcpu *vcpu);
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_civoid __noreturn hyp_panic(void);
1018c2ecf20Sopenharmony_ci#ifdef __KVM_NVHE_HYPERVISOR__
1028c2ecf20Sopenharmony_civoid __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr,
1038c2ecf20Sopenharmony_ci			       u64 elr, u64 par);
1048c2ecf20Sopenharmony_ci#endif
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci#endif /* __ARM64_KVM_HYP_H__ */
1078c2ecf20Sopenharmony_ci
108