mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vm-virtio: Define and implement Translatable trait
This new trait simplifies the address translation of a GuestAddress by having GuestAddress implementing it. The three crates virtio-devices, block_util and net_util have been updated accordingly to rely on this new trait, helping with code readability and limiting the amount of duplicated code. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
committed by
Rob Bradford
parent
c99d637693
commit
77df4e6773
@@ -14,8 +14,8 @@ use virtio_bindings::bindings::virtio_net::{
|
||||
VIRTIO_NET_F_GUEST_UFO, VIRTIO_NET_OK,
|
||||
};
|
||||
use virtio_queue::Queue;
|
||||
use vm_memory::{ByteValued, Bytes, GuestAddress, GuestMemoryAtomic, GuestMemoryError};
|
||||
use vm_virtio::AccessPlatform;
|
||||
use vm_memory::{ByteValued, Bytes, GuestMemoryAtomic, GuestMemoryError};
|
||||
use vm_virtio::{AccessPlatform, Translatable};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
@@ -65,44 +65,22 @@ impl CtrlQueue {
|
||||
for mut desc_chain in queue.iter().map_err(Error::QueueIterator)? {
|
||||
let ctrl_desc = desc_chain.next().ok_or(Error::NoControlHeaderDescriptor)?;
|
||||
|
||||
let ctrl_desc_addr = if let Some(access_platform) = access_platform {
|
||||
GuestAddress(
|
||||
access_platform
|
||||
.translate(ctrl_desc.addr().0, u64::from(ctrl_desc.len()))
|
||||
.unwrap(),
|
||||
)
|
||||
} else {
|
||||
ctrl_desc.addr()
|
||||
};
|
||||
|
||||
let ctrl_hdr: ControlHeader = desc_chain
|
||||
.memory()
|
||||
.read_obj(ctrl_desc_addr)
|
||||
.read_obj(
|
||||
ctrl_desc
|
||||
.addr()
|
||||
.translate(access_platform, ctrl_desc.len() as usize),
|
||||
)
|
||||
.map_err(Error::GuestMemory)?;
|
||||
let data_desc = desc_chain.next().ok_or(Error::NoDataDescriptor)?;
|
||||
|
||||
let data_desc_addr = if let Some(access_platform) = access_platform {
|
||||
GuestAddress(
|
||||
access_platform
|
||||
.translate(data_desc.addr().0, u64::from(data_desc.len()))
|
||||
.unwrap(),
|
||||
)
|
||||
} else {
|
||||
data_desc.addr()
|
||||
};
|
||||
let data_desc_addr = data_desc
|
||||
.addr()
|
||||
.translate(access_platform, data_desc.len() as usize);
|
||||
|
||||
let status_desc = desc_chain.next().ok_or(Error::NoStatusDescriptor)?;
|
||||
|
||||
let status_desc_addr = if let Some(access_platform) = access_platform {
|
||||
GuestAddress(
|
||||
access_platform
|
||||
.translate(status_desc.addr().0, u64::from(status_desc.len()))
|
||||
.unwrap(),
|
||||
)
|
||||
} else {
|
||||
status_desc.addr()
|
||||
};
|
||||
|
||||
let ok = match u32::from(ctrl_hdr.class) {
|
||||
VIRTIO_NET_CTRL_MQ => {
|
||||
let queue_pairs = desc_chain
|
||||
@@ -154,7 +132,9 @@ impl CtrlQueue {
|
||||
.memory()
|
||||
.write_obj(
|
||||
if ok { VIRTIO_NET_OK } else { VIRTIO_NET_ERR } as u8,
|
||||
status_desc_addr,
|
||||
status_desc
|
||||
.addr()
|
||||
.translate(access_platform, status_desc.len() as usize),
|
||||
)
|
||||
.map_err(Error::GuestMemory)?;
|
||||
let len = ctrl_desc.len() + data_desc.len() + status_desc.len();
|
||||
|
||||
@@ -11,8 +11,8 @@ use std::os::unix::io::{AsRawFd, RawFd};
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
use std::sync::Arc;
|
||||
use virtio_queue::Queue;
|
||||
use vm_memory::{Bytes, GuestAddress, GuestMemory, GuestMemoryAtomic};
|
||||
use vm_virtio::AccessPlatform;
|
||||
use vm_memory::{Bytes, GuestMemory, GuestMemoryAtomic};
|
||||
use vm_virtio::{AccessPlatform, Translatable};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct TxVirtio {
|
||||
@@ -60,16 +60,7 @@ impl TxVirtio {
|
||||
|
||||
let mut iovecs = Vec::new();
|
||||
while let Some(desc) = next_desc {
|
||||
let desc_addr = if let Some(access_platform) = access_platform {
|
||||
GuestAddress(
|
||||
access_platform
|
||||
.translate(desc.addr().0, u64::from(desc.len()))
|
||||
.unwrap(),
|
||||
)
|
||||
} else {
|
||||
desc.addr()
|
||||
};
|
||||
|
||||
let desc_addr = desc.addr().translate(access_platform, desc.len() as usize);
|
||||
if !desc.is_write_only() && desc.len() > 0 {
|
||||
let buf = desc_chain
|
||||
.memory()
|
||||
@@ -195,31 +186,18 @@ impl RxVirtio {
|
||||
.next()
|
||||
.ok_or(NetQueuePairError::DescriptorChainTooShort)?;
|
||||
|
||||
let desc_addr = if let Some(access_platform) = access_platform {
|
||||
GuestAddress(
|
||||
access_platform
|
||||
.translate(desc.addr().0, u64::from(desc.len()))
|
||||
.unwrap(),
|
||||
let num_buffers_addr = desc_chain
|
||||
.memory()
|
||||
.checked_offset(
|
||||
desc.addr().translate(access_platform, desc.len() as usize),
|
||||
10,
|
||||
)
|
||||
} else {
|
||||
desc.addr()
|
||||
};
|
||||
|
||||
let num_buffers_addr = desc_chain.memory().checked_offset(desc_addr, 10).unwrap();
|
||||
.unwrap();
|
||||
let mut next_desc = Some(desc);
|
||||
|
||||
let mut iovecs = Vec::new();
|
||||
while let Some(desc) = next_desc {
|
||||
let desc_addr = if let Some(access_platform) = access_platform {
|
||||
GuestAddress(
|
||||
access_platform
|
||||
.translate(desc.addr().0, u64::from(desc.len()))
|
||||
.unwrap(),
|
||||
)
|
||||
} else {
|
||||
desc.addr()
|
||||
};
|
||||
|
||||
let desc_addr = desc.addr().translate(access_platform, desc.len() as usize);
|
||||
if desc.is_write_only() && desc.len() > 0 {
|
||||
let buf = desc_chain
|
||||
.memory()
|
||||
|
||||
Reference in New Issue
Block a user