diff --git a/litebox/src/net/phy.rs b/litebox/src/net/phy.rs index ff4d85c6e..e8ebc4beb 100644 --- a/litebox/src/net/phy.rs +++ b/litebox/src/net/phy.rs @@ -51,7 +51,11 @@ impl smoltcp::phy::Device for Device None, + Err( + platform::ReceiveError::WouldBlock + | platform::ReceiveError::ProtocolError + | platform::ReceiveError::Eof, + ) => None, } } diff --git a/litebox/src/platform/mock.rs b/litebox/src/platform/mock.rs index 3a3297aa6..ae3d5b217 100644 --- a/litebox/src/platform/mock.rs +++ b/litebox/src/platform/mock.rs @@ -59,6 +59,8 @@ impl MockPlatform { impl Provider for MockPlatform {} +impl RawMessageProvider for MockPlatform {} + pub(crate) struct MockRawMutex { inner: AtomicU32, internal_state: std::sync::RwLock, diff --git a/litebox/src/platform/mod.rs b/litebox/src/platform/mod.rs index 983f20c84..5087270e2 100644 --- a/litebox/src/platform/mod.rs +++ b/litebox/src/platform/mod.rs @@ -43,6 +43,7 @@ macro_rules! log_println { pub trait Provider: RawMutexProvider + IPInterfaceProvider + + RawMessageProvider + TimeProvider + PunchthroughProvider + DebugLogProvider @@ -382,17 +383,54 @@ pub trait IPInterfaceProvider { fn receive_ip_packet(&self, packet: &mut [u8]) -> Result; } -/// A non-exhaustive list of errors that can be thrown by [`IPInterfaceProvider::send_ip_packet`]. +/// Errors from send operations on [`IPInterfaceProvider`] and [`RawMessageProvider`]. #[derive(Error, Debug)] #[non_exhaustive] -pub enum SendError {} +pub enum SendError { + /// The underlying device returned an I/O error. The packet was not sent. + #[error("I/O error on send: errno {0}")] + Io(i32), + /// The channel is not available on this platform. + #[error("send channel unavailable")] + Unavailable, +} -/// A non-exhaustive list of errors that can be thrown by [`IPInterfaceProvider::receive_ip_packet`]. +/// Errors from receive operations on [`IPInterfaceProvider`] and [`RawMessageProvider`]. #[derive(Error, Debug)] #[non_exhaustive] pub enum ReceiveError { #[error("Receive operation would block")] WouldBlock, + #[error("IPC protocol error: oversized frame")] + ProtocolError, + #[error("Channel closed (EOF)")] + Eof, +} + +/// A raw byte-stream channel for direct message passing between the guest and +/// the host (bypassing the IP network stack). +/// +/// When available, this provides a fast path for protocols like 9P that would +/// otherwise pay the overhead of traversing two smoltcp stacks. +/// +/// The default implementation returns [`ReceiveError::WouldBlock`] / +/// [`SendError::Unavailable`], indicating the channel is not available. +/// Platforms that support direct messaging override these methods. +pub trait RawMessageProvider { + /// Send bytes to the host over the raw channel. + /// + /// Returns `Ok(n)` with the number of bytes sent, or an error. + fn send_raw_message(&self, _data: &[u8]) -> Result { + Err(SendError::Unavailable) + } + + /// Receive bytes from the host over the raw channel. + /// + /// Returns `Ok(n)` with the number of bytes read into `buf`, or + /// [`ReceiveError::WouldBlock`] if no data is available yet. + fn recv_raw_message(&self, _buf: &mut [u8]) -> Result { + Err(ReceiveError::WouldBlock) + } } /// An interface to understanding time. diff --git a/litebox_platform_linux_kernel/src/lib.rs b/litebox_platform_linux_kernel/src/lib.rs index 12f6bc2d1..cf4d05fb4 100644 --- a/litebox_platform_linux_kernel/src/lib.rs +++ b/litebox_platform_linux_kernel/src/lib.rs @@ -85,6 +85,8 @@ impl<'a, Host: HostInterface> PunchthroughToken for LinuxPunchthroughToken<'a, H impl Provider for LinuxKernel {} +impl litebox::platform::RawMessageProvider for LinuxKernel {} + // TODO: implement pointer validation to ensure the pointers are in user space. type UserConstPtr = litebox::platform::common_providers::userspace_pointers::UserConstPtr< litebox::platform::common_providers::userspace_pointers::NoValidation, diff --git a/litebox_platform_linux_userland/src/lib.rs b/litebox_platform_linux_userland/src/lib.rs index c3e60a83a..55cf15d60 100644 --- a/litebox_platform_linux_userland/src/lib.rs +++ b/litebox_platform_linux_userland/src/lib.rs @@ -445,6 +445,8 @@ impl LinuxUserland { impl litebox::platform::Provider for LinuxUserland {} +impl litebox::platform::RawMessageProvider for LinuxUserland {} + impl litebox::platform::SignalProvider for LinuxUserland { type Signal = litebox_common_linux::signal::Signal; diff --git a/litebox_platform_lvbs/src/lib.rs b/litebox_platform_lvbs/src/lib.rs index 2487086d7..34979db09 100644 --- a/litebox_platform_lvbs/src/lib.rs +++ b/litebox_platform_lvbs/src/lib.rs @@ -1351,6 +1351,8 @@ impl litebox::platform::SystemInfoProvider for LinuxKernel< } } +impl litebox::platform::RawMessageProvider for LinuxKernel {} + #[cfg(feature = "optee_syscall")] /// Checks whether the given physical addresses are contiguous with respect to ALIGN. fn is_contiguous(addrs: &[PhysPageAddr]) -> bool { diff --git a/litebox_platform_windows_userland/src/lib.rs b/litebox_platform_windows_userland/src/lib.rs index 9d827e057..c8bc60c9c 100644 --- a/litebox_platform_windows_userland/src/lib.rs +++ b/litebox_platform_windows_userland/src/lib.rs @@ -331,6 +331,8 @@ impl WindowsUserland { } } +impl litebox::platform::RawMessageProvider for WindowsUserland {} + impl litebox::platform::Provider for WindowsUserland {} impl litebox::platform::SignalProvider for WindowsUserland {