Skip to content

Commit

Permalink
Merge pull request #102 from rcore-os/indirect
Browse files Browse the repository at this point in the history
Add support for indirect descriptors in VirtQueue with alloc feature
  • Loading branch information
qwandor authored Jul 24, 2023
2 parents 9653e4c + 2d3a6cc commit 7cbbef1
Show file tree
Hide file tree
Showing 8 changed files with 340 additions and 90 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ VirtIO guest drivers in Rust. For **no_std** environment.

| Feature flag | Supported | |
| ---------------------------- | --------- | --------------------------------------- |
| `VIRTIO_F_INDIRECT_DESC` | | Indirect descriptors |
| `VIRTIO_F_INDIRECT_DESC` | | Indirect descriptors |
| `VIRTIO_F_EVENT_IDX` || `avail_event` and `used_event` fields |
| `VIRTIO_F_VERSION_1` | TODO | VirtIO version 1 compliance |
| `VIRTIO_F_ACCESS_PLATFORM` || Limited device access to memory |
Expand Down
18 changes: 12 additions & 6 deletions src/device/blk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use zerocopy::{AsBytes, FromBytes};

const QUEUE: u16 = 0;
const QUEUE_SIZE: u16 = 16;
const SUPPORTED_FEATURES: BlkFeature = BlkFeature::RO.union(BlkFeature::FLUSH);
const SUPPORTED_FEATURES: BlkFeature = BlkFeature::RO
.union(BlkFeature::FLUSH)
.union(BlkFeature::RING_INDIRECT_DESC);

/// Driver for a VirtIO block device.
///
Expand Down Expand Up @@ -68,7 +70,11 @@ impl<H: Hal, T: Transport> VirtIOBlk<H, T> {
};
info!("found a block device of size {}KB", capacity / 2);

let queue = VirtQueue::new(&mut transport, QUEUE)?;
let queue = VirtQueue::new(
&mut transport,
QUEUE,
negotiated_features.contains(BlkFeature::RING_INDIRECT_DESC),
)?;
transport.finish_init();

Ok(VirtIOBlk {
Expand Down Expand Up @@ -601,7 +607,7 @@ mod tests {
let transport = FakeTransport {
device_type: DeviceType::Block,
max_queue_size: QUEUE_SIZE.into(),
device_features: 0,
device_features: BlkFeature::RING_INDIRECT_DESC.bits(),
config_space: NonNull::from(&mut config_space),
state: state.clone(),
};
Expand Down Expand Up @@ -671,7 +677,7 @@ mod tests {
let transport = FakeTransport {
device_type: DeviceType::Block,
max_queue_size: QUEUE_SIZE.into(),
device_features: 0,
device_features: BlkFeature::RING_INDIRECT_DESC.bits(),
config_space: NonNull::from(&mut config_space),
state: state.clone(),
};
Expand Down Expand Up @@ -746,7 +752,7 @@ mod tests {
let transport = FakeTransport {
device_type: DeviceType::Block,
max_queue_size: QUEUE_SIZE.into(),
device_features: BlkFeature::FLUSH.bits(),
device_features: (BlkFeature::RING_INDIRECT_DESC | BlkFeature::FLUSH).bits(),
config_space: NonNull::from(&mut config_space),
state: state.clone(),
};
Expand Down Expand Up @@ -813,7 +819,7 @@ mod tests {
let transport = FakeTransport {
device_type: DeviceType::Block,
max_queue_size: QUEUE_SIZE.into(),
device_features: 0,
device_features: BlkFeature::RING_INDIRECT_DESC.bits(),
config_space: NonNull::from(&mut config_space),
state: state.clone(),
};
Expand Down
4 changes: 2 additions & 2 deletions src/device/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ impl<H: Hal, T: Transport> VirtIOConsole<H, T> {
(features & supported_features).bits()
});
let config_space = transport.config_space::<Config>()?;
let receiveq = VirtQueue::new(&mut transport, QUEUE_RECEIVEQ_PORT_0)?;
let transmitq = VirtQueue::new(&mut transport, QUEUE_TRANSMITQ_PORT_0)?;
let receiveq = VirtQueue::new(&mut transport, QUEUE_RECEIVEQ_PORT_0, false)?;
let transmitq = VirtQueue::new(&mut transport, QUEUE_TRANSMITQ_PORT_0, false)?;

// Safe because no alignment or initialisation is required for [u8], the DMA buffer is
// dereferenceable, and the lifetime of the reference matches the lifetime of the DMA buffer
Expand Down
4 changes: 2 additions & 2 deletions src/device/gpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ impl<H: Hal, T: Transport> VirtIOGpu<H, T> {
);
}

let control_queue = VirtQueue::new(&mut transport, QUEUE_TRANSMIT)?;
let cursor_queue = VirtQueue::new(&mut transport, QUEUE_CURSOR)?;
let control_queue = VirtQueue::new(&mut transport, QUEUE_TRANSMIT, false)?;
let cursor_queue = VirtQueue::new(&mut transport, QUEUE_CURSOR, false)?;

let queue_buf_send = FromBytes::new_box_slice_zeroed(PAGE_SIZE);
let queue_buf_recv = FromBytes::new_box_slice_zeroed(PAGE_SIZE);
Expand Down
4 changes: 2 additions & 2 deletions src/device/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ impl<H: Hal, T: Transport> VirtIOInput<H, T> {

let config = transport.config_space::<Config>()?;

let mut event_queue = VirtQueue::new(&mut transport, QUEUE_EVENT)?;
let status_queue = VirtQueue::new(&mut transport, QUEUE_STATUS)?;
let mut event_queue = VirtQueue::new(&mut transport, QUEUE_EVENT, false)?;
let status_queue = VirtQueue::new(&mut transport, QUEUE_STATUS, false)?;
for (i, event) in event_buf.as_mut().iter_mut().enumerate() {
// Safe because the buffer lasts as long as the queue.
let token = unsafe { event_queue.add(&[], &mut [event.as_bytes_mut()])? };
Expand Down
4 changes: 2 additions & 2 deletions src/device/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ impl<H: Hal, T: Transport, const QUEUE_SIZE: usize> VirtIONet<H, T, QUEUE_SIZE>
return Err(Error::InvalidParam);
}

let send_queue = VirtQueue::new(&mut transport, QUEUE_TRANSMIT)?;
let mut recv_queue = VirtQueue::new(&mut transport, QUEUE_RECEIVE)?;
let send_queue = VirtQueue::new(&mut transport, QUEUE_TRANSMIT, false)?;
let mut recv_queue = VirtQueue::new(&mut transport, QUEUE_RECEIVE, false)?;

const NONE_BUF: Option<RxBuffer> = None;
let mut rx_buffers = [NONE_BUF; QUEUE_SIZE];
Expand Down
6 changes: 3 additions & 3 deletions src/device/socket/vsock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,9 +257,9 @@ impl<H: Hal, T: Transport> VirtIOSocket<H, T> {
};
debug!("guest cid: {guest_cid:?}");

let mut rx = VirtQueue::new(&mut transport, RX_QUEUE_IDX)?;
let tx = VirtQueue::new(&mut transport, TX_QUEUE_IDX)?;
let event = VirtQueue::new(&mut transport, EVENT_QUEUE_IDX)?;
let mut rx = VirtQueue::new(&mut transport, RX_QUEUE_IDX, false)?;
let tx = VirtQueue::new(&mut transport, TX_QUEUE_IDX, false)?;
let event = VirtQueue::new(&mut transport, EVENT_QUEUE_IDX, false)?;

// Allocate and add buffers for the RX queue.
let mut rx_queue_buffers = [null_mut(); QUEUE_SIZE];
Expand Down
Loading

0 comments on commit 7cbbef1

Please sign in to comment.