Skip to content

Commit bb8704a

Browse files
committed
Windows
Signed-off-by: Ludvig Liljenberg <[email protected]>
1 parent 04344df commit bb8704a

File tree

5 files changed

+47
-42
lines changed

5 files changed

+47
-42
lines changed

src/hyperlight_host/src/hypervisor/hyperv_windows.rs

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,32 @@ use core::ffi::c_void;
1818
use std::fmt;
1919
use std::fmt::{Debug, Formatter};
2020
use std::string::String;
21+
use std::sync::atomic::{AtomicBool, Ordering};
22+
use std::sync::Arc;
2123

2224
use hyperlight_common::mem::PAGE_SIZE_USIZE;
2325
use log::LevelFilter;
2426
use tracing::{instrument, Span};
2527
use windows::Win32::System::Hypervisor::{
26-
WHvX64RegisterCr0, WHvX64RegisterCr3, WHvX64RegisterCr4, WHvX64RegisterCs, WHvX64RegisterEfer,
27-
WHV_MEMORY_ACCESS_TYPE, WHV_PARTITION_HANDLE, WHV_REGISTER_VALUE, WHV_RUN_VP_EXIT_CONTEXT,
28-
WHV_RUN_VP_EXIT_REASON, WHV_X64_SEGMENT_REGISTER, WHV_X64_SEGMENT_REGISTER_0,
28+
WHvCancelRunVirtualProcessor, WHvX64RegisterCr0, WHvX64RegisterCr3, WHvX64RegisterCr4,
29+
WHvX64RegisterCs, WHvX64RegisterEfer, WHV_MEMORY_ACCESS_TYPE, WHV_PARTITION_HANDLE,
30+
WHV_REGISTER_VALUE, WHV_RUN_VP_EXIT_CONTEXT, WHV_RUN_VP_EXIT_REASON, WHV_X64_SEGMENT_REGISTER,
31+
WHV_X64_SEGMENT_REGISTER_0,
2932
};
3033

3134
use super::fpu::{FP_TAG_WORD_DEFAULT, MXCSR_DEFAULT};
3235
#[cfg(gdb)]
3336
use super::handlers::DbgMemAccessHandlerWrapper;
3437
use super::handlers::{MemAccessHandlerWrapper, OutBHandlerWrapper};
3538
use super::surrogate_process::SurrogateProcess;
36-
use super::surrogate_process_manager::*;
3739
use super::windows_hypervisor_platform::{VMPartition, VMProcessor};
3840
use super::wrappers::{HandleWrapper, WHvFPURegisters};
41+
use super::{surrogate_process_manager::*, InterruptHandle};
3942
use super::{
4043
HyperlightExit, Hypervisor, VirtualCPU, CR0_AM, CR0_ET, CR0_MP, CR0_NE, CR0_PE, CR0_PG, CR0_WP,
4144
CR4_OSFXSR, CR4_OSXMMEXCPT, CR4_PAE, EFER_LMA, EFER_LME, EFER_NX, EFER_SCE,
4245
};
4346
use crate::hypervisor::fpu::FP_CONTROL_WORD_DEFAULT;
44-
use crate::hypervisor::hypervisor_handler::HypervisorHandler;
4547
use crate::hypervisor::wrappers::WHvGeneralRegisters;
4648
use crate::mem::memory_region::{MemoryRegion, MemoryRegionFlags};
4749
use crate::mem::ptr::{GuestPtr, RawPtr};
@@ -56,6 +58,7 @@ pub(crate) struct HypervWindowsDriver {
5658
entrypoint: u64,
5759
orig_rsp: GuestPtr,
5860
mem_regions: Vec<MemoryRegion>,
61+
interrupt_handle: Arc<WindowsInterruptHandle>,
5962
}
6063
/* This does not automatically impl Send/Sync because the host
6164
* address of the shared memory region is a raw pointer, which are
@@ -90,6 +93,7 @@ impl HypervWindowsDriver {
9093

9194
let mut proc = VMProcessor::new(partition)?;
9295
Self::setup_initial_sregs(&mut proc, pml4_address)?;
96+
let partition_handle = proc.get_partition_hdl();
9397

9498
// subtract 2 pages for the guard pages, since when we copy memory to and from surrogate process,
9599
// we don't want to copy the guard pages themselves (that would cause access violation)
@@ -102,6 +106,11 @@ impl HypervWindowsDriver {
102106
entrypoint,
103107
orig_rsp: GuestPtr::try_from(RawPtr::from(rsp))?,
104108
mem_regions,
109+
interrupt_handle: Arc::new(WindowsInterruptHandle {
110+
running: AtomicBool::new(false),
111+
parition_handle: partition_handle,
112+
dropped: AtomicBool::new(false),
113+
}),
105114
})
106115
}
107116

@@ -151,11 +160,6 @@ impl HypervWindowsDriver {
151160
error.push_str(&format!("Registers: \n{:#?}", self.processor.get_regs()?));
152161
Ok(error)
153162
}
154-
155-
#[instrument(skip_all, parent = Span::current(), level = "Trace")]
156-
pub(crate) fn get_partition_hdl(&self) -> WHV_PARTITION_HANDLE {
157-
self.processor.get_partition_hdl()
158-
}
159163
}
160164

161165
impl Debug for HypervWindowsDriver {
@@ -307,7 +311,6 @@ impl Hypervisor for HypervWindowsDriver {
307311
page_size: u32,
308312
outb_hdl: OutBHandlerWrapper,
309313
mem_access_hdl: MemAccessHandlerWrapper,
310-
hv_handler: Option<HypervisorHandler>,
311314
max_guest_log_level: Option<LevelFilter>,
312315
#[cfg(gdb)] dbg_mem_access_hdl: DbgMemAccessHandlerWrapper,
313316
) -> Result<()> {
@@ -333,7 +336,6 @@ impl Hypervisor for HypervWindowsDriver {
333336

334337
VirtualCPU::run(
335338
self.as_mut_hypervisor(),
336-
hv_handler,
337339
outb_hdl,
338340
mem_access_hdl,
339341
#[cfg(gdb)]
@@ -349,7 +351,6 @@ impl Hypervisor for HypervWindowsDriver {
349351
dispatch_func_addr: RawPtr,
350352
outb_hdl: OutBHandlerWrapper,
351353
mem_access_hdl: MemAccessHandlerWrapper,
352-
hv_handler: Option<HypervisorHandler>,
353354
#[cfg(gdb)] dbg_mem_access_hdl: DbgMemAccessHandlerWrapper,
354355
) -> Result<()> {
355356
// Reset general purpose registers, then set RIP and RSP
@@ -371,7 +372,6 @@ impl Hypervisor for HypervWindowsDriver {
371372

372373
VirtualCPU::run(
373374
self.as_mut_hypervisor(),
374-
hv_handler,
375375
outb_hdl,
376376
mem_access_hdl,
377377
#[cfg(gdb)]
@@ -407,7 +407,11 @@ impl Hypervisor for HypervWindowsDriver {
407407

408408
#[instrument(err(Debug), skip_all, parent = Span::current(), level = "Trace")]
409409
fn run(&mut self) -> Result<super::HyperlightExit> {
410+
self.interrupt_handle.running.store(true, Ordering::Relaxed);
410411
let exit_context: WHV_RUN_VP_EXIT_CONTEXT = self.processor.run()?;
412+
self.interrupt_handle
413+
.running
414+
.store(false, Ordering::Relaxed);
411415

412416
let result = match exit_context.ExitReason {
413417
// WHvRunVpExitReasonX64IoPortAccess
@@ -481,8 +485,8 @@ impl Hypervisor for HypervWindowsDriver {
481485
Ok(result)
482486
}
483487

484-
fn get_partition_handle(&self) -> WHV_PARTITION_HANDLE {
485-
self.processor.get_partition_hdl()
488+
fn interrupt_handle(&self) -> Arc<dyn InterruptHandle> {
489+
self.interrupt_handle.clone()
486490
}
487491

488492
#[instrument(skip_all, parent = Span::current(), level = "Trace")]
@@ -496,28 +500,24 @@ impl Hypervisor for HypervWindowsDriver {
496500
}
497501
}
498502

499-
#[cfg(test)]
500-
pub mod tests {
501-
use std::sync::{Arc, Mutex};
503+
impl Drop for HypervWindowsDriver {
504+
fn drop(&mut self) {}
505+
}
502506

503-
use serial_test::serial;
507+
pub struct WindowsInterruptHandle {
508+
// `WHvCancelRunVirtualProcessor()` will return Ok even if the vcpu is not running, which is the reason we need this flag.
509+
running: AtomicBool,
510+
parition_handle: WHV_PARTITION_HANDLE,
511+
dropped: AtomicBool,
512+
}
504513

505-
use crate::hypervisor::handlers::{MemAccessHandler, OutBHandler};
506-
use crate::hypervisor::tests::test_initialise;
507-
use crate::Result;
514+
impl InterruptHandle for WindowsInterruptHandle {
515+
fn kill(&self) -> bool {
516+
self.running.load(Ordering::Relaxed)
517+
&& unsafe { WHvCancelRunVirtualProcessor(self.parition_handle, 0, 0).is_ok() }
518+
}
508519

509-
#[test]
510-
#[serial]
511-
fn test_init() {
512-
let outb_handler = {
513-
let func: Box<dyn FnMut(u16, u32) -> Result<()> + Send> =
514-
Box::new(|_, _| -> Result<()> { Ok(()) });
515-
Arc::new(Mutex::new(OutBHandler::from(func)))
516-
};
517-
let mem_access_handler = {
518-
let func: Box<dyn FnMut() -> Result<()> + Send> = Box::new(|| -> Result<()> { Ok(()) });
519-
Arc::new(Mutex::new(MemAccessHandler::from(func)))
520-
};
521-
test_initialise(outb_handler, mem_access_handler).unwrap();
520+
fn dropped(&self) -> bool {
521+
self.dropped.load(Ordering::Relaxed)
522522
}
523523
}

src/hyperlight_host/src/hypervisor/mod.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ pub(crate) mod crashdump;
5959

6060
use std::fmt::Debug;
6161
use std::str::FromStr;
62+
#[cfg(any(kvm, mshv))]
6263
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
6364
use std::sync::{Arc, Mutex};
6465

@@ -227,10 +228,6 @@ pub(crate) trait Hypervisor: Debug + Sync + Send {
227228
/// get a mutable trait object from self
228229
fn as_mut_hypervisor(&mut self) -> &mut dyn Hypervisor;
229230

230-
/// Get the partition handle for WHP
231-
#[cfg(target_os = "windows")]
232-
fn get_partition_handle(&self) -> windows::Win32::System::Hypervisor::WHV_PARTITION_HANDLE;
233-
234231
#[cfg(crashdump)]
235232
fn get_memory_regions(&self) -> &[MemoryRegion];
236233

@@ -337,6 +334,7 @@ pub trait InterruptHandle: Send + Sync {
337334
fn dropped(&self) -> bool;
338335
}
339336

337+
#[cfg(any(kvm, mshv))]
340338
#[derive(Debug)]
341339
pub(super) struct LinuxInterruptHandle {
342340
/// True when the vcpu is currently running and blocking the thread
@@ -347,6 +345,7 @@ pub(super) struct LinuxInterruptHandle {
347345
dropped: AtomicBool,
348346
}
349347

348+
#[cfg(any(kvm, mshv))]
350349
impl InterruptHandle for LinuxInterruptHandle {
351350
fn kill(&self) -> bool {
352351
let sigrtmin = libc::SIGRTMIN();

src/hyperlight_host/src/sandbox/initialized_multi_use.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ impl MultiUseSandbox {
201201
self.dispatch_ptr.clone(),
202202
self.out_hdl.clone(),
203203
self.mem_hdl.clone(),
204+
#[cfg(gdb)]
204205
self.dbg_mem_access_fn.clone(),
205206
)?;
206207

src/hyperlight_host/src/sandbox/uninitialized_evolve.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ limitations under the License.
1616

1717
use crate::hypervisor::handlers::{MemAccessHandlerCaller, OutBHandlerCaller};
1818
use crate::hypervisor::Hypervisor;
19+
#[cfg(target_os = "linux")]
1920
use crate::signal_handlers::setup_signal_handlers;
2021
use crate::HyperlightError::NoHypervisorFound;
2122
use std::sync::{Arc, Mutex};
@@ -89,6 +90,7 @@ where
8990
#[cfg(gdb)]
9091
let dbg_mem_access_hdl = dbg_mem_access_handler_wrapper(hshm.clone());
9192

93+
#[cfg(target_os = "linux")]
9294
setup_signal_handlers()?;
9395

9496
vm.initialise(
@@ -225,6 +227,9 @@ fn set_up_hypervisor_partition(
225227

226228
#[cfg(target_os = "windows")]
227229
Some(HypervisorType::Whp) => {
230+
use crate::hypervisor::wrappers::HandleWrapper;
231+
use std::ffi::c_void;
232+
228233
let mmap_file_handle = mgr
229234
.shared_mem
230235
.with_exclusivity(|e| e.get_mmap_file_handle())?;

src/hyperlight_host/tests/integration_test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ use crate::common::{new_uninit, new_uninit_rust};
3333

3434
#[test]
3535
fn kill_running_vm() {
36-
// this test is rust-guest only
3736
let mut sbox1: MultiUseSandbox = new_uninit().unwrap().evolve(Noop::default()).unwrap();
3837

3938
let interrupt_handle = sbox1.interrupt_handle();
40-
assert!(!interrupt_handle.dropped());
39+
assert!(!interrupt_handle.dropped()); // not yet dropped
40+
assert!(!interrupt_handle.kill()); // nothing to kill since vcpu is not running
4141

4242
// kill vm after 1 second
4343
thread::spawn(move || {

0 commit comments

Comments
 (0)