mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-21 20:15:21 +00:00
virtio-devices: vdpa: Make vhost-vdpa handler optional
In order to anticipate for migration support, we need to be able to create a Vdpa object without VhostKernVdpa object associated with it. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
02f951a9c3
commit
340fd6571a
@ -85,7 +85,7 @@ pub type Result<T> = std::result::Result<T, Error>;
|
|||||||
pub struct Vdpa {
|
pub struct Vdpa {
|
||||||
common: VirtioCommon,
|
common: VirtioCommon,
|
||||||
id: String,
|
id: String,
|
||||||
vhost: VhostKernVdpa<GuestMemoryAtomic<GuestMemoryMmap>>,
|
vhost: Option<VhostKernVdpa<GuestMemoryAtomic<GuestMemoryMmap>>>,
|
||||||
iova_range: VhostVdpaIovaRange,
|
iova_range: VhostVdpaIovaRange,
|
||||||
enabled_queues: BTreeMap<usize, bool>,
|
enabled_queues: BTreeMap<usize, bool>,
|
||||||
backend_features: u64,
|
backend_features: u64,
|
||||||
@ -123,7 +123,7 @@ impl Vdpa {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
id,
|
id,
|
||||||
vhost,
|
vhost: Some(vhost),
|
||||||
iova_range,
|
iova_range,
|
||||||
enabled_queues: BTreeMap::new(),
|
enabled_queues: BTreeMap::new(),
|
||||||
backend_features,
|
backend_features,
|
||||||
@ -131,9 +131,13 @@ impl Vdpa {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn enable_vrings(&mut self, enable: bool) -> Result<()> {
|
fn enable_vrings(&mut self, enable: bool) -> Result<()> {
|
||||||
|
assert!(self.vhost.is_some());
|
||||||
|
|
||||||
for (queue_index, enabled) in self.enabled_queues.iter_mut() {
|
for (queue_index, enabled) in self.enabled_queues.iter_mut() {
|
||||||
if *enabled != enable {
|
if *enabled != enable {
|
||||||
self.vhost
|
self.vhost
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
.set_vring_enable(*queue_index, enable)
|
.set_vring_enable(*queue_index, enable)
|
||||||
.map_err(Error::SetVringEnable)?;
|
.map_err(Error::SetVringEnable)?;
|
||||||
*enabled = enable;
|
*enabled = enable;
|
||||||
@ -150,9 +154,13 @@ impl Vdpa {
|
|||||||
queues: Vec<(usize, Queue, EventFd)>,
|
queues: Vec<(usize, Queue, EventFd)>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
self.vhost
|
self.vhost
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
.set_features(self.common.acked_features)
|
.set_features(self.common.acked_features)
|
||||||
.map_err(Error::SetFeatures)?;
|
.map_err(Error::SetFeatures)?;
|
||||||
self.vhost
|
self.vhost
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
.set_backend_features(self.backend_features)
|
.set_backend_features(self.backend_features)
|
||||||
.map_err(Error::SetBackendFeatures)?;
|
.map_err(Error::SetBackendFeatures)?;
|
||||||
|
|
||||||
@ -160,6 +168,8 @@ impl Vdpa {
|
|||||||
let queue_max_size = queue.max_size();
|
let queue_max_size = queue.max_size();
|
||||||
let queue_size = queue.size();
|
let queue_size = queue.size();
|
||||||
self.vhost
|
self.vhost
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
.set_vring_num(*queue_index, queue_size)
|
.set_vring_num(*queue_index, queue_size)
|
||||||
.map_err(Error::SetVringNum)?;
|
.map_err(Error::SetVringNum)?;
|
||||||
|
|
||||||
@ -183,9 +193,13 @@ impl Vdpa {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.vhost
|
self.vhost
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
.set_vring_addr(*queue_index, &config_data)
|
.set_vring_addr(*queue_index, &config_data)
|
||||||
.map_err(Error::SetVringAddr)?;
|
.map_err(Error::SetVringAddr)?;
|
||||||
self.vhost
|
self.vhost
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
.set_vring_base(
|
.set_vring_base(
|
||||||
*queue_index,
|
*queue_index,
|
||||||
queue
|
queue
|
||||||
@ -199,11 +213,15 @@ impl Vdpa {
|
|||||||
virtio_interrupt.notifier(VirtioInterruptType::Queue(*queue_index as u16))
|
virtio_interrupt.notifier(VirtioInterruptType::Queue(*queue_index as u16))
|
||||||
{
|
{
|
||||||
self.vhost
|
self.vhost
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
.set_vring_call(*queue_index, &eventfd)
|
.set_vring_call(*queue_index, &eventfd)
|
||||||
.map_err(Error::SetVringCall)?;
|
.map_err(Error::SetVringCall)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.vhost
|
self.vhost
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
.set_vring_kick(*queue_index, queue_evt)
|
.set_vring_kick(*queue_index, queue_evt)
|
||||||
.map_err(Error::SetVringKick)?;
|
.map_err(Error::SetVringKick)?;
|
||||||
}
|
}
|
||||||
@ -211,6 +229,8 @@ impl Vdpa {
|
|||||||
// Setup the config eventfd if there is one
|
// Setup the config eventfd if there is one
|
||||||
if let Some(eventfd) = virtio_interrupt.notifier(VirtioInterruptType::Config) {
|
if let Some(eventfd) = virtio_interrupt.notifier(VirtioInterruptType::Config) {
|
||||||
self.vhost
|
self.vhost
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
.set_config_call(&eventfd)
|
.set_config_call(&eventfd)
|
||||||
.map_err(Error::SetConfigCall)?;
|
.map_err(Error::SetConfigCall)?;
|
||||||
}
|
}
|
||||||
@ -218,6 +238,8 @@ impl Vdpa {
|
|||||||
self.enable_vrings(true)?;
|
self.enable_vrings(true)?;
|
||||||
|
|
||||||
self.vhost
|
self.vhost
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
.set_status(
|
.set_status(
|
||||||
(DEVICE_ACKNOWLEDGE | DEVICE_DRIVER | DEVICE_DRIVER_OK | DEVICE_FEATURES_OK) as u8,
|
(DEVICE_ACKNOWLEDGE | DEVICE_DRIVER | DEVICE_DRIVER_OK | DEVICE_FEATURES_OK) as u8,
|
||||||
)
|
)
|
||||||
@ -227,7 +249,11 @@ impl Vdpa {
|
|||||||
fn reset_vdpa(&mut self) -> Result<()> {
|
fn reset_vdpa(&mut self) -> Result<()> {
|
||||||
self.enable_vrings(false)?;
|
self.enable_vrings(false)?;
|
||||||
|
|
||||||
self.vhost.set_status(0).map_err(Error::SetStatus)
|
self.vhost
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.set_status(0)
|
||||||
|
.map_err(Error::SetStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dma_map(&self, iova: u64, size: u64, host_vaddr: *const u8, readonly: bool) -> Result<()> {
|
fn dma_map(&self, iova: u64, size: u64, host_vaddr: *const u8, readonly: bool) -> Result<()> {
|
||||||
@ -236,7 +262,10 @@ impl Vdpa {
|
|||||||
return Err(Error::InvalidIovaRange(iova, iova_last));
|
return Err(Error::InvalidIovaRange(iova, iova_last));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert!(self.vhost.is_some());
|
||||||
self.vhost
|
self.vhost
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
.dma_map(iova, size, host_vaddr, readonly)
|
.dma_map(iova, size, host_vaddr, readonly)
|
||||||
.map_err(Error::DmaMap)
|
.map_err(Error::DmaMap)
|
||||||
}
|
}
|
||||||
@ -247,7 +276,12 @@ impl Vdpa {
|
|||||||
return Err(Error::InvalidIovaRange(iova, iova_last));
|
return Err(Error::InvalidIovaRange(iova, iova_last));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.vhost.dma_unmap(iova, size).map_err(Error::DmaUnmap)
|
assert!(self.vhost.is_some());
|
||||||
|
self.vhost
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.dma_unmap(iova, size)
|
||||||
|
.map_err(Error::DmaUnmap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,13 +303,15 @@ impl VirtioDevice for Vdpa {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn read_config(&self, offset: u64, data: &mut [u8]) {
|
fn read_config(&self, offset: u64, data: &mut [u8]) {
|
||||||
if let Err(e) = self.vhost.get_config(offset as u32, data) {
|
assert!(self.vhost.is_some());
|
||||||
|
if let Err(e) = self.vhost.as_ref().unwrap().get_config(offset as u32, data) {
|
||||||
error!("Failed reading virtio config: {}", e);
|
error!("Failed reading virtio config: {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_config(&mut self, offset: u64, data: &[u8]) {
|
fn write_config(&mut self, offset: u64, data: &[u8]) {
|
||||||
if let Err(e) = self.vhost.set_config(offset as u32, data) {
|
assert!(self.vhost.is_some());
|
||||||
|
if let Err(e) = self.vhost.as_ref().unwrap().set_config(offset as u32, data) {
|
||||||
error!("Failed writing virtio config: {}", e);
|
error!("Failed writing virtio config: {}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user