From 78d769107da2ab6972267993c9660325d4d80ff4 Mon Sep 17 00:00:00 2001 From: Jie Yang Date: Sun, 13 Mar 2022 11:28:58 +0800 Subject: [PATCH] Update version to 2.1.0-4 Signed-off-by: Jie Yang (cherry picked from commit e9cfa81784d4a86efd4392a487c0294d440c03c0) --- ...-command-for-booting-with-the-raw-im.patch | 64 + ...o-need-to-delete-the-unmapped-region.patch | 112 ++ 0018-arm-use-the-HighPcieEcam-region.patch | 61 + ...g-the-same-device-multiple-times-pro.patch | 73 + 0020-machine-update-seccomp-rules.patch | 226 +++ ...onsole-fix-the-bug-of-delete-park-fd.patch | 57 + ...scription-of-hot-plug-of-PCI-devices.patch | 26 + ...ippy-warning-when-compiling-cargo-cl.patch | 1439 +++++++++++++++++ stratovirt.spec | 15 +- 9 files changed, 2072 insertions(+), 1 deletion(-) create mode 100644 0016-docs-correct-the-command-for-booting-with-the-raw-im.patch create mode 100644 0017-pci-no-need-to-delete-the-unmapped-region.patch create mode 100644 0018-arm-use-the-HighPcieEcam-region.patch create mode 100644 0019-vfio-fix-hot-plug-the-same-device-multiple-times-pro.patch create mode 100644 0020-machine-update-seccomp-rules.patch create mode 100644 0021-console-fix-the-bug-of-delete-park-fd.patch create mode 100644 0022-docs-add-the-description-of-hot-plug-of-PCI-devices.patch create mode 100644 0023-Modify-cargo-cllippy-warning-when-compiling-cargo-cl.patch diff --git a/0016-docs-correct-the-command-for-booting-with-the-raw-im.patch b/0016-docs-correct-the-command-for-booting-with-the-raw-im.patch new file mode 100644 index 0000000..27bb0ae --- /dev/null +++ b/0016-docs-correct-the-command-for-booting-with-the-raw-im.patch @@ -0,0 +1,64 @@ +From f5435cecabd10dd8d7a97d9e0091e28b45e46957 Mon Sep 17 00:00:00 2001 +From: zhouli57 +Date: Mon, 7 Mar 2022 08:43:32 +0800 +Subject: [PATCH 1/8] docs: correct the command for booting with the raw image + +Signed-off-by: zhouli57 +--- + docs/boot.ch.md | 8 +++----- + docs/boot.md | 4 ++-- + 2 files changed, 5 insertions(+), 7 deletions(-) + +diff --git a/docs/boot.ch.md b/docs/boot.ch.md +index 31153a9..774e4a8 100644 +--- a/docs/boot.ch.md ++++ b/docs/boot.ch.md +@@ -225,7 +225,7 @@ fi + -m 2G \ + -append "console=${con} reboot=k panic=1 root=/dev/vda rw" \ + -drive file=/path/to/rootfs,id=rootfs,readonly=off,direct=off \ +- -device virtio-blk-device,drive=rootfs,id=rootfs \ ++ -device virtio-blk-pci,drive=rootfs,id=blk1,bus=pcie.0,addr=0x2 \ + -drive file=/path/to/OVMF_CODE.fd,if=pflash,unit=0,readonly=true \ + -drive file=/path/to/OVMF_VARS.fd,if=pflash,unit=1 \ + -qmp unix:/path/to/socket,server,nowait \ +@@ -237,12 +237,10 @@ fi + ```shell + /usr/bin/stratovirt \ + -machine ${machine} \ +- -kernel /path/to/kernel \ + -smp 1 \ + -m 2G \ +- -append "console=${con} reboot=k panic=1 root=/dev/vda rw" \ +- -drive file=/path/to/rootfs,id=rootfs,readonly=off,direct=off \ +- -device virtio-blk-device,drive=rootfs \ ++ -drive file=/path/to/raw_image,id=raw_image,readonly=off,direct=off \ ++ -device virtio-blk-pci,drive=raw_image,id=blk1,bus=pcie.0,addr=0x2 \ + -drive file=/path/to/OVMF_CODE.fd,if=pflash,unit=0,readonly=true \ + -drive file=/path/to/OVMF_VARS.fd,if=pflash,unit=1 \ + -qmp unix:/path/to/socket,server,nowait \ +diff --git a/docs/boot.md b/docs/boot.md +index 64d75b4..66541fa 100644 +--- a/docs/boot.md ++++ b/docs/boot.md +@@ -230,7 +230,7 @@ fi + -m 2G \ + -append "console=${con} reboot=k panic=1 root=/dev/vda rw" \ + -drive file=/path/to/rootfs,id=rootfs,readonly=off,direct=off \ +- -device virtio-blk-device,drive=rootfs,id=rootfs \ ++ -device virtio-blk-pci,drive=rootfs,id=blk1,bus=pcie.0,addr=0x2 \ + -drive file=/path/to/OVMF_CODE.fd,if=pflash,unit=0,readonly=true \ + -drive file=/path/to/OVMF_VARS.fd,if=pflash,unit=1 \ + -qmp unix:/path/to/socket,server,nowait \ +@@ -245,7 +245,7 @@ The command for booting with the raw image is as follows: + -smp 1 \ + -m 2G \ + -drive file=/path/to/raw_image,id=raw_image,readonly=off,direct=off \ +- -device virtio-blk-device,drive=raw_image \ ++ -device virtio-blk-pci,drive=raw_image,id=blk1,bus=pcie.0,addr=0x2 \ + -drive file=/path/to/OVMF_CODE.fd,if=pflash,unit=0,readonly=true \ + -drive file=/path/to/OVMF_VARS.fd,if=pflash,unit=1 \ + -qmp unix:/path/to/socket,server,nowait \ +-- +2.20.1 + diff --git a/0017-pci-no-need-to-delete-the-unmapped-region.patch b/0017-pci-no-need-to-delete-the-unmapped-region.patch new file mode 100644 index 0000000..c15392f --- /dev/null +++ b/0017-pci-no-need-to-delete-the-unmapped-region.patch @@ -0,0 +1,112 @@ +From cd3d687aeaee2d94a1b09895b14f87a3f232cb22 Mon Sep 17 00:00:00 2001 +From: zhouli57 +Date: Mon, 7 Mar 2022 20:51:56 +0800 +Subject: [PATCH 2/8] pci: no need to delete the unmapped region + +When we hot-plug a pci device but fail for some reason, for example, +hot-plug to an unsupported bus, at this point, the device has finished +registering the region, and we need to clean up the registered region. +Because the device has not been actually used, the address in the BAR +may not have been updated, so there may be an error in unregister_bars. +in fact, there is no need to delete the unmapped region. + +Signed-off-by: zhouli57 +--- + pci/src/config.rs | 75 ++++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 71 insertions(+), 4 deletions(-) + +diff --git a/pci/src/config.rs b/pci/src/config.rs +index 88d7f03..c2b4c88 100644 +--- a/pci/src/config.rs ++++ b/pci/src/config.rs +@@ -569,11 +569,12 @@ impl PciConfig { + pub fn unregister_bars(&mut self, bus: &Arc>) -> Result<()> { + let locked_bus = bus.lock().unwrap(); + for bar in self.bars.iter_mut() { ++ if bar.address == BAR_SPACE_UNMAPPED || bar.size == 0 { ++ continue; ++ } + match bar.region_type { +- RegionType::Io => { +- if bar.address == BAR_SPACE_UNMAPPED || bar.size == 0 { +- continue; +- } ++ RegionType::Io => ++ { + #[cfg(target_arch = "x86_64")] + if let Some(region) = bar.region.as_ref() { + locked_bus +@@ -1102,4 +1103,70 @@ mod tests { + assert_eq!(size1, 0x10); + assert_eq!(size2, 0x40); + } ++ ++ #[test] ++ fn test_unregister_bars() { ++ let read_ops = move |_data: &mut [u8], _addr: GuestAddress, _offset: u64| -> bool { true }; ++ let write_ops = move |_data: &[u8], _addr: GuestAddress, _offset: u64| -> bool { true }; ++ let region_ops = RegionOps { ++ read: Arc::new(read_ops), ++ write: Arc::new(write_ops), ++ }; ++ let region = Region::init_io_region(2048, region_ops); ++ let mut pci_config = PciConfig::new(PCI_CONFIG_SPACE_SIZE, 3); ++ ++ // bar is unmapped ++ #[cfg(target_arch = "x86_64")] ++ pci_config.register_bar(0, region.clone(), RegionType::Io, false, 2048); ++ pci_config.register_bar(1, region.clone(), RegionType::Mem32Bit, false, 2048); ++ pci_config.register_bar(2, region.clone(), RegionType::Mem64Bit, true, 2048); ++ ++ #[cfg(target_arch = "x86_64")] ++ let io_region = Region::init_container_region(1 << 16); ++ let mem_region = Region::init_container_region(u64::max_value()); ++ let bus = Arc::new(Mutex::new(PciBus::new( ++ String::from("bus"), ++ #[cfg(target_arch = "x86_64")] ++ io_region.clone(), ++ mem_region.clone(), ++ ))); ++ ++ assert!(pci_config.unregister_bars(&bus).is_ok()); ++ ++ // bar is mapped ++ #[cfg(target_arch = "x86_64")] ++ pci_config.register_bar(0, region.clone(), RegionType::Io, false, 2048); ++ pci_config.register_bar(1, region.clone(), RegionType::Mem32Bit, false, 2048); ++ pci_config.register_bar(2, region.clone(), RegionType::Mem64Bit, true, 2048); ++ ++ #[cfg(target_arch = "x86_64")] ++ le_write_u32( ++ &mut pci_config.config, ++ BAR_0 as usize, ++ 2048 | BAR_IO_SPACE as u32, ++ ) ++ .unwrap(); ++ le_write_u32(&mut pci_config.config, BAR_0 as usize + REG_SIZE, 2048).unwrap(); ++ le_write_u32( ++ &mut pci_config.config, ++ BAR_0 as usize + 2 * REG_SIZE, ++ 2048 | BAR_MEM_64BIT as u32 | BAR_PREFETCH as u32, ++ ) ++ .unwrap(); ++ le_write_u16( ++ &mut pci_config.config, ++ COMMAND as usize, ++ COMMAND_IO_SPACE | COMMAND_MEMORY_SPACE, ++ ) ++ .unwrap(); ++ pci_config ++ .update_bar_mapping( ++ #[cfg(target_arch = "x86_64")] ++ &io_region, ++ &mem_region, ++ ) ++ .unwrap(); ++ ++ assert!(pci_config.unregister_bars(&bus).is_ok()); ++ } + } +-- +2.20.1 + diff --git a/0018-arm-use-the-HighPcieEcam-region.patch b/0018-arm-use-the-HighPcieEcam-region.patch new file mode 100644 index 0000000..47cc00c --- /dev/null +++ b/0018-arm-use-the-HighPcieEcam-region.patch @@ -0,0 +1,61 @@ +From afe05089a4284acef30a97fb88435fea46e29d8e Mon Sep 17 00:00:00 2001 +From: zhouli57 +Date: Fri, 11 Mar 2022 14:22:07 +0800 +Subject: [PATCH 3/8] arm: use the HighPcieEcam region + +We use 16MB ECAM region on arm, which only support 16 pcie buses, and +now we use the high ECAM region, which can support 256 pcie buses. + +Signed-off-by: zhouli57 +--- + machine/src/standard_vm/aarch64/mod.rs | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/machine/src/standard_vm/aarch64/mod.rs b/machine/src/standard_vm/aarch64/mod.rs +index 1e6fc6c..ddf8a41 100644 +--- a/machine/src/standard_vm/aarch64/mod.rs ++++ b/machine/src/standard_vm/aarch64/mod.rs +@@ -141,8 +141,8 @@ impl StdMachine { + sysbus, + pci_host: Arc::new(Mutex::new(PciHost::new( + &sys_mem, +- MEM_LAYOUT[LayoutEntryType::PcieEcam as usize], +- MEM_LAYOUT[LayoutEntryType::PcieMmio as usize], ++ MEM_LAYOUT[LayoutEntryType::HighPcieEcam as usize], ++ MEM_LAYOUT[LayoutEntryType::HighPcieMmio as usize], + ))), + boot_source: Arc::new(Mutex::new(vm_config.clone().boot_source)), + vm_state: Arc::new((Mutex::new(KvmVmState::Created), Condvar::new())), +@@ -221,14 +221,14 @@ impl StdMachineOps for StdMachine { + let root_bus = Arc::downgrade(&self.pci_host.lock().unwrap().root_bus); + let mmconfig_region_ops = PciHost::build_mmconfig_ops(self.pci_host.clone()); + let mmconfig_region = Region::init_io_region( +- MEM_LAYOUT[LayoutEntryType::PcieEcam as usize].1, ++ MEM_LAYOUT[LayoutEntryType::HighPcieEcam as usize].1, + mmconfig_region_ops, + ); + self.sys_mem + .root() + .add_subregion( + mmconfig_region, +- MEM_LAYOUT[LayoutEntryType::PcieEcam as usize].0, ++ MEM_LAYOUT[LayoutEntryType::HighPcieEcam as usize].0, + ) + .chain_err(|| "Failed to register ECAM in memory space.")?; + +@@ -645,9 +645,9 @@ impl EventLoopManager for StdMachine { + // + // * `fdt` - Flatted device-tree blob where node will be filled into. + fn generate_pci_host_node(fdt: &mut FdtBuilder) -> util::errors::Result<()> { +- let pcie_ecam_base = MEM_LAYOUT[LayoutEntryType::PcieEcam as usize].0; +- let pcie_ecam_size = MEM_LAYOUT[LayoutEntryType::PcieEcam as usize].1; +- let pcie_buses_num = MEM_LAYOUT[LayoutEntryType::PcieEcam as usize].1 >> 20; ++ let pcie_ecam_base = MEM_LAYOUT[LayoutEntryType::HighPcieEcam as usize].0; ++ let pcie_ecam_size = MEM_LAYOUT[LayoutEntryType::HighPcieEcam as usize].1; ++ let pcie_buses_num = MEM_LAYOUT[LayoutEntryType::HighPcieEcam as usize].1 >> 20; + let node = format!("pcie@{:x}", pcie_ecam_base); + let pci_node_dep = fdt.begin_node(&node)?; + fdt.set_property_string("compatible", "pci-host-ecam-generic")?; +-- +2.20.1 + diff --git a/0019-vfio-fix-hot-plug-the-same-device-multiple-times-pro.patch b/0019-vfio-fix-hot-plug-the-same-device-multiple-times-pro.patch new file mode 100644 index 0000000..1f58478 --- /dev/null +++ b/0019-vfio-fix-hot-plug-the-same-device-multiple-times-pro.patch @@ -0,0 +1,73 @@ +From 13e120e99398ece2ceab00f90d0087123309ea60 Mon Sep 17 00:00:00 2001 +From: "Xinle.Guo" +Date: Fri, 11 Mar 2022 14:50:48 +0800 +Subject: [PATCH 4/8] vfio: fix hot plug the same device multiple times problem + +It will success to hot plug the same device after the second +time. But this is not what we expected. So, we check if the +device name is repeated before get VFIO device. + +Signed-off-by: Xinle.Guo +--- + vfio/src/vfio_dev.rs | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +diff --git a/vfio/src/vfio_dev.rs b/vfio/src/vfio_dev.rs +index 9607b71..198421c 100644 +--- a/vfio/src/vfio_dev.rs ++++ b/vfio/src/vfio_dev.rs +@@ -464,6 +464,8 @@ pub struct VfioDevInfo { + pub struct VfioDevice { + /// File descriptor for a VFIO device instance. + pub fd: File, ++ /// Identify the unique VFIO device. ++ pub name: String, + /// Vfio group the device belongs to. + pub group: Weak, + /// Vfio container the device belongs to. +@@ -515,10 +517,12 @@ impl VfioDevice { + + let group = + Self::vfio_get_group(&path, mem_as).chain_err(|| "Failed to get iommu group")?; +- let fd = Self::vfio_get_device(&group, &path).chain_err(|| "Failed to get vfio device")?; ++ let (name, fd) = ++ Self::vfio_get_device(&group, &path).chain_err(|| "Failed to get vfio device")?; + let dev_info = Self::get_dev_info(&fd).chain_err(|| "Failed to get device info")?; + let vfio_dev = Arc::new(Mutex::new(VfioDevice { + fd, ++ name, + group: Arc::downgrade(&group), + container: group.container.clone(), + dev_info, +@@ -569,11 +573,18 @@ impl VfioDevice { + Ok(group) + } + +- fn vfio_get_device(group: &VfioGroup, name: &Path) -> Result { ++ fn vfio_get_device(group: &VfioGroup, name: &Path) -> Result<(String, File)> { + let mut dev_name: &str = ""; + if let Some(n) = name.file_name() { + dev_name = n.to_str().chain_err(|| "Invalid device path")?; + } ++ ++ for device in group.devices.lock().unwrap().iter() { ++ if device.1.lock().unwrap().name == dev_name { ++ bail!("Device {} is already attached", dev_name); ++ } ++ } ++ + let path: CString = CString::new(dev_name.as_bytes()) + .chain_err(|| "Failed to convert device name to CString type of data")?; + let ptr = path.as_ptr(); +@@ -589,7 +600,7 @@ impl VfioDevice { + + // Safe as we have verified that fd is a valid FD. + let device = unsafe { File::from_raw_fd(fd) }; +- Ok(device) ++ Ok((String::from(dev_name), device)) + } + + fn get_dev_info(device: &File) -> Result { +-- +2.20.1 + diff --git a/0020-machine-update-seccomp-rules.patch b/0020-machine-update-seccomp-rules.patch new file mode 100644 index 0000000..ebf29ee --- /dev/null +++ b/0020-machine-update-seccomp-rules.patch @@ -0,0 +1,226 @@ +From 639982129fb79cc8f175497cd5b091a6dfd3ec40 Mon Sep 17 00:00:00 2001 +From: zhouli57 +Date: Tue, 8 Mar 2022 15:42:13 +0800 +Subject: [PATCH 5/8] machine: update seccomp rules + +Fix the problem of snapshot failure caused by compiling with a new +version(1.57) of the compiler on openEuler 22.03 LTS. + +Signed-off-by: zhouli57 +--- + machine/src/micro_vm/syscall.rs | 46 ++++++++++++++++---- + machine/src/standard_vm/aarch64/syscall.rs | 33 +++++++++++---- + machine/src/standard_vm/x86_64/syscall.rs | 49 +++++++++++++++++----- + 3 files changed, 102 insertions(+), 26 deletions(-) + +diff --git a/machine/src/micro_vm/syscall.rs b/machine/src/micro_vm/syscall.rs +index ff066a9..5e9c6d8 100644 +--- a/machine/src/micro_vm/syscall.rs ++++ b/machine/src/micro_vm/syscall.rs +@@ -22,6 +22,7 @@ const FUTEX_CMP_REQUEUE: u32 = 4; + const FUTEX_WAKE_OP: u32 = 5; + const FUTEX_WAIT_BITSET: u32 = 9; + const FUTEX_PRIVATE_FLAG: u32 = 128; ++const FUTEX_CLOCK_REALTIME: u32 = 256; + const FUTEX_WAIT_PRIVATE: u32 = FUTEX_WAIT | FUTEX_PRIVATE_FLAG; + const FUTEX_WAKE_PRIVATE: u32 = FUTEX_WAKE | FUTEX_PRIVATE_FLAG; + const FUTEX_CMP_REQUEUE_PRIVATE: u32 = FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG; +@@ -88,12 +89,7 @@ pub fn syscall_whitelist() -> Vec { + BpfRule::new(libc::SYS_munmap), + BpfRule::new(libc::SYS_accept4), + BpfRule::new(libc::SYS_lseek), +- BpfRule::new(libc::SYS_futex) +- .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAKE_PRIVATE) +- .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT_PRIVATE) +- .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_CMP_REQUEUE_PRIVATE) +- .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAKE_OP_PRIVATE) +- .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT_BITSET_PRIVATE), ++ futex_rule(), + BpfRule::new(libc::SYS_exit), + BpfRule::new(libc::SYS_exit_group), + BpfRule::new(libc::SYS_rt_sigreturn), +@@ -121,9 +117,7 @@ pub fn syscall_whitelist() -> Vec { + BpfRule::new(libc::SYS_mkdir), + #[cfg(target_arch = "aarch64")] + BpfRule::new(libc::SYS_mkdirat), +- BpfRule::new(libc::SYS_madvise) +- .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_DONTNEED as u32) +- .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_WILLNEED as u32), ++ madvise_rule(), + ] + } + +@@ -181,3 +175,37 @@ fn ioctl_arch_allow_list(bpf_rule: BpfRule) -> BpfRule { + .add_constraint(SeccompCmpOpt::Eq, 1, KVM_GET_DEVICE_ATTR() as u32) + .add_constraint(SeccompCmpOpt::Eq, 1, KVM_GET_REG_LIST() as u32) + } ++ ++fn madvise_rule() -> BpfRule { ++ #[cfg(all(target_env = "musl", target_arch = "x86_64"))] ++ return BpfRule::new(libc::SYS_madvise) ++ .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_FREE as u32) ++ .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_DONTNEED as u32) ++ .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_WILLNEED as u32); ++ #[cfg(not(all(target_env = "musl", target_arch = "x86_64")))] ++ return BpfRule::new(libc::SYS_madvise) ++ .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_DONTNEED as u32) ++ .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_WILLNEED as u32); ++} ++ ++fn futex_rule() -> BpfRule { ++ #[cfg(target_env = "musl")] ++ return BpfRule::new(libc::SYS_futex) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAKE_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_CMP_REQUEUE_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAKE_OP_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT_BITSET_PRIVATE); ++ #[cfg(target_env = "gnu")] ++ return BpfRule::new(libc::SYS_futex) ++ .add_constraint( ++ SeccompCmpOpt::Eq, ++ 1, ++ FUTEX_WAIT_BITSET_PRIVATE | FUTEX_CLOCK_REALTIME, ++ ) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAKE_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_CMP_REQUEUE_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAKE_OP_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT_BITSET_PRIVATE); ++} +diff --git a/machine/src/standard_vm/aarch64/syscall.rs b/machine/src/standard_vm/aarch64/syscall.rs +index e8ecdd5..ed3140e 100644 +--- a/machine/src/standard_vm/aarch64/syscall.rs ++++ b/machine/src/standard_vm/aarch64/syscall.rs +@@ -28,6 +28,7 @@ const FUTEX_CMP_REQUEUE: u32 = 4; + const FUTEX_WAKE_OP: u32 = 5; + const FUTEX_WAIT_BITSET: u32 = 9; + const FUTEX_PRIVATE_FLAG: u32 = 128; ++const FUTEX_CLOCK_REALTIME: u32 = 256; + const FUTEX_WAIT_PRIVATE: u32 = FUTEX_WAIT | FUTEX_PRIVATE_FLAG; + const FUTEX_WAKE_PRIVATE: u32 = FUTEX_WAKE | FUTEX_PRIVATE_FLAG; + const FUTEX_CMP_REQUEUE_PRIVATE: u32 = FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG; +@@ -91,13 +92,7 @@ pub fn syscall_whitelist() -> Vec { + BpfRule::new(libc::SYS_munmap), + BpfRule::new(libc::SYS_accept4), + BpfRule::new(libc::SYS_lseek), +- BpfRule::new(libc::SYS_futex) +- .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT) +- .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAKE_PRIVATE) +- .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT_PRIVATE) +- .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_CMP_REQUEUE_PRIVATE) +- .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAKE_OP_PRIVATE) +- .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT_BITSET_PRIVATE), ++ futex_rule(), + BpfRule::new(libc::SYS_exit), + BpfRule::new(libc::SYS_exit_group), + BpfRule::new(libc::SYS_rt_sigreturn), +@@ -189,3 +184,27 @@ fn madvise_rule() -> BpfRule { + .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_WILLNEED as u32) + .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_DONTDUMP as u32); + } ++ ++fn futex_rule() -> BpfRule { ++ #[cfg(target_env = "musl")] ++ return BpfRule::new(libc::SYS_futex) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAKE_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_CMP_REQUEUE_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAKE_OP_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT_BITSET_PRIVATE); ++ #[cfg(target_env = "gnu")] ++ return BpfRule::new(libc::SYS_futex) ++ .add_constraint( ++ SeccompCmpOpt::Eq, ++ 1, ++ FUTEX_WAIT_BITSET_PRIVATE | FUTEX_CLOCK_REALTIME, ++ ) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAKE_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_CMP_REQUEUE_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAKE_OP_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT_BITSET_PRIVATE); ++} +diff --git a/machine/src/standard_vm/x86_64/syscall.rs b/machine/src/standard_vm/x86_64/syscall.rs +index f39170a..6f8e10d 100644 +--- a/machine/src/standard_vm/x86_64/syscall.rs ++++ b/machine/src/standard_vm/x86_64/syscall.rs +@@ -28,6 +28,7 @@ const FUTEX_CMP_REQUEUE: u32 = 4; + const FUTEX_WAKE_OP: u32 = 5; + const FUTEX_WAIT_BITSET: u32 = 9; + const FUTEX_PRIVATE_FLAG: u32 = 128; ++const FUTEX_CLOCK_REALTIME: u32 = 256; + const FUTEX_WAIT_PRIVATE: u32 = FUTEX_WAIT | FUTEX_PRIVATE_FLAG; + const FUTEX_WAKE_PRIVATE: u32 = FUTEX_WAKE | FUTEX_PRIVATE_FLAG; + const FUTEX_CMP_REQUEUE_PRIVATE: u32 = FUTEX_CMP_REQUEUE | FUTEX_PRIVATE_FLAG; +@@ -94,12 +95,7 @@ pub fn syscall_whitelist() -> Vec { + BpfRule::new(libc::SYS_munmap), + BpfRule::new(libc::SYS_accept4), + BpfRule::new(libc::SYS_lseek), +- BpfRule::new(libc::SYS_futex) +- .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAKE_PRIVATE) +- .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT_PRIVATE) +- .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_CMP_REQUEUE_PRIVATE) +- .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAKE_OP_PRIVATE) +- .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT_BITSET_PRIVATE), ++ futex_rule(), + BpfRule::new(libc::SYS_exit), + BpfRule::new(libc::SYS_exit_group), + BpfRule::new(libc::SYS_rt_sigreturn), +@@ -118,10 +114,7 @@ pub fn syscall_whitelist() -> Vec { + BpfRule::new(libc::SYS_statx), + BpfRule::new(libc::SYS_mkdir), + BpfRule::new(libc::SYS_unlink), +- BpfRule::new(libc::SYS_madvise) +- .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_DONTNEED as u32) +- .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_WILLNEED as u32) +- .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_DONTDUMP as u32), ++ madvise_rule(), + BpfRule::new(libc::SYS_msync), + BpfRule::new(libc::SYS_readlinkat), + #[cfg(target_env = "musl")] +@@ -202,3 +195,39 @@ fn ioctl_allow_list() -> BpfRule { + .add_constraint(SeccompCmpOpt::Eq, 1, KVM_SET_MSRS() as u32) + .add_constraint(SeccompCmpOpt::Eq, 1, KVM_SET_VCPU_EVENTS() as u32) + } ++ ++fn madvise_rule() -> BpfRule { ++ #[cfg(target_env = "musl")] ++ return BpfRule::new(libc::SYS_madvise) ++ .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_FREE as u32) ++ .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_DONTNEED as u32) ++ .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_WILLNEED as u32) ++ .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_DONTDUMP as u32); ++ #[cfg(target_env = "gnu")] ++ return BpfRule::new(libc::SYS_madvise) ++ .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_DONTNEED as u32) ++ .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_WILLNEED as u32) ++ .add_constraint(SeccompCmpOpt::Eq, 2, libc::MADV_DONTDUMP as u32); ++} ++ ++fn futex_rule() -> BpfRule { ++ #[cfg(target_env = "musl")] ++ return BpfRule::new(libc::SYS_futex) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAKE_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_CMP_REQUEUE_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAKE_OP_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT_BITSET_PRIVATE); ++ #[cfg(target_env = "gnu")] ++ return BpfRule::new(libc::SYS_futex) ++ .add_constraint( ++ SeccompCmpOpt::Eq, ++ 1, ++ FUTEX_WAIT_BITSET_PRIVATE | FUTEX_CLOCK_REALTIME, ++ ) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAKE_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_CMP_REQUEUE_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAKE_OP_PRIVATE) ++ .add_constraint(SeccompCmpOpt::Eq, 1, FUTEX_WAIT_BITSET_PRIVATE); ++} +-- +2.20.1 + diff --git a/0021-console-fix-the-bug-of-delete-park-fd.patch b/0021-console-fix-the-bug-of-delete-park-fd.patch new file mode 100644 index 0000000..ed17ecb --- /dev/null +++ b/0021-console-fix-the-bug-of-delete-park-fd.patch @@ -0,0 +1,57 @@ +From 0dbad5e4ba71f344767fee9d7180495d8cb26a84 Mon Sep 17 00:00:00 2001 +From: Jiajie Li +Date: Fri, 11 Mar 2022 21:24:16 +0800 +Subject: [PATCH 6/8] console: fix the bug of delete park fd + +Console device need two fd: listen_fd and stream_fd. Only one of +them can be valid in event loop. When stream_fd is valid, it will +park stream fd. At this time, send the reboot command through the +console device, deactivate function will delete both of these fds. +But the sequence is importent. If you delete listen_fd first, then +deleting stream_fd will try to delete the listen_fd which is it's +park fd. It will get an error: NoParkedFd. + +Fix it by delete delete stream_fd first. + +Signed-off-by: Jiajie Li +--- + virtio/src/console.rs | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/virtio/src/console.rs b/virtio/src/console.rs +index 48d3838..1192d28 100644 +--- a/virtio/src/console.rs ++++ b/virtio/src/console.rs +@@ -234,14 +234,6 @@ impl ConsoleHandler { + } + } + ChardevType::Socket(_) => { +- let listener_fd = locked_chardev.listener.as_ref().unwrap().as_raw_fd(); +- notifiers.push(EventNotifier::new( +- NotifierOperation::Delete, +- listener_fd, +- None, +- EventSet::IN, +- Vec::new(), +- )); + if let Some(stream_fd) = locked_chardev.stream_fd { + notifiers.push(EventNotifier::new( + NotifierOperation::Delete, +@@ -251,6 +243,14 @@ impl ConsoleHandler { + Vec::new(), + )); + } ++ let listener_fd = locked_chardev.listener.as_ref().unwrap().as_raw_fd(); ++ notifiers.push(EventNotifier::new( ++ NotifierOperation::Delete, ++ listener_fd, ++ None, ++ EventSet::IN, ++ Vec::new(), ++ )); + } + _ => (), + } +-- +2.20.1 + diff --git a/0022-docs-add-the-description-of-hot-plug-of-PCI-devices.patch b/0022-docs-add-the-description-of-hot-plug-of-PCI-devices.patch new file mode 100644 index 0000000..15bba51 --- /dev/null +++ b/0022-docs-add-the-description-of-hot-plug-of-PCI-devices.patch @@ -0,0 +1,26 @@ +From 00927b92ea59d61ac757f942c0b88a9413ab1105 Mon Sep 17 00:00:00 2001 +From: zhouli57 +Date: Sat, 12 Mar 2022 09:05:03 +0800 +Subject: [PATCH 7/8] docs: add the description of hot plug of PCI devices + +Signed-off-by: zhouli57 +--- + docs/qmp.md | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/docs/qmp.md b/docs/qmp.md +index be933fa..ceee6fd 100644 +--- a/docs/qmp.md ++++ b/docs/qmp.md +@@ -166,6 +166,8 @@ Add a device. + + * Guest kernel config: CONFIG_HOTPLUG_PCI_PCIE=y + ++* You are not advised to hot plug/unplug devices during VM startup, shutdown or suspension, or when the VM is under high pressure. In this case, the driver in the VM may not respond to requests, causing VM exceptions. ++ + #### Example + + ```json +-- +2.20.1 + diff --git a/0023-Modify-cargo-cllippy-warning-when-compiling-cargo-cl.patch b/0023-Modify-cargo-cllippy-warning-when-compiling-cargo-cl.patch new file mode 100644 index 0000000..a573d85 --- /dev/null +++ b/0023-Modify-cargo-cllippy-warning-when-compiling-cargo-cl.patch @@ -0,0 +1,1439 @@ +From 4df5013eb6ac7e2e24445bc87e4d92840c70611a Mon Sep 17 00:00:00 2001 +From: ace yan +Date: Sat, 12 Mar 2022 22:35:04 +0800 +Subject: [PATCH 8/8] Modify cargo cllippy warning when compiling cargo cllippy + in high version rust. + +Signed-off-by: Yan Wen +--- + acpi/src/aml_compiler.rs | 6 ++--- + address_space/src/address.rs | 2 +- + address_space/src/address_space.rs | 4 +-- + address_space/src/host_mmap.rs | 2 +- + address_space/src/region.rs | 2 +- + boot_loader/src/x86_64/bootparam.rs | 28 ++++++++++---------- + boot_loader/src/x86_64/direct_boot/mod.rs | 12 ++++----- + boot_loader/src/x86_64/standard_boot/mod.rs | 4 +-- + cpu/src/x86_64/caps.rs | 8 +----- + cpu/src/x86_64/mod.rs | 6 ++--- + devices/src/legacy/pflash.rs | 24 +++++++---------- + machine/src/lib.rs | 10 +++---- + machine/src/micro_vm/mod.rs | 6 ++--- + machine/src/standard_vm/aarch64/mod.rs | 9 ------- + machine/src/standard_vm/mod.rs | 12 ++++----- + machine/src/standard_vm/x86_64/ich9_lpc.rs | 1 - + machine_manager/src/cmdline.rs | 4 +-- + machine_manager/src/config/boot_source.rs | 3 --- + machine_manager/src/config/chardev.rs | 2 +- + machine_manager/src/config/devices.rs | 4 +-- + machine_manager/src/config/drive.rs | 19 +++---------- + machine_manager/src/config/machine_config.rs | 13 ++++----- + machine_manager/src/config/mod.rs | 8 +++--- + machine_manager/src/config/network.rs | 3 --- + machine_manager/src/config/vfio.rs | 10 +------ + machine_manager/src/event_loop.rs | 2 -- + machine_manager/src/lib.rs | 1 - + machine_manager/src/machine.rs | 6 ++--- + machine_manager/src/qmp/mod.rs | 2 -- + machine_manager/src/qmp/qmp_schema.rs | 7 ----- + machine_manager/src/socket.rs | 3 ++- + migration/src/header.rs | 2 ++ + migration/src/manager.rs | 4 +-- + migration_derive/src/field_parser.rs | 10 +++---- + migration_derive/src/lib.rs | 1 - + ozone/src/capability.rs | 2 +- + ozone/src/cgroup.rs | 4 +-- + pci/src/bus.rs | 4 +-- + pci/src/host.rs | 1 + + pci/src/lib.rs | 2 +- + pci/src/msix.rs | 8 +++--- + src/main.rs | 8 +++--- + util/src/arg_parser.rs | 6 ++--- + util/src/daemonize.rs | 2 -- + util/src/logger.rs | 3 --- + util/src/seccomp.rs | 2 -- + util/src/tap.rs | 2 +- + util/src/unix.rs | 2 -- + vfio/src/vfio_dev.rs | 9 +++---- + vfio/src/vfio_pci.rs | 6 +---- + virtio/src/balloon.rs | 6 +++-- + virtio/src/block.rs | 2 +- + virtio/src/queue.rs | 8 +++--- + virtio/src/vhost/kernel/mod.rs | 4 +-- + 54 files changed, 120 insertions(+), 201 deletions(-) + +diff --git a/acpi/src/aml_compiler.rs b/acpi/src/aml_compiler.rs +index 0c4c59d..3fa4fa0 100644 +--- a/acpi/src/aml_compiler.rs ++++ b/acpi/src/aml_compiler.rs +@@ -153,7 +153,7 @@ fn build_name_string(name: &str) -> Vec { + 2 => { + bytes.push(0x2E); + bytes.append(&mut build_name_seg(&remain_first)); +- bytes.append(&mut build_name_seg(&strs[1].to_string())); ++ bytes.append(&mut build_name_seg(strs[1])); + } + _ => { + bytes.push(0x2F); +@@ -161,7 +161,7 @@ fn build_name_string(name: &str) -> Vec { + bytes.append(&mut build_name_seg(&remain_first)); + + strs.iter().skip(1).for_each(|s| { +- bytes.extend(build_name_seg(&s.to_string())); ++ bytes.extend(build_name_seg(s)); + }) + } + } +@@ -604,7 +604,7 @@ impl AmlBuilder for AmlFieldUnit { + let mut bytes = self + .name + .as_ref() +- .map(|str| build_name_seg(&str)) ++ .map(|str| build_name_seg(str)) + .unwrap_or_else(|| vec![0x0_u8]); + bytes.extend(build_pkg_length(self.length as usize, false)); + bytes +diff --git a/address_space/src/address.rs b/address_space/src/address.rs +index 803b672..e7760c3 100644 +--- a/address_space/src/address.rs ++++ b/address_space/src/address.rs +@@ -143,7 +143,7 @@ impl PartialOrd for AddressRange { + /// Implement Ord trait for AddressRange. + impl Ord for AddressRange { + fn cmp(&self, other: &AddressRange) -> Ordering { +- self.partial_cmp(&other).unwrap() ++ self.partial_cmp(other).unwrap() + } + } + +diff --git a/address_space/src/address_space.rs b/address_space/src/address_space.rs +index 949c305..81774da 100644 +--- a/address_space/src/address_space.rs ++++ b/address_space/src/address_space.rs +@@ -112,7 +112,7 @@ impl AddressSpace { + pub fn register_listener(&self, listener: ListenerObj) -> Result<()> { + let mut locked_listener = listener.lock().unwrap(); + for fr in self.flat_view.load().0.iter() { +- locked_listener.handle_request(Some(&fr), None, ListenerReqType::AddRegion)?; ++ locked_listener.handle_request(Some(fr), None, ListenerReqType::AddRegion)?; + } + locked_listener.enable(); + +@@ -141,7 +141,7 @@ impl AddressSpace { + pub fn unregister_listener(&self, listener: ListenerObj) -> Result<()> { + let mut locked_listener = listener.lock().unwrap(); + for fr in self.flat_view.load().0.iter() { +- locked_listener.handle_request(Some(&fr), None, ListenerReqType::DeleteRegion)?; ++ locked_listener.handle_request(Some(fr), None, ListenerReqType::DeleteRegion)?; + } + locked_listener.disable(); + drop(locked_listener); +diff --git a/address_space/src/host_mmap.rs b/address_space/src/host_mmap.rs +index 27e768b..1a6b0a8 100644 +--- a/address_space/src/host_mmap.rs ++++ b/address_space/src/host_mmap.rs +@@ -220,7 +220,7 @@ pub fn create_host_mmaps( + if let Some(path) = &mem_config.mem_path { + let file_len = ranges.iter().fold(0, |acc, x| acc + x.1); + f_back = Some( +- FileBackend::new_mem(&path, file_len) ++ FileBackend::new_mem(path, file_len) + .chain_err(|| "Failed to create file that backs memory")?, + ); + } else if mem_config.mem_share { +diff --git a/address_space/src/region.rs b/address_space/src/region.rs +index f88c63e..7c9e8da 100644 +--- a/address_space/src/region.rs ++++ b/address_space/src/region.rs +@@ -358,7 +358,7 @@ impl Region { + /// + /// * `space` - The AddressSpace that the region belongs to. + pub(crate) fn set_belonged_address_space(&self, space: &Arc) { +- *self.space.write().unwrap() = Arc::downgrade(&space); ++ *self.space.write().unwrap() = Arc::downgrade(space); + } + + /// Release the address space this region belongs to, +diff --git a/boot_loader/src/x86_64/bootparam.rs b/boot_loader/src/x86_64/bootparam.rs +index 82beb21..8f1b35d 100644 +--- a/boot_loader/src/x86_64/bootparam.rs ++++ b/boot_loader/src/x86_64/bootparam.rs +@@ -267,22 +267,22 @@ mod test { + boot_params.setup_e820_entries(&config, &space); + assert_eq!(boot_params.e820_entries, 4); + +- unsafe { +- assert_eq!(boot_params.e820_table[0].addr, 0); +- assert_eq!(boot_params.e820_table[0].size, 0x0009_FC00); +- assert_eq!(boot_params.e820_table[0].type_, 1); ++ assert!(boot_params.e820_table[0].addr == 0); + +- assert_eq!(boot_params.e820_table[1].addr, 0x0009_FC00); +- assert_eq!(boot_params.e820_table[1].size, 0x400); +- assert_eq!(boot_params.e820_table[1].type_, 2); ++ assert!(boot_params.e820_table[0].addr == 0); ++ assert!(boot_params.e820_table[0].size == 0x0009_FC00); ++ assert!(boot_params.e820_table[0].type_ == 1); + +- assert_eq!(boot_params.e820_table[2].addr, 0x000F_0000); +- assert_eq!(boot_params.e820_table[2].size, 0); +- assert_eq!(boot_params.e820_table[2].type_, 2); ++ assert!(boot_params.e820_table[1].addr == 0x0009_FC00); ++ assert!(boot_params.e820_table[1].size == 0x400); ++ assert!(boot_params.e820_table[1].type_ == 2); + +- assert_eq!(boot_params.e820_table[3].addr, 0x0010_0000); +- assert_eq!(boot_params.e820_table[3].size, 0x0ff0_0000); +- assert_eq!(boot_params.e820_table[3].type_, 1); +- } ++ assert!(boot_params.e820_table[2].addr == 0x000F_0000); ++ assert!(boot_params.e820_table[2].size == 0); ++ assert!(boot_params.e820_table[2].type_ == 2); ++ ++ assert!(boot_params.e820_table[3].addr == 0x0010_0000); ++ assert!(boot_params.e820_table[3].size == 0x0ff0_0000); ++ assert!(boot_params.e820_table[3].type_ == 1); + } + } +diff --git a/boot_loader/src/x86_64/direct_boot/mod.rs b/boot_loader/src/x86_64/direct_boot/mod.rs +index 915b0cf..da0c123 100644 +--- a/boot_loader/src/x86_64/direct_boot/mod.rs ++++ b/boot_loader/src/x86_64/direct_boot/mod.rs +@@ -55,7 +55,7 @@ pub fn load_bzimage(kernel_image: &mut File) -> Result { + + kernel_image.seek(SeekFrom::Start(BOOT_HDR_START))?; + kernel_image +- .read_exact(&mut boot_hdr.as_mut_bytes()) ++ .read_exact(boot_hdr.as_mut_bytes()) + .chain_err(|| "Failed to read boot_hdr from bzImage kernel")?; + boot_hdr.type_of_loader = UNDEFINED_ID; + +@@ -115,7 +115,7 @@ fn load_kernel_image( + ) + }; + +- load_image(&mut kernel_image, vmlinux_start, &sys_mem).chain_err(|| "Failed to load image")?; ++ load_image(&mut kernel_image, vmlinux_start, sys_mem).chain_err(|| "Failed to load image")?; + + boot_layout.boot_ip = kernel_start; + +@@ -142,7 +142,7 @@ fn load_initrd( + let initrd_size = initrd_image.metadata().unwrap().len() as u64; + let initrd_addr = (initrd_addr_max - initrd_size) & !0xfff_u64; + +- load_image(&mut initrd_image, initrd_addr, &sys_mem).chain_err(|| "Failed to load image")?; ++ load_image(&mut initrd_image, initrd_addr, sys_mem).chain_err(|| "Failed to load image")?; + + header.set_ramdisk(initrd_addr as u32, initrd_size as u32); + +@@ -186,7 +186,7 @@ fn setup_boot_params( + boot_hdr: &RealModeKernelHeader, + ) -> Result<()> { + let mut boot_params = BootParams::new(*boot_hdr); +- boot_params.setup_e820_entries(&config, sys_mem); ++ boot_params.setup_e820_entries(config, sys_mem); + sys_mem + .write_object(&boot_params, GuestAddress(ZERO_PAGE_START)) + .chain_err(|| format!("Failed to load zero page to 0x{:x}", ZERO_PAGE_START))?; +@@ -244,7 +244,7 @@ pub fn load_linux( + ..Default::default() + }; + let mut boot_header = load_kernel_image( +- &config.kernel.as_ref().unwrap(), ++ config.kernel.as_ref().unwrap(), + sys_mem, + &mut boot_loader_layout, + )?; +@@ -252,7 +252,7 @@ pub fn load_linux( + load_initrd(config, sys_mem, &mut boot_header) + .chain_err(|| "Failed to load initrd to vm memory")?; + +- setup_kernel_cmdline(&config, sys_mem, &mut boot_header) ++ setup_kernel_cmdline(config, sys_mem, &mut boot_header) + .chain_err(|| "Failed to setup kernel cmdline")?; + + setup_boot_params(config, sys_mem, &boot_header).chain_err(|| "Failed to setup boot params")?; +diff --git a/boot_loader/src/x86_64/standard_boot/mod.rs b/boot_loader/src/x86_64/standard_boot/mod.rs +index 92a0552..49e8a03 100644 +--- a/boot_loader/src/x86_64/standard_boot/mod.rs ++++ b/boot_loader/src/x86_64/standard_boot/mod.rs +@@ -21,13 +21,13 @@ use address_space::AddressSpace; + use devices::legacy::{FwCfgEntryType, FwCfgOps}; + use util::byte_code::ByteCode; + ++use self::elf::load_elf_kernel; + use super::bootparam::RealModeKernelHeader; + use super::X86BootLoaderConfig; + use super::{BOOT_HDR_START, CMDLINE_START}; + use crate::errors::{ErrorKind, Result, ResultExt}; + use crate::x86_64::bootparam::{E820Entry, E820_RAM, E820_RESERVED, UEFI_OVMF_ID}; + use crate::x86_64::{INITRD_ADDR_MAX, SETUP_START}; +-use elf::load_elf_kernel; + + fn load_image( + image: &mut File, +@@ -219,7 +219,7 @@ pub fn load_linux( + if let Err(e) = boot_header.check_valid_kernel() { + match e.kind() { + ErrorKind::ElfKernel => { +- load_elf_kernel(&mut kernel_image, &sys_mem, fwcfg)?; ++ load_elf_kernel(&mut kernel_image, sys_mem, fwcfg)?; + return Ok(()); + } + _ => return Err(e), +diff --git a/cpu/src/x86_64/caps.rs b/cpu/src/x86_64/caps.rs +index 7b0a34c..4bf75fb 100644 +--- a/cpu/src/x86_64/caps.rs ++++ b/cpu/src/x86_64/caps.rs +@@ -40,13 +40,7 @@ impl X86CPUCaps { + X86CPUCaps { + has_xsave: kvm.check_extension(Cap::Xsave), + has_xcrs: kvm.check_extension(Cap::Xcrs), +- supported_msrs: kvm +- .get_msr_index_list() +- .unwrap() +- .as_slice() +- .iter() +- .copied() +- .collect(), ++ supported_msrs: kvm.get_msr_index_list().unwrap().as_slice().to_vec(), + } + } + +diff --git a/cpu/src/x86_64/mod.rs b/cpu/src/x86_64/mod.rs +index 7b7a183..37e0f84 100644 +--- a/cpu/src/x86_64/mod.rs ++++ b/cpu/src/x86_64/mod.rs +@@ -22,9 +22,9 @@ use kvm_bindings::{ + }; + use kvm_ioctls::{Kvm, VcpuFd}; + ++use self::cpuid::host_cpuid; + use crate::errors::{Result, ResultExt}; + use crate::CPU; +-use cpuid::host_cpuid; + use migration::{DeviceStateDesc, FieldDesc, MigrationHook, MigrationManager, StateTransfer}; + use util::byte_code::ByteCode; + +@@ -145,8 +145,8 @@ impl X86CPUState { + boot_config: &X86CPUBootConfig, + ) -> Result<()> { + self.setup_lapic(vcpu_fd)?; +- self.setup_regs(&boot_config); +- self.setup_sregs(vcpu_fd, &boot_config)?; ++ self.setup_regs(boot_config); ++ self.setup_sregs(vcpu_fd, boot_config)?; + self.setup_fpu(); + self.setup_msrs(); + +diff --git a/devices/src/legacy/pflash.rs b/devices/src/legacy/pflash.rs +index 0446f91..36f708d 100644 +--- a/devices/src/legacy/pflash.rs ++++ b/devices/src/legacy/pflash.rs +@@ -251,24 +251,19 @@ impl PFlash { + } + + fn query_devid(&mut self, offset: u64) -> Result { +- let mut resp: u32; + let index: u64 = offset + >> (self.bank_width.trailing_zeros() + self.max_device_width.trailing_zeros() + - self.device_width.trailing_zeros()); + + // Mask off upper bits, the rest (ident[2] and ident[3]) is not emulated. +- match index & 0xFF { +- 0 => { +- resp = self.ident[0]; +- } +- 1 => { +- resp = self.ident[1]; +- } ++ let mut resp: u32 = match index & 0xFF { ++ 0 => self.ident[0], ++ 1 => self.ident[1], + _ => { + debug!("Device ID 2 and 3 are not supported"); + return Ok(0); + } +- } ++ }; + + if self.device_width < self.bank_width { + let mut i: u32 = self.device_width; +@@ -283,7 +278,6 @@ impl PFlash { + } + + fn query_cfi(&mut self, offset: u64) -> Result { +- let mut resp: u32; + // Adjust index for expected device-width addressing. + let index: u64 = offset + >> (self.bank_width.trailing_zeros() + self.max_device_width.trailing_zeros() +@@ -293,7 +287,7 @@ impl PFlash { + return Err(ErrorKind::PFlashIndexOverflow(index, self.cfi_table.len()).into()); + } + +- resp = self.cfi_table[index as usize].into(); ++ let mut resp: u32 = self.cfi_table[index as usize].into(); + if self.device_width != self.max_device_width { + if self.device_width != 1 || self.bank_width > 4 { + return Err( +@@ -359,7 +353,7 @@ impl PFlash { + std::slice::from_raw_parts_mut((host_addr + offset) as *mut u8, data.len() as usize) + }; + data.as_mut() +- .write_all(&src) ++ .write_all(src) + .chain_err(|| "Failed to read data from PFlash Rom")?; + + Ok(()) +@@ -378,7 +372,7 @@ impl PFlash { + let mut dst = unsafe { + std::slice::from_raw_parts_mut((host_addr + offset) as *mut u8, data.len() as usize) + }; +- dst.write_all(&data) ++ dst.write_all(data) + .chain_err(|| "Failed to write data to PFlash Rom")?; + + Ok(()) +@@ -476,7 +470,7 @@ impl PFlash { + match self.cmd { + 0x10 | 0x40 => { + if !self.read_only { +- if let Err(e) = self.write_data(&data, offset) { ++ if let Err(e) = self.write_data(data, offset) { + error!("Failed to write to PFlash device: {}.", e.display_chain()); + } + if let Err(e) = self.update_content(offset, data_len.into()) { +@@ -592,7 +586,7 @@ impl PFlash { + match self.cmd { + 0xe8 => { + if !self.read_only { +- if let Err(e) = self.write_data(&data, offset) { ++ if let Err(e) = self.write_data(data, offset) { + error!("Failed to write to PFlash device: {}.", e.display_chain()); + } + } else { +diff --git a/machine/src/lib.rs b/machine/src/lib.rs +index 7f88b22..e759bd8 100644 +--- a/machine/src/lib.rs ++++ b/machine/src/lib.rs +@@ -180,7 +180,7 @@ pub trait MachineOps { + let mut mem_mappings = Vec::new(); + if !is_migrate { + let ram_ranges = self.arch_ram_ranges(mem_config.mem_size); +- mem_mappings = create_host_mmaps(&ram_ranges, &mem_config, nr_cpus) ++ mem_mappings = create_host_mmaps(&ram_ranges, mem_config, nr_cpus) + .chain_err(|| "Failed to mmap guest ram.")?; + } + +@@ -253,7 +253,7 @@ pub trait MachineOps { + if let Some(boot_config) = boot_cfg { + for cpu_index in 0..nr_cpus as usize { + cpus[cpu_index as usize] +- .realize(&boot_config) ++ .realize(boot_config) + .chain_err(|| { + format!( + "Failed to realize arch cpu register for CPU {}/KVM", +@@ -529,7 +529,7 @@ pub trait MachineOps { + host: &str, + multifunc: bool, + ) -> Result<()> { +- let (devfn, parent_bus) = self.get_devfn_and_parent_bus(&bdf)?; ++ let (devfn, parent_bus) = self.get_devfn_and_parent_bus(bdf)?; + let path = format!("/sys/bus/pci/devices/{}", host); + let device = VfioDevice::new(Path::new(&path), self.get_sys_mem()) + .chain_err(|| "Failed to create vfio device.")?; +@@ -595,7 +595,7 @@ pub trait MachineOps { + device: Arc>, + multi_func: bool, + ) -> Result<()> { +- let (devfn, parent_bus) = self.get_devfn_and_parent_bus(&bdf)?; ++ let (devfn, parent_bus) = self.get_devfn_and_parent_bus(bdf)?; + let sys_mem = self.get_sys_mem(); + let pcidev = VirtioPciDevice::new( + id.to_string(), +@@ -616,7 +616,7 @@ pub trait MachineOps { + let pci_host = self.get_pci_host()?; + let locked_pci_host = pci_host.lock().unwrap(); + let bus = +- if let Some((bus, _)) = PciBus::find_attached_bus(&locked_pci_host.root_bus, &dev_id) { ++ if let Some((bus, _)) = PciBus::find_attached_bus(&locked_pci_host.root_bus, dev_id) { + bus + } else { + bail!("Bus not found, dev id {}", dev_id); +diff --git a/machine/src/micro_vm/mod.rs b/machine/src/micro_vm/mod.rs +index 5952c58..c3bffdd 100644 +--- a/machine/src/micro_vm/mod.rs ++++ b/machine/src/micro_vm/mod.rs +@@ -906,7 +906,7 @@ impl DeviceInterface for LightMachine { + current: true, + qom_path: String::from("/machine/unattached/device[") + + &cpu_index.to_string() +- + &"]".to_string(), ++ + "]", + halted: false, + props: Some(cpu_instance), + CPU: cpu_index as isize, +@@ -971,9 +971,7 @@ impl DeviceInterface for LightMachine { + vcpus_count: 1, + props: cpu_instance, + qom_path: Some( +- String::from("/machine/unattached/device[") +- + &cpu_index.to_string() +- + &"]".to_string(), ++ String::from("/machine/unattached/device[") + &cpu_index.to_string() + "]", + ), + }; + hotplug_vec.push(serde_json::to_value(hotpluggable_cpu).unwrap()); +diff --git a/machine/src/standard_vm/aarch64/mod.rs b/machine/src/standard_vm/aarch64/mod.rs +index ddf8a41..3fd2de3 100644 +--- a/machine/src/standard_vm/aarch64/mod.rs ++++ b/machine/src/standard_vm/aarch64/mod.rs +@@ -155,15 +155,6 @@ impl StdMachine { + }) + } + +- /// Run `LightMachine` with `paused` flag. +- /// +- /// # Arguments +- /// +- /// * `paused` - Flag for `paused` when `LightMachine` starts to run. +- pub fn run(&self, paused: bool) -> Result<()> { +- ::vm_start(paused, &self.cpus, &mut self.vm_state.0.lock().unwrap()) +- } +- + pub fn handle_reset_request(vm: &Arc>) -> Result<()> { + use crate::errors::ResultExt; + +diff --git a/machine/src/standard_vm/mod.rs b/machine/src/standard_vm/mod.rs +index c96f89a..98916f1 100644 +--- a/machine/src/standard_vm/mod.rs ++++ b/machine/src/standard_vm/mod.rs +@@ -607,12 +607,12 @@ impl StdMachine { + + if dev.vhost_type.is_some() { + let net = Arc::new(Mutex::new(VhostKern::Net::new(&dev, self.get_sys_mem()))); +- self.add_virtio_pci_device(&args.id, &pci_bdf, net, multifunction) ++ self.add_virtio_pci_device(&args.id, pci_bdf, net, multifunction) + .chain_err(|| "Failed to add virtio net device")?; + } else { + let net_id = dev.id.clone(); + let net = Arc::new(Mutex::new(virtio::Net::new(dev))); +- self.add_virtio_pci_device(&args.id, &pci_bdf, net.clone(), multifunction) ++ self.add_virtio_pci_device(&args.id, pci_bdf, net.clone(), multifunction) + .chain_err(|| "Failed to add virtio net device")?; + MigrationManager::register_device_instance_mutex_with_id( + VirtioNetState::descriptor(), +@@ -684,7 +684,7 @@ impl DeviceInterface for StdMachine { + current: true, + qom_path: String::from("/machine/unattached/device[") + + &cpu_index.to_string() +- + &"]".to_string(), ++ + "]", + halted: false, + props: Some(cpu_instance), + CPU: cpu_index as isize, +@@ -750,7 +750,7 @@ impl DeviceInterface for StdMachine { + "virtio-blk-pci" => { + if let Err(e) = self.plug_virtio_pci_blk(&pci_bdf, args.as_ref()) { + error!("{}", e.display_chain()); +- let err_str = format!("Failed to add virtio pci blk: {}", e.to_string()); ++ let err_str = format!("Failed to add virtio pci blk: {}", e); + return Response::create_error_response( + qmp_schema::QmpErrorClass::GenericError(err_str), + None, +@@ -760,7 +760,7 @@ impl DeviceInterface for StdMachine { + "virtio-net-pci" => { + if let Err(e) = self.plug_virtio_pci_net(&pci_bdf, args.as_ref()) { + error!("{}", e.display_chain()); +- let err_str = format!("Failed to add virtio pci net: {}", e.to_string()); ++ let err_str = format!("Failed to add virtio pci net: {}", e); + return Response::create_error_response( + qmp_schema::QmpErrorClass::GenericError(err_str), + None, +@@ -794,7 +794,7 @@ impl DeviceInterface for StdMachine { + error!("{}", e.display_chain()); + error!("Failed to detach device"); + } +- let err_str = format!("Failed to plug device: {}", e.to_string()); ++ let err_str = format!("Failed to plug device: {}", e); + Response::create_error_response( + qmp_schema::QmpErrorClass::GenericError(err_str), + None, +diff --git a/machine/src/standard_vm/x86_64/ich9_lpc.rs b/machine/src/standard_vm/x86_64/ich9_lpc.rs +index 9053bd4..24a8770 100644 +--- a/machine/src/standard_vm/x86_64/ich9_lpc.rs ++++ b/machine/src/standard_vm/x86_64/ich9_lpc.rs +@@ -297,7 +297,6 @@ impl PciDevOps for LPCBridge { + ) { + if let Err(e) = self.update_pm_base() { + error!("Failed to update PM base addr: {}", e.display_chain()); +- return; + } + } + } +diff --git a/machine_manager/src/cmdline.rs b/machine_manager/src/cmdline.rs +index b8e3645..24c34ab 100644 +--- a/machine_manager/src/cmdline.rs ++++ b/machine_manager/src/cmdline.rs +@@ -401,6 +401,7 @@ pub fn create_vmconfig(args: &ArgMatches) -> Result { + add_args_to_config!((args.value_of("smp")), vm_cfg, add_cpu); + add_args_to_config!((args.value_of("kernel")), vm_cfg, add_kernel); + add_args_to_config!((args.value_of("initrd-file")), vm_cfg, add_initrd); ++ add_args_to_config!((args.value_of("serial")), vm_cfg, add_serial); + add_args_to_config!( + (args.is_present("mem-prealloc")), + vm_cfg, +@@ -417,9 +418,8 @@ pub fn create_vmconfig(args: &ArgMatches) -> Result { + add_args_to_config_multi!((args.values_of("object")), vm_cfg, add_object); + add_args_to_config_multi!((args.values_of("netdev")), vm_cfg, add_netdev); + add_args_to_config_multi!((args.values_of("chardev")), vm_cfg, add_chardev); +- add_args_to_config_multi!((args.values_of("device")), vm_cfg, add_devices); ++ add_args_to_config_multi!((args.values_of("device")), vm_cfg, add_device); + add_args_to_config_multi!((args.values_of("global")), vm_cfg, add_global_config); +- add_args_to_config!((args.value_of("serial")), vm_cfg, add_serial); + + if let Some(s) = args.value_of("trace") { + add_trace_events(&s)?; +diff --git a/machine_manager/src/config/boot_source.rs b/machine_manager/src/config/boot_source.rs +index 81b9d1e..81cc0f5 100644 +--- a/machine_manager/src/config/boot_source.rs ++++ b/machine_manager/src/config/boot_source.rs +@@ -10,9 +10,6 @@ + // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + // See the Mulan PSL v2 for more details. + +-extern crate serde; +-extern crate serde_json; +- + use std::fmt; + use std::path::PathBuf; + +diff --git a/machine_manager/src/config/chardev.rs b/machine_manager/src/config/chardev.rs +index 187de49..2eb435b 100644 +--- a/machine_manager/src/config/chardev.rs ++++ b/machine_manager/src/config/chardev.rs +@@ -221,7 +221,7 @@ impl VmConfig { + } + } + _ => { +- let chardev_config = serial_config.to_string() + &",id=serial_chardev".to_string(); ++ let chardev_config = serial_config.to_string() + ",id=serial_chardev"; + self.add_chardev(&chardev_config) + .chain_err(|| "Failed to add chardev")?; + "serial_chardev" +diff --git a/machine_manager/src/config/devices.rs b/machine_manager/src/config/devices.rs +index c9d60bd..cfc972c 100644 +--- a/machine_manager/src/config/devices.rs ++++ b/machine_manager/src/config/devices.rs +@@ -14,11 +14,11 @@ use super::errors::Result; + use super::{CmdParser, VmConfig}; + + impl VmConfig { +- pub fn add_devices(&mut self, device_config: &str) -> Result<()> { ++ pub fn add_device(&mut self, device_config: &str) -> Result<()> { + let mut cmd_params = CmdParser::new("device"); + cmd_params.push(""); + +- cmd_params.get_parameters(&device_config)?; ++ cmd_params.get_parameters(device_config)?; + if let Some(device_type) = cmd_params.get_value::("")? { + self.devices.push((device_type, device_config.to_string())); + } +diff --git a/machine_manager/src/config/drive.rs b/machine_manager/src/config/drive.rs +index 9670161..88d78f2 100644 +--- a/machine_manager/src/config/drive.rs ++++ b/machine_manager/src/config/drive.rs +@@ -10,9 +10,6 @@ + // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + // See the Mulan PSL v2 for more details. + +-extern crate serde; +-extern crate serde_json; +- + use std::fs::metadata; + use std::os::linux::fs::MetadataExt; + use std::path::Path; +@@ -276,7 +273,7 @@ pub fn parse_blk(vm_config: &mut VmConfig, drive_config: &str) -> Result Self { +- PFlashConfig { +- path_on_host: String::new(), +- read_only: false, +- unit: 0_usize, +- } +- } +-} +- + impl ConfigCheck for PFlashConfig { + fn check(&self) -> Result<()> { + if self.path_on_host.len() > MAX_PATH_LENGTH { +@@ -325,10 +312,10 @@ impl VmConfig { + }; + match drive_type.as_str() { + "none" => { +- self.add_block_drive(&drive_config)?; ++ self.add_block_drive(drive_config)?; + } + "pflash" => { +- self.add_pflash(&drive_config)?; ++ self.add_pflash(drive_config)?; + } + _ => { + bail!("Unknow 'if' argument: {:?}", drive_type.as_str()); +diff --git a/machine_manager/src/config/machine_config.rs b/machine_manager/src/config/machine_config.rs +index f1b5533..92fddab 100644 +--- a/machine_manager/src/config/machine_config.rs ++++ b/machine_manager/src/config/machine_config.rs +@@ -10,9 +10,6 @@ + // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + // See the Mulan PSL v2 for more details. + +-extern crate serde; +-extern crate serde_json; +- + use std::str::FromStr; + + use serde::{Deserialize, Serialize}; +@@ -238,7 +235,7 @@ impl VmConfig { + } + + pub fn add_mem_path(&mut self, mem_path: &str) -> Result<()> { +- self.machine_config.mem_config.mem_path = Some(mem_path.replace("\"", "")); ++ self.machine_config.mem_config.mem_path = Some(mem_path.replace('\"', "")); + Ok(()) + } + +@@ -251,8 +248,8 @@ fn memory_unit_conversion(origin_value: &str) -> Result { + if (origin_value.ends_with('M') | origin_value.ends_with('m')) + && (origin_value.contains('M') ^ origin_value.contains('m')) + { +- let value = origin_value.replacen("M", "", 1); +- let value = value.replacen("m", "", 1); ++ let value = origin_value.replacen('M', "", 1); ++ let value = value.replacen('m', "", 1); + get_inner( + value + .parse::() +@@ -264,8 +261,8 @@ fn memory_unit_conversion(origin_value: &str) -> Result { + } else if (origin_value.ends_with('G') | origin_value.ends_with('g')) + && (origin_value.contains('G') ^ origin_value.contains('g')) + { +- let value = origin_value.replacen("G", "", 1); +- let value = value.replacen("g", "", 1); ++ let value = origin_value.replacen('G', "", 1); ++ let value = value.replacen('g', "", 1); + get_inner( + value + .parse::() +diff --git a/machine_manager/src/config/mod.rs b/machine_manager/src/config/mod.rs +index 14e2ec8..56e8a51 100644 +--- a/machine_manager/src/config/mod.rs ++++ b/machine_manager/src/config/mod.rs +@@ -123,7 +123,7 @@ fn parse_rng_obj(object_args: &str) -> Result { + let mut cmd_params = CmdParser::new("rng-object"); + cmd_params.push("").push("id").push("filename"); + +- cmd_params.parse(&object_args)?; ++ cmd_params.parse(object_args)?; + let id = if let Some(obj_id) = cmd_params.get_value::("id")? { + obj_id + } else { +@@ -221,7 +221,7 @@ impl VmConfig { + let mut cmd_params = CmdParser::new("object"); + cmd_params.push(""); + +- cmd_params.get_parameters(&object_args)?; ++ cmd_params.get_parameters(object_args)?; + let obj_type = cmd_params.get_value::("")?; + if obj_type.is_none() { + bail!("Object type not specified"); +@@ -229,11 +229,11 @@ impl VmConfig { + let device_type = obj_type.unwrap(); + match device_type.as_str() { + "iothread" => { +- self.add_iothread(&object_args) ++ self.add_iothread(object_args) + .chain_err(|| "Failed to add iothread")?; + } + "rng-random" => { +- let rng_cfg = parse_rng_obj(&object_args)?; ++ let rng_cfg = parse_rng_obj(object_args)?; + let id = rng_cfg.id.clone(); + let object_config = ObjConfig::Rng(rng_cfg); + if self.object.get(&id).is_none() { +diff --git a/machine_manager/src/config/network.rs b/machine_manager/src/config/network.rs +index 9d17ead..b0cdf76 100644 +--- a/machine_manager/src/config/network.rs ++++ b/machine_manager/src/config/network.rs +@@ -10,9 +10,6 @@ + // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + // See the Mulan PSL v2 for more details. + +-extern crate serde; +-extern crate serde_json; +- + use serde::{Deserialize, Serialize}; + + use super::{ +diff --git a/machine_manager/src/config/vfio.rs b/machine_manager/src/config/vfio.rs +index dc18615..8acb4df 100644 +--- a/machine_manager/src/config/vfio.rs ++++ b/machine_manager/src/config/vfio.rs +@@ -13,20 +13,12 @@ + use super::errors::{ErrorKind, Result}; + use crate::config::{CmdParser, ConfigCheck, MAX_STRING_LENGTH}; + ++#[derive(Default)] + pub struct VfioConfig { + pub host: String, + pub id: String, + } + +-impl Default for VfioConfig { +- fn default() -> Self { +- VfioConfig { +- host: String::new(), +- id: String::new(), +- } +- } +-} +- + impl ConfigCheck for VfioConfig { + fn check(&self) -> Result<()> { + if self.host.len() > MAX_STRING_LENGTH { +diff --git a/machine_manager/src/event_loop.rs b/machine_manager/src/event_loop.rs +index fa973f6..72ef64f 100644 +--- a/machine_manager/src/event_loop.rs ++++ b/machine_manager/src/event_loop.rs +@@ -10,8 +10,6 @@ + // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + // See the Mulan PSL v2 for more details. + +-extern crate util; +- + use std::collections::HashMap; + use std::sync::{Arc, Mutex}; + use std::{process, thread}; +diff --git a/machine_manager/src/lib.rs b/machine_manager/src/lib.rs +index 8de5dae..a544c60 100644 +--- a/machine_manager/src/lib.rs ++++ b/machine_manager/src/lib.rs +@@ -25,7 +25,6 @@ + extern crate log; + #[macro_use] + extern crate error_chain; +-extern crate serde_json; + + pub mod cmdline; + pub mod config; +diff --git a/machine_manager/src/machine.rs b/machine_manager/src/machine.rs +index df6d899..02d8900 100644 +--- a/machine_manager/src/machine.rs ++++ b/machine_manager/src/machine.rs +@@ -10,8 +10,6 @@ + // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + // See the Mulan PSL v2 for more details. + +-extern crate util; +- + use std::os::unix::io::RawFd; + use std::sync::Mutex; + +@@ -351,8 +349,8 @@ pub trait DeviceInterface { + let chardev_label = &path.label; + let info = ChardevInfo { + open: true, +- filename: chardev_path.to_string().replace("\"", ""), +- label: chardev_label.to_string().replace("\"", ""), ++ filename: chardev_path.to_string().replace('\"', ""), ++ label: chardev_label.to_string().replace('\"', ""), + }; + vec_chardev_info.push(info); + } +diff --git a/machine_manager/src/qmp/mod.rs b/machine_manager/src/qmp/mod.rs +index 365ef93..12e493a 100644 +--- a/machine_manager/src/qmp/mod.rs ++++ b/machine_manager/src/qmp/mod.rs +@@ -25,8 +25,6 @@ + //! 3. Qmp's message structure base is transformed by scripts from Qemu's + //! `qmp-schema.json`. It's can be compatible by Qemu's zoology. Those + //! transformed structures can be found in `machine_manager/src/qmp/qmp_schema.rs` +-extern crate serde; +-extern crate serde_json; + + #[allow(non_upper_case_globals)] + #[allow(non_camel_case_types)] +diff --git a/machine_manager/src/qmp/qmp_schema.rs b/machine_manager/src/qmp/qmp_schema.rs +index f1e0096..0058e94 100644 +--- a/machine_manager/src/qmp/qmp_schema.rs ++++ b/machine_manager/src/qmp/qmp_schema.rs +@@ -10,11 +10,6 @@ + // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + // See the Mulan PSL v2 for more details. + +-extern crate serde; +-extern crate serde_json; +-extern crate strum; +-extern crate strum_macros; +- + use serde::{Deserialize, Serialize}; + pub use serde_json::Value as Any; + use strum_macros::{EnumIter, EnumString, EnumVariantNames}; +@@ -1741,8 +1736,6 @@ impl Command for query_iothreads { + + #[cfg(test)] + mod tests { +- extern crate serde; +- extern crate serde_json; + use super::*; + + #[test] +diff --git a/machine_manager/src/socket.rs b/machine_manager/src/socket.rs +index c0813c4..594ef64 100644 +--- a/machine_manager/src/socket.rs ++++ b/machine_manager/src/socket.rs +@@ -197,7 +197,7 @@ impl Socket { + let performer = &socket_mutexed.performer.as_ref().unwrap(); + if let Err(e) = crate::qmp::handle_qmp( + stream_fd, +- &performer, ++ performer, + &mut shared_leak_bucket.lock().unwrap(), + ) { + error!("{}", e); +@@ -297,6 +297,7 @@ struct SocketStream { + /// `RawFd` for socket + socket_fd: RawFd, + /// Make `UnixStream` persistent without `drop` ++ #[allow(dead_code)] + persistent: Option, + } + +diff --git a/migration/src/header.rs b/migration/src/header.rs +index e39ab52..46833b4 100644 +--- a/migration/src/header.rs ++++ b/migration/src/header.rs +@@ -80,6 +80,7 @@ pub struct MigrationHeader { + /// Magic number for migration file/stream. + magic_num: [u8; 16], + /// Current version of migration. ++ #[allow(dead_code)] + current_version: u32, + /// Compatible version of migration. + compat_version: u32, +@@ -88,6 +89,7 @@ pub struct MigrationHeader { + /// Endianness of byte order. + byte_order: EndianType, + /// The type of hypervisor. ++ #[allow(dead_code)] + hypervisor_type: [u8; 8], + /// The version of hypervisor. + hypervisor_version: u32, +diff --git a/migration/src/manager.rs b/migration/src/manager.rs +index ef903f9..1ea194e 100644 +--- a/migration/src/manager.rs ++++ b/migration/src/manager.rs +@@ -71,11 +71,11 @@ pub trait MigrationHook: StateTransfer { + let device_alias = self.get_device_alias(); + let instance_id = InstanceId { + object_type: device_alias, +- object_id: id_remap(&id), ++ object_id: id_remap(id), + }; + + writer +- .write_all(&instance_id.as_bytes()) ++ .write_all(instance_id.as_bytes()) + .chain_err(|| "Failed to write instance id.")?; + writer + .write_all(&state_data) +diff --git a/migration_derive/src/field_parser.rs b/migration_derive/src/field_parser.rs +index 2318a74..2403399 100644 +--- a/migration_derive/src/field_parser.rs ++++ b/migration_derive/src/field_parser.rs +@@ -21,7 +21,7 @@ pub fn parse_fields(input: &syn::Fields, ident: &syn::Ident) -> Vec { + let pairs = name_fields.named.pairs(); +- for field in pairs.into_iter() { ++ for field in pairs { + fields.push(parse_field(field, ident)); + } + } +@@ -51,11 +51,7 @@ fn parse_field( + let ty = input.value().ty.clone(); + let (ty_ident, len, is_array) = parse_ty(ty); + let type_name = if is_array { +- format!( +- "[{};{}]", +- ty_ident.path.get_ident().unwrap().to_string(), +- len +- ) ++ format!("[{};{}]", ty_ident.path.get_ident().unwrap(), len) + } else { + ty_ident.path.get_ident().unwrap().to_string() + }; +@@ -113,7 +109,7 @@ pub fn parse_fields_default(input: &syn::Fields) -> Vec { + let pairs = name_fields.named.pairs(); +- for field in pairs.into_iter() { ++ for field in pairs { + fields.push(parse_field_default(field)); + } + } +diff --git a/migration_derive/src/lib.rs b/migration_derive/src/lib.rs +index abb17b4..a71ab54 100644 +--- a/migration_derive/src/lib.rs ++++ b/migration_derive/src/lib.rs +@@ -50,7 +50,6 @@ + + #[macro_use] + extern crate syn; +-extern crate quote; + + use proc_macro::TokenStream; + use quote::quote; +diff --git a/ozone/src/capability.rs b/ozone/src/capability.rs +index d1fb21d..e7eae70 100644 +--- a/ozone/src/capability.rs ++++ b/ozone/src/capability.rs +@@ -140,7 +140,7 @@ pub fn set_capability_for_ozone(capability: &str) -> Result<()> { + } + + for item in all_caps.iter() { +- if cap_add_arr.contains(&item.0) { ++ if cap_add_arr.contains(item.0) { + continue; + } + if has_cap(item.1 .0).chain_err(|| ErrorKind::CapsError("CAPGET"))? { +diff --git a/ozone/src/cgroup.rs b/ozone/src/cgroup.rs +index c5763d4..8ce6539 100644 +--- a/ozone/src/cgroup.rs ++++ b/ozone/src/cgroup.rs +@@ -112,8 +112,8 @@ fn get_base_location(controller: &str, exec_file: &str, name: &str) -> Result Result<()> { +- let write_path = get_base_location("cpuset", &exec_file, &name)?; +- write_cgroup_value(&write_path, "cpuset.mems", &node) ++ let write_path = get_base_location("cpuset", exec_file, name)?; ++ write_cgroup_value(&write_path, "cpuset.mems", node) + .chain_err(|| ErrorKind::WriteError("cpuset.mems".to_string(), node.to_string()))?; + + let mut upper_path = write_path.clone(); +diff --git a/pci/src/bus.rs b/pci/src/bus.rs +index 53f94d5..8fb9d1e 100644 +--- a/pci/src/bus.rs ++++ b/pci/src/bus.rs +@@ -125,7 +125,7 @@ impl PciBus { + } + if locked_bus.in_range(bus_num) { + for sub_bus in &locked_bus.child_buses { +- if let Some(b) = PciBus::find_bus_by_num(&sub_bus, bus_num) { ++ if let Some(b) = PciBus::find_bus_by_num(sub_bus, bus_num) { + return Some(b); + } + } +@@ -145,7 +145,7 @@ impl PciBus { + return Some((*bus).clone()); + } + for sub_bus in &locked_bus.child_buses { +- if let Some(b) = PciBus::find_bus_by_name(&sub_bus, bus_name) { ++ if let Some(b) = PciBus::find_bus_by_name(sub_bus, bus_name) { + return Some(b); + } + } +diff --git a/pci/src/host.rs b/pci/src/host.rs +index df7b617..1713c2e 100644 +--- a/pci/src/host.rs ++++ b/pci/src/host.rs +@@ -51,6 +51,7 @@ const ECAM_OFFSET_MASK: u64 = 0xfff; + #[derive(Clone)] + pub struct PciHost { + pub root_bus: Arc>, ++ #[allow(dead_code)] + device: Option>>, + #[cfg(target_arch = "x86_64")] + config_addr: u32, +diff --git a/pci/src/lib.rs b/pci/src/lib.rs +index 03b1b8c..87eb163 100644 +--- a/pci/src/lib.rs ++++ b/pci/src/lib.rs +@@ -225,7 +225,7 @@ pub fn init_multifunction( + parent_bus: Weak>, + ) -> Result<()> { + let mut header_type = +- le_read_u16(&config, HEADER_TYPE as usize)? & (!HEADER_TYPE_MULTIFUNC as u16); ++ le_read_u16(config, HEADER_TYPE as usize)? & (!HEADER_TYPE_MULTIFUNC as u16); + if multifunction { + header_type |= HEADER_TYPE_MULTIFUNC as u16; + } +diff --git a/pci/src/msix.rs b/pci/src/msix.rs +index 71d172e..cbf27ea 100644 +--- a/pci/src/msix.rs ++++ b/pci/src/msix.rs +@@ -364,7 +364,7 @@ impl MigrationHook for Msix { + + pub fn is_msix_enabled(msix_cap_offset: usize, config: &[u8]) -> bool { + let offset: usize = msix_cap_offset + MSIX_CAP_CONTROL as usize; +- let msix_ctl = le_read_u16(&config, offset).unwrap(); ++ let msix_ctl = le_read_u16(config, offset).unwrap(); + if msix_ctl & MSIX_CAP_ENABLE > 0 { + return true; + } +@@ -373,7 +373,7 @@ pub fn is_msix_enabled(msix_cap_offset: usize, config: &[u8]) -> bool { + + fn is_msix_func_masked(msix_cap_offset: usize, config: &[u8]) -> bool { + let offset: usize = msix_cap_offset + MSIX_CAP_CONTROL as usize; +- let msix_ctl = le_read_u16(&config, offset).unwrap(); ++ let msix_ctl = le_read_u16(config, offset).unwrap(); + if msix_ctl & MSIX_CAP_FUNC_MASK > 0 { + return true; + } +@@ -405,7 +405,7 @@ pub fn init_msix( + vector_nr: u32, + config: &mut PciConfig, + dev_id: Arc, +- id: &str, ++ _id: &str, + ) -> Result<()> { + if vector_nr > MSIX_TABLE_SIZE_MAX as u32 + 1 { + bail!("Too many msix vectors."); +@@ -440,7 +440,7 @@ pub fn init_msix( + config.msix = Some(msix.clone()); + + #[cfg(not(test))] +- MigrationManager::register_device_instance_mutex_with_id(MsixState::descriptor(), msix, id); ++ MigrationManager::register_device_instance_mutex_with_id(MsixState::descriptor(), msix, _id); + + Ok(()) + } +diff --git a/src/main.rs b/src/main.rs +index b0a7c77..1b974ee 100644 +--- a/src/main.rs ++++ b/src/main.rs +@@ -135,12 +135,12 @@ fn real_main(cmd_args: &arg_parser::ArgMatches, vm_config: &mut VmConfig) -> Res + EventLoop::object_init(&vm_config.iothreads)?; + register_kill_signal(); + +- let listeners = check_api_channel(&cmd_args, vm_config)?; ++ let listeners = check_api_channel(cmd_args, vm_config)?; + let mut sockets = Vec::new(); + let vm: Arc> = match vm_config.machine_config.mach_type { + MachineType::MicroVm => { + let vm = Arc::new(Mutex::new( +- LightMachine::new(&vm_config).chain_err(|| "Failed to init MicroVM")?, ++ LightMachine::new(vm_config).chain_err(|| "Failed to init MicroVM")?, + )); + MachineOps::realize(&vm, vm_config, cmd_args.is_present("incoming")) + .chain_err(|| "Failed to realize micro VM.")?; +@@ -153,7 +153,7 @@ fn real_main(cmd_args: &arg_parser::ArgMatches, vm_config: &mut VmConfig) -> Res + } + MachineType::StandardVm => { + let vm = Arc::new(Mutex::new( +- StdMachine::new(&vm_config).chain_err(|| "Failed to init StandardVM")?, ++ StdMachine::new(vm_config).chain_err(|| "Failed to init StandardVM")?, + )); + MachineOps::realize(&vm, vm_config, cmd_args.is_present("incoming")) + .chain_err(|| "Failed to realize standard VM.")?; +@@ -166,7 +166,7 @@ fn real_main(cmd_args: &arg_parser::ArgMatches, vm_config: &mut VmConfig) -> Res + } + MachineType::None => { + let vm = Arc::new(Mutex::new( +- StdMachine::new(&vm_config).chain_err(|| "Failed to init NoneVM")?, ++ StdMachine::new(vm_config).chain_err(|| "Failed to init NoneVM")?, + )); + EventLoop::set_manager(vm.clone(), None); + for listener in listeners { +diff --git a/util/src/arg_parser.rs b/util/src/arg_parser.rs +index 2285284..48ba493 100644 +--- a/util/src/arg_parser.rs ++++ b/util/src/arg_parser.rs +@@ -579,7 +579,7 @@ impl<'a> ArgMatches<'a> { + if let Some(index) = args.iter().position(|arg| arg == ARG_SEPARATOR) { + return (&args[..index], &args[index + 1..]); + } +- (&args, &[]) ++ (args, &[]) + } + + pub fn extra_args(&self) -> Vec { +@@ -592,14 +592,14 @@ fn parse_cmdline( + cmd_args: &[String], + allow_list: &[String], + ) -> Result<(ArgsMap, Vec, Vec)> { +- let (cmd_args, sub_args) = ArgMatches::split_arg(&cmd_args); ++ let (cmd_args, sub_args) = ArgMatches::split_arg(cmd_args); + let mut arg_map: BTreeMap> = BTreeMap::new(); + let mut multi_vec: Vec = Vec::new(); + + let mut i = (0, ""); + let mut j = 1; + for cmd_arg in &cmd_args[1..] { +- if !allow_list.contains(&cmd_arg) && cmd_arg.starts_with(PREFIX_CHARS_SHORT) { ++ if !allow_list.contains(cmd_arg) && cmd_arg.starts_with(PREFIX_CHARS_SHORT) { + return Err(ErrorKind::UnexpectedArguments(cmd_arg.to_string()).into()); + } + +diff --git a/util/src/daemonize.rs b/util/src/daemonize.rs +index 043251b..a057ebe 100644 +--- a/util/src/daemonize.rs ++++ b/util/src/daemonize.rs +@@ -31,8 +31,6 @@ + //! sent to the process group. + //! 8. Handle any `SIGCLD` signals. + +-extern crate libc; +- + use std::cmp::Ordering; + use std::fs::{File, OpenOptions}; + use std::io::prelude::*; +diff --git a/util/src/logger.rs b/util/src/logger.rs +index da155b4..ae562cb 100644 +--- a/util/src/logger.rs ++++ b/util/src/logger.rs +@@ -10,9 +10,6 @@ + // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + // See the Mulan PSL v2 for more details. + +-extern crate libc; +-extern crate log; +- + use std::io::prelude::*; + use std::sync::Mutex; + +diff --git a/util/src/seccomp.rs b/util/src/seccomp.rs +index 87591c9..40ab17e 100644 +--- a/util/src/seccomp.rs ++++ b/util/src/seccomp.rs +@@ -77,8 +77,6 @@ + //! ``` + //! This programe will be trapped. + +-extern crate libc; +- + use crate::errors::Result; + use crate::offset_of; + +diff --git a/util/src/tap.rs b/util/src/tap.rs +index 1668a71..1530f97 100644 +--- a/util/src/tap.rs ++++ b/util/src/tap.rs +@@ -106,7 +106,7 @@ impl Tap { + } + + pub fn write(&mut self, buf: &[u8]) -> IoResult { +- self.file.write(&buf) ++ self.file.write(buf) + } + + pub fn as_raw_fd(&self) -> RawFd { +diff --git a/util/src/unix.rs b/util/src/unix.rs +index bdfdc3f..a41c81a 100644 +--- a/util/src/unix.rs ++++ b/util/src/unix.rs +@@ -10,8 +10,6 @@ + // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + // See the Mulan PSL v2 for more details. + +-extern crate libc; +- + use std::fs::File; + use std::os::unix::io::AsRawFd; + +diff --git a/vfio/src/vfio_dev.rs b/vfio/src/vfio_dev.rs +index 198421c..db0c58d 100644 +--- a/vfio/src/vfio_dev.rs ++++ b/vfio/src/vfio_dev.rs +@@ -515,10 +515,9 @@ impl VfioDevice { + bail!("No provided host PCI device, use -device vfio-pci,host=DDDD:BB:DD.F"); + } + +- let group = +- Self::vfio_get_group(&path, mem_as).chain_err(|| "Failed to get iommu group")?; ++ let group = Self::vfio_get_group(path, mem_as).chain_err(|| "Failed to get iommu group")?; + let (name, fd) = +- Self::vfio_get_device(&group, &path).chain_err(|| "Failed to get vfio device")?; ++ Self::vfio_get_device(&group, path).chain_err(|| "Failed to get vfio device")?; + let dev_info = Self::get_dev_info(&fd).chain_err(|| "Failed to get device info")?; + let vfio_dev = Arc::new(Mutex::new(VfioDevice { + fd, +@@ -813,12 +812,12 @@ impl VfioDevice { + irq_set[0].count = irq_fds.len() as u32; + + // It is safe as enough memory space to save irq_set data. +- let mut data: &mut [u8] = unsafe { ++ let data: &mut [u8] = unsafe { + irq_set[0] + .data + .as_mut_slice(irq_fds.len() * size_of::()) + }; +- LittleEndian::write_i32_into(irq_fds.as_slice(), &mut data); ++ LittleEndian::write_i32_into(irq_fds.as_slice(), data); + // Safe as device is the owner of file, and we will verify the result is valid. + let ret = unsafe { ioctl_with_ref(&self.fd, VFIO_DEVICE_SET_IRQS(), &irq_set[0]) }; + if ret < 0 { +diff --git a/vfio/src/vfio_pci.rs b/vfio/src/vfio_pci.rs +index bfb2334..abc8f6c 100644 +--- a/vfio/src/vfio_pci.rs ++++ b/vfio/src/vfio_pci.rs +@@ -479,7 +479,7 @@ impl VfioPciDevice { + let write = move |data: &[u8], _: GuestAddress, offset: u64| -> bool { + let mut locked_msix = msix.lock().unwrap(); + locked_msix.table[offset as usize..(offset as usize + data.len())] +- .copy_from_slice(&data); ++ .copy_from_slice(data); + let vector = offset / MSIX_TABLE_ENTRY_SIZE as u64; + if locked_msix.is_vector_masked(vector as u16) { + return true; +@@ -955,7 +955,6 @@ impl PciDevOps for VfioPciDevice { + + if let Err(e) = self.setup_bars_mmap() { + error!("Failed to map bar regions, error is {}", e.display_chain()); +- return; + } + } + } else if ranges_overlap(offset, end, BAR_0 as usize, (BAR_5 as usize) + REG_SIZE) { +@@ -971,7 +970,6 @@ impl PciDevOps for VfioPciDevice { + &locked_parent_bus.mem_region, + ) { + error!("Failed to update bar, error is {}", e.display_chain()); +- return; + } + } + } else if ranges_overlap(offset, end, cap_offset, cap_offset + MSIX_CAP_SIZE as usize) { +@@ -983,12 +981,10 @@ impl PciDevOps for VfioPciDevice { + if !was_enable && is_enable { + if let Err(e) = self.vfio_enable_msix() { + error!("{}\nFailed to enable MSI-X.", e.display_chain()); +- return; + } + } else if was_enable && !is_enable { + if let Err(e) = self.vfio_disable_msix() { + error!("{}\nFailed to disable MSI-X.", e.display_chain()); +- return; + } + } + } else { +diff --git a/virtio/src/balloon.rs b/virtio/src/balloon.rs +index 300876e..a2aa067 100644 +--- a/virtio/src/balloon.rs ++++ b/virtio/src/balloon.rs +@@ -67,8 +67,10 @@ struct Iovec { + #[derive(Copy, Clone, Default)] + struct VirtioBalloonConfig { + /// Number of pages host wants Guest to give up. ++ #[allow(dead_code)] + pub num_pages: u32, + /// Number of pages we've actually got in balloon. ++ #[allow(dead_code)] + pub actual: u32, + } + +@@ -419,13 +421,13 @@ impl Listener for BlnMemInfo { + ListenerReqType::AddRegion => { + let fr = range.unwrap(); + if fr.owner.region_type() == RegionType::Ram { +- self.add_mem_range(&fr); ++ self.add_mem_range(fr); + } + } + ListenerReqType::DeleteRegion => { + let fr = range.unwrap(); + if fr.owner.region_type() == RegionType::Ram { +- self.delete_mem_range(&fr); ++ self.delete_mem_range(fr); + } + } + _ => {} +diff --git a/virtio/src/block.rs b/virtio/src/block.rs +index a2e35e8..6c36e77 100644 +--- a/virtio/src/block.rs ++++ b/virtio/src/block.rs +@@ -303,7 +303,7 @@ impl Request { + } + VIRTIO_BLK_T_GET_ID => { + if let Some(serial) = serial_num { +- let serial_vec = get_serial_num_config(&serial); ++ let serial_vec = get_serial_num_config(serial); + + for iov in self.iovec.iter() { + if (iov.iov_len as usize) < serial_vec.len() { +diff --git a/virtio/src/queue.rs b/virtio/src/queue.rs +index b2c7132..13409a8 100644 +--- a/virtio/src/queue.rs ++++ b/virtio/src/queue.rs +@@ -316,7 +316,7 @@ impl SplitVringDesc { + } + + if miss_cached { +- if let Err(ref e) = checked_offset_mem(&sys_mem, self.addr, u64::from(self.len)) { ++ if let Err(ref e) = checked_offset_mem(sys_mem, self.addr, u64::from(self.len)) { + error!( + "The memory of descriptor is invalid, {} ", + error_chain::ChainedError::display_chain(e), +@@ -653,7 +653,7 @@ impl SplitVring { + + fn is_invalid_memory(&self, sys_mem: &Arc, actual_size: u64) -> bool { + let desc_table_end = +- match checked_offset_mem(&sys_mem, self.desc_table, DESCRIPTOR_LEN * actual_size) { ++ match checked_offset_mem(sys_mem, self.desc_table, DESCRIPTOR_LEN * actual_size) { + Ok(addr) => addr, + Err(ref e) => { + error!( +@@ -667,7 +667,7 @@ impl SplitVring { + }; + + let desc_avail_end = match checked_offset_mem( +- &sys_mem, ++ sys_mem, + self.avail_ring, + VRING_AVAIL_LEN_EXCEPT_AVAILELEM + AVAILELEM_LEN * actual_size, + ) { +@@ -684,7 +684,7 @@ impl SplitVring { + }; + + if let Err(ref e) = checked_offset_mem( +- &sys_mem, ++ sys_mem, + self.used_ring, + VRING_USED_LEN_EXCEPT_USEDELEM + USEDELEM_LEN * actual_size, + ) { +diff --git a/virtio/src/vhost/kernel/mod.rs b/virtio/src/vhost/kernel/mod.rs +index 3a273eb..ccc85e9 100644 +--- a/virtio/src/vhost/kernel/mod.rs ++++ b/virtio/src/vhost/kernel/mod.rs +@@ -200,14 +200,14 @@ impl Listener for VhostMemInfo { + ) -> std::result::Result<(), address_space::errors::Error> { + match req_type { + ListenerReqType::AddRegion => { +- if Self::check_vhost_mem_range(&range.unwrap()) { ++ if Self::check_vhost_mem_range(range.unwrap()) { + self.add_mem_range(range.unwrap()); + } + } + ListenerReqType::DeleteRegion => { + let fr = range.unwrap(); + if fr.owner.region_type() == RegionType::Ram { +- self.delete_mem_range(&fr); ++ self.delete_mem_range(fr); + } + } + _ => {} +-- +2.20.1 + diff --git a/stratovirt.spec b/stratovirt.spec index 5f67662..c5cd468 100644 --- a/stratovirt.spec +++ b/stratovirt.spec @@ -6,7 +6,7 @@ Name: stratovirt Version: 2.1.0 -Release: 3 +Release: 4 Summary: StratoVirt is an opensource VMM(Virtual Machine Manager) which aims to perform next generation virtualization. License: Mulan PSL v2 @@ -28,6 +28,14 @@ Patch012: 0012-net-fix-the-bug-when-tap-is-abnormally-removed.patch Patch013: 0013-docs-boot-update-detailed-usage-for-standard-boot.patch Patch014: 0014-virtio-queue-fix-error-access-queue-s-host-virtual-a.patch Patch015: 0015-vfio-doc-create-a-new-document-for-using-vfio.patch +Patch016: 0016-docs-correct-the-command-for-booting-with-the-raw-im.patch +Patch017: 0017-pci-no-need-to-delete-the-unmapped-region.patch +Patch018: 0018-arm-use-the-HighPcieEcam-region.patch +Patch019: 0019-vfio-fix-hot-plug-the-same-device-multiple-times-pro.patch +Patch020: 0020-machine-update-seccomp-rules.patch +Patch021: 0021-console-fix-the-bug-of-delete-park-fd.patch +Patch022: 0022-docs-add-the-description-of-hot-plug-of-PCI-devices.patch +Patch023: 0023-Modify-cargo-cllippy-warning-when-compiling-cargo-cl.patch ExclusiveArch: x86_64 aarch64 @@ -82,6 +90,11 @@ chmod 555 ${RPM_BUILD_ROOT}/usr/bin/stratovirt chmod 555 ${RPM_BUILD_ROOT}/usr/bin/ozone %changelog +* Sun Mar 13 2022 Jie Yang - 2.1.0-4 +- Some bug fixes. +- Eliminate build warnings and clippy errors with Rust 1.57.0. +- Update docs. + * Fri Mar 01 2022 Jie Yang - 2.1.0-3 - Fix memory snapshot failure with hotplugged devices. - Fix address translation for virtio devices. -- Gitee