Skip to content

Commit 8bd200d

Browse files
jpoimboesuryasaimadhu
authored andcommitted
KVM: VMX: Flatten __vmx_vcpu_run()
Move the vmx_vm{enter,exit}() functionality into __vmx_vcpu_run(). This will make it easier to do the spec_ctrl handling before the first RET. Signed-off-by: Josh Poimboeuf <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Signed-off-by: Borislav Petkov <[email protected]>
1 parent 8faea26 commit 8bd200d

File tree

1 file changed

+46
-73
lines changed

1 file changed

+46
-73
lines changed

arch/x86/kvm/vmx/vmenter.S

Lines changed: 46 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -30,68 +30,6 @@
3030

3131
.section .noinstr.text, "ax"
3232

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-
9533
/**
9634
* __vmx_vcpu_run - Run a vCPU via a transition to VMX guest mode
9735
* @vmx: struct vcpu_vmx * (forwarded to vmx_update_host_rsp)
@@ -124,8 +62,7 @@ SYM_FUNC_START(__vmx_vcpu_run)
12462
/* Copy @launched to BL, _ASM_ARG3 is volatile. */
12563
mov %_ASM_ARG3B, %bl
12664

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
12966
call vmx_update_host_rsp
13067

13168
/* Load @regs to RAX. */
@@ -154,11 +91,37 @@ SYM_FUNC_START(__vmx_vcpu_run)
15491
/* Load guest RAX. This kills the @regs pointer! */
15592
mov VCPU_RAX(%_ASM_AX), %_ASM_AX
15693

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)
159119

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
162125

163126
/* Temporarily save guest's RAX. */
164127
push %_ASM_AX
@@ -185,9 +148,13 @@ SYM_FUNC_START(__vmx_vcpu_run)
185148
mov %r15, VCPU_R15(%_ASM_AX)
186149
#endif
187150

151+
/* IMPORTANT: RSB must be stuffed before the first return. */
152+
FILL_RETURN_BUFFER %_ASM_BX, RSB_CLEAR_LOOPS, X86_FEATURE_RETPOLINE
153+
188154
/* Clear RAX to indicate VM-Exit (as opposed to VM-Fail). */
189155
xor %eax, %eax
190156

157+
.Lclear_regs:
191158
/*
192159
* Clear all general purpose registers except RSP and RAX to prevent
193160
* speculative use of the guest's values, even those that are reloaded
@@ -197,7 +164,7 @@ SYM_FUNC_START(__vmx_vcpu_run)
197164
* free. RSP and RAX are exempt as RSP is restored by hardware during
198165
* VM-Exit and RAX is explicitly loaded with 0 or 1 to return VM-Fail.
199166
*/
200-
1: xor %ecx, %ecx
167+
xor %ecx, %ecx
201168
xor %edx, %edx
202169
xor %ebx, %ebx
203170
xor %ebp, %ebp
@@ -216,8 +183,8 @@ SYM_FUNC_START(__vmx_vcpu_run)
216183

217184
/* "POP" @regs. */
218185
add $WORD_SIZE, %_ASM_SP
219-
pop %_ASM_BX
220186

187+
pop %_ASM_BX
221188
#ifdef CONFIG_X86_64
222189
pop %r12
223190
pop %r13
@@ -230,9 +197,15 @@ SYM_FUNC_START(__vmx_vcpu_run)
230197
pop %_ASM_BP
231198
RET
232199

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+
236209
SYM_FUNC_END(__vmx_vcpu_run)
237210

238211

0 commit comments

Comments
 (0)