vmcs, controls, err, exit_reason
This commit is contained in:
7
nel_os_kernel/Cargo.lock
generated
7
nel_os_kernel/Cargo.lock
generated
@ -141,12 +141,19 @@ dependencies = [
|
||||
"linked_list_allocator",
|
||||
"modular-bitfield",
|
||||
"nel_os_common",
|
||||
"numeric-enum-macro",
|
||||
"raw-cpuid 11.5.0",
|
||||
"spin 0.10.0",
|
||||
"uart_16550",
|
||||
"x86_64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "numeric-enum-macro"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "300e4bdb6b46b592948e700ea1ef24a4296491f6a0ee722b258040abd15a3714"
|
||||
|
||||
[[package]]
|
||||
name = "owned_ttf_parser"
|
||||
version = "0.25.0"
|
||||
|
@ -14,3 +14,4 @@ ab_glyph = { version = "0.2", features = ["libm"], default-features = false }
|
||||
raw-cpuid = "11.5.0"
|
||||
acpi = "5.2.0"
|
||||
modular-bitfield = "0.12.0"
|
||||
numeric-enum-macro = "0.2.0"
|
||||
|
@ -1,6 +1,8 @@
|
||||
mod vmcs;
|
||||
mod vmxon;
|
||||
|
||||
use core::arch::asm;
|
||||
|
||||
use raw_cpuid::cpuid;
|
||||
use x86_64::{
|
||||
registers::rflags::{self, RFlags},
|
||||
@ -72,3 +74,31 @@ pub fn vmx_capture_status() -> Result<(), &'static str> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vmread(field: u32) -> Result<u64, &'static str> {
|
||||
let field: u64 = field.into();
|
||||
let value: u64;
|
||||
unsafe {
|
||||
asm!(
|
||||
"vmread {0}, {1}",
|
||||
in(reg) field,
|
||||
out(reg) value,
|
||||
options(att_syntax)
|
||||
)
|
||||
};
|
||||
vmx_capture_status()?;
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn vmwrite(field: u32, value: u64) -> Result<(), &'static str> {
|
||||
let field: u64 = field.into();
|
||||
unsafe {
|
||||
asm!(
|
||||
"vmwrite {1}, {0}",
|
||||
in(reg) field,
|
||||
in(reg) value,
|
||||
options(att_syntax)
|
||||
)
|
||||
};
|
||||
vmx_capture_status()
|
||||
}
|
||||
|
@ -1,50 +0,0 @@
|
||||
use core::arch::asm;
|
||||
|
||||
use x86_64::structures::paging::{FrameAllocator, PhysFrame, Size4KiB};
|
||||
|
||||
use crate::vmm::x86_64::intel::vmx_capture_status;
|
||||
|
||||
pub struct Vmcs {
|
||||
pub frame: PhysFrame,
|
||||
}
|
||||
|
||||
impl Vmcs {
|
||||
pub fn new(frame_allocator: &mut impl FrameAllocator<Size4KiB>) -> Result<Self, &'static str> {
|
||||
let frame = frame_allocator
|
||||
.allocate_frame()
|
||||
.ok_or("Failed to allocate VMCS frame")?;
|
||||
Ok(Vmcs { frame })
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) -> Result<(), &'static str> {
|
||||
let vmcs_addr = self.get_vmcs_addr();
|
||||
|
||||
unsafe {
|
||||
asm!(
|
||||
"vmclear ({})",
|
||||
in(reg) &vmcs_addr,
|
||||
options(att_syntax)
|
||||
);
|
||||
vmx_capture_status()?;
|
||||
asm!(
|
||||
"vmptrld ({})",
|
||||
in(reg) &vmcs_addr,
|
||||
options(att_syntax)
|
||||
);
|
||||
vmx_capture_status()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_revision_id(&mut self, revision_id: u32) {
|
||||
let vmcs_addr = self.get_vmcs_addr();
|
||||
|
||||
unsafe {
|
||||
core::ptr::write_volatile(vmcs_addr as *mut u32, revision_id);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_vmcs_addr(&self) -> u64 {
|
||||
self.frame.start_address().as_u64()
|
||||
}
|
||||
}
|
31
nel_os_kernel/src/vmm/x86_64/intel/vmcs/controls.rs
Normal file
31
nel_os_kernel/src/vmm/x86_64/intel/vmcs/controls.rs
Normal file
@ -0,0 +1,31 @@
|
||||
use modular_bitfield::{bitfield, prelude::*};
|
||||
|
||||
use crate::vmm::x86_64::intel::vmcs;
|
||||
|
||||
#[bitfield]
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct PinBasedVmExecutionControls {
|
||||
pub external_interrupt_exiting: bool,
|
||||
reserved1: B1,
|
||||
pub interrupt_window_exiting: bool,
|
||||
pub nmi_exiting: bool,
|
||||
reserved2: B1,
|
||||
pub virtual_nmi: bool,
|
||||
pub activate_vmx_preemption_timer: bool,
|
||||
pub process_posted_interrupts: bool,
|
||||
reserved3: B24,
|
||||
}
|
||||
|
||||
impl PinBasedVmExecutionControls {
|
||||
pub fn read() -> Result<Self, &'static str> {
|
||||
vmcs::VmcsControl32::PIN_BASED_VM_EXECUTION_CONTROLS
|
||||
.read()
|
||||
.map(|value| PinBasedVmExecutionControls::from(value))
|
||||
.map_err(|_| "Failed to read Pin-Based VM Execution Controls")
|
||||
}
|
||||
|
||||
pub fn write(&self) -> Result<(), &'static str> {
|
||||
vmcs::VmcsControl32::PIN_BASED_VM_EXECUTION_CONTROLS.write(u32::from(*self))
|
||||
}
|
||||
}
|
44
nel_os_kernel/src/vmm/x86_64/intel/vmcs/err.rs
Normal file
44
nel_os_kernel/src/vmm/x86_64/intel/vmcs/err.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use numeric_enum_macro::numeric_enum;
|
||||
|
||||
use crate::vmm::x86_64::intel::vmcs::VmcsReadOnlyData32;
|
||||
|
||||
numeric_enum! {
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum InstructionError {
|
||||
NOT_AVAILABLE = 0,
|
||||
VMCALL_IN_VMXROOT = 1,
|
||||
VMCLEAR_INVALID_PHYS = 2,
|
||||
VMCLEAR_VMXONPTR = 3,
|
||||
VMLAUNCH_NONCLEAR_VMCS = 4,
|
||||
VMRESUME_NONLAUNCHED_VMCS = 5,
|
||||
VMRESUME_AFTER_VMXOFF = 6,
|
||||
VMENTRY_INVALID_CTRL = 7,
|
||||
VMENTRY_INVALID_HOST_STATE = 8,
|
||||
VMPTRLD_INVALID_PHYS = 9,
|
||||
VMPTRLD_VMXONP = 10,
|
||||
VMPTRLD_INCORRECT_REV = 11,
|
||||
VMRW_UNSUPPORTED_COMPONENT = 12,
|
||||
VMW_RO_COMPONENT = 13,
|
||||
VMXON_IN_VMXROOT = 15,
|
||||
VMENTRY_INVALID_EXEC_CTRL = 16,
|
||||
VMENTRY_NONLAUNCHED_EXEC_CTRL = 17,
|
||||
VMENTRY_EXEC_VMCSPTR = 18,
|
||||
VMCALL_NONCLEAR_VMCS = 19,
|
||||
VMCALL_INVALID_EXITCTL = 20,
|
||||
VMCALL_INCORRECT_MSGREV = 22,
|
||||
VMXOFF_DUALMONITOR = 23,
|
||||
VMCALL_INVALID_SMM = 24,
|
||||
VMENTRY_INVALID_EXECCTRL = 25,
|
||||
VMENTRY_EVENTS_BLOCKED = 26,
|
||||
INVALID_INVEPT = 28,
|
||||
}
|
||||
}
|
||||
|
||||
impl InstructionError {
|
||||
pub fn read() -> Result<Self, &'static str> {
|
||||
let err = VmcsReadOnlyData32::VM_INSTRUCTION_ERROR.read()?;
|
||||
|
||||
InstructionError::try_from(err).map_err(|_| "Unknown instruction error")
|
||||
}
|
||||
}
|
175
nel_os_kernel/src/vmm/x86_64/intel/vmcs/exit_reason.rs
Normal file
175
nel_os_kernel/src/vmm/x86_64/intel/vmcs/exit_reason.rs
Normal file
@ -0,0 +1,175 @@
|
||||
use numeric_enum_macro::numeric_enum;
|
||||
|
||||
use crate::vmm::x86_64::intel::vmcs;
|
||||
|
||||
numeric_enum! {
|
||||
#[repr(u16)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum VmxExitReason {
|
||||
EXCEPTION = 0,
|
||||
EXTERNAL_INTERRUPT = 1,
|
||||
TRIPLE_FAULT = 2,
|
||||
INIT = 3,
|
||||
SIPI = 4,
|
||||
IO_SMI = 5,
|
||||
OTHER_SMI = 6,
|
||||
INTERRUPT_WINDOW = 7,
|
||||
NMI_WINDOW = 8,
|
||||
TASK_SWITCH = 9,
|
||||
CPUID = 10,
|
||||
GETSEC = 11,
|
||||
HLT = 12,
|
||||
INVD = 13,
|
||||
INVLPG = 14,
|
||||
RDPMC = 15,
|
||||
RDTSC = 16,
|
||||
RSM = 17,
|
||||
VMCALL = 18,
|
||||
VMCLEAR = 19,
|
||||
VMLAUNCH = 20,
|
||||
VMPTRLD = 21,
|
||||
VMPTRST = 22,
|
||||
VMREAD = 23,
|
||||
VMRESUME = 24,
|
||||
VMWRITE = 25,
|
||||
VMXOFF = 26,
|
||||
VMXON = 27,
|
||||
CONTROL_REGISTER_ACCESSES = 28,
|
||||
MOV_DR = 29,
|
||||
IO_INSTRUCTION = 30,
|
||||
RDMSR = 31,
|
||||
WRMSR = 32,
|
||||
VM_ENTRY_FAILURE_INVALID_GUEST_STATE = 33,
|
||||
VM_ENTRY_FAILURE_MSR_LOADING = 34,
|
||||
MWAIT = 36,
|
||||
MONITOR_TRAP_FLAG = 37,
|
||||
MONITOR = 39,
|
||||
PAUSE = 40,
|
||||
VM_ENTRY_FAILURE_MACHINE_CHECK_EVENT = 41,
|
||||
TPR_BELOW_THRESHOLD = 43,
|
||||
APIC_ACCESS = 44,
|
||||
VIRTUALIZED_EOI = 45,
|
||||
ACCESS_TO_GDTR_OR_IDTR = 46,
|
||||
ACCESS_TO_LDTR_OR_TR = 47,
|
||||
EPT_VIOLATION = 48,
|
||||
EPT_MISCONFIGURATION = 49,
|
||||
INVEPT = 50,
|
||||
RDTSCP = 51,
|
||||
VMX_PREEMPTION_TIMER_EXPIRED = 52,
|
||||
INVVPID = 53,
|
||||
WBINVD = 54,
|
||||
XSETBV = 55,
|
||||
APIC_WRITE = 56,
|
||||
RDRAND = 57,
|
||||
INVPCID = 58,
|
||||
VMFUNC = 59,
|
||||
ENCLS = 60,
|
||||
RDSEED = 61,
|
||||
PAGE_MODIFICATION_LOG_FULL = 62,
|
||||
XSAVES = 63,
|
||||
XRSTORS = 64,
|
||||
PCONFIG = 65,
|
||||
SPP_RELATED_EVENT = 66,
|
||||
UMWAIT = 67,
|
||||
TPAUSE = 68,
|
||||
LOADIWKEY = 69,
|
||||
ENCLV = 70,
|
||||
ENQCMD_PASID_TRANSLATION_FAILURE = 72,
|
||||
ENQCMDS_PASID_TRANSLATION_FAILURE = 73,
|
||||
BUS_LOCK = 74,
|
||||
INSTRUCTION_TIMEOUT = 75,
|
||||
SEAMCALL = 76,
|
||||
TDCALL = 77,
|
||||
RDMSRLIST = 78,
|
||||
WRMSRLIST = 79,
|
||||
}
|
||||
}
|
||||
|
||||
impl VmxExitReason {
|
||||
pub fn read() -> Result<Self, &'static str> {
|
||||
let reason = vmcs::VmcsReadOnlyData32::VM_EXIT_REASON.read()? as u16;
|
||||
VmxExitReason::try_from(reason).map_err(|_| "Unknown VMX exit reason")
|
||||
}
|
||||
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
use VmxExitReason::*;
|
||||
match self {
|
||||
EXCEPTION => "Exception or non-maskable interrupt (NMI)",
|
||||
EXTERNAL_INTERRUPT => "External interrupt",
|
||||
TRIPLE_FAULT => "Triple fault",
|
||||
INIT => "INIT signal",
|
||||
SIPI => "Start-up IPI (SIPI)",
|
||||
IO_SMI => "I/O system-management interrupt (SMI)",
|
||||
OTHER_SMI => "Other SMI",
|
||||
INTERRUPT_WINDOW => "Interrupt window",
|
||||
NMI_WINDOW => "NMI window",
|
||||
TASK_SWITCH => "Task switch",
|
||||
CPUID => "CPUID instruction execution",
|
||||
GETSEC => "GETSEC instruction execution",
|
||||
HLT => "HLT instruction execution",
|
||||
INVD => "INVD instruction execution",
|
||||
INVLPG => "INVLPG instruction execution",
|
||||
RDPMC => "RDPMC instruction execution",
|
||||
RDTSC => "RDTSC instruction execution",
|
||||
RSM => "RSM instruction execution in SMM",
|
||||
VMCALL => "VMCALL instruction execution",
|
||||
VMCLEAR => "VMCLEAR instruction execution",
|
||||
VMLAUNCH => "VMLAUNCH instruction execution",
|
||||
VMPTRLD => "VMPTRLD instruction execution",
|
||||
VMPTRST => "VMPTRST instruction execution",
|
||||
VMREAD => "VMREAD instruction execution",
|
||||
VMRESUME => "VMRESUME instruction execution",
|
||||
VMWRITE => "VMWRITE instruction execution",
|
||||
VMXOFF => "VMXOFF instruction execution",
|
||||
VMXON => "VMXON instruction execution",
|
||||
CONTROL_REGISTER_ACCESSES => "Control-register accesses",
|
||||
MOV_DR => "MOV to or from debug registers",
|
||||
IO_INSTRUCTION => "I/O instruction execution",
|
||||
RDMSR => "RDMSR instruction execution",
|
||||
WRMSR => "WRMSR or WRMSRNS instruction execution",
|
||||
VM_ENTRY_FAILURE_INVALID_GUEST_STATE => "VM-entry failure due to invalid guest state",
|
||||
VM_ENTRY_FAILURE_MSR_LOADING => "VM-entry failure due to MSR loading",
|
||||
MWAIT => "MWAIT instruction execution",
|
||||
MONITOR_TRAP_FLAG => "Monitor trap flag",
|
||||
MONITOR => "MONITOR instruction execution",
|
||||
PAUSE => "PAUSE instruction execution",
|
||||
VM_ENTRY_FAILURE_MACHINE_CHECK_EVENT => "VM-entry failure due to machine-check event",
|
||||
TPR_BELOW_THRESHOLD => "TPR below threshold",
|
||||
APIC_ACCESS => "APIC access",
|
||||
VIRTUALIZED_EOI => "Virtualized EOI",
|
||||
ACCESS_TO_GDTR_OR_IDTR => "Access to GDTR or IDTR",
|
||||
ACCESS_TO_LDTR_OR_TR => "Access to LDTR or TR",
|
||||
EPT_VIOLATION => "EPT violation",
|
||||
EPT_MISCONFIGURATION => "EPT misconfiguration",
|
||||
INVEPT => "INVEPT instruction execution",
|
||||
RDTSCP => "RDTSCP instruction execution",
|
||||
VMX_PREEMPTION_TIMER_EXPIRED => "VMX-preemption timer expired",
|
||||
INVVPID => "INVVPID instruction execution",
|
||||
WBINVD => "WBINVD or WBNOINVD instruction execution",
|
||||
XSETBV => "XSETBV instruction execution",
|
||||
APIC_WRITE => "APIC write",
|
||||
RDRAND => "RDRAND instruction execution",
|
||||
INVPCID => "INVPCID instruction execution",
|
||||
VMFUNC => "VMFUNC instruction execution",
|
||||
ENCLS => "ENCLS instruction execution",
|
||||
RDSEED => "RDSEED instruction execution",
|
||||
PAGE_MODIFICATION_LOG_FULL => "Page-modification log full",
|
||||
XSAVES => "XSAVES instruction execution",
|
||||
XRSTORS => "XRSTORS instruction execution",
|
||||
PCONFIG => "PCONFIG instruction execution",
|
||||
SPP_RELATED_EVENT => "SPP-related event",
|
||||
UMWAIT => "UMWAIT instruction execution",
|
||||
TPAUSE => "TPAUSE instruction execution",
|
||||
LOADIWKEY => "LOADIWKEY instruction execution",
|
||||
ENCLV => "ENCLV instruction execution",
|
||||
ENQCMD_PASID_TRANSLATION_FAILURE => "ENQCMD PASID translation failure",
|
||||
ENQCMDS_PASID_TRANSLATION_FAILURE => "ENQCMDS PASID translation failure",
|
||||
BUS_LOCK => "Bus lock",
|
||||
INSTRUCTION_TIMEOUT => "Instruction timeout",
|
||||
SEAMCALL => "SEAMCALL instruction execution",
|
||||
TDCALL => "TDCALL instruction execution",
|
||||
RDMSRLIST => "RDMSRLIST instruction execution",
|
||||
WRMSRLIST => "WRMSRLIST instruction execution",
|
||||
}
|
||||
}
|
||||
}
|
126
nel_os_kernel/src/vmm/x86_64/intel/vmcs/mod.rs
Normal file
126
nel_os_kernel/src/vmm/x86_64/intel/vmcs/mod.rs
Normal file
@ -0,0 +1,126 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
pub mod controls;
|
||||
pub mod err;
|
||||
pub mod exit_reason;
|
||||
|
||||
use core::arch::asm;
|
||||
|
||||
use x86_64::structures::paging::{FrameAllocator, PhysFrame, Size4KiB};
|
||||
|
||||
use crate::vmm::x86_64::intel::vmx_capture_status;
|
||||
|
||||
macro_rules! vmcs_read {
|
||||
($field_enum: ident, u64) => {
|
||||
impl $field_enum {
|
||||
pub fn read(self) -> Result<u64, &'static str> {
|
||||
crate::vmm::x86_64::intel::vmread(self as u32)
|
||||
}
|
||||
}
|
||||
};
|
||||
($field_enum: ident, $ux: ty) => {
|
||||
impl $field_enum {
|
||||
pub fn read(self) -> Result<$ux, &'static str> {
|
||||
crate::vmm::x86_64::intel::vmread(self as u32).map(|v| v as $ux)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! vmcs_write {
|
||||
($field_enum: ident, u64) => {
|
||||
impl $field_enum {
|
||||
pub fn write(self, value: u64) -> Result<(), &'static str> {
|
||||
crate::vmm::x86_64::intel::vmwrite(self as u32, value)
|
||||
}
|
||||
}
|
||||
};
|
||||
($field_enum: ident, $ux: ty) => {
|
||||
impl $field_enum {
|
||||
pub fn write(self, value: $ux) -> Result<(), &'static str> {
|
||||
crate::vmm::x86_64::intel::vmwrite(self as u32, value as u64)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub struct Vmcs {
|
||||
pub frame: PhysFrame,
|
||||
}
|
||||
|
||||
impl Vmcs {
|
||||
pub fn new(frame_allocator: &mut impl FrameAllocator<Size4KiB>) -> Result<Self, &'static str> {
|
||||
let frame = frame_allocator
|
||||
.allocate_frame()
|
||||
.ok_or("Failed to allocate VMCS frame")?;
|
||||
Ok(Vmcs { frame })
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) -> Result<(), &'static str> {
|
||||
let vmcs_addr = self.get_vmcs_addr();
|
||||
|
||||
unsafe {
|
||||
asm!(
|
||||
"vmclear ({})",
|
||||
in(reg) &vmcs_addr,
|
||||
options(att_syntax)
|
||||
);
|
||||
vmx_capture_status()?;
|
||||
asm!(
|
||||
"vmptrld ({})",
|
||||
in(reg) &vmcs_addr,
|
||||
options(att_syntax)
|
||||
);
|
||||
vmx_capture_status()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_revision_id(&mut self, revision_id: u32) {
|
||||
let vmcs_addr = self.get_vmcs_addr();
|
||||
|
||||
unsafe {
|
||||
core::ptr::write_volatile(vmcs_addr as *mut u32, revision_id);
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_vmcs_addr(&self) -> u64 {
|
||||
self.frame.start_address().as_u64()
|
||||
}
|
||||
}
|
||||
|
||||
pub enum VmcsControl32 {
|
||||
PIN_BASED_VM_EXECUTION_CONTROLS = 0x00004000,
|
||||
PRIMARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS = 0x00004002,
|
||||
EXCEPTION_BITMAP = 0x00004004,
|
||||
PAGE_FAULT_ERROR_CODE_MASK = 0x00004006,
|
||||
PAGE_FAULT_ERROR_CODE_MATCH = 0x00004008,
|
||||
CR3_TARGET_COUNT = 0x0000400A,
|
||||
PRIMARY_VM_EXIT_CONTROLS = 0x0000400C,
|
||||
VM_EXIT_MSR_STORE_COUNT = 0x0000400E,
|
||||
VM_EXIT_MSR_LOAD_COUNT = 0x00004010,
|
||||
VM_ENTRY_CONTROLS = 0x00004012,
|
||||
VM_ENTRY_MSR_LOAD_COUNT = 0x00004014,
|
||||
VM_ENTRY_INTERRUPTION_INFORMATION_FIELD = 0x00004016,
|
||||
VM_ENTRY_EXCEPTION_ERROR_CODE = 0x00004018,
|
||||
VM_ENTRY_INSTRUCTION_LENGTH = 0x0000401A,
|
||||
TPR_THRESHOLD = 0x0000401C,
|
||||
SECONDARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS = 0x0000401E,
|
||||
PLE_GAP = 0x00004020,
|
||||
PLE_WINDOW = 0x00004022,
|
||||
INSTRUCTION_TIMEOUT_CONTROL = 0x00004024,
|
||||
}
|
||||
vmcs_read!(VmcsControl32, u32);
|
||||
vmcs_write!(VmcsControl32, u32);
|
||||
|
||||
pub enum VmcsReadOnlyData32 {
|
||||
VM_INSTRUCTION_ERROR = 0x00004400,
|
||||
VM_EXIT_REASON = 0x00004402,
|
||||
VM_EXIT_INTERRUPTION_INFORMATION_FIELD = 0x00004404,
|
||||
VM_EXIT_INTERRUPTION_ERROR_CODE = 0x00004406,
|
||||
IDT_VECTORING_INFORMATION_FIELD = 0x00004408,
|
||||
IDT_VECTORING_ERROR_CODE = 0x0000440A,
|
||||
VM_EXIT_INSTRUCTION_LENGTH = 0x0000440C,
|
||||
VM_EXIT_INSTRUCTION_INFO = 0x0000440E,
|
||||
}
|
||||
vmcs_read!(VmcsReadOnlyData32, u32);
|
Reference in New Issue
Block a user