Skip to content

Commit 6412927

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 <[email protected]>
1 parent 7ae4959 commit 6412927

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;
@@ -284,10 +284,12 @@ pub(crate) fn is_hypervisor_present() -> bool {
284284
/// called the Microsoft Hypervisor (MSHV)
285285
pub(super) struct HypervLinuxDriver {
286286
_mshv: Mshv,
287+
// TODO(danbugs:297): remove
288+
#[allow(dead_code)]
287289
vm_fd: VmFd,
288290
vcpu_fd: VcpuFd,
289291
entrypoint: u64,
290-
mem_regions: Vec<MemoryRegion>,
292+
mem_sections: SandboxMemorySections,
291293
orig_rsp: GuestPtr,
292294

293295
#[cfg(gdb)]
@@ -307,7 +309,7 @@ impl HypervLinuxDriver {
307309
/// `initialise` to do it for you.
308310
#[instrument(skip_all, parent = Span::current(), level = "Trace")]
309311
pub(super) fn new(
310-
mem_regions: Vec<MemoryRegion>,
312+
mem_sections: SandboxMemorySections,
311313
entrypoint_ptr: GuestPtr,
312314
rsp_ptr: GuestPtr,
313315
pml4_ptr: GuestPtr,
@@ -372,18 +374,19 @@ impl HypervLinuxDriver {
372374
(None, None)
373375
};
374376

375-
mem_regions.iter().try_for_each(|region| {
376-
let mshv_region = region.to_owned().into();
377-
vm_fd.map_user_memory(mshv_region)
378-
})?;
377+
// TODO(danbugs:297): bring back
378+
// mem_sections.iter().try_for_each(|region| {
379+
// let mshv_region = region.to_owned().into();
380+
// vm_fd.map_user_memory(mshv_region)
381+
// })?;
379382

380383
Self::setup_initial_sregs(&mut vcpu_fd, pml4_ptr.absolute()?)?;
381384

382385
Ok(Self {
383386
_mshv: mshv,
384387
vm_fd,
385388
vcpu_fd,
386-
mem_regions,
389+
mem_sections,
387390
entrypoint: entrypoint_ptr.absolute()?,
388391
orig_rsp: rsp_ptr,
389392

@@ -428,7 +431,7 @@ impl Debug for HypervLinuxDriver {
428431
f.field("Entrypoint", &self.entrypoint)
429432
.field("Original RSP", &self.orig_rsp);
430433

431-
for region in &self.mem_regions {
434+
for region in self.mem_sections.iter() {
432435
f.field("Memory Region", &region);
433436
}
434437

@@ -452,9 +455,9 @@ impl Hypervisor for HypervLinuxDriver {
452455
#[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")]
453456
fn initialise(
454457
&mut self,
455-
peb_addr: RawPtr,
458+
hyperlight_peb_guest_memory_region_address: u64,
459+
hyperlight_peb_guest_memory_region_size: u64,
456460
seed: u64,
457-
page_size: u32,
458461
outb_hdl: OutBHandlerWrapper,
459462
mem_access_hdl: MemAccessHandlerWrapper,
460463
hv_handler: Option<HypervisorHandler>,
@@ -472,9 +475,9 @@ impl Hypervisor for HypervLinuxDriver {
472475
rflags: 2, //bit 1 of rlags is required to be set
473476

474477
// function args
475-
rcx: peb_addr.into(),
476-
rdx: seed,
477-
r8: page_size.into(),
478+
rcx: hyperlight_peb_guest_memory_region_address.into(),
479+
rdx: hyperlight_peb_guest_memory_region_size.into(),
480+
r8: seed.into(),
478481
r9: max_guest_log_level,
479482

480483
..Default::default()
@@ -610,20 +613,24 @@ impl Hypervisor for HypervLinuxDriver {
610613
INVALID_GPA_ACCESS_MESSAGE => {
611614
let mimo_message = m.to_memory_info()?;
612615
let gpa = mimo_message.guest_physical_address;
613-
let access_info = MemoryRegionFlags::try_from(mimo_message)?;
616+
// TODO(danbugs:297): bring back
617+
// let access_info = MemoryRegionFlags::try_from(mimo_message)?;
614618
crate::debug!(
615619
"mshv MMIO invalid GPA access -Details: Address: {} \n {:#?}",
616620
gpa,
617621
&self
618622
);
619-
match self.get_memory_access_violation(
620-
gpa as usize,
621-
&self.mem_regions,
622-
access_info,
623-
) {
624-
Some(access_info_violation) => access_info_violation,
625-
None => HyperlightExit::Mmio(gpa),
626-
}
623+
// TODO(danbugs:297): bring back
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+
// }
632+
633+
HyperlightExit::Mmio(gpa)
627634
}
628635
// The only case an intercept exit is expected is when debugging is enabled
629636
// and the intercepts are installed
@@ -657,10 +664,11 @@ impl Hypervisor for HypervLinuxDriver {
657664
self as &mut dyn Hypervisor
658665
}
659666

660-
#[cfg(crashdump)]
661-
fn get_memory_regions(&self) -> &[MemoryRegion] {
662-
&self.mem_regions
663-
}
667+
// TODO(danbugs:297): bring back
668+
// #[cfg(crashdump)]
669+
// fn get_memory_regions(&self) -> &[MemoryRegion] {
670+
// &self.mem_sections
671+
// }
664672

665673
#[cfg(gdb)]
666674
fn handle_debug(
@@ -708,71 +716,73 @@ impl Hypervisor for HypervLinuxDriver {
708716
}
709717
}
710718

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

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)