Skip to content
Merged
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
39 changes: 39 additions & 0 deletions vm/devices/net/net_mana/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1492,6 +1492,15 @@ struct OutOfMemory;

impl ContiguousBufferManager {
pub fn new(dma_client: Arc<dyn DmaClient>, page_limit: u32) -> anyhow::Result<Self> {
anyhow::ensure!(
page_limit.is_power_of_two(),
anyhow::anyhow!("page_limit must be a power of two, {page_limit} is not.")
);
Comment thread
ben-zen marked this conversation as resolved.
anyhow::ensure!(
PAGE_SIZE64 * Into::<u64>::into(page_limit) <= Into::<u64>::into(u32::MAX),
anyhow::anyhow!("{page_limit} will overflow the len field")
);

let len = PAGE_SIZE32 * page_limit;
Comment thread
ben-zen marked this conversation as resolved.
let mem = dma_client.allocate_dma_buffer(len as usize)?;
Ok(Self {
Expand Down Expand Up @@ -1526,3 +1535,33 @@ impl Inspect for ContiguousBufferManager {
.counter("failed_allocations", self.failed_allocations);
}
}

#[cfg(test)]
mod tests {
use super::*;
use anyhow::{Result, anyhow, ensure};
use user_driver_emulated_mock::DeviceTestMemory;

Comment thread
ben-zen marked this conversation as resolved.
#[test]
fn page_counts_powers_of_two_only() -> Result<()> {
for i in 1..35 {
let dtm = DeviceTestMemory::new(Into::<u64>::into(i) * 2, false, "test");
match ContiguousBufferManager::new(dtm.dma_client(), i) {
Ok(_) => {
ensure!(
i.is_power_of_two(),
anyhow!("The CBM should only work for powers of 2")
);
}
Err(_) => {
ensure!(
!i.is_power_of_two(),
anyhow!("Powers of 2 should get CBMs, failed for {i} pages.")
Comment thread
ben-zen marked this conversation as resolved.
);
}
}
}

Ok(())
}
}
Loading