arch/x86/kvm/vmx/vmenter.S

Source file repositories/reference/linux-study-clean/arch/x86/kvm/vmx/vmenter.S

File Facts

System
Linux kernel
Corpus path
arch/x86/kvm/vmx/vmenter.S
Extension
.S
Size
7489 bytes
Lines
275
Domain
Architecture Layer
Bucket
arch/x86
Inferred role
Architecture Layer: arch/x86
Status
atlas-only

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/linkage.h>
#include <asm/asm.h>
#include <asm/bitsperlong.h>
#include <asm/nospec-branch.h>
#include <asm/percpu.h>
#include <asm/segment.h>
#include "kvm-asm-offsets.h"
#include "vmenter.h"

.section .noinstr.text, "ax"

/**
 * __vmx_vcpu_run - Run a vCPU via a transition to VMX guest mode
 * @vmx:	struct vcpu_vmx *
 * @flags:	KVM_ENTER_VMRESUME:	use VMRESUME instead of VMLAUNCH
 *		KVM_ENTER_SAVE_SPEC_CTRL: save guest SPEC_CTRL into vmx->spec_ctrl
 *		KVM_ENTER_CLEAR_CPU_BUFFERS_FOR_MMIO: vCPU can access host MMIO
 *
 * Returns:
 *	0 on VM-Exit, 1 on VM-Fail
 */
SYM_FUNC_START(__vmx_vcpu_run)
	push %_ASM_BP
	mov  %_ASM_SP, %_ASM_BP
#ifdef CONFIG_X86_64
	push %r15
	push %r14
	push %r13
	push %r12
#else
	push %edi
	push %esi
#endif
	push %_ASM_BX

	/* Save @vmx for SPEC_CTRL handling */
	push %_ASM_ARG1

	/* Save @flags (used for VMLAUNCH vs. VMRESUME and mitigations). */
	push %_ASM_ARG2

	lea (%_ASM_SP), %_ASM_ARG2
	call vmx_update_host_rsp

	/* Reload @vmx, _ASM_ARG1 may be modified by vmx_update_host_rsp().  */
	mov WORD_SIZE(%_ASM_SP), %_ASM_DI

	/*
	 * Unlike AMD there's no V_SPEC_CTRL here, so do not leave the body
	 * out of line.  Clobbers RAX, RCX, RDX, RSI.
	 */
	ALTERNATIVE "jmp .Lspec_ctrl_guest_done", "", X86_FEATURE_MSR_SPEC_CTRL
	RESTORE_GUEST_SPEC_CTRL_BODY VMX_spec_ctrl(%_ASM_DI), .Lspec_ctrl_guest_done
.Lspec_ctrl_guest_done:

	/*
	 * Since vmentry is serializing on affected CPUs, there's no need for
	 * an LFENCE to stop speculation from skipping the wrmsr.
	 */

	/*
	 * Load guest registers.  Don't clobber flags. Intentionally omit
	 * %_ASM_SP as it's context switched by hardware
	 */
	LOAD_REGS %_ASM_DI, VMX_vcpu_arch_regs, \
		  %_ASM_AX, %_ASM_CX, %_ASM_DX, %_ASM_BX, %_ASM_BP, %_ASM_SI
#ifdef CONFIG_X86_64
	LOAD_REGS %_ASM_DI, VMX_vcpu_arch_regs, \
		  %r8, %r9, %r10, %r11, %r12, %r13, %r14, %r15
#endif

Annotation

Implementation Notes