Skip to content

Commit 3212be7

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.
1 parent ce40760 commit 3212be7

File tree

4 files changed

+244
-205
lines changed

4 files changed

+244
-205
lines changed

Diff for: src/hyperlight_host/src/hypervisor/hyperv_linux.rs

+106-97
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,13 @@ extern crate mshv_ioctls3 as mshv_ioctls;
2626

2727
use std::fmt::{Debug, Formatter};
2828

29-
use log::error;
3029
#[cfg(mshv2)]
3130
use mshv_bindings::hv_message;
3231
use mshv_bindings::{
3332
hv_message_type, hv_message_type_HVMSG_GPA_INTERCEPT, hv_message_type_HVMSG_UNMAPPED_GPA,
3433
hv_message_type_HVMSG_X64_HALT, hv_message_type_HVMSG_X64_IO_PORT_INTERCEPT, hv_register_assoc,
35-
hv_register_name_HV_X64_REGISTER_RIP, hv_register_value, mshv_user_mem_region,
36-
FloatingPointUnit, SegmentRegister, SpecialRegisters, StandardRegisters,
34+
hv_register_name_HV_X64_REGISTER_RIP, hv_register_value, FloatingPointUnit, SegmentRegister,
35+
SpecialRegisters, StandardRegisters,
3736
};
3837
#[cfg(mshv3)]
3938
use mshv_bindings::{
@@ -53,7 +52,7 @@ use super::{
5352
};
5453
use crate::hypervisor::hypervisor_handler::HypervisorHandler;
5554
use crate::hypervisor::HyperlightExit;
56-
use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags};
55+
use crate::sandbox::sandbox_builder::SandboxMemorySections;
5756
use crate::mem::ptr::{GuestPtr, RawPtr};
5857
use crate::{log_then_return, new_error, Result};
5958

@@ -79,10 +78,12 @@ pub(crate) fn is_hypervisor_present() -> bool {
7978
/// called the Microsoft Hypervisor (MSHV)
8079
pub(super) struct HypervLinuxDriver {
8180
_mshv: Mshv,
81+
// TODO(danbugs:297): remove
82+
#[allow(dead_code)]
8283
vm_fd: VmFd,
8384
vcpu_fd: VcpuFd,
8485
entrypoint: u64,
85-
mem_regions: Vec<MemoryRegion>,
86+
mem_sections: SandboxMemorySections,
8687
orig_rsp: GuestPtr,
8788
}
8889

@@ -97,7 +98,7 @@ impl HypervLinuxDriver {
9798
/// `initialise` to do it for you.
9899
#[instrument(skip_all, parent = Span::current(), level = "Trace")]
99100
pub(super) fn new(
100-
mem_regions: Vec<MemoryRegion>,
101+
mem_sections: SandboxMemorySections,
101102
entrypoint_ptr: GuestPtr,
102103
rsp_ptr: GuestPtr,
103104
pml4_ptr: GuestPtr,
@@ -124,18 +125,19 @@ impl HypervLinuxDriver {
124125

125126
let mut vcpu_fd = vm_fd.create_vcpu(0)?;
126127

127-
mem_regions.iter().try_for_each(|region| {
128-
let mshv_region = region.to_owned().into();
129-
vm_fd.map_user_memory(mshv_region)
130-
})?;
128+
// TODO(danbugs:297): bring back
129+
// mem_sections.iter().try_for_each(|region| {
130+
// let mshv_region = region.to_owned().into();
131+
// vm_fd.map_user_memory(mshv_region)
132+
// })?;
131133

132134
Self::setup_initial_sregs(&mut vcpu_fd, pml4_ptr.absolute()?)?;
133135

134136
Ok(Self {
135137
_mshv: mshv,
136138
vm_fd,
137139
vcpu_fd,
138-
mem_regions,
140+
mem_sections,
139141
entrypoint: entrypoint_ptr.absolute()?,
140142
orig_rsp: rsp_ptr,
141143
})
@@ -175,7 +177,7 @@ impl Debug for HypervLinuxDriver {
175177
f.field("Entrypoint", &self.entrypoint)
176178
.field("Original RSP", &self.orig_rsp);
177179

178-
for region in &self.mem_regions {
180+
for region in self.mem_sections.iter() {
179181
f.field("Memory Region", &region);
180182
}
181183

@@ -199,9 +201,9 @@ impl Hypervisor for HypervLinuxDriver {
199201
#[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")]
200202
fn initialise(
201203
&mut self,
202-
peb_addr: RawPtr,
204+
hyperlight_peb_guest_memory_region_address: u64,
205+
hyperlight_peb_guest_memory_region_size: u64,
203206
seed: u64,
204-
page_size: u32,
205207
outb_hdl: OutBHandlerWrapper,
206208
mem_access_hdl: MemAccessHandlerWrapper,
207209
hv_handler: Option<HypervisorHandler>,
@@ -213,9 +215,9 @@ impl Hypervisor for HypervLinuxDriver {
213215
rflags: 2, //bit 1 of rlags is required to be set
214216

215217
// function args
216-
rcx: peb_addr.into(),
217-
rdx: seed,
218-
r8: page_size.into(),
218+
rcx: hyperlight_peb_guest_memory_region_address.into(),
219+
rdx: hyperlight_peb_guest_memory_region_size.into(),
220+
r8: seed.into(),
219221
r9: self.get_max_log_level().into(),
220222

221223
..Default::default()
@@ -349,20 +351,24 @@ impl Hypervisor for HypervLinuxDriver {
349351
INVALID_GPA_ACCESS_MESSAGE => {
350352
let mimo_message = m.to_memory_info()?;
351353
let gpa = mimo_message.guest_physical_address;
352-
let access_info = MemoryRegionFlags::try_from(mimo_message)?;
354+
// TODO(danbugs:297): bring back
355+
// let access_info = MemoryRegionFlags::try_from(mimo_message)?;
353356
crate::debug!(
354357
"mshv MMIO invalid GPA access -Details: Address: {} \n {:#?}",
355358
gpa,
356359
&self
357360
);
358-
match self.get_memory_access_violation(
359-
gpa as usize,
360-
&self.mem_regions,
361-
access_info,
362-
) {
363-
Some(access_info_violation) => access_info_violation,
364-
None => HyperlightExit::Mmio(gpa),
365-
}
361+
// TODO(danbugs:297): bring back
362+
// match self.get_memory_access_violation(
363+
// gpa as usize,
364+
// &self.mem_regions,
365+
// access_info,
366+
// ) {
367+
// Some(access_info_violation) => access_info_violation,
368+
// None => HyperlightExit::Mmio(gpa),
369+
// }
370+
371+
HyperlightExit::Mmio(gpa)
366372
}
367373
other => {
368374
crate::debug!("mshv Other Exit: Exit: {:#?} \n {:#?}", other, &self);
@@ -387,76 +393,79 @@ impl Hypervisor for HypervLinuxDriver {
387393
self as &mut dyn Hypervisor
388394
}
389395

390-
#[cfg(crashdump)]
391-
fn get_memory_regions(&self) -> &[MemoryRegion] {
392-
&self.mem_regions
393-
}
394-
}
395-
396-
impl Drop for HypervLinuxDriver {
397-
#[instrument(skip_all, parent = Span::current(), level = "Trace")]
398-
fn drop(&mut self) {
399-
for region in &self.mem_regions {
400-
let mshv_region: mshv_user_mem_region = region.to_owned().into();
401-
match self.vm_fd.unmap_user_memory(mshv_region) {
402-
Ok(_) => (),
403-
Err(e) => error!("Failed to unmap user memory in HyperVOnLinux ({:?})", e),
404-
}
405-
}
406-
}
396+
// TODO(danbugs:297): bring back
397+
// #[cfg(crashdump)]
398+
// fn get_memory_regions(&self) -> &[MemoryRegion] {
399+
// &self.mem_sections
400+
// }
407401
}
408402

409-
#[cfg(test)]
410-
mod tests {
411-
use super::*;
412-
use crate::mem::memory_region::MemoryRegionVecBuilder;
413-
use crate::mem::shared_mem::{ExclusiveSharedMemory, SharedMemory};
414-
415-
#[rustfmt::skip]
416-
const CODE: [u8; 12] = [
417-
0xba, 0xf8, 0x03, /* mov $0x3f8, %dx */
418-
0x00, 0xd8, /* add %bl, %al */
419-
0x04, b'0', /* add $'0', %al */
420-
0xee, /* out %al, (%dx) */
421-
/* send a 0 to indicate we're done */
422-
0xb0, b'\0', /* mov $'\0', %al */
423-
0xee, /* out %al, (%dx) */
424-
0xf4, /* HLT */
425-
];
426-
427-
fn shared_mem_with_code(
428-
code: &[u8],
429-
mem_size: usize,
430-
load_offset: usize,
431-
) -> Result<Box<ExclusiveSharedMemory>> {
432-
if load_offset > mem_size {
433-
log_then_return!(
434-
"code load offset ({}) > memory size ({})",
435-
load_offset,
436-
mem_size
437-
);
438-
}
439-
let mut shared_mem = ExclusiveSharedMemory::new(mem_size)?;
440-
shared_mem.copy_from_slice(code, load_offset)?;
441-
Ok(Box::new(shared_mem))
442-
}
443-
444-
#[test]
445-
fn create_driver() {
446-
if !super::is_hypervisor_present() {
447-
return;
448-
}
449-
const MEM_SIZE: usize = 0x3000;
450-
let gm = shared_mem_with_code(CODE.as_slice(), MEM_SIZE, 0).unwrap();
451-
let rsp_ptr = GuestPtr::try_from(0).unwrap();
452-
let pml4_ptr = GuestPtr::try_from(0).unwrap();
453-
let entrypoint_ptr = GuestPtr::try_from(0).unwrap();
454-
let mut regions = MemoryRegionVecBuilder::new(0, gm.base_addr());
455-
regions.push_page_aligned(
456-
MEM_SIZE,
457-
MemoryRegionFlags::READ | MemoryRegionFlags::WRITE | MemoryRegionFlags::EXECUTE,
458-
crate::mem::memory_region::MemoryRegionType::Code,
459-
);
460-
super::HypervLinuxDriver::new(regions.build(), entrypoint_ptr, rsp_ptr, pml4_ptr).unwrap();
461-
}
462-
}
403+
// TODO(danbugs:297): bring back
404+
// impl Drop for HypervLinuxDriver {
405+
// #[instrument(skip_all, parent = Span::current(), level = "Trace")]
406+
// fn drop(&mut self) {
407+
// for region in self.mem_sections.iter() {
408+
// let mshv_region: mshv_user_mem_region = region.to_owned().into();
409+
// match self.vm_fd.unmap_user_memory(mshv_region) {
410+
// Ok(_) => (),
411+
// Err(e) => error!("Failed to unmap user memory in HyperVOnLinux ({:?})", e),
412+
// }
413+
// }
414+
// }
415+
// }
416+
417+
// TODO(danbugs:297): bring back
418+
// #[cfg(test)]
419+
// mod tests {
420+
// use super::*;
421+
// use crate::mem::memory_region::MemoryRegionVecBuilder;
422+
// use crate::mem::shared_mem::{ExclusiveSharedMemory, SharedMemory};
423+
//
424+
// #[rustfmt::skip]
425+
// const CODE: [u8; 12] = [
426+
// 0xba, 0xf8, 0x03, /* mov $0x3f8, %dx */
427+
// 0x00, 0xd8, /* add %bl, %al */
428+
// 0x04, b'0', /* add $'0', %al */
429+
// 0xee, /* out %al, (%dx) */
430+
// /* send a 0 to indicate we're done */
431+
// 0xb0, b'\0', /* mov $'\0', %al */
432+
// 0xee, /* out %al, (%dx) */
433+
// 0xf4, /* HLT */
434+
// ];
435+
//
436+
// fn shared_mem_with_code(
437+
// code: &[u8],
438+
// mem_size: usize,
439+
// load_offset: usize,
440+
// ) -> Result<Box<ExclusiveSharedMemory>> {
441+
// if load_offset > mem_size {
442+
// log_then_return!(
443+
// "code load offset ({}) > memory size ({})",
444+
// load_offset,
445+
// mem_size
446+
// );
447+
// }
448+
// let mut shared_mem = ExclusiveSharedMemory::new(mem_size)?;
449+
// shared_mem.copy_from_slice(code, load_offset)?;
450+
// Ok(Box::new(shared_mem))
451+
// }
452+
//
453+
// #[test]
454+
// fn create_driver() {
455+
// if !super::is_hypervisor_present() {
456+
// return;
457+
// }
458+
// const MEM_SIZE: usize = 0x3000;
459+
// let gm = shared_mem_with_code(CODE.as_slice(), MEM_SIZE, 0).unwrap();
460+
// let rsp_ptr = GuestPtr::try_from(0).unwrap();
461+
// let pml4_ptr = GuestPtr::try_from(0).unwrap();
462+
// let entrypoint_ptr = GuestPtr::try_from(0).unwrap();
463+
// let mut regions = MemoryRegionVecBuilder::new(0, gm.base_addr());
464+
// regions.push_page_aligned(
465+
// MEM_SIZE,
466+
// MemoryRegionFlags::READ | MemoryRegionFlags::WRITE | MemoryRegionFlags::EXECUTE,
467+
// crate::mem::memory_region::MemoryRegionType::Code,
468+
// );
469+
// super::HypervLinuxDriver::new(regions.build(), entrypoint_ptr, rsp_ptr, pml4_ptr).unwrap();
470+
// }
471+
// }

Diff for: src/hyperlight_host/src/hypervisor/hyperv_windows.rs

+2-2
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 tracing::{instrument, Span};
2424
use windows::Win32::System::Hypervisor::{
2525
WHvX64RegisterCr0, WHvX64RegisterCr3, WHvX64RegisterCr4, WHvX64RegisterCs, WHvX64RegisterEfer,
@@ -92,7 +92,7 @@ impl HypervWindowsDriver {
9292

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

Diff for: src/hyperlight_host/src/hypervisor/inprocess.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,10 @@ pub struct InprocessArgs<'a> {
3131
pub entrypoint_raw: u64,
3232
/// raw ptr to peb structure. Since we are in-process mode, this is a ptr in the host's address space
3333
pub peb_ptr_raw: u64,
34-
// compiler can't tell that we are actually using this in a deeply unsafe way.
35-
#[allow(dead_code)]
36-
pub(crate) leaked_outb_wrapper: LeakedOutBWrapper<'a>,
34+
// TODO(danbugs:297): bring back
35+
// // compiler can't tell that we are actually using this in a deeply unsafe way.
36+
// #[allow(dead_code)]
37+
// pub(crate) leaked_outb_wrapper: LeakedOutBWrapper<'a>,
3738
}
3839

3940
/// Arguments passed to inprocess driver
@@ -71,7 +72,6 @@ impl<'a> Hypervisor for InprocessDriver<'a> {
7172
&mut self,
7273
_peb_addr: crate::mem::ptr::RawPtr,
7374
seed: u64,
74-
page_size: u32,
7575
_outb_handle_fn: super::handlers::OutBHandlerWrapper,
7676
_mem_access_fn: super::handlers::MemAccessHandlerWrapper,
7777
_hv_handler: Option<super::hypervisor_handler::HypervisorHandler>,
@@ -80,10 +80,11 @@ impl<'a> Hypervisor for InprocessDriver<'a> {
8080
let entrypoint_fn: extern "win64" fn(u64, u64, u64, u64) =
8181
unsafe { std::mem::transmute(self.args.entrypoint_raw as *const c_void) };
8282

83+
// TODO(danbugs:297): fix
8384
entrypoint_fn(
8485
self.args.peb_ptr_raw,
8586
seed,
86-
page_size as u64,
87+
0x0 as u64,
8788
log::max_level() as u64,
8889
);
8990

0 commit comments

Comments
 (0)