mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-01-11 17:10:13 +00:00
Provide an interface for Virtual Machine Monitor like OpenVMM and its use as OpenHCL paravisor to control VTL0 (Virtual trust Level). Expose devices and support IOCTLs for features like VTL creation, VTL0 memory management, context switch, making hypercalls, mapping VTL0 address space to VTL2 userspace, getting new VMBus messages and channel events in VTL2 etc. Co-developed-by: Roman Kisel <romank@linux.microsoft.com> Signed-off-by: Roman Kisel <romank@linux.microsoft.com> Co-developed-by: Saurabh Sengar <ssengar@linux.microsoft.com> Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com> Reviewed-by: Michael Kelley <mhklinux@outlook.com> Signed-off-by: Naman Jain <namjain@linux.microsoft.com> Signed-off-by: Wei Liu <wei.liu@kernel.org>
117 lines
3.3 KiB
ArmAsm
117 lines
3.3 KiB
ArmAsm
/* SPDX-License-Identifier: GPL-2.0
|
|
*
|
|
* Assembly level code for mshv_vtl VTL transition
|
|
*
|
|
* Copyright (c) 2025, Microsoft Corporation.
|
|
*
|
|
* Author:
|
|
* Naman Jain <namjain@microsoft.com>
|
|
*/
|
|
|
|
#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
|
|
|
|
/* save rbx/rbp/rsi/rdi/r8-r15 */
|
|
mov %rbx, MSHV_VTL_CPU_CONTEXT_rbx(%rax)
|
|
mov %rbp, MSHV_VTL_CPU_CONTEXT_rbp(%rax)
|
|
mov %rsi, MSHV_VTL_CPU_CONTEXT_rsi(%rax)
|
|
mov %rdi, MSHV_VTL_CPU_CONTEXT_rdi(%rax)
|
|
mov %r8, MSHV_VTL_CPU_CONTEXT_r8(%rax)
|
|
mov %r9, MSHV_VTL_CPU_CONTEXT_r9(%rax)
|
|
mov %r10, MSHV_VTL_CPU_CONTEXT_r10(%rax)
|
|
mov %r11, MSHV_VTL_CPU_CONTEXT_r11(%rax)
|
|
mov %r12, MSHV_VTL_CPU_CONTEXT_r12(%rax)
|
|
mov %r13, MSHV_VTL_CPU_CONTEXT_r13(%rax)
|
|
mov %r14, MSHV_VTL_CPU_CONTEXT_r14(%rax)
|
|
mov %r15, MSHV_VTL_CPU_CONTEXT_r15(%rax)
|
|
|
|
/* pop callee-save registers r12-r15, rbx */
|
|
pop %rbx
|
|
pop %r15
|
|
pop %r14
|
|
pop %r13
|
|
pop %r12
|
|
|
|
pop %rbp
|
|
RET
|
|
SYM_FUNC_END(__mshv_vtl_return_call)
|
|
/*
|
|
* Make sure that static_call_key symbol: __SCK____mshv_vtl_return_hypercall is accessible here.
|
|
* Below code is inspired from __ADDRESSABLE(sym) macro. Symbol name is kept simple, to avoid
|
|
* naming it something like "__UNIQUE_ID_addressable___SCK____mshv_vtl_return_hypercall_662.0"
|
|
* which would otherwise have been generated by the macro.
|
|
*/
|
|
.section .discard.addressable,"aw"
|
|
.align 8
|
|
.type mshv_vtl_return_sym, @object
|
|
.size mshv_vtl_return_sym, 8
|
|
mshv_vtl_return_sym:
|
|
.quad __SCK____mshv_vtl_return_hypercall
|