Skip to content

Commit 20ad22f

Browse files
committed
[common/peb,guest,host/{mem,sandbox}] removed the guest error region
Guest errors are now transmitted via the input/output stacks. Signed-off-by: danbugs <[email protected]>
1 parent d8240f0 commit 20ad22f

File tree

10 files changed

+29
-197
lines changed

10 files changed

+29
-197
lines changed

src/hyperlight_common/src/mem/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ pub struct GuestPanicContextData {
8484
pub struct HyperlightPEB {
8585
pub security_cookie_seed: u64,
8686
pub guest_function_dispatch_ptr: u64,
87-
pub guestErrorData: GuestErrorData,
8887
pub pCode: *mut c_char,
8988
pub pOutb: *mut c_void,
9089
pub pOutbContext: *mut c_void,

src/hyperlight_guest/src/entrypoint.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ 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;
2928
use crate::host_function_call::{outb, OutBAction};
@@ -146,8 +145,6 @@ pub extern "win64" fn entrypoint(peb_address: u64, seed: u64, ops: u64, max_log_
146145

147146
(*peb_ptr).guest_function_dispatch_ptr = dispatch_function as usize as u64;
148147

149-
reset_error();
150-
151148
hyperlight_main();
152149
}
153150
});

src/hyperlight_guest/src/guest_error.rs

Lines changed: 5 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -14,73 +14,27 @@ 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 log::error;
2322

2423
use crate::entrypoint::halt;
2524
use crate::host_function_call::{outb, OutBAction};
26-
use crate::P_PEB;
25+
use crate::shared_output_data::push_shared_output_data;
2726

2827
pub(crate) fn write_error(error_code: ErrorCode, message: Option<&str>) {
2928
let guest_error = GuestError::new(
3029
error_code.clone(),
3130
message.map_or("".to_string(), |m| m.to_string()),
3231
);
33-
let mut guest_error_buffer: Vec<u8> = (&guest_error)
32+
let guest_error_buffer: Vec<u8> = (&guest_error)
3433
.try_into()
3534
.expect("Invalid guest_error_buffer, could not be converted to a Vec<u8>");
3635

37-
unsafe {
38-
assert!(!(*P_PEB.unwrap()).guestErrorData.guestErrorBuffer.is_null());
39-
let len = guest_error_buffer.len();
40-
if guest_error_buffer.len() > (*P_PEB.unwrap()).guestErrorData.guestErrorSize as usize {
41-
error!(
42-
"Guest error buffer is too small to hold the error message: size {} buffer size {} message may be truncated",
43-
guest_error_buffer.len(),
44-
(*P_PEB.unwrap()).guestErrorData.guestErrorSize as usize
45-
);
46-
// get the length of the message
47-
let message_len = message.map_or("".to_string(), |m| m.to_string()).len();
48-
// message is too long, truncate it
49-
let truncate_len = message_len
50-
- (guest_error_buffer.len()
51-
- (*P_PEB.unwrap()).guestErrorData.guestErrorSize 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 = (*P_PEB.unwrap()).guestErrorData.guestErrorBuffer 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-
let peb_ptr = P_PEB.unwrap();
78-
core::ptr::write_bytes(
79-
(*peb_ptr).guestErrorData.guestErrorBuffer,
80-
0,
81-
(*peb_ptr).guestErrorData.guestErrorSize as usize,
82-
);
83-
}
36+
push_shared_output_data(guest_error_buffer)
37+
.expect("Unable to push guest error to shared output data");
8438
}
8539

8640
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
@@ -23,7 +23,7 @@ use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode;
2323

2424
use crate::entrypoint::halt;
2525
use crate::error::{HyperlightGuestError, Result};
26-
use crate::guest_error::{reset_error, set_error};
26+
use crate::guest_error::set_error;
2727
use crate::shared_input_data::try_pop_shared_input_data_into;
2828
use crate::shared_output_data::push_shared_output_data;
2929
use crate::REGISTERED_GUEST_FUNCTIONS;
@@ -81,8 +81,6 @@ pub(crate) fn call_guest_function(function_call: FunctionCall) -> Result<Vec<u8>
8181
#[no_mangle]
8282
#[inline(never)]
8383
fn internal_dispatch_function() -> Result<()> {
84-
reset_error();
85-
8684
#[cfg(debug_assertions)]
8785
log::trace!("internal_dispatch_function");
8886

src/hyperlight_host/src/func/guest_err.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,27 @@ use crate::mem::shared_mem::HostSharedMemory;
2121
use crate::metrics::{METRIC_GUEST_ERROR, METRIC_GUEST_ERROR_LABEL_CODE};
2222
use crate::sandbox::mem_mgr::MemMgrWrapper;
2323
use crate::{log_then_return, Result};
24+
2425
/// Check for a guest error and return an `Err` if one was found,
2526
/// and `Ok` if one was not found.
26-
pub(crate) fn check_for_guest_error(mgr: &MemMgrWrapper<HostSharedMemory>) -> Result<()> {
27-
let guest_err = mgr.as_ref().get_guest_error()?;
27+
pub(crate) fn check_for_guest_error(mgr: &mut MemMgrWrapper<HostSharedMemory>) -> Result<()> {
28+
let guest_err = mgr.as_mut().get_guest_error().ok();
29+
let Some(guest_err) = guest_err else {
30+
return Ok(());
31+
};
32+
33+
metrics::counter!(
34+
METRIC_GUEST_ERROR,
35+
METRIC_GUEST_ERROR_LABEL_CODE => (guest_err.code as u64).to_string()
36+
)
37+
.increment(1);
38+
2839
match guest_err.code {
2940
ErrorCode::NoError => Ok(()),
3041
ErrorCode::StackOverflow => {
31-
metrics::counter!(METRIC_GUEST_ERROR, METRIC_GUEST_ERROR_LABEL_CODE => (guest_err.code as u64).to_string()).increment(1);
3242
log_then_return!(StackOverflow());
3343
}
3444
_ => {
35-
metrics::counter!(METRIC_GUEST_ERROR, METRIC_GUEST_ERROR_LABEL_CODE => (guest_err.code as u64).to_string()).increment(1);
3645
log_then_return!(GuestError(guest_err.code, guest_err.message.clone()));
3746
}
3847
}

src/hyperlight_host/src/mem/layout.rs

Lines changed: 3 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ use rand::{rng, RngCore};
2222
use tracing::{instrument, Span};
2323

2424
use super::memory_region::MemoryRegionType::{
25-
Code, GuardPage, GuestErrorData, Heap, InputData, OutputData, PageTables, PanicContext, Peb,
26-
Stack,
25+
Code, GuardPage, Heap, InputData, OutputData, PageTables, PanicContext, Peb, Stack,
2726
};
2827
use super::memory_region::{MemoryRegion, MemoryRegionFlags, MemoryRegionVecBuilder};
2928
use super::mgr::AMOUNT_OF_MEMORY_PER_PT;
@@ -45,8 +44,6 @@ use crate::{log_then_return, new_error, Result};
4544
// +-------------------------------------------+
4645
// | Input Data |
4746
// +-------------------------------------------+
48-
// | Guest Error Log |
49-
// +-------------------------------------------+
5047
// | PEB Struct | (HyperlightPEB size)
5148
// +-------------------------------------------+
5249
// | Guest Code |
@@ -60,9 +57,6 @@ use crate::{log_then_return, new_error, Result};
6057
// | PML4 |
6158
// +-------------------------------------------+ 0x0_000
6259

63-
/// - `GuestError` - contains a buffer for any guest error that occurred.
64-
/// the length of this field is `GuestErrorBufferSize` from `SandboxConfiguration`
65-
///
6660
/// - `InputData` - this is a buffer that is used for input data to the host program.
6761
/// the length of this field is `InputDataSize` from `SandboxConfiguration`
6862
///
@@ -95,7 +89,6 @@ pub(crate) struct SandboxMemoryLayout {
9589
peb_offset: usize,
9690
peb_security_cookie_seed_offset: usize,
9791
peb_guest_dispatch_function_ptr_offset: usize, // set by guest in guest entrypoint
98-
peb_guest_error_offset: usize,
9992
peb_code_and_outb_pointer_offset: usize,
10093
peb_runmode_offset: usize,
10194
peb_input_data_offset: usize,
@@ -106,7 +99,6 @@ pub(crate) struct SandboxMemoryLayout {
10699

107100
// The following are the actual values
108101
// that are written to the PEB struct
109-
pub(super) guest_error_buffer_offset: usize,
110102
pub(super) input_data_buffer_offset: usize,
111103
pub(super) output_data_buffer_offset: usize,
112104
guest_panic_context_buffer_offset: usize,
@@ -143,10 +135,6 @@ impl Debug for SandboxMemoryLayout {
143135
"Guest Dispatch Function Pointer Offset",
144136
&format_args!("{:#x}", self.peb_guest_dispatch_function_ptr_offset),
145137
)
146-
.field(
147-
"Guest Error Offset",
148-
&format_args!("{:#x}", self.peb_guest_error_offset),
149-
)
150138
.field(
151139
"Code and OutB Pointer Offset",
152140
&format_args!("{:#x}", self.peb_code_and_outb_pointer_offset),
@@ -171,10 +159,6 @@ impl Debug for SandboxMemoryLayout {
171159
"Guest Stack Offset",
172160
&format_args!("{:#x}", self.peb_guest_stack_data_offset),
173161
)
174-
.field(
175-
"Guest Error Buffer Offset",
176-
&format_args!("{:#x}", self.guest_error_buffer_offset),
177-
)
178162
.field(
179163
"Input Data Buffer Offset",
180164
&format_args!("{:#x}", self.input_data_buffer_offset),
@@ -259,7 +243,6 @@ impl SandboxMemoryLayout {
259243
peb_offset + offset_of!(HyperlightPEB, security_cookie_seed);
260244
let peb_guest_dispatch_function_ptr_offset =
261245
peb_offset + offset_of!(HyperlightPEB, guest_function_dispatch_ptr);
262-
let peb_guest_error_offset = peb_offset + offset_of!(HyperlightPEB, guestErrorData);
263246
let peb_code_and_outb_pointer_offset = peb_offset + offset_of!(HyperlightPEB, pCode);
264247
let peb_runmode_offset = peb_offset + offset_of!(HyperlightPEB, runMode);
265248
let peb_input_data_offset = peb_offset + offset_of!(HyperlightPEB, inputdata);
@@ -272,12 +255,8 @@ impl SandboxMemoryLayout {
272255
// The following offsets are the actual values that relate to memory layout,
273256
// which are written to PEB struct
274257
let peb_address = Self::BASE_ADDRESS + peb_offset;
275-
let guest_error_buffer_offset = round_up_to(
276-
peb_guest_stack_data_offset + size_of::<GuestStackData>(),
277-
PAGE_SIZE_USIZE,
278-
);
279258
let input_data_buffer_offset = round_up_to(
280-
guest_error_buffer_offset + cfg.get_guest_error_buffer_size(),
259+
peb_guest_stack_data_offset + size_of::<GuestStackData>(),
281260
PAGE_SIZE_USIZE,
282261
);
283262
let output_data_buffer_offset = round_up_to(
@@ -305,15 +284,13 @@ impl SandboxMemoryLayout {
305284
heap_size,
306285
peb_security_cookie_seed_offset,
307286
peb_guest_dispatch_function_ptr_offset,
308-
peb_guest_error_offset,
309287
peb_code_and_outb_pointer_offset,
310288
peb_runmode_offset,
311289
peb_input_data_offset,
312290
peb_output_data_offset,
313291
peb_guest_panic_context_offset,
314292
peb_heap_data_offset,
315293
peb_guest_stack_data_offset,
316-
guest_error_buffer_offset,
317294
sandbox_memory_config: cfg,
318295
code_size,
319296
input_data_buffer_offset,
@@ -333,18 +310,6 @@ impl SandboxMemoryLayout {
333310
self.peb_runmode_offset
334311
}
335312

336-
/// Get the offset in guest memory to the max size of the guest error buffer
337-
#[instrument(skip_all, parent = Span::current(), level= "Trace")]
338-
pub(super) fn get_guest_error_buffer_size_offset(&self) -> usize {
339-
self.peb_guest_error_offset
340-
}
341-
342-
/// Get the offset in guest memory to the error message buffer pointer
343-
#[instrument(skip_all, parent = Span::current(), level= "Trace")]
344-
fn get_guest_error_buffer_pointer_offset(&self) -> usize {
345-
self.peb_guest_error_offset + size_of::<u64>()
346-
}
347-
348313
/// Get the offset in guest memory to the output data size
349314
#[instrument(skip_all, parent = Span::current(), level= "Trace")]
350315
pub(super) fn get_output_data_size_offset(&self) -> usize {
@@ -542,7 +507,6 @@ impl SandboxMemoryLayout {
542507
let mut total_mapped_memory_size: usize = round_up_to(code_size, PAGE_SIZE_USIZE);
543508
total_mapped_memory_size += round_up_to(stack_size, PAGE_SIZE_USIZE);
544509
total_mapped_memory_size += round_up_to(heap_size, PAGE_SIZE_USIZE);
545-
total_mapped_memory_size += round_up_to(cfg.get_guest_error_buffer_size(), PAGE_SIZE_USIZE);
546510
total_mapped_memory_size += round_up_to(cfg.get_input_data_size(), PAGE_SIZE_USIZE);
547511
total_mapped_memory_size += round_up_to(cfg.get_output_data_size(), PAGE_SIZE_USIZE);
548512
total_mapped_memory_size +=
@@ -626,30 +590,12 @@ impl SandboxMemoryLayout {
626590
}
627591

628592
// PEB
629-
let guest_error_offset = builder.push_page_aligned(
593+
let input_data_offset = builder.push_page_aligned(
630594
size_of::<HyperlightPEB>(),
631595
MemoryRegionFlags::READ | MemoryRegionFlags::WRITE,
632596
Peb,
633597
);
634598

635-
let expected_guest_error_offset =
636-
TryInto::<usize>::try_into(self.guest_error_buffer_offset)?;
637-
638-
if guest_error_offset != expected_guest_error_offset {
639-
return Err(new_error!(
640-
"Guest error offset does not match expected Guest error offset expected: {}, actual: {}",
641-
expected_guest_error_offset,
642-
guest_error_offset
643-
));
644-
}
645-
646-
// guest error
647-
let input_data_offset = builder.push_page_aligned(
648-
self.sandbox_memory_config.get_guest_error_buffer_size(),
649-
MemoryRegionFlags::READ | MemoryRegionFlags::WRITE,
650-
GuestErrorData,
651-
);
652-
653599
let expected_input_data_offset = TryInto::<usize>::try_into(self.input_data_buffer_offset)?;
654600

655601
if input_data_offset != expected_input_data_offset {
@@ -818,14 +764,6 @@ impl SandboxMemoryLayout {
818764

819765
// Skip guest_dispatch_function_ptr_offset because it is set by the guest
820766

821-
// Set up Guest Error Fields
822-
let addr = get_address!(guest_error_buffer);
823-
shared_mem.write_u64(self.get_guest_error_buffer_pointer_offset(), addr)?;
824-
shared_mem.write_u64(
825-
self.get_guest_error_buffer_size_offset(),
826-
u64::try_from(self.sandbox_memory_config.get_guest_error_buffer_size())?,
827-
)?;
828-
829767
// Skip code, is set when loading binary
830768
// skip outb and outb context, is set when running in_proc
831769

@@ -958,8 +896,6 @@ mod tests {
958896

959897
expected_size += round_up_to(size_of::<HyperlightPEB>(), PAGE_SIZE_USIZE);
960898

961-
expected_size += round_up_to(cfg.get_guest_error_buffer_size(), PAGE_SIZE_USIZE);
962-
963899
expected_size += round_up_to(cfg.get_input_data_size(), PAGE_SIZE_USIZE);
964900

965901
expected_size += round_up_to(cfg.get_output_data_size(), PAGE_SIZE_USIZE);

src/hyperlight_host/src/mem/memory_region.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,6 @@ pub enum MemoryRegionType {
131131
Code,
132132
/// The region contains the PEB
133133
Peb,
134-
/// The region contains the Guest Error Data
135-
GuestErrorData,
136134
/// The region contains the Input Data
137135
InputData,
138136
/// The region contains the Output Data

src/hyperlight_host/src/mem/mgr.rs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,6 @@ where
199199
MemoryRegionType::OutputData => PAGE_PRESENT | PAGE_RW | PAGE_NX,
200200
MemoryRegionType::Peb => PAGE_PRESENT | PAGE_RW | PAGE_NX,
201201
MemoryRegionType::PanicContext => PAGE_PRESENT | PAGE_RW | PAGE_NX,
202-
MemoryRegionType::GuestErrorData => PAGE_PRESENT | PAGE_RW | PAGE_NX,
203202
MemoryRegionType::PageTables => PAGE_PRESENT | PAGE_RW | PAGE_NX,
204203
},
205204
// If there is an error then the address isn't mapped so mark it as not present
@@ -591,22 +590,11 @@ impl SandboxMemoryManager<HostSharedMemory> {
591590

592591
/// Get the guest error data
593592
#[instrument(err(Debug), skip_all, parent = Span::current(), level= "Trace")]
594-
pub(crate) fn get_guest_error(&self) -> Result<GuestError> {
595-
// get memory buffer max size
596-
let err_buffer_size_offset = self.layout.get_guest_error_buffer_size_offset();
597-
let max_err_buffer_size = self.shared_mem.read::<u64>(err_buffer_size_offset)?;
598-
599-
// get guest error from layout and shared mem
600-
let mut guest_error_buffer = vec![b'0'; usize::try_from(max_err_buffer_size)?];
601-
let err_msg_offset = self.layout.guest_error_buffer_offset;
602-
self.shared_mem
603-
.copy_to_slice(guest_error_buffer.as_mut_slice(), err_msg_offset)?;
604-
GuestError::try_from(guest_error_buffer.as_slice()).map_err(|e| {
605-
new_error!(
606-
"get_guest_error: failed to convert buffer to GuestError: {}",
607-
e
608-
)
609-
})
593+
pub(crate) fn get_guest_error(&mut self) -> Result<GuestError> {
594+
self.shared_mem.try_pop_buffer_into::<GuestError>(
595+
self.layout.output_data_buffer_offset,
596+
self.layout.sandbox_memory_config.get_output_data_size(),
597+
)
610598
}
611599

612600
/// Read guest panic data from the `SharedMemory` contained within `self`

0 commit comments

Comments
 (0)