30
30
31
31
.section .noinstr.text, "ax"
32
32
33
- /**
34
- * vmx_vmenter - VM-Enter the current loaded VMCS
35
- *
36
- * %RFLAGS.ZF: !VMCS.LAUNCHED, i.e. controls VMLAUNCH vs. VMRESUME
37
- *
38
- * Returns:
39
- * %RFLAGS.CF is set on VM-Fail Invalid
40
- * %RFLAGS.ZF is set on VM-Fail Valid
41
- * %RFLAGS.{CF,ZF} are cleared on VM-Success, i.e. VM-Exit
42
- *
43
- * Note that VMRESUME/VMLAUNCH fall-through and return directly if
44
- * they VM-Fail, whereas a successful VM-Enter + VM-Exit will jump
45
- * to vmx_vmexit.
46
- */
47
- SYM_FUNC_START_LOCAL (vmx_vmenter)
48
- /* EFLAGS.ZF is set if VMCS.LAUNCHED == 0 */
49
- je 2f
50
-
51
- 1: vmresume
52
- RET
53
-
54
- 2: vmlaunch
55
- RET
56
-
57
- 3: cmpb $0 , kvm_rebooting
58
- je 4f
59
- RET
60
- 4: ud2
61
-
62
- _ASM_EXTABLE(1b, 3b)
63
- _ASM_EXTABLE(2b, 3b)
64
-
65
- SYM_FUNC_END(vmx_vmenter)
66
-
67
- /**
68
- * vmx_vmexit - Handle a VMX VM-Exit
69
- *
70
- * Returns:
71
- * %RFLAGS.{CF,ZF} are cleared on VM-Success, i.e. VM-Exit
72
- *
73
- * This is vmx_vmenter's partner in crime. On a VM-Exit, control will jump
74
- * here after hardware loads the host's state, i.e. this is the destination
75
- * referred to by VMCS.HOST_RIP.
76
- */
77
- SYM_FUNC_START(vmx_vmexit)
78
- #ifdef CONFIG_RETPOLINE
79
- ALTERNATIVE "jmp .Lvmexit_skip_rsb" , "", X86_FEATURE_RETPOLINE
80
- /* Preserve guest's RAX, it's used to stuff the RSB. */
81
- push %_ASM_AX
82
-
83
- /* IMPORTANT: Stuff the RSB immediately after VM-Exit, before RET! */
84
- FILL_RETURN_BUFFER %_ASM_AX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE
85
-
86
- /* Clear RFLAGS.CF and RFLAGS.ZF to preserve VM-Exit, i.e. !VM-Fail. */
87
- or $1 , %_ASM_AX
88
-
89
- pop %_ASM_AX
90
- .Lvmexit_skip_rsb:
91
- #endif
92
- RET
93
- SYM_FUNC_END(vmx_vmexit)
94
-
95
33
/**
96
34
* __vmx_vcpu_run - Run a vCPU via a transition to VMX guest mode
97
35
* @vmx: struct vcpu_vmx * (forwarded to vmx_update_host_rsp)
@@ -124,8 +62,7 @@ SYM_FUNC_START(__vmx_vcpu_run)
124
62
/* Copy @launched to BL, _ASM_ARG3 is volatile. */
125
63
mov %_ASM_ARG3B, %bl
126
64
127
- /* Adjust RSP to account for the CALL to vmx_vmenter(). */
128
- lea -WORD_SIZE(%_ASM_SP), %_ASM_ARG2
65
+ lea (%_ASM_SP), %_ASM_ARG2
129
66
call vmx_update_host_rsp
130
67
131
68
/* Load @regs to RAX. */
@@ -154,11 +91,37 @@ SYM_FUNC_START(__vmx_vcpu_run)
154
91
/* Load guest RAX. This kills the @regs pointer! */
155
92
mov VCPU_RAX(%_ASM_AX), %_ASM_AX
156
93
157
- /* Enter guest mode */
158
- call vmx_vmenter
94
+ /* Check EFLAGS.ZF from 'testb' above */
95
+ je .Lvmlaunch
96
+
97
+ /*
98
+ * After a successful VMRESUME/VMLAUNCH, control flow "magically"
99
+ * resumes below at 'vmx_vmexit' due to the VMCS HOST_RIP setting.
100
+ * So this isn't a typical function and objtool needs to be told to
101
+ * save the unwind state here and restore it below.
102
+ */
103
+ UNWIND_HINT_SAVE
104
+
105
+ /*
106
+ * If VMRESUME/VMLAUNCH and corresponding vmexit succeed, execution resumes at
107
+ * the 'vmx_vmexit' label below.
108
+ */
109
+ .Lvmresume:
110
+ vmresume
111
+ jmp .Lvmfail
112
+
113
+ .Lvmlaunch:
114
+ vmlaunch
115
+ jmp .Lvmfail
116
+
117
+ _ASM_EXTABLE(.Lvmresume, .Lfixup)
118
+ _ASM_EXTABLE(.Lvmlaunch, .Lfixup)
159
119
160
- /* Jump on VM-Fail. */
161
- jbe 2f
120
+ SYM_INNER_LABEL(vmx_vmexit, SYM_L_GLOBAL)
121
+
122
+ /* Restore unwind state from before the VMRESUME/VMLAUNCH. */
123
+ UNWIND_HINT_RESTORE
124
+ ENDBR
162
125
163
126
/* Temporarily save guest's RAX. */
164
127
push %_ASM_AX
@@ -185,9 +148,13 @@ SYM_FUNC_START(__vmx_vcpu_run)
185
148
mov %r15 , VCPU_R15(%_ASM_AX)
186
149
#endif
187
150
151
+ /* IMPORTANT: RSB must be stuffed before the first return. */
152
+ FILL_RETURN_BUFFER %_ASM_BX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE
153
+
188
154
/* Clear RAX to indicate VM-Exit (as opposed to VM-Fail). */
189
155
xor %eax , %eax
190
156
157
+ .Lclear_regs:
191
158
/*
192
159
* Clear all general purpose registers except RSP and RAX to prevent
193
160
* speculative use of the guest's values, even those that are reloaded
@@ -197,7 +164,7 @@ SYM_FUNC_START(__vmx_vcpu_run)
197
164
* free. RSP and RAX are exempt as RSP is restored by hardware during
198
165
* VM-Exit and RAX is explicitly loaded with 0 or 1 to return VM-Fail.
199
166
*/
200
- 1: xor %ecx , %ecx
167
+ xor %ecx , %ecx
201
168
xor %edx , %edx
202
169
xor %ebx , %ebx
203
170
xor %ebp , %ebp
@@ -216,8 +183,8 @@ SYM_FUNC_START(__vmx_vcpu_run)
216
183
217
184
/* "POP" @regs. */
218
185
add $WORD_SIZE, %_ASM_SP
219
- pop %_ASM_BX
220
186
187
+ pop %_ASM_BX
221
188
#ifdef CONFIG_X86_64
222
189
pop %r12
223
190
pop %r13
@@ -230,9 +197,15 @@ SYM_FUNC_START(__vmx_vcpu_run)
230
197
pop %_ASM_BP
231
198
RET
232
199
233
- /* VM-Fail. Out-of-line to avoid a taken Jcc after VM-Exit. */
234
- 2: mov $1 , %eax
235
- jmp 1b
200
+ .Lfixup:
201
+ cmpb $0 , kvm_rebooting
202
+ jne .Lvmfail
203
+ ud2
204
+ .Lvmfail:
205
+ /* VM-Fail: set return value to 1 */
206
+ mov $1 , %eax
207
+ jmp .Lclear_regs
208
+
236
209
SYM_FUNC_END(__vmx_vcpu_run)
237
210
238
211
0 commit comments