Skip to content

Commit 8346642

Browse files
author
Dorinda Bassey
committed
devices/vhost: Add config space support for vhost-user devices
Implement read_config() for vhost-user devices using the VHOST_USER_GET_CONFIG protocol message. This enables vhost-user devices to expose their configuration space to the guest. This provides a general mechanism for any vhost-user device that needs to expose configuration to the guest (e.g., virtio-snd). Signed-off-by: Dorinda Bassey <dbassey@redhat.com>
1 parent 319d94e commit 8346642

1 file changed

Lines changed: 34 additions & 11 deletions

File tree

src/devices/src/virtio/vhost_user/device.rs

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use log::{debug, error, warn};
1515
use polly::event_manager::{EventManager, Subscriber};
1616
use utils::epoll::{EpollEvent, EventSet};
1717
use utils::eventfd::{EventFd, EFD_NONBLOCK};
18+
use vhost::vhost_user::message::VhostUserConfigFlags;
1819
use vhost::vhost_user::{Frontend, VhostUserFrontend, VhostUserProtocolFeatures};
1920
use vhost::{VhostBackend, VhostUserMemoryRegionInfo, VringConfigData};
2021
use vm_memory::{Address, GuestMemory, GuestMemoryMmap, GuestMemoryRegion};
@@ -146,14 +147,6 @@ impl VhostUserDevice {
146147
num_queues as usize
147148
};
148149

149-
debug!(
150-
"{}: using {} queues (requested: {}, sizes provided: {})",
151-
device_name,
152-
actual_num_queues,
153-
num_queues,
154-
queue_sizes.len()
155-
);
156-
157150
let default_size = queue_sizes.last().copied().unwrap_or(256);
158151
let queue_configs: Vec<_> = (0..actual_num_queues)
159152
.map(|i| {
@@ -358,10 +351,40 @@ impl VirtioDevice for VhostUserDevice {
358351
}
359352

360353
fn read_config(&self, offset: u64, data: &mut [u8]) {
361-
// For now, configuration space reads are not supported
362-
// This can be extended using VHOST_USER_GET_CONFIG
354+
// Fetch config from backend on every read (same as QEMU/crosvm)
355+
// No caching to avoid invalidation issues
356+
if self.has_protocol_features {
357+
if let Ok(mut frontend) = self.frontend.lock() {
358+
match frontend.get_config(
359+
offset as u32,
360+
data.len() as u32,
361+
VhostUserConfigFlags::empty(),
362+
data,
363+
) {
364+
Ok((_, returned_buf)) => {
365+
if data.len() <= returned_buf.len() {
366+
data.copy_from_slice(&returned_buf[..data.len()]);
367+
debug!(
368+
"{}: read {} bytes from config at offset {}",
369+
self.device_name,
370+
data.len(),
371+
offset
372+
);
373+
return;
374+
}
375+
}
376+
Err(e) => {
377+
debug!(
378+
"{}: failed to read config from backend: {:?}",
379+
self.device_name, e
380+
);
381+
}
382+
}
383+
}
384+
}
385+
363386
debug!(
364-
"{}: config read at offset {} (not yet implemented)",
387+
"{}: config read at offset {} returning zeros (backend not available)",
365388
self.device_name, offset
366389
);
367390
data.fill(0);

0 commit comments

Comments
 (0)