xref: /openbmc/linux/arch/arm64/include/asm/kvm_hyp.h (revision 57e784b4079e9499ea1bafd56a0d422252aa2401)
1caab277bSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
213720a56SMarc Zyngier /*
313720a56SMarc Zyngier  * Copyright (C) 2015 - ARM Ltd
413720a56SMarc Zyngier  * Author: Marc Zyngier <marc.zyngier@arm.com>
513720a56SMarc Zyngier  */
613720a56SMarc Zyngier 
713720a56SMarc Zyngier #ifndef __ARM64_KVM_HYP_H__
813720a56SMarc Zyngier #define __ARM64_KVM_HYP_H__
913720a56SMarc Zyngier 
1013720a56SMarc Zyngier #include <linux/compiler.h>
1113720a56SMarc Zyngier #include <linux/kvm_host.h>
121e4448c5SMarc Zyngier #include <asm/alternative.h>
1313720a56SMarc Zyngier #include <asm/sysreg.h>
1413720a56SMarc Zyngier 
15b619d9aaSAndrew Scull DECLARE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
16a0e47952SAndrew Scull DECLARE_PER_CPU(unsigned long, kvm_hyp_vector);
1763fec243SDavid Brazdil DECLARE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);
18a0e47952SAndrew Scull 
19*57e784b4SMarc Zyngier /*
20*57e784b4SMarc Zyngier  * Unified accessors for registers that have a different encoding
21*57e784b4SMarc Zyngier  * between VHE and non-VHE. They must be specified without their "ELx"
22*57e784b4SMarc Zyngier  * encoding, but with the SYS_ prefix, as defined in asm/sysreg.h.
23*57e784b4SMarc Zyngier  */
24*57e784b4SMarc Zyngier 
25*57e784b4SMarc Zyngier #if defined(__KVM_VHE_HYPERVISOR__)
26*57e784b4SMarc Zyngier 
27*57e784b4SMarc Zyngier #define read_sysreg_el0(r)	read_sysreg_s(r##_EL02)
28*57e784b4SMarc Zyngier #define write_sysreg_el0(v,r)	write_sysreg_s(v, r##_EL02)
29*57e784b4SMarc Zyngier #define read_sysreg_el1(r)	read_sysreg_s(r##_EL12)
30*57e784b4SMarc Zyngier #define write_sysreg_el1(v,r)	write_sysreg_s(v, r##_EL12)
31*57e784b4SMarc Zyngier #define read_sysreg_el2(r)	read_sysreg_s(r##_EL1)
32*57e784b4SMarc Zyngier #define write_sysreg_el2(v,r)	write_sysreg_s(v, r##_EL1)
33*57e784b4SMarc Zyngier 
34*57e784b4SMarc Zyngier #else // !__KVM_VHE_HYPERVISOR__
35*57e784b4SMarc Zyngier 
3613720a56SMarc Zyngier #define read_sysreg_elx(r,nvh,vh)					\
3713720a56SMarc Zyngier 	({								\
3813720a56SMarc Zyngier 		u64 reg;						\
39fdec2a9eSDave Martin 		asm volatile(ALTERNATIVE(__mrs_s("%0", r##nvh),	\
40be604c61SKees Cook 					 __mrs_s("%0", r##vh),		\
4113720a56SMarc Zyngier 					 ARM64_HAS_VIRT_HOST_EXTN)	\
4213720a56SMarc Zyngier 			     : "=r" (reg));				\
4313720a56SMarc Zyngier 		reg;							\
4413720a56SMarc Zyngier 	})
4513720a56SMarc Zyngier 
4613720a56SMarc Zyngier #define write_sysreg_elx(v,r,nvh,vh)					\
4713720a56SMarc Zyngier 	do {								\
4813720a56SMarc Zyngier 		u64 __val = (u64)(v);					\
49fdec2a9eSDave Martin 		asm volatile(ALTERNATIVE(__msr_s(r##nvh, "%x0"),	\
50be604c61SKees Cook 					 __msr_s(r##vh, "%x0"),		\
5113720a56SMarc Zyngier 					 ARM64_HAS_VIRT_HOST_EXTN)	\
5213720a56SMarc Zyngier 					 : : "rZ" (__val));		\
5313720a56SMarc Zyngier 	} while (0)
5413720a56SMarc Zyngier 
5513720a56SMarc Zyngier #define read_sysreg_el0(r)	read_sysreg_elx(r, _EL0, _EL02)
5613720a56SMarc Zyngier #define write_sysreg_el0(v,r)	write_sysreg_elx(v, r, _EL0, _EL02)
5713720a56SMarc Zyngier #define read_sysreg_el1(r)	read_sysreg_elx(r, _EL1, _EL12)
5813720a56SMarc Zyngier #define write_sysreg_el1(v,r)	write_sysreg_elx(v, r, _EL1, _EL12)
59fdec2a9eSDave Martin #define read_sysreg_el2(r)	read_sysreg_elx(r, _EL2, _EL1)
60fdec2a9eSDave Martin #define write_sysreg_el2(v,r)	write_sysreg_elx(v, r, _EL2, _EL1)
6113720a56SMarc Zyngier 
62*57e784b4SMarc Zyngier #endif	// __KVM_VHE_HYPERVISOR__
63*57e784b4SMarc Zyngier 
648c2d146eSJames Morse /*
658c2d146eSJames Morse  * Without an __arch_swab32(), we fall back to ___constant_swab32(), but the
668c2d146eSJames Morse  * static inline can allow the compiler to out-of-line this. KVM always wants
678c2d146eSJames Morse  * the macro version as its always inlined.
688c2d146eSJames Morse  */
698c2d146eSJames Morse #define __kvm_swab32(x)	___constant_swab32(x)
708c2d146eSJames Morse 
713272f0d0SMarc Zyngier int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu);
7213720a56SMarc Zyngier 
73fc5d1f1aSChristoffer Dall void __vgic_v3_save_state(struct vgic_v3_cpu_if *cpu_if);
74fc5d1f1aSChristoffer Dall void __vgic_v3_restore_state(struct vgic_v3_cpu_if *cpu_if);
75fc5d1f1aSChristoffer Dall void __vgic_v3_activate_traps(struct vgic_v3_cpu_if *cpu_if);
76fc5d1f1aSChristoffer Dall void __vgic_v3_deactivate_traps(struct vgic_v3_cpu_if *cpu_if);
77fc5d1f1aSChristoffer Dall void __vgic_v3_save_aprs(struct vgic_v3_cpu_if *cpu_if);
78fc5d1f1aSChristoffer Dall void __vgic_v3_restore_aprs(struct vgic_v3_cpu_if *cpu_if);
7959da1cbfSMarc Zyngier int __vgic_v3_perform_cpuif_access(struct kvm_vcpu *vcpu);
8013720a56SMarc Zyngier 
819aebdea4SDavid Brazdil #ifdef __KVM_NVHE_HYPERVISOR__
82688c50aaSChristoffer Dall void __timer_enable_traps(struct kvm_vcpu *vcpu);
83688c50aaSChristoffer Dall void __timer_disable_traps(struct kvm_vcpu *vcpu);
849aebdea4SDavid Brazdil #endif
8513720a56SMarc Zyngier 
8613aeb9b4SDavid Brazdil #ifdef __KVM_NVHE_HYPERVISOR__
874cdecabaSChristoffer Dall void __sysreg_save_state_nvhe(struct kvm_cpu_context *ctxt);
884cdecabaSChristoffer Dall void __sysreg_restore_state_nvhe(struct kvm_cpu_context *ctxt);
8913aeb9b4SDavid Brazdil #else
90f837453dSChristoffer Dall void sysreg_save_host_state_vhe(struct kvm_cpu_context *ctxt);
91f837453dSChristoffer Dall void sysreg_restore_host_state_vhe(struct kvm_cpu_context *ctxt);
92f837453dSChristoffer Dall void sysreg_save_guest_state_vhe(struct kvm_cpu_context *ctxt);
93f837453dSChristoffer Dall void sysreg_restore_guest_state_vhe(struct kvm_cpu_context *ctxt);
9413aeb9b4SDavid Brazdil #endif
9513720a56SMarc Zyngier 
96014c4c77SChristoffer Dall void __debug_switch_to_guest(struct kvm_vcpu *vcpu);
97014c4c77SChristoffer Dall void __debug_switch_to_host(struct kvm_vcpu *vcpu);
9813720a56SMarc Zyngier 
99b96b0c5dSSuzuki K Poulose #ifdef __KVM_NVHE_HYPERVISOR__
100b96b0c5dSSuzuki K Poulose void __debug_save_host_buffers_nvhe(struct kvm_vcpu *vcpu);
101b96b0c5dSSuzuki K Poulose void __debug_restore_host_buffers_nvhe(struct kvm_vcpu *vcpu);
102b96b0c5dSSuzuki K Poulose #endif
103b96b0c5dSSuzuki K Poulose 
10413720a56SMarc Zyngier void __fpsimd_save_state(struct user_fpsimd_state *fp_regs);
10513720a56SMarc Zyngier void __fpsimd_restore_state(struct user_fpsimd_state *fp_regs);
10652029198SMarc Zyngier void __sve_restore_state(void *sve_pffr, u32 *fpsr);
10713720a56SMarc Zyngier 
10809cf57ebSDavid Brazdil #ifndef __KVM_NVHE_HYPERVISOR__
109a2465629SChristoffer Dall void activate_traps_vhe_load(struct kvm_vcpu *vcpu);
1101460b4b2SFuad Tabba void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu);
11109cf57ebSDavid Brazdil #endif
112a2465629SChristoffer Dall 
113b619d9aaSAndrew Scull u64 __guest_enter(struct kvm_vcpu *vcpu);
11409cf57ebSDavid Brazdil 
115eeeee719SDavid Brazdil bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt);
116eeeee719SDavid Brazdil 
11709cf57ebSDavid Brazdil #ifdef __KVM_NVHE_HYPERVISOR__
118c4b000c3SAndrew Scull void __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr,
119c4b000c3SAndrew Scull 			       u64 elr, u64 par);
12009cf57ebSDavid Brazdil #endif
12113720a56SMarc Zyngier 
122f320bc74SQuentin Perret #ifdef __KVM_NVHE_HYPERVISOR__
123f320bc74SQuentin Perret void __pkvm_init_switch_pgd(phys_addr_t phys, unsigned long size,
124f320bc74SQuentin Perret 			    phys_addr_t pgd, void *sp, void *cont_fn);
125f320bc74SQuentin Perret int __pkvm_init(phys_addr_t phys, unsigned long size, unsigned long nr_cpus,
126f320bc74SQuentin Perret 		unsigned long *per_cpu_base, u32 hyp_va_bits);
127f320bc74SQuentin Perret void __noreturn __host_enter(struct kvm_cpu_context *host_ctxt);
128f320bc74SQuentin Perret #endif
129f320bc74SQuentin Perret 
1306c30bfb1SFuad Tabba extern u64 kvm_nvhe_sym(id_aa64pfr0_el1_sys_val);
1316c30bfb1SFuad Tabba extern u64 kvm_nvhe_sym(id_aa64pfr1_el1_sys_val);
1326c30bfb1SFuad Tabba extern u64 kvm_nvhe_sym(id_aa64isar0_el1_sys_val);
1336c30bfb1SFuad Tabba extern u64 kvm_nvhe_sym(id_aa64isar1_el1_sys_val);
134def8c222SVladimir Murzin extern u64 kvm_nvhe_sym(id_aa64isar2_el1_sys_val);
1357c419937SMarc Zyngier extern u64 kvm_nvhe_sym(id_aa64mmfr0_el1_sys_val);
1367c419937SMarc Zyngier extern u64 kvm_nvhe_sym(id_aa64mmfr1_el1_sys_val);
1376c30bfb1SFuad Tabba extern u64 kvm_nvhe_sym(id_aa64mmfr2_el1_sys_val);
1388669651cSQuentin Perret extern u64 kvm_nvhe_sym(id_aa64smfr0_el1_sys_val);
1397c419937SMarc Zyngier 
14013e248aaSWill Deacon extern unsigned long kvm_nvhe_sym(__icache_flags);
14173f38ef2SWill Deacon extern unsigned int kvm_nvhe_sym(kvm_arm_vmid_bits);
14273f38ef2SWill Deacon 
14313720a56SMarc Zyngier #endif /* __ARM64_KVM_HYP_H__ */
144