Skip to content

Commit b4767f1

Browse files
committed
Merge branch 'main' into vm_trait
2 parents ec06c04 + e99716a commit b4767f1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1166
-1469
lines changed

.github/CODEOWNERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Global Code Owners
2+
* @danbugs @ludfjig @dblnz @devigned @syntactically @marosset @jprendes @simongdavies

Cargo.lock

Lines changed: 8 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<div align="center">
22
<h1>Hyperlight</h1>
33
<img src="https://raw.githubusercontent.com/hyperlight-dev/hyperlight/refs/heads/main/docs/assets/hyperlight-logo.png" width="150px" alt="hyperlight logo"/>
4-
<p><strong>Hyperlight is a lightweight Virtual Machine Manager (VMM) designed to be embedded within applications. It enables safe execution of untrusted code within <i>micro virtual machines</i> with very low latency and minimal overhead.</strong></p>
4+
<p><strong>Hyperlight is a lightweight Virtual Machine Manager (VMM) designed to be embedded within applications. It enables safe execution of untrusted code within <i>micro virtual machines</i> with very low latency and minimal overhead.</strong> <br> We are a <a href="https://cncf.io/">Cloud Native Computing Foundation</a> sandbox project. </p>
55
</div>
66

77
> Note: Hyperlight is a nascent project with an evolving API and no guaranteed support. Assistance is provided on a
@@ -47,16 +47,11 @@ fn main() -> hyperlight_host::Result<()> {
4747
None, // default host print function
4848
)?;
4949

50-
// Register a host function
51-
fn sleep_5_secs() -> hyperlight_host::Result<()> {
50+
// Registering a host function makes it available to be called by the guest
51+
uninitialized_sandbox.register("Sleep5Secs", || {
5252
thread::sleep(std::time::Duration::from_secs(5));
5353
Ok(())
54-
}
55-
56-
let host_function = Arc::new(Mutex::new(sleep_5_secs));
57-
58-
// Registering a host function makes it available to be called by the guest
59-
host_function.register(&mut uninitialized_sandbox, "Sleep5Secs")?;
54+
})?;
6055
// Note: This function is unused by the guest code below, it's just here for demonstration purposes
6156

6257
// Initialize sandbox to be able to call host functions

src/hyperlight_common/src/flatbuffer_wrappers/function_types.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ pub enum ReturnValue {
9999
/// bool
100100
Bool(bool),
101101
/// ()
102-
Void,
102+
Void(()),
103103
/// Vec<u8>
104104
VecBytes(Vec<u8>),
105105
}
@@ -508,7 +508,7 @@ impl TryFrom<ReturnValue> for () {
508508
#[cfg_attr(feature = "tracing", instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace"))]
509509
fn try_from(value: ReturnValue) -> Result<Self> {
510510
match value {
511-
ReturnValue::Void => Ok(()),
511+
ReturnValue::Void(()) => Ok(()),
512512
_ => {
513513
bail!("Unexpected return value type: {:?}", value)
514514
}
@@ -570,7 +570,7 @@ impl TryFrom<FbFunctionCallResult<'_>> for ReturnValue {
570570
};
571571
Ok(ReturnValue::String(hlstring.unwrap_or("".to_string())))
572572
}
573-
FbReturnValue::hlvoid => Ok(ReturnValue::Void),
573+
FbReturnValue::hlvoid => Ok(ReturnValue::Void(())),
574574
FbReturnValue::hlsizeprefixedbuffer => {
575575
let hlvecbytes =
576576
match function_call_result_fb.return_value_as_hlsizeprefixedbuffer() {
@@ -724,7 +724,7 @@ impl TryFrom<&ReturnValue> for Vec<u8> {
724724
builder.finish_size_prefixed(function_call_result, None);
725725
builder.finished_data().to_vec()
726726
}
727-
ReturnValue::Void => {
727+
ReturnValue::Void(()) => {
728728
let hlvoid = hlvoid::create(&mut builder, &hlvoidArgs {});
729729
let function_call_result = FbFunctionCallResult::create(
730730
&mut builder,

src/hyperlight_common/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,6 @@ pub mod flatbuffer_wrappers;
3636
mod flatbuffers;
3737
/// cbindgen:ignore
3838
pub mod mem;
39+
40+
/// cbindgen:ignore
41+
pub mod outb;

src/hyperlight_common/src/mem/mod.rs renamed to src/hyperlight_common/src/mem.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,24 +74,16 @@ pub struct GuestStackData {
7474
pub bootStackAddress: u64,
7575
}
7676

77-
#[repr(C)]
78-
pub struct GuestPanicContextData {
79-
pub guestPanicContextDataSize: u64,
80-
pub guestPanicContextDataBuffer: *mut c_void,
81-
}
82-
8377
#[repr(C)]
8478
pub struct HyperlightPEB {
8579
pub security_cookie_seed: u64,
8680
pub guest_function_dispatch_ptr: u64,
87-
pub guestErrorData: GuestErrorData,
8881
pub pCode: *mut c_char,
8982
pub pOutb: *mut c_void,
9083
pub pOutbContext: *mut c_void,
9184
pub runMode: RunMode,
9285
pub inputdata: InputData,
9386
pub outputdata: OutputData,
94-
pub guestPanicContextData: GuestPanicContextData,
9587
pub guestheapData: GuestHeapData,
9688
pub gueststackData: GuestStackData,
9789
}

src/hyperlight_common/src/outb.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
use core::convert::TryFrom;
2+
3+
use anyhow::{anyhow, Error};
4+
5+
/// Exception codes for the x86 architecture.
6+
/// These are helpful to identify the type of exception that occurred
7+
/// together with OutBAction::Abort.
8+
#[repr(u8)]
9+
#[derive(Debug, Clone, Copy)]
10+
pub enum Exception {
11+
DivideByZero = 0,
12+
Debug = 1,
13+
NonMaskableInterrupt = 2,
14+
Breakpoint = 3,
15+
Overflow = 4,
16+
BoundRangeExceeded = 5,
17+
InvalidOpcode = 6,
18+
DeviceNotAvailable = 7,
19+
DoubleFault = 8,
20+
CoprocessorSegmentOverrun = 9,
21+
InvalidTSS = 10,
22+
SegmentNotPresent = 11,
23+
StackSegmentFault = 12,
24+
GeneralProtectionFault = 13,
25+
PageFault = 14,
26+
Reserved = 15,
27+
X87FloatingPointException = 16,
28+
AlignmentCheck = 17,
29+
MachineCheck = 18,
30+
SIMDFloatingPointException = 19,
31+
VirtualizationException = 20,
32+
SecurityException = 30,
33+
NoException = 0xFF,
34+
}
35+
36+
impl TryFrom<u8> for Exception {
37+
type Error = Error;
38+
39+
fn try_from(value: u8) -> Result<Self, Self::Error> {
40+
use Exception::*;
41+
let exception = match value {
42+
0 => DivideByZero,
43+
1 => Debug,
44+
2 => NonMaskableInterrupt,
45+
3 => Breakpoint,
46+
4 => Overflow,
47+
5 => BoundRangeExceeded,
48+
6 => InvalidOpcode,
49+
7 => DeviceNotAvailable,
50+
8 => DoubleFault,
51+
9 => CoprocessorSegmentOverrun,
52+
10 => InvalidTSS,
53+
11 => SegmentNotPresent,
54+
12 => StackSegmentFault,
55+
13 => GeneralProtectionFault,
56+
14 => PageFault,
57+
15 => Reserved,
58+
16 => X87FloatingPointException,
59+
17 => AlignmentCheck,
60+
18 => MachineCheck,
61+
19 => SIMDFloatingPointException,
62+
20 => VirtualizationException,
63+
30 => SecurityException,
64+
0x7F => NoException,
65+
_ => return Err(anyhow!("Unknown exception code: {:#x}", value)),
66+
};
67+
68+
Ok(exception)
69+
}
70+
}
71+
72+
/// Supported actions when issuing an OUTB actions by Hyperlight.
73+
/// - Log: for logging,
74+
/// - CallFunction: makes a call to a host function,
75+
/// - Abort: aborts the execution of the guest,
76+
/// - DebugPrint: prints a message to the host
77+
pub enum OutBAction {
78+
Log = 99,
79+
CallFunction = 101,
80+
Abort = 102,
81+
DebugPrint = 103,
82+
}
83+
84+
impl TryFrom<u16> for OutBAction {
85+
type Error = anyhow::Error;
86+
fn try_from(val: u16) -> anyhow::Result<Self> {
87+
match val {
88+
99 => Ok(OutBAction::Log),
89+
101 => Ok(OutBAction::CallFunction),
90+
102 => Ok(OutBAction::Abort),
91+
103 => Ok(OutBAction::DebugPrint),
92+
_ => Err(anyhow::anyhow!("Invalid OutBAction value: {}", val)),
93+
}
94+
}
95+
}

src/hyperlight_guest/src/entrypoint.rs

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,16 @@ limitations under the License.
1616

1717
use core::arch::asm;
1818
use core::ffi::{c_char, c_void, CStr};
19-
use core::ptr::copy_nonoverlapping;
2019

2120
use hyperlight_common::mem::{HyperlightPEB, RunMode};
21+
use hyperlight_common::outb::OutBAction;
2222
use log::LevelFilter;
2323
use spin::Once;
2424

2525
use crate::gdt::load_gdt;
26-
use crate::guest_error::reset_error;
2726
use crate::guest_function_call::dispatch_function;
2827
use crate::guest_logger::init_logger;
29-
use crate::host_function_call::{outb, OutBAction};
28+
use crate::host_function_call::{debug_print, outb};
3029
use crate::idtr::load_idt;
3130
use crate::{
3231
__security_cookie, HEAP_ALLOCATOR, MIN_STACK_ADDRESS, OS_PAGE_SIZE, OUTB_PTR,
@@ -44,26 +43,26 @@ pub fn halt() {
4443

4544
#[no_mangle]
4645
pub extern "C" fn abort() -> ! {
47-
abort_with_code(0)
46+
abort_with_code(&[0])
4847
}
4948

50-
pub fn abort_with_code(code: i32) -> ! {
51-
outb(OutBAction::Abort as u16, code as u8);
49+
pub fn abort_with_code(code: &[u8]) -> ! {
50+
outb(OutBAction::Abort as u16, code);
5251
unreachable!()
5352
}
5453

5554
/// Aborts the program with a code and a message.
5655
///
5756
/// # Safety
5857
/// This function is unsafe because it dereferences a raw pointer.
59-
pub unsafe fn abort_with_code_and_message(code: i32, message_ptr: *const c_char) -> ! {
60-
let peb_ptr = P_PEB.unwrap();
61-
copy_nonoverlapping(
62-
message_ptr,
63-
(*peb_ptr).guestPanicContextData.guestPanicContextDataBuffer as *mut c_char,
64-
CStr::from_ptr(message_ptr).count_bytes() + 1, // +1 for null terminator
58+
pub unsafe fn abort_with_code_and_message(code: &[u8], message_ptr: *const c_char) -> ! {
59+
debug_print(
60+
CStr::from_ptr(message_ptr)
61+
.to_str()
62+
.expect("Invalid UTF-8 string"),
6563
);
66-
outb(OutBAction::Abort as u16, code as u8);
64+
65+
outb(OutBAction::Abort as u16, code);
6766
unreachable!()
6867
}
6968

@@ -115,7 +114,7 @@ pub extern "win64" fn entrypoint(peb_address: u64, seed: u64, ops: u64, max_log_
115114
RUNNING_MODE = (*peb_ptr).runMode;
116115

117116
OUTB_PTR = {
118-
let outb_ptr: extern "win64" fn(u16, u8) =
117+
let outb_ptr: extern "win64" fn(u16, *const u8, u64) =
119118
core::mem::transmute((*peb_ptr).pOutb);
120119
Some(outb_ptr)
121120
};
@@ -125,8 +124,12 @@ pub extern "win64" fn entrypoint(peb_address: u64, seed: u64, ops: u64, max_log_
125124
}
126125

127126
OUTB_PTR_WITH_CONTEXT = {
128-
let outb_ptr_with_context: extern "win64" fn(*mut c_void, u16, u8) =
129-
core::mem::transmute((*peb_ptr).pOutb);
127+
let outb_ptr_with_context: extern "win64" fn(
128+
*mut c_void,
129+
u16,
130+
*const u8,
131+
u64,
132+
) = core::mem::transmute((*peb_ptr).pOutb);
130133
Some(outb_ptr_with_context)
131134
};
132135
}
@@ -146,8 +149,6 @@ pub extern "win64" fn entrypoint(peb_address: u64, seed: u64, ops: u64, max_log_
146149

147150
(*peb_ptr).guest_function_dispatch_ptr = dispatch_function as usize as u64;
148151

149-
reset_error();
150-
151152
hyperlight_main();
152153
}
153154
});

0 commit comments

Comments
 (0)