Drivers: hv: Introduce mshv_vtl driver
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>pull/1354/merge
parent
cffe9f58de
commit
7bfe3b8ea6
|
|
@ -1,7 +1,12 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-y := hv_init.o mmu.o nested.o irqdomain.o ivm.o
|
||||
obj-$(CONFIG_X86_64) += hv_apic.o
|
||||
obj-$(CONFIG_HYPERV_VTL_MODE) += hv_vtl.o
|
||||
obj-$(CONFIG_HYPERV_VTL_MODE) += hv_vtl.o mshv_vtl_asm.o
|
||||
|
||||
$(obj)/mshv_vtl_asm.o: $(obj)/mshv-asm-offsets.h
|
||||
|
||||
$(obj)/mshv-asm-offsets.h: $(obj)/mshv-asm-offsets.s FORCE
|
||||
$(call filechk,offsets,__MSHV_ASM_OFFSETS_H__)
|
||||
|
||||
ifdef CONFIG_X86_64
|
||||
obj-$(CONFIG_PARAVIRT_SPINLOCKS) += hv_spinlock.o
|
||||
|
|
@ -12,3 +17,6 @@ obj-$(CONFIG_PARAVIRT_SPINLOCKS) += hv_spinlock.o
|
|||
obj-$(CONFIG_CRASH_DUMP) += hv_crash.o hv_trampoline.o
|
||||
endif
|
||||
endif
|
||||
|
||||
targets += mshv-asm-offsets.s
|
||||
clean-files += mshv-asm-offsets.h
|
||||
|
|
|
|||
|
|
@ -9,12 +9,17 @@
|
|||
#include <asm/apic.h>
|
||||
#include <asm/boot.h>
|
||||
#include <asm/desc.h>
|
||||
#include <asm/fpu/api.h>
|
||||
#include <asm/fpu/types.h>
|
||||
#include <asm/i8259.h>
|
||||
#include <asm/mshyperv.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/realmode.h>
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/smap.h>
|
||||
#include <linux/export.h>
|
||||
#include <../kernel/smpboot.h>
|
||||
#include "../../kernel/fpu/legacy.h"
|
||||
|
||||
extern struct boot_params boot_params;
|
||||
static struct real_mode_header hv_vtl_real_mode_header;
|
||||
|
|
@ -249,3 +254,28 @@ int __init hv_vtl_early_init(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_STATIC_CALL_NULL(__mshv_vtl_return_hypercall, void (*)(void));
|
||||
|
||||
void mshv_vtl_return_call_init(u64 vtl_return_offset)
|
||||
{
|
||||
static_call_update(__mshv_vtl_return_hypercall,
|
||||
(void *)((u8 *)hv_hypercall_pg + vtl_return_offset));
|
||||
}
|
||||
EXPORT_SYMBOL(mshv_vtl_return_call_init);
|
||||
|
||||
void mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0)
|
||||
{
|
||||
struct hv_vp_assist_page *hvp;
|
||||
|
||||
hvp = hv_vp_assist_page[smp_processor_id()];
|
||||
hvp->vtl_ret_x64rax = vtl0->rax;
|
||||
hvp->vtl_ret_x64rcx = vtl0->rcx;
|
||||
|
||||
kernel_fpu_begin_mask(0);
|
||||
fxrstor(&vtl0->fx_state);
|
||||
__mshv_vtl_return_call(vtl0);
|
||||
fxsave(&vtl0->fx_state);
|
||||
kernel_fpu_end();
|
||||
}
|
||||
EXPORT_SYMBOL(mshv_vtl_return_call);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Generate definitions needed by assembly language modules.
|
||||
* This code generates raw asm output which is post-processed to extract
|
||||
* and format the required data.
|
||||
*
|
||||
* Copyright (c) 2025, Microsoft Corporation.
|
||||
*
|
||||
* Author:
|
||||
* Naman Jain <namjain@microsoft.com>
|
||||
*/
|
||||
#define COMPILE_OFFSETS
|
||||
|
||||
#include <linux/kbuild.h>
|
||||
#include <asm/mshyperv.h>
|
||||
|
||||
static void __used common(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_HYPERV_VTL_MODE)) {
|
||||
OFFSET(MSHV_VTL_CPU_CONTEXT_rax, mshv_vtl_cpu_context, rax);
|
||||
OFFSET(MSHV_VTL_CPU_CONTEXT_rcx, mshv_vtl_cpu_context, rcx);
|
||||
OFFSET(MSHV_VTL_CPU_CONTEXT_rdx, mshv_vtl_cpu_context, rdx);
|
||||
OFFSET(MSHV_VTL_CPU_CONTEXT_rbx, mshv_vtl_cpu_context, rbx);
|
||||
OFFSET(MSHV_VTL_CPU_CONTEXT_rbp, mshv_vtl_cpu_context, rbp);
|
||||
OFFSET(MSHV_VTL_CPU_CONTEXT_rsi, mshv_vtl_cpu_context, rsi);
|
||||
OFFSET(MSHV_VTL_CPU_CONTEXT_rdi, mshv_vtl_cpu_context, rdi);
|
||||
OFFSET(MSHV_VTL_CPU_CONTEXT_r8, mshv_vtl_cpu_context, r8);
|
||||
OFFSET(MSHV_VTL_CPU_CONTEXT_r9, mshv_vtl_cpu_context, r9);
|
||||
OFFSET(MSHV_VTL_CPU_CONTEXT_r10, mshv_vtl_cpu_context, r10);
|
||||
OFFSET(MSHV_VTL_CPU_CONTEXT_r11, mshv_vtl_cpu_context, r11);
|
||||
OFFSET(MSHV_VTL_CPU_CONTEXT_r12, mshv_vtl_cpu_context, r12);
|
||||
OFFSET(MSHV_VTL_CPU_CONTEXT_r13, mshv_vtl_cpu_context, r13);
|
||||
OFFSET(MSHV_VTL_CPU_CONTEXT_r14, mshv_vtl_cpu_context, r14);
|
||||
OFFSET(MSHV_VTL_CPU_CONTEXT_r15, mshv_vtl_cpu_context, r15);
|
||||
OFFSET(MSHV_VTL_CPU_CONTEXT_cr2, mshv_vtl_cpu_context, cr2);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/* 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
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
#include <asm/paravirt.h>
|
||||
#include <asm/msr.h>
|
||||
#include <hyperv/hvhdk.h>
|
||||
#include <asm/fpu/types.h>
|
||||
|
||||
/*
|
||||
* Hyper-V always provides a single IO-APIC at this MMIO address.
|
||||
|
|
@ -269,13 +270,46 @@ static inline u64 hv_get_non_nested_msr(unsigned int reg) { return 0; }
|
|||
static inline int hv_apicid_to_vp_index(u32 apic_id) { return -EINVAL; }
|
||||
#endif /* CONFIG_HYPERV */
|
||||
|
||||
struct mshv_vtl_cpu_context {
|
||||
union {
|
||||
struct {
|
||||
u64 rax;
|
||||
u64 rcx;
|
||||
u64 rdx;
|
||||
u64 rbx;
|
||||
u64 cr2;
|
||||
u64 rbp;
|
||||
u64 rsi;
|
||||
u64 rdi;
|
||||
u64 r8;
|
||||
u64 r9;
|
||||
u64 r10;
|
||||
u64 r11;
|
||||
u64 r12;
|
||||
u64 r13;
|
||||
u64 r14;
|
||||
u64 r15;
|
||||
};
|
||||
u64 gp_regs[16];
|
||||
};
|
||||
|
||||
struct fxregs_state fx_state;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_HYPERV_VTL_MODE
|
||||
void __init hv_vtl_init_platform(void);
|
||||
int __init hv_vtl_early_init(void);
|
||||
void mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0);
|
||||
void mshv_vtl_return_call_init(u64 vtl_return_offset);
|
||||
void mshv_vtl_return_hypercall(void);
|
||||
void __mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0);
|
||||
#else
|
||||
static inline void __init hv_vtl_init_platform(void) {}
|
||||
static inline int __init hv_vtl_early_init(void) { return 0; }
|
||||
static inline void mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0) {}
|
||||
static inline void mshv_vtl_return_call_init(u64 vtl_return_offset) {}
|
||||
static inline void mshv_vtl_return_hypercall(void) {}
|
||||
static inline void __mshv_vtl_return_call(struct mshv_vtl_cpu_context *vtl0) {}
|
||||
#endif
|
||||
|
||||
#include <asm-generic/mshyperv.h>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ config HYPERV
|
|||
|
||||
config HYPERV_VTL_MODE
|
||||
bool "Enable Linux to boot in VTL context"
|
||||
depends on (X86_64 || ARM64) && HYPERV
|
||||
depends on (X86_64 && HAVE_STATIC_CALL) || ARM64
|
||||
depends on HYPERV
|
||||
depends on SMP
|
||||
default n
|
||||
help
|
||||
|
|
@ -82,4 +83,28 @@ config MSHV_ROOT
|
|||
|
||||
If unsure, say N.
|
||||
|
||||
config MSHV_VTL
|
||||
tristate "Microsoft Hyper-V VTL driver"
|
||||
depends on X86_64 && HYPERV_VTL_MODE
|
||||
depends on HYPERV_VMBUS
|
||||
# Mapping VTL0 memory to a userspace process in VTL2 is supported in OpenHCL.
|
||||
# VTL2 for OpenHCL makes use of Huge Pages to improve performance on VMs,
|
||||
# specially with large memory requirements.
|
||||
depends on TRANSPARENT_HUGEPAGE
|
||||
# MTRRs are controlled by VTL0, and are not specific to individual VTLs.
|
||||
# Therefore, do not attempt to access or modify MTRRs here.
|
||||
depends on !MTRR
|
||||
select CPUMASK_OFFSTACK
|
||||
select VIRT_XFER_TO_GUEST_WORK
|
||||
default n
|
||||
help
|
||||
Select this option to enable Hyper-V VTL driver support.
|
||||
This driver provides interfaces for Virtual Machine Manager (VMM) running in VTL2
|
||||
userspace to create VTLs and partitions, setup and manage VTL0 memory and
|
||||
allow userspace to make direct hypercalls. This also allows to map VTL0's address
|
||||
space to a usermode process in VTL2 and supports getting new VMBus messages and channel
|
||||
events in VTL2.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
endmenu
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ obj-$(CONFIG_HYPERV_VMBUS) += hv_vmbus.o
|
|||
obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o
|
||||
obj-$(CONFIG_HYPERV_BALLOON) += hv_balloon.o
|
||||
obj-$(CONFIG_MSHV_ROOT) += mshv_root.o
|
||||
obj-$(CONFIG_MSHV_VTL) += mshv_vtl.o
|
||||
|
||||
CFLAGS_hv_trace.o = -I$(src)
|
||||
CFLAGS_hv_balloon.o = -I$(src)
|
||||
|
|
@ -14,7 +15,11 @@ hv_vmbus-$(CONFIG_HYPERV_TESTING) += hv_debugfs.o
|
|||
hv_utils-y := hv_util.o hv_kvp.o hv_snapshot.o hv_utils_transport.o
|
||||
mshv_root-y := mshv_root_main.o mshv_synic.o mshv_eventfd.o mshv_irq.o \
|
||||
mshv_root_hv_call.o mshv_portid_table.o
|
||||
mshv_vtl-y := mshv_vtl_main.o
|
||||
|
||||
# Code that must be built-in
|
||||
obj-$(CONFIG_HYPERV) += hv_common.o
|
||||
obj-$(subst m,y,$(CONFIG_MSHV_ROOT)) += hv_proc.o mshv_common.o
|
||||
obj-$(subst m,y,$(CONFIG_MSHV_ROOT)) += hv_proc.o
|
||||
ifneq ($(CONFIG_MSHV_ROOT)$(CONFIG_MSHV_VTL),)
|
||||
obj-y += mshv_common.o
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
#ifndef _MSHV_VTL_H
|
||||
#define _MSHV_VTL_H
|
||||
|
||||
#include <linux/mshv.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
struct mshv_vtl_run {
|
||||
u32 cancel;
|
||||
u32 vtl_ret_action_size;
|
||||
u32 pad[2];
|
||||
char exit_message[MSHV_MAX_RUN_MSG_SIZE];
|
||||
union {
|
||||
struct mshv_vtl_cpu_context cpu_context;
|
||||
|
||||
/*
|
||||
* Reserving room for the cpu context to grow and to maintain compatibility
|
||||
* with user mode.
|
||||
*/
|
||||
char reserved[1024];
|
||||
};
|
||||
char vtl_ret_actions[MSHV_MAX_RUN_MSG_SIZE];
|
||||
};
|
||||
|
||||
#endif /* _MSHV_VTL_H */
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -885,6 +885,48 @@ struct hv_get_vp_from_apic_id_in {
|
|||
u32 apic_ids[];
|
||||
} __packed;
|
||||
|
||||
union hv_register_vsm_partition_config {
|
||||
u64 as_uint64;
|
||||
struct {
|
||||
u64 enable_vtl_protection : 1;
|
||||
u64 default_vtl_protection_mask : 4;
|
||||
u64 zero_memory_on_reset : 1;
|
||||
u64 deny_lower_vtl_startup : 1;
|
||||
u64 intercept_acceptance : 1;
|
||||
u64 intercept_enable_vtl_protection : 1;
|
||||
u64 intercept_vp_startup : 1;
|
||||
u64 intercept_cpuid_unimplemented : 1;
|
||||
u64 intercept_unrecoverable_exception : 1;
|
||||
u64 intercept_page : 1;
|
||||
u64 mbz : 51;
|
||||
} __packed;
|
||||
};
|
||||
|
||||
union hv_register_vsm_capabilities {
|
||||
u64 as_uint64;
|
||||
struct {
|
||||
u64 dr6_shared: 1;
|
||||
u64 mbec_vtl_mask: 16;
|
||||
u64 deny_lower_vtl_startup: 1;
|
||||
u64 supervisor_shadow_stack: 1;
|
||||
u64 hardware_hvpt_available: 1;
|
||||
u64 software_hvpt_available: 1;
|
||||
u64 hardware_hvpt_range_bits: 6;
|
||||
u64 intercept_page_available: 1;
|
||||
u64 return_action_available: 1;
|
||||
u64 reserved: 35;
|
||||
} __packed;
|
||||
};
|
||||
|
||||
union hv_register_vsm_page_offsets {
|
||||
struct {
|
||||
u64 vtl_call_offset : 12;
|
||||
u64 vtl_return_offset : 12;
|
||||
u64 reserved_mbz : 40;
|
||||
} __packed;
|
||||
u64 as_uint64;
|
||||
};
|
||||
|
||||
struct hv_nested_enlightenments_control {
|
||||
struct {
|
||||
u32 directhypercall : 1;
|
||||
|
|
@ -1007,6 +1049,70 @@ enum hv_register_name {
|
|||
|
||||
/* VSM */
|
||||
HV_REGISTER_VSM_VP_STATUS = 0x000D0003,
|
||||
|
||||
/* Synthetic VSM registers */
|
||||
HV_REGISTER_VSM_CODE_PAGE_OFFSETS = 0x000D0002,
|
||||
HV_REGISTER_VSM_CAPABILITIES = 0x000D0006,
|
||||
HV_REGISTER_VSM_PARTITION_CONFIG = 0x000D0007,
|
||||
|
||||
#if defined(CONFIG_X86)
|
||||
/* X64 Debug Registers */
|
||||
HV_X64_REGISTER_DR0 = 0x00050000,
|
||||
HV_X64_REGISTER_DR1 = 0x00050001,
|
||||
HV_X64_REGISTER_DR2 = 0x00050002,
|
||||
HV_X64_REGISTER_DR3 = 0x00050003,
|
||||
HV_X64_REGISTER_DR6 = 0x00050004,
|
||||
HV_X64_REGISTER_DR7 = 0x00050005,
|
||||
|
||||
/* X64 Cache control MSRs */
|
||||
HV_X64_REGISTER_MSR_MTRR_CAP = 0x0008000D,
|
||||
HV_X64_REGISTER_MSR_MTRR_DEF_TYPE = 0x0008000E,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_BASE0 = 0x00080010,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_BASE1 = 0x00080011,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_BASE2 = 0x00080012,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_BASE3 = 0x00080013,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_BASE4 = 0x00080014,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_BASE5 = 0x00080015,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_BASE6 = 0x00080016,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_BASE7 = 0x00080017,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_BASE8 = 0x00080018,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_BASE9 = 0x00080019,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_BASEA = 0x0008001A,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_BASEB = 0x0008001B,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_BASEC = 0x0008001C,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_BASED = 0x0008001D,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_BASEE = 0x0008001E,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_BASEF = 0x0008001F,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_MASK0 = 0x00080040,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_MASK1 = 0x00080041,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_MASK2 = 0x00080042,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_MASK3 = 0x00080043,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_MASK4 = 0x00080044,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_MASK5 = 0x00080045,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_MASK6 = 0x00080046,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_MASK7 = 0x00080047,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_MASK8 = 0x00080048,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_MASK9 = 0x00080049,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_MASKA = 0x0008004A,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_MASKB = 0x0008004B,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_MASKC = 0x0008004C,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_MASKD = 0x0008004D,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_MASKE = 0x0008004E,
|
||||
HV_X64_REGISTER_MSR_MTRR_PHYS_MASKF = 0x0008004F,
|
||||
HV_X64_REGISTER_MSR_MTRR_FIX64K00000 = 0x00080070,
|
||||
HV_X64_REGISTER_MSR_MTRR_FIX16K80000 = 0x00080071,
|
||||
HV_X64_REGISTER_MSR_MTRR_FIX16KA0000 = 0x00080072,
|
||||
HV_X64_REGISTER_MSR_MTRR_FIX4KC0000 = 0x00080073,
|
||||
HV_X64_REGISTER_MSR_MTRR_FIX4KC8000 = 0x00080074,
|
||||
HV_X64_REGISTER_MSR_MTRR_FIX4KD0000 = 0x00080075,
|
||||
HV_X64_REGISTER_MSR_MTRR_FIX4KD8000 = 0x00080076,
|
||||
HV_X64_REGISTER_MSR_MTRR_FIX4KE0000 = 0x00080077,
|
||||
HV_X64_REGISTER_MSR_MTRR_FIX4KE8000 = 0x00080078,
|
||||
HV_X64_REGISTER_MSR_MTRR_FIX4KF0000 = 0x00080079,
|
||||
HV_X64_REGISTER_MSR_MTRR_FIX4KF8000 = 0x0008007A,
|
||||
|
||||
HV_X64_REGISTER_REG_PAGE = 0x0009001C,
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -322,4 +322,84 @@ struct mshv_get_set_vp_state {
|
|||
* #define MSHV_ROOT_HVCALL _IOWR(MSHV_IOCTL, 0x07, struct mshv_root_hvcall)
|
||||
*/
|
||||
|
||||
/* Structure definitions, macros and IOCTLs for mshv_vtl */
|
||||
|
||||
#define MSHV_CAP_CORE_API_STABLE 0x0
|
||||
#define MSHV_CAP_REGISTER_PAGE 0x1
|
||||
#define MSHV_CAP_VTL_RETURN_ACTION 0x2
|
||||
#define MSHV_CAP_DR6_SHARED 0x3
|
||||
#define MSHV_MAX_RUN_MSG_SIZE 256
|
||||
|
||||
struct mshv_vp_registers {
|
||||
__u32 count; /* supports only 1 register at a time */
|
||||
__u32 reserved; /* Reserved for alignment or future use */
|
||||
__u64 regs_ptr; /* pointer to struct hv_register_assoc */
|
||||
};
|
||||
|
||||
struct mshv_vtl_set_eventfd {
|
||||
__s32 fd;
|
||||
__u32 flag;
|
||||
};
|
||||
|
||||
struct mshv_vtl_signal_event {
|
||||
__u32 connection_id;
|
||||
__u32 flag;
|
||||
};
|
||||
|
||||
struct mshv_vtl_sint_post_msg {
|
||||
__u64 message_type;
|
||||
__u32 connection_id;
|
||||
__u32 payload_size; /* Must not exceed HV_MESSAGE_PAYLOAD_BYTE_COUNT */
|
||||
__u64 payload_ptr; /* pointer to message payload (bytes) */
|
||||
};
|
||||
|
||||
struct mshv_vtl_ram_disposition {
|
||||
__u64 start_pfn;
|
||||
__u64 last_pfn;
|
||||
};
|
||||
|
||||
struct mshv_vtl_set_poll_file {
|
||||
__u32 cpu;
|
||||
__u32 fd;
|
||||
};
|
||||
|
||||
struct mshv_vtl_hvcall_setup {
|
||||
__u64 bitmap_array_size; /* stores number of bytes */
|
||||
__u64 allow_bitmap_ptr;
|
||||
};
|
||||
|
||||
struct mshv_vtl_hvcall {
|
||||
__u64 control; /* Hypercall control code */
|
||||
__u64 input_size; /* Size of the input data */
|
||||
__u64 input_ptr; /* Pointer to the input struct */
|
||||
__u64 status; /* Status of the hypercall (output) */
|
||||
__u64 output_size; /* Size of the output data */
|
||||
__u64 output_ptr; /* Pointer to the output struct */
|
||||
};
|
||||
|
||||
struct mshv_sint_mask {
|
||||
__u8 mask;
|
||||
__u8 reserved[7];
|
||||
};
|
||||
|
||||
/* /dev/mshv device IOCTL */
|
||||
#define MSHV_CHECK_EXTENSION _IOW(MSHV_IOCTL, 0x00, __u32)
|
||||
|
||||
/* vtl device */
|
||||
#define MSHV_CREATE_VTL _IOR(MSHV_IOCTL, 0x1D, char)
|
||||
#define MSHV_ADD_VTL0_MEMORY _IOW(MSHV_IOCTL, 0x21, struct mshv_vtl_ram_disposition)
|
||||
#define MSHV_SET_POLL_FILE _IOW(MSHV_IOCTL, 0x25, struct mshv_vtl_set_poll_file)
|
||||
#define MSHV_RETURN_TO_LOWER_VTL _IO(MSHV_IOCTL, 0x27)
|
||||
#define MSHV_GET_VP_REGISTERS _IOWR(MSHV_IOCTL, 0x05, struct mshv_vp_registers)
|
||||
#define MSHV_SET_VP_REGISTERS _IOW(MSHV_IOCTL, 0x06, struct mshv_vp_registers)
|
||||
|
||||
/* VMBus device IOCTLs */
|
||||
#define MSHV_SINT_SIGNAL_EVENT _IOW(MSHV_IOCTL, 0x22, struct mshv_vtl_signal_event)
|
||||
#define MSHV_SINT_POST_MESSAGE _IOW(MSHV_IOCTL, 0x23, struct mshv_vtl_sint_post_msg)
|
||||
#define MSHV_SINT_SET_EVENTFD _IOW(MSHV_IOCTL, 0x24, struct mshv_vtl_set_eventfd)
|
||||
#define MSHV_SINT_PAUSE_MESSAGE_STREAM _IOW(MSHV_IOCTL, 0x25, struct mshv_sint_mask)
|
||||
|
||||
/* hv_hvcall device */
|
||||
#define MSHV_HVCALL_SETUP _IOW(MSHV_IOCTL, 0x1E, struct mshv_vtl_hvcall_setup)
|
||||
#define MSHV_HVCALL _IOWR(MSHV_IOCTL, 0x1F, struct mshv_vtl_hvcall)
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue