mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 21:55:20 +00:00
vm-virtio: Implement reset() for virtio-pmem
The virtio specification defines a device can be reset, which was not supported by this virtio-pmem implementation. The reason it is needed is to support unbinding this device from the guest driver, and rebind it to vfio-pci driver. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
eb91bc812b
commit
3e750de43f
@ -291,6 +291,8 @@ pub struct Pmem {
|
|||||||
avail_features: u64,
|
avail_features: u64,
|
||||||
acked_features: u64,
|
acked_features: u64,
|
||||||
config: VirtioPmemConfig,
|
config: VirtioPmemConfig,
|
||||||
|
queue_evts: Option<Vec<EventFd>>,
|
||||||
|
interrupt_cb: Option<Arc<VirtioInterrupt>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pmem {
|
impl Pmem {
|
||||||
@ -306,6 +308,8 @@ impl Pmem {
|
|||||||
avail_features: 1u64 << VIRTIO_F_VERSION_1,
|
avail_features: 1u64 << VIRTIO_F_VERSION_1,
|
||||||
acked_features: 0u64,
|
acked_features: 0u64,
|
||||||
config,
|
config,
|
||||||
|
queue_evts: None,
|
||||||
|
interrupt_cb: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -407,7 +411,26 @@ impl VirtioDevice for Pmem {
|
|||||||
};
|
};
|
||||||
self.kill_evt = Some(self_kill_evt);
|
self.kill_evt = Some(self_kill_evt);
|
||||||
|
|
||||||
if let Some(disk) = self.disk.take() {
|
// Save the interrupt EventFD as we need to return it on reset
|
||||||
|
// but clone it to pass into the thread.
|
||||||
|
self.interrupt_cb = Some(interrupt_cb.clone());
|
||||||
|
|
||||||
|
let mut tmp_queue_evts: Vec<EventFd> = Vec::new();
|
||||||
|
for queue_evt in queue_evts.iter() {
|
||||||
|
// Save the queue EventFD as we need to return it on reset
|
||||||
|
// but clone it to pass into the thread.
|
||||||
|
tmp_queue_evts.push(queue_evt.try_clone().map_err(|e| {
|
||||||
|
error!("failed to clone queue EventFd: {}", e);
|
||||||
|
ActivateError::BadActivate
|
||||||
|
})?);
|
||||||
|
}
|
||||||
|
self.queue_evts = Some(tmp_queue_evts);
|
||||||
|
|
||||||
|
if let Some(disk) = self.disk.as_ref() {
|
||||||
|
let disk = disk.try_clone().map_err(|e| {
|
||||||
|
error!("failed cloning pmem disk: {}", e);
|
||||||
|
ActivateError::BadActivate
|
||||||
|
})?;
|
||||||
let mut handler = PmemEpollHandler {
|
let mut handler = PmemEpollHandler {
|
||||||
queue: queues.remove(0),
|
queue: queues.remove(0),
|
||||||
mem,
|
mem,
|
||||||
@ -430,4 +453,17 @@ impl VirtioDevice for Pmem {
|
|||||||
}
|
}
|
||||||
Err(ActivateError::BadActivate)
|
Err(ActivateError::BadActivate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn reset(&mut self) -> Option<(Arc<VirtioInterrupt>, Vec<EventFd>)> {
|
||||||
|
if let Some(kill_evt) = self.kill_evt.take() {
|
||||||
|
// Ignore the result because there is nothing we can do about it.
|
||||||
|
let _ = kill_evt.write(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the interrupt and queue EventFDs
|
||||||
|
Some((
|
||||||
|
self.interrupt_cb.take().unwrap(),
|
||||||
|
self.queue_evts.take().unwrap(),
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user