GNU Linux-libre 5.15.137-gnu
[releases.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
8 #define WORD_SIZE (BITS_PER_LONG / 8)
9
10 /* Intentionally omit RAX as it's context switched by hardware */
11 #define VCPU_RCX        __VCPU_REGS_RCX * WORD_SIZE
12 #define VCPU_RDX        __VCPU_REGS_RDX * WORD_SIZE
13 #define VCPU_RBX        __VCPU_REGS_RBX * WORD_SIZE
14 /* Intentionally omit RSP as it's context switched by hardware */
15 #define VCPU_RBP        __VCPU_REGS_RBP * WORD_SIZE
16 #define VCPU_RSI        __VCPU_REGS_RSI * WORD_SIZE
17 #define VCPU_RDI        __VCPU_REGS_RDI * WORD_SIZE
18
19 #ifdef CONFIG_X86_64
20 #define VCPU_R8         __VCPU_REGS_R8  * WORD_SIZE
21 #define VCPU_R9         __VCPU_REGS_R9  * WORD_SIZE
22 #define VCPU_R10        __VCPU_REGS_R10 * WORD_SIZE
23 #define VCPU_R11        __VCPU_REGS_R11 * WORD_SIZE
24 #define VCPU_R12        __VCPU_REGS_R12 * WORD_SIZE
25 #define VCPU_R13        __VCPU_REGS_R13 * WORD_SIZE
26 #define VCPU_R14        __VCPU_REGS_R14 * WORD_SIZE
27 #define VCPU_R15        __VCPU_REGS_R15 * WORD_SIZE
28 #endif
29
30 .section .noinstr.text, "ax"
31
32 /**
33  * __svm_vcpu_run - Run a vCPU via a transition to SVM guest mode
34  * @vmcb_pa:    unsigned long
35  * @regs:       unsigned long * (to guest registers)
36  */
37 SYM_FUNC_START(__svm_vcpu_run)
38         push %_ASM_BP
39 #ifdef CONFIG_X86_64
40         push %r15
41         push %r14
42         push %r13
43         push %r12
44 #else
45         push %edi
46         push %esi
47 #endif
48         push %_ASM_BX
49
50         /* Save @regs. */
51         push %_ASM_ARG2
52
53         /* Save @vmcb. */
54         push %_ASM_ARG1
55
56         /* Move @regs to RAX. */
57         mov %_ASM_ARG2, %_ASM_AX
58
59         /* Load guest registers. */
60         mov VCPU_RCX(%_ASM_AX), %_ASM_CX
61         mov VCPU_RDX(%_ASM_AX), %_ASM_DX
62         mov VCPU_RBX(%_ASM_AX), %_ASM_BX
63         mov VCPU_RBP(%_ASM_AX), %_ASM_BP
64         mov VCPU_RSI(%_ASM_AX), %_ASM_SI
65         mov VCPU_RDI(%_ASM_AX), %_ASM_DI
66 #ifdef CONFIG_X86_64
67         mov VCPU_R8 (%_ASM_AX),  %r8
68         mov VCPU_R9 (%_ASM_AX),  %r9
69         mov VCPU_R10(%_ASM_AX), %r10
70         mov VCPU_R11(%_ASM_AX), %r11
71         mov VCPU_R12(%_ASM_AX), %r12
72         mov VCPU_R13(%_ASM_AX), %r13
73         mov VCPU_R14(%_ASM_AX), %r14
74         mov VCPU_R15(%_ASM_AX), %r15
75 #endif
76
77         /* "POP" @vmcb to RAX. */
78         pop %_ASM_AX
79
80         /* Enter guest mode */
81         sti
82
83 1:      vmrun %_ASM_AX
84
85 2:      cli
86
87 #ifdef CONFIG_RETPOLINE
88         /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */
89         FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE
90 #endif
91
92         /* "POP" @regs to RAX. */
93         pop %_ASM_AX
94
95         /* Save all guest registers.  */
96         mov %_ASM_CX,   VCPU_RCX(%_ASM_AX)
97         mov %_ASM_DX,   VCPU_RDX(%_ASM_AX)
98         mov %_ASM_BX,   VCPU_RBX(%_ASM_AX)
99         mov %_ASM_BP,   VCPU_RBP(%_ASM_AX)
100         mov %_ASM_SI,   VCPU_RSI(%_ASM_AX)
101         mov %_ASM_DI,   VCPU_RDI(%_ASM_AX)
102 #ifdef CONFIG_X86_64
103         mov %r8,  VCPU_R8 (%_ASM_AX)
104         mov %r9,  VCPU_R9 (%_ASM_AX)
105         mov %r10, VCPU_R10(%_ASM_AX)
106         mov %r11, VCPU_R11(%_ASM_AX)
107         mov %r12, VCPU_R12(%_ASM_AX)
108         mov %r13, VCPU_R13(%_ASM_AX)
109         mov %r14, VCPU_R14(%_ASM_AX)
110         mov %r15, VCPU_R15(%_ASM_AX)
111 #endif
112
113         /*
114          * Mitigate RETBleed for AMD/Hygon Zen uarch. RET should be
115          * untrained as soon as we exit the VM and are back to the
116          * kernel. This should be done before re-enabling interrupts
117          * because interrupt handlers won't sanitize 'ret' if the return is
118          * from the kernel.
119          */
120         UNTRAIN_RET
121
122         /* SRSO */
123         ALTERNATIVE "", "call entry_ibpb", X86_FEATURE_IBPB_ON_VMEXIT
124
125         /*
126          * Clear all general purpose registers except RSP and RAX to prevent
127          * speculative use of the guest's values, even those that are reloaded
128          * via the stack.  In theory, an L1 cache miss when restoring registers
129          * could lead to speculative execution with the guest's values.
130          * Zeroing XORs are dirt cheap, i.e. the extra paranoia is essentially
131          * free.  RSP and RAX are exempt as they are restored by hardware
132          * during VM-Exit.
133          */
134         xor %ecx, %ecx
135         xor %edx, %edx
136         xor %ebx, %ebx
137         xor %ebp, %ebp
138         xor %esi, %esi
139         xor %edi, %edi
140 #ifdef CONFIG_X86_64
141         xor %r8d,  %r8d
142         xor %r9d,  %r9d
143         xor %r10d, %r10d
144         xor %r11d, %r11d
145         xor %r12d, %r12d
146         xor %r13d, %r13d
147         xor %r14d, %r14d
148         xor %r15d, %r15d
149 #endif
150
151         pop %_ASM_BX
152
153 #ifdef CONFIG_X86_64
154         pop %r12
155         pop %r13
156         pop %r14
157         pop %r15
158 #else
159         pop %esi
160         pop %edi
161 #endif
162         pop %_ASM_BP
163         RET
164
165 3:      cmpb $0, kvm_rebooting
166         jne 2b
167         ud2
168
169         _ASM_EXTABLE(1b, 3b)
170
171 SYM_FUNC_END(__svm_vcpu_run)
172
173 /**
174  * __svm_sev_es_vcpu_run - Run a SEV-ES vCPU via a transition to SVM guest mode
175  * @vmcb_pa:    unsigned long
176  */
177 SYM_FUNC_START(__svm_sev_es_vcpu_run)
178         push %_ASM_BP
179 #ifdef CONFIG_X86_64
180         push %r15
181         push %r14
182         push %r13
183         push %r12
184 #else
185         push %edi
186         push %esi
187 #endif
188         push %_ASM_BX
189
190         /* Move @vmcb to RAX. */
191         mov %_ASM_ARG1, %_ASM_AX
192
193         /* Enter guest mode */
194         sti
195
196 1:      vmrun %_ASM_AX
197
198 2:      cli
199
200 #ifdef CONFIG_RETPOLINE
201         /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */
202         FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE
203 #endif
204
205         /*
206          * Mitigate RETBleed for AMD/Hygon Zen uarch. RET should be
207          * untrained as soon as we exit the VM and are back to the
208          * kernel. This should be done before re-enabling interrupts
209          * because interrupt handlers won't sanitize RET if the return is
210          * from the kernel.
211          */
212         UNTRAIN_RET
213
214         pop %_ASM_BX
215
216 #ifdef CONFIG_X86_64
217         pop %r12
218         pop %r13
219         pop %r14
220         pop %r15
221 #else
222         pop %esi
223         pop %edi
224 #endif
225         pop %_ASM_BP
226         RET
227
228 3:      cmpb $0, kvm_rebooting
229         jne 2b
230         ud2
231
232         _ASM_EXTABLE(1b, 3b)
233
234 SYM_FUNC_END(__svm_sev_es_vcpu_run)