Skip to content

Commit b4d2abb

Browse files
committed
[common,guest,host] refactored guest and host error data regions
- the guest error data region was removed and now, instead, we leverage the output data region to communicate guest errors back to the host. - previously, the host error data region was incorrectly accessed making it essentially unused. This commit removes the region altogether. There is some merit to the region existing in some way, but this is outside of the scope of #297. Signed-off-by: danbugs <[email protected]>
1 parent 032b1f2 commit b4d2abb

File tree

12 files changed

+90
-390
lines changed

12 files changed

+90
-390
lines changed

src/hyperlight_common/src/input_output.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,20 @@ use core::slice::from_raw_parts_mut;
1818

1919
use anyhow::{bail, Result};
2020

21+
/// The host will use the `InputDataSection` to pass data to the guest. This can be, for example,
22+
/// the issuing of a function call or the result of calling a host function.
2123
pub struct InputDataSection {
2224
ptr: *mut u8,
2325
len: u64,
2426
}
2527

2628
impl InputDataSection {
29+
/// Creates a new `InputDataSection` with the given pointer and length.
2730
pub fn new(ptr: *mut u8, len: u64) -> Self {
2831
InputDataSection { ptr, len }
2932
}
3033

34+
/// Tries to pop shared input data into a type `T`. The type `T` must implement the `TryFrom` trait
3135
pub fn try_pop_shared_input_data_into<T>(&self) -> Result<T>
3236
where
3337
T: for<'a> TryFrom<&'a [u8]>,
@@ -79,6 +83,8 @@ impl InputDataSection {
7983
}
8084
}
8185

86+
/// The guest will use the `OutputDataSection` to pass data back to the host. This can be, for example,
87+
/// issuing a host function call or the result of a guest function call.
8288
pub struct OutputDataSection {
8389
pub ptr: *mut u8,
8490
pub len: u64,
@@ -87,10 +93,12 @@ pub struct OutputDataSection {
8793
impl OutputDataSection {
8894
const STACK_PTR_SIZE: usize = size_of::<u64>();
8995

96+
/// Creates a new `OutputDataSection` with the given pointer and length.
9097
pub fn new(ptr: *mut u8, len: u64) -> Self {
9198
OutputDataSection { ptr, len }
9299
}
93100

101+
/// Pushes shared output data to the output buffer.
94102
pub fn push_shared_output_data(&self, data: Vec<u8>) -> Result<()> {
95103
let shared_buffer_size = self.len as usize;
96104
let odb: &mut [u8] = unsafe { from_raw_parts_mut(self.ptr, shared_buffer_size) };

src/hyperlight_common/src/lib.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ pub const PAGE_SIZE: usize = 0x1_000; // 4KB
2525
extern crate alloc;
2626
extern crate core;
2727

28-
use crate::peb::{HyperlightPEB, RunMode};
29-
3028
pub mod flatbuffer_wrappers;
3129
/// cbindgen:ignore
3230
/// FlatBuffers-related utilities and (mostly) generated code
@@ -48,11 +46,11 @@ pub mod peb;
4846

4947
/// We keep track of the PEB address in a global variable that references a region of
5048
/// shared memory.
51-
pub static mut PEB: *mut HyperlightPEB = core::ptr::null_mut();
49+
pub static mut PEB: *mut peb::HyperlightPEB = core::ptr::null_mut();
5250

5351
/// Hyperlight supports running in both hypervisor mode and in process mode. We keep track of that
5452
/// state in this global variable.
55-
pub static mut RUNNING_MODE: RunMode = RunMode::None;
53+
pub static mut RUNNING_MODE: peb::RunMode = peb::RunMode::None;
5654

5755
/// For in-process mode, we can't call the `outb` instruction directly because it is a privileged
5856
/// instruction. Instead, we use a function pointer to call an `outb_handler` function.

src/hyperlight_common/src/peb.rs

Lines changed: 5 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,6 @@ pub struct HyperlightPEB {
6161
/// before re-entering the guest.
6262
guest_function_dispatch_ptr: u64,
6363

64-
/// Guest error data can be used to pass guest error information
65-
/// between host and the guest.
66-
guest_error_data: Option<MemoryRegion>,
67-
68-
/// Host error data can be used to pass host error information
69-
/// between the host and the guest.
70-
host_error_data: Option<MemoryRegion>,
71-
7264
/// The input data pointer is used to pass data from
7365
/// the host to the guest.
7466
input_data: Option<MemoryRegion>,
@@ -109,8 +101,6 @@ impl HyperlightPEB {
109101
guest_memory_base_address,
110102
guest_memory_size,
111103
guest_function_dispatch_ptr: 0,
112-
guest_error_data: None,
113-
host_error_data: None,
114104
input_data: None,
115105
output_data: None,
116106
guest_panic_context: None,
@@ -134,10 +124,6 @@ impl HyperlightPEB {
134124
/// - +--------------------------+
135125
/// - | Input data | 16KB
136126
/// - +--------------------------+
137-
/// - | Host error data | 4KB
138-
/// - +--------------------------+
139-
/// - | Guest error data | 4KB
140-
/// - +--------------------------+
141127
/// - | Guest heap data | (configurable size)
142128
/// - +--------------------------+
143129
/// - | Guest stack data | (configurable size)
@@ -159,29 +145,19 @@ impl HyperlightPEB {
159145

160146
let guest_heap_size = self.get_guest_heap_data_size();
161147

162-
self.set_guest_error_data_region(
163-
guest_stack_size + guest_heap_size, // start at the end of the host function details
164-
PAGE_SIZE as u64, // 4KB
165-
);
166-
167-
self.set_host_error_data_region(
168-
guest_stack_size + guest_heap_size + PAGE_SIZE as u64, // start at the end of the guest error data
169-
PAGE_SIZE as u64, // 4KB
170-
);
171-
172148
self.set_input_data_region(
173-
guest_stack_size + guest_heap_size + PAGE_SIZE as u64 * 2, // start at the end of the host error data
174-
PAGE_SIZE as u64 * 4, // 16KB
149+
guest_stack_size + guest_heap_size, // start at the end of the heap
150+
PAGE_SIZE as u64 * 4, // 16KB
175151
);
176152

177153
self.set_output_data_region(
178-
guest_stack_size + guest_heap_size + PAGE_SIZE as u64 * 6, // start at the end of the input data
154+
guest_stack_size + guest_heap_size + PAGE_SIZE as u64 * 4, // start at the end of the input data
179155
PAGE_SIZE as u64 * 4, // 16KB
180156
);
181157

182158
self.set_guest_panic_context_region(
183-
guest_stack_size + guest_heap_size + PAGE_SIZE as u64 * 10, // start at the end of the output data
184-
PAGE_SIZE as u64, // 4KB
159+
guest_stack_size + guest_heap_size + PAGE_SIZE as u64 * 8, // start at the end of the output data
160+
PAGE_SIZE as u64, // 4KB
185161
);
186162
}
187163

@@ -291,57 +267,6 @@ impl HyperlightPEB {
291267
.size
292268
}
293269

294-
/// Sets the guest error data region.
295-
pub fn set_guest_error_data_region(&mut self, offset: u64, size: u64) {
296-
self.guest_error_data = Some(MemoryRegion {
297-
offset: Some(offset),
298-
size,
299-
});
300-
}
301-
302-
/// Gets the guest error data region depending on the running mode (i.e., if `RunMode::Hypervisor` this
303-
/// returns the same as `get_guest_error_guest_address`. If `RunMode::InProcessWindows` or `RunMode::InProcessLinux`, it
304-
/// returns the error data host address).
305-
pub fn get_guest_error_data_address(&self) -> u64 {
306-
let region = self
307-
.guest_error_data
308-
.as_ref()
309-
.expect("Guest error data region not set");
310-
match self.run_mode {
311-
RunMode::Hypervisor => self.get_guest_error_guest_address(),
312-
RunMode::InProcessWindows | RunMode::InProcessLinux => {
313-
region.offset.unwrap() + self.guest_memory_host_base_address
314-
}
315-
_ => panic!("Invalid running mode"),
316-
}
317-
}
318-
319-
/// Gets the guest error data region with guest addresses.
320-
pub fn get_guest_error_guest_address(&self) -> u64 {
321-
self.guest_error_data
322-
.as_ref()
323-
.expect("Guest error data region not set")
324-
.offset
325-
.unwrap()
326-
+ self.guest_memory_base_address
327-
}
328-
329-
/// Gets the guest error data size.
330-
pub fn get_guest_error_data_size(&self) -> u64 {
331-
self.guest_error_data
332-
.as_ref()
333-
.expect("Guest error data region not set")
334-
.size
335-
}
336-
337-
/// Sets the host error data region.
338-
pub fn set_host_error_data_region(&mut self, offset: u64, size: u64) {
339-
self.host_error_data = Some(MemoryRegion {
340-
offset: Some(offset),
341-
size,
342-
});
343-
}
344-
345270
/// Sets the input data region.
346271
pub fn set_input_data_region(&mut self, offset: u64, size: u64) {
347272
self.input_data = Some(MemoryRegion {
@@ -350,24 +275,6 @@ impl HyperlightPEB {
350275
});
351276
}
352277

353-
/// Gets the host error data region with guest addresses.
354-
pub fn get_host_error_guest_address(&self) -> u64 {
355-
self.host_error_data
356-
.as_ref()
357-
.expect("Host error data region not set")
358-
.offset
359-
.unwrap()
360-
+ self.guest_memory_base_address
361-
}
362-
363-
/// Gets the host error data size.
364-
pub fn get_host_error_data_size(&self) -> u64 {
365-
self.host_error_data
366-
.as_ref()
367-
.expect("Host error data region not set")
368-
.size
369-
}
370-
371278
/// Gets the input data region with guest addresses.
372279
pub fn get_input_data_guest_region(&self) -> (u64, u64) {
373280
let region = self.input_data.as_ref().expect("Input data region not set");

src/hyperlight_guest/src/entrypoint.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use log::LevelFilter;
2424
use spin::Once;
2525

2626
use crate::gdt::load_gdt;
27-
use crate::guest_error::reset_error;
2827
use crate::guest_function_call::dispatch_function;
2928
use crate::guest_logger::init_logger;
3029
use crate::idtr::load_idt;
@@ -142,8 +141,6 @@ pub extern "win64" fn entrypoint(peb_address: u64, seed: u64, max_log_level: u64
142141
_ => panic!("Invalid runmode in PEB"),
143142
}
144143

145-
reset_error();
146-
147144
hyperlight_main();
148145
});
149146

src/hyperlight_guest/src/guest_error.rs

Lines changed: 9 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -14,72 +14,33 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
use alloc::string::{String, ToString};
17+
use alloc::string::ToString;
1818
use alloc::vec::Vec;
1919
use core::ffi::{c_char, CStr};
2020

2121
use hyperlight_common::flatbuffer_wrappers::guest_error::{ErrorCode, GuestError};
22+
use hyperlight_common::input_output::OutputDataSection;
2223
use hyperlight_common::outb::{outb, OutBAction};
2324
use hyperlight_common::PEB;
24-
use log::error;
2525

2626
use crate::entrypoint::halt;
2727

2828
pub(crate) fn write_error(error_code: ErrorCode, message: Option<&str>) {
2929
let peb = unsafe { (*PEB).clone() };
30+
let output_data: OutputDataSection = peb.get_output_data_region().into();
31+
3032
let guest_error = GuestError::new(
3133
error_code.clone(),
3234
message.map_or("".to_string(), |m| m.to_string()),
3335
);
34-
let mut guest_error_buffer: Vec<u8> = (&guest_error)
36+
37+
let guest_error_buffer: Vec<u8> = (&guest_error)
3538
.try_into()
3639
.expect("Invalid guest_error_buffer, could not be converted to a Vec<u8>");
3740

38-
unsafe {
39-
assert_ne!(!peb.get_guest_error_data_address(), 0);
40-
let len = guest_error_buffer.len();
41-
if guest_error_buffer.len() > peb.get_guest_error_data_size() as usize {
42-
error!(
43-
"Guest error buffer is too small to hold the error message: size {} buffer size {} message may be truncated",
44-
guest_error_buffer.len(),
45-
peb.get_guest_error_data_size() as usize
46-
);
47-
// get the length of the message
48-
let message_len = message.map_or("".to_string(), |m| m.to_string()).len();
49-
// message is too long, truncate it
50-
let truncate_len =
51-
message_len - (guest_error_buffer.len() - peb.get_guest_error_data_size() as usize);
52-
let truncated_message = message
53-
.map_or("".to_string(), |m| m.to_string())
54-
.chars()
55-
.take(truncate_len)
56-
.collect::<String>();
57-
let guest_error = GuestError::new(error_code, truncated_message);
58-
guest_error_buffer = (&guest_error)
59-
.try_into()
60-
.expect("Invalid guest_error_buffer, could not be converted to a Vec<u8>");
61-
}
62-
63-
// Optimally, we'd use copy_from_slice here, but, because
64-
// p_guest_error_buffer is a *mut c_void, we can't do that.
65-
// Instead, we do the copying manually using pointer arithmetic.
66-
// Plus; before, we'd do an assert w/ the result from copy_from_slice,
67-
// but, because copy_nonoverlapping doesn't return anything, we can't do that.
68-
// Instead, we do the prior asserts/checks to check the destination pointer isn't null
69-
// and that there is enough space in the destination buffer for the copy.
70-
let dest_ptr = peb.get_guest_error_data_address() as *mut u8;
71-
core::ptr::copy_nonoverlapping(guest_error_buffer.as_ptr(), dest_ptr, len);
72-
}
73-
}
74-
75-
pub(crate) fn reset_error() {
76-
unsafe {
77-
core::ptr::write_bytes(
78-
(*PEB).get_guest_error_data_address() as *mut u8,
79-
0,
80-
(*PEB).get_guest_error_data_size() as usize,
81-
);
82-
}
41+
output_data
42+
.push_shared_output_data(guest_error_buffer)
43+
.expect("Failed to push shared output data");
8344
}
8445

8546
pub(crate) fn set_error(error_code: ErrorCode, message: &str) {

src/hyperlight_guest/src/guest_function_call.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use hyperlight_common::input_output::{InputDataSection, OutputDataSection};
2424

2525
use crate::entrypoint::halt;
2626
use crate::error::{HyperlightGuestError, Result};
27-
use crate::guest_error::{reset_error, set_error};
27+
use crate::guest_error::set_error;
2828
use crate::{PEB, REGISTERED_GUEST_FUNCTIONS};
2929

3030
type GuestFunc = fn(&FunctionCall) -> Result<Vec<u8>>;
@@ -80,8 +80,6 @@ pub(crate) fn call_guest_function(function_call: FunctionCall) -> Result<Vec<u8>
8080
#[no_mangle]
8181
#[inline(never)]
8282
fn internal_dispatch_function() -> Result<()> {
83-
reset_error();
84-
8583
#[cfg(debug_assertions)]
8684
log::trace!("internal_dispatch_function");
8785

src/hyperlight_guest/src/host_error.rs

Lines changed: 0 additions & 42 deletions
This file was deleted.

src/hyperlight_guest/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,6 @@ pub mod guest_error;
3434
pub mod guest_function_call;
3535
pub mod guest_function_definition;
3636
pub mod guest_function_register;
37-
// TODO(danbugs:297): bring back
38-
// pub mod host_error;
3937

4038
pub(crate) mod guest_logger;
4139
pub mod memory;

0 commit comments

Comments
 (0)