Skip to content

Commit a0cf29f

Browse files
committed
Use new API in host and guest
Signed-off-by: Jorge Prendes <jorge.prendes@gmail.com>
1 parent 59e5cab commit a0cf29f

9 files changed

Lines changed: 87 additions & 81 deletions

File tree

src/hyperlight_guest/src/guest_handle/host_comm.rs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,17 @@ use alloc::format;
1818
use alloc::string::ToString;
1919
use alloc::vec::Vec;
2020

21-
use flatbuffers::FlatBufferBuilder;
2221
use hyperlight_common::flatbuffer_wrappers::function_call::{FunctionCall, FunctionCallType};
2322
use hyperlight_common::flatbuffer_wrappers::function_types::{
2423
FunctionCallResult, ParameterValue, ReturnType, ReturnValue,
2524
};
2625
use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode;
2726
use hyperlight_common::flatbuffer_wrappers::guest_log_data::GuestLogData;
2827
use hyperlight_common::flatbuffer_wrappers::guest_log_level::LogLevel;
29-
use hyperlight_common::flatbuffer_wrappers::util::estimate_flatbuffer_capacity;
28+
use hyperlight_common::flatbuffer_wrappers::host_function_details::HostFunctionDetails;
29+
use hyperlight_common::flatbuffer_wrappers::util::{
30+
decode, encode, encode_extend, estimate_flatbuffer_capacity,
31+
};
3032
use hyperlight_common::outb::OutBAction;
3133
use tracing::instrument;
3234

@@ -124,10 +126,15 @@ impl GuestHandle {
124126
return_type,
125127
);
126128

127-
let mut builder = FlatBufferBuilder::with_capacity(estimated_capacity);
128-
129-
let host_function_call_buffer = host_function_call.encode(&mut builder);
130-
self.push_shared_output_data(host_function_call_buffer)?;
129+
let host_function_call_buffer = Vec::with_capacity(estimated_capacity);
130+
let host_function_call_buffer =
131+
encode_extend(&host_function_call, host_function_call_buffer).map_err(|e| {
132+
HyperlightGuestError::new(
133+
ErrorCode::GuestError,
134+
format!("Error serializing host function call to flatbuffer: {}", e),
135+
)
136+
})?;
137+
self.push_shared_output_data(&host_function_call_buffer)?;
131138

132139
unsafe {
133140
out32(OutBAction::CallFunction as u16, 0);
@@ -173,9 +180,8 @@ impl GuestHandle {
173180
line,
174181
);
175182

176-
let bytes: Vec<u8> = guest_log_data
177-
.try_into()
178-
.expect("Failed to convert GuestLogData to bytes");
183+
let bytes: Vec<u8> =
184+
encode(&guest_log_data).expect("Failed to convert GuestLogData to bytes");
179185

180186
self.push_shared_output_data(&bytes)
181187
.expect("Unable to push log data to shared output data");

src/hyperlight_guest/src/guest_handle/io.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use core::any::type_name;
2020
use core::slice::from_raw_parts_mut;
2121

2222
use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode;
23+
use hyperlight_common::flatbuffer_wrappers::util::{Deserialize, decode};
2324
use tracing::instrument;
2425

2526
use super::handle::GuestHandle;
@@ -30,7 +31,7 @@ impl GuestHandle {
3031
#[instrument(skip_all, level = "Trace")]
3132
pub fn try_pop_shared_input_data_into<T>(&self) -> Result<T>
3233
where
33-
T: for<'a> TryFrom<&'a [u8]>,
34+
T: for<'a> Deserialize<'a>,
3435
{
3536
let peb_ptr = self.peb().unwrap();
3637
let input_stack_size = unsafe { (*peb_ptr).input_stack.size as usize };
@@ -69,7 +70,7 @@ impl GuestHandle {
6970
let buffer = &idb[last_element_offset_rel as usize..];
7071

7172
// convert the buffer to T
72-
let type_t = match T::try_from(buffer) {
73+
let type_t = match decode::<T>(buffer) {
7374
Ok(t) => Ok(t),
7475
Err(_e) => {
7576
return Err(HyperlightGuestError::new(

src/hyperlight_guest_bin/src/guest_function/call.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ limitations under the License.
1717
use alloc::format;
1818
use alloc::vec::Vec;
1919

20-
use flatbuffers::FlatBufferBuilder;
2120
use hyperlight_common::flatbuffer_wrappers::function_call::{FunctionCall, FunctionCallType};
2221
use hyperlight_common::flatbuffer_wrappers::function_types::{FunctionCallResult, ParameterType};
2322
use hyperlight_common::flatbuffer_wrappers::guest_error::{ErrorCode, GuestError};
23+
use hyperlight_common::flatbuffer_wrappers::util::encode;
2424
use hyperlight_guest::bail;
2525
use hyperlight_guest::error::{HyperlightGuestError, Result};
2626
use tracing::instrument;
@@ -115,10 +115,9 @@ pub(crate) fn internal_dispatch_function() {
115115
Err(err) => {
116116
let guest_error = Err(GuestError::new(err.kind, err.message));
117117
let fcr = FunctionCallResult::new(guest_error);
118-
let mut builder = FlatBufferBuilder::new();
119-
let data = fcr.encode(&mut builder);
118+
let data = encode(&fcr).unwrap();
120119
handle
121-
.push_shared_output_data(data)
120+
.push_shared_output_data(&data)
122121
.expect("Failed to serialize function call result");
123122
}
124123
}

src/hyperlight_guest_capi/src/error.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ limitations under the License.
1616

1717
use core::ffi::{CStr, c_char};
1818

19-
use flatbuffers::FlatBufferBuilder;
2019
use hyperlight_common::flatbuffer_wrappers::function_types::FunctionCallResult;
2120
use hyperlight_common::flatbuffer_wrappers::guest_error::{ErrorCode, GuestError};
21+
use hyperlight_common::flatbuffer_wrappers::util::encode;
2222
use hyperlight_guest_bin::GUEST_HANDLE;
2323

2424
use crate::alloc::borrow::ToOwned;
@@ -33,12 +33,11 @@ pub extern "C" fn hl_set_error(err: ErrorCode, message: *const c_char) {
3333
.to_owned(),
3434
));
3535
let fcr = FunctionCallResult::new(guest_error);
36-
let mut builder = FlatBufferBuilder::new();
37-
let data = fcr.encode(&mut builder);
36+
let data = encode(&fcr).unwrap();
3837
unsafe {
3938
#[allow(static_mut_refs)] // we are single threaded
4039
GUEST_HANDLE
41-
.push_shared_output_data(data)
40+
.push_shared_output_data(&data)
4241
.expect("Failed to set error")
4342
}
4443
}

src/hyperlight_host/benches/benchmarks.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ use std::thread;
1919
use std::time::{Duration, Instant};
2020

2121
use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main};
22-
use flatbuffers::FlatBufferBuilder;
2322
use hyperlight_common::flatbuffer_wrappers::function_call::{FunctionCall, FunctionCallType};
2423
use hyperlight_common::flatbuffer_wrappers::function_types::{ParameterValue, ReturnType};
25-
use hyperlight_common::flatbuffer_wrappers::util::estimate_flatbuffer_capacity;
24+
use hyperlight_common::flatbuffer_wrappers::util::{
25+
decode, encode, encode_extend, estimate_flatbuffer_capacity,
26+
};
2627
use hyperlight_host::GuestBinary;
2728
use hyperlight_host::mem::shared_mem::ExclusiveSharedMemory;
2829
use hyperlight_host::sandbox::{MultiUseSandbox, SandboxConfiguration, UninitializedSandbox};
@@ -437,18 +438,17 @@ fn function_call_serialization_benchmark(c: &mut Criterion) {
437438
function_call.function_name.as_str(),
438439
function_call.parameters.as_deref().unwrap_or(&[]),
439440
);
440-
let mut builder = FlatBufferBuilder::with_capacity(estimated_capacity);
441-
let serialized: &[u8] = function_call.encode(&mut builder);
441+
let serialized = Vec::with_capacity(estimated_capacity);
442+
let serialized = encode_extend(&function_call, serialized).unwrap();
442443
std::hint::black_box(serialized);
443444
});
444445
});
445446

446447
group.bench_function("deserialize_function_call", |b| {
447-
let mut builder = FlatBufferBuilder::new();
448-
let bytes = function_call.clone().encode(&mut builder);
448+
let bytes = encode(&function_call).unwrap();
449449

450450
b.iter(|| {
451-
let deserialized: FunctionCall = bytes.try_into().unwrap();
451+
let deserialized: FunctionCall = decode(&bytes).unwrap();
452452
std::hint::black_box(deserialized);
453453
});
454454
});

src/hyperlight_host/src/mem/mgr.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ limitations under the License.
1616
#[cfg(feature = "nanvix-unstable")]
1717
use std::mem::offset_of;
1818

19-
use flatbuffers::FlatBufferBuilder;
2019
use hyperlight_common::flatbuffer_wrappers::function_call::{
2120
FunctionCall, validate_guest_function_call_buffer,
2221
};
2322
use hyperlight_common::flatbuffer_wrappers::function_types::FunctionCallResult;
2423
use hyperlight_common::flatbuffer_wrappers::guest_log_data::GuestLogData;
24+
use hyperlight_common::flatbuffer_wrappers::util::encode;
2525
use hyperlight_common::vmem::{self, PAGE_TABLE_SIZE};
2626
#[cfg(all(feature = "crashdump", not(feature = "i686-guest")))]
2727
use hyperlight_common::vmem::{BasicMapping, MappingKind};
@@ -451,13 +451,16 @@ impl SandboxMemoryManager<HostSharedMemory> {
451451
&mut self,
452452
res: &FunctionCallResult,
453453
) -> Result<()> {
454-
let mut builder = FlatBufferBuilder::new();
455-
let data = res.encode(&mut builder);
454+
let data = encode(res).map_err(|_| {
455+
new_error!(
456+
"write_response_from_host_function_call: failed to convert FunctionCallResult to Vec<u8>"
457+
)
458+
})?;
456459

457460
self.scratch_mem.push_buffer(
458461
self.layout.get_input_data_buffer_scratch_host_offset(),
459462
self.layout.input_data_size,
460-
data,
463+
&data,
461464
)
462465
}
463466

src/hyperlight_host/src/mem/shared_mem.rs

Lines changed: 41 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use std::mem::{align_of, size_of};
2222
use std::ptr::null_mut;
2323
use std::sync::{Arc, RwLock};
2424

25+
use hyperlight_common::flatbuffer_wrappers::util::{Deserialize, decode};
2526
use hyperlight_common::mem::PAGE_SIZE_USIZE;
2627
use tracing::{Span, instrument};
2728
#[cfg(target_os = "windows")]
@@ -1130,17 +1131,11 @@ impl HostSharedMemory {
11301131
Ok(())
11311132
}
11321133

1133-
/// Pops the given given buffer into a `T` and returns it.
1134-
/// NOTE! the data must be a size-prefixed flatbuffer, and
1135-
/// buffer_start_offset must point to the beginning of the buffer
1136-
pub fn try_pop_buffer_into<T>(
1134+
fn try_pop_buffer_raw(
11371135
&mut self,
11381136
buffer_start_offset: usize,
11391137
buffer_size: usize,
1140-
) -> Result<T>
1141-
where
1142-
T: for<'b> TryFrom<&'b [u8]>,
1143-
{
1138+
) -> Result<Vec<u8>> {
11441139
// get the stackpointer
11451140
let stack_pointer_rel = self.read::<u64>(buffer_start_offset)? as usize;
11461141

@@ -1180,17 +1175,15 @@ impl HostSharedMemory {
11801175

11811176
// Get the size of the flatbuffer buffer from memory
11821177
let fb_buffer_size = {
1183-
let raw_prefix = self.read::<u32>(last_element_offset_abs)?;
1184-
// flatbuffer byte arrays are prefixed by 4 bytes indicating
1185-
// the remaining size; add 4 for the prefix itself.
1186-
let total = raw_prefix.checked_add(4).ok_or_else(|| {
1187-
new_error!(
1188-
"Corrupt buffer size prefix: value {} overflows when adding 4-byte header.",
1189-
raw_prefix
1190-
)
1191-
})?;
1192-
usize::try_from(total)
1193-
}?;
1178+
stack_pointer_rel - last_element_offset_rel - 8
1179+
/*
1180+
let size_i32 = self.read::<u32>(last_element_offset_abs)? + 4;
1181+
// ^^^ flatbuffer byte arrays are prefixed by 4 bytes
1182+
// indicating its size, so, to get the actual size, we need
1183+
// to add 4.
1184+
usize::try_from(size_i32)
1185+
*/
1186+
};
11941187

11951188
if fb_buffer_size > max_element_size {
11961189
return Err(new_error!(
@@ -1203,12 +1196,6 @@ impl HostSharedMemory {
12031196
let mut result_buffer = vec![0; fb_buffer_size];
12041197

12051198
self.copy_to_slice(&mut result_buffer, last_element_offset_abs)?;
1206-
let to_return = T::try_from(result_buffer.as_slice()).map_err(|_e| {
1207-
new_error!(
1208-
"pop_buffer_into: failed to convert buffer to {}",
1209-
type_name::<T>()
1210-
)
1211-
})?;
12121199

12131200
// update the stack pointer to point to the element we just popped off since that is now free
12141201
self.write::<u64>(buffer_start_offset, last_element_offset_rel as u64)?;
@@ -1217,6 +1204,27 @@ impl HostSharedMemory {
12171204
let num_bytes_to_zero = stack_pointer_rel - last_element_offset_rel;
12181205
self.fill(0, last_element_offset_abs, num_bytes_to_zero)?;
12191206

1207+
Ok(result_buffer)
1208+
}
1209+
1210+
/// Pops the given given buffer into a `T` and returns it.
1211+
/// NOTE! the data must be a size-prefixed flatbuffer, and
1212+
/// buffer_start_offset must point to the beginning of the buffer
1213+
pub fn try_pop_buffer_into<T>(
1214+
&mut self,
1215+
buffer_start_offset: usize,
1216+
buffer_size: usize,
1217+
) -> Result<T>
1218+
where
1219+
T: for<'b> Deserialize<'b>,
1220+
{
1221+
let result_buffer = self.try_pop_buffer_raw(buffer_start_offset, buffer_size)?;
1222+
let to_return: T = decode(result_buffer.as_slice()).map_err(|_e| {
1223+
new_error!(
1224+
"pop_buffer_into: failed to convert buffer to {}",
1225+
type_name::<T>()
1226+
)
1227+
})?;
12201228
Ok(to_return)
12211229
}
12221230
}
@@ -1730,16 +1738,6 @@ mod tests {
17301738
mod try_pop_buffer_bounds {
17311739
use super::*;
17321740

1733-
#[derive(Debug, PartialEq)]
1734-
struct RawBytes(Vec<u8>);
1735-
1736-
impl TryFrom<&[u8]> for RawBytes {
1737-
type Error = String;
1738-
fn try_from(value: &[u8]) -> std::result::Result<Self, Self::Error> {
1739-
Ok(RawBytes(value.to_vec()))
1740-
}
1741-
}
1742-
17431741
/// Create a buffer with stack pointer initialized to 8 (empty).
17441742
fn make_buffer(mem_size: usize) -> super::super::HostSharedMemory {
17451743
let eshm = ExclusiveSharedMemory::new(mem_size).unwrap();
@@ -1760,8 +1758,8 @@ mod tests {
17601758
data.extend_from_slice(payload);
17611759

17621760
hshm.push_buffer(0, mem_size, &data).unwrap();
1763-
let result: RawBytes = hshm.try_pop_buffer_into(0, mem_size).unwrap();
1764-
assert_eq!(result.0, data);
1761+
let result = hshm.try_pop_buffer_raw(0, mem_size).unwrap();
1762+
assert_eq!(result, data);
17651763
}
17661764

17671765
#[test]
@@ -1778,7 +1776,7 @@ mod tests {
17781776
// Corrupt size prefix at element start (offset 8) to near u32::MAX.
17791777
hshm.write::<u32>(8, 0xFFFF_FFFBu32).unwrap(); // +4 = 0xFFFF_FFFF
17801778

1781-
let result: Result<RawBytes> = hshm.try_pop_buffer_into(0, mem_size);
1779+
let result = hshm.try_pop_buffer_raw(0, mem_size);
17821780
let err_msg = format!("{}", result.unwrap_err());
17831781
assert!(
17841782
err_msg.contains("Corrupt buffer size prefix: flatbuffer claims 4294967295 bytes but the element slot is only 9 bytes"),
@@ -1801,7 +1799,7 @@ mod tests {
18011799
// Corrupt back-pointer (offset 16) to 0 (before valid range).
18021800
hshm.write::<u64>(16, 0u64).unwrap();
18031801

1804-
let result: Result<RawBytes> = hshm.try_pop_buffer_into(0, mem_size);
1802+
let result = hshm.try_pop_buffer_raw(0, mem_size);
18051803
let err_msg = format!("{}", result.unwrap_err());
18061804
assert!(
18071805
err_msg.contains(
@@ -1826,7 +1824,7 @@ mod tests {
18261824
// Corrupt back-pointer (offset 16) to 9999 (past stack pointer 24).
18271825
hshm.write::<u64>(16, 9999u64).unwrap();
18281826

1829-
let result: Result<RawBytes> = hshm.try_pop_buffer_into(0, mem_size);
1827+
let result = hshm.try_pop_buffer_raw(0, mem_size);
18301828
let err_msg = format!("{}", result.unwrap_err());
18311829
assert!(
18321830
err_msg.contains(
@@ -1851,7 +1849,7 @@ mod tests {
18511849
// Corrupt size prefix: claim 5 bytes (total 9), exceeding the 8-byte slot.
18521850
hshm.write::<u32>(8, 5u32).unwrap(); // fb_buffer_size = 5 + 4 = 9
18531851

1854-
let result: Result<RawBytes> = hshm.try_pop_buffer_into(0, mem_size);
1852+
let result = hshm.try_pop_buffer_raw(0, mem_size);
18551853
let err_msg = format!("{}", result.unwrap_err());
18561854
assert!(
18571855
err_msg.contains("Corrupt buffer size prefix: flatbuffer claims 9 bytes but the element slot is only 8 bytes"),
@@ -1876,7 +1874,7 @@ mod tests {
18761874
// stack_pointer_rel = 24. Set back-pointer to 23 (> 24 - 16 = 8, so rejected).
18771875
hshm.write::<u64>(16, 23u64).unwrap();
18781876

1879-
let result: Result<RawBytes> = hshm.try_pop_buffer_into(0, mem_size);
1877+
let result = hshm.try_pop_buffer_raw(0, mem_size);
18801878
let err_msg = format!("{}", result.unwrap_err());
18811879
assert!(
18821880
err_msg.contains(
@@ -1902,7 +1900,7 @@ mod tests {
19021900
// Write 0xFFFF_FFFD as size prefix: checked_add(4) returns None.
19031901
hshm.write::<u32>(8, 0xFFFF_FFFDu32).unwrap();
19041902

1905-
let result: Result<RawBytes> = hshm.try_pop_buffer_into(0, mem_size);
1903+
let result = hshm.try_pop_buffer_raw(0, mem_size);
19061904
let err_msg = format!("{}", result.unwrap_err());
19071905
assert!(
19081906
err_msg.contains("Corrupt buffer size prefix: value 4294967293 overflows when adding 4-byte header"),

0 commit comments

Comments
 (0)