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