mirror of
https://github.com/rust-vmm/vhost-device.git
synced 2025-12-30 09:46:55 +00:00
Merge branch 'main' into dependabot/submodules/rust-vmm-ci-aee82cf
This commit is contained in:
commit
5ea0aa732f
@ -1,2 +1,2 @@
|
||||
# Add the list of code owners here (using their GitHub username)
|
||||
* gatekeeper-PullAssigner @vireshk
|
||||
* gatekeeper-PullAssigner @vireshk @stsquad @mathieupoirier
|
||||
|
||||
17
README.md
17
README.md
@ -9,3 +9,20 @@ crates.
|
||||
Here is the list of device backends that we support:
|
||||
|
||||
- [I2C](https://github.com/rust-vmm/vhost-device/blob/master/src/i2c/README.md)
|
||||
|
||||
## Separation of Concerns
|
||||
|
||||
The binaries built by this repository can be run with any VMM which
|
||||
can act as a vhost-user master. Typically they have been tested with
|
||||
[QEMU](https://www.qemu.org) although the rust-vmm project does
|
||||
provide a [vhost-user
|
||||
master](https://github.com/rust-vmm/vhost/tree/main/src/vhost_user)
|
||||
crate for rust based VMMs.
|
||||
|
||||
While it's possible to implement all parts of the backend inside the
|
||||
vhost-device workspace consideration should be given to separating the
|
||||
VirtQueue handling and response logic to a crate in [vm-virtio
|
||||
devices](https://github.com/rust-vmm/vm-virtio/tree/main/crates/devices).
|
||||
This way a monolithic rust-vmm VMM implementation can reuse the core
|
||||
logic to service the virtio requests directly in the application.
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use log::info;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::{File, OpenOptions};
|
||||
use std::os::unix::io::AsRawFd;
|
||||
|
||||
@ -446,11 +447,10 @@ impl<D: I2cDevice> I2cAdapter<D> {
|
||||
|
||||
/// I2C map and helpers
|
||||
pub(crate) const MAX_I2C_VDEV: usize = 1 << 7;
|
||||
const I2C_INVALID_ADAPTER: u32 = 0xFFFFFFFF;
|
||||
|
||||
pub struct I2cMap<D: I2cDevice> {
|
||||
adapters: Vec<I2cAdapter<D>>,
|
||||
device_map: [u32; MAX_I2C_VDEV],
|
||||
device_map: HashMap<u16, usize>,
|
||||
}
|
||||
|
||||
impl<D: I2cDevice> I2cMap<D> {
|
||||
@ -458,7 +458,7 @@ impl<D: I2cDevice> I2cMap<D> {
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let mut device_map: [u32; MAX_I2C_VDEV] = [I2C_INVALID_ADAPTER; MAX_I2C_VDEV];
|
||||
let mut device_map = HashMap::new();
|
||||
let mut adapters: Vec<I2cAdapter<D>> = Vec::new();
|
||||
|
||||
for (i, device_cfg) in device_config.inner.iter().enumerate() {
|
||||
@ -468,7 +468,7 @@ impl<D: I2cDevice> I2cMap<D> {
|
||||
// Check that all addresses corresponding to the adapter are valid.
|
||||
for addr in &device_cfg.addr {
|
||||
adapter.set_device_addr(*addr as usize)?;
|
||||
device_map[*addr as usize] = i as u32;
|
||||
device_map.insert(*addr, i);
|
||||
}
|
||||
|
||||
info!(
|
||||
@ -486,21 +486,21 @@ impl<D: I2cDevice> I2cMap<D> {
|
||||
}
|
||||
|
||||
pub fn transfer(&self, reqs: &mut [I2cReq]) -> Result<()> {
|
||||
let device = reqs[0].addr as usize;
|
||||
let device = reqs[0].addr;
|
||||
|
||||
// identify the device in the device_map
|
||||
let index = self.device_map[device];
|
||||
let index = match self.device_map.get(&device) {
|
||||
Some(&index) => index,
|
||||
|
||||
// This can happen a lot while scanning the bus, don't print any errors.
|
||||
if index == I2C_INVALID_ADAPTER {
|
||||
return Err(Error::ClientAddressInvalid);
|
||||
}
|
||||
// This can happen a lot while scanning the bus, don't print any errors.
|
||||
None => return Err(Error::ClientAddressInvalid),
|
||||
};
|
||||
|
||||
// get the corresponding adapter based on the device config.
|
||||
let adapter = &self.adapters[index as usize];
|
||||
|
||||
// Set device's address
|
||||
adapter.set_device_addr(device)?;
|
||||
adapter.set_device_addr(device as usize)?;
|
||||
adapter.transfer(reqs)
|
||||
}
|
||||
}
|
||||
@ -590,11 +590,11 @@ pub mod tests {
|
||||
assert_eq!(i2c_map.adapters[1].adapter_no(), 2);
|
||||
assert_eq!(i2c_map.adapters[2].adapter_no(), 5);
|
||||
|
||||
assert_eq!(i2c_map.device_map[4], 0);
|
||||
assert_eq!(i2c_map.device_map[32], 1);
|
||||
assert_eq!(i2c_map.device_map[21], 1);
|
||||
assert_eq!(i2c_map.device_map[10], 2);
|
||||
assert_eq!(i2c_map.device_map[23], 2);
|
||||
assert_eq!(i2c_map.device_map.get(&4), Some(&0));
|
||||
assert_eq!(i2c_map.device_map.get(&32), Some(&1));
|
||||
assert_eq!(i2c_map.device_map.get(&21), Some(&1));
|
||||
assert_eq!(i2c_map.device_map.get(&10), Some(&2));
|
||||
assert_eq!(i2c_map.device_map.get(&23), Some(&2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@ -86,7 +86,6 @@ unsafe impl ByteValued for VirtioI2cInHdr {}
|
||||
pub struct VhostUserI2cBackend<D: I2cDevice> {
|
||||
i2c_map: Arc<I2cMap<D>>,
|
||||
event_idx: bool,
|
||||
mem: Option<GuestMemoryAtomic<GuestMemoryMmap>>,
|
||||
pub exit_event: EventFd,
|
||||
}
|
||||
|
||||
@ -95,7 +94,6 @@ impl<D: I2cDevice> VhostUserI2cBackend<D> {
|
||||
Ok(VhostUserI2cBackend {
|
||||
i2c_map,
|
||||
event_idx: false,
|
||||
mem: None,
|
||||
exit_event: EventFd::new(EFD_NONBLOCK).map_err(Error::EventFdFailed)?,
|
||||
})
|
||||
}
|
||||
@ -249,9 +247,8 @@ impl<D: 'static + I2cDevice + Sync + Send> VhostUserBackendMut<VringRwLock, ()>
|
||||
|
||||
fn update_memory(
|
||||
&mut self,
|
||||
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||
_mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||
) -> VhostUserBackendResult<()> {
|
||||
self.mem = Some(mem);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user