Skip to content

Commit f67ac9f

Browse files
committed
[host/hypervisor/[*]] update drivers to use CGM
Updates drivers to map memory region in accordance to CGM usage. > Note: only updated KVM fully so far. WHP and inprocess drivers are TODOs. Signed-off-by: danbugs <danilochiarlone@gmail.com>
1 parent 588af6f commit f67ac9f

File tree

4 files changed

+236
-190
lines changed

4 files changed

+236
-190
lines changed

src/hyperlight_host/src/hypervisor/hyperv_linux.rs

Lines changed: 106 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ use mshv_bindings::{
3838
use mshv_bindings::{
3939
hv_message_type, hv_message_type_HVMSG_GPA_INTERCEPT, hv_message_type_HVMSG_UNMAPPED_GPA,
4040
hv_message_type_HVMSG_X64_HALT, hv_message_type_HVMSG_X64_IO_PORT_INTERCEPT, hv_register_assoc,
41-
hv_register_name_HV_X64_REGISTER_RIP, hv_register_value, mshv_user_mem_region,
42-
FloatingPointUnit, SegmentRegister, SpecialRegisters, StandardRegisters,
41+
hv_register_name_HV_X64_REGISTER_RIP, hv_register_value, FloatingPointUnit, SegmentRegister,
42+
SpecialRegisters, StandardRegisters,
4343
};
4444
#[cfg(mshv3)]
4545
use mshv_bindings::{
@@ -61,7 +61,7 @@ use super::{
6161
};
6262
use crate::hypervisor::hypervisor_handler::HypervisorHandler;
6363
use crate::hypervisor::HyperlightExit;
64-
use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags};
64+
use crate::sandbox::sandbox_builder::SandboxMemorySections;
6565
use crate::mem::ptr::{GuestPtr, RawPtr};
6666
#[cfg(gdb)]
6767
use crate::HyperlightError;
@@ -289,10 +289,12 @@ pub(crate) fn is_hypervisor_present() -> bool {
289289
/// called the Microsoft Hypervisor (MSHV)
290290
pub(super) struct HypervLinuxDriver {
291291
_mshv: Mshv,
292+
// TODO(danbugs:297): remove
293+
#[allow(dead_code)]
292294
vm_fd: VmFd,
293295
vcpu_fd: VcpuFd,
294296
entrypoint: u64,
295-
mem_regions: Vec<MemoryRegion>,
297+
mem_sections: SandboxMemorySections,
296298
orig_rsp: GuestPtr,
297299

298300
#[cfg(gdb)]
@@ -312,7 +314,7 @@ impl HypervLinuxDriver {
312314
/// `initialise` to do it for you.
313315
#[instrument(skip_all, parent = Span::current(), level = "Trace")]
314316
pub(super) fn new(
315-
mem_regions: Vec<MemoryRegion>,
317+
mem_sections: SandboxMemorySections,
316318
entrypoint_ptr: GuestPtr,
317319
rsp_ptr: GuestPtr,
318320
pml4_ptr: GuestPtr,
@@ -377,18 +379,19 @@ impl HypervLinuxDriver {
377379
(None, None)
378380
};
379381

380-
mem_regions.iter().try_for_each(|region| {
381-
let mshv_region = region.to_owned().into();
382-
vm_fd.map_user_memory(mshv_region)
383-
})?;
382+
// TODO(danbugs:297): bring back
383+
// mem_sections.iter().try_for_each(|region| {
384+
// let mshv_region = region.to_owned().into();
385+
// vm_fd.map_user_memory(mshv_region)
386+
// })?;
384387

385388
Self::setup_initial_sregs(&mut vcpu_fd, pml4_ptr.absolute()?)?;
386389

387390
Ok(Self {
388391
_mshv: mshv,
389392
vm_fd,
390393
vcpu_fd,
391-
mem_regions,
394+
mem_sections,
392395
entrypoint: entrypoint_ptr.absolute()?,
393396
orig_rsp: rsp_ptr,
394397

@@ -433,7 +436,7 @@ impl Debug for HypervLinuxDriver {
433436
f.field("Entrypoint", &self.entrypoint)
434437
.field("Original RSP", &self.orig_rsp);
435438

436-
for region in &self.mem_regions {
439+
for region in self.mem_sections.iter() {
437440
f.field("Memory Region", &region);
438441
}
439442

@@ -457,9 +460,9 @@ impl Hypervisor for HypervLinuxDriver {
457460
#[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")]
458461
fn initialise(
459462
&mut self,
460-
peb_addr: RawPtr,
463+
hyperlight_peb_guest_memory_region_address: u64,
464+
hyperlight_peb_guest_memory_region_size: u64,
461465
seed: u64,
462-
page_size: u32,
463466
outb_hdl: OutBHandlerWrapper,
464467
mem_access_hdl: MemAccessHandlerWrapper,
465468
hv_handler: Option<HypervisorHandler>,
@@ -477,9 +480,9 @@ impl Hypervisor for HypervLinuxDriver {
477480
rflags: 2, //bit 1 of rlags is required to be set
478481

479482
// function args
480-
rcx: peb_addr.into(),
481-
rdx: seed,
482-
r8: page_size.into(),
483+
rcx: hyperlight_peb_guest_memory_region_address.into(),
484+
rdx: hyperlight_peb_guest_memory_region_size.into(),
485+
r8: seed.into(),
483486
r9: max_guest_log_level,
484487

485488
..Default::default()
@@ -615,20 +618,24 @@ impl Hypervisor for HypervLinuxDriver {
615618
INVALID_GPA_ACCESS_MESSAGE => {
616619
let mimo_message = m.to_memory_info()?;
617620
let gpa = mimo_message.guest_physical_address;
618-
let access_info = MemoryRegionFlags::try_from(mimo_message)?;
621+
// TODO(danbugs:297): bring back
622+
// let access_info = MemoryRegionFlags::try_from(mimo_message)?;
619623
crate::debug!(
620624
"mshv MMIO invalid GPA access -Details: Address: {} \n {:#?}",
621625
gpa,
622626
&self
623627
);
624-
match self.get_memory_access_violation(
625-
gpa as usize,
626-
&self.mem_regions,
627-
access_info,
628-
) {
629-
Some(access_info_violation) => access_info_violation,
630-
None => HyperlightExit::Mmio(gpa),
631-
}
628+
// TODO(danbugs:297): bring back
629+
// match self.get_memory_access_violation(
630+
// gpa as usize,
631+
// &self.mem_regions,
632+
// access_info,
633+
// ) {
634+
// Some(access_info_violation) => access_info_violation,
635+
// None => HyperlightExit::Mmio(gpa),
636+
// }
637+
638+
HyperlightExit::Mmio(gpa)
632639
}
633640
// The only case an intercept exit is expected is when debugging is enabled
634641
// and the intercepts are installed
@@ -662,10 +669,11 @@ impl Hypervisor for HypervLinuxDriver {
662669
self as &mut dyn Hypervisor
663670
}
664671

665-
#[cfg(crashdump)]
666-
fn get_memory_regions(&self) -> &[MemoryRegion] {
667-
&self.mem_regions
668-
}
672+
// TODO(danbugs:297): bring back
673+
// #[cfg(crashdump)]
674+
// fn get_memory_regions(&self) -> &[MemoryRegion] {
675+
// &self.mem_sections
676+
// }
669677

670678
#[cfg(gdb)]
671679
fn handle_debug(
@@ -713,71 +721,73 @@ impl Hypervisor for HypervLinuxDriver {
713721
}
714722
}
715723

716-
impl Drop for HypervLinuxDriver {
717-
#[instrument(skip_all, parent = Span::current(), level = "Trace")]
718-
fn drop(&mut self) {
719-
for region in &self.mem_regions {
720-
let mshv_region: mshv_user_mem_region = region.to_owned().into();
721-
match self.vm_fd.unmap_user_memory(mshv_region) {
722-
Ok(_) => (),
723-
Err(e) => error!("Failed to unmap user memory in HyperVOnLinux ({:?})", e),
724-
}
725-
}
726-
}
727-
}
728-
729-
#[cfg(test)]
730-
mod tests {
731-
use super::*;
732-
use crate::mem::memory_region::MemoryRegionVecBuilder;
733-
use crate::mem::shared_mem::{ExclusiveSharedMemory, SharedMemory};
734-
735-
#[rustfmt::skip]
736-
const CODE: [u8; 12] = [
737-
0xba, 0xf8, 0x03, /* mov $0x3f8, %dx */
738-
0x00, 0xd8, /* add %bl, %al */
739-
0x04, b'0', /* add $'0', %al */
740-
0xee, /* out %al, (%dx) */
741-
/* send a 0 to indicate we're done */
742-
0xb0, b'\0', /* mov $'\0', %al */
743-
0xee, /* out %al, (%dx) */
744-
0xf4, /* HLT */
745-
];
746-
747-
fn shared_mem_with_code(
748-
code: &[u8],
749-
mem_size: usize,
750-
load_offset: usize,
751-
) -> Result<Box<ExclusiveSharedMemory>> {
752-
if load_offset > mem_size {
753-
log_then_return!(
754-
"code load offset ({}) > memory size ({})",
755-
load_offset,
756-
mem_size
757-
);
758-
}
759-
let mut shared_mem = ExclusiveSharedMemory::new(mem_size)?;
760-
shared_mem.copy_from_slice(code, load_offset)?;
761-
Ok(Box::new(shared_mem))
762-
}
763-
764-
#[test]
765-
fn create_driver() {
766-
if !super::is_hypervisor_present() {
767-
return;
768-
}
769-
const MEM_SIZE: usize = 0x3000;
770-
let gm = shared_mem_with_code(CODE.as_slice(), MEM_SIZE, 0).unwrap();
771-
let rsp_ptr = GuestPtr::try_from(0).unwrap();
772-
let pml4_ptr = GuestPtr::try_from(0).unwrap();
773-
let entrypoint_ptr = GuestPtr::try_from(0).unwrap();
774-
let mut regions = MemoryRegionVecBuilder::new(0, gm.base_addr());
775-
regions.push_page_aligned(
776-
MEM_SIZE,
777-
MemoryRegionFlags::READ | MemoryRegionFlags::WRITE | MemoryRegionFlags::EXECUTE,
778-
crate::mem::memory_region::MemoryRegionType::Code,
779-
);
780-
super::HypervLinuxDriver::new(
724+
// TODO(danbugs:297): bring back
725+
// impl Drop for HypervLinuxDriver {
726+
// #[instrument(skip_all, parent = Span::current(), level = "Trace")]
727+
// fn drop(&mut self) {
728+
// for region in self.mem_sections.iter() {
729+
// let mshv_region: mshv_user_mem_region = region.to_owned().into();
730+
// match self.vm_fd.unmap_user_memory(mshv_region) {
731+
// Ok(_) => (),
732+
// Err(e) => error!("Failed to unmap user memory in HyperVOnLinux ({:?})", e),
733+
// }
734+
// }
735+
// }
736+
// }
737+
738+
// TODO(danbugs:297): bring back
739+
// #[cfg(test)]
740+
// mod tests {
741+
// use super::*;
742+
// use crate::mem::memory_region::MemoryRegionVecBuilder;
743+
// use crate::mem::shared_mem::{ExclusiveSharedMemory, SharedMemory};
744+
//
745+
// #[rustfmt::skip]
746+
// const CODE: [u8; 12] = [
747+
// 0xba, 0xf8, 0x03, /* mov $0x3f8, %dx */
748+
// 0x00, 0xd8, /* add %bl, %al */
749+
// 0x04, b'0', /* add $'0', %al */
750+
// 0xee, /* out %al, (%dx) */
751+
// /* send a 0 to indicate we're done */
752+
// 0xb0, b'\0', /* mov $'\0', %al */
753+
// 0xee, /* out %al, (%dx) */
754+
// 0xf4, /* HLT */
755+
// ];
756+
//
757+
// fn shared_mem_with_code(
758+
// code: &[u8],
759+
// mem_size: usize,
760+
// load_offset: usize,
761+
// ) -> Result<Box<ExclusiveSharedMemory>> {
762+
// if load_offset > mem_size {
763+
// log_then_return!(
764+
// "code load offset ({}) > memory size ({})",
765+
// load_offset,
766+
// mem_size
767+
// );
768+
// }
769+
// let mut shared_mem = ExclusiveSharedMemory::new(mem_size)?;
770+
// shared_mem.copy_from_slice(code, load_offset)?;
771+
// Ok(Box::new(shared_mem))
772+
// }
773+
//
774+
// #[test]
775+
// fn create_driver() {
776+
// if !super::is_hypervisor_present() {
777+
// return;
778+
// }
779+
// const MEM_SIZE: usize = 0x3000;
780+
// let gm = shared_mem_with_code(CODE.as_slice(), MEM_SIZE, 0).unwrap();
781+
// let rsp_ptr = GuestPtr::try_from(0).unwrap();
782+
// let pml4_ptr = GuestPtr::try_from(0).unwrap();
783+
// let entrypoint_ptr = GuestPtr::try_from(0).unwrap();
784+
// let mut regions = MemoryRegionVecBuilder::new(0, gm.base_addr());
785+
// regions.push_page_aligned(
786+
// MEM_SIZE,
787+
// MemoryRegionFlags::READ | MemoryRegionFlags::WRITE | MemoryRegionFlags::EXECUTE,
788+
// crate::mem::memory_region::MemoryRegionType::Code,
789+
// );
790+
// super::HypervLinuxDriver::new(
781791
regions.build(),
782792
entrypoint_ptr,
783793
rsp_ptr,
@@ -786,5 +796,5 @@ mod tests {
786796
None,
787797
)
788798
.unwrap();
789-
}
790-
}
799+
// }
800+
// }

src/hyperlight_host/src/hypervisor/hyperv_windows.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use std::fmt;
1919
use std::fmt::{Debug, Formatter};
2020
use std::string::String;
2121

22-
use hyperlight_common::mem::PAGE_SIZE_USIZE;
22+
use hyperlight_common::mem::PAGE_SIZE;
2323
use log::LevelFilter;
2424
use tracing::{instrument, Span};
2525
use windows::Win32::System::Hypervisor::{
@@ -93,7 +93,7 @@ impl HypervWindowsDriver {
9393

9494
// subtract 2 pages for the guard pages, since when we copy memory to and from surrogate process,
9595
// we don't want to copy the guard pages themselves (that would cause access violation)
96-
let mem_size = raw_size - 2 * PAGE_SIZE_USIZE;
96+
let mem_size = raw_size - 2 * PAGE_SIZE;
9797
Ok(Self {
9898
size: mem_size,
9999
processor: proc,

src/hyperlight_host/src/hypervisor/inprocess.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ pub struct InprocessArgs<'a> {
3333
pub entrypoint_raw: u64,
3434
/// raw ptr to peb structure. Since we are in-process mode, this is a ptr in the host's address space
3535
pub peb_ptr_raw: u64,
36-
// compiler can't tell that we are actually using this in a deeply unsafe way.
37-
#[allow(dead_code)]
38-
pub(crate) leaked_outb_wrapper: LeakedOutBWrapper<'a>,
36+
// TODO(danbugs:297): bring back
37+
// // compiler can't tell that we are actually using this in a deeply unsafe way.
38+
// #[allow(dead_code)]
39+
// pub(crate) leaked_outb_wrapper: LeakedOutBWrapper<'a>,
3940
}
4041

4142
/// Arguments passed to inprocess driver
@@ -73,7 +74,6 @@ impl<'a> Hypervisor for InprocessDriver<'a> {
7374
&mut self,
7475
_peb_addr: crate::mem::ptr::RawPtr,
7576
seed: u64,
76-
page_size: u32,
7777
_outb_handle_fn: super::handlers::OutBHandlerWrapper,
7878
_mem_access_fn: super::handlers::MemAccessHandlerWrapper,
7979
_hv_handler: Option<super::hypervisor_handler::HypervisorHandler>,
@@ -83,10 +83,11 @@ impl<'a> Hypervisor for InprocessDriver<'a> {
8383
let entrypoint_fn: extern "win64" fn(u64, u64, u64, u64) =
8484
unsafe { std::mem::transmute(self.args.entrypoint_raw as *const c_void) };
8585

86+
// TODO(danbugs:297): fix
8687
entrypoint_fn(
8788
self.args.peb_ptr_raw,
8889
seed,
89-
page_size as u64,
90+
0x0 as u64,
9091
log::max_level() as u64,
9192
);
9293

0 commit comments

Comments
 (0)