diff --git a/docs-fix-some-statement.patch b/docs-fix-some-statement.patch new file mode 100644 index 0000000..95b7351 --- /dev/null +++ b/docs-fix-some-statement.patch @@ -0,0 +1,227 @@ +From aeede83c9a6a4b07aee477b67d763561a3f342e6 Mon Sep 17 00:00:00 2001 +From: Ming Yang +Date: Wed, 18 Aug 2021 18:44:39 +0800 +Subject: [PATCH 01/10] docs: fix some statement + +Signed-off-by: Ming Yang +--- + 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/path/to/standard_vm_kernel +-console=ttys0 root=/dev/vda reboot=k panic=1 rw ++console=ttyS0 root=/dev/vda reboot=k panic=1 rw + ``` + + - feature: +@@ -77,7 +77,7 @@ Pflash can be added by the following config. + `/path/to/pflash` is the path of pflash file. + ``` + /path/to/pflash +-/path/to/OVMF_VARS ++/path/to/OVMF_VARS + ``` + + - iothread +@@ -144,7 +144,7 @@ To use `virsh console` command, the virtio console with redirect `pty` should be + + + +- /dev/random ++ /path/to/random_file +
+ + ``` +@@ -153,7 +153,7 @@ To use `virsh console` command, the virtio console with redirect `pty` should be + + ``` + +- ++ + + +
+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 @@ + + hvm + /path/to/standard_vm_kernel +- console=ttys0 root=/dev/vda reboot=k panic=1 rw ++ console=ttyAMA0 root=/dev/vda reboot=k panic=1 rw + /path/to/pflash + + +@@ -24,8 +24,8 @@ + /path/to/StratoVirt_binary_file + + +- +- ++ ++ + + +
+@@ -58,7 +58,7 @@ + + + +- /dev/random ++ /path/to/random_file +
+ + +@@ -67,7 +67,7 @@ +
+ + +- ++ + + +
+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 @@ + + hvm + /path/to/standard_vm_kernel +- console=ttys0 root=/dev/vda reboot=k panic=1 rw ++ console=hvc0 root=/dev/vda reboot=k panic=1 rw + /path/to/pflash +- /path/to/OVMF_VARS ++ /path/to/OVMF_VARS + + + +@@ -32,8 +32,8 @@ + + + +- +- ++ ++ + + + +@@ -66,7 +66,7 @@ + + + +- /dev/random ++ /path/to/random_file +
+ + +@@ -75,7 +75,7 @@ +
+ + +- ++ + + +
+-- +2.25.1 + diff --git a/0001-fix-spelling-errors-in-project.patch b/fix-spelling-errors-in-project.patch similarity index 100% rename from 0001-fix-spelling-errors-in-project.patch rename to fix-spelling-errors-in-project.patch diff --git a/0005-kernel_config-update-kernel-config-5.10-on-aarch64-p.patch b/kernel_config-update-kernel-config-5.10-on-aarch64-p.patch similarity index 100% rename from 0005-kernel_config-update-kernel-config-5.10-on-aarch64-p.patch rename to kernel_config-update-kernel-config-5.10-on-aarch64-p.patch diff --git a/machine-add-init_multifunction-function-to-init-mult.patch b/machine-add-init_multifunction-function-to-init-mult.patch new file mode 100644 index 0000000..0b65ac6 --- /dev/null +++ b/machine-add-init_multifunction-function-to-init-mult.patch @@ -0,0 +1,146 @@ +From 7e9ea7ef5f9673d40cf64fcd306c879028d39c29 Mon Sep 17 00:00:00 2001 +From: Ming Yang +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 +Signed-off-by: Ming Yang +--- + 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, ++ devfn: u8, ++ parent_bus: Weak>, ++) -> 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 + diff --git a/machine-add-realization-for-multifunction.patch b/machine-add-realization-for-multifunction.patch new file mode 100644 index 0000000..7939c65 --- /dev/null +++ b/machine-add-realization-for-multifunction.patch @@ -0,0 +1,636 @@ +From 4e8272a490b9901fc92fbaad1c10fee6d8b43fe3 Mon Sep 17 00:00:00 2001 +From: Ming Yang +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 +Signed-off-by: Ming Yang +--- + 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>) -> Self { ++ pub fn new( ++ name: String, ++ devfn: u8, ++ port_num: u8, ++ parent_bus: Weak>, ++ 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, + name: String, + parent_bus: Weak>, ++ /// Multi-Function flag. ++ multi_func: bool, + } + + impl VfioPciDevice { +@@ -106,6 +109,7 @@ impl VfioPciDevice { + devfn: u8, + name: String, + parent_bus: Weak>, ++ multi_func: bool, + ) -> Result { + 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>, + /// Virtio queues. The vector and Queue will be shared acrossing thread, so all with Arc> wrapper. + queues: Arc>>>>, ++ /// Multi-Function flag. ++ multi_func: bool, + } + + impl VirtioPciDevice { +@@ -496,6 +501,7 @@ impl VirtioPciDevice { + sys_mem: Arc, + device: Arc>, + parent_bus: Weak>, ++ 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::() 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> = ++ 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 + diff --git a/machine-fix-more-than-one-pcie-root-ports-with-same-.patch b/machine-fix-more-than-one-pcie-root-ports-with-same-.patch new file mode 100644 index 0000000..b5690a4 --- /dev/null +++ b/machine-fix-more-than-one-pcie-root-ports-with-same-.patch @@ -0,0 +1,30 @@ +From d0d7be6b637db9e3d1401905472d15082b7f2de6 Mon Sep 17 00:00:00 2001 +From: Ming Yang +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 +--- + 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 + diff --git a/0004-machine-standard_vm-fix-inappropriate-file-open-perm.patch b/machine-standard_vm-fix-inappropriate-file-open-perm.patch similarity index 100% rename from 0004-machine-standard_vm-fix-inappropriate-file-open-perm.patch rename to machine-standard_vm-fix-inappropriate-file-open-perm.patch diff --git a/machine_manager-add-autodeflate-for-balloon.patch b/machine_manager-add-autodeflate-for-balloon.patch new file mode 100644 index 0000000..089dcbe --- /dev/null +++ b/machine_manager-add-autodeflate-for-balloon.patch @@ -0,0 +1,71 @@ +From aa94544a6fcc53039946cd6545893eed75d60d6e Mon Sep 17 00:00:00 2001 +From: Ming Yang +Date: Tue, 24 Aug 2021 16:54:02 +0800 +Subject: [PATCH 02/10] machine_manager: add autodeflate for balloon. + +Signed-off-by: Ming Yang +--- + 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::::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 + diff --git a/machine_manager-add-multifunction-for-devices.patch b/machine_manager-add-multifunction-for-devices.patch new file mode 100644 index 0000000..600a7cd --- /dev/null +++ b/machine_manager-add-multifunction-for-devices.patch @@ -0,0 +1,360 @@ +From b9ec3a6f3b7e35b342a778ded719cab4602e01a7 Mon Sep 17 00:00:00 2001 +From: Ming Yang +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 +Signed-off-by: Ming Yang +--- + 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 Result { + .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 { + } else { + return Err(ErrorKind::FieldIsMissing("guest-cid", "vsock").into()); + }; +- let device_type = cmd_parser.get_value::("")?; +- // 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::("bus")?.is_some() { +- bail!("virtio mmio device does not support bus property"); +- } +- if cmd_parser.get_value::("addr")?.is_some() { +- bail!("virtio mmio device does not support addr property"); +- } +- } ++ + let vhost_fd = cmd_parser.get_value::("vhostfd")?; + let vsock = VsockConfig { + id, +@@ -315,6 +305,7 @@ pub fn parse_vsock(vsock_config: &str) -> Result { + pub struct VirtioSerialInfo { + pub id: String, + pub pci_bdf: Option, ++ 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::("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 Result Result { + Ok(pci_bdf) + } + ++pub fn get_multi_function(pci_cfg: &str) -> Result { ++ 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::("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 { + let mut cmd_parser = CmdParser::new("pcie-root-port"); + cmd_parser +@@ -138,6 +156,12 @@ pub fn parse_root_port(rootport_cfg: &str) -> Result { + } else { + return Err(ErrorKind::FieldIsMissing("id", "rootport").into()); + } ++ root_port.multifunction = ++ if let Some(multi_func) = cmd_parser.get_value::("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::("addr")?.is_some() { + bail!("virtio mmio device does not support addr arguments"); + } ++ if cmd_parser.get_value::("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 Result +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 +--- + 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, + pub iops: Option, + } + +@@ -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 { + if let Some(direct) = cmd_parser.get_value::("direct")? { + drive.direct = direct.into(); + } +- if let Some(serial) = cmd_parser.get_value::("serial")? { +- drive.serial_num = Some(serial); +- } + drive.iops = cmd_parser.get_value::("throttling.iops-total")?; + Ok(drive) + } +@@ -171,6 +166,7 @@ pub fn parse_blk(vm_config: &mut VmConfig, drive_config: &str) -> Result Result("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 + diff --git a/migration-add-dev_id-into-VirtioPciState-when-save-a.patch b/migration-add-dev_id-into-VirtioPciState-when-save-a.patch new file mode 100644 index 0000000..1f40c95 --- /dev/null +++ b/migration-add-dev_id-into-VirtioPciState-when-save-a.patch @@ -0,0 +1,44 @@ +From aa0f9438a27ad4ae2086d49b70d72def2f9f9024 Mon Sep 17 00:00:00 2001 +From: Wei Gao +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 +--- + 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 + diff --git a/0002-migration-fix-an-error-during-migration-interface-on.patch b/migration-fix-an-error-during-migration-interface-on.patch similarity index 100% rename from 0002-migration-fix-an-error-during-migration-interface-on.patch rename to migration-fix-an-error-during-migration-interface-on.patch diff --git a/0003-migration-fix-an-errors-during-the-PL011-device-stat.patch b/migration-fix-an-errors-during-the-PL011-device-stat.patch similarity index 100% rename from 0003-migration-fix-an-errors-during-the-PL011-device-stat.patch rename to migration-fix-an-errors-during-the-PL011-device-stat.patch diff --git a/migration-move-function-transport_reset-to-save-stat.patch b/migration-move-function-transport_reset-to-save-stat.patch new file mode 100644 index 0000000..64396ad --- /dev/null +++ b/migration-move-function-transport_reset-to-save-stat.patch @@ -0,0 +1,66 @@ +From c44049602c22c09b82ae5ca67afc2fa202d4fbf1 Mon Sep 17 00:00:00 2001 +From: Wei Gao +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 +--- + 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 + diff --git a/stratovirt.spec b/stratovirt.spec index 723a2a0..504eb13 100644 --- a/stratovirt.spec +++ b/stratovirt.spec @@ -6,21 +6,31 @@ Name: stratovirt Version: 2.0.0 -Release: 5 +Release: 6 Summary: StratoVirt is an opensource VMM(Virtual Machine Manager) which aims to perform next generation virtualization. License: Mulan PSL v2 URL: https://gitee.com/openeuler/StratoVirt Source0: %{name}-%{version}.tar.gz -Patch001: 0001-fix-spelling-errors-in-project.patch -Patch002: 0002-migration-fix-an-error-during-migration-interface-on.patch -Patch003: 0003-migration-fix-an-errors-during-the-PL011-device-stat.patch -Patch004: 0004-machine-standard_vm-fix-inappropriate-file-open-perm.patch -Patch005: 0005-kernel_config-update-kernel-config-5.10-on-aarch64-p.patch -Patch006: 0006-syscall-add-syscall-newfstatat-in-x86_64-unknown-lin.patch -Patch007: 0007-vfio-fix-the-problem-of-dma-mapping-failed.patch -Patch008: 0008-virtio-fix-dev_id-initialization-for-virtio-pci-and-.patch +Patch001: fix-spelling-errors-in-project.patch +Patch002: migration-fix-an-error-during-migration-interface-on.patch +Patch003: migration-fix-an-errors-during-the-PL011-device-stat.patch +Patch004: machine-standard_vm-fix-inappropriate-file-open-perm.patch +Patch005: kernel_config-update-kernel-config-5.10-on-aarch64-p.patch +Patch006: syscall-add-syscall-newfstatat-in-x86_64-unknown-lin.patch +Patch007: vfio-fix-the-problem-of-dma-mapping-failed.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 @@ -75,6 +85,18 @@ chmod 555 ${RPM_BUILD_ROOT}/usr/bin/stratovirt chmod 555 ${RPM_BUILD_ROOT}/usr/bin/ozone %changelog +* Mon Aug 30 2021 Jie Yang - 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 - 2.0.0-5 - add ozone in rpm package. diff --git a/0006-syscall-add-syscall-newfstatat-in-x86_64-unknown-lin.patch b/syscall-add-syscall-newfstatat-in-x86_64-unknown-lin.patch similarity index 100% rename from 0006-syscall-add-syscall-newfstatat-in-x86_64-unknown-lin.patch rename to syscall-add-syscall-newfstatat-in-x86_64-unknown-lin.patch diff --git a/vfio-adding-ram-device-region-to-vfio-bar-region.patch b/vfio-adding-ram-device-region-to-vfio-bar-region.patch new file mode 100644 index 0000000..228eeff --- /dev/null +++ b/vfio-adding-ram-device-region-to-vfio-bar-region.patch @@ -0,0 +1,130 @@ +From 7d40dbe810cf21added24d7cf2425a62bae4b25b Mon Sep 17 00:00:00 2001 +From: "Xinle.Guo" +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 +--- + 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 + diff --git a/0007-vfio-fix-the-problem-of-dma-mapping-failed.patch b/vfio-fix-the-problem-of-dma-mapping-failed.patch similarity index 100% rename from 0007-vfio-fix-the-problem-of-dma-mapping-failed.patch rename to vfio-fix-the-problem-of-dma-mapping-failed.patch diff --git a/0008-virtio-fix-dev_id-initialization-for-virtio-pci-and-.patch b/virtio-fix-dev_id-initialization-for-virtio-pci-and-.patch similarity index 100% rename from 0008-virtio-fix-dev_id-initialization-for-virtio-pci-and-.patch rename to virtio-fix-dev_id-initialization-for-virtio-pci-and-.patch