Update version to 2.0.0-6
Signed-off-by: Jie Yang <yangjieyj.yang@huawei.com> (cherry picked from commit 6158eab66897bf7fb11ce7ae8c3b568f8de0e2dd)
This commit is contained in:
parent
52ebe49cfb
commit
2d9d03c21a
227
docs-fix-some-statement.patch
Normal file
227
docs-fix-some-statement.patch
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
From aeede83c9a6a4b07aee477b67d763561a3f342e6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ming Yang <yangming73@huawei.com>
|
||||||
|
Date: Wed, 18 Aug 2021 18:44:39 +0800
|
||||||
|
Subject: [PATCH 01/10] docs: fix some statement
|
||||||
|
|
||||||
|
Signed-off-by: Ming Yang <yangming73@huawei.com>
|
||||||
|
---
|
||||||
|
docs/config_guidebook.md | 32 ++++++++++++++++---------------
|
||||||
|
docs/interconnect_with_libvirt.md | 8 ++++----
|
||||||
|
docs/stratovirt_aarch64.xml | 10 +++++-----
|
||||||
|
docs/stratovirt_x86.xml | 12 ++++++------
|
||||||
|
4 files changed, 32 insertions(+), 30 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/docs/config_guidebook.md b/docs/config_guidebook.md
|
||||||
|
index 72b4c7e..e1279e1 100644
|
||||||
|
--- a/docs/config_guidebook.md
|
||||||
|
+++ b/docs/config_guidebook.md
|
||||||
|
@@ -148,7 +148,7 @@ There is only one argument for iothread:
|
||||||
|
|
||||||
|
Virtio block device is a virtual block device, which process read and write requests in virtio queue from guest.
|
||||||
|
|
||||||
|
-Eight properties are supported for virtio block device.
|
||||||
|
+Nine properties are supported for virtio block device.
|
||||||
|
|
||||||
|
* drive_id: unique device-id in StratoVirt.
|
||||||
|
* path_on_host: the path of block device in host.
|
||||||
|
@@ -156,7 +156,8 @@ Eight properties are supported for virtio block device.
|
||||||
|
* read_only: whether virtio block device is read-only. If not set, default is false.
|
||||||
|
* direct: open block device with `O_DIRECT` mode. If not set, default is true.
|
||||||
|
* iothread: indicate which iothread will be used, if not specified the main thread will be used. (optional)
|
||||||
|
-* iops: used to limit IO operations for block device. (optional)
|
||||||
|
+* throttling.iops-total: used to limit IO operations for block device. (optional)
|
||||||
|
+* if: drive type, for block drive, it should be `none`. If not set, default is `none` (optional)
|
||||||
|
* format: the format of block image, default value `raw`. NB: currently only `raw` is supported. (optional)
|
||||||
|
If not set, default is raw.
|
||||||
|
|
||||||
|
@@ -170,11 +171,11 @@ If you want to boot VM with a virtio block device as rootfs, you should add `roo
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# virtio mmio block device.
|
||||||
|
--drive id=drive_id,file=path_on_host[,serial=serial_num,readonly=off,direct=off]
|
||||||
|
--device virtio-blk-device,drive=drive_id[,iothread=iothread1,iops=200]
|
||||||
|
+-drive id=drive_id,file=path_on_host[,serial=serial_num,readonly=off,direct=off,throttling.iops-total=200]
|
||||||
|
+-device virtio-blk-device,drive=drive_id[,iothread=iothread1]
|
||||||
|
# virtio pci block device.
|
||||||
|
--drive id=drive_id,file=path_on_host[,serial=serial_num,readonly=off,direct=off]
|
||||||
|
--device virtio-blk-pci,drive=drive_id,bus=pcie.0,addr=0x3.0x0[,iothread=iothread1,iops=200]
|
||||||
|
+-drive id=drive_id,file=path_on_host[,serial=serial_num,readonly=off,direct=off,throttling.iops-total=200]
|
||||||
|
+-device virtio-blk-pci,drive=drive_id,bus=pcie.0,addr=0x3.0x0[,iothread=iothread1]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
@@ -207,11 +208,11 @@ is a single function device, the function number should be set to zero.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# virtio mmio net device
|
||||||
|
--netdev tap,id=netdevid,ifname=host_dev_name[,mac=12:34:56:78:9A:BC]
|
||||||
|
--device virtio-net-device,netdev=netdevid,id=netid[,iothread=iothread1]
|
||||||
|
+-netdev tap,id=netdevid,ifname=host_dev_name
|
||||||
|
+-device virtio-net-device,netdev=netdevid,id=netid[,iothread=iothread1,mac=12:34:56:78:9A:BC]
|
||||||
|
# virtio pci net device
|
||||||
|
--netdev tap,id=netdevid,ifname=host_dev_name[,mac=12:34:56:78:9A:BC]
|
||||||
|
--device virtio-net-pci,netdev=netdevid,id=netid,bus=pcie.0,addr=0x2.0x0[,iothread=iothread1]
|
||||||
|
+-netdev tap,id=netdevid,ifname=host_dev_name
|
||||||
|
+-device virtio-net-pci,netdev=netdevid,id=netid,bus=pcie.0,addr=0x2.0x0[,iothread=iothread1,mac=12:34:56:78:9A:BC]
|
||||||
|
```
|
||||||
|
|
||||||
|
StratoVirt also supports vhost-net to get a higher performance in network. It can be set by
|
||||||
|
@@ -222,11 +223,11 @@ given when `vhost=on`, StratoVirt gets it by opening "/dev/vhost-net" automatica
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# virtio mmio net device
|
||||||
|
--netdev tap,id=netdevid,ifname=host_dev_name,vhost=on[,mac=12:34:56:78:9A:BC,vhostfd=2]
|
||||||
|
--device virtio-net-device,netdev=netdevid,id=netid[,iothread=iothread1]
|
||||||
|
+-netdev tap,id=netdevid,ifname=host_dev_name,vhost=on[,vhostfd=2]
|
||||||
|
+-device virtio-net-device,netdev=netdevid,id=netid[,iothread=iothread1,mac=12:34:56:78:9A:BC]
|
||||||
|
# virtio pci net device
|
||||||
|
--netdev tap,id=netdevid,ifname=host_dev_name,vhost=on[,mac=12:34:56:78:9A:BC,vhostfd=2]
|
||||||
|
--device virtio-net-pci,netdev=netdevid,id=netid,bus=pcie.0,addr=0x2.0x0[,iothread=iothread1]
|
||||||
|
+-netdev tap,id=netdevid,ifname=host_dev_name,vhost=on[,vhostfd=2]
|
||||||
|
+-device virtio-net-pci,netdev=netdevid,id=netid,bus=pcie.0,addr=0x2.0x0[,iothread=iothread1,mac=12:34:56:78:9A:BC]
|
||||||
|
```
|
||||||
|
|
||||||
|
*How to set a tap device?*
|
||||||
|
@@ -290,10 +291,11 @@ If you want use it, need:
|
||||||
|
|
||||||
|
And `modprobe vhost_vsock` in the host.
|
||||||
|
|
||||||
|
-Two properties can be set for virtio vsock device.
|
||||||
|
+Three properties can be set for virtio vsock device.
|
||||||
|
|
||||||
|
* vsock_id: unique device-id in StratoVirt.
|
||||||
|
* guest_cid: a unique Context-ID in host to each guest, it should satisfy `3<=guest_cid<u32:MAX`.
|
||||||
|
+* vhostfd: fd of vsock device. (optional).
|
||||||
|
|
||||||
|
For vhost-vsock-pci, two more properties are required.
|
||||||
|
* bus: name of bus which to attach.
|
||||||
|
diff --git a/docs/interconnect_with_libvirt.md b/docs/interconnect_with_libvirt.md
|
||||||
|
index d5205ed..2dee64b 100644
|
||||||
|
--- a/docs/interconnect_with_libvirt.md
|
||||||
|
+++ b/docs/interconnect_with_libvirt.md
|
||||||
|
@@ -34,7 +34,7 @@ Optional value of `arch` are: `aarch64` and `x86_64`. On X86 platform, supported
|
||||||
|
`/path/to/standard_vm_kernel` is the path of standard vm kernel.
|
||||||
|
```
|
||||||
|
<kernel>/path/to/standard_vm_kernel</kernel>
|
||||||
|
-<cmdline>console=ttys0 root=/dev/vda reboot=k panic=1 rw</cmdline>
|
||||||
|
+<cmdline>console=ttyS0 root=/dev/vda reboot=k panic=1 rw</cmdline>
|
||||||
|
```
|
||||||
|
|
||||||
|
- feature:
|
||||||
|
@@ -77,7 +77,7 @@ Pflash can be added by the following config.
|
||||||
|
`/path/to/pflash` is the path of pflash file.
|
||||||
|
```
|
||||||
|
<loader readonly='yes' type='pflash'>/path/to/pflash</loader>
|
||||||
|
-<nvram template='/path/to/OVMF_VARS'/>/path/to/OVMF_VARS</nvram>
|
||||||
|
+<nvram template='/path/to/OVMF_VARS'>/path/to/OVMF_VARS</nvram>
|
||||||
|
```
|
||||||
|
|
||||||
|
- iothread
|
||||||
|
@@ -144,7 +144,7 @@ To use `virsh console` command, the virtio console with redirect `pty` should be
|
||||||
|
<controller type='pci' index='5' model='pcie-root-port' />
|
||||||
|
<rng model='virtio'>
|
||||||
|
<rate period='1000' bytes='1234'/>
|
||||||
|
- <backend model='random'>/dev/random</backend>
|
||||||
|
+ <backend model='random'>/path/to/random_file</backend>
|
||||||
|
<address type='pci' domain='0x000' bus='0x05' slot='0x00' function='0x00'/>
|
||||||
|
</rng>
|
||||||
|
```
|
||||||
|
@@ -153,7 +153,7 @@ To use `virsh console` command, the virtio console with redirect `pty` should be
|
||||||
|
|
||||||
|
```
|
||||||
|
<controller type='pci' index='7' model='pcie-root-port' />
|
||||||
|
-<hostdev model='subsystem' type='pci' managed='yes'>
|
||||||
|
+<hostdev mode='subsystem' type='pci' managed='yes'>
|
||||||
|
<driver name='vfio'/>
|
||||||
|
<source>
|
||||||
|
<address domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
|
||||||
|
diff --git a/docs/stratovirt_aarch64.xml b/docs/stratovirt_aarch64.xml
|
||||||
|
index 9bbf8d2..fa37d2b 100644
|
||||||
|
--- a/docs/stratovirt_aarch64.xml
|
||||||
|
+++ b/docs/stratovirt_aarch64.xml
|
||||||
|
@@ -13,7 +13,7 @@
|
||||||
|
<os>
|
||||||
|
<type arch='aarch64' machine='virt'>hvm</type>
|
||||||
|
<kernel>/path/to/standard_vm_kernel</kernel>
|
||||||
|
- <cmdline>console=ttys0 root=/dev/vda reboot=k panic=1 rw</cmdline>
|
||||||
|
+ <cmdline>console=ttyAMA0 root=/dev/vda reboot=k panic=1 rw</cmdline>
|
||||||
|
<loader readonly='yes' type='pflash'>/path/to/pflash</loader>
|
||||||
|
</os>
|
||||||
|
<features>
|
||||||
|
@@ -24,8 +24,8 @@
|
||||||
|
<emulator>/path/to/StratoVirt_binary_file</emulator>
|
||||||
|
<controller type='pci' index='0' model='pcie-root'/>
|
||||||
|
<!-- block -->
|
||||||
|
- <disk type='file' device='disk' iothread='1'>
|
||||||
|
- <driver name='qemu' type='raw'/>
|
||||||
|
+ <disk type='file' device='disk'>
|
||||||
|
+ <driver name='qemu' type='raw' iothread='1'/>
|
||||||
|
<source file='/path/to/rootfs'/>
|
||||||
|
<target dev='hda' bus='virtio'/>
|
||||||
|
<address type='pci' domain='0x000' bus='0x00' slot='0x01' function='0x00'/>
|
||||||
|
@@ -58,7 +58,7 @@
|
||||||
|
<!-- rng -->
|
||||||
|
<rng model='virtio'>
|
||||||
|
<rate period='1000' bytes='1234'/>
|
||||||
|
- <backend model='random'>/dev/random</backend>
|
||||||
|
+ <backend model='random'>/path/to/random_file</backend>
|
||||||
|
<address type='pci' domain='0x000' bus='0x00' slot='0x05' function='0x00'/>
|
||||||
|
</rng>
|
||||||
|
<!-- vsock -->
|
||||||
|
@@ -67,7 +67,7 @@
|
||||||
|
<address type='pci' domain='0x000' bus='0x00' slot='0x06' function='0x00'/>
|
||||||
|
</vsock>
|
||||||
|
<!-- vfio -->
|
||||||
|
- <hostdev model='subsystem' type='pci' managed='yes'>
|
||||||
|
+ <hostdev mode='subsystem' type='pci' managed='yes'>
|
||||||
|
<driver name='vfio'/>
|
||||||
|
<source>
|
||||||
|
<address domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
|
||||||
|
diff --git a/docs/stratovirt_x86.xml b/docs/stratovirt_x86.xml
|
||||||
|
index b561a5f..68069c0 100644
|
||||||
|
--- a/docs/stratovirt_x86.xml
|
||||||
|
+++ b/docs/stratovirt_x86.xml
|
||||||
|
@@ -13,9 +13,9 @@
|
||||||
|
<os>
|
||||||
|
<type arch='x86_64' machine='q35'>hvm</type>
|
||||||
|
<kernel>/path/to/standard_vm_kernel</kernel>
|
||||||
|
- <cmdline>console=ttys0 root=/dev/vda reboot=k panic=1 rw</cmdline>
|
||||||
|
+ <cmdline>console=hvc0 root=/dev/vda reboot=k panic=1 rw</cmdline>
|
||||||
|
<loader readonly='yes' type='pflash'>/path/to/pflash</loader>
|
||||||
|
- <nvram template='/path/to/OVMF_VARS'/>/path/to/OVMF_VARS</nvram>
|
||||||
|
+ <nvram template='/path/to/OVMF_VARS'>/path/to/OVMF_VARS</nvram>
|
||||||
|
</os>
|
||||||
|
<features>
|
||||||
|
<acpi/>
|
||||||
|
@@ -32,8 +32,8 @@
|
||||||
|
<controller type='pci' index='6' model='pcie-root-port' />
|
||||||
|
<controller type='pci' index='7' model='pcie-root-port' />
|
||||||
|
<!-- block -->
|
||||||
|
- <disk type='file' device='disk' iothread='1'>
|
||||||
|
- <driver name='qemu' type='raw'/>
|
||||||
|
+ <disk type='file' device='disk'>
|
||||||
|
+ <driver name='qemu' type='raw' iothread='1'/>
|
||||||
|
<source file='/path/to/rootfs'/>
|
||||||
|
<target dev='hda' bus='virtio'/>
|
||||||
|
<iotune>
|
||||||
|
@@ -66,7 +66,7 @@
|
||||||
|
<!-- rng -->
|
||||||
|
<rng model='virtio'>
|
||||||
|
<rate period='1000' bytes='1234'/>
|
||||||
|
- <backend model='random'>/dev/random</backend>
|
||||||
|
+ <backend model='random'>/path/to/random_file</backend>
|
||||||
|
<address type='pci' domain='0x000' bus='0x05' slot='0x00' function='0x00'/>
|
||||||
|
</rng>
|
||||||
|
<!-- vsock -->
|
||||||
|
@@ -75,7 +75,7 @@
|
||||||
|
<address type='pci' domain='0x000' bus='0x06' slot='0x00' function='0x00'/>
|
||||||
|
</vsock>
|
||||||
|
<!-- vfio -->
|
||||||
|
- <hostdev model='subsystem' type='pci' managed='yes'>
|
||||||
|
+ <hostdev mode='subsystem' type='pci' managed='yes'>
|
||||||
|
<driver name='vfio'/>
|
||||||
|
<source>
|
||||||
|
<address domain='0x0000' bus='0x03' slot='0x00' function='0x0'/>
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
146
machine-add-init_multifunction-function-to-init-mult.patch
Normal file
146
machine-add-init_multifunction-function-to-init-mult.patch
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
From 7e9ea7ef5f9673d40cf64fcd306c879028d39c29 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ming Yang <yangming73@huawei.com>
|
||||||
|
Date: Sat, 28 Aug 2021 10:32:38 +0800
|
||||||
|
Subject: [PATCH 09/10] machine: add init_multifunction function to init
|
||||||
|
multifunction.
|
||||||
|
|
||||||
|
Signed-off-by: Xinle.Guo <guoxinle1@huawei.com>
|
||||||
|
Signed-off-by: Ming Yang <yangming73@huawei.com>
|
||||||
|
---
|
||||||
|
pci/src/config.rs | 2 ++
|
||||||
|
pci/src/lib.rs | 88 ++++++++++++++++++++++++++++++++++++++++++++++-
|
||||||
|
2 files changed, 89 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/pci/src/config.rs b/pci/src/config.rs
|
||||||
|
index 873fe7a..812001d 100644
|
||||||
|
--- a/pci/src/config.rs
|
||||||
|
+++ b/pci/src/config.rs
|
||||||
|
@@ -27,6 +27,8 @@ pub const PCI_CONFIG_SPACE_SIZE: usize = 256;
|
||||||
|
pub const PCIE_CONFIG_SPACE_SIZE: usize = 4096;
|
||||||
|
/// Size in bytes of dword.
|
||||||
|
pub const REG_SIZE: usize = 4;
|
||||||
|
+/// Max number of function.
|
||||||
|
+pub const MAX_FUNC: u8 = 8;
|
||||||
|
|
||||||
|
/// Vendor ID Register.
|
||||||
|
pub const VENDOR_ID: u8 = 0x0;
|
||||||
|
diff --git a/pci/src/lib.rs b/pci/src/lib.rs
|
||||||
|
index 8f11ad4..dfcbd71 100644
|
||||||
|
--- a/pci/src/lib.rs
|
||||||
|
+++ b/pci/src/lib.rs
|
||||||
|
@@ -46,11 +46,15 @@ pub mod msix;
|
||||||
|
mod root_port;
|
||||||
|
|
||||||
|
pub use bus::PciBus;
|
||||||
|
+use config::{HEADER_TYPE, HEADER_TYPE_MULTIFUNC, MAX_FUNC};
|
||||||
|
pub use host::PciHost;
|
||||||
|
pub use msix::init_msix;
|
||||||
|
pub use root_port::RootPort;
|
||||||
|
|
||||||
|
-use std::mem::size_of;
|
||||||
|
+use std::{
|
||||||
|
+ mem::size_of,
|
||||||
|
+ sync::{Mutex, Weak},
|
||||||
|
+};
|
||||||
|
|
||||||
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
|
|
||||||
|
@@ -105,6 +109,18 @@ le_read!(le_read_u16, read_u16, u16);
|
||||||
|
le_read!(le_read_u32, read_u32, u32);
|
||||||
|
le_read!(le_read_u64, read_u64, u64);
|
||||||
|
|
||||||
|
+pub fn pci_devfn(slot: u8, func: u8) -> u8 {
|
||||||
|
+ ((slot & 0x1f) << 3) | (func & 0x07)
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+pub fn pci_slot(devfn: u8) -> u8 {
|
||||||
|
+ devfn >> 3 & 0x1f
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+pub fn pci_func(devfn: u8) -> u8 {
|
||||||
|
+ devfn & 0x07
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
pub trait PciDevOps: Send {
|
||||||
|
/// Init writable bit mask.
|
||||||
|
fn init_write_mask(&mut self) -> Result<()>;
|
||||||
|
@@ -150,6 +166,76 @@ pub trait PciDevOps: Send {
|
||||||
|
fn name(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/// Init multifunction for pci devices.
|
||||||
|
+///
|
||||||
|
+/// # Arguments
|
||||||
|
+///
|
||||||
|
+/// * `multifunction` - Whether to open multifunction.
|
||||||
|
+/// * `config` - Configuration space of pci devices.
|
||||||
|
+/// * `devfn` - Devfn number.
|
||||||
|
+/// * `parent_bus` - Parent bus of pci devices.
|
||||||
|
+pub fn init_multifunction(
|
||||||
|
+ multifunction: bool,
|
||||||
|
+ config: &mut Vec<u8>,
|
||||||
|
+ devfn: u8,
|
||||||
|
+ parent_bus: Weak<Mutex<PciBus>>,
|
||||||
|
+) -> Result<()> {
|
||||||
|
+ let mut header_type =
|
||||||
|
+ le_read_u16(&config, HEADER_TYPE as usize)? & (!HEADER_TYPE_MULTIFUNC as u16);
|
||||||
|
+ if multifunction {
|
||||||
|
+ header_type |= HEADER_TYPE_MULTIFUNC as u16;
|
||||||
|
+ }
|
||||||
|
+ le_write_u16(config, HEADER_TYPE as usize, header_type as u16)?;
|
||||||
|
+
|
||||||
|
+ // Allow two ways of multifunction bit:
|
||||||
|
+ // 1. The multifunction bit of all devices must be set;
|
||||||
|
+ // 2. Function 0 must set the bit, the rest function (1~7) is allowed to
|
||||||
|
+ // leave the bit to 0.
|
||||||
|
+ let slot = pci_slot(devfn);
|
||||||
|
+ let bus = parent_bus.upgrade().unwrap();
|
||||||
|
+ let locked_bus = bus.lock().unwrap();
|
||||||
|
+ if pci_func(devfn) != 0 {
|
||||||
|
+ let pci_dev = locked_bus.devices.get(&pci_devfn(slot, 0));
|
||||||
|
+ if pci_dev.is_none() {
|
||||||
|
+ return Ok(());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ let mut data = vec![0_u8; 2];
|
||||||
|
+ pci_dev
|
||||||
|
+ .unwrap()
|
||||||
|
+ .lock()
|
||||||
|
+ .unwrap()
|
||||||
|
+ .read_config(HEADER_TYPE as usize, data.as_mut_slice());
|
||||||
|
+ if LittleEndian::read_u16(&data) & HEADER_TYPE_MULTIFUNC as u16 == 0 {
|
||||||
|
+ // Function 0 should set multifunction bit.
|
||||||
|
+ bail!(
|
||||||
|
+ "PCI: single function device can't be populated in bus {} function {}.{}",
|
||||||
|
+ &locked_bus.name,
|
||||||
|
+ slot,
|
||||||
|
+ devfn & 0x07
|
||||||
|
+ );
|
||||||
|
+ }
|
||||||
|
+ return Ok(());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if multifunction {
|
||||||
|
+ return Ok(());
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ // If function 0 is set to single function, the rest function should be None.
|
||||||
|
+ for func in 1..MAX_FUNC {
|
||||||
|
+ if locked_bus.devices.get(&pci_devfn(slot, func)).is_some() {
|
||||||
|
+ bail!(
|
||||||
|
+ "PCI: {}.0 indicates single function, but {}.{} is already populated",
|
||||||
|
+ slot,
|
||||||
|
+ slot,
|
||||||
|
+ func
|
||||||
|
+ );
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ Ok(())
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/// Check whether two regions overlap with each other.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
636
machine-add-realization-for-multifunction.patch
Normal file
636
machine-add-realization-for-multifunction.patch
Normal file
@ -0,0 +1,636 @@
|
|||||||
|
From 4e8272a490b9901fc92fbaad1c10fee6d8b43fe3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ming Yang <yangming73@huawei.com>
|
||||||
|
Date: Sat, 28 Aug 2021 10:33:25 +0800
|
||||||
|
Subject: [PATCH 10/10] machine: add realization for multifunction.
|
||||||
|
|
||||||
|
1. Add realization for multifunction of virtio pci devices,
|
||||||
|
vfio pci devices and pcie-root-port.
|
||||||
|
2. Add docs for multifunction.
|
||||||
|
|
||||||
|
Signed-off-by: Xinle.Guo <guoxinle1@huawei.com>
|
||||||
|
Signed-off-by: Ming Yang <yangming73@huawei.com>
|
||||||
|
---
|
||||||
|
docs/config_guidebook.md | 14 ++--
|
||||||
|
machine/src/lib.rs | 93 +++++++++++++++++-----
|
||||||
|
machine/src/standard_vm/x86_64/ich9_lpc.rs | 10 ++-
|
||||||
|
pci/src/host.rs | 6 +-
|
||||||
|
pci/src/root_port.rs | 29 +++++--
|
||||||
|
vfio/src/vfio_pci.rs | 31 ++++++--
|
||||||
|
virtio/src/virtio_pci.rs | 53 +++++++++++-
|
||||||
|
7 files changed, 192 insertions(+), 44 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/docs/config_guidebook.md b/docs/config_guidebook.md
|
||||||
|
index b1f7b08..946d155 100644
|
||||||
|
--- a/docs/config_guidebook.md
|
||||||
|
+++ b/docs/config_guidebook.md
|
||||||
|
@@ -212,7 +212,7 @@ is a single function device, the function number should be set to zero.
|
||||||
|
-device virtio-net-device,netdev=netdevid,id=netid[,iothread=iothread1,mac=12:34:56:78:9A:BC]
|
||||||
|
# virtio pci net device
|
||||||
|
-netdev tap,id=netdevid,ifname=host_dev_name
|
||||||
|
--device virtio-net-pci,netdev=netdevid,id=netid,bus=pcie.0,addr=0x2.0x0[,iothread=iothread1,mac=12:34:56:78:9A:BC]
|
||||||
|
+-device virtio-net-pci,netdev=netdevid,id=netid,bus=pcie.0,addr=0x2.0x0[,multifunction=on,iothread=iothread1,mac=12:34:56:78:9A:BC]
|
||||||
|
```
|
||||||
|
|
||||||
|
StratoVirt also supports vhost-net to get a higher performance in network. It can be set by
|
||||||
|
@@ -227,7 +227,7 @@ given when `vhost=on`, StratoVirt gets it by opening "/dev/vhost-net" automatica
|
||||||
|
-device virtio-net-device,netdev=netdevid,id=netid[,iothread=iothread1,mac=12:34:56:78:9A:BC]
|
||||||
|
# virtio pci net device
|
||||||
|
-netdev tap,id=netdevid,ifname=host_dev_name,vhost=on[,vhostfd=2]
|
||||||
|
--device virtio-net-pci,netdev=netdevid,id=netid,bus=pcie.0,addr=0x2.0x0[,iothread=iothread1,mac=12:34:56:78:9A:BC]
|
||||||
|
+-device virtio-net-pci,netdev=netdevid,id=netid,bus=pcie.0,addr=0x2.0x0[,multifunction=on,iothread=iothread1,mac=12:34:56:78:9A:BC]
|
||||||
|
```
|
||||||
|
|
||||||
|
*How to set a tap device?*
|
||||||
|
@@ -273,7 +273,7 @@ of device and the second one represents function number of it.
|
||||||
|
-device virtconsole,chardev=virtioconsole1,id=console_id
|
||||||
|
|
||||||
|
# virtio pci device
|
||||||
|
--device virtio-serial-pci,bus=pcie.0,addr=0x1[,id=virtio-serial0]
|
||||||
|
+-device virtio-serial-pci,bus=pcie.0,addr=0x1.0x0[,multifunction=on,id=virtio-serial0]
|
||||||
|
-chardev socket,path=socket_path,id=virtioconsole1,server,nowait
|
||||||
|
-device virtconsole,chardev=virtioconsole1,id=console_id
|
||||||
|
```
|
||||||
|
@@ -307,7 +307,7 @@ of device and the second one represents function number of it.
|
||||||
|
-device vhost-vsock-device,id=vsock_id,guest-cid=3
|
||||||
|
|
||||||
|
# virtio pci device.
|
||||||
|
--device vhost-vsock-pci,id=vsock_id,guest-cid=3,bus=pcie.0,addr=0x1.0x0
|
||||||
|
+-device vhost-vsock-pci,id=vsock_id,guest-cid=3,bus=pcie.0,addr=0x1.0x0[,multifunction=on]
|
||||||
|
```
|
||||||
|
|
||||||
|
*You can only set one virtio vsock device for one VM.*
|
||||||
|
@@ -363,7 +363,7 @@ of device and the second one represents function number of it.
|
||||||
|
# virtio mmio balloon device
|
||||||
|
-device virtio-balloon-device,deflate-on-oom=true
|
||||||
|
# virtio pci balloon device
|
||||||
|
--device virtio-balloon-pci,bus=pcie.0,addr=0x4.0x0,deflate-on-oom=true
|
||||||
|
+-device virtio-balloon-pci,bus=pcie.0,addr=0x4.0x0,deflate-on-oom=true[,multifunction=on]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.8 Virtio-rng
|
||||||
|
@@ -396,7 +396,7 @@ single function device, the function number should be set to zero.
|
||||||
|
-device virtio-rng-device,rng=objrng0,max-bytes=1234,period=1000
|
||||||
|
# virtio pci rng device
|
||||||
|
-object rng-random,id=objrng0,filename=/path/to/random_file
|
||||||
|
--device virtio-rng-pci,rng=objrng0,max-bytes=1234,period=1000,bus=pcie.0,addr=0x1
|
||||||
|
+-device virtio-rng-pci,rng=objrng0,max-bytes=1234,period=1000,bus=pcie.0,addr=0x1.0x0[,multifunction=on]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.9 PCIe root port
|
||||||
|
@@ -458,7 +458,7 @@ Four properties are supported for VFIO device
|
||||||
|
* addr: including slot number and function number.
|
||||||
|
```shell
|
||||||
|
# cmdline
|
||||||
|
--device vfio-pci,host=0000:1a:00.3,id=net,bus=pcie.0,addr=0x03
|
||||||
|
+-device vfio-pci,host=0000:1a:00.3,id=net,bus=pcie.0,addr=0x03.0x0[,multifunction=on]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.12 Chardev
|
||||||
|
diff --git a/machine/src/lib.rs b/machine/src/lib.rs
|
||||||
|
index 22aed89..23394ef 100644
|
||||||
|
--- a/machine/src/lib.rs
|
||||||
|
+++ b/machine/src/lib.rs
|
||||||
|
@@ -123,9 +123,9 @@ use devices::InterruptController;
|
||||||
|
use hypervisor::KVM_FDS;
|
||||||
|
use kvm_ioctls::VcpuFd;
|
||||||
|
use machine_manager::config::{
|
||||||
|
- get_pci_bdf, parse_balloon, parse_blk, parse_net, parse_rng_dev, parse_root_port, parse_vfio,
|
||||||
|
- parse_virtconsole, parse_virtio_serial, parse_vsock, MachineMemConfig, PFlashConfig, PciBdf,
|
||||||
|
- SerialConfig, VfioConfig, VmConfig,
|
||||||
|
+ get_multi_function, get_pci_bdf, parse_balloon, parse_blk, parse_net, parse_rng_dev,
|
||||||
|
+ parse_root_port, parse_vfio, parse_virtconsole, parse_virtio_serial, parse_vsock,
|
||||||
|
+ MachineMemConfig, PFlashConfig, PciBdf, SerialConfig, VfioConfig, VmConfig,
|
||||||
|
};
|
||||||
|
use machine_manager::event_loop::EventLoop;
|
||||||
|
use machine_manager::machine::{KvmVmState, MachineInterface};
|
||||||
|
@@ -297,9 +297,16 @@ pub trait MachineOps {
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
let bdf = get_pci_bdf(cfg_args)?;
|
||||||
|
+ let multi_func = get_multi_function(cfg_args)?;
|
||||||
|
let (devfn, parent_bus) = self.get_devfn_and_parent_bus(&bdf)?;
|
||||||
|
- let virtio_pci_device =
|
||||||
|
- VirtioPciDevice::new(device_cfg.id, devfn, sys_mem, vsock.clone(), parent_bus);
|
||||||
|
+ let virtio_pci_device = VirtioPciDevice::new(
|
||||||
|
+ device_cfg.id,
|
||||||
|
+ devfn,
|
||||||
|
+ sys_mem,
|
||||||
|
+ vsock.clone(),
|
||||||
|
+ parent_bus,
|
||||||
|
+ multi_func,
|
||||||
|
+ );
|
||||||
|
virtio_pci_device
|
||||||
|
.realize()
|
||||||
|
.chain_err(|| "Failed to add virtio pci vsock device")?;
|
||||||
|
@@ -342,9 +349,11 @@ pub trait MachineOps {
|
||||||
|
} else {
|
||||||
|
let name = device_cfg.id;
|
||||||
|
let bdf = get_pci_bdf(cfg_args)?;
|
||||||
|
+ let multi_func = get_multi_function(cfg_args)?;
|
||||||
|
let (devfn, parent_bus) = self.get_devfn_and_parent_bus(&bdf)?;
|
||||||
|
let sys_mem = self.get_sys_mem().clone();
|
||||||
|
- let virtio_pci_device = VirtioPciDevice::new(name, devfn, sys_mem, balloon, parent_bus);
|
||||||
|
+ let virtio_pci_device =
|
||||||
|
+ VirtioPciDevice::new(name, devfn, sys_mem, balloon, parent_bus, multi_func);
|
||||||
|
virtio_pci_device
|
||||||
|
.realize()
|
||||||
|
.chain_err(|| "Failed to add virtio pci balloon device")?;
|
||||||
|
@@ -373,16 +382,24 @@ pub trait MachineOps {
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
let name = device_cfg.id;
|
||||||
|
- let bdf = if let Some(virtio_serial_info) = &vm_config.virtio_serial {
|
||||||
|
- // Reasonable, because for virtio-serial-pci device, the bdf has been checked.
|
||||||
|
- virtio_serial_info.pci_bdf.clone().unwrap()
|
||||||
|
+ let virtio_serial_info = if let Some(serial_info) = &vm_config.virtio_serial {
|
||||||
|
+ serial_info
|
||||||
|
} else {
|
||||||
|
- bail!("No pci BDF configured for virtconsole");
|
||||||
|
+ bail!("No virtio-serial-pci device configured for virtconsole");
|
||||||
|
};
|
||||||
|
+ // Reasonable, because for virtio-serial-pci device, the bdf has been checked.
|
||||||
|
+ let bdf = virtio_serial_info.pci_bdf.clone().unwrap();
|
||||||
|
+ let multi_func = virtio_serial_info.multifunction;
|
||||||
|
let (devfn, parent_bus) = self.get_devfn_and_parent_bus(&bdf)?;
|
||||||
|
let sys_mem = self.get_sys_mem().clone();
|
||||||
|
- let virtio_pci_device =
|
||||||
|
- VirtioPciDevice::new(name, devfn, sys_mem, console.clone(), parent_bus);
|
||||||
|
+ let virtio_pci_device = VirtioPciDevice::new(
|
||||||
|
+ name,
|
||||||
|
+ devfn,
|
||||||
|
+ sys_mem,
|
||||||
|
+ console.clone(),
|
||||||
|
+ parent_bus,
|
||||||
|
+ multi_func,
|
||||||
|
+ );
|
||||||
|
virtio_pci_device
|
||||||
|
.realize()
|
||||||
|
.chain_err(|| "Failed to add virtio pci console device")?;
|
||||||
|
@@ -416,10 +433,17 @@ pub trait MachineOps {
|
||||||
|
.chain_err(|| "Failed to add virtio mmio rng device")?;
|
||||||
|
} else {
|
||||||
|
let bdf = get_pci_bdf(cfg_args)?;
|
||||||
|
+ let multi_func = get_multi_function(cfg_args)?;
|
||||||
|
let (devfn, parent_bus) = self.get_devfn_and_parent_bus(&bdf)?;
|
||||||
|
let sys_mem = self.get_sys_mem().clone();
|
||||||
|
- let vitio_pci_device =
|
||||||
|
- VirtioPciDevice::new(device_cfg.id, devfn, sys_mem, rng_dev.clone(), parent_bus);
|
||||||
|
+ let vitio_pci_device = VirtioPciDevice::new(
|
||||||
|
+ device_cfg.id,
|
||||||
|
+ devfn,
|
||||||
|
+ sys_mem,
|
||||||
|
+ rng_dev.clone(),
|
||||||
|
+ parent_bus,
|
||||||
|
+ multi_func,
|
||||||
|
+ );
|
||||||
|
vitio_pci_device
|
||||||
|
.realize()
|
||||||
|
.chain_err(|| "Failed to add pci rng device")?;
|
||||||
|
@@ -434,6 +458,7 @@ pub trait MachineOps {
|
||||||
|
|
||||||
|
fn add_virtio_pci_blk(&mut self, vm_config: &mut VmConfig, cfg_args: &str) -> Result<()> {
|
||||||
|
let bdf = get_pci_bdf(cfg_args)?;
|
||||||
|
+ let multi_func = get_multi_function(cfg_args)?;
|
||||||
|
let (devfn, parent_bus) = self.get_devfn_and_parent_bus(&bdf)?;
|
||||||
|
let sys_mem = self.get_sys_mem();
|
||||||
|
let device_cfg = parse_blk(vm_config, cfg_args)?;
|
||||||
|
@@ -444,6 +469,7 @@ pub trait MachineOps {
|
||||||
|
sys_mem.clone(),
|
||||||
|
device.clone(),
|
||||||
|
parent_bus,
|
||||||
|
+ multi_func,
|
||||||
|
);
|
||||||
|
pcidev
|
||||||
|
.realize()
|
||||||
|
@@ -454,19 +480,34 @@ pub trait MachineOps {
|
||||||
|
|
||||||
|
fn add_virtio_pci_net(&mut self, vm_config: &mut VmConfig, cfg_args: &str) -> Result<()> {
|
||||||
|
let bdf = get_pci_bdf(cfg_args)?;
|
||||||
|
+ let multi_func = get_multi_function(cfg_args)?;
|
||||||
|
let (devfn, parent_bus) = self.get_devfn_and_parent_bus(&bdf)?;
|
||||||
|
let sys_mem = self.get_sys_mem();
|
||||||
|
let device_cfg = parse_net(vm_config, cfg_args)?;
|
||||||
|
let virtio_pci_device = if device_cfg.vhost_type.is_some() {
|
||||||
|
let device = Arc::new(Mutex::new(VhostKern::Net::new(&device_cfg, &sys_mem)));
|
||||||
|
- VirtioPciDevice::new(device_cfg.id, devfn, sys_mem.clone(), device, parent_bus)
|
||||||
|
+ VirtioPciDevice::new(
|
||||||
|
+ device_cfg.id,
|
||||||
|
+ devfn,
|
||||||
|
+ sys_mem.clone(),
|
||||||
|
+ device,
|
||||||
|
+ parent_bus,
|
||||||
|
+ multi_func,
|
||||||
|
+ )
|
||||||
|
} else {
|
||||||
|
let device = Arc::new(Mutex::new(virtio::Net::new(device_cfg.clone())));
|
||||||
|
MigrationManager::register_device_instance_mutex(
|
||||||
|
VirtioNetState::descriptor(),
|
||||||
|
device.clone(),
|
||||||
|
);
|
||||||
|
- VirtioPciDevice::new(device_cfg.id, devfn, sys_mem.clone(), device, parent_bus)
|
||||||
|
+ VirtioPciDevice::new(
|
||||||
|
+ device_cfg.id,
|
||||||
|
+ devfn,
|
||||||
|
+ sys_mem.clone(),
|
||||||
|
+ device,
|
||||||
|
+ parent_bus,
|
||||||
|
+ multi_func,
|
||||||
|
+ )
|
||||||
|
};
|
||||||
|
virtio_pci_device
|
||||||
|
.realize()
|
||||||
|
@@ -484,9 +525,17 @@ pub trait MachineOps {
|
||||||
|
let path = "/sys/bus/pci/devices/".to_string() + &device_cfg.host;
|
||||||
|
let name = device_cfg.id;
|
||||||
|
let bdf = get_pci_bdf(cfg_args)?;
|
||||||
|
+ let multi_func = get_multi_function(cfg_args)?;
|
||||||
|
let (devfn, parent_bus) = self.get_devfn_and_parent_bus(&bdf)?;
|
||||||
|
- let vfio_pci_dev = VfioPciDevice::new(Path::new(&path), container, devfn, name, parent_bus)
|
||||||
|
- .chain_err(|| "Failed to create vfio pci device")?;
|
||||||
|
+ let vfio_pci_dev = VfioPciDevice::new(
|
||||||
|
+ Path::new(&path),
|
||||||
|
+ container,
|
||||||
|
+ devfn,
|
||||||
|
+ name,
|
||||||
|
+ parent_bus,
|
||||||
|
+ multi_func,
|
||||||
|
+ )
|
||||||
|
+ .chain_err(|| "Failed to create vfio pci device")?;
|
||||||
|
|
||||||
|
VfioPciDevice::realize(vfio_pci_dev).chain_err(|| "Failed to realize vfio pci device")?;
|
||||||
|
Ok(())
|
||||||
|
@@ -513,7 +562,13 @@ pub trait MachineOps {
|
||||||
|
if PciBus::find_bus_by_name(&bus, &device_cfg.id).is_some() {
|
||||||
|
bail!("ID {} already exists.");
|
||||||
|
}
|
||||||
|
- let rootport = RootPort::new(device_cfg.id, devfn, device_cfg.port, parent_bus);
|
||||||
|
+ let rootport = RootPort::new(
|
||||||
|
+ device_cfg.id,
|
||||||
|
+ devfn,
|
||||||
|
+ device_cfg.port,
|
||||||
|
+ parent_bus,
|
||||||
|
+ device_cfg.multifunction,
|
||||||
|
+ );
|
||||||
|
rootport
|
||||||
|
.realize()
|
||||||
|
.chain_err(|| "Failed to add pci root port")?;
|
||||||
|
diff --git a/machine/src/standard_vm/x86_64/ich9_lpc.rs b/machine/src/standard_vm/x86_64/ich9_lpc.rs
|
||||||
|
index b5d7524..0b1b3d5 100644
|
||||||
|
--- a/machine/src/standard_vm/x86_64/ich9_lpc.rs
|
||||||
|
+++ b/machine/src/standard_vm/x86_64/ich9_lpc.rs
|
||||||
|
@@ -15,7 +15,10 @@ use std::sync::{Arc, Mutex, Weak};
|
||||||
|
use acpi::AcpiPMTimer;
|
||||||
|
use address_space::{AddressSpace, GuestAddress, Region, RegionOps};
|
||||||
|
use error_chain::ChainedError;
|
||||||
|
-use pci::config::{PciConfig, DEVICE_ID, PCI_CONFIG_SPACE_SIZE, SUB_CLASS_CODE, VENDOR_ID};
|
||||||
|
+use pci::config::{
|
||||||
|
+ PciConfig, DEVICE_ID, HEADER_TYPE, HEADER_TYPE_BRIDGE, HEADER_TYPE_MULTIFUNC,
|
||||||
|
+ PCI_CONFIG_SPACE_SIZE, SUB_CLASS_CODE, VENDOR_ID,
|
||||||
|
+};
|
||||||
|
use pci::errors::Result as PciResult;
|
||||||
|
use pci::{le_write_u16, le_write_u32, ranges_overlap, PciBus, PciDevOps};
|
||||||
|
use util::byte_code::ByteCode;
|
||||||
|
@@ -96,6 +99,11 @@ impl PciDevOps for LPCBridge {
|
||||||
|
CLASS_CODE_ISA_BRIDGE,
|
||||||
|
)?;
|
||||||
|
le_write_u32(&mut self.config.write_mask, PM_BASE_OFFSET as usize, 0xff80)?;
|
||||||
|
+ le_write_u16(
|
||||||
|
+ &mut self.config.config,
|
||||||
|
+ HEADER_TYPE as usize,
|
||||||
|
+ (HEADER_TYPE_BRIDGE | HEADER_TYPE_MULTIFUNC) as u16,
|
||||||
|
+ )?;
|
||||||
|
|
||||||
|
let parent_bus = self.parent_bus.clone();
|
||||||
|
parent_bus
|
||||||
|
diff --git a/pci/src/host.rs b/pci/src/host.rs
|
||||||
|
index 19bbee7..153ba14 100644
|
||||||
|
--- a/pci/src/host.rs
|
||||||
|
+++ b/pci/src/host.rs
|
||||||
|
@@ -440,7 +440,7 @@ pub mod tests {
|
||||||
|
let root_bus = Arc::downgrade(&pci_host.lock().unwrap().root_bus);
|
||||||
|
let pio_addr_ops = PciHost::build_pio_addr_ops(pci_host.clone());
|
||||||
|
let pio_data_ops = PciHost::build_pio_data_ops(pci_host.clone());
|
||||||
|
- let root_port = RootPort::new("pcie.1".to_string(), 8, 0, root_bus);
|
||||||
|
+ let root_port = RootPort::new("pcie.1".to_string(), 8, 0, root_bus, false);
|
||||||
|
root_port.realize().unwrap();
|
||||||
|
|
||||||
|
let mut data = [0_u8; 4];
|
||||||
|
@@ -517,10 +517,10 @@ pub mod tests {
|
||||||
|
let root_bus = Arc::downgrade(&pci_host.lock().unwrap().root_bus);
|
||||||
|
let mmconfig_region_ops = PciHost::build_mmconfig_ops(pci_host.clone());
|
||||||
|
|
||||||
|
- let mut root_port = RootPort::new("pcie.1".to_string(), 8, 0, root_bus.clone());
|
||||||
|
+ let mut root_port = RootPort::new("pcie.1".to_string(), 8, 0, root_bus.clone(), false);
|
||||||
|
root_port.write_config(SECONDARY_BUS_NUM as usize, &[1]);
|
||||||
|
root_port.realize().unwrap();
|
||||||
|
- let mut root_port = RootPort::new("pcie.2".to_string(), 16, 0, root_bus);
|
||||||
|
+ let mut root_port = RootPort::new("pcie.2".to_string(), 16, 0, root_bus, false);
|
||||||
|
root_port.write_config(SECONDARY_BUS_NUM as usize, &[2]);
|
||||||
|
root_port.realize().unwrap();
|
||||||
|
|
||||||
|
diff --git a/pci/src/root_port.rs b/pci/src/root_port.rs
|
||||||
|
index 948e31d..321c55e 100644
|
||||||
|
--- a/pci/src/root_port.rs
|
||||||
|
+++ b/pci/src/root_port.rs
|
||||||
|
@@ -20,12 +20,13 @@ use util::byte_code::ByteCode;
|
||||||
|
|
||||||
|
use super::config::{
|
||||||
|
PciConfig, PcieDevType, BAR_0, CLASS_CODE_PCI_BRIDGE, COMMAND, COMMAND_IO_SPACE,
|
||||||
|
- COMMAND_MEMORY_SPACE, DEVICE_ID, HEADER_TYPE, HEADER_TYPE_BRIDGE, HEADER_TYPE_MULTIFUNC,
|
||||||
|
- IO_BASE, MEMORY_BASE, PCIE_CONFIG_SPACE_SIZE, PCI_VENDOR_ID_REDHAT, PREF_MEMORY_BASE,
|
||||||
|
- PREF_MEMORY_LIMIT, PREF_MEM_RANGE_64BIT, REG_SIZE, SUB_CLASS_CODE, VENDOR_ID,
|
||||||
|
+ COMMAND_MEMORY_SPACE, DEVICE_ID, HEADER_TYPE, HEADER_TYPE_BRIDGE, IO_BASE, MEMORY_BASE,
|
||||||
|
+ PCIE_CONFIG_SPACE_SIZE, PCI_VENDOR_ID_REDHAT, PREF_MEMORY_BASE, PREF_MEMORY_LIMIT,
|
||||||
|
+ PREF_MEM_RANGE_64BIT, REG_SIZE, SUB_CLASS_CODE, VENDOR_ID,
|
||||||
|
};
|
||||||
|
use crate::bus::PciBus;
|
||||||
|
use crate::errors::{Result, ResultExt};
|
||||||
|
+use crate::init_multifunction;
|
||||||
|
use crate::msix::init_msix;
|
||||||
|
use crate::{le_read_u16, le_write_u16, ranges_overlap, PciDevOps};
|
||||||
|
|
||||||
|
@@ -56,6 +57,7 @@ pub struct RootPort {
|
||||||
|
io_region: Region,
|
||||||
|
mem_region: Region,
|
||||||
|
dev_id: u16,
|
||||||
|
+ multifunction: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RootPort {
|
||||||
|
@@ -68,7 +70,13 @@ impl RootPort {
|
||||||
|
/// * `port_num` - Root port number.
|
||||||
|
/// * `parent_bus` - Weak reference to the parent bus.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
- pub fn new(name: String, devfn: u8, port_num: u8, parent_bus: Weak<Mutex<PciBus>>) -> Self {
|
||||||
|
+ pub fn new(
|
||||||
|
+ name: String,
|
||||||
|
+ devfn: u8,
|
||||||
|
+ port_num: u8,
|
||||||
|
+ parent_bus: Weak<Mutex<PciBus>>,
|
||||||
|
+ multifunction: bool,
|
||||||
|
+ ) -> Self {
|
||||||
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
let io_region = Region::init_container_region(1 << 16);
|
||||||
|
let mem_region = Region::init_container_region(u64::max_value());
|
||||||
|
@@ -90,6 +98,7 @@ impl RootPort {
|
||||||
|
io_region,
|
||||||
|
mem_region,
|
||||||
|
dev_id: 0,
|
||||||
|
+ multifunction,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -113,9 +122,15 @@ impl PciDevOps for RootPort {
|
||||||
|
le_write_u16(config_space, VENDOR_ID as usize, PCI_VENDOR_ID_REDHAT)?;
|
||||||
|
le_write_u16(config_space, DEVICE_ID as usize, DEVICE_ID_RP)?;
|
||||||
|
le_write_u16(config_space, SUB_CLASS_CODE as usize, CLASS_CODE_PCI_BRIDGE)?;
|
||||||
|
- config_space[HEADER_TYPE as usize] = HEADER_TYPE_BRIDGE | HEADER_TYPE_MULTIFUNC;
|
||||||
|
+ config_space[HEADER_TYPE as usize] = HEADER_TYPE_BRIDGE;
|
||||||
|
config_space[PREF_MEMORY_BASE as usize] = PREF_MEM_RANGE_64BIT;
|
||||||
|
config_space[PREF_MEMORY_LIMIT as usize] = PREF_MEM_RANGE_64BIT;
|
||||||
|
+ init_multifunction(
|
||||||
|
+ self.multifunction,
|
||||||
|
+ config_space,
|
||||||
|
+ self.devfn,
|
||||||
|
+ self.parent_bus.clone(),
|
||||||
|
+ )?;
|
||||||
|
self.config
|
||||||
|
.add_pcie_cap(self.devfn, self.port_num, PcieDevType::RootPort as u8)?;
|
||||||
|
|
||||||
|
@@ -294,7 +309,7 @@ mod tests {
|
||||||
|
fn test_read_config() {
|
||||||
|
let pci_host = create_pci_host();
|
||||||
|
let root_bus = Arc::downgrade(&pci_host.lock().unwrap().root_bus);
|
||||||
|
- let root_port = RootPort::new("pcie.1".to_string(), 8, 0, root_bus);
|
||||||
|
+ let root_port = RootPort::new("pcie.1".to_string(), 8, 0, root_bus, false);
|
||||||
|
root_port.realize().unwrap();
|
||||||
|
|
||||||
|
let root_port = pci_host.lock().unwrap().find_device(0, 8).unwrap();
|
||||||
|
@@ -310,7 +325,7 @@ mod tests {
|
||||||
|
fn test_write_config() {
|
||||||
|
let pci_host = create_pci_host();
|
||||||
|
let root_bus = Arc::downgrade(&pci_host.lock().unwrap().root_bus);
|
||||||
|
- let root_port = RootPort::new("pcie.1".to_string(), 8, 0, root_bus);
|
||||||
|
+ let root_port = RootPort::new("pcie.1".to_string(), 8, 0, root_bus, false);
|
||||||
|
root_port.realize().unwrap();
|
||||||
|
let root_port = pci_host.lock().unwrap().find_device(0, 8).unwrap();
|
||||||
|
|
||||||
|
diff --git a/vfio/src/vfio_pci.rs b/vfio/src/vfio_pci.rs
|
||||||
|
index e366e47..40004a5 100644
|
||||||
|
--- a/vfio/src/vfio_pci.rs
|
||||||
|
+++ b/vfio/src/vfio_pci.rs
|
||||||
|
@@ -32,7 +32,7 @@ use pci::config::SECONDARY_BUS_NUM;
|
||||||
|
use pci::config::{
|
||||||
|
PciConfig, RegionType, BAR_0, BAR_5, BAR_IO_SPACE, BAR_MEM_64BIT, BAR_SPACE_UNMAPPED, COMMAND,
|
||||||
|
COMMAND_BUS_MASTER, COMMAND_INTERRUPT_DISABLE, COMMAND_IO_SPACE, COMMAND_MEMORY_SPACE,
|
||||||
|
- IO_BASE_ADDR_MASK, MEM_BASE_ADDR_MASK, PCIE_CONFIG_SPACE_SIZE, REG_SIZE,
|
||||||
|
+ HEADER_TYPE, IO_BASE_ADDR_MASK, MEM_BASE_ADDR_MASK, PCIE_CONFIG_SPACE_SIZE, REG_SIZE,
|
||||||
|
};
|
||||||
|
use pci::errors::Result as PciResult;
|
||||||
|
use pci::msix::{
|
||||||
|
@@ -41,7 +41,8 @@ use pci::msix::{
|
||||||
|
MSIX_TABLE_OFFSET, MSIX_TABLE_SIZE_MAX,
|
||||||
|
};
|
||||||
|
use pci::{
|
||||||
|
- le_read_u16, le_read_u32, le_write_u16, le_write_u32, ranges_overlap, PciBus, PciDevOps,
|
||||||
|
+ init_multifunction, le_read_u16, le_read_u32, le_write_u16, le_write_u32, ranges_overlap,
|
||||||
|
+ PciBus, PciDevOps,
|
||||||
|
};
|
||||||
|
use util::unix::host_page_size;
|
||||||
|
|
||||||
|
@@ -96,6 +97,8 @@ pub struct VfioPciDevice {
|
||||||
|
dev_id: Arc<AtomicU16>,
|
||||||
|
name: String,
|
||||||
|
parent_bus: Weak<Mutex<PciBus>>,
|
||||||
|
+ /// Multi-Function flag.
|
||||||
|
+ multi_func: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VfioPciDevice {
|
||||||
|
@@ -106,6 +109,7 @@ impl VfioPciDevice {
|
||||||
|
devfn: u8,
|
||||||
|
name: String,
|
||||||
|
parent_bus: Weak<Mutex<PciBus>>,
|
||||||
|
+ multi_func: bool,
|
||||||
|
) -> Result<Self> {
|
||||||
|
Ok(VfioPciDevice {
|
||||||
|
// Unknown PCI or PCIe type here, allocate enough space to match the two types.
|
||||||
|
@@ -122,6 +126,7 @@ impl VfioPciDevice {
|
||||||
|
dev_id: Arc::new(AtomicU16::new(0)),
|
||||||
|
name,
|
||||||
|
parent_bus,
|
||||||
|
+ multi_func,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -710,6 +715,15 @@ impl PciDevOps for VfioPciDevice {
|
||||||
|
PciResultExt::chain_err(self.pci_config_reset(), || {
|
||||||
|
"Failed to reset vfio device pci config space"
|
||||||
|
})?;
|
||||||
|
+ PciResultExt::chain_err(
|
||||||
|
+ init_multifunction(
|
||||||
|
+ self.multi_func,
|
||||||
|
+ &mut self.pci_config.config,
|
||||||
|
+ self.devfn,
|
||||||
|
+ self.parent_bus.clone(),
|
||||||
|
+ ),
|
||||||
|
+ || "Failed to init vfio device multifunction.",
|
||||||
|
+ )?;
|
||||||
|
|
||||||
|
#[cfg(target_arch = "aarch64")]
|
||||||
|
{
|
||||||
|
@@ -762,7 +776,15 @@ impl PciDevOps for VfioPciDevice {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if ranges_overlap(offset, end, BAR_0 as usize, BAR_5 as usize + REG_SIZE) {
|
||||||
|
+ // BAR and header_type are always controlled by StratoVirt.
|
||||||
|
+ if ranges_overlap(offset, end, BAR_0 as usize, (BAR_5 as usize) + REG_SIZE)
|
||||||
|
+ || ranges_overlap(
|
||||||
|
+ offset,
|
||||||
|
+ end,
|
||||||
|
+ HEADER_TYPE as usize,
|
||||||
|
+ (HEADER_TYPE as usize) + 2,
|
||||||
|
+ )
|
||||||
|
+ {
|
||||||
|
self.pci_config.read(offset, data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@@ -778,9 +800,6 @@ impl PciDevOps for VfioPciDevice {
|
||||||
|
if i + offset == 0x3d {
|
||||||
|
// Clear INIx
|
||||||
|
*data &= 0;
|
||||||
|
- } else if i + offset == 0x0e {
|
||||||
|
- // Clear multi-function
|
||||||
|
- *data &= 0x7f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/virtio/src/virtio_pci.rs b/virtio/src/virtio_pci.rs
|
||||||
|
index 8bdfce6..5a5b991 100644
|
||||||
|
--- a/virtio/src/virtio_pci.rs
|
||||||
|
+++ b/virtio/src/virtio_pci.rs
|
||||||
|
@@ -25,7 +25,10 @@ use pci::config::{
|
||||||
|
};
|
||||||
|
use pci::errors::{ErrorKind, Result as PciResult, ResultExt};
|
||||||
|
use pci::msix::update_dev_id;
|
||||||
|
-use pci::{config::PciConfig, init_msix, le_write_u16, ranges_overlap, PciBus, PciDevOps};
|
||||||
|
+use pci::{
|
||||||
|
+ config::PciConfig, init_msix, init_multifunction, le_write_u16, ranges_overlap, PciBus,
|
||||||
|
+ PciDevOps,
|
||||||
|
+};
|
||||||
|
use util::byte_code::ByteCode;
|
||||||
|
use vmm_sys_util::eventfd::EventFd;
|
||||||
|
|
||||||
|
@@ -487,6 +490,8 @@ pub struct VirtioPciDevice {
|
||||||
|
interrupt_cb: Option<Arc<VirtioInterrupt>>,
|
||||||
|
/// Virtio queues. The vector and Queue will be shared acrossing thread, so all with Arc<Mutex<..>> wrapper.
|
||||||
|
queues: Arc<Mutex<Vec<Arc<Mutex<Queue>>>>>,
|
||||||
|
+ /// Multi-Function flag.
|
||||||
|
+ multi_func: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VirtioPciDevice {
|
||||||
|
@@ -496,6 +501,7 @@ impl VirtioPciDevice {
|
||||||
|
sys_mem: Arc<AddressSpace>,
|
||||||
|
device: Arc<Mutex<dyn VirtioDevice>>,
|
||||||
|
parent_bus: Weak<Mutex<PciBus>>,
|
||||||
|
+ multi_func: bool,
|
||||||
|
) -> Self {
|
||||||
|
let queue_num = device.lock().unwrap().queue_num();
|
||||||
|
let queue_size = device.lock().unwrap().queue_size();
|
||||||
|
@@ -515,6 +521,7 @@ impl VirtioPciDevice {
|
||||||
|
notify_eventfds: NotifyEventFds::new(queue_num),
|
||||||
|
interrupt_cb: None,
|
||||||
|
queues: Arc::new(Mutex::new(Vec::with_capacity(queue_num))),
|
||||||
|
+ multi_func,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -869,6 +876,12 @@ impl PciDevOps for VirtioPciDevice {
|
||||||
|
SUBSYSTEM_ID,
|
||||||
|
0x40 + device_type as u16,
|
||||||
|
)?;
|
||||||
|
+ init_multifunction(
|
||||||
|
+ self.multi_func,
|
||||||
|
+ &mut self.config.config,
|
||||||
|
+ self.devfn,
|
||||||
|
+ self.parent_bus.clone(),
|
||||||
|
+ )?;
|
||||||
|
|
||||||
|
let common_cap = VirtioPciCap::new(
|
||||||
|
size_of::<VirtioPciCap>() as u8 + PCI_CAP_VNDR_AND_NEXT_SIZE,
|
||||||
|
@@ -1146,6 +1159,10 @@ mod tests {
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
use address_space::{AddressSpace, GuestAddress, HostMemMapping};
|
||||||
|
+ use pci::{
|
||||||
|
+ config::{HEADER_TYPE, HEADER_TYPE_MULTIFUNC},
|
||||||
|
+ le_read_u16,
|
||||||
|
+ };
|
||||||
|
use util::num_ops::{read_u32, write_u32};
|
||||||
|
use vmm_sys_util::eventfd::EventFd;
|
||||||
|
|
||||||
|
@@ -1347,6 +1364,7 @@ mod tests {
|
||||||
|
sys_mem,
|
||||||
|
virtio_dev,
|
||||||
|
Arc::downgrade(&parent_bus),
|
||||||
|
+ false,
|
||||||
|
);
|
||||||
|
virtio_pci.init_write_mask().unwrap();
|
||||||
|
virtio_pci.init_write_clear_mask().unwrap();
|
||||||
|
@@ -1381,6 +1399,7 @@ mod tests {
|
||||||
|
sys_mem,
|
||||||
|
virtio_dev,
|
||||||
|
Arc::downgrade(&parent_bus),
|
||||||
|
+ false,
|
||||||
|
);
|
||||||
|
assert!(virtio_pci.realize().is_ok());
|
||||||
|
}
|
||||||
|
@@ -1414,6 +1433,7 @@ mod tests {
|
||||||
|
sys_mem,
|
||||||
|
virtio_dev,
|
||||||
|
Arc::downgrade(&parent_bus),
|
||||||
|
+ false,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Prepare msix and interrupt callback
|
||||||
|
@@ -1467,4 +1487,35 @@ mod tests {
|
||||||
|
(common_cfg_ops.write)(0_u32.as_bytes(), GuestAddress(0), COMMON_STATUS_REG);
|
||||||
|
assert_eq!(virtio_pci.device_activated.load(Ordering::Relaxed), false);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ #[test]
|
||||||
|
+ fn test_multifunction() {
|
||||||
|
+ let virtio_dev: Arc<Mutex<dyn VirtioDevice>> =
|
||||||
|
+ Arc::new(Mutex::new(VirtioDeviceTest::new()));
|
||||||
|
+ let sys_mem = AddressSpace::new(Region::init_container_region(u64::max_value())).unwrap();
|
||||||
|
+ let parent_bus = Arc::new(Mutex::new(PciBus::new(
|
||||||
|
+ String::from("test bus"),
|
||||||
|
+ #[cfg(target_arch = "x86_64")]
|
||||||
|
+ Region::init_container_region(1 << 16),
|
||||||
|
+ sys_mem.root().clone(),
|
||||||
|
+ )));
|
||||||
|
+ let mut virtio_pci = VirtioPciDevice::new(
|
||||||
|
+ String::from("test device"),
|
||||||
|
+ 24,
|
||||||
|
+ sys_mem,
|
||||||
|
+ virtio_dev,
|
||||||
|
+ Arc::downgrade(&parent_bus),
|
||||||
|
+ true,
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ assert!(init_multifunction(
|
||||||
|
+ virtio_pci.multi_func,
|
||||||
|
+ &mut virtio_pci.config.config,
|
||||||
|
+ virtio_pci.devfn,
|
||||||
|
+ virtio_pci.parent_bus.clone()
|
||||||
|
+ )
|
||||||
|
+ .is_ok());
|
||||||
|
+ let header_type = le_read_u16(&virtio_pci.config.config, HEADER_TYPE as usize).unwrap();
|
||||||
|
+ assert_eq!(header_type, HEADER_TYPE_MULTIFUNC as u16);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
30
machine-fix-more-than-one-pcie-root-ports-with-same-.patch
Normal file
30
machine-fix-more-than-one-pcie-root-ports-with-same-.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From d0d7be6b637db9e3d1401905472d15082b7f2de6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ming Yang <yangming73@huawei.com>
|
||||||
|
Date: Tue, 24 Aug 2021 19:31:05 +0800
|
||||||
|
Subject: [PATCH 04/10] machine: fix more than one pcie-root-ports with same
|
||||||
|
id.
|
||||||
|
|
||||||
|
Signed-off-by: Ming Yang <yangming73@huawei.com>
|
||||||
|
---
|
||||||
|
machine/src/lib.rs | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/machine/src/lib.rs b/machine/src/lib.rs
|
||||||
|
index 8ba0ba3..22aed89 100644
|
||||||
|
--- a/machine/src/lib.rs
|
||||||
|
+++ b/machine/src/lib.rs
|
||||||
|
@@ -508,6 +508,11 @@ pub trait MachineOps {
|
||||||
|
let bdf = get_pci_bdf(cfg_args)?;
|
||||||
|
let (devfn, parent_bus) = self.get_devfn_and_parent_bus(&bdf)?;
|
||||||
|
let device_cfg = parse_root_port(cfg_args)?;
|
||||||
|
+ let pci_host = self.get_pci_host()?;
|
||||||
|
+ let bus = pci_host.lock().unwrap().root_bus.clone();
|
||||||
|
+ if PciBus::find_bus_by_name(&bus, &device_cfg.id).is_some() {
|
||||||
|
+ bail!("ID {} already exists.");
|
||||||
|
+ }
|
||||||
|
let rootport = RootPort::new(device_cfg.id, devfn, device_cfg.port, parent_bus);
|
||||||
|
rootport
|
||||||
|
.realize()
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
71
machine_manager-add-autodeflate-for-balloon.patch
Normal file
71
machine_manager-add-autodeflate-for-balloon.patch
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
From aa94544a6fcc53039946cd6545893eed75d60d6e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ming Yang <yangming73@huawei.com>
|
||||||
|
Date: Tue, 24 Aug 2021 16:54:02 +0800
|
||||||
|
Subject: [PATCH 02/10] machine_manager: add autodeflate for balloon.
|
||||||
|
|
||||||
|
Signed-off-by: Ming Yang <yangming73@huawei.com>
|
||||||
|
---
|
||||||
|
machine_manager/src/machine.rs | 9 ++++++++-
|
||||||
|
machine_manager/src/qmp/mod.rs | 2 +-
|
||||||
|
machine_manager/src/qmp/qmp_schema.rs | 4 +++-
|
||||||
|
3 files changed, 12 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/machine_manager/src/machine.rs b/machine_manager/src/machine.rs
|
||||||
|
index 49dbc38..ab8b288 100644
|
||||||
|
--- a/machine_manager/src/machine.rs
|
||||||
|
+++ b/machine_manager/src/machine.rs
|
||||||
|
@@ -299,13 +299,20 @@ pub trait DeviceInterface {
|
||||||
|
Response::create_response(serde_json::to_value(&vec_types).unwrap(), None)
|
||||||
|
}
|
||||||
|
|
||||||
|
- fn device_list_properties(&self) -> Response {
|
||||||
|
+ fn device_list_properties(&self, typename: String) -> Response {
|
||||||
|
let mut vec_props = Vec::<DeviceProps>::new();
|
||||||
|
let prop = DeviceProps {
|
||||||
|
name: "disable-legacy".to_string(),
|
||||||
|
prop_type: "OnOffAuto".to_string(),
|
||||||
|
};
|
||||||
|
vec_props.push(prop);
|
||||||
|
+ if typename.contains("virtio-balloon") {
|
||||||
|
+ let prop = DeviceProps {
|
||||||
|
+ name: "deflate-on-oom".to_string(),
|
||||||
|
+ prop_type: "bool".to_string(),
|
||||||
|
+ };
|
||||||
|
+ vec_props.push(prop);
|
||||||
|
+ }
|
||||||
|
Response::create_response(serde_json::to_value(&vec_props).unwrap(), None)
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/machine_manager/src/qmp/mod.rs b/machine_manager/src/qmp/mod.rs
|
||||||
|
index 8d9cd6f..f18f869 100644
|
||||||
|
--- a/machine_manager/src/qmp/mod.rs
|
||||||
|
+++ b/machine_manager/src/qmp/mod.rs
|
||||||
|
@@ -436,9 +436,9 @@ fn qmp_command_exec(
|
||||||
|
(query_cpus, query_cpus),
|
||||||
|
(query_balloon, query_balloon),
|
||||||
|
(list_type, list_type),
|
||||||
|
- (device_list_properties, device_list_properties),
|
||||||
|
(query_hotpluggable_cpus, query_hotpluggable_cpus);
|
||||||
|
(device_add, device_add, id, driver, addr, lun),
|
||||||
|
+ (device_list_properties, device_list_properties, typename),
|
||||||
|
(device_del, device_del, id),
|
||||||
|
(blockdev_add, blockdev_add, node_name, file, cache, read_only),
|
||||||
|
(netdev_add, netdev_add, id, if_name, fds),
|
||||||
|
diff --git a/machine_manager/src/qmp/qmp_schema.rs b/machine_manager/src/qmp/qmp_schema.rs
|
||||||
|
index 9544d46..a7c2a73 100644
|
||||||
|
--- a/machine_manager/src/qmp/qmp_schema.rs
|
||||||
|
+++ b/machine_manager/src/qmp/qmp_schema.rs
|
||||||
|
@@ -1375,7 +1375,9 @@ impl Command for list_type {
|
||||||
|
/// <- {"return":[]}
|
||||||
|
/// ```
|
||||||
|
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
|
||||||
|
-pub struct device_list_properties {}
|
||||||
|
+pub struct device_list_properties {
|
||||||
|
+ pub typename: String,
|
||||||
|
+}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct DeviceProps {
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
360
machine_manager-add-multifunction-for-devices.patch
Normal file
360
machine_manager-add-multifunction-for-devices.patch
Normal file
@ -0,0 +1,360 @@
|
|||||||
|
From b9ec3a6f3b7e35b342a778ded719cab4602e01a7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ming Yang <yangming73@huawei.com>
|
||||||
|
Date: Sat, 28 Aug 2021 10:25:21 +0800
|
||||||
|
Subject: [PATCH 08/10] machine_manager: add multifunction for devices.
|
||||||
|
|
||||||
|
1. Add arugument: "multifunction" for devices
|
||||||
|
|
||||||
|
Signed-off-by: Xinle.Guo <guoxinle1@huawei.com>
|
||||||
|
Signed-off-by: Ming Yang <yangming73@huawei.com>
|
||||||
|
---
|
||||||
|
machine_manager/src/config/balloon.rs | 7 +++-
|
||||||
|
machine_manager/src/config/chardev.rs | 43 +++++++++++++++--------
|
||||||
|
machine_manager/src/config/drive.rs | 9 +++++
|
||||||
|
machine_manager/src/config/network.rs | 9 +++++
|
||||||
|
machine_manager/src/config/pci.rs | 49 +++++++++++++++++++++++++++
|
||||||
|
machine_manager/src/config/rng.rs | 8 +++++
|
||||||
|
machine_manager/src/config/vfio.rs | 8 ++++-
|
||||||
|
7 files changed, 116 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/machine_manager/src/config/balloon.rs b/machine_manager/src/config/balloon.rs
|
||||||
|
index 77dc1b5..ec19445 100644
|
||||||
|
--- a/machine_manager/src/config/balloon.rs
|
||||||
|
+++ b/machine_manager/src/config/balloon.rs
|
||||||
|
@@ -47,6 +47,7 @@ pub fn parse_balloon(vm_config: &mut VmConfig, balloon_config: &str) -> Result<B
|
||||||
|
.push("")
|
||||||
|
.push("bus")
|
||||||
|
.push("addr")
|
||||||
|
+ .push("multifunction")
|
||||||
|
.push("id")
|
||||||
|
.push("deflate-on-oom");
|
||||||
|
cmd_parser.parse(balloon_config)?;
|
||||||
|
@@ -84,7 +85,7 @@ mod tests {
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
- fn test_pci_block_config_cmdline_parser() {
|
||||||
|
+ fn test_pci_balloon_config_cmdline_parser() {
|
||||||
|
let mut vm_config = VmConfig::default();
|
||||||
|
let bln_cfg = "virtio-balloon-pci,deflate-on-oom=true,bus=pcie.0,addr=0x1.0x2,id=balloon0";
|
||||||
|
let bln_cfg_res = parse_balloon(&mut vm_config, bln_cfg);
|
||||||
|
@@ -98,6 +99,10 @@ mod tests {
|
||||||
|
let pci = pci_bdf.unwrap();
|
||||||
|
assert_eq!(pci.bus, "pcie.0".to_string());
|
||||||
|
assert_eq!(pci.addr, (1, 2));
|
||||||
|
+
|
||||||
|
+ let mut vm_config = VmConfig::default();
|
||||||
|
+ let bln_cfg = "virtio-balloon-pci,deflate-on-oom=true,bus=pcie.0,addr=0x1.0x2,id=balloon0,multifunction=on";
|
||||||
|
+ assert!(parse_balloon(&mut vm_config, bln_cfg).is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
diff --git a/machine_manager/src/config/chardev.rs b/machine_manager/src/config/chardev.rs
|
||||||
|
index e5b3ff1..c1f37b5 100644
|
||||||
|
--- a/machine_manager/src/config/chardev.rs
|
||||||
|
+++ b/machine_manager/src/config/chardev.rs
|
||||||
|
@@ -16,7 +16,7 @@ use super::{
|
||||||
|
errors::{ErrorKind, Result, ResultExt},
|
||||||
|
get_pci_bdf, pci_args_check, PciBdf,
|
||||||
|
};
|
||||||
|
-use crate::config::{CmdParser, ConfigCheck, VmConfig};
|
||||||
|
+use crate::config::{CmdParser, ConfigCheck, ExBool, VmConfig};
|
||||||
|
|
||||||
|
const MAX_STRING_LENGTH: usize = 255;
|
||||||
|
const MAX_PATH_LENGTH: usize = 4096;
|
||||||
|
@@ -275,6 +275,7 @@ pub fn parse_vsock(vsock_config: &str) -> Result<VsockConfig> {
|
||||||
|
.push("id")
|
||||||
|
.push("bus")
|
||||||
|
.push("addr")
|
||||||
|
+ .push("multifunction")
|
||||||
|
.push("guest-cid")
|
||||||
|
.push("vhostfd");
|
||||||
|
cmd_parser.parse(vsock_config)?;
|
||||||
|
@@ -290,18 +291,7 @@ pub fn parse_vsock(vsock_config: &str) -> Result<VsockConfig> {
|
||||||
|
} else {
|
||||||
|
return Err(ErrorKind::FieldIsMissing("guest-cid", "vsock").into());
|
||||||
|
};
|
||||||
|
- let device_type = cmd_parser.get_value::<String>("")?;
|
||||||
|
- // Safe, because "parse_vsock" function only be called when certain
|
||||||
|
- // devices type are added.
|
||||||
|
- let dev_type = device_type.unwrap();
|
||||||
|
- if dev_type == *"vhost-vsock-device" {
|
||||||
|
- if cmd_parser.get_value::<String>("bus")?.is_some() {
|
||||||
|
- bail!("virtio mmio device does not support bus property");
|
||||||
|
- }
|
||||||
|
- if cmd_parser.get_value::<String>("addr")?.is_some() {
|
||||||
|
- bail!("virtio mmio device does not support addr property");
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+
|
||||||
|
let vhost_fd = cmd_parser.get_value::<i32>("vhostfd")?;
|
||||||
|
let vsock = VsockConfig {
|
||||||
|
id,
|
||||||
|
@@ -315,6 +305,7 @@ pub fn parse_vsock(vsock_config: &str) -> Result<VsockConfig> {
|
||||||
|
pub struct VirtioSerialInfo {
|
||||||
|
pub id: String,
|
||||||
|
pub pci_bdf: Option<PciBdf>,
|
||||||
|
+ pub multifunction: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConfigCheck for VirtioSerialInfo {
|
||||||
|
@@ -333,7 +324,12 @@ impl ConfigCheck for VirtioSerialInfo {
|
||||||
|
|
||||||
|
pub fn parse_virtio_serial(vm_config: &mut VmConfig, serial_config: &str) -> Result<()> {
|
||||||
|
let mut cmd_parser = CmdParser::new("virtio-serial");
|
||||||
|
- cmd_parser.push("").push("id").push("bus").push("addr");
|
||||||
|
+ cmd_parser
|
||||||
|
+ .push("")
|
||||||
|
+ .push("id")
|
||||||
|
+ .push("bus")
|
||||||
|
+ .push("addr")
|
||||||
|
+ .push("multifunction");
|
||||||
|
cmd_parser.parse(serial_config)?;
|
||||||
|
pci_args_check(&cmd_parser)?;
|
||||||
|
|
||||||
|
@@ -343,14 +339,24 @@ pub fn parse_virtio_serial(vm_config: &mut VmConfig, serial_config: &str) -> Res
|
||||||
|
} else {
|
||||||
|
"".to_string()
|
||||||
|
};
|
||||||
|
+ let multifunction = if let Some(switch) = cmd_parser.get_value::<ExBool>("multifunction")? {
|
||||||
|
+ switch.into()
|
||||||
|
+ } else {
|
||||||
|
+ false
|
||||||
|
+ };
|
||||||
|
let virtio_serial = if serial_config.contains("-pci") {
|
||||||
|
let pci_bdf = get_pci_bdf(serial_config)?;
|
||||||
|
VirtioSerialInfo {
|
||||||
|
id,
|
||||||
|
pci_bdf: Some(pci_bdf),
|
||||||
|
+ multifunction,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
- VirtioSerialInfo { id, pci_bdf: None }
|
||||||
|
+ VirtioSerialInfo {
|
||||||
|
+ id,
|
||||||
|
+ pci_bdf: None,
|
||||||
|
+ multifunction,
|
||||||
|
+ }
|
||||||
|
};
|
||||||
|
virtio_serial.check()?;
|
||||||
|
vm_config.virtio_serial = Some(virtio_serial);
|
||||||
|
@@ -434,6 +440,13 @@ mod tests {
|
||||||
|
console_cfg.chardev.backend,
|
||||||
|
ChardevType::Socket("/path/to/socket".to_string())
|
||||||
|
);
|
||||||
|
+
|
||||||
|
+ let mut vm_config = VmConfig::default();
|
||||||
|
+ assert!(parse_virtio_serial(
|
||||||
|
+ &mut vm_config,
|
||||||
|
+ "virtio-serial-pci,bus=pcie.0,addr=0x1.0x2,multifunction=on"
|
||||||
|
+ )
|
||||||
|
+ .is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
diff --git a/machine_manager/src/config/drive.rs b/machine_manager/src/config/drive.rs
|
||||||
|
index 3aaef75..16831df 100644
|
||||||
|
--- a/machine_manager/src/config/drive.rs
|
||||||
|
+++ b/machine_manager/src/config/drive.rs
|
||||||
|
@@ -164,6 +164,7 @@ pub fn parse_blk(vm_config: &mut VmConfig, drive_config: &str) -> Result<BlkDevC
|
||||||
|
.push("id")
|
||||||
|
.push("bus")
|
||||||
|
.push("addr")
|
||||||
|
+ .push("multifunction")
|
||||||
|
.push("drive")
|
||||||
|
.push("bootindex")
|
||||||
|
.push("serial")
|
||||||
|
@@ -412,6 +413,14 @@ mod tests {
|
||||||
|
// drive "rootfs" has been removed.
|
||||||
|
let blk_cfg_res = parse_blk(&mut vm_config, blk_cfg);
|
||||||
|
assert!(blk_cfg_res.is_err());
|
||||||
|
+
|
||||||
|
+ let mut vm_config = VmConfig::default();
|
||||||
|
+ assert!(vm_config
|
||||||
|
+ .add_drive("id=rootfs,file=/path/to/rootfs,serial=111111,readonly=off,direct=on")
|
||||||
|
+ .is_ok());
|
||||||
|
+ let blk_cfg =
|
||||||
|
+ "virtio-blk-pci,id=blk1,bus=pcie.0,addr=0x1.0x2,drive=rootfs,multifunction=on";
|
||||||
|
+ assert!(parse_blk(&mut vm_config, blk_cfg).is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
diff --git a/machine_manager/src/config/network.rs b/machine_manager/src/config/network.rs
|
||||||
|
index 71e6b3f..b0ad545 100644
|
||||||
|
--- a/machine_manager/src/config/network.rs
|
||||||
|
+++ b/machine_manager/src/config/network.rs
|
||||||
|
@@ -159,6 +159,7 @@ pub fn parse_net(vm_config: &mut VmConfig, net_config: &str) -> Result<NetworkIn
|
||||||
|
.push("netdev")
|
||||||
|
.push("bus")
|
||||||
|
.push("addr")
|
||||||
|
+ .push("multifunction")
|
||||||
|
.push("mac")
|
||||||
|
.push("iothread");
|
||||||
|
|
||||||
|
@@ -344,5 +345,13 @@ mod tests {
|
||||||
|
|
||||||
|
let net_cfg_res = parse_net(&mut vm_config, net_cfg);
|
||||||
|
assert!(net_cfg_res.is_err());
|
||||||
|
+
|
||||||
|
+ let mut vm_config = VmConfig::default();
|
||||||
|
+ assert!(vm_config
|
||||||
|
+ .add_netdev("tap,id=eth1,ifname=tap1,vhost=on,vhostfd=4")
|
||||||
|
+ .is_ok());
|
||||||
|
+ let net_cfg =
|
||||||
|
+ "virtio-net-pci,id=net1,netdev=eth1,bus=pcie.0,addr=0x1.0x2,mac=12:34:56:78:9A:BC,multifunction=on";
|
||||||
|
+ assert!(parse_net(&mut vm_config, net_cfg).is_ok());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/machine_manager/src/config/pci.rs b/machine_manager/src/config/pci.rs
|
||||||
|
index 13bca99..a3a6c9d 100644
|
||||||
|
--- a/machine_manager/src/config/pci.rs
|
||||||
|
+++ b/machine_manager/src/config/pci.rs
|
||||||
|
@@ -12,6 +12,7 @@
|
||||||
|
|
||||||
|
use super::errors::{ErrorKind, Result, ResultExt};
|
||||||
|
use super::{CmdParser, ConfigCheck, MAX_STRING_LENGTH};
|
||||||
|
+use crate::config::ExBool;
|
||||||
|
|
||||||
|
/// Basic information of pci devices such as bus number,
|
||||||
|
/// slot number and function number.
|
||||||
|
@@ -43,6 +44,7 @@ impl Default for PciBdf {
|
||||||
|
pub struct RootPortConfig {
|
||||||
|
pub port: u8,
|
||||||
|
pub id: String,
|
||||||
|
+ pub multifunction: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ConfigCheck for RootPortConfig {
|
||||||
|
@@ -64,6 +66,7 @@ impl Default for RootPortConfig {
|
||||||
|
RootPortConfig {
|
||||||
|
port: 0,
|
||||||
|
id: "".to_string(),
|
||||||
|
+ multifunction: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -112,6 +115,21 @@ pub fn get_pci_bdf(pci_cfg: &str) -> Result<PciBdf> {
|
||||||
|
Ok(pci_bdf)
|
||||||
|
}
|
||||||
|
|
||||||
|
+pub fn get_multi_function(pci_cfg: &str) -> Result<bool> {
|
||||||
|
+ let mut cmd_parser = CmdParser::new("multifunction");
|
||||||
|
+ cmd_parser.push("").push("multifunction");
|
||||||
|
+ cmd_parser.get_parameters(pci_cfg)?;
|
||||||
|
+
|
||||||
|
+ if let Some(multi_func) = cmd_parser
|
||||||
|
+ .get_value::<ExBool>("multifunction")
|
||||||
|
+ .chain_err(|| "Failed to get multifunction parameter, please set on or off (default).")?
|
||||||
|
+ {
|
||||||
|
+ return Ok(multi_func.inner);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ Ok(false)
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
pub fn parse_root_port(rootport_cfg: &str) -> Result<RootPortConfig> {
|
||||||
|
let mut cmd_parser = CmdParser::new("pcie-root-port");
|
||||||
|
cmd_parser
|
||||||
|
@@ -138,6 +156,12 @@ pub fn parse_root_port(rootport_cfg: &str) -> Result<RootPortConfig> {
|
||||||
|
} else {
|
||||||
|
return Err(ErrorKind::FieldIsMissing("id", "rootport").into());
|
||||||
|
}
|
||||||
|
+ root_port.multifunction =
|
||||||
|
+ if let Some(multi_func) = cmd_parser.get_value::<ExBool>("multifunction")? {
|
||||||
|
+ multi_func.into()
|
||||||
|
+ } else {
|
||||||
|
+ false
|
||||||
|
+ };
|
||||||
|
root_port.check()?;
|
||||||
|
|
||||||
|
Ok(root_port)
|
||||||
|
@@ -155,6 +179,9 @@ pub fn pci_args_check(cmd_parser: &CmdParser) -> Result<()> {
|
||||||
|
if cmd_parser.get_value::<String>("addr")?.is_some() {
|
||||||
|
bail!("virtio mmio device does not support addr arguments");
|
||||||
|
}
|
||||||
|
+ if cmd_parser.get_value::<ExBool>("multifunction")?.is_some() {
|
||||||
|
+ bail!("virtio mmio device does not support multifunction arguments");
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
@@ -193,4 +220,26 @@ mod tests {
|
||||||
|
let pci_bdf = get_pci_bdf("virtio-balloon-device,addr=0x1.0x2");
|
||||||
|
assert!(pci_bdf.is_err());
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ #[test]
|
||||||
|
+ fn test_get_multi_function() {
|
||||||
|
+ assert_eq!(
|
||||||
|
+ get_multi_function("virtio-balloon-device,bus=pcie.0,addr=0x1.0x2").unwrap(),
|
||||||
|
+ false
|
||||||
|
+ );
|
||||||
|
+ assert_eq!(
|
||||||
|
+ get_multi_function("virtio-balloon-device,bus=pcie.0,addr=0x1.0x2,multifunction=on")
|
||||||
|
+ .unwrap(),
|
||||||
|
+ true
|
||||||
|
+ );
|
||||||
|
+ assert_eq!(
|
||||||
|
+ get_multi_function("virtio-balloon-device,bus=pcie.0,addr=0x1.0x2,multifunction=off")
|
||||||
|
+ .unwrap(),
|
||||||
|
+ false
|
||||||
|
+ );
|
||||||
|
+ assert!(get_multi_function(
|
||||||
|
+ "virtio-balloon-device,bus=pcie.0,addr=0x1.0x2,multifunction=close"
|
||||||
|
+ )
|
||||||
|
+ .is_err());
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
diff --git a/machine_manager/src/config/rng.rs b/machine_manager/src/config/rng.rs
|
||||||
|
index 295c6f2..139d15e 100644
|
||||||
|
--- a/machine_manager/src/config/rng.rs
|
||||||
|
+++ b/machine_manager/src/config/rng.rs
|
||||||
|
@@ -72,6 +72,7 @@ pub fn parse_rng_dev(vm_config: &mut VmConfig, rng_config: &str) -> Result<RngCo
|
||||||
|
.push("id")
|
||||||
|
.push("bus")
|
||||||
|
.push("addr")
|
||||||
|
+ .push("multifunction")
|
||||||
|
.push("max-bytes")
|
||||||
|
.push("period")
|
||||||
|
.push("rng");
|
||||||
|
@@ -234,5 +235,12 @@ mod tests {
|
||||||
|
let rng_cfg = "virtio-rng-device,rng=objrng0,bus=pcie.0,addr=0x1.0x3";
|
||||||
|
let rng_config = parse_rng_dev(&mut vm_config, rng_cfg);
|
||||||
|
assert!(rng_config.is_err());
|
||||||
|
+
|
||||||
|
+ let mut vm_config = VmConfig::default();
|
||||||
|
+ assert!(vm_config
|
||||||
|
+ .add_object("rng-random,id=objrng0,filename=/path/to/random_file")
|
||||||
|
+ .is_ok());
|
||||||
|
+ let rng_cfg = "virtio-rng-pci,rng=objrng0,bus=pcie.0,addr=0x1.0x3,multifunction=on";
|
||||||
|
+ assert!(parse_rng_dev(&mut vm_config, rng_cfg).is_ok());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/machine_manager/src/config/vfio.rs b/machine_manager/src/config/vfio.rs
|
||||||
|
index 2a941c5..5f7d450 100644
|
||||||
|
--- a/machine_manager/src/config/vfio.rs
|
||||||
|
+++ b/machine_manager/src/config/vfio.rs
|
||||||
|
@@ -52,7 +52,8 @@ pub fn parse_vfio(_vm_config: &VmConfig, vfio_config: &str) -> Result<VfioConfig
|
||||||
|
.push("host")
|
||||||
|
.push("id")
|
||||||
|
.push("bus")
|
||||||
|
- .push("addr");
|
||||||
|
+ .push("addr")
|
||||||
|
+ .push("multifunction");
|
||||||
|
cmd_parser.parse(vfio_config)?;
|
||||||
|
|
||||||
|
let mut vfio: VfioConfig = VfioConfig::default();
|
||||||
|
@@ -127,5 +128,10 @@ mod tests {
|
||||||
|
let pci = pci_bdf.unwrap();
|
||||||
|
assert_eq!(pci.bus, "pcie.0".to_string());
|
||||||
|
assert_eq!(pci.addr, (1, 2));
|
||||||
|
+
|
||||||
|
+ let mut vm_config = VmConfig::default();
|
||||||
|
+ let vfio_cfg1 =
|
||||||
|
+ "vfio-pci,host=0000:1a:00.3,id=net,bus=pcie.0,addr=0x1.0x2,multifunction=on";
|
||||||
|
+ assert!(parse_vfio(&mut vm_config, vfio_cfg1).is_ok());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
135
machine_manager-move-argument-serial-from-drive-to-d.patch
Normal file
135
machine_manager-move-argument-serial-from-drive-to-d.patch
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
From a2dcc9cb71d8a341d5f437edcbe1a9c19a69e1a7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Ming Yang <yangming73@huawei.com>
|
||||||
|
Date: Fri, 27 Aug 2021 16:51:29 +0800
|
||||||
|
Subject: [PATCH 07/10] machine_manager: move argument "serial" from -drive to
|
||||||
|
-device virtio-blk-pci/device.
|
||||||
|
|
||||||
|
1. When interconnect with libvirt, the "serial" argument is given followed by -device
|
||||||
|
virtio-blk-pci. Thus it is moved in this commit.
|
||||||
|
|
||||||
|
Signed-off-by: Ming Yang <yangming73@huawei.com>
|
||||||
|
---
|
||||||
|
docs/config_guidebook.md | 8 ++++----
|
||||||
|
machine_manager/src/config/drive.rs | 25 +++++++++++++------------
|
||||||
|
2 files changed, 17 insertions(+), 16 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/docs/config_guidebook.md b/docs/config_guidebook.md
|
||||||
|
index e1279e1..b1f7b08 100644
|
||||||
|
--- a/docs/config_guidebook.md
|
||||||
|
+++ b/docs/config_guidebook.md
|
||||||
|
@@ -171,11 +171,11 @@ If you want to boot VM with a virtio block device as rootfs, you should add `roo
|
||||||
|
|
||||||
|
```shell
|
||||||
|
# virtio mmio block device.
|
||||||
|
--drive id=drive_id,file=path_on_host[,serial=serial_num,readonly=off,direct=off,throttling.iops-total=200]
|
||||||
|
--device virtio-blk-device,drive=drive_id[,iothread=iothread1]
|
||||||
|
+-drive id=drive_id,file=path_on_host[,readonly=off][,direct=off][,throttling.iops-total=200]
|
||||||
|
+-device virtio-blk-device,drive=drive_id[,iothread=iothread1][,serial=serial_num]
|
||||||
|
# virtio pci block device.
|
||||||
|
--drive id=drive_id,file=path_on_host[,serial=serial_num,readonly=off,direct=off,throttling.iops-total=200]
|
||||||
|
--device virtio-blk-pci,drive=drive_id,bus=pcie.0,addr=0x3.0x0[,iothread=iothread1]
|
||||||
|
+-drive id=drive_id,file=path_on_host[,readonly=off][,direct=off][,throttling.iops-total=200]
|
||||||
|
+-device virtio-blk-pci,drive=drive_id,bus=pcie.0,addr=0x3.0x0[,iothread=iothread1,][serial=serial_num]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
diff --git a/machine_manager/src/config/drive.rs b/machine_manager/src/config/drive.rs
|
||||||
|
index 4d05eb8..3aaef75 100644
|
||||||
|
--- a/machine_manager/src/config/drive.rs
|
||||||
|
+++ b/machine_manager/src/config/drive.rs
|
||||||
|
@@ -62,7 +62,6 @@ pub struct DriveConfig {
|
||||||
|
pub path_on_host: String,
|
||||||
|
pub read_only: bool,
|
||||||
|
pub direct: bool,
|
||||||
|
- pub serial_num: Option<String>,
|
||||||
|
pub iops: Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -73,7 +72,6 @@ impl Default for DriveConfig {
|
||||||
|
path_on_host: "".to_string(),
|
||||||
|
read_only: false,
|
||||||
|
direct: true,
|
||||||
|
- serial_num: None,
|
||||||
|
iops: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -155,9 +153,6 @@ pub fn parse_drive(cmd_parser: CmdParser) -> Result<DriveConfig> {
|
||||||
|
if let Some(direct) = cmd_parser.get_value::<ExBool>("direct")? {
|
||||||
|
drive.direct = direct.into();
|
||||||
|
}
|
||||||
|
- if let Some(serial) = cmd_parser.get_value::<String>("serial")? {
|
||||||
|
- drive.serial_num = Some(serial);
|
||||||
|
- }
|
||||||
|
drive.iops = cmd_parser.get_value::<u64>("throttling.iops-total")?;
|
||||||
|
Ok(drive)
|
||||||
|
}
|
||||||
|
@@ -171,6 +166,7 @@ pub fn parse_blk(vm_config: &mut VmConfig, drive_config: &str) -> Result<BlkDevC
|
||||||
|
.push("addr")
|
||||||
|
.push("drive")
|
||||||
|
.push("bootindex")
|
||||||
|
+ .push("serial")
|
||||||
|
.push("iothread");
|
||||||
|
|
||||||
|
cmd_parser.parse(drive_config)?;
|
||||||
|
@@ -192,12 +188,15 @@ pub fn parse_blk(vm_config: &mut VmConfig, drive_config: &str) -> Result<BlkDevC
|
||||||
|
blkdevcfg.iothread = Some(iothread);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if let Some(serial) = cmd_parser.get_value::<String>("serial")? {
|
||||||
|
+ blkdevcfg.serial_num = Some(serial);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if let Some(drive_arg) = &vm_config.drives.remove(&blkdrive) {
|
||||||
|
blkdevcfg.id = drive_arg.id.clone();
|
||||||
|
blkdevcfg.path_on_host = drive_arg.path_on_host.clone();
|
||||||
|
blkdevcfg.read_only = drive_arg.read_only;
|
||||||
|
blkdevcfg.direct = drive_arg.direct;
|
||||||
|
- blkdevcfg.serial_num = drive_arg.serial_num.clone();
|
||||||
|
blkdevcfg.iops = drive_arg.iops;
|
||||||
|
} else {
|
||||||
|
bail!("No drive configured matched for blk device");
|
||||||
|
@@ -361,11 +360,13 @@ mod tests {
|
||||||
|
fn test_drive_config_cmdline_parser() {
|
||||||
|
let mut vm_config = VmConfig::default();
|
||||||
|
assert!(vm_config
|
||||||
|
- .add_drive("id=rootfs,file=/path/to/rootfs,serial=111111,readonly=off,direct=on,throttling.iops-total=200")
|
||||||
|
+ .add_drive(
|
||||||
|
+ "id=rootfs,file=/path/to/rootfs,readonly=off,direct=on,throttling.iops-total=200"
|
||||||
|
+ )
|
||||||
|
.is_ok());
|
||||||
|
let blk_cfg_res = parse_blk(
|
||||||
|
&mut vm_config,
|
||||||
|
- "virtio-blk-device,drive=rootfs,iothread=iothread1",
|
||||||
|
+ "virtio-blk-device,drive=rootfs,iothread=iothread1,serial=111111",
|
||||||
|
);
|
||||||
|
assert!(blk_cfg_res.is_ok());
|
||||||
|
let blk_device_config = blk_cfg_res.unwrap();
|
||||||
|
@@ -377,11 +378,11 @@ mod tests {
|
||||||
|
|
||||||
|
let mut vm_config = VmConfig::default();
|
||||||
|
assert!(vm_config
|
||||||
|
- .add_drive("id=rootfs,file=/path/to/rootfs,serial=111111,readonly=off,direct=on")
|
||||||
|
+ .add_drive("id=rootfs,file=/path/to/rootfs,readonly=off,direct=on")
|
||||||
|
.is_ok());
|
||||||
|
let blk_cfg_res = parse_blk(
|
||||||
|
&mut vm_config,
|
||||||
|
- "virtio-blk-device,drive=rootfs1,iothread=iothread1,iops=200",
|
||||||
|
+ "virtio-blk-device,drive=rootfs1,iothread=iothread1,iops=200,serial=111111",
|
||||||
|
);
|
||||||
|
assert!(blk_cfg_res.is_err()); // Can not find drive named "rootfs1".
|
||||||
|
}
|
||||||
|
@@ -390,9 +391,9 @@ mod tests {
|
||||||
|
fn test_pci_block_config_cmdline_parser() {
|
||||||
|
let mut vm_config = VmConfig::default();
|
||||||
|
assert!(vm_config
|
||||||
|
- .add_drive("id=rootfs,file=/path/to/rootfs,serial=111111,readonly=off,direct=on")
|
||||||
|
+ .add_drive("id=rootfs,file=/path/to/rootfs,readonly=off,direct=on")
|
||||||
|
.is_ok());
|
||||||
|
- let blk_cfg = "virtio-blk-pci,id=blk1,bus=pcie.0,addr=0x1.0x2,drive=rootfs";
|
||||||
|
+ let blk_cfg = "virtio-blk-pci,id=blk1,bus=pcie.0,addr=0x1.0x2,drive=rootfs,serial=111111";
|
||||||
|
let blk_cfg_res = parse_blk(&mut vm_config, blk_cfg);
|
||||||
|
assert!(blk_cfg_res.is_ok());
|
||||||
|
let drive_configs = blk_cfg_res.unwrap();
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
44
migration-add-dev_id-into-VirtioPciState-when-save-a.patch
Normal file
44
migration-add-dev_id-into-VirtioPciState-when-save-a.patch
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
From aa0f9438a27ad4ae2086d49b70d72def2f9f9024 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Wei Gao <gaowei66@huawei.com>
|
||||||
|
Date: Thu, 26 Aug 2021 10:50:43 +0800
|
||||||
|
Subject: [PATCH 03/10] migration: add dev_id into VirtioPciState when save and
|
||||||
|
restore device state.
|
||||||
|
|
||||||
|
After commit 94c7bfbeeacda20d488b7ad2ad4fa9293f5883b4, pci device's dev_id will be reallocated when device activated or reset. So it's necessary to save dev_id during migration.
|
||||||
|
|
||||||
|
Signed-off-by: Wei Gao <gaowei66@huawei.com>
|
||||||
|
---
|
||||||
|
virtio/src/virtio_pci.rs | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/virtio/src/virtio_pci.rs b/virtio/src/virtio_pci.rs
|
||||||
|
index aaf009e..8bdfce6 100644
|
||||||
|
--- a/virtio/src/virtio_pci.rs
|
||||||
|
+++ b/virtio/src/virtio_pci.rs
|
||||||
|
@@ -439,6 +439,7 @@ impl Clone for NotifyEventFds {
|
||||||
|
#[desc_version(compat_version = "0.1.0")]
|
||||||
|
pub struct VirtioPciState {
|
||||||
|
activated: bool,
|
||||||
|
+ dev_id: u16,
|
||||||
|
/// Max length of config_space is 4096.
|
||||||
|
config_space: [u8; 4096],
|
||||||
|
write_mask: [u8; 4096],
|
||||||
|
@@ -1040,6 +1041,7 @@ impl StateTransfer for VirtioPciDevice {
|
||||||
|
|
||||||
|
// Save virtio pci state.
|
||||||
|
state.activated = self.device_activated.load(Ordering::Relaxed);
|
||||||
|
+ state.dev_id = self.dev_id.load(Ordering::Acquire);
|
||||||
|
{
|
||||||
|
let locked_queues = self.queues.lock().unwrap();
|
||||||
|
for (index, queue) in locked_queues.iter().enumerate() {
|
||||||
|
@@ -1083,6 +1085,7 @@ impl StateTransfer for VirtioPciDevice {
|
||||||
|
// Set virtio pci state.
|
||||||
|
self.device_activated
|
||||||
|
.store(pci_state.activated, Ordering::Relaxed);
|
||||||
|
+ self.dev_id.store(pci_state.dev_id, Ordering::Release);
|
||||||
|
{
|
||||||
|
let queue_type = self.common_config.lock().unwrap().queue_type;
|
||||||
|
let mut locked_queues = self.queues.lock().unwrap();
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
66
migration-move-function-transport_reset-to-save-stat.patch
Normal file
66
migration-move-function-transport_reset-to-save-stat.patch
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
From c44049602c22c09b82ae5ca67afc2fa202d4fbf1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Wei Gao <gaowei66@huawei.com>
|
||||||
|
Date: Thu, 26 Aug 2021 11:59:02 +0800
|
||||||
|
Subject: [PATCH 05/10] migration: move function "transport_reset" to save
|
||||||
|
state stage for vhost_vsock device.
|
||||||
|
|
||||||
|
Because of vsock control protocol is not resilient to vsock packed loss, vsock device will
|
||||||
|
break the connection during restoring. As a solution to this, send a "VIRTIO_VSOCK_EVENT_TRANSPORT_RESET"
|
||||||
|
event when VM doing snapshot. Then vsock pack will not loss. More details about this event can be
|
||||||
|
found in virtio Spec section 5.10.6.6.
|
||||||
|
|
||||||
|
Signed-off-by: Wei Gao <gaowei66@huawei.com>
|
||||||
|
---
|
||||||
|
virtio/src/vhost/kernel/vsock.rs | 14 +++++++++-----
|
||||||
|
1 file changed, 9 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/virtio/src/vhost/kernel/vsock.rs b/virtio/src/vhost/kernel/vsock.rs
|
||||||
|
index 5c3d198..29e59af 100644
|
||||||
|
--- a/virtio/src/vhost/kernel/vsock.rs
|
||||||
|
+++ b/virtio/src/vhost/kernel/vsock.rs
|
||||||
|
@@ -113,7 +113,7 @@ impl Vsock {
|
||||||
|
/// The `VIRTIO_VSOCK_EVENT_TRANSPORT_RESET` event indicates that communication has
|
||||||
|
/// been interrupted. The driver shuts down established connections and the guest_cid
|
||||||
|
/// configuration field is fetched again.
|
||||||
|
- fn transport_reset(&mut self) -> Result<()> {
|
||||||
|
+ fn transport_reset(&self) -> Result<()> {
|
||||||
|
let mut event_queue_locked = self.event_queue.as_ref().unwrap().lock().unwrap();
|
||||||
|
let element = event_queue_locked
|
||||||
|
.vring
|
||||||
|
@@ -136,7 +136,7 @@ impl Vsock {
|
||||||
|
.chain_err(|| format!("Failed to add used ring {}", element.index))?;
|
||||||
|
|
||||||
|
if let Some(interrupt_cb) = &self.interrupt_cb {
|
||||||
|
- interrupt_cb(&VirtioInterruptType::Vring, None)
|
||||||
|
+ interrupt_cb(&VirtioInterruptType::Vring, Some(&*event_queue_locked))
|
||||||
|
.chain_err(|| ErrorKind::EventFdWrite)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -337,6 +337,9 @@ impl StateTransfer for Vsock {
|
||||||
|
self.backend.as_ref().unwrap().set_running(true),
|
||||||
|
|| "Failed to set vsock backend running",
|
||||||
|
)?;
|
||||||
|
+ migration::errors::ResultExt::chain_err(self.transport_reset(), || {
|
||||||
|
+ "Failed to send vsock transport reset event"
|
||||||
|
+ })?;
|
||||||
|
|
||||||
|
Ok(state.as_bytes().to_vec())
|
||||||
|
}
|
||||||
|
@@ -358,10 +361,11 @@ impl StateTransfer for Vsock {
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MigrationHook for Vsock {
|
||||||
|
+ #[cfg(target_arch = "aarch64")]
|
||||||
|
fn resume(&mut self) -> migration::errors::Result<()> {
|
||||||
|
- if let Err(e) = self.transport_reset() {
|
||||||
|
- error!("Failed to resume virtio vsock device: {}", e);
|
||||||
|
- }
|
||||||
|
+ migration::errors::ResultExt::chain_err(self.transport_reset(), || {
|
||||||
|
+ "Failed to resume virtio vsock device"
|
||||||
|
+ })?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
@ -6,21 +6,31 @@
|
|||||||
|
|
||||||
Name: stratovirt
|
Name: stratovirt
|
||||||
Version: 2.0.0
|
Version: 2.0.0
|
||||||
Release: 5
|
Release: 6
|
||||||
Summary: StratoVirt is an opensource VMM(Virtual Machine Manager) which aims to perform next generation virtualization.
|
Summary: StratoVirt is an opensource VMM(Virtual Machine Manager) which aims to perform next generation virtualization.
|
||||||
|
|
||||||
License: Mulan PSL v2
|
License: Mulan PSL v2
|
||||||
URL: https://gitee.com/openeuler/StratoVirt
|
URL: https://gitee.com/openeuler/StratoVirt
|
||||||
Source0: %{name}-%{version}.tar.gz
|
Source0: %{name}-%{version}.tar.gz
|
||||||
|
|
||||||
Patch001: 0001-fix-spelling-errors-in-project.patch
|
Patch001: fix-spelling-errors-in-project.patch
|
||||||
Patch002: 0002-migration-fix-an-error-during-migration-interface-on.patch
|
Patch002: migration-fix-an-error-during-migration-interface-on.patch
|
||||||
Patch003: 0003-migration-fix-an-errors-during-the-PL011-device-stat.patch
|
Patch003: migration-fix-an-errors-during-the-PL011-device-stat.patch
|
||||||
Patch004: 0004-machine-standard_vm-fix-inappropriate-file-open-perm.patch
|
Patch004: machine-standard_vm-fix-inappropriate-file-open-perm.patch
|
||||||
Patch005: 0005-kernel_config-update-kernel-config-5.10-on-aarch64-p.patch
|
Patch005: kernel_config-update-kernel-config-5.10-on-aarch64-p.patch
|
||||||
Patch006: 0006-syscall-add-syscall-newfstatat-in-x86_64-unknown-lin.patch
|
Patch006: syscall-add-syscall-newfstatat-in-x86_64-unknown-lin.patch
|
||||||
Patch007: 0007-vfio-fix-the-problem-of-dma-mapping-failed.patch
|
Patch007: vfio-fix-the-problem-of-dma-mapping-failed.patch
|
||||||
Patch008: 0008-virtio-fix-dev_id-initialization-for-virtio-pci-and-.patch
|
Patch008: virtio-fix-dev_id-initialization-for-virtio-pci-and-.patch
|
||||||
|
Patch009: docs-fix-some-statement.patch
|
||||||
|
Patch010: machine_manager-add-autodeflate-for-balloon.patch
|
||||||
|
Patch011: migration-add-dev_id-into-VirtioPciState-when-save-a.patch
|
||||||
|
Patch012: machine-fix-more-than-one-pcie-root-ports-with-same-.patch
|
||||||
|
Patch013: migration-move-function-transport_reset-to-save-stat.patch
|
||||||
|
Patch014: vfio-adding-ram-device-region-to-vfio-bar-region.patch
|
||||||
|
Patch015: machine_manager-move-argument-serial-from-drive-to-d.patch
|
||||||
|
Patch016: machine_manager-add-multifunction-for-devices.patch
|
||||||
|
Patch017: machine-add-init_multifunction-function-to-init-mult.patch
|
||||||
|
Patch018: machine-add-realization-for-multifunction.patch
|
||||||
|
|
||||||
ExclusiveArch: x86_64 aarch64
|
ExclusiveArch: x86_64 aarch64
|
||||||
|
|
||||||
@ -75,6 +85,18 @@ chmod 555 ${RPM_BUILD_ROOT}/usr/bin/stratovirt
|
|||||||
chmod 555 ${RPM_BUILD_ROOT}/usr/bin/ozone
|
chmod 555 ${RPM_BUILD_ROOT}/usr/bin/ozone
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Aug 30 2021 Jie Yang <yangjieyj.yang@huawei.com> - 2.0.0-6
|
||||||
|
- docs: fix some statement
|
||||||
|
- machine_manager: add autodeflate for balloon
|
||||||
|
- migration: add dev_id into VirtioPciState when save and restore device state
|
||||||
|
- machine: fix more than one pcie-root-ports with same id
|
||||||
|
- migration: move function "transport_reset" to save state stage for vhost vsock device
|
||||||
|
- vfio: adding ram device region to vfio bar region
|
||||||
|
- machine_manager: move argument "serial" from -drive to -device virtio-blk-pci/device
|
||||||
|
- machine_manager: add multifunction for devices
|
||||||
|
- machine: add init_multifunction function to init multifunction
|
||||||
|
- machine: add realization for multifunction
|
||||||
|
|
||||||
* Thu Aug 24 2021 Ming Yang <yangming73@huawei.com> - 2.0.0-5
|
* Thu Aug 24 2021 Ming Yang <yangming73@huawei.com> - 2.0.0-5
|
||||||
- add ozone in rpm package.
|
- add ozone in rpm package.
|
||||||
|
|
||||||
|
|||||||
130
vfio-adding-ram-device-region-to-vfio-bar-region.patch
Normal file
130
vfio-adding-ram-device-region-to-vfio-bar-region.patch
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
From 7d40dbe810cf21added24d7cf2425a62bae4b25b Mon Sep 17 00:00:00 2001
|
||||||
|
From: "Xinle.Guo" <guoxinle1@huawei.com>
|
||||||
|
Date: Tue, 24 Aug 2021 15:29:08 +0800
|
||||||
|
Subject: [PATCH 06/10] vfio: adding ram device region to vfio bar region
|
||||||
|
|
||||||
|
The ram device region was added to memory region of parent bus.
|
||||||
|
But vfio bar region could not manage ram device region when
|
||||||
|
adding or deleting sub region. To fix this problem, it should be
|
||||||
|
added as sub region of vfio bar region. The VM exits when
|
||||||
|
guest tries to read/write device bar region. Using ram device
|
||||||
|
region which remaps mmio region can improve I/O performance. So,
|
||||||
|
the memory region should look like as follows:
|
||||||
|
|
||||||
|
|----- IO region ----------|
|
||||||
|
|-----|---- IO region ----|-----|------|-ram device region-|(memory region)
|
||||||
|
virtio bar region vfio bar region
|
||||||
|
|
||||||
|
So, guest can read/write host device bar region directly.
|
||||||
|
|
||||||
|
Signed-off-by: Xinle.Guo <guoxinle1@huawei.com>
|
||||||
|
---
|
||||||
|
vfio/src/lib.rs | 4 ++--
|
||||||
|
vfio/src/vfio_pci.rs | 35 ++++++++++++++++++++---------------
|
||||||
|
2 files changed, 22 insertions(+), 17 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/vfio/src/lib.rs b/vfio/src/lib.rs
|
||||||
|
index be70f45..801b7d0 100644
|
||||||
|
--- a/vfio/src/lib.rs
|
||||||
|
+++ b/vfio/src/lib.rs
|
||||||
|
@@ -23,8 +23,8 @@ pub mod errors {
|
||||||
|
PciErr(pci::errors::Error, pci::errors::ErrorKind);
|
||||||
|
}
|
||||||
|
errors {
|
||||||
|
- UnregMemBar(id: usize) {
|
||||||
|
- display("Failed to unmap BAR {} in memory space.", id)
|
||||||
|
+ AddRegBar(id: usize) {
|
||||||
|
+ display("Failed to add sub region at the BAR {} in memory space.", id)
|
||||||
|
}
|
||||||
|
VfioIoctl(ioctl: String, result: i32) {
|
||||||
|
display("Vfio ioctl failed: {}, result is: {}", ioctl, result)
|
||||||
|
diff --git a/vfio/src/vfio_pci.rs b/vfio/src/vfio_pci.rs
|
||||||
|
index b42e321..e366e47 100644
|
||||||
|
--- a/vfio/src/vfio_pci.rs
|
||||||
|
+++ b/vfio/src/vfio_pci.rs
|
||||||
|
@@ -345,19 +345,19 @@ impl VfioPciDevice {
|
||||||
|
.chain_err(|| "Failed to get vfio bar info")?;
|
||||||
|
let size = vfio_bar.size;
|
||||||
|
|
||||||
|
+ let region = Region::init_container_region(size);
|
||||||
|
let bar_region = if i == table_bar {
|
||||||
|
- let region = Region::init_container_region(size);
|
||||||
|
region
|
||||||
|
.add_subregion(
|
||||||
|
Region::init_io_region(table_size as u64, table_ops.clone()),
|
||||||
|
table_offset,
|
||||||
|
)
|
||||||
|
- .chain_err(|| ErrorKind::UnregMemBar(i as usize))?;
|
||||||
|
+ .chain_err(|| ErrorKind::AddRegBar(i as usize))?;
|
||||||
|
|
||||||
|
if table_offset > 0 {
|
||||||
|
region
|
||||||
|
.add_subregion(Region::init_io_region(table_offset, bar_ops.clone()), 0)
|
||||||
|
- .chain_err(|| ErrorKind::UnregMemBar(i as usize))?;
|
||||||
|
+ .chain_err(|| ErrorKind::AddRegBar(i as usize))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if table_offset + table_size < size {
|
||||||
|
@@ -369,11 +369,14 @@ impl VfioPciDevice {
|
||||||
|
),
|
||||||
|
table_offset + table_size,
|
||||||
|
)
|
||||||
|
- .chain_err(|| ErrorKind::UnregMemBar(i as usize))?;
|
||||||
|
+ .chain_err(|| ErrorKind::AddRegBar(i as usize))?;
|
||||||
|
}
|
||||||
|
region
|
||||||
|
} else {
|
||||||
|
- Region::init_io_region(size, bar_ops.clone())
|
||||||
|
+ region
|
||||||
|
+ .add_subregion(Region::init_io_region(size, bar_ops.clone()), 0)
|
||||||
|
+ .chain_err(|| ErrorKind::AddRegBar(i as usize))?;
|
||||||
|
+ region
|
||||||
|
};
|
||||||
|
|
||||||
|
self.pci_config
|
||||||
|
@@ -634,14 +637,16 @@ impl VfioPciDevice {
|
||||||
|
.chain_err(|| "Failed to create HostMemMapping")?;
|
||||||
|
|
||||||
|
let ram_device = Region::init_ram_device_region(Arc::new(host_mmap));
|
||||||
|
- // Avoid being covered by user memory region.
|
||||||
|
- ram_device.set_priority(1);
|
||||||
|
- let parent_bus = self.parent_bus.upgrade().unwrap();
|
||||||
|
- let locked_parent_bus = parent_bus.lock().unwrap();
|
||||||
|
- locked_parent_bus
|
||||||
|
- .mem_region
|
||||||
|
- .add_subregion(ram_device, gpa + mmap.offset)
|
||||||
|
- .chain_err(|| "Failed add to mem region")?;
|
||||||
|
+ let bar = self
|
||||||
|
+ .pci_config
|
||||||
|
+ .bars
|
||||||
|
+ .get_mut(i as usize)
|
||||||
|
+ .chain_err(|| "Failed to get pci bar info")?;
|
||||||
|
+ bar.region
|
||||||
|
+ .as_ref()
|
||||||
|
+ .unwrap()
|
||||||
|
+ .add_subregion(ram_device, mmap.offset)
|
||||||
|
+ .chain_err(|| ErrorKind::AddRegBar(i as usize))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
@@ -757,7 +762,7 @@ impl PciDevOps for VfioPciDevice {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if offset >= (BAR_0 as usize) && offset < (BAR_5 as usize) + REG_SIZE {
|
||||||
|
+ if ranges_overlap(offset, end, BAR_0 as usize, BAR_5 as usize + REG_SIZE) {
|
||||||
|
self.pci_config.read(offset, data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@@ -806,7 +811,7 @@ impl PciDevOps for VfioPciDevice {
|
||||||
|
cap_offset = msix.lock().unwrap().msix_cap_offset as usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if ranges_overlap(offset, end, COMMAND as usize, COMMAND as usize + 4) {
|
||||||
|
+ if ranges_overlap(offset, end, COMMAND as usize, COMMAND as usize + REG_SIZE) {
|
||||||
|
self.pci_config
|
||||||
|
.write(offset, data, self.dev_id.load(Ordering::Acquire));
|
||||||
|
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user