mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
virtio-devices: generic-vhost-user: Config change notification
Add support for backend that is connected via the vhost-user-generic frontend to generate an interrupt into the guest when it has made a change to the configuration. This is useful for devices that can change the exposed configuration at runtime. Assisted-by: Claude:Opus-4.7 Signed-off-by: Rob Bradford <rbradford@meta.com>
This commit is contained in:
@@ -26,13 +26,27 @@ use crate::thread_helper::spawn_virtio_thread;
|
|||||||
use crate::vhost_user::{VhostUserCommon, VhostUserState};
|
use crate::vhost_user::{VhostUserCommon, VhostUserState};
|
||||||
use crate::{
|
use crate::{
|
||||||
ActivateResult, GuestMemoryMmap, GuestRegionMmap, MmapRegion, VIRTIO_F_ACCESS_PLATFORM,
|
ActivateResult, GuestMemoryMmap, GuestRegionMmap, MmapRegion, VIRTIO_F_ACCESS_PLATFORM,
|
||||||
VirtioCommon, VirtioDevice, VirtioSharedMemoryList,
|
VirtioCommon, VirtioDevice, VirtioInterrupt, VirtioInterruptType, VirtioSharedMemoryList,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type State = VhostUserState<()>;
|
pub type State = VhostUserState<()>;
|
||||||
|
|
||||||
struct BackendReqHandler {}
|
struct BackendReqHandler {
|
||||||
impl VhostUserFrontendReqHandler for BackendReqHandler {}
|
interrupt_cb: Arc<dyn VirtioInterrupt>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VhostUserFrontendReqHandler for BackendReqHandler {
|
||||||
|
fn handle_config_change(&self) -> std::io::Result<u64> {
|
||||||
|
self.interrupt_cb
|
||||||
|
.trigger(VirtioInterruptType::Config)
|
||||||
|
.map_err(|e| {
|
||||||
|
error!("Failed to signal config change: {e:?}");
|
||||||
|
std::io::Error::other(e)
|
||||||
|
})?;
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct GenericVhostUser {
|
pub struct GenericVhostUser {
|
||||||
vu_common: VhostUserCommon,
|
vu_common: VhostUserCommon,
|
||||||
id: String,
|
id: String,
|
||||||
@@ -97,7 +111,8 @@ impl GenericVhostUser {
|
|||||||
| VhostUserProtocolFeatures::REPLY_ACK
|
| VhostUserProtocolFeatures::REPLY_ACK
|
||||||
| VhostUserProtocolFeatures::INFLIGHT_SHMFD
|
| VhostUserProtocolFeatures::INFLIGHT_SHMFD
|
||||||
| VhostUserProtocolFeatures::LOG_SHMFD
|
| VhostUserProtocolFeatures::LOG_SHMFD
|
||||||
| VhostUserProtocolFeatures::DEVICE_STATE;
|
| VhostUserProtocolFeatures::DEVICE_STATE
|
||||||
|
| VhostUserProtocolFeatures::BACKEND_REQ;
|
||||||
|
|
||||||
let avail_features = super::DEFAULT_VIRTIO_FEATURES;
|
let avail_features = super::DEFAULT_VIRTIO_FEATURES;
|
||||||
|
|
||||||
@@ -275,7 +290,22 @@ impl VirtioDevice for GenericVhostUser {
|
|||||||
.activate(&queues, interrupt_cb.clone())?;
|
.activate(&queues, interrupt_cb.clone())?;
|
||||||
self.guest_memory = Some(mem.clone());
|
self.guest_memory = Some(mem.clone());
|
||||||
|
|
||||||
let backend_req_handler: Option<FrontendReqHandler<BackendReqHandler>> = None;
|
let has_backend_req = self.vu_common.acked_protocol_features
|
||||||
|
& VhostUserProtocolFeatures::BACKEND_REQ.bits()
|
||||||
|
!= 0;
|
||||||
|
|
||||||
|
let backend_req_handler = has_backend_req
|
||||||
|
.then(|| {
|
||||||
|
FrontendReqHandler::new(Arc::new(BackendReqHandler {
|
||||||
|
interrupt_cb: interrupt_cb.clone(),
|
||||||
|
}))
|
||||||
|
.map_err(|e| {
|
||||||
|
crate::ActivateError::VhostUserSetup(Error::FrontendReqHandlerCreation(e))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
// Return inner Err early, keep Option of `Ok` value
|
||||||
|
.transpose()?;
|
||||||
|
|
||||||
// Run a dedicated thread for handling potential reconnections with
|
// Run a dedicated thread for handling potential reconnections with
|
||||||
// the backend.
|
// the backend.
|
||||||
let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds();
|
let (kill_evt, pause_evt) = self.vu_common.virtio_common.dup_eventfds();
|
||||||
|
|||||||
Reference in New Issue
Block a user