1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2012-2015 - ARM Ltd
4 * Author: Marc Zyngier <marc.zyngier@arm.com>
7 #include <hyp/sysreg-sr.h>
9 #include <linux/compiler.h>
10 #include <linux/kvm_host.h>
12 #include <asm/kprobes.h>
13 #include <asm/kvm_asm.h>
14 #include <asm/kvm_emulate.h>
15 #include <asm/kvm_hyp.h>
18 * VHE: Host and guest must save mdscr_el1 and sp_el0 (and the PC and
19 * pstate, which are handled as part of the el2 return state) on every
20 * switch (sp_el0 is being dealt with in the assembly code).
21 * tpidr_el0 and tpidrro_el0 only need to be switched when going
22 * to host userspace or a different VCPU. EL1 registers only need to be
23 * switched when potentially going to run a different VCPU. The latter two
24 * classes are handled as part of kvm_arch_vcpu_load and kvm_arch_vcpu_put.
27 void sysreg_save_host_state_vhe(struct kvm_cpu_context *ctxt)
29 __sysreg_save_common_state(ctxt);
31 NOKPROBE_SYMBOL(sysreg_save_host_state_vhe);
33 void sysreg_save_guest_state_vhe(struct kvm_cpu_context *ctxt)
35 __sysreg_save_common_state(ctxt);
36 __sysreg_save_el2_return_state(ctxt);
38 NOKPROBE_SYMBOL(sysreg_save_guest_state_vhe);
40 void sysreg_restore_host_state_vhe(struct kvm_cpu_context *ctxt)
42 __sysreg_restore_common_state(ctxt);
44 NOKPROBE_SYMBOL(sysreg_restore_host_state_vhe);
46 void sysreg_restore_guest_state_vhe(struct kvm_cpu_context *ctxt)
48 __sysreg_restore_common_state(ctxt);
49 __sysreg_restore_el2_return_state(ctxt);
51 NOKPROBE_SYMBOL(sysreg_restore_guest_state_vhe);
54 * kvm_vcpu_load_sysregs_vhe - Load guest system registers to the physical CPU
56 * @vcpu: The VCPU pointer
58 * Load system registers that do not affect the host's execution, for
59 * example EL1 system registers on a VHE system where the host kernel
60 * runs at EL2. This function is called from KVM's vcpu_load() function
61 * and loading system register state early avoids having to load them on
62 * every entry to the VM.
64 void kvm_vcpu_load_sysregs_vhe(struct kvm_vcpu *vcpu)
66 struct kvm_cpu_context *guest_ctxt = &vcpu->arch.ctxt;
67 struct kvm_cpu_context *host_ctxt;
69 host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
70 __sysreg_save_user_state(host_ctxt);
73 * Load guest EL1 and user state
75 * We must restore the 32-bit state before the sysregs, thanks
76 * to erratum #852523 (Cortex-A57) or #853709 (Cortex-A72).
78 __sysreg32_restore_state(vcpu);
79 __sysreg_restore_user_state(guest_ctxt);
80 __sysreg_restore_el1_state(guest_ctxt);
82 vcpu->arch.sysregs_loaded_on_cpu = true;
84 activate_traps_vhe_load(vcpu);
88 * kvm_vcpu_put_sysregs_vhe - Restore host system registers to the physical CPU
90 * @vcpu: The VCPU pointer
92 * Save guest system registers that do not affect the host's execution, for
93 * example EL1 system registers on a VHE system where the host kernel
94 * runs at EL2. This function is called from KVM's vcpu_put() function
95 * and deferring saving system register state until we're no longer running the
96 * VCPU avoids having to save them on every exit from the VM.
98 void kvm_vcpu_put_sysregs_vhe(struct kvm_vcpu *vcpu)
100 struct kvm_cpu_context *guest_ctxt = &vcpu->arch.ctxt;
101 struct kvm_cpu_context *host_ctxt;
103 host_ctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
104 deactivate_traps_vhe_put(vcpu);
106 __sysreg_save_el1_state(guest_ctxt);
107 __sysreg_save_user_state(guest_ctxt);
108 __sysreg32_save_state(vcpu);
110 /* Restore host user state */
111 __sysreg_restore_user_state(host_ctxt);
113 vcpu->arch.sysregs_loaded_on_cpu = false;