This commit is contained in:
Masato Imai
2025-05-02 12:17:36 +00:00
parent 7168cd0826
commit 19244695d8
5 changed files with 232 additions and 20 deletions

View File

@@ -111,6 +111,7 @@ impl EPT {
let lv4_index = (gpa >> 39) & 0x1FF;
let lv3_index = (gpa >> 30) & 0x1FF;
let lv2_index = (gpa >> 21) & 0x1FF;
let page_offset = gpa & 0x1FFFFF;
let lv4_table = Self::frame_to_table_ptr(&self.root_table);
let lv4_entry = &lv4_table[lv4_index as usize];
@@ -130,7 +131,19 @@ impl EPT {
return None;
}
Some(lv2_entry.address().as_u64())
let phys_addr_base = lv2_entry.address().as_u64();
Some(phys_addr_base | page_offset)
}
pub fn get(&mut self, gpa: u64) -> Result<u8, &'static str> {
let hpa = self
.get_phys_addr(gpa)
.ok_or("Failed to get physical address")?;
let phys_addr_offset = memory::PHYSICAL_MEMORY_OFFSET.load(Ordering::Relaxed);
let hpa = hpa + phys_addr_offset;
let guest_memory = unsafe { &*(hpa as *const u8) };
Ok(*guest_memory)
}
pub fn set(&mut self, gpa: u64, value: u8) -> Result<(), &'static str> {
@@ -140,9 +153,8 @@ impl EPT {
let phys_addr_offset = memory::PHYSICAL_MEMORY_OFFSET.load(Ordering::Relaxed);
let hpa = hpa + phys_addr_offset;
let guest_memory = unsafe { &mut *(hpa as *mut [u8; 0x100000]) };
let offset = (gpa & 0xFFFFF) as usize;
guest_memory[offset] = value;
let guest_memory = unsafe { &mut *(hpa as *mut u8) };
*guest_memory = value;
Ok(())
}

View File

@@ -1,5 +1,7 @@
use core::ptr::read_unaligned;
use crate::info;
pub const BZIMAGE: &'static [u8] = include_bytes!("../../bzImage");
pub const LAYOUT_BOOTPARAM: u64 = 0x0001_0000;
@@ -40,15 +42,48 @@ pub struct BootParams {
impl BootParams {
pub const E820MAX: usize = 128;
pub fn from_bytes(bytes: &[u8]) -> Result<Self, &'static str> {
if bytes.len() < size_of::<Self>() {
return Err("バイト配列が小さすぎます");
}
pub fn new() -> Self {
let params = Self {
_screen_info: [0; 0x40],
_apm_bios_info: [0; 0x14],
_pad2: [0; 4],
tboot_addr: 0,
ist_info: [0; 0x10],
_pad3: [0; 0x10],
hd0_info: [0; 0x10],
hd1_info: [0; 0x10],
_sys_desc_table: [0; 0x10],
_olpc_ofw_header: [0; 0x10],
_pad4: [0; 0x80],
_edid_info: [0; 0x80],
_efi_info: [0; 0x20],
alt_mem_k: 0,
scratch: 0,
e820_entries: 0,
eddbuf_entries: 0,
edd_mbr_sig_buf_entries: 0,
kbd_status: 0,
_pad6: [0; 5],
hdr: SetupHeader::default(),
_pad7: [0; 0x290 - SetupHeader::HEADER_OFFSET - size_of::<SetupHeader>()],
_edd_mbr_sig_buffer: [0; 0x10],
e820_map: [E820Entry {
addr: 0,
size: 0,
type_: E820Type::Ram as u32,
}; Self::E820MAX],
_unimplemented: [0; 0x330],
};
unsafe {
let boot_params_ptr = bytes.as_ptr() as *const Self;
Ok(read_unaligned(boot_params_ptr))
}
params
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self, &'static str> {
let hdr = SetupHeader::from_bytes(bytes)?;
info!("hdr: {:?}", hdr);
let mut bp = BootParams::new();
bp.hdr = hdr;
Ok(bp)
}
pub fn add_e820_entry(&mut self, addr: u64, size: u64, type_: E820Type) {
@@ -60,7 +95,7 @@ impl BootParams {
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, Default)]
pub struct SetupHeader {
pub setup_sects: u8,
pub root_flags: u16,
@@ -111,16 +146,16 @@ impl SetupHeader {
return Err("バイト配列が小さすぎます");
}
let mut header = unsafe {
let mut hdr = unsafe {
let header_ptr = bytes.as_ptr().add(Self::HEADER_OFFSET) as *const Self;
read_unaligned(header_ptr)
};
if header.setup_sects == 0 {
header.setup_sects = 4;
if hdr.setup_sects == 0 {
hdr.setup_sects = 4;
}
Ok(header)
Ok(hdr)
}
pub fn get_protected_code_offset(&self) -> usize {
@@ -129,7 +164,7 @@ impl SetupHeader {
}
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, Default)]
pub struct LoadflagBitfield {
raw: u8,
}

View File

@@ -1,3 +1,4 @@
use rand::{Rng, SeedableRng};
use x86::{
bits64::vmx::{vmread, vmwrite},
controlregs::{cr0, cr3, cr4, Cr0},
@@ -12,7 +13,6 @@ use core::sync::atomic::Ordering;
use crate::{
info,
memory::{self, BootInfoFrameAllocator},
serial_print,
vmm::vmcs::{
DescriptorType, EntryControls, Granularity, PrimaryExitControls,
PrimaryProcessorBasedVmExecutionControls, SecondaryProcessorBasedVmExecutionControls,
@@ -118,6 +118,7 @@ impl VCpu {
core::mem::size_of::<BootParams>(),
)
};
info!("BootParams: {:?}", bp);
self.load_image(bp_bytes, linux::LAYOUT_BOOTPARAM as usize);
let code_offset = bp.hdr.get_protected_code_offset();
@@ -137,6 +138,38 @@ impl VCpu {
}
}
pub fn test_guest_memory(&mut self) {
for x in 1..=1024 {
let mut gpa = 0;
let start = 100 * 1024 * (x - 1);
let end = 100 * 1024 * x;
let mut random_data = [0u8; 100 * 1024];
let mut rng = rand::rngs::SmallRng::from_seed([0u8; 16]);
for byte in random_data.iter_mut() {
*byte = rng.gen();
}
self.load_image(&random_data, start);
while gpa < 100 * 1024 {
let value = self.ept.get((gpa + start) as u64).unwrap();
if value != random_data[gpa] {
panic!("Guest memory test failed at {:#x}", gpa);
}
gpa += 1;
}
info!(
"Guest memory test passed for range {:#x} - {:#x}",
start, end
);
}
let start = 100 * 1024 * 0;
let end = 100 * 1024 * 1024;
self.ept.set_range(start as u64, end as u64, 0).unwrap();
}
pub fn setup_guest_memory(&mut self, frame_allocator: &mut BootInfoFrameAllocator) {
let mut pages = 100;
let mut gpa = 0;
@@ -154,6 +187,8 @@ impl VCpu {
}
info!("Guest memory setup complete");
self.test_guest_memory();
self.load_kernel(linux::BZIMAGE);
unsafe {
let phys_mem_offset = memory::PHYSICAL_MEMORY_OFFSET.load(Ordering::Relaxed);