diff --git a/vhost/src/vhost_user/backend_req_handler.rs b/vhost/src/vhost_user/backend_req_handler.rs index e857e60..7a59435 100644 --- a/vhost/src/vhost_user/backend_req_handler.rs +++ b/vhost/src/vhost_user/backend_req_handler.rs @@ -1079,10 +1079,10 @@ mod tests { #[test] fn test_get_shmem_config_multiple_regions() { - let memory_sizes = [ - 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000, - ]; - let config = VhostUserShMemConfig::new(8, &memory_sizes); + let config = VhostUserShMemConfig::new(&[ + (0, 0x1000), (1, 0x2000), (2, 0x3000), (3, 0x4000), + (4, 0x5000), (5, 0x6000), (6, 0x7000), (7, 0x8000), + ]); let (p1, p2) = UnixStream::pair().unwrap(); let mut dummy_backend = DummyBackendReqHandler::new(); @@ -1109,9 +1109,8 @@ mod tests { #[test] fn test_get_shmem_config_non_continuous_regions() { - // Create a configuration with non-continuous regions - let memory_sizes = [0x10000, 0, 0x20000, 0, 0, 0, 0, 0]; - let config = VhostUserShMemConfig::new(2, &memory_sizes); + // Create a configuration with non-contiguous region IDs (0 and 2, skipping 1) + let config = VhostUserShMemConfig::new(&[(0, 0x10000), (2, 0x20000)]); let (p1, p2) = UnixStream::pair().unwrap(); let mut dummy_backend = DummyBackendReqHandler::new(); diff --git a/vhost/src/vhost_user/frontend.rs b/vhost/src/vhost_user/frontend.rs index 13c4dd9..815928e 100644 --- a/vhost/src/vhost_user/frontend.rs +++ b/vhost/src/vhost_user/frontend.rs @@ -1220,7 +1220,7 @@ mod tests { fn test_frontend_get_shmem_config() { let (mut frontend, mut peer) = create_pair2(); - let expected_config = VhostUserShMemConfig::new(2, &[0x1000, 0x2000]); + let expected_config = VhostUserShMemConfig::new(&[(0, 0x1000), (1, 0x2000)]); let hdr = VhostUserMsgHeader::new( FrontendReq::GET_SHMEM_CONFIG, 0x4, diff --git a/vhost/src/vhost_user/message.rs b/vhost/src/vhost_user/message.rs index 88dbcaf..0d98409 100644 --- a/vhost/src/vhost_user/message.rs +++ b/vhost/src/vhost_user/message.rs @@ -700,7 +700,8 @@ pub struct VhostUserShMemConfig { pub nregions: u32, /// Padding for correct alignment padding: u32, - /// Size of each memory region + /// Size of each memory region, indexed by region ID. + /// A zero entry means the region with that ID is absent. pub memory_sizes: [u64; 256], } @@ -715,11 +716,17 @@ impl Default for VhostUserShMemConfig { } impl VhostUserShMemConfig { - /// Create a new instance - pub fn new(nregions: u32, memory: &[u64]) -> Self { - let memory_sizes: [u64; 256] = std::array::from_fn(|i| *memory.get(i).unwrap_or(&0)); + /// Create a new instance from a list of `(id, size)` pairs. + /// + /// Region IDs do not need to be contiguous. Each ID is used directly as an + /// index into the internal array, leaving absent regions as zero. + pub fn new(regions: &[(u8, u64)]) -> Self { + let mut memory_sizes = [0u64; 256]; + for &(id, size) in regions { + memory_sizes[usize::from(id)] = size; + } Self { - nregions, + nregions: regions.len() as u32, padding: 0, memory_sizes, }