clippy
All checks were successful
Check / Build ISO (nightly-2025-04-27) (push) Successful in 1m18s

This commit is contained in:
Masato Imai
2025-08-24 05:23:18 +00:00
parent 5df8c77ea7
commit db650f470f
17 changed files with 108 additions and 107 deletions

View File

@@ -1,9 +1,16 @@
#!/bin/sh -ex #!/bin/bash -ex
EFI_BINARY="$1" EFI_BINARY="$1"
cd ../nel_os_kernel cd ../nel_os_kernel
cargo build --release -q if [[ "$EFI_BINARY" == "target/x86_64-unknown-uefi/release/"* ]]; then
cargo build --release -q
elif [[ "$EFI_BINARY" == "target/x86_64-unknown-uefi/debug/"* ]]; then
cargo build -q
else
echo "Error: EFI binary path must contain either '/target/x86_64-unknown-uefi/release/' or '/target/x86_64-unknown-uefi/debug/'"
exit 1
fi
cd ../nel_os_bootloader cd ../nel_os_bootloader
dd if=/dev/zero of=fat.img bs=1k count=32768 dd if=/dev/zero of=fat.img bs=1k count=32768

View File

@@ -60,9 +60,7 @@ pub fn unsubscribe(callback: SubscriberCallback) -> Result<(), &'static str> {
pub fn dispatch_to_subscribers(context: &InterruptContext) { pub fn dispatch_to_subscribers(context: &InterruptContext) {
let subscribers = SUBSCRIBERS.lock(); let subscribers = SUBSCRIBERS.lock();
for subscriber in subscribers.iter() { for subscriber in subscribers.iter().flatten() {
if let Some(subscriber) = subscriber {
(subscriber.callback)(subscriber.context, context); (subscriber.callback)(subscriber.context, context);
} }
}
} }

View File

@@ -1,14 +1,14 @@
#[macro_export] #[macro_export]
macro_rules! info { macro_rules! info {
($($arg:tt)*) => ($crate::print!("[{:>12.5} I] {}\n", crate::time::get_ticks() as f64 / 1000., format_args!($($arg)*))); ($($arg:tt)*) => ($crate::print!("[{:>12.5} I] {}\n", $crate::time::get_ticks() as f64 / 1000., format_args!($($arg)*)));
} }
#[macro_export] #[macro_export]
macro_rules! error { macro_rules! error {
($($arg:tt)*) => ($crate::print!("[{:>12.5} E] {}\n", crate::time::get_ticks() as f64 / 1000., format_args!($($arg)*))); ($($arg:tt)*) => ($crate::print!("[{:>12.5} E] {}\n", $crate::time::get_ticks() as f64 / 1000., format_args!($($arg)*)));
} }
#[macro_export] #[macro_export]
macro_rules! warn { macro_rules! warn {
($($arg:tt)*) => ($crate::print!("[{:>12.5} W] {}\n", crate::time::get_ticks() as f64 / 1000., format_args!($($arg)*))); ($($arg:tt)*) => ($crate::print!("[{:>12.5} W] {}\n", $crate::time::get_ticks() as f64 / 1000., format_args!($($arg)*)));
} }

View File

@@ -30,7 +30,7 @@ use crate::{
constant::{KERNEL_STACK_SIZE, PKG_VERSION}, constant::{KERNEL_STACK_SIZE, PKG_VERSION},
graphics::{FrameBuffer, FRAME_BUFFER}, graphics::{FrameBuffer, FRAME_BUFFER},
interrupt::apic, interrupt::apic,
memory::{allocator, memory::BitmapMemoryTable, paging}, memory::{allocator, bitmap::BitmapMemoryTable, paging},
}; };
pub static BZIMAGE_ADDR: Once<u64> = Once::new(); pub static BZIMAGE_ADDR: Once<u64> = Once::new();
@@ -104,7 +104,7 @@ pub extern "sysv64" fn main(boot_info: &nel_os_common::BootInfo) {
max_range = max_range.max(range.end); max_range = max_range.max(range.end);
} }
info!("Usable memory: {}MiB", count / 1024 / 1024); info!("Usable memory: {}MiB", count / 1024 / 1024);
memory::memory::MAX_MEMORY.call_once(|| max_range as usize * 2); memory::bitmap::MAX_MEMORY.call_once(|| max_range as usize * 2);
let mut bitmap_table = BitmapMemoryTable::init(&boot_info.usable_memory); let mut bitmap_table = BitmapMemoryTable::init(&boot_info.usable_memory);
info!( info!(
@@ -133,7 +133,7 @@ pub extern "sysv64" fn main(boot_info: &nel_os_common::BootInfo) {
if boot_info.frame_buffer.is_some() { if boot_info.frame_buffer.is_some() {
let frame_buffer = let frame_buffer =
FrameBuffer::from_raw_buffer(&boot_info.frame_buffer.as_ref().unwrap(), (64, 64, 64)); FrameBuffer::from_raw_buffer(boot_info.frame_buffer.as_ref().unwrap(), (64, 64, 64));
frame_buffer.clear(); frame_buffer.clear();
FRAME_BUFFER.lock().replace(frame_buffer); FRAME_BUFFER.lock().replace(frame_buffer);

View File

@@ -1,3 +1,3 @@
pub mod allocator; pub mod allocator;
pub mod memory; pub mod bitmap;
pub mod paging; pub mod paging;

View File

@@ -46,7 +46,7 @@ pub fn load_kernel(vcpu: &mut dyn VCpu) -> Result<(), &'static str> {
256 256
}; };
let cmdline_start = LAYOUT_CMDLINE as u64; let cmdline_start = LAYOUT_CMDLINE;
let cmdline_end = cmdline_start + cmdline_max_size as u64; let cmdline_end = cmdline_start + cmdline_max_size as u64;
vcpu.write_memory_ranged(cmdline_start, cmdline_end, 0)?; vcpu.write_memory_ranged(cmdline_start, cmdline_end, 0)?;
let cmdline_val = "console=ttyS0 earlyprintk=serial nokaslr"; let cmdline_val = "console=ttyS0 earlyprintk=serial nokaslr";
@@ -128,11 +128,17 @@ pub struct BootParams {
pub _unimplemented: [u8; 0x330], pub _unimplemented: [u8; 0x330],
} }
impl Default for BootParams {
fn default() -> Self {
Self::new()
}
}
impl BootParams { impl BootParams {
pub const E820MAX: usize = 128; pub const E820MAX: usize = 128;
pub fn new() -> Self { pub fn new() -> Self {
let params = Self { Self {
_screen_info: [0; 0x40], _screen_info: [0; 0x40],
_apm_bios_info: [0; 0x14], _apm_bios_info: [0; 0x14],
_pad2: [0; 4], _pad2: [0; 4],
@@ -162,9 +168,7 @@ impl BootParams {
type_: E820Type::Ram as u32, type_: E820Type::Ram as u32,
}; Self::E820MAX], }; Self::E820MAX],
_unimplemented: [0; 0x330], _unimplemented: [0; 0x330],
}; }
params
} }
pub fn from_bytes(bytes: &[u8]) -> Result<Self, &'static str> { pub fn from_bytes(bytes: &[u8]) -> Result<Self, &'static str> {

View File

@@ -44,20 +44,20 @@ pub fn check_vmcs_control_fields() -> Result<(), &'static str> {
fn is_valid_ept_ptr(ept_ptr: u64) -> Result<(), &'static str> { fn is_valid_ept_ptr(ept_ptr: u64) -> Result<(), &'static str> {
let memory_type = ept_ptr & 0b111; let memory_type = ept_ptr & 0b111;
if memory_type != 0 && memory_type != 6 { if memory_type != 0 && memory_type != 6 {
return Err("VMCS EPT pointer memory type is not valid (must be 0 or 6)"); return Err("VMCS Ept pointer memory type is not valid (must be 0 or 6)");
} }
let walk_length = (ept_ptr >> 3) & 0b111; let walk_length = (ept_ptr >> 3) & 0b111;
if walk_length != 3 { if walk_length != 3 {
return Err("VMCS EPT pointer walk length is not valid (must be 3)"); return Err("VMCS Ept pointer walk length is not valid (must be 3)");
} }
if ept_ptr & 0xf00 != 0 { if ept_ptr & 0xf00 != 0 {
return Err("VMCS EPT pointer reserved bits are not zero"); return Err("VMCS Ept pointer reserved bits are not zero");
} }
if !is_valid_phys_addr(ept_ptr) { if !is_valid_phys_addr(ept_ptr) {
return Err("VMCS EPT pointer is not a valid physical address"); return Err("VMCS Ept pointer is not a valid physical address");
} }
Ok(()) Ok(())
@@ -72,12 +72,12 @@ fn check_ept() -> Result<(), &'static str> {
} else { } else {
if secondary_exec_ctrl.unrestricted_guest() { if secondary_exec_ctrl.unrestricted_guest() {
return Err( return Err(
"VMCS Secondary processor-based execution controls field: EPT is not set while unrestricted guest is set", "VMCS Secondary processor-based execution controls field: Ept is not set while unrestricted guest is set",
); );
} }
if secondary_exec_ctrl.mode_based_control_ept() { if secondary_exec_ctrl.mode_based_control_ept() {
return Err( return Err(
"VMCS Secondary processor-based execution controls field: EPT is not set while mode-based control for EPT is set", "VMCS Secondary processor-based execution controls field: Ept is not set while mode-based control for Ept is set",
); );
} }
} }
@@ -107,8 +107,7 @@ fn check_interrupt() -> Result<(), &'static str> {
} else { } else {
// TODO // TODO
} }
} else { } else if secondary_exec_ctrl.virtualize_x2apic_mode()
if secondary_exec_ctrl.virtualize_x2apic_mode()
|| secondary_exec_ctrl.apic_register_virtualization() || secondary_exec_ctrl.apic_register_virtualization()
|| secondary_exec_ctrl.virtual_interrupt_delivery() || secondary_exec_ctrl.virtual_interrupt_delivery()
{ {
@@ -116,7 +115,6 @@ fn check_interrupt() -> Result<(), &'static str> {
"VMCS Primary processor-based execution controls field: Use TPR shadow is not set while virtualize x2APIC mode, APIC register virtualization, or virtual interrupt delivery is set", "VMCS Primary processor-based execution controls field: Use TPR shadow is not set while virtualize x2APIC mode, APIC register virtualization, or virtual interrupt delivery is set",
); );
} }
}
// TODO // TODO
@@ -130,7 +128,7 @@ fn check_ept_violation_exception_info() -> Result<(), &'static str> {
let exception_info = vmread(vmcs::control::VIRT_EXCEPTION_INFO_ADDR_FULL)?; let exception_info = vmread(vmcs::control::VIRT_EXCEPTION_INFO_ADDR_FULL)?;
if is_valid_page_aligned_phys_addr(exception_info) { if is_valid_page_aligned_phys_addr(exception_info) {
return Err("VMCS EPT violation exception info address is not a valid page-aligned physical address"); return Err("VMCS Ept violation exception info address is not a valid page-aligned physical address");
} }
} }

View File

@@ -258,6 +258,7 @@ pub struct ExtFeatureEbx0 {
pub avx512vl: bool, pub avx512vl: bool,
} }
#[allow(clippy::enum_clike_unportable_variant)]
pub enum VmxLeaf { pub enum VmxLeaf {
MAXIMUM_INPUT = 0x0, MAXIMUM_INPUT = 0x0,
VERSION_AND_FEATURE_INFO = 0x1, VERSION_AND_FEATURE_INFO = 0x1,
@@ -268,7 +269,7 @@ pub enum VmxLeaf {
EXTENDED_FEATURE_2 = 0x80000002, EXTENDED_FEATURE_2 = 0x80000002,
EXTENDED_FEATURE_3 = 0x80000003, EXTENDED_FEATURE_3 = 0x80000003,
EXTENDED_FEATURE_4 = 0x80000004, EXTENDED_FEATURE_4 = 0x80000004,
UNKNOWN = 0xFFFFFFFF, Unknown = 0xFFFFFFFF,
} }
impl VmxLeaf { impl VmxLeaf {
@@ -283,7 +284,7 @@ impl VmxLeaf {
0x80000002 => VmxLeaf::EXTENDED_FEATURE_2, 0x80000002 => VmxLeaf::EXTENDED_FEATURE_2,
0x80000003 => VmxLeaf::EXTENDED_FEATURE_3, 0x80000003 => VmxLeaf::EXTENDED_FEATURE_3,
0x80000004 => VmxLeaf::EXTENDED_FEATURE_4, 0x80000004 => VmxLeaf::EXTENDED_FEATURE_4,
_ => VmxLeaf::UNKNOWN, _ => VmxLeaf::Unknown,
} }
} }
} }

View File

@@ -9,15 +9,15 @@ use x86_64::{
PhysAddr, PhysAddr,
}; };
pub struct EPT { pub struct Ept {
pub root_table: PhysFrame, pub root_table: PhysFrame,
} }
impl EPT { impl Ept {
pub fn new(allocator: &mut impl FrameAllocator<Size4KiB>) -> Result<Self, &'static str> { pub fn new(allocator: &mut impl FrameAllocator<Size4KiB>) -> Result<Self, &'static str> {
let root_table_frame = allocator let root_table_frame = allocator
.allocate_frame() .allocate_frame()
.ok_or("Failed to allocate EPT root table frame")?; .ok_or("Failed to allocate Ept root table frame")?;
Self::init_table(&root_table_frame); Self::init_table(&root_table_frame);
@@ -289,7 +289,7 @@ impl EPT {
#[bitfield] #[bitfield]
#[repr(u64)] #[repr(u64)]
#[derive(Debug)] #[derive(Debug)]
pub struct EPTP { pub struct Eptp {
pub typ: B3, pub typ: B3,
pub level: B3, pub level: B3,
pub dirty_accessed: bool, pub dirty_accessed: bool,
@@ -298,9 +298,9 @@ pub struct EPTP {
pub phys: B52, pub phys: B52,
} }
impl EPTP { impl Eptp {
pub fn init(lv4_table: &PhysFrame) -> Self { pub fn init(lv4_table: &PhysFrame) -> Self {
EPTP::new() Eptp::new()
.with_typ(6) .with_typ(6)
.with_level(3) .with_level(3)
.with_dirty_accessed(true) .with_dirty_accessed(true)
@@ -308,7 +308,7 @@ impl EPTP {
.with_phys(lv4_table.start_address().as_u64() >> 12) .with_phys(lv4_table.start_address().as_u64() >> 12)
} }
pub fn get_lv4_table(&self) -> &mut [EntryBase; 512] { pub fn get_lv4_table(&mut self) -> &mut [EntryBase; 512] {
let table_ptr = self.phys() << 12; let table_ptr = self.phys() << 12;
unsafe { &mut *(table_ptr as *mut [EntryBase; 512]) } unsafe { &mut *(table_ptr as *mut [EntryBase; 512]) }

View File

@@ -36,11 +36,11 @@ pub fn set_xcr(vcpu: &mut IntelVCpu, index: u32, xcr: u64) -> Result<(), &'stati
return Err("Invalid XCR index"); return Err("Invalid XCR index");
} }
if !(xcr & 0b1 != 0) { if xcr & 0b1 == 0 {
return Err("X87 is not enabled"); return Err("X87 is not enabled");
} }
if (xcr & 0b100 != 0) && !(xcr & 0b10 != 0) { if (xcr & 0b100 != 0) && (xcr & 0b10 == 0) {
return Err("SSE is not enabled"); return Err("SSE is not enabled");
} }
@@ -49,7 +49,7 @@ pub fn set_xcr(vcpu: &mut IntelVCpu, index: u32, xcr: u64) -> Result<(), &'stati
} }
if xcr & 0b11100000 != 0 { if xcr & 0b11100000 != 0 {
if !(xcr & 0b100 != 0) { if xcr & 0b100 == 0 {
return Err("YMM bits are not enabled"); return Err("YMM bits are not enabled");
} }

View File

@@ -33,11 +33,11 @@ pub enum InitPhase {
} }
pub enum ReadSel { pub enum ReadSel {
IRR, Irr,
ISR, Isr,
} }
pub struct PIC { pub struct Pic {
pub primary_mask: u8, pub primary_mask: u8,
pub secondary_mask: u8, pub secondary_mask: u8,
pub primary_phase: InitPhase, pub primary_phase: InitPhase,
@@ -52,7 +52,7 @@ pub struct PIC {
pub secondary_read_sel: ReadSel, pub secondary_read_sel: ReadSel,
} }
impl PIC { impl Pic {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
primary_mask: 0xFF, primary_mask: 0xFF,
@@ -65,8 +65,8 @@ impl PIC {
primary_isr: 0, primary_isr: 0,
secondary_irr: 0, secondary_irr: 0,
secondary_isr: 0, secondary_isr: 0,
primary_read_sel: ReadSel::IRR, primary_read_sel: ReadSel::Irr,
secondary_read_sel: ReadSel::IRR, secondary_read_sel: ReadSel::Irr,
} }
} }
@@ -160,10 +160,7 @@ impl PIC {
vector: u32, vector: u32,
error_code: Option<u32>, error_code: Option<u32>,
) -> Result<(), &'static str> { ) -> Result<(), &'static str> {
let has_error_code = match vector { let has_error_code = matches!(vector, 8 | 10..=14 | 17 | 21);
8 | 10..=14 | 17 | 21 => true,
_ => false,
};
let interrupt_info = EntryIntrInfo::new() let interrupt_info = EntryIntrInfo::new()
.with_vector(vector as u8) .with_vector(vector as u8)
@@ -210,15 +207,15 @@ impl PIC {
match qual.port() { match qual.port() {
0x20 => { 0x20 => {
let v = match self.primary_read_sel { let v = match self.primary_read_sel {
ReadSel::IRR => self.primary_irr, ReadSel::Irr => self.primary_irr,
ReadSel::ISR => self.primary_isr, ReadSel::Isr => self.primary_isr,
}; };
regs.rax = v as u64; regs.rax = v as u64;
} }
0xA0 => { 0xA0 => {
let v = match self.secondary_read_sel { let v = match self.secondary_read_sel {
ReadSel::IRR => self.secondary_irr, ReadSel::Irr => self.secondary_irr,
ReadSel::ISR => self.secondary_isr, ReadSel::Isr => self.secondary_isr,
}; };
regs.rax = v as u64; regs.rax = v as u64;
} }
@@ -244,8 +241,8 @@ impl PIC {
match qual.port() { match qual.port() {
0x20 => match dx { 0x20 => match dx {
0x11 => pic.primary_phase = InitPhase::Phase1, 0x11 => pic.primary_phase = InitPhase::Phase1,
0x0A => pic.primary_read_sel = ReadSel::ISR, 0x0A => pic.primary_read_sel = ReadSel::Isr,
0x0B => pic.primary_read_sel = ReadSel::IRR, 0x0B => pic.primary_read_sel = ReadSel::Irr,
0x20 => { 0x20 => {
pic.primary_isr = 0; pic.primary_isr = 0;
} }
@@ -253,7 +250,7 @@ impl PIC {
let irq = dx & 0x7; let irq = dx & 0x7;
pic.primary_isr &= !(1 << irq); pic.primary_isr &= !(1 << irq);
} }
_ => panic!("Primary PIC command: {:#x}", dx), _ => panic!("Primary Pic command: {:#x}", dx),
}, },
0x21 => match pic.primary_phase { 0x21 => match pic.primary_phase {
InitPhase::Uninitialized | InitPhase::Initialized => pic.primary_mask = dx, InitPhase::Uninitialized | InitPhase::Initialized => pic.primary_mask = dx,
@@ -265,14 +262,14 @@ impl PIC {
pic.primary_phase = InitPhase::Phase3; pic.primary_phase = InitPhase::Phase3;
} }
InitPhase::Phase3 => { InitPhase::Phase3 => {
info!("Primary PIC Initialized"); info!("Primary Pic Initialized");
pic.primary_phase = InitPhase::Initialized pic.primary_phase = InitPhase::Initialized
} }
}, },
0xA0 => match dx { 0xA0 => match dx {
0x11 => pic.secondary_phase = InitPhase::Phase1, 0x11 => pic.secondary_phase = InitPhase::Phase1,
0x0A => pic.secondary_read_sel = ReadSel::ISR, 0x0A => pic.secondary_read_sel = ReadSel::Isr,
0x0B => pic.secondary_read_sel = ReadSel::IRR, 0x0B => pic.secondary_read_sel = ReadSel::Irr,
0x20 => { 0x20 => {
pic.secondary_isr = 0; pic.secondary_isr = 0;
} }
@@ -280,7 +277,7 @@ impl PIC {
let irq = dx & 0x7; let irq = dx & 0x7;
pic.secondary_isr &= !(1 << irq); pic.secondary_isr &= !(1 << irq);
} }
_ => panic!("Secondary PIC command: {:#x}", dx), _ => panic!("Secondary Pic command: {:#x}", dx),
}, },
0xA1 => match pic.secondary_phase { 0xA1 => match pic.secondary_phase {
InitPhase::Uninitialized | InitPhase::Initialized => pic.secondary_mask = dx, InitPhase::Uninitialized | InitPhase::Initialized => pic.secondary_mask = dx,
@@ -292,7 +289,7 @@ impl PIC {
pic.secondary_phase = InitPhase::Phase3; pic.secondary_phase = InitPhase::Phase3;
} }
InitPhase::Phase3 => { InitPhase::Phase3 => {
info!("Secondary PIC Initialized"); info!("Secondary Pic Initialized");
pic.secondary_phase = InitPhase::Initialized pic.secondary_phase = InitPhase::Initialized
} }
}, },
@@ -353,13 +350,13 @@ impl IOBitmap {
} }
} }
fn get_bitmap_a(&self) -> &mut [u8] { fn get_bitmap_a(&mut self) -> &mut [u8] {
unsafe { unsafe {
core::slice::from_raw_parts_mut(self.bitmap_a.start_address().as_u64() as *mut u8, 4096) core::slice::from_raw_parts_mut(self.bitmap_a.start_address().as_u64() as *mut u8, 4096)
} }
} }
fn get_bitmap_b(&self) -> &mut [u8] { fn get_bitmap_b(&mut self) -> &mut [u8] {
unsafe { unsafe {
core::slice::from_raw_parts_mut(self.bitmap_b.start_address().as_u64() as *mut u8, 4096) core::slice::from_raw_parts_mut(self.bitmap_b.start_address().as_u64() as *mut u8, 4096)
} }

View File

@@ -12,7 +12,7 @@ type MsrIndex = u32;
const MAX_NUM_ENTS: usize = 512; const MAX_NUM_ENTS: usize = 512;
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy, Default)]
#[repr(C, packed)] #[repr(C, packed)]
pub struct SavedMsr { pub struct SavedMsr {
pub index: MsrIndex, pub index: MsrIndex,
@@ -20,16 +20,6 @@ pub struct SavedMsr {
pub data: u64, pub data: u64,
} }
impl Default for SavedMsr {
fn default() -> Self {
Self {
index: 0,
reserved: 0,
data: 0,
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct ShadowMsr { pub struct ShadowMsr {
ents: Vec<SavedMsr>, ents: Vec<SavedMsr>,
@@ -126,6 +116,12 @@ pub fn _update_msrs(vcpu: &mut IntelVCpu) -> Result<(), MsrError> {
Ok(()) Ok(())
} }
impl Default for ShadowMsr {
fn default() -> Self {
Self::new()
}
}
impl ShadowMsr { impl ShadowMsr {
pub fn new() -> Self { pub fn new() -> Self {
let ents = vec![]; let ents = vec![];

View File

@@ -46,13 +46,13 @@ pub struct IntelVCpu {
activated: bool, activated: bool,
vmxon: vmxon::Vmxon, vmxon: vmxon::Vmxon,
vmcs: vmcs::Vmcs, vmcs: vmcs::Vmcs,
ept: ept::EPT, ept: ept::Ept,
eptp: ept::EPTP, eptp: ept::Eptp,
guest_memory_size: u64, guest_memory_size: u64,
pub host_msr: ShadowMsr, pub host_msr: ShadowMsr,
pub guest_msr: ShadowMsr, pub guest_msr: ShadowMsr,
pub ia32e_enabled: bool, pub ia32e_enabled: bool,
pic: super::io::PIC, pic: super::io::Pic,
io_bitmap: IOBitmap, io_bitmap: IOBitmap,
pub pending_irq: u16, pub pending_irq: u16,
pub host_xcr0: u64, pub host_xcr0: u64,
@@ -155,8 +155,8 @@ impl IntelVCpu {
} }
VmxExitReason::EPT_VIOLATION => { VmxExitReason::EPT_VIOLATION => {
let guest_address = vmread(vmcs::ro::GUEST_PHYSICAL_ADDR_FULL)?; let guest_address = vmread(vmcs::ro::GUEST_PHYSICAL_ADDR_FULL)?;
info!("EPT Violation at guest address: {:#x}", guest_address); info!("Ept Violation at guest address: {:#x}", guest_address);
return Err("EPT Violation"); return Err("Ept Violation");
} }
VmxExitReason::TRIPLE_FAULT => { VmxExitReason::TRIPLE_FAULT => {
info!("Triple fault detected"); info!("Triple fault detected");
@@ -378,7 +378,7 @@ impl IntelVCpu {
pages -= 1; pages -= 1;
} }
let eptp = ept::EPTP::init(&self.ept.root_table); let eptp = ept::Eptp::init(&self.ept.root_table);
vmwrite(x86::vmx::vmcs::control::EPTP_FULL, u64::from(eptp))?; vmwrite(x86::vmx::vmcs::control::EPTP_FULL, u64::from(eptp))?;
Ok(()) Ok(())
@@ -397,7 +397,7 @@ impl IntelVCpu {
vmwrite( vmwrite(
vmcs::host::RIP, vmcs::host::RIP,
crate::vmm::x86_64::intel::asm::asm_vmexit_handler as u64, crate::vmm::x86_64::intel::asm::asm_vmexit_handler as usize as u64,
)?; )?;
vmwrite( vmwrite(
vmcs::host::RSP, vmcs::host::RSP,
@@ -556,11 +556,11 @@ impl IntelVCpu {
return Ok(vaddr & 0xFFFFFFFF); return Ok(vaddr & 0xFFFFFFFF);
} }
let pml4_idx = ((vaddr >> 39) & 0x1FF) as u64; let pml4_idx = (vaddr >> 39) & 0x1FF;
let pdpt_idx = ((vaddr >> 30) & 0x1FF) as u64; let pdpt_idx = (vaddr >> 30) & 0x1FF;
let pd_idx = ((vaddr >> 21) & 0x1FF) as u64; let pd_idx = (vaddr >> 21) & 0x1FF;
let pt_idx = ((vaddr >> 12) & 0x1FF) as u64; let pt_idx = (vaddr >> 12) & 0x1FF;
let page_offset = (vaddr & 0xFFF) as u64; let page_offset = vaddr & 0xFFF;
let pml4_entry_addr = pml4_base + (pml4_idx * 8); let pml4_entry_addr = pml4_base + (pml4_idx * 8);
let pml4_entry = self.read_guest_phys_u64(pml4_entry_addr)?; let pml4_entry = self.read_guest_phys_u64(pml4_entry_addr)?;
@@ -609,7 +609,7 @@ impl IntelVCpu {
for i in 0..8 { for i in 0..8 {
match self.ept.get(gpa + i) { match self.ept.get(gpa + i) {
Ok(byte) => result_bytes[i as usize] = byte, Ok(byte) => result_bytes[i as usize] = byte,
Err(_) => return Err("Failed to read from EPT"), Err(_) => return Err("Failed to read from Ept"),
} }
} }
@@ -645,9 +645,9 @@ impl IntelVCpu {
let exit_ctrl = vmread(x86::vmx::vmcs::control::VMEXIT_CONTROLS)?; let exit_ctrl = vmread(x86::vmx::vmcs::control::VMEXIT_CONTROLS)?;
info!("VM-exit controls: {:#x}", exit_ctrl); info!("VM-exit controls: {:#x}", exit_ctrl);
// EPT pointer // Ept pointer
let eptp = vmread(x86::vmx::vmcs::control::EPTP_FULL)?; let eptp = vmread(x86::vmx::vmcs::control::EPTP_FULL)?;
info!("EPT pointer: {:#x}", eptp); info!("Ept pointer: {:#x}", eptp);
info!("=== Guest State ==="); info!("=== Guest State ===");
@@ -899,8 +899,8 @@ impl VCpu for IntelVCpu {
let vmcs = vmcs::Vmcs::new(frame_allocator)?; let vmcs = vmcs::Vmcs::new(frame_allocator)?;
let ept = ept::EPT::new(frame_allocator)?; let ept = ept::Ept::new(frame_allocator)?;
let eptp = ept::EPTP::init(&ept.root_table); let eptp = ept::Eptp::init(&ept.root_table);
Ok(IntelVCpu { Ok(IntelVCpu {
launch_done: false, launch_done: false,
@@ -914,7 +914,7 @@ impl VCpu for IntelVCpu {
host_msr: ShadowMsr::new(), host_msr: ShadowMsr::new(),
guest_msr: ShadowMsr::new(), guest_msr: ShadowMsr::new(),
ia32e_enabled: false, ia32e_enabled: false,
pic: super::io::PIC::new(), pic: super::io::Pic::new(),
io_bitmap: IOBitmap::new(frame_allocator), io_bitmap: IOBitmap::new(frame_allocator),
pending_irq: 0, pending_irq: 0,
host_xcr0: 0, host_xcr0: 0,

View File

@@ -23,7 +23,7 @@ impl PinBasedVmExecutionControls {
pub fn read() -> Result<Self, &'static str> { pub fn read() -> Result<Self, &'static str> {
vmcs::VmcsControl32::PIN_BASED_VM_EXECUTION_CONTROLS vmcs::VmcsControl32::PIN_BASED_VM_EXECUTION_CONTROLS
.read() .read()
.map(|value| PinBasedVmExecutionControls::from(value)) .map(PinBasedVmExecutionControls::from)
.map_err(|_| "Failed to read Pin-Based VM Execution Controls") .map_err(|_| "Failed to read Pin-Based VM Execution Controls")
} }
@@ -70,7 +70,7 @@ impl PrimaryProcessorBasedVmExecutionControls {
pub fn read() -> Result<Self, &'static str> { pub fn read() -> Result<Self, &'static str> {
vmcs::VmcsControl32::PRIMARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS vmcs::VmcsControl32::PRIMARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS
.read() .read()
.map(|value| PrimaryProcessorBasedVmExecutionControls::from(value)) .map(PrimaryProcessorBasedVmExecutionControls::from)
.map_err(|_| "Failed to read Primary Processor-Based VM Execution Controls") .map_err(|_| "Failed to read Primary Processor-Based VM Execution Controls")
} }
@@ -121,7 +121,7 @@ impl SecondaryProcessorBasedVmExecutionControls {
pub fn read() -> Result<Self, &'static str> { pub fn read() -> Result<Self, &'static str> {
vmcs::VmcsControl32::SECONDARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS vmcs::VmcsControl32::SECONDARY_PROCESSOR_BASED_VM_EXECUTION_CONTROLS
.read() .read()
.map(|value| SecondaryProcessorBasedVmExecutionControls::from(value)) .map(SecondaryProcessorBasedVmExecutionControls::from)
.map_err(|_| "Failed to read Secondary Processor-Based VM Execution Controls") .map_err(|_| "Failed to read Secondary Processor-Based VM Execution Controls")
} }
@@ -158,7 +158,7 @@ impl EntryControls {
pub fn read() -> Result<Self, &'static str> { pub fn read() -> Result<Self, &'static str> {
vmcs::VmcsControl32::VM_ENTRY_CONTROLS vmcs::VmcsControl32::VM_ENTRY_CONTROLS
.read() .read()
.map(|value| EntryControls::from(value)) .map(EntryControls::from)
.map_err(|_| "Failed to read VM Entry Controls") .map_err(|_| "Failed to read VM Entry Controls")
} }
@@ -200,7 +200,7 @@ impl PrimaryExitControls {
pub fn read() -> Result<Self, &'static str> { pub fn read() -> Result<Self, &'static str> {
vmcs::VmcsControl32::PRIMARY_VM_EXIT_CONTROLS vmcs::VmcsControl32::PRIMARY_VM_EXIT_CONTROLS
.read() .read()
.map(|value| PrimaryExitControls::from(value)) .map(PrimaryExitControls::from)
.map_err(|_| "Failed to read Primary VM Exit Controls") .map_err(|_| "Failed to read Primary VM Exit Controls")
} }

View File

@@ -42,7 +42,7 @@ impl InstructionError {
InstructionError::try_from(err).map_err(|_| "Unknown instruction error") InstructionError::try_from(err).map_err(|_| "Unknown instruction error")
} }
pub fn to_str(&self) -> &'static str { pub fn to_str(self) -> &'static str {
match self { match self {
InstructionError::NOT_AVAILABLE => "Instruction not available", InstructionError::NOT_AVAILABLE => "Instruction not available",
InstructionError::VMCALL_IN_VMXROOT => "VMCALL in VMX root operation", InstructionError::VMCALL_IN_VMXROOT => "VMCALL in VMX root operation",

View File

@@ -139,8 +139,8 @@ impl VmxExitReason {
VIRTUALIZED_EOI => "Virtualized EOI", VIRTUALIZED_EOI => "Virtualized EOI",
ACCESS_TO_GDTR_OR_IDTR => "Access to GDTR or IDTR", ACCESS_TO_GDTR_OR_IDTR => "Access to GDTR or IDTR",
ACCESS_TO_LDTR_OR_TR => "Access to LDTR or TR", ACCESS_TO_LDTR_OR_TR => "Access to LDTR or TR",
EPT_VIOLATION => "EPT violation", EPT_VIOLATION => "Ept violation",
EPT_MISCONFIGURATION => "EPT misconfiguration", EPT_MISCONFIGURATION => "Ept misconfiguration",
INVEPT => "INVEPT instruction execution", INVEPT => "INVEPT instruction execution",
RDTSCP => "RDTSCP instruction execution", RDTSCP => "RDTSCP instruction execution",
VMX_PREEMPTION_TIMER_EXPIRED => "VMX-preemption timer expired", VMX_PREEMPTION_TIMER_EXPIRED => "VMX-preemption timer expired",