arch/x86/kvm/vmenter.h

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

File Facts

System
Linux kernel
Corpus path
arch/x86/kvm/vmenter.h
Extension
.h
Size
2900 bytes
Lines
112
Domain
Architecture Layer
Bucket
arch/x86
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

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

#ifndef __KVM_X86_VMENTER_H
#define __KVM_X86_VMENTER_H

#include <asm/kvm_vcpu_regs.h>

#define KVM_ENTER_VMRESUME			BIT(0)
#define KVM_ENTER_SAVE_SPEC_CTRL		BIT(1)
#define KVM_ENTER_CLEAR_CPU_BUFFERS_FOR_MMIO	BIT(2)

#ifdef __ASSEMBLER__
.macro RESTORE_GUEST_SPEC_CTRL_BODY guest_spec_ctrl:req, label:req
	/*
	 * SPEC_CTRL handling: if the guest's SPEC_CTRL value differs from the
	 * host's, write the MSR.  This is kept out-of-line so that the common
	 * case does not have to jump.
	 *
	 * IMPORTANT: To avoid RSB underflow attacks and any other nastiness,
	 * there must not be any returns or indirect branches between this code
	 * and vmentry.
	 */
#ifdef CONFIG_X86_64
	mov \guest_spec_ctrl, %rdx
	cmp PER_CPU_VAR(x86_spec_ctrl_current), %rdx
	je \label
	movl %edx, %eax
	shr $32, %rdx
#else
	mov \guest_spec_ctrl, %eax
	mov PER_CPU_VAR(x86_spec_ctrl_current), %ecx
	xor %eax, %ecx
	mov 4 + \guest_spec_ctrl, %edx
	mov PER_CPU_VAR(x86_spec_ctrl_current + 4), %esi
	xor %edx, %esi
	or %esi, %ecx
	je \label
#endif
	mov $MSR_IA32_SPEC_CTRL, %ecx
	wrmsr
.endm

.macro RESTORE_HOST_SPEC_CTRL_BODY guest_spec_ctrl:req, enter_flags:req, label:req
	/* Same for after vmexit.  */
	mov $MSR_IA32_SPEC_CTRL, %ecx

	/*
	 * Load the value that the guest had written into MSR_IA32_SPEC_CTRL,
	 * if it was not intercepted during guest execution.
	 */
	testl $KVM_ENTER_SAVE_SPEC_CTRL, \enter_flags
	jz 998f
	rdmsr
	movl %eax, \guest_spec_ctrl
	movl %edx, 4 + \guest_spec_ctrl
998:
	/* Now restore the host value of the MSR if different from the guest's.  */
#ifdef CONFIG_X86_64
	mov PER_CPU_VAR(x86_spec_ctrl_current), %rdx
	cmp \guest_spec_ctrl, %rdx
	/*
	 * For legacy IBRS, the IBRS bit always needs to be written after
	 * transitioning from a less privileged predictor mode, regardless of
	 * whether the guest/host values differ.
	 */
	ALTERNATIVE __stringify(je \label), "", X86_FEATURE_KERNEL_IBRS
	movl %edx, %eax
	shr $32, %rdx
#else
	mov PER_CPU_VAR(x86_spec_ctrl_current), %eax
	mov \guest_spec_ctrl, %esi
	xor %eax, %esi
	mov PER_CPU_VAR(x86_spec_ctrl_current + 4), %edx
	mov 4 + \guest_spec_ctrl, %edi
	xor %edx, %edi
	or %edi, %esi
	ALTERNATIVE __stringify(je \label), "", X86_FEATURE_KERNEL_IBRS
#endif
	wrmsr
.endm

#define WORD_SIZE (BITS_PER_LONG / 8)

.macro LOAD_REGS src:req, regs_ofs:req, regs:vararg
.irp reg, \regs
	REG_NUM reg_num \reg
	mov (\regs_ofs + reg_num * WORD_SIZE)(\src), \reg
.endr
.endm

.macro STORE_REGS dst:req, regs_ofs:req, regs:vararg
.irp reg, \regs

Annotation

Implementation Notes