Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vhost-device I2C support #1

Merged
merged 9 commits into from
Aug 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
kcov_output/
target/
.vscode/
*.swp
2 changes: 1 addition & 1 deletion CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Add the list of code owners here (using their GitHub username)
* gatekeeper-PullAssigner
* gatekeeper-PullAssigner @vireshk
15 changes: 4 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
[package]
name = "crate-template"
version = "0.1.0"
authors = ["TODO"]
description = "This is a template for creating rust-vmm repositories."
repository = "https://github.com/rust-vmm/crate-template"
readme = "README.md"
keywords = ["virt"]
license = "Apache-2.0 OR BSD-3-Clause"
edition = "2018"
[workspace]

[dependencies]
members = [
"src/i2c",
]
42 changes: 6 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,11 @@
# Crate Name
# vhost-device

## Design

TODO: This section should have a high-level design of the crate.
This repository hosts various 'vhost-user' device backends in their own crates.
See their individual README.md files for specific information about those
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about also mentioning all these devices (which right now is just one 😆) here as well, and have a link that takes you to their readme?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

crates.

Some questions that might help in writing this section:
- What is the purpose of this crate?
- What are the main components of the crate? How do they interact which each
other?
Here is the list of device backends that we support:

## Usage

TODO: This section describes how the crate is used.

Some questions that might help in writing this section:
- What traits do users need to implement?
- Does the crate have any default/optional features? What is each feature
doing?
- Is this crate used by other rust-vmm components? If yes, how?

## Examples

TODO: Usage examples.

```rust
use my_crate;

...
```

## License

**!!!NOTICE**: The BSD-3-Clause license is not included in this template.
The license needs to be manually added because the text of the license file
also includes the copyright. The copyright can be different for different
crates. If the crate contains code from CrosVM, the crate must add the
CrosVM copyright which can be found
[here](https://chromium.googlesource.com/chromiumos/platform/crosvm/+/master/LICENSE).
For crates developed from scratch, the copyright is different and depends on
the contributors.
- [I2C](https://github.com/rust-vmm/vhost-device/blob/master/src/i2c/README.md)
2 changes: 1 addition & 1 deletion coverage_config_x86_64.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"coverage_score": 90,
"coverage_score": 36.7,
"exclude_path": "",
"crate_features": ""
}
23 changes: 23 additions & 0 deletions src/i2c/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "vhost-device-i2c"
version = "0.1.0"
authors = ["Viresh Kumar <[email protected]>"]
description = "vhost i2c backend device"
repository = "https://github.com/rust-vmm/vhost-device"
readme = "README.md"
keywords = ["i2c", "vhost", "virt", "backend"]
license = "Apache-2.0 OR BSD-3-Clause"
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
clap = { version = "=3.0.0-beta.2", features = ["yaml"] }
epoll = "4.3"
libc = ">=0.2.95"
log = ">=0.4.6"
vhost = { git = "https://github.com/rust-vmm/vhost", features = ["vhost-user-slave"] }
vhost-user-backend = { git = "https://github.com/rust-vmm/vhost-user-backend" }
virtio-bindings = ">=0.1"
vm-memory = ">=0.3.0"
vmm-sys-util = ">=0.8.0"
64 changes: 64 additions & 0 deletions src/i2c/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# vhost-device-i2c - I2C emulation backend daemon

## Description
This program is a vhost-user backend that emulates a VirtIO I2C bus.
This program takes the layout of the i2c bus and its devices on the host
OS and then talks to them via the /dev/i2c-X interface when a request
comes from the guest OS for an I2C or SMBUS device.

This program is tested with QEMU's `-device vhost-user-i2c-pci` but should
work with any virtual machine monitor (VMM) that supports vhost-user. See the
Examples section below.

## Synopsis

**vhost-device-i2c** [*OPTIONS*]

## Options

.. program:: vhost-device-i2c

.. option:: -h, --help

Print help.

.. option:: -s, --socket-path=PATH

Location of vhost-user Unix domain sockets, this path will be suffixed with
0,1,2..socket_count-1.

.. option:: -c, --socket-count=INT

Number of guests (sockets) to attach to, default set to 1.

.. option:: -l, --device-list=I2C-DEVICES

I2c device list at the host OS in the format:
<bus>:<client_addr>[:<client_addr>],[<bus>:<client_addr>[:<client_addr>]]

Example: --device-list "2:32:21,3:10:23"

Here,
bus (decimal): adatper bus number. e.g. 2 for /dev/i2c-2, 3 for /dev/i2c-3.
client_addr (decimal): address for client device, 32 == 0x20.

## Examples

The daemon should be started first:

::

host# vhost-device-i2c --socket-path=vi2c.sock --socket-count=1 --device-list 0:32
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be an integration test?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be an integration test?

The kind of sample tests that I was able to find tested the routines directly. What you are suggesting here is a bit different, test the generated binary. Can you point me to some sample code for this kind of testing ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are doing tests on the binary in vmm-reference. Here is an example of a test: https://github.com/rust-vmm/vmm-reference/blob/1226002a93a4dd857864ec4bc2eed3688e9870e3/tests/test_run_reference_vmm.py#L296. We're currently testing the vmm-reference binary using Python integration tests, but in this case we should see if writing Rust integration tests can be implemented. We can open a separate issue for this one.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are doing tests on the binary in vmm-reference. Here is an example of a test: https://github.com/rust-vmm/vmm-reference/blob/1226002a93a4dd857864ec4bc2eed3688e9870e3/tests/test_run_reference_vmm.py#L296. We're currently testing the vmm-reference binary using Python integration tests, but in this case we should see if writing Rust integration tests can be implemented. We can open a separate issue for this one.

I fixed it differently, broke most of main.rs into another routine which I am able to test now. Cover is 44% now.


The QEMU invocation needs to create a chardev socket the device can
use to communicate as well as share the guests memory over a memfd.

::

host# qemu-system \
-chardev socket,path=vi2c.sock,id=vi2c \
-device vhost-user-i2c-pci,chardev=vi2c,id=i2c \
-m 4096 \
-object memory-backend-file,id=mem,size=4G,mem-path=/dev/shm,share=on \
-numa node,memdev=mem \
...
37 changes: 37 additions & 0 deletions src/i2c/src/cli.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: vhost-device-i2c
version: "0.1.0"
author: "Viresh Kumar <[email protected]>"
about: Virtio I2C backend daemon.

settings:
- ArgRequiredElseHelp

args:
# Connection to sockets
- socket_path:
short: s
long: socket-path
value_name: FILE
takes_value: true
about: Location of vhost-user Unix domain socket. This is suffixed by 0,1,2..socket_count-1.
- socket_count:
short: c
long: socket-count
value_name: INT
takes_value: true
about: Number of guests (sockets) to connect to. Default = 1.
# I2C device list on host
- devices:
short: l
long: device-list
value_name: PATH
takes_value: true
about: List of I2C bus and clients in format <bus>:<client_addr>[:<client_addr>][,<bus>:<client_addr>[:<client_addr>]]

groups:
- required_args:
args:
- socket_path
args:
- devices
required: true
Loading