KVM: SVM: restore host save area from assembly
[sfrench/cifs-2.6.git] / arch / x86 / kvm / svm / vmenter.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #include <linux/linkage.h>
3 #include <asm/asm.h>
4 #include <asm/bitsperlong.h>
5 #include <asm/kvm_vcpu_regs.h>
6 #include <asm/nospec-branch.h>
7 #include "kvm-asm-offsets.h"
8
9 #define WORD_SIZE (BITS_PER_LONG / 8)
10
11 /* Intentionally omit RAX as it's context switched by hardware */
12 #define VCPU_RCX        (SVM_vcpu_arch_regs + __VCPU_REGS_RCX * WORD_SIZE)
13 #define VCPU_RDX        (SVM_vcpu_arch_regs + __VCPU_REGS_RDX * WORD_SIZE)
14 #define VCPU_RBX        (SVM_vcpu_arch_regs + __VCPU_REGS_RBX * WORD_SIZE)
15 /* Intentionally omit RSP as it's context switched by hardware */
16 #define VCPU_RBP        (SVM_vcpu_arch_regs + __VCPU_REGS_RBP * WORD_SIZE)
17 #define VCPU_RSI        (SVM_vcpu_arch_regs + __VCPU_REGS_RSI * WORD_SIZE)
18 #define VCPU_RDI        (SVM_vcpu_arch_regs + __VCPU_REGS_RDI * WORD_SIZE)
19
20 #ifdef CONFIG_X86_64
21 #define VCPU_R8         (SVM_vcpu_arch_regs + __VCPU_REGS_R8  * WORD_SIZE)
22 #define VCPU_R9         (SVM_vcpu_arch_regs + __VCPU_REGS_R9  * WORD_SIZE)
23 #define VCPU_R10        (SVM_vcpu_arch_regs + __VCPU_REGS_R10 * WORD_SIZE)
24 #define VCPU_R11        (SVM_vcpu_arch_regs + __VCPU_REGS_R11 * WORD_SIZE)
25 #define VCPU_R12        (SVM_vcpu_arch_regs + __VCPU_REGS_R12 * WORD_SIZE)
26 #define VCPU_R13        (SVM_vcpu_arch_regs + __VCPU_REGS_R13 * WORD_SIZE)
27 #define VCPU_R14        (SVM_vcpu_arch_regs + __VCPU_REGS_R14 * WORD_SIZE)
28 #define VCPU_R15        (SVM_vcpu_arch_regs + __VCPU_REGS_R15 * WORD_SIZE)
29 #endif
30
31 #define SVM_vmcb01_pa   (SVM_vmcb01 + KVM_VMCB_pa)
32
33 .section .noinstr.text, "ax"
34
35 /**
36  * __svm_vcpu_run - Run a vCPU via a transition to SVM guest mode
37  * @svm:        struct vcpu_svm *
38  */
39 SYM_FUNC_START(__svm_vcpu_run)
40         push %_ASM_BP
41 #ifdef CONFIG_X86_64
42         push %r15
43         push %r14
44         push %r13
45         push %r12
46 #else
47         push %edi
48         push %esi
49 #endif
50         push %_ASM_BX
51
52         /*
53          * Save variables needed after vmexit on the stack, in inverse
54          * order compared to when they are needed.
55          */
56
57         /* Needed to restore access to percpu variables.  */
58         __ASM_SIZE(push) PER_CPU_VAR(svm_data + SD_save_area_pa)
59
60         /* Save @svm. */
61         push %_ASM_ARG1
62
63 .ifnc _ASM_ARG1, _ASM_DI
64         /* Move @svm to RDI. */
65         mov %_ASM_ARG1, %_ASM_DI
66 .endif
67
68         /*
69          * Use a single vmcb (vmcb01 because it's always valid) for
70          * context switching guest state via VMLOAD/VMSAVE, that way
71          * the state doesn't need to be copied between vmcb01 and
72          * vmcb02 when switching vmcbs for nested virtualization.
73          */
74         mov SVM_vmcb01_pa(%_ASM_DI), %_ASM_AX
75 1:      vmload %_ASM_AX
76 2:
77
78         /* Get svm->current_vmcb->pa into RAX. */
79         mov SVM_current_vmcb(%_ASM_DI), %_ASM_AX
80         mov KVM_VMCB_pa(%_ASM_AX), %_ASM_AX
81
82         /* Load guest registers. */
83         mov VCPU_RCX(%_ASM_DI), %_ASM_CX
84         mov VCPU_RDX(%_ASM_DI), %_ASM_DX
85         mov VCPU_RBX(%_ASM_DI), %_ASM_BX
86         mov VCPU_RBP(%_ASM_DI), %_ASM_BP
87         mov VCPU_RSI(%_ASM_DI), %_ASM_SI
88 #ifdef CONFIG_X86_64
89         mov VCPU_R8 (%_ASM_DI),  %r8
90         mov VCPU_R9 (%_ASM_DI),  %r9
91         mov VCPU_R10(%_ASM_DI), %r10
92         mov VCPU_R11(%_ASM_DI), %r11
93         mov VCPU_R12(%_ASM_DI), %r12
94         mov VCPU_R13(%_ASM_DI), %r13
95         mov VCPU_R14(%_ASM_DI), %r14
96         mov VCPU_R15(%_ASM_DI), %r15
97 #endif
98         mov VCPU_RDI(%_ASM_DI), %_ASM_DI
99
100         /* Enter guest mode */
101         sti
102
103 3:      vmrun %_ASM_AX
104 4:
105         cli
106
107         /* Pop @svm to RAX while it's the only available register. */
108         pop %_ASM_AX
109
110         /* Save all guest registers.  */
111         mov %_ASM_CX,   VCPU_RCX(%_ASM_AX)
112         mov %_ASM_DX,   VCPU_RDX(%_ASM_AX)
113         mov %_ASM_BX,   VCPU_RBX(%_ASM_AX)
114         mov %_ASM_BP,   VCPU_RBP(%_ASM_AX)
115         mov %_ASM_SI,   VCPU_RSI(%_ASM_AX)
116         mov %_ASM_DI,   VCPU_RDI(%_ASM_AX)
117 #ifdef CONFIG_X86_64
118         mov %r8,  VCPU_R8 (%_ASM_AX)
119         mov %r9,  VCPU_R9 (%_ASM_AX)
120         mov %r10, VCPU_R10(%_ASM_AX)
121         mov %r11, VCPU_R11(%_ASM_AX)
122         mov %r12, VCPU_R12(%_ASM_AX)
123         mov %r13, VCPU_R13(%_ASM_AX)
124         mov %r14, VCPU_R14(%_ASM_AX)
125         mov %r15, VCPU_R15(%_ASM_AX)
126 #endif
127
128         /* @svm can stay in RDI from now on.  */
129         mov %_ASM_AX, %_ASM_DI
130
131         mov SVM_vmcb01_pa(%_ASM_DI), %_ASM_AX
132 5:      vmsave %_ASM_AX
133 6:
134
135         /* Restores GSBASE among other things, allowing access to percpu data.  */
136         pop %_ASM_AX
137 7:      vmload %_ASM_AX
138 8:
139
140 #ifdef CONFIG_RETPOLINE
141         /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */
142         FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE
143 #endif
144
145         /*
146          * Mitigate RETBleed for AMD/Hygon Zen uarch. RET should be
147          * untrained as soon as we exit the VM and are back to the
148          * kernel. This should be done before re-enabling interrupts
149          * because interrupt handlers won't sanitize 'ret' if the return is
150          * from the kernel.
151          */
152         UNTRAIN_RET
153
154         /*
155          * Clear all general purpose registers except RSP and RAX to prevent
156          * speculative use of the guest's values, even those that are reloaded
157          * via the stack.  In theory, an L1 cache miss when restoring registers
158          * could lead to speculative execution with the guest's values.
159          * Zeroing XORs are dirt cheap, i.e. the extra paranoia is essentially
160          * free.  RSP and RAX are exempt as they are restored by hardware
161          * during VM-Exit.
162          */
163         xor %ecx, %ecx
164         xor %edx, %edx
165         xor %ebx, %ebx
166         xor %ebp, %ebp
167         xor %esi, %esi
168         xor %edi, %edi
169 #ifdef CONFIG_X86_64
170         xor %r8d,  %r8d
171         xor %r9d,  %r9d
172         xor %r10d, %r10d
173         xor %r11d, %r11d
174         xor %r12d, %r12d
175         xor %r13d, %r13d
176         xor %r14d, %r14d
177         xor %r15d, %r15d
178 #endif
179
180         pop %_ASM_BX
181
182 #ifdef CONFIG_X86_64
183         pop %r12
184         pop %r13
185         pop %r14
186         pop %r15
187 #else
188         pop %esi
189         pop %edi
190 #endif
191         pop %_ASM_BP
192         RET
193
194 10:     cmpb $0, kvm_rebooting
195         jne 2b
196         ud2
197 30:     cmpb $0, kvm_rebooting
198         jne 4b
199         ud2
200 50:     cmpb $0, kvm_rebooting
201         jne 6b
202         ud2
203 70:     cmpb $0, kvm_rebooting
204         jne 8b
205         ud2
206
207         _ASM_EXTABLE(1b, 10b)
208         _ASM_EXTABLE(3b, 30b)
209         _ASM_EXTABLE(5b, 50b)
210         _ASM_EXTABLE(7b, 70b)
211
212 SYM_FUNC_END(__svm_vcpu_run)
213
214 /**
215  * __svm_sev_es_vcpu_run - Run a SEV-ES vCPU via a transition to SVM guest mode
216  * @svm:        struct vcpu_svm *
217  */
218 SYM_FUNC_START(__svm_sev_es_vcpu_run)
219         push %_ASM_BP
220 #ifdef CONFIG_X86_64
221         push %r15
222         push %r14
223         push %r13
224         push %r12
225 #else
226         push %edi
227         push %esi
228 #endif
229         push %_ASM_BX
230
231         /* Get svm->current_vmcb->pa into RAX. */
232         mov SVM_current_vmcb(%_ASM_ARG1), %_ASM_AX
233         mov KVM_VMCB_pa(%_ASM_AX), %_ASM_AX
234
235         /* Enter guest mode */
236         sti
237
238 1:      vmrun %_ASM_AX
239
240 2:      cli
241
242 #ifdef CONFIG_RETPOLINE
243         /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */
244         FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE
245 #endif
246
247         /*
248          * Mitigate RETBleed for AMD/Hygon Zen uarch. RET should be
249          * untrained as soon as we exit the VM and are back to the
250          * kernel. This should be done before re-enabling interrupts
251          * because interrupt handlers won't sanitize RET if the return is
252          * from the kernel.
253          */
254         UNTRAIN_RET
255
256         pop %_ASM_BX
257
258 #ifdef CONFIG_X86_64
259         pop %r12
260         pop %r13
261         pop %r14
262         pop %r15
263 #else
264         pop %esi
265         pop %edi
266 #endif
267         pop %_ASM_BP
268         RET
269
270 3:      cmpb $0, kvm_rebooting
271         jne 2b
272         ud2
273
274         _ASM_EXTABLE(1b, 3b)
275
276 SYM_FUNC_END(__svm_sev_es_vcpu_run)