mirror of
https://github.com/mii443/nel_os.git
synced 2025-08-22 16:15:38 +00:00
wip
This commit is contained in:
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -107,6 +107,7 @@ dependencies = [
|
|||||||
"pc-keyboard",
|
"pc-keyboard",
|
||||||
"pic8259",
|
"pic8259",
|
||||||
"rand",
|
"rand",
|
||||||
|
"raw-cpuid 11.5.0",
|
||||||
"spin 0.5.2",
|
"spin 0.5.2",
|
||||||
"uart_16550",
|
"uart_16550",
|
||||||
"volatile 0.2.7",
|
"volatile 0.2.7",
|
||||||
@ -253,6 +254,15 @@ dependencies = [
|
|||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "raw-cpuid"
|
||||||
|
version = "11.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.9.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.20"
|
version = "1.0.20"
|
||||||
@ -356,7 +366,7 @@ checksum = "2781db97787217ad2a2845c396a5efe286f87467a5810836db6d74926e94a385"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bit_field",
|
"bit_field",
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"raw-cpuid",
|
"raw-cpuid 10.7.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -16,6 +16,7 @@ x86 = "0.52.0"
|
|||||||
bitfield = "0.19.0"
|
bitfield = "0.19.0"
|
||||||
numeric-enum-macro = "0.2.0"
|
numeric-enum-macro = "0.2.0"
|
||||||
rand = { version = "0.6.5", default-features = false }
|
rand = { version = "0.6.5", default-features = false }
|
||||||
|
raw-cpuid = "11.5.0"
|
||||||
|
|
||||||
[dependencies.lazy_static]
|
[dependencies.lazy_static]
|
||||||
version = "1.0"
|
version = "1.0"
|
||||||
|
257
src/vmm/cpuid.rs
Normal file
257
src/vmm/cpuid.rs
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
use raw_cpuid::cpuid;
|
||||||
|
|
||||||
|
use crate::info;
|
||||||
|
|
||||||
|
use super::{vcpu::VCpu, vmcs::VmxLeaf};
|
||||||
|
|
||||||
|
pub fn handle_cpuid_exit(vcpu: &mut VCpu) {
|
||||||
|
let regs = &mut vcpu.guest_registers;
|
||||||
|
let vendor: &[u8; 12] = b"NelogikaNelo";
|
||||||
|
let vendor = unsafe { core::mem::transmute::<&[u8; 12], &[u32; 3]>(vendor) };
|
||||||
|
match VmxLeaf::from(regs.rax) {
|
||||||
|
VmxLeaf::MAXIMUM_INPUT => {
|
||||||
|
info!("CPUID max input");
|
||||||
|
regs.rax = 0x20;
|
||||||
|
regs.rbx = vendor[0] as u64;
|
||||||
|
regs.rcx = vendor[1] as u64;
|
||||||
|
regs.rdx = vendor[2] as u64;
|
||||||
|
}
|
||||||
|
VmxLeaf::VERSION_AND_FEATURE_INFO => {
|
||||||
|
info!("CPUID version and feature info");
|
||||||
|
let ecx = FeatureInfoEcx {
|
||||||
|
sse3: false,
|
||||||
|
pclmulqdq: false,
|
||||||
|
dtes64: false,
|
||||||
|
monitor: false,
|
||||||
|
ds_cpl: false,
|
||||||
|
vmx: false,
|
||||||
|
smx: false,
|
||||||
|
eist: false,
|
||||||
|
tm2: false,
|
||||||
|
ssse3: false,
|
||||||
|
cnxt_id: false,
|
||||||
|
sdbg: false,
|
||||||
|
fma: false,
|
||||||
|
cmpxchg16b: false,
|
||||||
|
xtpr: false,
|
||||||
|
pdcm: false,
|
||||||
|
_reserved_0: false,
|
||||||
|
pcid: true,
|
||||||
|
dca: false,
|
||||||
|
sse4_1: false,
|
||||||
|
sse4_2: false,
|
||||||
|
x2apic: false,
|
||||||
|
movbe: false,
|
||||||
|
popcnt: false,
|
||||||
|
tsc_deadline: false,
|
||||||
|
aesni: false,
|
||||||
|
xsave: false,
|
||||||
|
osxsave: false,
|
||||||
|
avx: false,
|
||||||
|
f16c: false,
|
||||||
|
rdrand: false,
|
||||||
|
hypervisor: false,
|
||||||
|
};
|
||||||
|
let edx = FeatureInfoEdx {
|
||||||
|
fpu: true,
|
||||||
|
vme: true,
|
||||||
|
de: true,
|
||||||
|
pse: true,
|
||||||
|
tsc: false,
|
||||||
|
msr: true,
|
||||||
|
pae: true,
|
||||||
|
mce: false,
|
||||||
|
cx8: true,
|
||||||
|
apic: false,
|
||||||
|
_reserved_0: false,
|
||||||
|
sep: true,
|
||||||
|
mtrr: false,
|
||||||
|
pge: true,
|
||||||
|
mca: false,
|
||||||
|
cmov: true,
|
||||||
|
pat: false,
|
||||||
|
pse36: true,
|
||||||
|
psn: false,
|
||||||
|
clfsh: false,
|
||||||
|
_reserved_1: false,
|
||||||
|
ds: false,
|
||||||
|
acpi: true,
|
||||||
|
mmx: false,
|
||||||
|
fxsr: true,
|
||||||
|
sse: false,
|
||||||
|
sse2: false,
|
||||||
|
ss: false,
|
||||||
|
htt: false,
|
||||||
|
tm: false,
|
||||||
|
_reserved_2: false,
|
||||||
|
pbe: false,
|
||||||
|
};
|
||||||
|
let cpuid = cpuid!(0x1, 0);
|
||||||
|
regs.rax = cpuid.eax as u64;
|
||||||
|
regs.rbx = cpuid.ebx as u64;
|
||||||
|
regs.rcx = ecx.to_u32() as u64;
|
||||||
|
regs.rdx = edx.to_u32() as u64;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
info!("Unhandled CPUID leaf: {:#x}", regs.rax);
|
||||||
|
invalid(vcpu);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn invalid(vcpu: &mut VCpu) {
|
||||||
|
let regs = &mut vcpu.guest_registers;
|
||||||
|
|
||||||
|
regs.rax = 0;
|
||||||
|
regs.rbx = 0;
|
||||||
|
regs.rcx = 0;
|
||||||
|
regs.rdx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
#[repr(C, packed)]
|
||||||
|
pub struct FeatureInfoEcx {
|
||||||
|
pub sse3: bool,
|
||||||
|
pub pclmulqdq: bool,
|
||||||
|
pub dtes64: bool,
|
||||||
|
pub monitor: bool,
|
||||||
|
pub ds_cpl: bool,
|
||||||
|
pub vmx: bool,
|
||||||
|
pub smx: bool,
|
||||||
|
pub eist: bool,
|
||||||
|
pub tm2: bool,
|
||||||
|
pub ssse3: bool,
|
||||||
|
pub cnxt_id: bool,
|
||||||
|
pub sdbg: bool,
|
||||||
|
pub fma: bool,
|
||||||
|
pub cmpxchg16b: bool,
|
||||||
|
pub xtpr: bool,
|
||||||
|
pub pdcm: bool,
|
||||||
|
pub _reserved_0: bool,
|
||||||
|
pub pcid: bool,
|
||||||
|
pub dca: bool,
|
||||||
|
pub sse4_1: bool,
|
||||||
|
pub sse4_2: bool,
|
||||||
|
pub x2apic: bool,
|
||||||
|
pub movbe: bool,
|
||||||
|
pub popcnt: bool,
|
||||||
|
pub tsc_deadline: bool,
|
||||||
|
pub aesni: bool,
|
||||||
|
pub xsave: bool,
|
||||||
|
pub osxsave: bool,
|
||||||
|
pub avx: bool,
|
||||||
|
pub f16c: bool,
|
||||||
|
pub rdrand: bool,
|
||||||
|
pub hypervisor: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FeatureInfoEcx {
|
||||||
|
pub fn to_u32(&self) -> u32 {
|
||||||
|
(self.sse3 as u32) << 0
|
||||||
|
| (self.pclmulqdq as u32) << 1
|
||||||
|
| (self.dtes64 as u32) << 2
|
||||||
|
| (self.monitor as u32) << 3
|
||||||
|
| (self.ds_cpl as u32) << 4
|
||||||
|
| (self.vmx as u32) << 5
|
||||||
|
| (self.smx as u32) << 6
|
||||||
|
| (self.eist as u32) << 7
|
||||||
|
| (self.tm2 as u32) << 8
|
||||||
|
| (self.ssse3 as u32) << 9
|
||||||
|
| (self.cnxt_id as u32) << 10
|
||||||
|
| (self.sdbg as u32) << 11
|
||||||
|
| (self.fma as u32) << 12
|
||||||
|
| (self.cmpxchg16b as u32) << 13
|
||||||
|
| (self.xtpr as u32) << 14
|
||||||
|
| (self.pdcm as u32) << 15
|
||||||
|
| (self._reserved_0 as u32) << 16
|
||||||
|
| (self.pcid as u32) << 17
|
||||||
|
| (self.dca as u32) << 18
|
||||||
|
| (self.sse4_1 as u32) << 19
|
||||||
|
| (self.sse4_2 as u32) << 20
|
||||||
|
| (self.x2apic as u32) << 21
|
||||||
|
| (self.movbe as u32) << 22
|
||||||
|
| (self.popcnt as u32) << 23
|
||||||
|
| (self.tsc_deadline as u32) << 24
|
||||||
|
| (self.aesni as u32) << 25
|
||||||
|
| (self.xsave as u32) << 26
|
||||||
|
| (self.osxsave as u32) << 27
|
||||||
|
| (self.avx as u32) << 28
|
||||||
|
| (self.f16c as u32) << 29
|
||||||
|
| (self.rdrand as u32) << 30
|
||||||
|
| (self.hypervisor as u32) << 31
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
#[repr(C, packed)]
|
||||||
|
pub struct FeatureInfoEdx {
|
||||||
|
pub fpu: bool,
|
||||||
|
pub vme: bool,
|
||||||
|
pub de: bool,
|
||||||
|
pub pse: bool,
|
||||||
|
pub tsc: bool,
|
||||||
|
pub msr: bool,
|
||||||
|
pub pae: bool,
|
||||||
|
pub mce: bool,
|
||||||
|
pub cx8: bool,
|
||||||
|
pub apic: bool,
|
||||||
|
pub _reserved_0: bool,
|
||||||
|
pub sep: bool,
|
||||||
|
pub mtrr: bool,
|
||||||
|
pub pge: bool,
|
||||||
|
pub mca: bool,
|
||||||
|
pub cmov: bool,
|
||||||
|
pub pat: bool,
|
||||||
|
pub pse36: bool,
|
||||||
|
pub psn: bool,
|
||||||
|
pub clfsh: bool,
|
||||||
|
pub _reserved_1: bool,
|
||||||
|
pub ds: bool,
|
||||||
|
pub acpi: bool,
|
||||||
|
pub mmx: bool,
|
||||||
|
pub fxsr: bool,
|
||||||
|
pub sse: bool,
|
||||||
|
pub sse2: bool,
|
||||||
|
pub ss: bool,
|
||||||
|
pub htt: bool,
|
||||||
|
pub tm: bool,
|
||||||
|
pub _reserved_2: bool,
|
||||||
|
pub pbe: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FeatureInfoEdx {
|
||||||
|
pub fn to_u32(&self) -> u32 {
|
||||||
|
(self.fpu as u32) << 0
|
||||||
|
| (self.vme as u32) << 1
|
||||||
|
| (self.de as u32) << 2
|
||||||
|
| (self.pse as u32) << 3
|
||||||
|
| (self.tsc as u32) << 4
|
||||||
|
| (self.msr as u32) << 5
|
||||||
|
| (self.pae as u32) << 6
|
||||||
|
| (self.mce as u32) << 7
|
||||||
|
| (self.cx8 as u32) << 8
|
||||||
|
| (self.apic as u32) << 9
|
||||||
|
| (self._reserved_0 as u32) << 10
|
||||||
|
| (self.sep as u32) << 11
|
||||||
|
| (self.mtrr as u32) << 12
|
||||||
|
| (self.pge as u32) << 13
|
||||||
|
| (self.mca as u32) << 14
|
||||||
|
| (self.cmov as u32) << 15
|
||||||
|
| (self.pat as u32) << 16
|
||||||
|
| (self.pse36 as u32) << 17
|
||||||
|
| (self.psn as u32) << 18
|
||||||
|
| (self.clfsh as u32) << 19
|
||||||
|
| (self._reserved_1 as u32) << 20
|
||||||
|
| (self.ds as u32) << 21
|
||||||
|
| (self.acpi as u32) << 22
|
||||||
|
| (self.mmx as u32) << 23
|
||||||
|
| (self.fxsr as u32) << 24
|
||||||
|
| (self.sse as u32) << 25
|
||||||
|
| (self.sse2 as u32) << 26
|
||||||
|
| (self.ss as u32) << 27
|
||||||
|
| (self.htt as u32) << 28
|
||||||
|
| (self.tm as u32) << 29
|
||||||
|
| (self._reserved_2 as u32) << 30
|
||||||
|
| (self.pbe as u32) << 31
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
pub mod asm;
|
pub mod asm;
|
||||||
|
pub mod cpuid;
|
||||||
pub mod ept;
|
pub mod ept;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod linux;
|
pub mod linux;
|
||||||
|
@ -11,10 +11,13 @@ use x86_64::VirtAddr;
|
|||||||
use crate::{
|
use crate::{
|
||||||
info,
|
info,
|
||||||
memory::BootInfoFrameAllocator,
|
memory::BootInfoFrameAllocator,
|
||||||
vmm::vmcs::{
|
vmm::{
|
||||||
DescriptorType, EntryControls, Granularity, PrimaryExitControls,
|
cpuid,
|
||||||
PrimaryProcessorBasedVmExecutionControls, SecondaryProcessorBasedVmExecutionControls,
|
vmcs::{
|
||||||
SegmentRights, VmxExitInfo, VmxExitReason,
|
DescriptorType, EntryControls, Granularity, PrimaryExitControls,
|
||||||
|
PrimaryProcessorBasedVmExecutionControls, SecondaryProcessorBasedVmExecutionControls,
|
||||||
|
SegmentRights, VmxExitInfo, VmxExitReason,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -215,7 +218,7 @@ impl VCpu {
|
|||||||
|
|
||||||
primary_exec_ctrl.0 |= (reserved_bits & 0xFFFFFFFF) as u32;
|
primary_exec_ctrl.0 |= (reserved_bits & 0xFFFFFFFF) as u32;
|
||||||
primary_exec_ctrl.0 &= (reserved_bits >> 32) as u32;
|
primary_exec_ctrl.0 &= (reserved_bits >> 32) as u32;
|
||||||
primary_exec_ctrl.set_hlt(true);
|
primary_exec_ctrl.set_hlt(false);
|
||||||
primary_exec_ctrl.set_activate_secondary_controls(true);
|
primary_exec_ctrl.set_activate_secondary_controls(true);
|
||||||
|
|
||||||
primary_exec_ctrl.write();
|
primary_exec_ctrl.write();
|
||||||
@ -256,6 +259,8 @@ impl VCpu {
|
|||||||
entry_ctrl.0 |= (reserved_bits & 0xFFFFFFFF) as u32;
|
entry_ctrl.0 |= (reserved_bits & 0xFFFFFFFF) as u32;
|
||||||
entry_ctrl.0 &= (reserved_bits >> 32) as u32;
|
entry_ctrl.0 &= (reserved_bits >> 32) as u32;
|
||||||
entry_ctrl.set_ia32e_mode_guest(false);
|
entry_ctrl.set_ia32e_mode_guest(false);
|
||||||
|
entry_ctrl.set_load_ia32_efer(true);
|
||||||
|
entry_ctrl.set_load_ia32_pat(true);
|
||||||
|
|
||||||
entry_ctrl.write();
|
entry_ctrl.write();
|
||||||
|
|
||||||
@ -279,6 +284,9 @@ impl VCpu {
|
|||||||
exit_ctrl.0 &= (reserved_bits >> 32) as u32;
|
exit_ctrl.0 &= (reserved_bits >> 32) as u32;
|
||||||
exit_ctrl.set_host_addr_space_size(true);
|
exit_ctrl.set_host_addr_space_size(true);
|
||||||
exit_ctrl.set_load_ia32_efer(true);
|
exit_ctrl.set_load_ia32_efer(true);
|
||||||
|
exit_ctrl.set_save_ia32_efer(true);
|
||||||
|
exit_ctrl.set_load_ia32_pat(true);
|
||||||
|
exit_ctrl.set_save_ia32_pat(true);
|
||||||
|
|
||||||
exit_ctrl.write();
|
exit_ctrl.write();
|
||||||
|
|
||||||
@ -355,8 +363,6 @@ impl VCpu {
|
|||||||
vmwrite(vmcs::guest::SS_BASE, 0)?;
|
vmwrite(vmcs::guest::SS_BASE, 0)?;
|
||||||
vmwrite(vmcs::guest::DS_BASE, 0)?;
|
vmwrite(vmcs::guest::DS_BASE, 0)?;
|
||||||
vmwrite(vmcs::guest::ES_BASE, 0)?;
|
vmwrite(vmcs::guest::ES_BASE, 0)?;
|
||||||
vmwrite(vmcs::guest::FS_BASE, 0)?;
|
|
||||||
vmwrite(vmcs::guest::GS_BASE, 0)?;
|
|
||||||
vmwrite(vmcs::guest::TR_BASE, 0)?;
|
vmwrite(vmcs::guest::TR_BASE, 0)?;
|
||||||
vmwrite(vmcs::guest::GDTR_BASE, 0)?;
|
vmwrite(vmcs::guest::GDTR_BASE, 0)?;
|
||||||
vmwrite(vmcs::guest::IDTR_BASE, 0)?;
|
vmwrite(vmcs::guest::IDTR_BASE, 0)?;
|
||||||
@ -373,15 +379,6 @@ impl VCpu {
|
|||||||
vmwrite(vmcs::guest::IDTR_LIMIT, 0)?;
|
vmwrite(vmcs::guest::IDTR_LIMIT, 0)?;
|
||||||
vmwrite(vmcs::guest::LDTR_LIMIT, 0)?;
|
vmwrite(vmcs::guest::LDTR_LIMIT, 0)?;
|
||||||
|
|
||||||
vmwrite(vmcs::guest::CS_SELECTOR, 0)?;
|
|
||||||
vmwrite(vmcs::guest::SS_SELECTOR, 0)?;
|
|
||||||
vmwrite(vmcs::guest::DS_SELECTOR, 0)?;
|
|
||||||
vmwrite(vmcs::guest::ES_SELECTOR, 0)?;
|
|
||||||
vmwrite(vmcs::guest::FS_SELECTOR, 0)?;
|
|
||||||
vmwrite(vmcs::guest::GS_SELECTOR, 0)?;
|
|
||||||
vmwrite(vmcs::guest::TR_SELECTOR, 0)?;
|
|
||||||
vmwrite(vmcs::guest::LDTR_SELECTOR, 0)?;
|
|
||||||
|
|
||||||
let cs_right = {
|
let cs_right = {
|
||||||
let mut rights = SegmentRights::default();
|
let mut rights = SegmentRights::default();
|
||||||
rights.set_rw(true);
|
rights.set_rw(true);
|
||||||
@ -448,7 +445,19 @@ impl VCpu {
|
|||||||
vmwrite(vmcs::guest::TR_ACCESS_RIGHTS, tr_right.0 as u64)?;
|
vmwrite(vmcs::guest::TR_ACCESS_RIGHTS, tr_right.0 as u64)?;
|
||||||
vmwrite(vmcs::guest::LDTR_ACCESS_RIGHTS, ldtr_right.0 as u64)?;
|
vmwrite(vmcs::guest::LDTR_ACCESS_RIGHTS, ldtr_right.0 as u64)?;
|
||||||
|
|
||||||
|
vmwrite(vmcs::guest::CS_SELECTOR, 0)?;
|
||||||
|
vmwrite(vmcs::guest::SS_SELECTOR, 0)?;
|
||||||
|
vmwrite(vmcs::guest::DS_SELECTOR, 0)?;
|
||||||
|
vmwrite(vmcs::guest::ES_SELECTOR, 0)?;
|
||||||
|
vmwrite(vmcs::guest::FS_SELECTOR, 0)?;
|
||||||
|
vmwrite(vmcs::guest::GS_SELECTOR, 0)?;
|
||||||
|
vmwrite(vmcs::guest::TR_SELECTOR, 0)?;
|
||||||
|
vmwrite(vmcs::guest::LDTR_SELECTOR, 0)?;
|
||||||
|
vmwrite(vmcs::guest::FS_BASE, 0)?;
|
||||||
|
vmwrite(vmcs::guest::GS_BASE, 0)?;
|
||||||
|
|
||||||
vmwrite(vmcs::guest::IA32_EFER_FULL, 0)?;
|
vmwrite(vmcs::guest::IA32_EFER_FULL, 0)?;
|
||||||
|
vmwrite(vmcs::guest::IA32_EFER_HIGH, 0)?;
|
||||||
vmwrite(vmcs::guest::RFLAGS, 0x2)?;
|
vmwrite(vmcs::guest::RFLAGS, 0x2)?;
|
||||||
vmwrite(vmcs::guest::LINK_PTR_FULL, u64::MAX)?;
|
vmwrite(vmcs::guest::LINK_PTR_FULL, u64::MAX)?;
|
||||||
|
|
||||||
@ -477,9 +486,29 @@ impl VCpu {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print_guest_regs(&self) {
|
||||||
|
info!("Guest Registers:");
|
||||||
|
info!("RAX: {:#x}", self.guest_registers.rax);
|
||||||
|
info!("RBX: {:#x}", self.guest_registers.rbx);
|
||||||
|
info!("RCX: {:#x}", self.guest_registers.rcx);
|
||||||
|
info!("RDX: {:#x}", self.guest_registers.rdx);
|
||||||
|
info!("RSI: {:#x}", self.guest_registers.rsi);
|
||||||
|
info!("RDI: {:#x}", self.guest_registers.rdi);
|
||||||
|
info!("RBP: {:#x}", self.guest_registers.rbp);
|
||||||
|
info!("R8: {:#x}", self.guest_registers.r8);
|
||||||
|
info!("R9: {:#x}", self.guest_registers.r9);
|
||||||
|
info!("R10: {:#x}", self.guest_registers.r10);
|
||||||
|
info!("R11: {:#x}", self.guest_registers.r11);
|
||||||
|
info!("R12: {:#x}", self.guest_registers.r12);
|
||||||
|
info!("R13: {:#x}", self.guest_registers.r13);
|
||||||
|
info!("R14: {:#x}", self.guest_registers.r14);
|
||||||
|
info!("R15: {:#x}", self.guest_registers.r15);
|
||||||
|
}
|
||||||
|
|
||||||
fn vmentry(&mut self) -> Result<(), InstructionError> {
|
fn vmentry(&mut self) -> Result<(), InstructionError> {
|
||||||
let success = {
|
let success = {
|
||||||
let result: u16;
|
let result: u16;
|
||||||
|
self.print_guest_regs();
|
||||||
if !self.launch_done {
|
if !self.launch_done {
|
||||||
unsafe {
|
unsafe {
|
||||||
result = crate::vmm::asm::asm_vm_entry(self as *mut _);
|
result = crate::vmm::asm::asm_vm_entry(self as *mut _);
|
||||||
@ -512,6 +541,16 @@ impl VCpu {
|
|||||||
vmwrite(vmcs::host::RSP, rsp).unwrap();
|
vmwrite(vmcs::host::RSP, rsp).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn step_next_inst(&mut self) -> Result<(), VmFail> {
|
||||||
|
unsafe {
|
||||||
|
let rip = vmread(vmcs::guest::RIP)?;
|
||||||
|
vmwrite(
|
||||||
|
vmcs::guest::RIP,
|
||||||
|
rip + vmread(vmcs::ro::VMEXIT_INSTRUCTION_LEN)?,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn vmexit_handler(&mut self) {
|
fn vmexit_handler(&mut self) {
|
||||||
let info = VmxExitInfo::read();
|
let info = VmxExitInfo::read();
|
||||||
|
|
||||||
@ -530,14 +569,16 @@ impl VCpu {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
info!(
|
info!("RIP: {:#x}", unsafe { vmread(vmcs::guest::RIP) }.unwrap());
|
||||||
"vcpu RIP: {:#x}",
|
|
||||||
unsafe { vmread(vmcs::guest::RIP) }.unwrap()
|
|
||||||
);
|
|
||||||
match info.get_reason() {
|
match info.get_reason() {
|
||||||
VmxExitReason::HLT => {
|
VmxExitReason::HLT => {
|
||||||
info!("HLT instruction executed");
|
info!("HLT instruction executed");
|
||||||
}
|
}
|
||||||
|
VmxExitReason::CPUID => {
|
||||||
|
info!("CPUID instruction executed");
|
||||||
|
cpuid::handle_cpuid_exit(self);
|
||||||
|
self.step_next_inst().unwrap();
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
panic!("VMExit reason: {:?}", info.get_reason());
|
panic!("VMExit reason: {:?}", info.get_reason());
|
||||||
}
|
}
|
||||||
|
@ -629,3 +629,27 @@ impl VmxExitInfo {
|
|||||||
reason.try_into().unwrap()
|
reason.try_into().unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub enum VmxLeaf {
|
||||||
|
MAXIMUM_INPUT = 0x0,
|
||||||
|
VERSION_AND_FEATURE_INFO = 0x1,
|
||||||
|
EXTENDED_FEATURE = 0x7,
|
||||||
|
EXTENDED_ENUMERATION = 0xD,
|
||||||
|
EXTENDED_FUNCTION = 0x80000000,
|
||||||
|
EXTENDED_PROCESSOR_SIGNATURE = 0x80000001,
|
||||||
|
UNKNOWN = 0xFFFFFFFF,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VmxLeaf {
|
||||||
|
pub fn from(rax: u64) -> VmxLeaf {
|
||||||
|
match rax {
|
||||||
|
0x0 => VmxLeaf::MAXIMUM_INPUT,
|
||||||
|
0x1 => VmxLeaf::VERSION_AND_FEATURE_INFO,
|
||||||
|
0x7 => VmxLeaf::EXTENDED_FEATURE,
|
||||||
|
0xD => VmxLeaf::EXTENDED_ENUMERATION,
|
||||||
|
0x80000000 => VmxLeaf::EXTENDED_FUNCTION,
|
||||||
|
0x80000001 => VmxLeaf::EXTENDED_PROCESSOR_SIGNATURE,
|
||||||
|
_ => VmxLeaf::UNKNOWN,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user