arch/x86/hyperv/mshv_vtl_asm.S

Source file repositories/reference/linux-study-clean/arch/x86/hyperv/mshv_vtl_asm.S

File Facts

System
Linux kernel
Corpus path
arch/x86/hyperv/mshv_vtl_asm.S
Extension
.S
Size
3399 bytes
Lines
117
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 <linux/static_call_types.h>
#include <asm/asm.h>
#include <asm/asm-offsets.h>
#include <asm/frame.h>
#include "mshv-asm-offsets.h"

	.text
	.section .noinstr.text, "ax"
/*
 * void __mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0)
 *
 * This function is used to context switch between different Virtual Trust Levels.
 * It is marked as 'noinstr' to prevent against instrumentation and debugging facilities.
 * NMIs aren't a problem because the NMI handler saves/restores CR2 specifically to guard
 * against #PFs in NMI context clobbering the guest state.
 */
SYM_FUNC_START(__mshv_vtl_return_call)
	/* Push callee save registers */
	pushq %rbp
	mov %rsp, %rbp
	pushq %r12
	pushq %r13
	pushq %r14
	pushq %r15
	pushq %rbx

	/* register switch to VTL0 clobbers all registers except rax/rcx */
	mov %_ASM_ARG1, %rax

	/* grab rbx/rbp/rsi/rdi/r8-r15 */
	mov MSHV_VTL_CPU_CONTEXT_rbx(%rax), %rbx
	mov MSHV_VTL_CPU_CONTEXT_rbp(%rax), %rbp
	mov MSHV_VTL_CPU_CONTEXT_rsi(%rax), %rsi
	mov MSHV_VTL_CPU_CONTEXT_rdi(%rax), %rdi
	mov MSHV_VTL_CPU_CONTEXT_r8(%rax), %r8
	mov MSHV_VTL_CPU_CONTEXT_r9(%rax), %r9
	mov MSHV_VTL_CPU_CONTEXT_r10(%rax), %r10
	mov MSHV_VTL_CPU_CONTEXT_r11(%rax), %r11
	mov MSHV_VTL_CPU_CONTEXT_r12(%rax), %r12
	mov MSHV_VTL_CPU_CONTEXT_r13(%rax), %r13
	mov MSHV_VTL_CPU_CONTEXT_r14(%rax), %r14
	mov MSHV_VTL_CPU_CONTEXT_r15(%rax), %r15

	mov MSHV_VTL_CPU_CONTEXT_cr2(%rax), %rdx
	mov %rdx, %cr2
	mov MSHV_VTL_CPU_CONTEXT_rdx(%rax), %rdx

	/* stash host registers on stack */
	pushq %rax
	pushq %rcx

	xor %ecx, %ecx

	/* make a hypercall to switch VTL */
	call STATIC_CALL_TRAMP_STR(__mshv_vtl_return_hypercall)

	/* stash guest registers on stack, restore saved host copies */
	pushq %rax
	pushq %rcx
	mov 16(%rsp), %rcx
	mov 24(%rsp), %rax

	mov %rdx, MSHV_VTL_CPU_CONTEXT_rdx(%rax)
	mov %cr2, %rdx
	mov %rdx, MSHV_VTL_CPU_CONTEXT_cr2(%rax)
	pop MSHV_VTL_CPU_CONTEXT_rcx(%rax)
	pop MSHV_VTL_CPU_CONTEXT_rax(%rax)
	add $16, %rsp

Annotation

Implementation Notes