]> asedeno.scripts.mit.edu Git - linux.git/blob - arch/arm64/kvm/hyp/entry.S
treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 234
[linux.git] / arch / arm64 / kvm / hyp / entry.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2015 - ARM Ltd
4  * Author: Marc Zyngier <marc.zyngier@arm.com>
5  */
6
7 #include <linux/linkage.h>
8
9 #include <asm/asm-offsets.h>
10 #include <asm/assembler.h>
11 #include <asm/fpsimdmacros.h>
12 #include <asm/kvm.h>
13 #include <asm/kvm_arm.h>
14 #include <asm/kvm_asm.h>
15 #include <asm/kvm_mmu.h>
16 #include <asm/kvm_ptrauth.h>
17
18 #define CPU_GP_REG_OFFSET(x)    (CPU_GP_REGS + x)
19 #define CPU_XREG_OFFSET(x)      CPU_GP_REG_OFFSET(CPU_USER_PT_REGS + 8*x)
20
21         .text
22         .pushsection    .hyp.text, "ax"
23
24 .macro save_callee_saved_regs ctxt
25         stp     x19, x20, [\ctxt, #CPU_XREG_OFFSET(19)]
26         stp     x21, x22, [\ctxt, #CPU_XREG_OFFSET(21)]
27         stp     x23, x24, [\ctxt, #CPU_XREG_OFFSET(23)]
28         stp     x25, x26, [\ctxt, #CPU_XREG_OFFSET(25)]
29         stp     x27, x28, [\ctxt, #CPU_XREG_OFFSET(27)]
30         stp     x29, lr,  [\ctxt, #CPU_XREG_OFFSET(29)]
31 .endm
32
33 .macro restore_callee_saved_regs ctxt
34         ldp     x19, x20, [\ctxt, #CPU_XREG_OFFSET(19)]
35         ldp     x21, x22, [\ctxt, #CPU_XREG_OFFSET(21)]
36         ldp     x23, x24, [\ctxt, #CPU_XREG_OFFSET(23)]
37         ldp     x25, x26, [\ctxt, #CPU_XREG_OFFSET(25)]
38         ldp     x27, x28, [\ctxt, #CPU_XREG_OFFSET(27)]
39         ldp     x29, lr,  [\ctxt, #CPU_XREG_OFFSET(29)]
40 .endm
41
42 /*
43  * u64 __guest_enter(struct kvm_vcpu *vcpu,
44  *                   struct kvm_cpu_context *host_ctxt);
45  */
46 ENTRY(__guest_enter)
47         // x0: vcpu
48         // x1: host context
49         // x2-x17: clobbered by macros
50         // x18: guest context
51
52         // Store the host regs
53         save_callee_saved_regs x1
54
55         add     x18, x0, #VCPU_CONTEXT
56
57         // Macro ptrauth_switch_to_guest format:
58         //      ptrauth_switch_to_guest(guest cxt, tmp1, tmp2, tmp3)
59         // The below macro to restore guest keys is not implemented in C code
60         // as it may cause Pointer Authentication key signing mismatch errors
61         // when this feature is enabled for kernel code.
62         ptrauth_switch_to_guest x18, x0, x1, x2
63
64         // Restore guest regs x0-x17
65         ldp     x0, x1,   [x18, #CPU_XREG_OFFSET(0)]
66         ldp     x2, x3,   [x18, #CPU_XREG_OFFSET(2)]
67         ldp     x4, x5,   [x18, #CPU_XREG_OFFSET(4)]
68         ldp     x6, x7,   [x18, #CPU_XREG_OFFSET(6)]
69         ldp     x8, x9,   [x18, #CPU_XREG_OFFSET(8)]
70         ldp     x10, x11, [x18, #CPU_XREG_OFFSET(10)]
71         ldp     x12, x13, [x18, #CPU_XREG_OFFSET(12)]
72         ldp     x14, x15, [x18, #CPU_XREG_OFFSET(14)]
73         ldp     x16, x17, [x18, #CPU_XREG_OFFSET(16)]
74
75         // Restore guest regs x19-x29, lr
76         restore_callee_saved_regs x18
77
78         // Restore guest reg x18
79         ldr     x18,      [x18, #CPU_XREG_OFFSET(18)]
80
81         // Do not touch any register after this!
82         eret
83         sb
84 ENDPROC(__guest_enter)
85
86 ENTRY(__guest_exit)
87         // x0: return code
88         // x1: vcpu
89         // x2-x29,lr: vcpu regs
90         // vcpu x0-x1 on the stack
91
92         add     x1, x1, #VCPU_CONTEXT
93
94         ALTERNATIVE(nop, SET_PSTATE_PAN(1), ARM64_HAS_PAN, CONFIG_ARM64_PAN)
95
96         // Store the guest regs x2 and x3
97         stp     x2, x3,   [x1, #CPU_XREG_OFFSET(2)]
98
99         // Retrieve the guest regs x0-x1 from the stack
100         ldp     x2, x3, [sp], #16       // x0, x1
101
102         // Store the guest regs x0-x1 and x4-x18
103         stp     x2, x3,   [x1, #CPU_XREG_OFFSET(0)]
104         stp     x4, x5,   [x1, #CPU_XREG_OFFSET(4)]
105         stp     x6, x7,   [x1, #CPU_XREG_OFFSET(6)]
106         stp     x8, x9,   [x1, #CPU_XREG_OFFSET(8)]
107         stp     x10, x11, [x1, #CPU_XREG_OFFSET(10)]
108         stp     x12, x13, [x1, #CPU_XREG_OFFSET(12)]
109         stp     x14, x15, [x1, #CPU_XREG_OFFSET(14)]
110         stp     x16, x17, [x1, #CPU_XREG_OFFSET(16)]
111         str     x18,      [x1, #CPU_XREG_OFFSET(18)]
112
113         // Store the guest regs x19-x29, lr
114         save_callee_saved_regs x1
115
116         get_host_ctxt   x2, x3
117
118         // Macro ptrauth_switch_to_guest format:
119         //      ptrauth_switch_to_host(guest cxt, host cxt, tmp1, tmp2, tmp3)
120         // The below macro to save/restore keys is not implemented in C code
121         // as it may cause Pointer Authentication key signing mismatch errors
122         // when this feature is enabled for kernel code.
123         ptrauth_switch_to_host x1, x2, x3, x4, x5
124
125         // Now restore the host regs
126         restore_callee_saved_regs x2
127
128 alternative_if ARM64_HAS_RAS_EXTN
129         // If we have the RAS extensions we can consume a pending error
130         // without an unmask-SError and isb.
131         esb
132         mrs_s   x2, SYS_DISR_EL1
133         str     x2, [x1, #(VCPU_FAULT_DISR - VCPU_CONTEXT)]
134         cbz     x2, 1f
135         msr_s   SYS_DISR_EL1, xzr
136         orr     x0, x0, #(1<<ARM_EXIT_WITH_SERROR_BIT)
137 1:      ret
138 alternative_else
139         // If we have a pending asynchronous abort, now is the
140         // time to find out. From your VAXorcist book, page 666:
141         // "Threaten me not, oh Evil one!  For I speak with
142         // the power of DEC, and I command thee to show thyself!"
143         mrs     x2, elr_el2
144         mrs     x3, esr_el2
145         mrs     x4, spsr_el2
146         mov     x5, x0
147
148         dsb     sy              // Synchronize against in-flight ld/st
149         nop
150         msr     daifclr, #4     // Unmask aborts
151 alternative_endif
152
153         // This is our single instruction exception window. A pending
154         // SError is guaranteed to occur at the earliest when we unmask
155         // it, and at the latest just after the ISB.
156         .global abort_guest_exit_start
157 abort_guest_exit_start:
158
159         isb
160
161         .global abort_guest_exit_end
162 abort_guest_exit_end:
163
164         // If the exception took place, restore the EL1 exception
165         // context so that we can report some information.
166         // Merge the exception code with the SError pending bit.
167         tbz     x0, #ARM_EXIT_WITH_SERROR_BIT, 1f
168         msr     elr_el2, x2
169         msr     esr_el2, x3
170         msr     spsr_el2, x4
171         orr     x0, x0, x5
172 1:      ret
173 ENDPROC(__guest_exit)