Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Send and Sync for various types. #132

Merged
merged 1 commit into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/device/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ pub struct VirtIOConsole<H: Hal, T: Transport> {
receive_token: Option<u16>,
}

// SAFETY: The config space can be accessed from any thread.
unsafe impl<H: Hal, T: Transport + Send> Send for VirtIOConsole<H, T> where
VirtQueue<H, QUEUE_SIZE>: Send
{
}

// SAFETY: A `&VirtIOConsole` only allows reading the config space.
unsafe impl<H: Hal, T: Transport + Sync> Sync for VirtIOConsole<H, T> where
VirtQueue<H, QUEUE_SIZE>: Sync
{
}

/// Information about a console device, read from its configuration space.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ConsoleInfo {
Expand Down
12 changes: 12 additions & 0 deletions src/device/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,18 @@ impl<H: Hal, T: Transport> VirtIOInput<H, T> {
}
}

// SAFETY: The config space can be accessed from any thread.
unsafe impl<H: Hal, T: Transport + Send> Send for VirtIOInput<H, T> where
VirtQueue<H, QUEUE_SIZE>: Send
{
}

// SAFETY: An '&VirtIOInput` can't do anything, all methods take `&mut self`.
unsafe impl<H: Hal, T: Transport + Sync> Sync for VirtIOInput<H, T> where
VirtQueue<H, QUEUE_SIZE>: Sync
{
}

impl<H: Hal, T: Transport> Drop for VirtIOInput<H, T> {
fn drop(&mut self) {
// Clear any pointers pointing to DMA regions, so the device doesn't try to access them
Expand Down
12 changes: 12 additions & 0 deletions src/device/socket/vsock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,18 @@ pub struct VirtIOSocket<H: Hal, T: Transport> {
rx_queue_buffers: [NonNull<[u8; RX_BUFFER_SIZE]>; QUEUE_SIZE],
}

// SAFETY: The `rx_queue_buffers` can be accessed from any thread.
unsafe impl<H: Hal, T: Transport + Send> Send for VirtIOSocket<H, T> where
VirtQueue<H, QUEUE_SIZE>: Send
{
}

// SAFETY: A `&VirtIOSocket` only allows reading the guest CID from a field.
unsafe impl<H: Hal, T: Transport + Sync> Sync for VirtIOSocket<H, T> where
VirtQueue<H, QUEUE_SIZE>: Sync
{
}

impl<H: Hal, T: Transport> Drop for VirtIOSocket<H, T> {
fn drop(&mut self) {
// Clear any pointers pointing to DMA regions, so the device doesn't try to access them
Expand Down
7 changes: 7 additions & 0 deletions src/hal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ pub struct Dma<H: Hal> {
_hal: PhantomData<H>,
}

// SAFETY: DMA memory can be accessed from any thread.
unsafe impl<H: Hal> Send for Dma<H> {}

// SAFETY: `&Dma` only allows pointers and physical addresses to be returned. Any actual access to
// the memory requires unsafe code, which is responsible for avoiding data races.
unsafe impl<H: Hal> Sync for Dma<H> {}

impl<H: Hal> Dma<H> {
/// Allocates the given number of pages of physically contiguous memory to be used for DMA in
/// the given direction.
Expand Down
7 changes: 7 additions & 0 deletions src/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
pub fn new<T: Transport>(
transport: &mut T,
idx: u16,
indirect: bool,

Check warning on line 74 in src/queue.rs

View workflow job for this annotation

GitHub Actions / build

unused variable: `indirect`

Check warning on line 74 in src/queue.rs

View workflow job for this annotation

GitHub Actions / build

unused variable: `indirect`
event_idx: bool,
) -> Result<Self> {
if transport.queue_used(idx) {
Expand Down Expand Up @@ -536,6 +536,13 @@
}
}

// SAFETY: None of the virt queue resources are tied to a particular thread.
unsafe impl<H: Hal, const SIZE: usize> Send for VirtQueue<H, SIZE> {}

// SAFETY: A `&VirtQueue` only allows reading from the various pointers it contains, so there is no
// data race.
unsafe impl<H: Hal, const SIZE: usize> Sync for VirtQueue<H, SIZE> {}

/// The inner layout of a VirtQueue.
///
/// Ref: 2.6 Split Virtqueues
Expand Down
7 changes: 7 additions & 0 deletions src/transport/mmio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,13 @@ impl MmioTransport {
}
}

// SAFETY: `header` is only used for MMIO, which can happen from any thread or CPU core.
unsafe impl Send for MmioTransport {}

// SAFETY: `&MmioTransport` only allows MMIO reads or getting the config space, both of which are
// fine to happen concurrently on different CPU cores.
unsafe impl Sync for MmioTransport {}

impl Transport for MmioTransport {
fn device_type(&self) -> DeviceType {
// Safe because self.header points to a valid VirtIO MMIO region.
Expand Down
13 changes: 13 additions & 0 deletions src/transport/pci.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,13 @@ impl Transport for PciTransport {
}
}

// SAFETY: MMIO can be done from any thread or CPU core.
unsafe impl Send for PciTransport {}

// SAFETY: `&PciTransport` only allows MMIO reads or getting the config space, both of which are
// fine to happen concurrently on different CPU cores.
unsafe impl Sync for PciTransport {}

impl Drop for PciTransport {
fn drop(&mut self) {
// Reset the device when the transport is dropped.
Expand Down Expand Up @@ -499,6 +506,12 @@ impl From<PciError> for VirtioPciError {
}
}

// SAFETY: The `vaddr` field of `VirtioPciError::Misaligned` is only used for debug output.
unsafe impl Send for VirtioPciError {}

// SAFETY: The `vaddr` field of `VirtioPciError::Misaligned` is only used for debug output.
unsafe impl Sync for VirtioPciError {}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
7 changes: 7 additions & 0 deletions src/transport/pci/bus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,13 @@ impl PciRoot {
}
}

// SAFETY: `mmio_base` is only used for MMIO, which can happen from any thread or CPU core.
unsafe impl Send for PciRoot {}

// SAFETY: `&PciRoot` only allows MMIO reads, which are fine to happen concurrently on different CPU
// cores.
unsafe impl Sync for PciRoot {}

/// Information about a PCI Base Address Register.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum BarInfo {
Expand Down
Loading