Skip to content

Commit 8aa7f89

Browse files
committed
tmp (x6)
Signed-off-by: danbugs <[email protected]>
1 parent be6198b commit 8aa7f89

36 files changed

+2365
-2594
lines changed

Diff for: src/hyperlight_common/src/flatbuffer_wrappers/hyperlight_peb.rs

+20-11
Original file line numberDiff line numberDiff line change
@@ -141,37 +141,39 @@ impl HyperlightPEB {
141141
);
142142
}
143143

144-
// TODO(danbugs:297): comment
144+
// Sets the guest error data region, where the guest can write errors to.
145145
pub fn set_guest_error_data_region(&mut self, ptr: u64, size: u64) {
146146
self.guest_error_data_ptr = self.guest_memory_base_address + ptr;
147147
self.guest_error_data_size = size;
148148
}
149149

150-
// TODO(danbugs:297): comment
150+
// Sets the host error data region, where the host can write errors to.
151151
pub fn set_host_error_data_region(&mut self, ptr: u64, size: u64) {
152152
self.host_error_data_ptr = self.guest_memory_base_address + ptr;
153153
self.host_error_data_size = size;
154154
}
155155

156-
// TODO(danbugs:297): comment
156+
// Sets the input data region, where the host can write things like function calls to.
157157
pub fn set_input_data_region(&mut self, ptr: u64, size: u64) {
158158
self.input_data_ptr = self.guest_memory_base_address + ptr;
159159
self.input_data_size = size;
160160
}
161161

162-
// TODO(danbugs:297): comment
162+
// Sets the output data region, where the guest can write things like function return values to.
163163
pub fn set_output_data_region(&mut self, ptr: u64, size: u64) {
164164
self.output_data_ptr = self.guest_memory_base_address + ptr;
165165
self.output_data_size = size;
166166
}
167167

168-
// TODO(danbugs:297): comment
168+
// Sets the guest panic context region, where the guest can write panic context data to.
169169
pub fn set_guest_panic_context_region(&mut self, ptr: u64, size: u64) {
170170
self.guest_panic_context_ptr = self.guest_memory_base_address + ptr;
171171
self.guest_panic_context_size = size;
172172
}
173173

174-
// TODO(danbugs:297): comment
174+
// Gets the guest heap size. If not set, this function panics—this is because the host is always
175+
// expected to set the size of the heap data region in accordance to info from the guest binary,
176+
// so, if this is not set, we have a critical error.
175177
pub fn get_guest_heap_data_size(&self) -> u64 {
176178
if self.guest_heap_data_size == 0 {
177179
panic!("Heap data size is not set");
@@ -180,7 +182,7 @@ impl HyperlightPEB {
180182
self.guest_heap_data_size
181183
}
182184

183-
// TODO(danbugs:297): comment
185+
// Sets the guest heap data region.
184186
pub fn set_guest_heap_data_region(&mut self, ptr: u64, size_override: Option<u64>) {
185187
self.guest_heap_data_ptr = self.guest_memory_base_address + ptr;
186188
// the Hyperlight host always sets the heap data size to a default value, the
@@ -196,7 +198,9 @@ impl HyperlightPEB {
196198
}
197199
}
198200

199-
// TODO(danbugs:297): comment
201+
// Gets the guest heap size. If not set, this function panics—this is because the host is always
202+
// expected to set the size of the heap data region in accordance to info from the guest binary,
203+
// so, if this is not set, we have a critical error.
200204
pub fn get_guest_stack_data_size(&self) -> u64 {
201205
if self.guest_stack_data_size == 0 {
202206
panic!("Stack data size is not set");
@@ -205,7 +209,7 @@ impl HyperlightPEB {
205209
self.guest_stack_data_size
206210
}
207211

208-
// TODO(danbugs:297): comment
212+
// Sets the guest stack data region.
209213
pub fn set_guest_stack_data_region(&mut self, ptr: u64, size_override: Option<u64>) {
210214
self.guest_stack_data_ptr = self.guest_memory_base_address + ptr;
211215

@@ -222,14 +226,19 @@ impl HyperlightPEB {
222226
}
223227
}
224228

225-
// TODO(danbugs:297): comment
229+
// Sets the host function details region, where the guest can write host function details to.
226230
pub fn set_host_function_details_region(&mut self, ptr: u64, size: u64) {
227231
self.host_function_details_ptr = self.guest_memory_base_address + ptr;
228232
self.host_function_details_size = size;
229233
}
230234

231-
// TODO(danbugs:297): comment
235+
// Gets the input data region, where the host can write things like function calls to.
232236
pub fn get_input_data_region(&self) -> (u64, u64) {
233237
(self.input_data_ptr, self.input_data_size)
234238
}
239+
240+
// Gets the output data region, where the guest can write things like function return values to.
241+
pub fn get_output_data_region(&self) -> (u64, u64) {
242+
(self.output_data_ptr, self.output_data_size)
243+
}
235244
}

Diff for: src/hyperlight_common/src/input_output/mod.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,16 @@ impl OutputDataSection {
105105
}
106106

107107
// get offset to next free address on the stack
108-
let stack_ptr_rel: usize = usize::from_le_bytes(
108+
let mut stack_ptr_rel: usize = usize::from_le_bytes(
109109
output_data_buffer[..8]
110110
.try_into()
111111
.expect("Shared output buffer too small"),
112112
);
113113

114+
if stack_ptr_rel == 0 {
115+
stack_ptr_rel = 8;
116+
}
117+
114118
// check if the stack pointer is within the bounds of the buffer.
115119
// It can be equal to the size, but never greater
116120
// It can never be less than 8. An empty buffer's stack pointer is 8
@@ -148,3 +152,15 @@ impl OutputDataSection {
148152
Ok(())
149153
}
150154
}
155+
156+
impl From<(u64, u64)> for InputDataSection {
157+
fn from((ptr, len): (u64, u64)) -> Self {
158+
InputDataSection::new(ptr as *mut u8, len as usize)
159+
}
160+
}
161+
162+
impl From<(u64, u64)> for OutputDataSection {
163+
fn from((ptr, len): (u64, u64)) -> Self {
164+
OutputDataSection::new(ptr as *mut u8, len as usize)
165+
}
166+
}

Diff for: src/hyperlight_guest/src/chkstk.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ limitations under the License.
1616

1717
use core::arch::global_asm;
1818
use core::mem::size_of;
19-
20-
use hyperlight_common::mem::RunMode;
21-
19+
use hyperlight_common::flatbuffer_wrappers::hyperlight_peb::RunMode;
2220
use crate::guest_error::{set_invalid_runmode_error, set_stack_allocate_error};
2321
use crate::{MIN_STACK_ADDRESS, RUNNING_MODE};
2422

Diff for: src/hyperlight_guest/src/entrypoint.rs

+74-40
Original file line numberDiff line numberDiff line change
@@ -14,55 +14,56 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616
use core::arch::asm;
17-
17+
use core::ffi::{c_char, CStr};
18+
use core::ptr::copy_nonoverlapping;
19+
use log::LevelFilter;
1820
use hyperlight_common::flatbuffer_wrappers::hyperlight_peb::{HyperlightPEB, RunMode};
1921
use spin::Once;
2022

2123
use crate::guest_function_call::dispatch_function;
22-
use crate::{__security_cookie, HEAP_ALLOCATOR, PEB};
24+
use crate::{__security_cookie, HEAP_ALLOCATOR, MIN_STACK_ADDRESS, PEB, RUNNING_MODE};
25+
use crate::gdt::load_gdt;
26+
use crate::guest_error::reset_error;
27+
use crate::guest_logger::init_logger;
28+
use crate::host_function_call::{outb, OutBAction};
29+
use crate::idtr::load_idt;
2330

2431
#[inline(never)]
2532
pub fn halt() {
2633
unsafe {
27-
if let RunMode::Hypervisor = PEB.clone().unwrap().run_mode {
34+
if RUNNING_MODE == RunMode::Hypervisor {
2835
asm!("hlt", options(nostack))
2936
}
3037
}
3138
}
3239

33-
// TODO(danbugs:297): delete
3440
#[no_mangle]
35-
pub fn __chkstk() {}
41+
pub extern "C" fn abort() -> ! {
42+
abort_with_code(0)
43+
}
3644

37-
// TODO(danbugs:297): bring back
38-
// #[no_mangle]
39-
// pub extern "C" fn abort() -> ! {
40-
// abort_with_code(0)
41-
// }
42-
//
43-
// pub fn abort_with_code(code: i32) -> ! {
44-
// outb(OutBAction::Abort as u16, code as u8);
45-
// unreachable!()
46-
// }
47-
//
48-
// /// Aborts the program with a code and a message.
49-
// ///
50-
// /// # Safety
51-
// /// This function is unsafe because it dereferences a raw pointer.
52-
// pub unsafe fn abort_with_code_and_message(code: i32, message_ptr: *const c_char) -> ! {
53-
// let peb_ptr = PEB.unwrap();
54-
// copy_nonoverlapping(
55-
// message_ptr,
56-
// (*peb_ptr).guestPanicContextData.guestPanicContextDataBuffer as *mut c_char,
57-
// CStr::from_ptr(message_ptr).count_bytes() + 1, // +1 for null terminator
58-
// );
59-
// outb(OutBAction::Abort as u16, code as u8);
60-
// unreachable!()
61-
// }
45+
pub fn abort_with_code(code: i32) -> ! {
46+
outb(OutBAction::Abort as u16, code as u8);
47+
unreachable!()
48+
}
49+
50+
/// Aborts the program with a code and a message.
51+
///
52+
/// # Safety
53+
/// This function is unsafe because it dereferences a raw pointer.
54+
pub unsafe fn abort_with_code_and_message(code: i32, message_ptr: *const c_char) -> ! {
55+
copy_nonoverlapping(
56+
message_ptr,
57+
(*PEB).guest_panic_context_ptr as *mut c_char,
58+
CStr::from_ptr(message_ptr).count_bytes() + 1, // +1 for null terminator
59+
);
60+
outb(OutBAction::Abort as u16, code as u8);
61+
unreachable!()
62+
}
6263

6364
extern "C" {
6465
fn hyperlight_main();
65-
// fn srand(seed: u32);
66+
fn srand(seed: u32);
6667
}
6768

6869
static INIT: Once = Once::new();
@@ -71,25 +72,58 @@ static INIT: Once = Once::new();
7172
// target without first having setup global `RUNNING_MODE` variable, which __chkstk relies on.
7273
#[no_mangle]
7374
pub extern "win64" fn entrypoint(
74-
hyperlight_peb_ptr: u64,
75-
_hyperlight_peb_size: u64,
75+
peb_address: u64,
76+
// TODO(danbugs:297): remove the extra arg
77+
_: u64,
7678
seed: u64,
77-
_max_log_level: u64,
79+
max_log_level: u64,
7880
) {
7981
INIT.call_once(|| unsafe {
80-
let peb = hyperlight_peb_ptr as *mut HyperlightPEB;
82+
PEB = peb_address as *mut HyperlightPEB;
83+
RUNNING_MODE = (*PEB).clone().run_mode;
84+
85+
// The guest receives an undifferentiated block of memory that it can address as it sees fit.
86+
// This 'addressing' is done by writing to the PEB the guest's memory layout via this function,
87+
// or by directly altering the PEB. `set_default_memory_layout` will configure the PEB to
88+
// with a memory layout that is compatible with the expectations of guests that use the
89+
// `hyperlight_guest` library (e.g., simpleguest, and callbackguest).
90+
(*PEB).set_default_memory_layout();
91+
92+
// The guest sets the address to a "guest function dispatch" function, which is a function
93+
// that is called by the host to dispatch calls to guest functions.
94+
(*PEB).guest_function_dispatch_ptr = dispatch_function as usize as u64;
8195

96+
// Set up the guest heap
8297
HEAP_ALLOCATOR
8398
.try_lock()
8499
.expect("Failed to access HEAP_ALLOCATOR")
85-
.init((*peb).guest_heap_data_ptr as usize, (*peb).guest_heap_data_size as usize);
86-
87-
(*peb).set_default_memory_layout();
88-
(*peb).guest_function_dispatch_ptr = dispatch_function as usize as u64;
100+
.init((*PEB).guest_heap_data_ptr as usize, (*PEB).guest_heap_data_size as usize);
89101

90102
__security_cookie = seed;
91103

92-
PEB = Some((*peb).clone());
104+
// Set the seed for the random number generator for C code using rand;
105+
let srand_seed = ((peb_address << 8 ^ seed >> 4) >> 32) as u32;
106+
srand(srand_seed);
107+
108+
// Set up the logger
109+
let max_log_level = LevelFilter::iter()
110+
.nth(max_log_level as usize)
111+
.expect("Invalid log level");
112+
init_logger(max_log_level);
113+
114+
if (*PEB).run_mode == RunMode::Hypervisor {
115+
// This static is to make it easier to implement the __chkstk function in assembly.
116+
// It also means that, should we change the layout of the struct in the future, we
117+
// don't have to change the assembly code. Plus, while this could be accessible via
118+
// the PEB, we don't want to expose it entirely to user code.
119+
MIN_STACK_ADDRESS = (*PEB).guest_stack_data_ptr;
120+
121+
// Setup GDT and IDT
122+
load_gdt();
123+
load_idt();
124+
}
125+
126+
reset_error();
93127

94128
hyperlight_main();
95129
});

Diff for: src/hyperlight_guest/src/guest_error.rs

+14-15
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ use hyperlight_common::flatbuffer_wrappers::guest_error::{ErrorCode, GuestError}
2222
use log::error;
2323

2424
use crate::entrypoint::halt;
25+
use crate::host_function_call::{outb, OutBAction};
2526
use crate::PEB;
2627

2728
pub(crate) fn write_error(error_code: ErrorCode, message: Option<&str>) {
28-
let peb = unsafe { PEB.clone().unwrap() };
29+
let peb = unsafe { (*PEB).clone() };
2930
let guest_error = GuestError::new(
3031
error_code.clone(),
3132
message.map_or("".to_string(), |m| m.to_string()),
@@ -35,7 +36,7 @@ pub(crate) fn write_error(error_code: ErrorCode, message: Option<&str>) {
3536
.expect("Invalid guest_error_buffer, could not be converted to a Vec<u8>");
3637

3738
unsafe {
38-
assert!(!peb.guest_error_data_ptr != 0);
39+
assert_ne!(!peb.guest_error_data_ptr, 0);
3940
let len = guest_error_buffer.len();
4041
if guest_error_buffer.len() > peb.guest_error_data_size as usize {
4142
error!(
@@ -73,11 +74,10 @@ pub(crate) fn write_error(error_code: ErrorCode, message: Option<&str>) {
7374

7475
pub(crate) fn reset_error() {
7576
unsafe {
76-
let peb = PEB.clone().unwrap();
7777
core::ptr::write_bytes(
78-
peb.guest_error_data_ptr as *mut u8,
78+
(*PEB).guest_error_data_ptr as *mut u8,
7979
0,
80-
peb.guest_error_data_size as usize,
80+
(*PEB).guest_error_data_size as usize,
8181
);
8282
}
8383
}
@@ -86,16 +86,15 @@ pub(crate) fn set_error(error_code: ErrorCode, message: &str) {
8686
write_error(error_code, Some(message));
8787
}
8888

89-
// TODO(danbugs:297): bring back
90-
// pub(crate) fn set_error_and_halt(error_code: ErrorCode, message: &str) {
91-
// set_error(error_code, message);
92-
// halt();
93-
// }
94-
//
95-
// #[no_mangle]
96-
// pub(crate) extern "win64" fn set_stack_allocate_error() {
97-
// outb(OutBAction::Abort as u16, ErrorCode::StackOverflow as u8);
98-
// }
89+
pub(crate) fn set_error_and_halt(error_code: ErrorCode, message: &str) {
90+
set_error(error_code, message);
91+
halt();
92+
}
93+
94+
#[no_mangle]
95+
pub(crate) extern "win64" fn set_stack_allocate_error() {
96+
outb(OutBAction::Abort as u16, ErrorCode::StackOverflow as u8);
97+
}
9998

10099
#[no_mangle]
101100
pub(crate) extern "win64" fn set_invalid_runmode_error() {

Diff for: src/hyperlight_guest/src/guest_function_call.rs

+3-10
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,10 @@ fn internal_dispatch_function() -> Result<()> {
8585
#[cfg(debug_assertions)]
8686
log::trace!("internal_dispatch_function");
8787

88-
let peb = unsafe { PEB.clone().unwrap() };
88+
let peb = unsafe { (*PEB).clone() };
8989

90-
let input_data_ptr = peb.input_data_ptr;
91-
let input_data_size = peb.input_data_size;
92-
let input_data_section =
93-
InputDataSection::new(input_data_ptr as *mut u8, input_data_size as usize);
94-
95-
let output_data_ptr = peb.output_data_ptr;
96-
let output_data_size = peb.output_data_size;
97-
let output_data_section =
98-
OutputDataSection::new(output_data_ptr as *mut u8, output_data_size as usize);
90+
let input_data_section: InputDataSection = peb.get_input_data_region().into();
91+
let output_data_section: OutputDataSection = peb.get_output_data_region().into();
9992

10093
let function_call = input_data_section
10194
.try_pop_shared_input_data_into::<FunctionCall>()

0 commit comments

Comments
 (0)