Skip to content

Commit

Permalink
Change IoVecBuffer[Mut] len to u32
Browse files Browse the repository at this point in the history
Signed-off-by: Brandon Pike <[email protected]>
  • Loading branch information
brandonpike committed Apr 12, 2024
1 parent c9112a6 commit d829d68
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 27 deletions.
26 changes: 16 additions & 10 deletions src/vmm/src/devices/virtio/iovec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pub enum IoVecError {
WriteOnlyDescriptor,
/// Tried to create an 'IoVecMut` from a read-only descriptor chain
ReadOnlyDescriptor,
/// Tried to create an `IoVec` or `IoVecMut` from a descriptor chain that was too large
OverflowedDescriptor,
/// Guest memory error: {0}
GuestMemory(#[from] GuestMemoryError),
}
Expand All @@ -40,14 +42,14 @@ pub struct IoVecBuffer {
// container of the memory regions included in this IO vector
vecs: IoVecVec,
// Total length of the IoVecBuffer
len: usize,
len: u32,
}

impl IoVecBuffer {
/// Create an `IoVecBuffer` from a `DescriptorChain`
pub fn from_descriptor_chain(head: DescriptorChain) -> Result<Self, IoVecError> {
let mut vecs = IoVecVec::new();
let mut len = 0usize;
let mut len = 0u32;

let mut next_descriptor = Some(head);
while let Some(desc) = next_descriptor {
Expand All @@ -68,7 +70,9 @@ impl IoVecBuffer {
iov_base,
iov_len: desc.len as size_t,
});
len += desc.len as usize;
len = len
.checked_add(desc.len)
.ok_or(IoVecError::OverflowedDescriptor)?;

next_descriptor = desc.next_descriptor();
}
Expand All @@ -77,7 +81,7 @@ impl IoVecBuffer {
}

/// Get the total length of the memory regions covered by this `IoVecBuffer`
pub(crate) fn len(&self) -> usize {
pub(crate) fn len(&self) -> u32 {
self.len
}

Expand Down Expand Up @@ -106,7 +110,7 @@ impl IoVecBuffer {
mut buf: &mut [u8],
offset: usize,
) -> Result<(), VolatileMemoryError> {
if offset < self.len() {
if offset < self.len() as usize {
let expected = buf.len();
let bytes_read = self.read_volatile_at(&mut buf, offset, expected)?;

Expand Down Expand Up @@ -188,14 +192,14 @@ pub struct IoVecBufferMut {
// container of the memory regions included in this IO vector
vecs: IoVecVec,
// Total length of the IoVecBufferMut
len: usize,
len: u32,
}

impl IoVecBufferMut {
/// Create an `IoVecBufferMut` from a `DescriptorChain`
pub fn from_descriptor_chain(head: DescriptorChain) -> Result<Self, IoVecError> {
let mut vecs = IoVecVec::new();
let mut len = 0usize;
let mut len = 0u32;

for desc in head {
if !desc.is_write_only() {
Expand All @@ -217,14 +221,16 @@ impl IoVecBufferMut {
iov_base,
iov_len: desc.len as size_t,
});
len += desc.len as usize;
len = len
.checked_add(desc.len)
.ok_or(IoVecError::OverflowedDescriptor)?;
}

Ok(Self { vecs, len })
}

/// Get the total length of the memory regions covered by this `IoVecBuffer`
pub(crate) fn len(&self) -> usize {
pub(crate) fn len(&self) -> u32 {
self.len
}

Expand All @@ -244,7 +250,7 @@ impl IoVecBufferMut {
mut buf: &[u8],
offset: usize,
) -> Result<(), VolatileMemoryError> {
if offset < self.len() {
if offset < self.len() as usize {
let expected = buf.len();
let bytes_written = self.write_volatile_at(&mut buf, offset, expected)?;

Expand Down
4 changes: 2 additions & 2 deletions src/vmm/src/devices/virtio/net/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ impl Net {

if let Some(ns) = mmds_ns {
if ns.is_mmds_frame(headers) {
let mut frame = vec![0u8; frame_iovec.len() - vnet_hdr_len()];
let mut frame = vec![0u8; frame_iovec.len() as usize - vnet_hdr_len()];
// Ok to unwrap here, because we are passing a buffer that has the exact size
// of the `IoVecBuffer` minus the VNET headers.
frame_iovec
Expand Down Expand Up @@ -609,7 +609,7 @@ impl Net {
};

// We only handle frames that are up to MAX_BUFFER_SIZE
if buffer.len() > MAX_BUFFER_SIZE {
if buffer.len() as usize > MAX_BUFFER_SIZE {
error!("net: received too big frame from driver");
self.metrics.tx_malformed_frames.inc();
tx_queue
Expand Down
2 changes: 1 addition & 1 deletion src/vmm/src/devices/virtio/rng/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ impl Entropy {
return Ok(0);
}

let mut rand_bytes = vec![0; iovec.len()];
let mut rand_bytes = vec![0; iovec.len() as usize];
rand::fill(&mut rand_bytes).map_err(|err| {
METRICS.host_rng_fails.inc();
err
Expand Down
2 changes: 1 addition & 1 deletion src/vmm/src/devices/virtio/vsock/csm/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ where

// The maximum amount of data we can read in is limited by both the RX buffer size and
// the peer available buffer space.
let max_len = std::cmp::min(pkt.buf_size(), self.peer_avail_credit());
let max_len = std::cmp::min(pkt.buf_size() as usize, self.peer_avail_credit());

// Read data from the stream straight to the RX buffer, for maximum throughput.
match pkt.read_at_offset_from(&mut self.stream, 0, max_len) {
Expand Down
5 changes: 4 additions & 1 deletion src/vmm/src/devices/virtio/vsock/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ mod defs {
#[rustfmt::skip]
pub enum VsockError {
/** The total length of the descriptor chain ({0}) is too short to hold a packet of length {1} + header */
DescChainTooShortForPacket(usize, u32),
DescChainTooShortForPacket(u32, u32),
/// Empty queue
EmptyQueue,
/// EventFd error: {0}
Expand All @@ -122,6 +122,8 @@ pub enum VsockError {
/** The total length of the descriptor chain ({0}) is less than the number of bytes required\
to hold a vsock packet header.*/
DescChainTooShortForHeader(usize),
/// The descriptor chain length was greater than the max ([u32::MAX])
DescChainOverflow,
/// The vsock header `len` field holds an invalid value: {0}
InvalidPktLen(u32),
/// A data fetch was attempted when no data was available.
Expand All @@ -144,6 +146,7 @@ impl From<IoVecError> for VsockError {
IoVecError::WriteOnlyDescriptor => VsockError::UnreadableDescriptor,
IoVecError::ReadOnlyDescriptor => VsockError::UnwritableDescriptor,
IoVecError::GuestMemory(err) => VsockError::GuestMemoryMmap(err),
IoVecError::OverflowedDescriptor => VsockError::DescChainOverflow,
}
}
}
Expand Down
19 changes: 7 additions & 12 deletions src/vmm/src/devices/virtio/vsock/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ impl VsockPacket {
return Err(VsockError::InvalidPktLen(hdr.len));
}

if (hdr.len as usize) > buffer.len() - VSOCK_PKT_HDR_SIZE as usize {
if (hdr.len) > buffer.len() - VSOCK_PKT_HDR_SIZE {
return Err(VsockError::DescChainTooShortForPacket(
buffer.len(),
hdr.len,
Expand All @@ -160,8 +160,8 @@ impl VsockPacket {
pub fn from_rx_virtq_head(chain: DescriptorChain) -> Result<Self, VsockError> {
let buffer = IoVecBufferMut::from_descriptor_chain(chain)?;

if buffer.len() < VSOCK_PKT_HDR_SIZE as usize {
return Err(VsockError::DescChainTooShortForHeader(buffer.len()));
if buffer.len() < VSOCK_PKT_HDR_SIZE {
return Err(VsockError::DescChainTooShortForHeader(buffer.len() as usize));
}

Ok(Self {
Expand Down Expand Up @@ -212,7 +212,7 @@ impl VsockPacket {
VsockPacketBuffer::Tx(ref iovec_buf) => iovec_buf.len(),
VsockPacketBuffer::Rx(ref iovec_buf) => iovec_buf.len(),
};
chain_length - VSOCK_PKT_HDR_SIZE as usize
(chain_length - VSOCK_PKT_HDR_SIZE) as usize
}

pub fn read_at_offset_from<T: ReadVolatile + Debug>(
Expand All @@ -225,8 +225,7 @@ impl VsockPacket {
VsockPacketBuffer::Tx(_) => Err(VsockError::UnwritableDescriptor),
VsockPacketBuffer::Rx(ref mut buffer) => {
if count
> buffer
.len()
> (buffer.len() as usize)
.saturating_sub(VSOCK_PKT_HDR_SIZE as usize)
.saturating_sub(offset)
{
Expand All @@ -249,8 +248,7 @@ impl VsockPacket {
match self.buffer {
VsockPacketBuffer::Tx(ref buffer) => {
if count
> buffer
.len()
> (buffer.len() as usize)
.saturating_sub(VSOCK_PKT_HDR_SIZE as usize)
.saturating_sub(offset)
{
Expand Down Expand Up @@ -427,10 +425,7 @@ mod tests {
.unwrap(),
)
.unwrap();
assert_eq!(
pkt.buf_size(),
handler_ctx.guest_txvq.dtable[1].len.get() as usize
);
assert_eq!(pkt.buf_size(), handler_ctx.guest_txvq.dtable[1].len.get());
}

// Test case: error on write-only hdr descriptor.
Expand Down

0 comments on commit d829d68

Please sign in to comment.