diff --git a/acpi/src/aml_compiler.rs b/acpi/src/aml_compiler.rs index f97216ae2eae04e4963fd37d419ae0650fd2ea52..54e7dbf38f8108c5cb2597cad8e8384821f3492f 100644 --- a/acpi/src/aml_compiler.rs +++ b/acpi/src/aml_compiler.rs @@ -224,12 +224,12 @@ impl AmlEisaId { impl AmlBuilder for AmlEisaId { fn aml_bytes(&self) -> Vec { let chars = self.name.chars().collect::>(); - let dword: u32 = (chars[0] as u32 - 0x40) << 26 - | (chars[1] as u32 - 0x40) << 21 - | (chars[2] as u32 - 0x40) << 16 - | chars[3].to_digit(16).unwrap() << 12 - | chars[4].to_digit(16).unwrap() << 8 - | chars[5].to_digit(16).unwrap() << 4 + let dword: u32 = ((chars[0] as u32 - 0x40) << 26) + | ((chars[1] as u32 - 0x40) << 21) + | ((chars[2] as u32 - 0x40) << 16) + | (chars[3].to_digit(16).unwrap() << 12) + | (chars[4].to_digit(16).unwrap() << 8) + | (chars[5].to_digit(16).unwrap() << 4) | chars[6].to_digit(16).unwrap(); let mut bytes = dword.as_bytes().to_vec(); @@ -290,7 +290,7 @@ impl AmlBuilder for AmlToUuid { for i in index { let mut chars = self.name.chars(); uuid_bytes.push( - (chars.nth(*i).unwrap().to_digit(16).unwrap() as u8) << 4 + ((chars.nth(*i).unwrap().to_digit(16).unwrap() as u8) << 4) | chars.next().unwrap().to_digit(16).unwrap() as u8, ); } @@ -339,16 +339,16 @@ fn build_pkg_length(length: usize, include_self: bool) -> Vec { bytes.push(pkg_length as u8); } 2 => { - bytes.push((1 << pkg_1byte_shift | (pkg_length & 0xF)) as u8); + bytes.push(((1 << pkg_1byte_shift) | (pkg_length & 0xF)) as u8); bytes.push((pkg_length >> pkg_2byte_shift) as u8); } 3 => { - bytes.push((2 << pkg_1byte_shift | (pkg_length & 0xF)) as u8); + bytes.push(((2 << pkg_1byte_shift) | (pkg_length & 0xF)) as u8); bytes.push((pkg_length >> pkg_2byte_shift) as u8); bytes.push((pkg_length >> pkg_3byte_shift) as u8); } 4 => { - bytes.push((3 << pkg_1byte_shift | (pkg_length & 0xF)) as u8); + bytes.push(((3 << pkg_1byte_shift) | (pkg_length & 0xF)) as u8); bytes.push((pkg_length >> pkg_2byte_shift) as u8); bytes.push((pkg_length >> pkg_3byte_shift) as u8); bytes.push((pkg_length >> pkg_4byte_shift) as u8); @@ -1321,7 +1321,7 @@ impl AmlBuilder for AmlDmaResource { fn aml_bytes(&self) -> Vec { let mut bytes = vec![0x2A, 1 << self.channel]; - let mut flags = (self.trans_sz as u8) | (self.dma_type as u8) << 5; + let mut flags = (self.trans_sz as u8) | ((self.dma_type as u8) << 5); if self.is_master { flags |= 1 << 2; // Bit-2 represents bus master } @@ -1706,9 +1706,9 @@ impl AmlBuilder for AmlExtendedInterrupt { bytes.extend(total_len.as_bytes()); let flags = self.usage as u8 - | (self.int_mode as u8) << 1 - | (self.int_polar as u8) << 2 - | (self.share as u8) << 3; + | ((self.int_mode as u8) << 1) + | ((self.int_polar as u8) << 2) + | ((self.share as u8) << 3); bytes.push(flags); bytes.push(self.irq_list.len() as u8); diff --git a/acpi/src/table_loader.rs b/acpi/src/table_loader.rs index e968e4d07a865a192171b4d5d641264f5d01d270..9e919273f1d960100b182860744cf666794b85cd 100644 --- a/acpi/src/table_loader.rs +++ b/acpi/src/table_loader.rs @@ -381,7 +381,7 @@ mod test { .is_ok()); let file_bytes = file_name.as_bytes(); - // SATETY: The "alloc" field of union consists of u8 members, so the access is safe. + // SAFETY: The "alloc" field of union consists of u8 members, so the access is safe. let alloc = unsafe { &table_loader.cmds.first().unwrap().entry.alloc }; assert_eq!( alloc.file[0..file_bytes.len()].to_vec(), diff --git a/address_space/src/address_space.rs b/address_space/src/address_space.rs index 980b187b697ec240fbe94b10536749e7b88a5aaa..b35909691d5594a96a157c616baf33c550306f05 100644 --- a/address_space/src/address_space.rs +++ b/address_space/src/address_space.rs @@ -625,7 +625,7 @@ impl AddressSpace { pub fn address_in_memory(&self, addr: GuestAddress, size: u64) -> bool { let view = &self.flat_view.load(); - view.find_flatrange(addr).map_or(false, |range| { + view.find_flatrange(addr).is_some_and(|range| { range.owner.region_type() == RegionType::Ram && size <= range.addr_range.end_addr().offset_from(addr) }) diff --git a/address_space/src/host_mmap.rs b/address_space/src/host_mmap.rs index cf6f8b17a93b312bd0216bad9c1cb97b2afffa82..c0f54f22e82684879c7377f2a1925d43ef30b70a 100644 --- a/address_space/src/host_mmap.rs +++ b/address_space/src/host_mmap.rs @@ -208,7 +208,7 @@ unsafe fn mem_prealloc(host_addr: u64, size: u64, nr_vcpus: u8) { trace::trace_scope_start!(pre_alloc, args = (size)); let page_size = host_page_size(); let threads = max_nr_threads(nr_vcpus); - let nr_pages = (size + page_size - 1) / page_size; + let nr_pages = size.div_ceil(page_size); let pages_per_thread = nr_pages / u64::from(threads); let left = nr_pages % u64::from(threads); let mut addr = host_addr; diff --git a/boot_loader/src/x86_64/direct_boot/gdt.rs b/boot_loader/src/x86_64/direct_boot/gdt.rs index 227387c3abbe43e2c2d58a7708e5e9c0c2416f42..e946cd39cafa48765f4257c27537087f17e2bae4 100644 --- a/boot_loader/src/x86_64/direct_boot/gdt.rs +++ b/boot_loader/src/x86_64/direct_boot/gdt.rs @@ -36,8 +36,8 @@ struct GdtEntry(pub u64); impl GdtEntry { fn new(flags: u64, base: u64, limit: u64) -> Self { - let base = (base & 0xff00_0000) << (56 - 24) | (base & 0x00ff_ffff) << 16; - let limit = (limit & 0x000f_0000) << (48 - 16) | (limit & 0x0000_ffff); + let base = ((base & 0xff00_0000) << (56 - 24)) | ((base & 0x00ff_ffff) << 16); + let limit = ((limit & 0x000f_0000) << (48 - 16)) | (limit & 0x0000_ffff); let flags = (flags & 0x0000_f0ff) << 40; GdtEntry(base | limit | flags) @@ -64,8 +64,8 @@ impl GdtEntry { // Bits(24 - 31): Base Address 24, 31 impl From for kvm_bindings::kvm_segment { fn from(item: GdtEntry) -> Self { - let base = (item.0 >> 16 & 0x00ff_ffff) | (item.0 >> (56 - 24) & 0xff00_0000); - let limit = (item.0 >> (48 - 16) & 0x000f_0000) | (item.0 & 0x0000_ffff); + let base = ((item.0 >> 16) & 0x00ff_ffff) | ((item.0 >> (56 - 24)) & 0xff00_0000); + let limit = ((item.0 >> (48 - 16)) & 0x000f_0000) | (item.0 & 0x0000_ffff); let flags = (item.0 >> 40) & 0x0000_f0ff; kvm_bindings::kvm_segment { diff --git a/cpu/src/x86_64/mod.rs b/cpu/src/x86_64/mod.rs index 06b2cc4eba75b046b074a93ed4fff983709f0f11..712f1d64c34c865327386182189cc099f0a7e889 100644 --- a/cpu/src/x86_64/mod.rs +++ b/cpu/src/x86_64/mod.rs @@ -109,10 +109,10 @@ impl X86CPUTopology { X86CPUTopology::default() } - pub fn set_topology(mut self, toplogy: (u8, u8, u8)) -> Self { - self.threads = toplogy.0; - self.cores = toplogy.1; - self.dies = toplogy.2; + pub fn set_topology(mut self, topology: (u8, u8, u8)) -> Self { + self.threads = topology.0; + self.cores = topology.1; + self.dies = topology.2; self } } @@ -406,7 +406,7 @@ impl X86CPUState { if entry.index == 0 { entry.ecx |= 1u32 << X86_FEATURE_HYPERVISOR; entry.ecx |= 1u32 << X86_FEATURE_TSC_DEADLINE_TIMER; - entry.ebx = self.apic_id << 24 | 8 << 8; + entry.ebx = (self.apic_id << 24) | (8 << 8); } } 2 => { diff --git a/devices/src/legacy/pflash.rs b/devices/src/legacy/pflash.rs index 009c9b29251d85ba7aeb93769d588b72fd47fc72..e0738eaecf0c8ad34f4f8360de90b1bf695380f7 100644 --- a/devices/src/legacy/pflash.rs +++ b/devices/src/legacy/pflash.rs @@ -780,11 +780,11 @@ impl SysBusDevOps for PFlash { match index { 0 => { - ret = self.ident[0] << 8 | self.ident[1]; + ret = (self.ident[0] << 8) | self.ident[1]; trace::pflash_manufacturer_id(ret); } 1 => { - ret = self.ident[2] << 8 | self.ident[3]; + ret = (self.ident[2] << 8) | self.ident[3]; trace::pflash_device_id(ret); } _ => { diff --git a/devices/src/legacy/pl011.rs b/devices/src/legacy/pl011.rs index 465173ba8eea13e76f721e8fb7e4f7041f4b1579..9ece4bb0a4997498053572e223423139c10ff4e1 100644 --- a/devices/src/legacy/pl011.rs +++ b/devices/src/legacy/pl011.rs @@ -49,9 +49,9 @@ const INT_TX: u32 = 1 << 5; // Receive interrupt bit const INT_RX: u32 = 1 << 4; // Framing/Panity/Break/Overrun error bits, bits 7~10. -const INT_E: u32 = 1 << 7 | 1 << 8 | 1 << 9 | 1 << 10; +const INT_E: u32 = (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10); // nUARTRI/nUARTCTS/nUARTDCD/nUARTDSR modem interrupt bits, bits 0~3. -const INT_MS: u32 = 1 | 1 << 1 | 1 << 2 | 1 << 3; +const INT_MS: u32 = 1 | (1 << 1) | (1 << 2) | (1 << 3); const PL011_FIFO_SIZE: usize = 16; diff --git a/devices/src/legacy/ramfb.rs b/devices/src/legacy/ramfb.rs index b0a1dc98b1f751ac04e43ea647c10c8d15b588fd..05965e66294c0ae1ffa7ed7d16c2253efa1cdfb3 100644 --- a/devices/src/legacy/ramfb.rs +++ b/devices/src/legacy/ramfb.rs @@ -53,7 +53,7 @@ pub struct RamfbConfig { pub install: bool, } -#[repr(packed)] +#[repr(C, packed)] struct RamfbCfg { _addr: u64, _fourcc: u32, diff --git a/devices/src/legacy/rtc.rs b/devices/src/legacy/rtc.rs index 4c324bf5e6c22acf464cb1032bb45f914632251e..f7fdc7c08acc1172c72e0ec865c8d3e8284ebbab 100644 --- a/devices/src/legacy/rtc.rs +++ b/devices/src/legacy/rtc.rs @@ -220,7 +220,7 @@ impl RTC { } RTC_REG_C => { // The interrupt request flag (IRQF), alarm interrupt flag (AF). - data[0] = 1 << 7 | 1 << 5; + data[0] = (1 << 7) | (1 << 5); } _ => { data[0] = self.cmos_data[self.cur_index as usize]; diff --git a/devices/src/pci/config.rs b/devices/src/pci/config.rs index db84bef81cf0ac2bc8b275839308861a1cc8d0c5..72fcab2b6f4ab1abbb04d6b67a4ebd0d4af47c7d 100644 --- a/devices/src/pci/config.rs +++ b/devices/src/pci/config.rs @@ -153,12 +153,12 @@ pub const MINIMUM_BAR_SIZE_FOR_MMIO: usize = 0x1000; const MINIMUM_BAR_SIZE_FOR_PIO: usize = 0x4; /// PCI Express capability registers, same as kernel defines - const PCI_EXT_CAP_VER_SHIFT: u8 = 16; const PCI_EXT_CAP_NEXT_SHIFT: u8 = 20; const PCI_EXP_VER2_SIZEOF: u8 = 0x3c; const PCI_EXP_FLAGS_VER2: u16 = 0x0002; const PCI_EXP_FLAGS_SLOT: u16 = 0x0100; + // PCIe type flag const PCI_EXP_FLAGS_TYPE_SHIFT: u16 = 4; const PCI_EXP_FLAGS_TYPE: u16 = 0x00f0; diff --git a/devices/src/pci/demo_device/dpy_device.rs b/devices/src/pci/demo_device/dpy_device.rs index 8248b9dd3c78fc4302aa3f66671ff3f01d6e962d..f7e36a17b4ed5e7d277c82f6a1e1328b19c7a4f7 100644 --- a/devices/src/pci/demo_device/dpy_device.rs +++ b/devices/src/pci/demo_device/dpy_device.rs @@ -223,12 +223,12 @@ impl DeviceTypeOperation for DemoDisplay { return self.unrealize(); } } - return self.sys_mem.write( + self.sys_mem.write( &mut buf.as_slice(), address_space::GuestAddress(mem_addr), buf.len() as u64, AddressAttr::Ram, - ); + ) } fn realize(&mut self) -> Result<()> { diff --git a/devices/src/pci/host.rs b/devices/src/pci/host.rs index 7f3b3d78f6be07e974ff727bc5609e40f88d717e..bf6755aec797b13b28a778ffd7fc6ef936cea028 100644 --- a/devices/src/pci/host.rs +++ b/devices/src/pci/host.rs @@ -396,7 +396,7 @@ fn build_prt_for_aml(pci_bus: &mut AmlDevice, irq: i32) { (0..PCI_PIN_NUM).for_each(|pin| { let gsi = (pin + slot) % PCI_PIN_NUM; let mut pkg = AmlPackage::new(4); - pkg.append_child(AmlDWord(u32::from(slot) << 16 | 0xFFFF)); + pkg.append_child(AmlDWord((u32::from(slot) << 16) | 0xFFFF)); pkg.append_child(AmlDWord(u32::from(pin))); pkg.append_child(AmlName(format!("GSI{}", gsi))); pkg.append_child(AmlZero); diff --git a/devices/src/pci/mod.rs b/devices/src/pci/mod.rs index 2866b3c440a43740fb7d70d367f8fa8b994dc4a5..b086d40f3630508af98bf45c257699608dda4cc4 100644 --- a/devices/src/pci/mod.rs +++ b/devices/src/pci/mod.rs @@ -34,7 +34,7 @@ use std::any::{Any, TypeId}; use std::collections::HashMap; use std::mem::size_of; use std::sync::atomic::AtomicBool; -use std::sync::{Arc, Mutex, Weak}; +use std::sync::{Arc, Mutex, RwLock, Weak}; use anyhow::{bail, Result}; use byteorder::{ByteOrder, LittleEndian}; @@ -118,7 +118,7 @@ fn pci_devfn(slot: u8, func: u8) -> u8 { } fn pci_slot(devfn: u8) -> u8 { - devfn >> 3 & 0x1f + (devfn >> 3) & 0x1f } fn pci_func(devfn: u8) -> u8 { @@ -258,7 +258,7 @@ pub trait PciDevOps: Device + Send { pub type ToPciDevOpsFunc = fn(&mut dyn Any) -> &mut dyn PciDevOps; -static mut PCIDEVOPS_HASHMAP: Option> = None; +static PCIDEVOPS_HASHMAP: RwLock>> = RwLock::new(None); pub fn convert_to_pcidevops(item: &mut dyn Any) -> &mut dyn PciDevOps { // SAFETY: The typeid of `T` is the typeid recorded in the hashmap. The target structure type of @@ -269,18 +269,15 @@ pub fn convert_to_pcidevops(item: &mut dyn Any) -> &mut dyn PciDev pub fn register_pcidevops_type() -> Result<()> { let type_id = TypeId::of::(); - // SAFETY: PCIDEVOPS_HASHMAP will be built in `type_init` function sequentially in the main thread. - // And will not be changed after `type_init`. - unsafe { - if PCIDEVOPS_HASHMAP.is_none() { - PCIDEVOPS_HASHMAP = Some(HashMap::new()); - } - let types = PCIDEVOPS_HASHMAP.as_mut().unwrap(); - if types.get(&type_id).is_some() { - bail!("Type Id {:?} has been registered.", type_id); - } - types.insert(type_id, convert_to_pcidevops::); + let mut locked_pcidevops = PCIDEVOPS_HASHMAP.write().unwrap(); + if locked_pcidevops.is_none() { + *locked_pcidevops = Some(HashMap::new()); } + let types = locked_pcidevops.as_mut().unwrap(); + if types.get(&type_id).is_some() { + bail!("Type Id {:?} has been registered.", type_id); + } + types.insert(type_id, convert_to_pcidevops::); Ok(()) } @@ -298,19 +295,18 @@ pub fn devices_register_pcidevops_type() -> Result<()> { #[cfg(test)] pub fn clean_pcidevops_type() { - unsafe { - PCIDEVOPS_HASHMAP = None; - } + *PCIDEVOPS_HASHMAP.write().unwrap() = None; } pub fn to_pcidevops(dev: &mut dyn Device) -> Option<&mut dyn PciDevOps> { - // SAFETY: PCIDEVOPS_HASHMAP has been built. And this function is called without changing hashmap. - unsafe { - let types = PCIDEVOPS_HASHMAP.as_mut().unwrap(); - let func = types.get(&dev.device_type_id())?; - let pcidev = func(dev.as_any_mut()); - Some(pcidev) + if PCIDEVOPS_HASHMAP.read().unwrap().is_none() { + // PCIDEVOPS_HASHMAP was not initialized + return None; } + let types = PCIDEVOPS_HASHMAP.read().unwrap(); + let func = types.as_ref().unwrap().get(&dev.device_type_id())?; + let pcidev = func(dev.as_any_mut()); + Some(pcidev) } /// Convert from Arc> to &mut dyn PciDevOps. @@ -395,7 +391,7 @@ pub fn init_multifunction( /// 0 <= pin <= 3. 0 = INTA, 1 = INTB, 2 = INTC, 3 = INTD. /// PCI-to-PCI bridge specification 9.1: Interrupt routing. pub fn swizzle_map_irq(devfn: u8, pin: u8) -> u32 { - let pci_slot = devfn >> 3 & 0x1f; + let pci_slot = (devfn >> 3) & 0x1f; u32::from((pci_slot + pin) % PCI_PIN_NUM) } diff --git a/devices/src/pci/root_port.rs b/devices/src/pci/root_port.rs index e531f84b7600f17fc93383a057ad441484dd942b..b1ebbca4cbd7c1c245579b104c6fbc9579201cf3 100644 --- a/devices/src/pci/root_port.rs +++ b/devices/src/pci/root_port.rs @@ -110,7 +110,7 @@ impl RootPort { /// * `cfg` - Root port config. /// * `parent_bus` - Weak reference to the parent bus. pub fn new(cfg: RootPortConfig, parent_bus: Weak>) -> Self { - let devfn = cfg.addr.0 << 3 | cfg.addr.1; + let devfn = (cfg.addr.0 << 3) | cfg.addr.1; #[cfg(target_arch = "x86_64")] let io_region = Region::init_container_region(1 << 16, "RootPortIo"); let mem_region = Region::init_container_region(u64::MAX, "RootPortMem"); @@ -637,7 +637,7 @@ impl HotplugOps for RootPort { if ((sltctl & PCI_EXP_SLTCTL_PIC) == PCI_EXP_SLTCTL_PWR_IND_OFF) && ((sltctl & PCI_EXP_SLTCTL_PCC) == PCI_EXP_SLTCTL_PWR_OFF) { - // if the slot has already been unpluged, skip notifying the guest. + // if the slot has already been unplugged, skip notifying the guest. return Ok(()); } diff --git a/devices/src/scsi/bus.rs b/devices/src/scsi/bus.rs index 035ffc31d36fac4e00a167dbecfb0e23cfa7f932..cd6db955d23b37514ec372969baa850f4a73cb85 100644 --- a/devices/src/scsi/bus.rs +++ b/devices/src/scsi/bus.rs @@ -373,7 +373,7 @@ pub enum ScsiXferMode { // Convert from (target, lun) to unique address in BusBase. pub fn get_scsi_key(target: u8, lun: u16) -> u64 { - u64::from(target) << TARGET_ID_SHIFT | u64::from(lun) + (u64::from(target) << TARGET_ID_SHIFT) | u64::from(lun) } // Convert from unique address in BusBase to (target, lun). @@ -828,7 +828,7 @@ pub fn scsi_cdb_xfer(cdb: &[u8; SCSI_CMD_BUF_SIZE], dev: Arc>) xfer *= block_size; } INQUIRY => { - xfer = i64::from(cdb[4]) | i64::from(cdb[3]) << 8; + xfer = i64::from(cdb[4]) | (i64::from(cdb[3]) << 8); } _ => {} } diff --git a/devices/src/smbios/smbios_table.rs b/devices/src/smbios/smbios_table.rs index 2751e6c9312785775b411a7335a50702d542216e..9961198e43b83db6c3c341a54157fe70a0ab6fe8 100644 --- a/devices/src/smbios/smbios_table.rs +++ b/devices/src/smbios/smbios_table.rs @@ -996,7 +996,7 @@ impl SmbiosTable { for i in 0..smbios_sockets { self.build_type4(smbios.type4.clone(), u16::from(i), mach_cfg); } - let mem_num = ((mach_cfg.mem_config.mem_size + 16 * GB_SIZE - 1) / (16 * GB_SIZE)) as u16; + let mem_num = mach_cfg.mem_config.mem_size.div_ceil(16 * GB_SIZE) as u16; self.build_type16(mach_cfg.mem_config.mem_size, mem_num); for i in 0..mem_num { diff --git a/devices/src/sysbus/mod.rs b/devices/src/sysbus/mod.rs index e472541ef074e6fbb2a814d0c01f51b806dd0263..44bd2559242d9cc5a4ad49f3c7693ade87558cdb 100644 --- a/devices/src/sysbus/mod.rs +++ b/devices/src/sysbus/mod.rs @@ -17,7 +17,7 @@ pub use error::SysBusError; use std::any::{Any, TypeId}; use std::collections::HashMap; use std::fmt; -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, Mutex, OnceLock, RwLock}; use anyhow::{bail, Context, Result}; use vmm_sys_util::eventfd::EventFd; @@ -365,7 +365,8 @@ impl AmlBuilder for SysBus { pub type ToSysBusDevOpsFunc = fn(&mut dyn Any) -> &mut dyn SysBusDevOps; -static mut SYSBUSDEVTYPE_HASHMAP: Option> = None; +static SYSBUSDEVTYPE_HASHMAP: OnceLock>> = + OnceLock::new(); pub fn convert_to_sysbusdevops(item: &mut dyn Any) -> &mut dyn SysBusDevOps { // SAFETY: The typeid of `T` is the typeid recorded in the hashmap. The target structure type of @@ -376,18 +377,12 @@ pub fn convert_to_sysbusdevops(item: &mut dyn Any) -> &mut dyn pub fn register_sysbusdevops_type() -> Result<()> { let type_id = TypeId::of::(); - // SAFETY: SYSBUSDEVTYPE_HASHMAP will be built in `type_init` function sequentially in the main thread. - // And will not be changed after `type_init`. - unsafe { - if SYSBUSDEVTYPE_HASHMAP.is_none() { - SYSBUSDEVTYPE_HASHMAP = Some(HashMap::new()); - } - let types = SYSBUSDEVTYPE_HASHMAP.as_mut().unwrap(); - if types.get(&type_id).is_some() { - bail!("Type Id {:?} has been registered.", type_id); - } - types.insert(type_id, convert_to_sysbusdevops::); + let map = SYSBUSDEVTYPE_HASHMAP.get_or_init(|| RwLock::new(HashMap::new())); + let mut types = map.write().unwrap(); + if types.get(&type_id).is_some() { + bail!("Type Id {:?} has been registered.", type_id); } + types.insert(type_id, convert_to_sysbusdevops::); Ok(()) } @@ -415,13 +410,10 @@ pub fn devices_register_sysbusdevops_type() -> Result<()> { } pub fn to_sysbusdevops(dev: &mut dyn Device) -> Option<&mut dyn SysBusDevOps> { - // SAFETY: SYSBUSDEVTYPE_HASHMAP has been built. And this function is called without changing hashmap. - unsafe { - let types = SYSBUSDEVTYPE_HASHMAP.as_mut().unwrap(); - let func = types.get(&dev.device_type_id())?; - let sysbusdev = func(dev.as_any_mut()); - Some(sysbusdev) - } + let types = SYSBUSDEVTYPE_HASHMAP.get().unwrap().read().unwrap(); + let func = types.get(&dev.device_type_id())?; + let sysbusdev = func(dev.as_any_mut()); + Some(sysbusdev) } #[cfg(test)] diff --git a/devices/src/usb/usbhost/host_usblib.rs b/devices/src/usb/usbhost/host_usblib.rs index 0962c5094f95879952ae3a599a3a5a9752422a32..48687f94d5f7b09f375527ced060352587da292f 100644 --- a/devices/src/usb/usbhost/host_usblib.rs +++ b/devices/src/usb/usbhost/host_usblib.rs @@ -459,7 +459,7 @@ pub struct PollFdIter<'a> { index: usize, } -impl<'a> Iterator for PollFdIter<'a> { +impl Iterator for PollFdIter<'_> { type Item = PollFd; fn next(&mut self) -> Option { diff --git a/devices/src/usb/usbhost/mod.rs b/devices/src/usb/usbhost/mod.rs index e345c1027816b07d7dbebd5f03918b7a3593aaa1..acdf8bcc515f544a9f5ade7533945421f15b254d 100644 --- a/devices/src/usb/usbhost/mod.rs +++ b/devices/src/usb/usbhost/mod.rs @@ -163,7 +163,7 @@ impl UsbHostRequest { pub fn ctrl_transfer_packet(&self, packet: &mut UsbPacket, actual_length: usize) { let setup_buf = get_buffer_from_transfer(self.host_transfer, 8); - let mut len = (setup_buf[7] as usize) << 8 | setup_buf[6] as usize; + let mut len = ((setup_buf[7] as usize) << 8) | setup_buf[6] as usize; if len > actual_length { len = actual_length; } @@ -586,7 +586,7 @@ impl UsbHost { trace::usb_host_parse_config(self.config.hostbus, self.config.hostaddr, conf.number()); for (i, intf) in conf.interfaces().enumerate() { // The usb_deviec.altsetting indexes alternate settings by the interface number. - // Get the 0th alternate setting first so that we can grap the interface number, + // Get the 0th alternate setting first so that we can get the interface number, // and then correct the alternate setting value if necessary. let mut intf_desc = intf.descriptors().next(); if intf_desc.is_none() { @@ -938,7 +938,7 @@ impl UsbHost { locked_iso_queue.unused.push_back(iso_transfer.unwrap()); if e == Error::NoDevice || e == Error::Io { // When the USB device reports the preceding error, XHCI notifies the guest - // of the error through packet status. The guest initiallizes the device + // of the error through packet status. The guest initializes the device // again. packet.lock().unwrap().status = UsbPacketStatus::Stall; }; diff --git a/devices/src/usb/xhci/xhci_controller.rs b/devices/src/usb/xhci/xhci_controller.rs index 9bb2a55aa40e822a0c365dd42e41ab6c89399f9a..8d10d57c3364b41520d479a63031a6a049dc1f51 100644 --- a/devices/src/usb/xhci/xhci_controller.rs +++ b/devices/src/usb/xhci/xhci_controller.rs @@ -632,7 +632,7 @@ impl UsbPort { /// Get port link state from port status and control register. pub fn get_port_link_state(&self) -> u32 { - self.portsc >> PORTSC_PLS_SHIFT & PORTSC_PLS_MASK + (self.portsc >> PORTSC_PLS_SHIFT) & PORTSC_PLS_MASK } /// Set port link state in port status and control register. @@ -677,11 +677,11 @@ impl XhciEvent { pub fn to_trb(&self) -> XhciTRB { XhciTRB { parameter: self.ptr, - status: self.length | (self.ccode as u32) << EVENT_TRB_CCODE_SHIFT, - control: u32::from(self.slot_id) << EVENT_TRB_SLOT_ID_SHIFT - | u32::from(self.ep_id) << EVENT_TRB_EP_ID_SHIFT + status: self.length | ((self.ccode as u32) << EVENT_TRB_CCODE_SHIFT), + control: (u32::from(self.slot_id) << EVENT_TRB_SLOT_ID_SHIFT) + | (u32::from(self.ep_id) << EVENT_TRB_EP_ID_SHIFT) | self.flags - | (self.trb_type as u32) << TRB_TYPE_SHIFT, + | ((self.trb_type as u32) << TRB_TYPE_SHIFT), addr: 0, ccs: false, } @@ -715,7 +715,7 @@ impl XhciSlotCtx { } pub fn get_slot_state(&self) -> u32 { - self.dev_state >> SLOT_STATE_SHIFT & SLOT_STATE_MASK + (self.dev_state >> SLOT_STATE_SHIFT) & SLOT_STATE_MASK } pub fn set_context_entry(&mut self, num: u32) { @@ -730,7 +730,7 @@ impl XhciSlotCtx { } pub fn get_max_exit_latency(&self) -> u32 { - self.dev_info2 >> SLOT_CONTEXT_MAX_EXIT_LATENCY_SHIFT & SLOT_CONTEXT_MAX_EXIT_LATENCY_MASK + (self.dev_info2 >> SLOT_CONTEXT_MAX_EXIT_LATENCY_SHIFT) & SLOT_CONTEXT_MAX_EXIT_LATENCY_MASK } pub fn set_max_exit_latency(&mut self, state: u32) { @@ -741,7 +741,8 @@ impl XhciSlotCtx { } pub fn get_interrupter_target(&self) -> u32 { - self.tt_info >> SLOT_CONTEXT_INTERRUPTER_TARGET_SHIFT & SLOT_CONTEXT_INTERRUPTER_TARGET_MASK + (self.tt_info >> SLOT_CONTEXT_INTERRUPTER_TARGET_SHIFT) + & SLOT_CONTEXT_INTERRUPTER_TARGET_MASK } pub fn set_interrupter_target(&mut self, state: u32) { @@ -752,7 +753,7 @@ impl XhciSlotCtx { } pub fn get_usb_device_address(&self) -> u32 { - self.dev_state >> SLOT_CONTEXT_DEVICE_ADDRESS_SHIFT & SLOT_CONTEXT_DEVICE_ADDRESS_MASK + (self.dev_state >> SLOT_CONTEXT_DEVICE_ADDRESS_SHIFT) & SLOT_CONTEXT_DEVICE_ADDRESS_MASK } pub fn set_usb_device_address(&mut self, state: u32) { @@ -797,7 +798,7 @@ impl XhciEpCtx { } pub fn get_ep_state(&self) -> u32 { - self.ep_info >> EP_CONTEXT_EP_STATE_SHIFT & EP_CONTEXT_EP_STATE_MASK + (self.ep_info >> EP_CONTEXT_EP_STATE_SHIFT) & EP_CONTEXT_EP_STATE_MASK } pub fn set_ep_state(&mut self, state: u32) { @@ -1194,7 +1195,7 @@ impl XhciDevice { } fn lookup_usb_port(&mut self, slot_ctx: &XhciSlotCtx) -> Option>> { - let port = (slot_ctx.dev_info2 >> SLOT_CTX_PORT_NUMBER_SHIFT & 0xff) as u8; + let port = ((slot_ctx.dev_info2 >> SLOT_CTX_PORT_NUMBER_SHIFT) & 0xff) as u8; if port < 1 || port > self.usb_ports.len() as u8 { error!("Invalid port: {}", port); return None; @@ -1265,23 +1266,23 @@ impl XhciDevice { TRBType::CrStopEndpoint => { slot_id = self.get_slot_id(&mut event, &trb); if slot_id != 0 { - let ep_id = trb.control >> TRB_CR_EPID_SHIFT & TRB_CR_EPID_MASK; + let ep_id = (trb.control >> TRB_CR_EPID_SHIFT) & TRB_CR_EPID_MASK; event.ccode = self.stop_endpoint(slot_id, ep_id)?; } } TRBType::CrResetEndpoint => { slot_id = self.get_slot_id(&mut event, &trb); if slot_id != 0 { - let ep_id = trb.control >> TRB_CR_EPID_SHIFT & TRB_CR_EPID_MASK; + let ep_id = (trb.control >> TRB_CR_EPID_SHIFT) & TRB_CR_EPID_MASK; event.ccode = self.reset_endpoint(slot_id, ep_id)?; } } TRBType::CrSetTrDequeue => { slot_id = self.get_slot_id(&mut event, &trb); if slot_id != 0 { - let ep_id = trb.control >> TRB_CR_EPID_SHIFT & TRB_CR_EPID_MASK; + let ep_id = (trb.control >> TRB_CR_EPID_SHIFT) & TRB_CR_EPID_MASK; let stream_id = - trb.status >> TRB_CR_STREAMID_SHIFT & TRB_CR_STREAMID_MASK; + (trb.status >> TRB_CR_STREAMID_SHIFT) & TRB_CR_STREAMID_MASK; event.ccode = self.set_tr_dequeue_pointer(slot_id, ep_id, stream_id, &trb)?; } diff --git a/devices/src/usb/xhci/xhci_pci.rs b/devices/src/usb/xhci/xhci_pci.rs index 493a501b03b54d35ee83f8d54fe8202b904b235f..dc8ac012b5b1ac7feb88aa54dd031dfa2e660f52 100644 --- a/devices/src/usb/xhci/xhci_pci.rs +++ b/devices/src/usb/xhci/xhci_pci.rs @@ -92,7 +92,7 @@ pub struct XhciConfig { /// Registers offset. /// 0x0 0x40 0x440 0x1000 0x2000 0x3000 0x4000 /// | cap | oper | port | runtime | doorbell | MSIX | - +/// /// XHCI pci device which can be attached to PCI bus. pub struct XhciPciDevice { base: PciDevBase, diff --git a/devices/src/usb/xhci/xhci_regs.rs b/devices/src/usb/xhci/xhci_regs.rs index c027e0d33751255cf65c4eb7a6a31fbbbcbfa3e1..a49225e863a73142eb29dac1ffb79641cea06f03 100644 --- a/devices/src/usb/xhci/xhci_regs.rs +++ b/devices/src/usb/xhci/xhci_regs.rs @@ -373,12 +373,12 @@ pub fn build_cap_ops(xhci_dev: &Arc>) -> RegionOps { let value = match offset { XHCI_CAP_REG_CAPLENGTH => { let hci_version_offset = XHCI_CAP_REG_HCIVERSION * 8; - XHCI_VERSION << hci_version_offset | XHCI_CAP_LENGTH + (XHCI_VERSION << hci_version_offset) | XHCI_CAP_LENGTH } XHCI_CAP_REG_HCSPARAMS1 => { - u32::from(max_ports) << CAP_HCSP_NP_SHIFT - | max_intrs << CAP_HCSP_NI_SHIFT - | (locked_dev.slots.len() as u32) << CAP_HCSP_NDS_SHIFT + (u32::from(max_ports) << CAP_HCSP_NP_SHIFT) + | (max_intrs << CAP_HCSP_NI_SHIFT) + | ((locked_dev.slots.len() as u32) << CAP_HCSP_NDS_SHIFT) } XHCI_CAP_REG_HCSPARAMS2 => { // IST @@ -388,15 +388,15 @@ pub fn build_cap_ops(xhci_dev: &Arc>) -> RegionOps { XHCI_CAP_REG_HCCPARAMS1 => { // The offset of the first extended capability is (base) + (0x8 << 2) // The primary stream array size is 1 << (0x7 + 1) - 0x8 << CAP_HCCP_EXCP_SHIFT | (0x7 << CAP_HCCP_MPSAS_SHIFT) | CAP_HCCP_AC64 + (0x8 << CAP_HCCP_EXCP_SHIFT) | (0 << CAP_HCCP_MPSAS_SHIFT) | CAP_HCCP_AC64 } XHCI_CAP_REG_DBOFF => XHCI_OFF_DOORBELL, XHCI_CAP_REG_RTSOFF => XHCI_OFF_RUNTIME, XHCI_CAP_REG_HCCPARAMS2 => 0, // Extended capabilities (USB 2.0) 0x20 => { - CAP_EXT_USB_REVISION_2_0 << CAP_EXT_REVISION_SHIFT - | 0x4 << CAP_EXT_NEXT_CAP_POINTER_SHIFT + (CAP_EXT_USB_REVISION_2_0 << CAP_EXT_REVISION_SHIFT) + | (0x4 << CAP_EXT_NEXT_CAP_POINTER_SHIFT) | u32::from(CAP_EXT_CAP_ID_SUPPORT_PROTOCOL) } 0x24 => CAP_EXT_USB_NAME_STRING, @@ -404,7 +404,7 @@ pub fn build_cap_ops(xhci_dev: &Arc>) -> RegionOps { 0x2c => 0x0, // Extended capabilities (USB 3.0) 0x30 => { - CAP_EXT_USB_REVISION_3_0 << CAP_EXT_REVISION_SHIFT + (CAP_EXT_USB_REVISION_3_0 << CAP_EXT_REVISION_SHIFT) | u32::from(CAP_EXT_CAP_ID_SUPPORT_PROTOCOL) } 0x34 => CAP_EXT_USB_NAME_STRING, diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs index 019376adea8b2243f5f01469404418335e89cd7e..6afa97dd44ce4eccaf24053dccb0e4cfcac368e4 100644 --- a/hypervisor/src/kvm/mod.rs +++ b/hypervisor/src/kvm/mod.rs @@ -755,7 +755,7 @@ impl KVMInterruptManager { pub fn arch_map_irq(&self, gsi: u32) -> u32 { let irq = gsi + GIC_IRQ_INTERNAL; let irqtype = KVM_ARM_IRQ_TYPE_SPI; - irqtype << KVM_ARM_IRQ_TYPE_SHIFT | irq + (irqtype << KVM_ARM_IRQ_TYPE_SHIFT) | irq } } diff --git a/machine/src/aarch64/standard.rs b/machine/src/aarch64/standard.rs index 34394e1b743039e5c6de664817bdfccbd615bcdd..82dd2e22346f14c15df6d4741ab158c8ec26f659 100644 --- a/machine/src/aarch64/standard.rs +++ b/machine/src/aarch64/standard.rs @@ -295,10 +295,7 @@ impl StdMachine { return None; } - let value = match vcpu.hypervisor_cpu.get_one_reg(addr) { - Ok(value) => Some(value), - _ => None, - }; + let value = vcpu.hypervisor_cpu.get_one_reg(addr).ok(); if cpu_state != CpuLifecycleState::Paused { self.resume(); @@ -1172,9 +1169,6 @@ impl AcpiBuilder for StdMachine { } } -/// Function that helps to generate flash node in device-tree. -/// - /// Trait that helps to generate all nodes in device-tree. #[allow(clippy::upper_case_acronyms)] trait CompileFDTHelper { diff --git a/machine/src/lib.rs b/machine/src/lib.rs index f066cdc80afeff5cf7a54a17d56e74589317f95b..6670b90bf5ff475f039286f3f52f17170fbb62b7 100644 --- a/machine/src/lib.rs +++ b/machine/src/lib.rs @@ -1673,7 +1673,7 @@ pub trait MachineOps: MachineLifecycle { let fast_unplug = vm_config .global_config .get("pcie-root-port.fast-unplug") - .map_or(false, |val| val == FAST_UNPLUG_ON); + .is_some_and(|val| val == FAST_UNPLUG_ON); RootPort::set_fast_unplug_feature(fast_unplug); Ok(()) diff --git a/machine/src/standard_common/mod.rs b/machine/src/standard_common/mod.rs index b34401fc3c71b126682773b01a75f633727644f3..4ab96c11d14db1f8dad01eb2422d937b616d0b3d 100644 --- a/machine/src/standard_common/mod.rs +++ b/machine/src/standard_common/mod.rs @@ -646,7 +646,7 @@ pub(crate) trait AcpiBuilder { #[cfg(target_arch = "x86_64")] { // FADT flag: disable HW_REDUCED_ACPI bit on x86 plantform. - fadt.set_field(112, 1_u32 << 10 | 1_u32 << 8); + fadt.set_field(112, (1_u32 << 10) | (1_u32 << 8)); // Reset Register bit, offset is 116. fadt.set_field(116, 0x01_u8); fadt.set_field(117, 0x08_u8); diff --git a/machine_manager/src/config/display.rs b/machine_manager/src/config/display.rs index 7369e4298794ee8fb10381a8f6451aaa04db4028..02c7e634759509f8e8c7517dbb8a2c6aa5822f65 100644 --- a/machine_manager/src/config/display.rs +++ b/machine_manager/src/config/display.rs @@ -65,7 +65,6 @@ fn get_dir_path(p: &str) -> Result { /// GTK and OHUI related configuration. #[derive(Parser, Debug, Clone, Default, Serialize, Deserialize)] #[command(no_binary_name(true))] - pub struct DisplayConfig { #[arg(long, alias = "classtype", value_parser = ["gtk", "ohui"])] pub display_type: String, diff --git a/machine_manager/src/config/mod.rs b/machine_manager/src/config/mod.rs index 144589bfcfd64dc553a934c541273a29b61f7f99..b9f8eeb7f3678a0c6867607ae828f243c1cb9b37 100644 --- a/machine_manager/src/config/mod.rs +++ b/machine_manager/src/config/mod.rs @@ -626,16 +626,16 @@ fn concat_classtype(args: &str, concat: bool) -> String { /// Stratovirt command line may use the first parameter as class type. /// Eg: /// 1. drive config: "-drive file=,if=pflash,unit=0" -/// This cmdline has no class type. +/// This cmdline has no class type. /// 2. device config: "-device virtio-balloon-pci,id=,bus=,addr=<0x4>" -/// This cmdline sets device type `virtio-balloon-pci` as the first parameter. +/// This cmdline sets device type `virtio-balloon-pci` as the first parameter. /// /// Use first_pos_is_type to indicate whether the first parameter is a type class which needs a separate analysis. /// Eg: /// 1. drive config: "-drive file=,if=pflash,unit=0" -/// Set first_pos_is_type false for this cmdline has no class type. +/// Set first_pos_is_type false for this cmdline has no class type. /// 2. device config: "-device virtio-balloon-pci,id=,bus=,addr=<0x4>" -/// Set first_pos_is_type true for this cmdline has device type "virtio-balloon-pci" as the first parameter. +/// Set first_pos_is_type true for this cmdline has device type "virtio-balloon-pci" as the first parameter. /// /// Use first_pos_is_subcommand to indicate whether the first parameter is a subclass. /// Eg: @@ -643,7 +643,7 @@ fn concat_classtype(args: &str, concat: bool) -> String { /// in the same `ChardevConfig` structure by using `enum`. So, we will use class type as a subcommand to indicate which subtype /// will be used to store the configuration in enumeration type. Subcommand in `clap` doesn't need `--` in parameter. /// 1. -serial file,path= -/// Set first_pos_is_subcommand true for first parameter `file` is the subclass type for chardev. +/// Set first_pos_is_subcommand true for first parameter `file` is the subclass type for chardev. pub fn str_slip_to_clap( args: &str, first_pos_is_type: bool, diff --git a/machine_manager/src/config/network.rs b/machine_manager/src/config/network.rs index 30f1ec807dd55b040b179368df9d941dbec059f2..96324749f7017a594a997bc12f3931f108b17aa7 100644 --- a/machine_manager/src/config/network.rs +++ b/machine_manager/src/config/network.rs @@ -119,7 +119,7 @@ impl ConfigCheck for NetDevcfg { if self.vhost_fds.is_some() && self.vhost_type().is_none() { bail!("Argument 'vhostfd' or 'vhostfds' are not needed for virtio-net device"); } - if self.tap_fds.is_none() && self.ifname.eq("") && self.netdev_type.ne("vhost-user") { + if self.tap_fds.is_none() && self.ifname.is_empty() && self.netdev_type.ne("vhost-user") { bail!("Tap device is missing, use \'ifname\' or \'fd\' to configure a tap device"); } diff --git a/machine_manager/src/config/smbios.rs b/machine_manager/src/config/smbios.rs index 56f8778f0e5b250eeab41d69842bf7c15c27f2bf..15f4bda37c91f850d3702ec9d0f71789a2f642f0 100644 --- a/machine_manager/src/config/smbios.rs +++ b/machine_manager/src/config/smbios.rs @@ -205,7 +205,7 @@ impl FromStr for Uuid { for i in index { let mut chars = name.chars(); uuid_bytes.push( - (chars.nth(*i).unwrap().to_digit(16).unwrap() as u8) << 4 + ((chars.nth(*i).unwrap().to_digit(16).unwrap() as u8) << 4) | chars.next().unwrap().to_digit(16).unwrap() as u8, ); } diff --git a/machine_manager/src/event_loop.rs b/machine_manager/src/event_loop.rs index c3eb2999c254ab051d10372621148fe8a82e07b3..8fd8b006eef6500d5ca9c3ef5cf7058fcb12a76c 100644 --- a/machine_manager/src/event_loop.rs +++ b/machine_manager/src/event_loop.rs @@ -12,11 +12,11 @@ use std::collections::HashMap; use std::os::unix::prelude::RawFd; -use std::sync::{Arc, Barrier, Mutex}; +use std::sync::{Arc, Barrier, Mutex, OnceLock}; use std::{process, thread}; use anyhow::{bail, Result}; -use log::{error, info}; +use log::{error, info, warn}; use super::config::IothreadConfig; use crate::machine::IOTHREADS; @@ -40,7 +40,7 @@ pub struct EventLoop { io_threads: HashMap, } -static mut GLOBAL_EVENT_LOOP: Option = None; +static GLOBAL_EVENT_LOOP: OnceLock = OnceLock::new(); impl EventLoop { /// Init GLOBAL_EVENT_LOOP, include main loop and io-threads loop @@ -65,43 +65,37 @@ impl EventLoop { } } - // SAFETY: This function is called at startup thus no concurrent accessing to - // GLOBAL_EVENT_LOOP. And each iothread has a dedicated EventLoopContext. - unsafe { - if GLOBAL_EVENT_LOOP.is_none() { - GLOBAL_EVENT_LOOP = Some(EventLoop { - main_loop: EventLoopContext::new(thread_exit_barrier), - io_threads, - }); - - if let Some(event_loop) = GLOBAL_EVENT_LOOP.as_mut() { - for (id, ctx) in &mut event_loop.io_threads { - thread::Builder::new().name(id.to_string()).spawn(move || { - let iothread_info = IothreadInfo { - shrink: 0, - pid: process::id(), - grow: 0, - max: 0, - id: id.to_string(), - }; - IOTHREADS.lock().unwrap().push(iothread_info); - while ctx.iothread_run().is_ok() { - // If is_cleaned() is true, it means the main thread will exit. - // So, exit the iothread. - if TempCleaner::is_cleaned() { - break; - } - } - if let Err(e) = ctx.clean_event_loop() { - error!("Failed to clean event loop {:?}", e); - } - ctx.thread_exit_barrier.wait(); - })?; + let res = GLOBAL_EVENT_LOOP.set(EventLoop { + main_loop: EventLoopContext::new(thread_exit_barrier), + io_threads, + }); + if res.is_err() { + warn!("GLOBAL_EVENT_LOOP has been initialized"); + return Ok(()); + } + let event_loop = GLOBAL_EVENT_LOOP.get().unwrap(); + for (id, ctx) in &event_loop.io_threads { + thread::Builder::new().name(id.to_string()).spawn(move || { + let iothread_info = IothreadInfo { + shrink: 0, + pid: process::id(), + grow: 0, + max: 0, + id: id.to_string(), + }; + IOTHREADS.lock().unwrap().push(iothread_info); + while ctx.iothread_run().is_ok() { + // If is_cleaned() is true, it means the main thread will exit. + // So, exit the iothread. + if TempCleaner::is_cleaned() { + break; } - } else { - bail!("Global Event Loop have not been initialized.") } - } + if let Err(e) = ctx.clean_event_loop() { + error!("Failed to clean event loop {:?}", e); + } + ctx.thread_exit_barrier.wait(); + })?; } Ok(()) @@ -112,16 +106,13 @@ impl EventLoop { /// # Arguments /// /// * `name` - if None, return main loop, OR return io-thread-loop which is related to `name`. - pub fn get_ctx(name: Option<&String>) -> Option<&mut EventLoopContext> { - // SAFETY: All concurrently accessed data of EventLoopContext is protected. - unsafe { - if let Some(event_loop) = GLOBAL_EVENT_LOOP.as_mut() { - if let Some(name) = name { - return event_loop.io_threads.get_mut(name); - } - - return Some(&mut event_loop.main_loop); + pub fn get_ctx(name: Option<&String>) -> Option<&EventLoopContext> { + if let Some(event_loop) = GLOBAL_EVENT_LOOP.get() { + if let Some(name) = name { + return event_loop.io_threads.get(name); } + + return Some(&event_loop.main_loop); } panic!("Global Event Loop have not been initialized."); @@ -133,13 +124,10 @@ impl EventLoop { /// /// * `manager` - The main part to manager the event loop. pub fn set_manager(manager: Arc>) { - // SAFETY: All concurrently accessed data of EventLoopContext is protected. - unsafe { - if let Some(event_loop) = GLOBAL_EVENT_LOOP.as_mut() { - event_loop.main_loop.set_manager(manager.clone()); - for (_name, io_thread) in event_loop.io_threads.iter_mut() { - io_thread.set_manager(manager.clone()); - } + if let Some(event_loop) = GLOBAL_EVENT_LOOP.get() { + event_loop.main_loop.set_manager(manager.clone()); + for (_name, io_thread) in event_loop.io_threads.iter() { + io_thread.set_manager(manager.clone()); } } } @@ -165,46 +153,34 @@ impl EventLoop { /// Once run main loop, `epoll` in `MainLoopContext` will execute /// `epoll_wait()` function to wait for events. pub fn loop_run() -> Result<()> { - // SAFETY: the main_loop ctx is dedicated for main thread, thus no concurrent - // accessing. - unsafe { - if let Some(event_loop) = GLOBAL_EVENT_LOOP.as_mut() { - loop { - let sig_num = get_signal(); - if sig_num != 0 { - info!("MainLoop exits due to receive signal {}", sig_num); - return Ok(()); - } - if !event_loop.main_loop.run()? { - info!("MainLoop exits due to guest internal operation."); - return Ok(()); - } + if let Some(event_loop) = GLOBAL_EVENT_LOOP.get() { + loop { + let sig_num = get_signal(); + if sig_num != 0 { + info!("MainLoop exits due to receive signal {}", sig_num); + return Ok(()); + } + if !event_loop.main_loop.run()? { + info!("MainLoop exits due to guest internal operation."); + return Ok(()); } - } else { - bail!("Global Event Loop have not been initialized.") } + } else { + bail!("Global Event Loop have not been initialized.") } } pub fn loop_clean() { EventLoop::kick_iothreads(); - // SAFETY: the main_loop ctx is dedicated for main thread, thus no concurrent - // accessing. - unsafe { - if let Some(event_loop) = GLOBAL_EVENT_LOOP.as_mut() { - event_loop.main_loop.thread_exit_barrier.wait(); - } - GLOBAL_EVENT_LOOP = None; + if let Some(event_loop) = GLOBAL_EVENT_LOOP.get() { + event_loop.main_loop.thread_exit_barrier.wait(); } } pub fn kick_iothreads() { - // SAFETY: All concurrently accessed data of EventLoopContext is protected. - unsafe { - if let Some(event_loop) = GLOBAL_EVENT_LOOP.as_mut() { - for (_name, io_thread) in event_loop.io_threads.iter_mut() { - io_thread.kick(); - } + if let Some(event_loop) = GLOBAL_EVENT_LOOP.get() { + for (_name, io_thread) in event_loop.io_threads.iter() { + io_thread.kick(); } } } diff --git a/machine_manager/src/qmp/qmp_channel.rs b/machine_manager/src/qmp/qmp_channel.rs index c975f7320c098afe4698ca78bb4369f87f7bbdce..dcc72abef15449c4911e1edeea94b74a562500e7 100644 --- a/machine_manager/src/qmp/qmp_channel.rs +++ b/machine_manager/src/qmp/qmp_channel.rs @@ -83,7 +83,7 @@ pub fn create_timestamp() -> TimeStamp { /// The struct `QmpChannel` is the only struct can handle Global variable /// `QMP_CHANNEL`. /// It is used to send event to qmp client and restore some file descriptor -/// which was sended by client. +/// which was sent by client. pub struct QmpChannel { /// The `writer` to send `QmpEvent`. event_writer: RwLock>, diff --git a/machine_manager/src/qmp/qmp_schema.rs b/machine_manager/src/qmp/qmp_schema.rs index 6e85bd42743da418f97ac7e007214430b8588a11..2afe20001fd54bb882ee82746d54a7c11b0e7696 100644 --- a/machine_manager/src/qmp/qmp_schema.rs +++ b/machine_manager/src/qmp/qmp_schema.rs @@ -1189,7 +1189,7 @@ pub struct GpuInfo { /// /// # Arguments /// -/// * `value` - Memoey size. +/// * `value` - Memory size. /// /// # Notes /// diff --git a/machine_manager/src/signal_handler.rs b/machine_manager/src/signal_handler.rs index 2f1ba86e99238e6bb7d8985c08f9499b5683c206..64fca1e3f088578cf6520c7e6fdb052df8cc0a09 100644 --- a/machine_manager/src/signal_handler.rs +++ b/machine_manager/src/signal_handler.rs @@ -29,7 +29,7 @@ pub const VM_EXIT_GENE_ERR: i32 = 1; const SYSTEMCALL_OFFSET: isize = 6; const SYS_SECCOMP: i32 = 1; -static mut RECEIVED_SIGNAL: AtomicI32 = AtomicI32::new(0); +static RECEIVED_SIGNAL: AtomicI32 = AtomicI32::new(0); pub fn exit_with_code(code: i32) { // SAFETY: The basic_clean function has been executed before exit. @@ -40,23 +40,33 @@ pub fn exit_with_code(code: i32) { pub fn set_signal(num: c_int) { /* - * Other three signals need to send shutdown message more than SIGSYS. - * So, if received other three signals, it should replace the SIGSYS - * which has been received before. The SIGTERM/SIGINT/SIGHUP has the - * same treatment, if received one of them, no need to replace it. + * Compared to the SIGSYS signal, the other three signals require + * additional shutdown information to be sent via the QMP channel. + * Therefore, if any of the other three signals are received, the + * previously received SIGSYS signal must be replaced in the global + * variable. The SIGTERM/SIGINT/SIGHUP signals are handled in the + * same way. + * Retry on CAS fail. */ - if [0, libc::SIGSYS].contains(&get_signal()) { - // SAFETY: just write a global variable. - unsafe { - RECEIVED_SIGNAL.store(num, Ordering::SeqCst); + loop { + let prev = get_signal(); + if prev != 0 && prev != libc::SIGSYS { + break; + } + + if RECEIVED_SIGNAL + .compare_exchange(prev, num, Ordering::SeqCst, Ordering::SeqCst) + .is_ok() + { + // CAS success,kick main loop + EventLoop::get_ctx(None).unwrap().kick(); + break; } - EventLoop::get_ctx(None).unwrap().kick(); } } pub fn get_signal() -> i32 { - // SAFETY: just read a global variable. - unsafe { RECEIVED_SIGNAL.load(Ordering::SeqCst) } + RECEIVED_SIGNAL.load(Ordering::SeqCst) } pub fn handle_signal() { diff --git a/machine_manager/src/temp_cleaner.rs b/machine_manager/src/temp_cleaner.rs index ba92cd78e09baa390f962c7266a2f0d31aeb439e..ea62de9d678a96c541ca6d06651b3aca478a1b8f 100644 --- a/machine_manager/src/temp_cleaner.rs +++ b/machine_manager/src/temp_cleaner.rs @@ -13,14 +13,11 @@ use std::collections::HashMap; use std::fs; use std::path::Path; -use std::sync::{ - atomic::{fence, Ordering}, - Arc, -}; +use std::sync::{Arc, Mutex, OnceLock}; use log::{error, info}; -static mut GLOBAL_TEMP_CLEANER: Option = None; +static GLOBAL_TEMP_CLEANER: OnceLock> = OnceLock::new(); pub type ExitNotifier = dyn Fn() + Send + Sync; @@ -31,52 +28,37 @@ pub struct TempCleaner { paths: Vec, /// Notifiers are used to release residual resources after exiting the vm. notifiers: HashMap>, + /// Indicate whether clean has been done. + executed: bool, } impl TempCleaner { pub fn object_init() { - // SAFETY: This global variable is only used in single thread, - // so there is no data competition or synchronization problem. - unsafe { - if GLOBAL_TEMP_CLEANER.is_none() { - GLOBAL_TEMP_CLEANER = Some(TempCleaner { - paths: Vec::new(), - notifiers: HashMap::new(), - }); - } - } + let _ = GLOBAL_TEMP_CLEANER.set(Mutex::new(TempCleaner { + paths: Vec::new(), + notifiers: HashMap::new(), + executed: false, + })); } /// Add to be removed file path pub fn add_path(path: String) { - // SAFETY: This global variable is only used in single thread, - // so there is no data competition or synchronization problem. - unsafe { - if let Some(tmp) = GLOBAL_TEMP_CLEANER.as_mut() { - tmp.paths.push(path); - } + if let Some(tmp) = GLOBAL_TEMP_CLEANER.get() { + tmp.lock().unwrap().paths.push(path); } } /// Add exit notifier. pub fn add_exit_notifier(id: String, exit: Arc) { - // SAFETY: This global variable is only used in single thread, - // so there is no data competition or synchronization problem. - unsafe { - if let Some(tmp) = GLOBAL_TEMP_CLEANER.as_mut() { - tmp.notifiers.insert(id, exit); - } + if let Some(tmp) = GLOBAL_TEMP_CLEANER.get() { + tmp.lock().unwrap().notifiers.insert(id, exit); } } /// Remove exit notifier by id. pub fn remove_exit_notifier(id: &str) { - // SAFETY: This global variable is only used in single thread, - // so there is no data competition or synchronization problem. - unsafe { - if let Some(tmp) = GLOBAL_TEMP_CLEANER.as_mut() { - tmp.notifiers.remove(id); - } + if let Some(tmp) = GLOBAL_TEMP_CLEANER.get() { + tmp.lock().unwrap().notifiers.remove(id); } } @@ -102,25 +84,20 @@ impl TempCleaner { /// Clean the resources pub fn clean() { - // SAFETY: This global variable is only used in single thread, - // so there is no data competition or synchronization problem. - unsafe { - if let Some(tmp) = GLOBAL_TEMP_CLEANER.as_mut() { - tmp.clean_files(); - tmp.exit_notifier(); - fence(Ordering::SeqCst); - GLOBAL_TEMP_CLEANER = None; - } + if let Some(tmp) = GLOBAL_TEMP_CLEANER.get() { + let mut locked_cleaner = tmp.lock().unwrap(); + locked_cleaner.clean_files(); + locked_cleaner.exit_notifier(); + locked_cleaner.paths.clear(); + locked_cleaner.notifiers.clear(); + locked_cleaner.executed = true; } } pub fn is_cleaned() -> bool { - // SAFETY: This global variable is read but not modified by iothread. - // so there is not need to add lock to it. - unsafe { - let ret = GLOBAL_TEMP_CLEANER.is_none(); - fence(Ordering::SeqCst); - ret + if let Some(tmp) = GLOBAL_TEMP_CLEANER.get() { + return tmp.lock().unwrap().executed; } + true } } diff --git a/migration/src/general.rs b/migration/src/general.rs index cfe6909cbf0829163b0e2bd7e36ee7428e3feee8..6b22b93e31abeda586028ddb2b78dc6dbd66b5e3 100644 --- a/migration/src/general.rs +++ b/migration/src/general.rs @@ -221,7 +221,7 @@ impl MigrationManager { let desc_db = MIGRATION_MANAGER.desc_db.read().unwrap(); for (_, desc) in desc_db.iter() { let desc_str = serde_json::to_string(desc)?; - db_data_len += desc_str.as_bytes().len(); + db_data_len += desc_str.len(); } Ok(db_data_len) diff --git a/migration/src/protocol.rs b/migration/src/protocol.rs index ca8e23c296ec325827f478286399ccd1391570b5..9a75e4720911bba64c6497ba5e1670eb404f5c38 100644 --- a/migration/src/protocol.rs +++ b/migration/src/protocol.rs @@ -295,7 +295,7 @@ const MAGIC_NUMBER: [u8; 16] = [ ]; const MAJOR_VERSION: u32 = 2; const MINOR_VERSION: u32 = 2; -const CURRENT_VERSION: u32 = MAJOR_VERSION << 12 | MINOR_VERSION & 0b1111; +const CURRENT_VERSION: u32 = (MAJOR_VERSION << 12) | MINOR_VERSION & 0b1111; const COMPAT_VERSION: u32 = CURRENT_VERSION; #[cfg(target_arch = "x86_64")] const EAX_VENDOR_INFO: u32 = 0x0; diff --git a/ozone/src/syscall.rs b/ozone/src/syscall.rs index 648f3fc20ea76c86fd9522183d4520789078b76d..ce068b5995e0465e67e72fc11d6df4a2bfa6360a 100644 --- a/ozone/src/syscall.rs +++ b/ozone/src/syscall.rs @@ -155,7 +155,7 @@ pub fn setns(fd: i32, nstype: i32) -> Result<()> { /// /// # Arguments /// -/// * `path` - The relative path of filder. +/// * `path` - The relative path of folder. pub fn mkdir(path: &str) -> Result<()> { let path_ptr = into_cstring(path)?; SyscallResult { diff --git a/ozonec/oci_spec/src/linux.rs b/ozonec/oci_spec/src/linux.rs index 6dafcd5a7a66001454e1ea34d42830dc06149b4a..36fdae702ee1fe8e5d669003530ff475c20b23f2 100644 --- a/ozonec/oci_spec/src/linux.rs +++ b/ozonec/oci_spec/src/linux.rs @@ -477,7 +477,7 @@ pub struct Seccomp { /// Path of UNIX domain socket over which the runtime will send the /// container process state data structure when the SCMP_ACT_NOTIFY /// action is used. - pub listennerPath: Option, + pub listenerPath: Option, #[serde(skip_serializing_if = "Option::is_none")] /// Seccomp file descriptor returned by the seccomp syscall. pub seccompFd: Option, diff --git a/ozonec/src/linux/process.rs b/ozonec/src/linux/process.rs index 5e64be67e0e1c8f8a64ec0d0a79a829f8c2011d5..f0d3accd674ac0680a19a601ada7257452cdfdca 100644 --- a/ozonec/src/linux/process.rs +++ b/ozonec/src/linux/process.rs @@ -216,7 +216,7 @@ impl Process { let setgroups = read_to_string("proc/self/setgroups") .with_context(|| "Failed to read setgroups")?; if setgroups.trim() == "deny" { - bail!("Cannot set additional gids as setgroup is desabled"); + bail!("Cannot set additional gids as setgroup is disabled"); } let gids: Vec = additional_gids diff --git a/ozonec/src/linux/seccomp.rs b/ozonec/src/linux/seccomp.rs index 14f4ea4ca6a34d014939c5a3461a844b8f14015d..d780b58efcbabc0cd0d1e7ad639eaa737dd7b452 100644 --- a/ozonec/src/linux/seccomp.rs +++ b/ozonec/src/linux/seccomp.rs @@ -191,7 +191,7 @@ mod tests { defaultErrnoRet: None, architectures: None, flags: None, - listennerPath: None, + listenerPath: None, seccompFd: None, listenerMetadata: None, syscalls: None, @@ -217,7 +217,7 @@ mod tests { defaultErrnoRet: None, architectures: None, flags: None, - listennerPath: None, + listenerPath: None, seccompFd: None, listenerMetadata: None, syscalls: None, diff --git a/ozonec/src/utils/clone.rs b/ozonec/src/utils/clone.rs index 2dd99e6629b2f0dfd63b1e122d915f18fb5327de..a22ef70f5716e24489ce78be3f8041df14c68e34 100644 --- a/ozonec/src/utils/clone.rs +++ b/ozonec/src/utils/clone.rs @@ -87,7 +87,7 @@ fn option_slice_as_mut_ptr(o: &mut Option<&mut [T]>) -> *mut T { } } -impl<'a> Clone3<'a> { +impl Clone3<'_> { pub fn exit_signal(&mut self, exit_signal: u64) -> &mut Self { self.exit_signal = exit_signal; self diff --git a/ozonec/src/utils/logger.rs b/ozonec/src/utils/logger.rs index 899b721d0c23d0519a7ffdc74b311bd87bf1e17a..9272d7e53a9fb37fce4dfc80ea24a0cfea2fa717 100644 --- a/ozonec/src/utils/logger.rs +++ b/ozonec/src/utils/logger.rs @@ -206,7 +206,7 @@ impl Log for Logger { eprintln!("Failed to log message: {:?}", e); return; } - if let Err(e) = log_rotate.rotate(fmt_msg.as_bytes().len()) { + if let Err(e) = log_rotate.rotate(fmt_msg.len()) { eprintln!("Failed to rotate log files: {:?}", e); } } diff --git a/tests/mod_test/tests/x86_64/cpu_hotplug_test.rs b/tests/mod_test/tests/x86_64/cpu_hotplug_test.rs index 6a279843d33dec4d5208778773ee93bf19865699..6a6fdabe5e44b2f2e5809d5a28d2fd60dfd833ce 100644 --- a/tests/mod_test/tests/x86_64/cpu_hotplug_test.rs +++ b/tests/mod_test/tests/x86_64/cpu_hotplug_test.rs @@ -228,7 +228,7 @@ fn overrange_hotplug_cpu() { } /// Hotplug cpu when max_cpus is not explicitly configured. -/// TestSetp: +/// TestStep: /// 1. Send id vcpu-1 and cpu-id 1 hotplug qmp command. /// 2. Destroy VM. /// Expect: diff --git a/ui/src/gtk/menu.rs b/ui/src/gtk/menu.rs index 05aad1879ccd3a77c0a3a625f7dc49cfe4820b0e..5b458c66dd48dcb403dcbb2602cbdaaf9bb43580 100644 --- a/ui/src/gtk/menu.rs +++ b/ui/src/gtk/menu.rs @@ -299,7 +299,7 @@ fn show_menubar_callback(gd: &Rc>) -> Result<()> { update_window_size(&active_gs) } -/// Make the window to fill the entir desktop. +/// Make the window to fill the entire desktop. fn full_screen_callback(gd: &Rc>) -> Result<()> { let borrowed_gd = gd.borrow(); let gtk_menu = borrowed_gd.gtk_menu.clone(); diff --git a/ui/src/gtk/mod.rs b/ui/src/gtk/mod.rs index 11a081aba1a7c3273d7b7b6b7a7e60cdd7c4c55b..68462f1b2f88e4ad5ca2f76a07eb30ec2f59a380 100644 --- a/ui/src/gtk/mod.rs +++ b/ui/src/gtk/mod.rs @@ -1073,7 +1073,7 @@ pub fn qmp_query_display_image() -> Result { if !locked_con.active { continue; } - let dev_name = &locked_con.dev_name.clone(); + let dev_name = locked_con.dev_name.clone(); if let Some(surface) = &mut locked_con.surface { // SAFETY: The image is created within the function, it can be ensure @@ -1087,7 +1087,7 @@ pub fn qmp_query_display_image() -> Result { surface.stride(), ) }?; - let mut file = create_file(&mut gpu_info, dev_name)?; + let mut file = create_file(&mut gpu_info, dev_name.as_str())?; cairo_image.write_to_png(&mut file)?; }; } @@ -1095,7 +1095,7 @@ pub fn qmp_query_display_image() -> Result { Ok(gpu_info) } -fn create_file(gpu_info: &mut GpuInfo, dev_name: &String) -> Result { +fn create_file(gpu_info: &mut GpuInfo, dev_name: &str) -> Result { let temp_dir = env::temp_dir().display().to_string(); let binding = temp_dir + "/stratovirt-images"; let path = Path::new(&binding); diff --git a/ui/src/pixman.rs b/ui/src/pixman.rs index be6643d1e15effaac486bfdc39e63a92e55c02cb..e2f27bce81d15094bf63f4742f5060001008f5b6 100644 --- a/ui/src/pixman.rs +++ b/ui/src/pixman.rs @@ -182,7 +182,7 @@ pub fn create_pixman_image( /// Bpp: bit per pixel pub fn bytes_per_pixel() -> usize { - ((pixman_format_bpp(pixman_format_code_t::PIXMAN_x8r8g8b8 as u32) + 7) / 8) as usize + pixman_format_bpp(pixman_format_code_t::PIXMAN_x8r8g8b8 as u32).div_ceil(8) as usize } /// Decrease the reference of image diff --git a/ui/src/vnc/client_io.rs b/ui/src/vnc/client_io.rs index 9866b2d8b9b5c4af937999402924d9b17ca0a131..863bd421448f508d5e6ef823112cb933cdc0e854 100644 --- a/ui/src/vnc/client_io.rs +++ b/ui/src/vnc/client_io.rs @@ -718,7 +718,7 @@ impl ClientIoHandler { self.update_frame_buff()?; } ClientMsg::KeyEvent => { - self.key_envent() + self.key_event() .unwrap_or_else(|e| error!("Key event error: {:?}", e)); } ClientMsg::PointerEvent => { @@ -966,7 +966,7 @@ impl ClientIoHandler { } /// Keyboard event. - fn key_envent(&mut self) -> Result<()> { + fn key_event(&mut self) -> Result<()> { if self.expect == 1 { self.expect = 8; return Ok(()); diff --git a/ui/src/vnc/encoding/enc_hextile.rs b/ui/src/vnc/encoding/enc_hextile.rs index 50e7f39f0772508a7cec33c75f8dbc2e5f78e224..c7512c03187dcf86ee26cd1dc5703d0df7b5a9f2 100644 --- a/ui/src/vnc/encoding/enc_hextile.rs +++ b/ui/src/vnc/encoding/enc_hextile.rs @@ -284,12 +284,12 @@ fn subrectangle_with_pixel_value( /// Second Byte: width-and-height-position. fn hextile_enc_sub_coloured(buf: &mut Vec, x: i32, y: i32, w: i32, h: i32) { buf.append( - &mut (((x & 0x0f) << 4 | (y & 0x0f)) as u8) + &mut ((((x & 0x0f) << 4) | (y & 0x0f)) as u8) .to_be_bytes() .to_vec(), ); buf.append( - &mut ((((w - 1) & 0x0f) << 4 | ((h - 1) & 0x0f)) as u8) + &mut (((((w - 1) & 0x0f) << 4) | ((h - 1) & 0x0f)) as u8) .to_be_bytes() .to_vec(), ); diff --git a/ui/src/vnc/mod.rs b/ui/src/vnc/mod.rs index 466ce59aff645ebb1d163cb70bd2c8132c4344d2..04bc12be250b71606b4f7223902ade8a31a94a4b 100644 --- a/ui/src/vnc/mod.rs +++ b/ui/src/vnc/mod.rs @@ -82,7 +82,7 @@ const DEFAULT_REFRESH_INTERVAL: u64 = 30; pub const BIT_PER_BYTE: u32 = 8; pub const fn round_up_div(n: u64, d: u64) -> u64 { - (n + d - 1) / d + n.div_ceil(d) } pub const fn round_up(n: u64, d: u64) -> u64 { diff --git a/util/src/evdev.rs b/util/src/evdev.rs index 612e398871581c28bc99c7be1326ad438d9f077e..ec4baedc189071e70b27a6460c4f151494ab544b 100644 --- a/util/src/evdev.rs +++ b/util/src/evdev.rs @@ -50,7 +50,7 @@ impl EvdevBuf { } pub fn get_bit(&self, bit: usize) -> bool { - if (bit + 7) / 8 > self.len { + if bit.div_ceil(8) > self.len { return false; } let idx = bit / 8; diff --git a/util/src/leak_bucket.rs b/util/src/leak_bucket.rs index 23a1d9109784a3ef1b9ef6bf478acfab966419b0..867705a25389b48fd4e8cb02c0787b479c7a834b 100644 --- a/util/src/leak_bucket.rs +++ b/util/src/leak_bucket.rs @@ -65,7 +65,7 @@ impl LeakBucket { /// # Arguments /// /// * `loop_context` - used for delay function call. - pub fn throttled(&mut self, loop_context: &mut EventLoopContext, need_units: u32) -> bool { + pub fn throttled(&mut self, loop_context: &EventLoopContext, need_units: u32) -> bool { // capacity value is zero, indicating that there is no need to limit if self.capacity == 0 { return false; diff --git a/util/src/logger.rs b/util/src/logger.rs index de35d83f6dcad5e8b49b9754279c7f3b37877dd8..0d194e9cd11df28ae1990e9fe124253691e33cba 100644 --- a/util/src/logger.rs +++ b/util/src/logger.rs @@ -136,7 +136,7 @@ impl Log for VmLogger { println!("Failed to log message {:?}", e); return; } - if let Err(e) = rotate.rotate_file(formatmsg.as_bytes().len()) { + if let Err(e) = rotate.rotate_file(formatmsg.len()) { println!("Failed to rotate log files {:?}", e); } } diff --git a/util/src/loop_context.rs b/util/src/loop_context.rs index 0a0af54f227e101d9ba9669ff25962b52b967924..eef83e2a47556ab99db0b0ea0504ad88ab7d045c 100644 --- a/util/src/loop_context.rs +++ b/util/src/loop_context.rs @@ -17,7 +17,7 @@ use std::io::Error; use std::os::unix::io::{AsRawFd, RawFd}; use std::rc::Rc; use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; -use std::sync::{Arc, Barrier, Mutex, RwLock}; +use std::sync::{Arc, Barrier, Mutex, OnceLock, RwLock}; use std::time::{Duration, Instant}; use anyhow::{anyhow, Context, Result}; @@ -214,7 +214,7 @@ pub struct EventLoopContext { /// Epoll file descriptor. epoll: Epoll, /// Control epoll loop running. - manager: Option>>, + manager: OnceLock>>, /// Used to wakeup epoll to re-evaluate events or timers. kick_event: EventFd, /// Used to avoid unnecessary kick operation when the @@ -227,7 +227,7 @@ pub struct EventLoopContext { /// Events abandoned are stored in garbage collector. gc: Arc>>>, /// Temp events vector, store wait returned events. - ready_events: Vec, + ready_events: Arc>>, /// Timer list timers: Arc>>>, /// The next timer id to be used. @@ -248,22 +248,18 @@ impl Drop for EventLoopContext { } } -// SAFETY: The closure in EventNotifier and Timer doesn't impl Send, they're -// not sent between threads actually. -unsafe impl Send for EventLoopContext {} - impl EventLoopContext { /// Constructs a new `EventLoopContext`. pub fn new(thread_exit_barrier: Arc) -> Self { let mut ctx = EventLoopContext { epoll: Epoll::new().unwrap(), - manager: None, + manager: OnceLock::new(), kick_event: create_new_eventfd().unwrap(), kick_me: AtomicBool::new(false), kicked: AtomicBool::new(false), events: Arc::new(RwLock::new(BTreeMap::new())), gc: Arc::new(RwLock::new(Vec::new())), - ready_events: vec![EpollEvent::default(); READY_EVENT_MAX], + ready_events: Arc::new(Mutex::new(vec![EpollEvent::default(); READY_EVENT_MAX])), timers: Arc::new(Mutex::new(Vec::new())), timer_next_id: AtomicU64::new(0), thread_pool: Arc::new(ThreadPool::default()), @@ -290,7 +286,7 @@ impl EventLoopContext { } // Force epoll.wait to exit to re-evaluate events and timers. - pub fn kick(&mut self) { + pub fn kick(&self) { self.kicked.store(true, Ordering::SeqCst); if self.kick_me.load(Ordering::SeqCst) { if let Err(e) = self.kick_event.write(1) { @@ -302,11 +298,13 @@ impl EventLoopContext { } } - pub fn set_manager(&mut self, manager: Arc>) { - self.manager = Some(manager); + pub fn set_manager(&self, manager: Arc>) { + if self.manager.set(manager).is_err() { + warn!("EventLoopManager has been set"); + } } - fn clear_gc(&mut self) { + fn clear_gc(&self) { let max_cnt = self.gc.write().unwrap().len(); let mut pop_cnt: usize = 0; @@ -323,7 +321,7 @@ impl EventLoopContext { } } - fn add_event(&mut self, mut event: EventNotifier) -> Result<()> { + fn add_event(&self, mut event: EventNotifier) -> Result<()> { // If there is one same alive event monitored, update the handlers and eventset. // If there is one same parked event, update the handlers and eventset but warn. // If there is no event in the map, insert the event and park the related. @@ -370,7 +368,7 @@ impl EventLoopContext { Ok(()) } - fn rm_event(&mut self, event: &EventNotifier) -> Result<()> { + fn rm_event(&self, event: &EventNotifier) -> Result<()> { // If there is no event in the map, return Error. // Else put the event in gc and reactivate the parked event. let mut events_map = self.events.write().unwrap(); @@ -420,7 +418,7 @@ impl EventLoopContext { Ok(()) } - fn modify_event(&mut self, mut event: EventNotifier) -> Result<()> { + fn modify_event(&self, mut event: EventNotifier) -> Result<()> { let mut events_map = self.events.write().unwrap(); match events_map.get_mut(&event.raw_fd) { Some(notifier) => { @@ -446,7 +444,7 @@ impl EventLoopContext { Ok(()) } - fn park_event(&mut self, event: &EventNotifier) -> Result<()> { + fn park_event(&self, event: &EventNotifier) -> Result<()> { let mut events_map = self.events.write().unwrap(); match events_map.get_mut(&event.raw_fd) { Some(notifier) => { @@ -468,7 +466,7 @@ impl EventLoopContext { Ok(()) } - fn resume_event(&mut self, event: &EventNotifier) -> Result<()> { + fn resume_event(&self, event: &EventNotifier) -> Result<()> { let mut events_map = self.events.write().unwrap(); match events_map.get_mut(&event.raw_fd) { Some(notifier) => { @@ -490,7 +488,7 @@ impl EventLoopContext { Ok(()) } - fn update_events_for_fd(&mut self, event: &EventNotifier, add: bool) -> Result<()> { + fn update_events_for_fd(&self, event: &EventNotifier, add: bool) -> Result<()> { let mut events_map = self.events.write().unwrap(); match events_map.get_mut(&event.raw_fd) { Some(notifier) => { @@ -524,7 +522,7 @@ impl EventLoopContext { /// # Arguments /// /// * `notifiers` - event notifiers wanted to add to or remove from `EventLoop`. - pub fn update_events(&mut self, notifiers: Vec) -> Result<()> { + pub fn update_events(&self, notifiers: Vec) -> Result<()> { for en in notifiers { trace::update_event(&en.raw_fd, &en.op); match en.op { @@ -557,8 +555,8 @@ impl EventLoopContext { } /// Executes `epoll.wait()` to wait for events, and call the responding callbacks. - pub fn run(&mut self) -> Result { - if let Some(manager) = &self.manager { + pub fn run(&self) -> Result { + if let Some(manager) = self.manager.get() { if manager.lock().unwrap().loop_should_exit() { manager.lock().unwrap().loop_cleanup()?; return Ok(false); @@ -569,7 +567,7 @@ impl EventLoopContext { Ok(true) } - pub fn iothread_run(&mut self) -> Result<()> { + pub fn iothread_run(&self) -> Result<()> { let min_timeout_ns = self.timers_min_duration(); if min_timeout_ns.is_none() { for _i in 0..AIO_PRFETCH_CYCLE_TIME { @@ -595,7 +593,7 @@ impl EventLoopContext { /// /// * `func` - the function will be called later. /// * `delay` - delay time. - pub fn timer_add(&mut self, func: Box, delay: Duration) -> u64 { + pub fn timer_add(&self, func: Box, delay: Duration) -> u64 { // insert in order of expire_time let mut timers = self.timers.lock().unwrap(); @@ -617,7 +615,7 @@ impl EventLoopContext { } /// Remove timer with specific timer id. - pub fn timer_del(&mut self, timer_id: u64) { + pub fn timer_del(&self, timer_id: u64) { let mut timers = self.timers.lock().unwrap(); for (i, t) in timers.iter().enumerate() { if timer_id == t.id { @@ -645,7 +643,7 @@ impl EventLoopContext { } /// Call function of the timers which have already expired. - pub fn run_timers(&mut self) { + pub fn run_timers(&self) { let now = get_current_time(); let mut expired_nr: usize = 0; @@ -665,7 +663,7 @@ impl EventLoopContext { } } - fn epoll_wait_manager(&mut self, mut time_out: Option) -> Result<()> { + fn epoll_wait_manager(&self, mut time_out: Option) -> Result<()> { let need_kick = !(time_out.is_some() && *time_out.as_ref().unwrap() == Duration::ZERO); if need_kick { self.kick_me.store(true, Ordering::SeqCst); @@ -687,11 +685,13 @@ impl EventLoopContext { }; } + let mut ready_events = self.ready_events.lock().unwrap(); + let time_out_ms = match time_out { Some(t) => i32::try_from(t.as_millis()).unwrap_or(i32::MAX), None => -1, }; - let ev_count = match self.epoll.wait(time_out_ms, &mut self.ready_events[..]) { + let ev_count = match self.epoll.wait(time_out_ms, &mut ready_events[..]) { Ok(ev_count) => ev_count, Err(e) if e.raw_os_error() == Some(libc::EINTR) => 0, Err(e) => return Err(anyhow!(UtilError::EpollWait(e))), @@ -703,14 +703,14 @@ impl EventLoopContext { for i in 0..ev_count { // SAFETY: elements in self.events_map never get released in other functions let event = unsafe { - let event_ptr = self.ready_events[i].data() as *const EventNotifier; + let event_ptr = ready_events[i].data() as *const EventNotifier; &*event_ptr as &EventNotifier }; let mut notifiers = Vec::new(); let status_locked = event.status.lock().unwrap(); if *status_locked == EventStatus::Alive { for handler in event.handlers.iter() { - match handler(self.ready_events[i].event_set(), event.raw_fd) { + match handler(ready_events[i].event_set(), event.raw_fd) { None => {} Some(mut notifier) => { notifiers.append(&mut notifier); @@ -729,8 +729,8 @@ impl EventLoopContext { Ok(()) } - pub fn clean_event_loop(&mut self) -> Result<()> { - if let Some(manager) = &self.manager { + pub fn clean_event_loop(&self) -> Result<()> { + if let Some(manager) = self.manager.get() { manager.lock().unwrap().loop_cleanup()?; } Ok(()) @@ -801,7 +801,7 @@ mod test { #[test] fn basic_test() { - let mut mainloop = EventLoopContext::new(Arc::new(Barrier::new(1))); + let mainloop = EventLoopContext::new(Arc::new(Barrier::new(1))); let mut notifiers = Vec::new(); let fd1 = EventFd::new(EFD_NONBLOCK).unwrap(); let fd1_related = EventFd::new(EFD_NONBLOCK).unwrap(); @@ -828,7 +828,7 @@ mod test { #[test] fn parked_event_test() { - let mut mainloop = EventLoopContext::new(Arc::new(Barrier::new(1))); + let mainloop = EventLoopContext::new(Arc::new(Barrier::new(1))); let mut notifiers = Vec::new(); let fd1 = EventFd::new(EFD_NONBLOCK).unwrap(); let fd2 = EventFd::new(EFD_NONBLOCK).unwrap(); @@ -875,7 +875,7 @@ mod test { #[test] fn event_handler_test() { - let mut mainloop = EventLoopContext::new(Arc::new(Barrier::new(1))); + let mainloop = EventLoopContext::new(Arc::new(Barrier::new(1))); let mut notifiers = Vec::new(); let fd1 = EventFd::new(EFD_NONBLOCK).unwrap(); let fd1_related = EventFd::new(EFD_NONBLOCK).unwrap(); @@ -914,7 +914,7 @@ mod test { #[test] fn error_operation_test() { - let mut mainloop = EventLoopContext::new(Arc::new(Barrier::new(1))); + let mainloop = EventLoopContext::new(Arc::new(Barrier::new(1))); let fd1 = EventFd::new(EFD_NONBLOCK).unwrap(); let leisure_fd = EventFd::new(EFD_NONBLOCK).unwrap(); @@ -951,7 +951,7 @@ mod test { #[test] fn error_parked_operation_test() { - let mut mainloop = EventLoopContext::new(Arc::new(Barrier::new(1))); + let mainloop = EventLoopContext::new(Arc::new(Barrier::new(1))); let fd1 = EventFd::new(EFD_NONBLOCK).unwrap(); let fd2 = EventFd::new(EFD_NONBLOCK).unwrap(); diff --git a/util/src/num_ops.rs b/util/src/num_ops.rs index f5ea59be220b5323a490857dc203d3d8ac00fc76..ff7c118d6ee4d87b011f7efba9a17847bbc24050 100644 --- a/util/src/num_ops.rs +++ b/util/src/num_ops.rs @@ -177,7 +177,7 @@ pub fn write_u64_low(origin: u64, value: u32) -> u64 { /// assert!(value == 0x1000_0000_1000_0000); /// ``` pub fn write_u64_high(origin: u64, value: u32) -> u64 { - u64::from(value) << 32 | (origin & 0x0000_0000_FFFF_FFFF_u64) + (u64::from(value) << 32) | (origin & 0x0000_0000_FFFF_FFFF_u64) } /// Extract from the 32 bit input @value the bit field specified by the diff --git a/util/src/ohos_binding/audio/mod.rs b/util/src/ohos_binding/audio/mod.rs index 7c5585c1ac7abf4ec14e879a7ee8f73339e576df..43b797a561930d653dadf69952dfad46fb28f75b 100755 --- a/util/src/ohos_binding/audio/mod.rs +++ b/util/src/ohos_binding/audio/mod.rs @@ -398,7 +398,7 @@ impl AudioContext { let mut other = AudioSpec::default(); other .set(size, rate, channels) - .map_or(false, |_| (self.spec == other)) + .is_ok_and(|_| (self.spec == other)) } } diff --git a/util/src/ohos_binding/audio/sys.rs b/util/src/ohos_binding/audio/sys.rs index 66440c38fb0210160ecb9b2ba80c947afde4d443..3260f60c5e8f97b2e47db7fd77981fe874e44dbc 100755 --- a/util/src/ohos_binding/audio/sys.rs +++ b/util/src/ohos_binding/audio/sys.rs @@ -305,7 +305,7 @@ extern "C" { builder: *mut *mut OhAudioStreamBuilder, type_: OhAudioStreamType, ) -> OhAudioStreamResult; - /// Destroy a streamBulder. + /// Destroy a streamBuilder. /// /// This function must be called when you are done using the builder. /// diff --git a/util/src/test_helper.rs b/util/src/test_helper.rs index 47cb11b622f3fc9d005347102464640d4cda0652..a8ee0ec52326b2cb762a71867ecfbc3856dc221b 100644 --- a/util/src/test_helper.rs +++ b/util/src/test_helper.rs @@ -10,7 +10,8 @@ // NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. // See the Mulan PSL v2 for more details. -use std::sync::{Arc, Mutex, RwLock}; +use std::sync::atomic::{AtomicU64, Ordering}; +use std::sync::{Arc, Mutex, OnceLock}; use std::time::{Duration, Instant}; use once_cell::sync::{Lazy, OnceCell}; @@ -41,7 +42,7 @@ impl IntxInfo { static TEST_ENABLED: OnceCell = OnceCell::new(); static TEST_BASE_TIME: OnceCell = OnceCell::new(); -static mut TEST_CLOCK: Option>> = None; +static TEST_CLOCK: OnceLock> = OnceLock::new(); pub static TEST_MSIX_LIST: Lazy>> = Lazy::new(|| Mutex::new(Vec::new())); pub static TEST_INTX_LIST: Lazy>> = Lazy::new(|| Mutex::new(Vec::new())); @@ -52,12 +53,7 @@ pub fn set_test_enabled() { if let Err(_e) = TEST_BASE_TIME.set(Instant::now()) { panic!("Failed to initialize clock"); } - // SAFETY: This module is only used for test. - unsafe { - if TEST_CLOCK.is_none() { - TEST_CLOCK = Some(Arc::new(RwLock::new(0))); - } - } + TEST_CLOCK.get_or_init(|| Arc::new(AtomicU64::new(0))); } pub fn is_test_enabled() -> bool { @@ -65,44 +61,32 @@ pub fn is_test_enabled() -> bool { } pub fn set_test_clock(value: u64) { - // SAFETY: This module is only used for test. - unsafe { - if TEST_CLOCK.is_none() { - panic!("TEST_CLOCK has not been initialized."); - } - if value <= get_test_clock() { - return; + let test_clock = TEST_CLOCK + .get() + .expect("TEST_CLOCK has not been initialized."); + let mut current = test_clock.load(Ordering::Acquire); + while value > current { + match test_clock.compare_exchange(current, value, Ordering::Release, Ordering::Acquire) { + Ok(_) => break, + Err(actual) => current = actual, } - - let mut test_clock = TEST_CLOCK.as_ref().unwrap().write().unwrap(); - *test_clock = value; } } pub fn get_test_clock() -> u64 { - // SAFETY: This module is only used for test. - unsafe { - if TEST_CLOCK.is_none() { - panic!("TEST_CLOCK has not been initialized."); - } - - *TEST_CLOCK.as_ref().unwrap().read().unwrap() - } + TEST_CLOCK + .get() + .expect("TEST_CLOCK has not been initialized.") + .load(Ordering::Acquire) } pub fn get_test_time() -> Instant { - // SAFETY: This module is only used for test. - unsafe { - if TEST_CLOCK.is_none() { - panic!("TEST_CLOCK has not been initialized."); - } - - TEST_BASE_TIME - .get() - .unwrap() - .checked_add(Duration::from_nanos(get_test_clock())) - .unwrap() - } + let base = TEST_BASE_TIME + .get() + .expect("TEST_BASE_TIME has not been initialized"); + let offset_nanos = get_test_clock(); + base.checked_add(Duration::from_nanos(offset_nanos)) + .expect("test time overflow") } pub fn add_msix_msg(addr: u64, data: u32) { diff --git a/vfio/src/vfio_pci.rs b/vfio/src/vfio_pci.rs index 9b2c595c6ceda28c4a31aa396e5dca7489d91deb..8dc8d316da28163f0decb739c1957eef69243be9 100644 --- a/vfio/src/vfio_pci.rs +++ b/vfio/src/vfio_pci.rs @@ -955,9 +955,12 @@ impl PciDevOps for VfioPciDevice { .msix .as_ref() .map_or(0, |m| m.lock().unwrap().msix_cap_offset as usize); - let was_enable = self.base.config.msix.as_ref().map_or(false, |m| { - m.lock().unwrap().is_enabled(&self.base.config.config) - }); + let was_enable = self + .base + .config + .msix + .as_ref() + .is_some_and(|m| m.lock().unwrap().is_enabled(&self.base.config.config)); let parent_bus = self.parent_bus().unwrap().upgrade().unwrap(); PCI_BUS!(parent_bus, locked_bus, pci_bus); self.base.config.write( @@ -979,9 +982,12 @@ impl PciDevOps for VfioPciDevice { } } } else if ranges_overlap(offset, size, cap_offset, MSIX_CAP_SIZE as usize).unwrap() { - let is_enable = self.base.config.msix.as_ref().map_or(false, |m| { - m.lock().unwrap().is_enabled(&self.base.config.config) - }); + let is_enable = self + .base + .config + .msix + .as_ref() + .is_some_and(|m| m.lock().unwrap().is_enabled(&self.base.config.config)); if !was_enable && is_enable { if let Err(e) = self.vfio_enable_msix() { diff --git a/virtio/src/device/balloon.rs b/virtio/src/device/balloon.rs index a44f2daa7f1768f72f14871c9241bac7024bae38..6fa950a9ac7b40a5b445be414318b01b88ce7813 100644 --- a/virtio/src/device/balloon.rs +++ b/virtio/src/device/balloon.rs @@ -82,7 +82,7 @@ struct GuestIovec { } #[derive(Clone, Copy, Default)] -#[repr(packed(1))] +#[repr(C, packed)] struct BalloonStat { _tag: u16, _val: u64, @@ -1251,10 +1251,9 @@ pub fn balloon_allow_list(syscall_allow_list: &mut Vec) { #[cfg(test)] mod tests { use super::*; - use crate::tests::{address_space_init, MEMORY_SIZE}; + use crate::tests::{address_space_init, eventloop_init, MEMORY_SIZE}; use crate::*; use address_space::{AddressAttr, AddressRange, HostMemMapping, Region}; - use machine_manager::event_loop::EventLoop; const QUEUE_SIZE: u16 = 256; @@ -1583,7 +1582,7 @@ mod tests { #[test] fn test_balloon_activate() { - EventLoop::object_init(&None).unwrap(); + eventloop_init(); let mem_space = address_space_init(); let interrupt_evt = EventFd::new(libc::EFD_NONBLOCK).unwrap(); @@ -1624,8 +1623,6 @@ mod tests { let mut bln = Balloon::new(bln_cfg, mem_space.clone()); bln.base.queues = queues; assert!(bln.activate(mem_space, interrupt_cb, queue_evts).is_ok()); - - EventLoop::loop_clean(); } #[test] diff --git a/virtio/src/device/block.rs b/virtio/src/device/block.rs index 17ac37a31669c7f6e05de43b05e339c2e41ef5b1..dc1907c011e49d80b3dc28d3db63cf5af924fa4b 100644 --- a/virtio/src/device/block.rs +++ b/virtio/src/device/block.rs @@ -1184,11 +1184,11 @@ impl VirtioDevice for Block { } fn init_config_features(&mut self) -> Result<()> { - self.base.device_features = 1_u64 << VIRTIO_F_VERSION_1 - | 1_u64 << VIRTIO_F_RING_INDIRECT_DESC - | 1_u64 << VIRTIO_F_RING_EVENT_IDX - | 1_u64 << VIRTIO_BLK_F_FLUSH - | 1_u64 << VIRTIO_BLK_F_SEG_MAX; + self.base.device_features = (1_u64 << VIRTIO_F_VERSION_1) + | (1_u64 << VIRTIO_F_RING_INDIRECT_DESC) + | (1_u64 << VIRTIO_F_RING_EVENT_IDX) + | (1_u64 << VIRTIO_BLK_F_FLUSH) + | (1_u64 << VIRTIO_BLK_F_SEG_MAX); if self.drive_cfg.readonly { self.base.device_features |= 1_u64 << VIRTIO_BLK_F_RO; }; @@ -1442,12 +1442,10 @@ mod tests { use vmm_sys_util::tempfile::TempFile; use super::*; - use crate::tests::address_space_init; + use crate::tests::{address_space_init, eventloop_init}; use crate::*; use address_space::{AddressAttr, GuestAddress}; - use machine_manager::config::{ - str_slip_to_clap, IothreadConfig, VmConfig, DEFAULT_VIRTQUEUE_SIZE, - }; + use machine_manager::config::{str_slip_to_clap, VmConfig, DEFAULT_VIRTQUEUE_SIZE}; use machine_manager::temp_cleaner::TempCleaner; const QUEUE_NUM_BLK: usize = 1; @@ -1490,7 +1488,8 @@ mod tests { // Use different input parameters to verify block `new()` and `realize()` functionality. #[test] fn test_block_init() { - assert!(EventLoop::object_init(&None).is_ok()); + eventloop_init(); + // New block device let mut block = init_default_block(); assert_eq!(block.disk_sectors, 0); @@ -1519,7 +1518,6 @@ mod tests { assert_eq!(block.device_type(), VIRTIO_TYPE_BLOCK); assert_eq!(block.queue_num(), QUEUE_NUM_BLK); assert_eq!(block.queue_size_max(), DEFAULT_VIRTQUEUE_SIZE); - EventLoop::loop_clean(); } // Test `write_config` and `read_config`. The main contests include: compare expect data and @@ -1631,13 +1629,7 @@ mod tests { fn test_iothread() { TempCleaner::object_init(); let thread_name = "io1".to_string(); - - // spawn io thread - let io_conf = IothreadConfig { - classtype: "iothread".to_string(), - id: thread_name.clone(), - }; - EventLoop::object_init(&Some(vec![io_conf])).unwrap(); + eventloop_init(); let mut block = init_default_block(); let file = TempFile::new().unwrap(); @@ -1788,6 +1780,5 @@ mod tests { } } TempCleaner::clean(); - EventLoop::loop_clean(); } } diff --git a/virtio/src/device/gpu.rs b/virtio/src/device/gpu.rs index e0eff987098ec23d7aeae7bb13951ba1b90496b1..fb0142e6ae148a643d914991370752c0abb53437 100644 --- a/virtio/src/device/gpu.rs +++ b/virtio/src/device/gpu.rs @@ -1183,7 +1183,7 @@ impl GpuIoHandler { } let pixman_format = get_image_format(res.pixman_image); - let bpp = (u32::from(pixman_format_bpp(pixman_format as u32)) + 8 - 1) / 8; + let bpp = u32::from(pixman_format_bpp(pixman_format as u32)).div_ceil(8); let pixman_stride = get_image_stride(res.pixman_image); let offset = info_set_scanout.rect.x_coord * bpp + info_set_scanout.rect.y_coord * pixman_stride as u32; @@ -1370,7 +1370,7 @@ impl GpuIoHandler { let res = &mut self.resources_list[res_idx]; let pixman_format = get_image_format(res.pixman_image); let width = get_image_width(res.pixman_image) as u32; - let bpp = (u32::from(pixman_format_bpp(pixman_format as u32)) + 8 - 1) / 8; + let bpp = u32::from(pixman_format_bpp(pixman_format as u32)).div_ceil(8); let stride = get_image_stride(res.pixman_image) as u32; let data: *mut u8 = get_image_data(res.pixman_image).cast(); @@ -1779,9 +1779,9 @@ impl VirtioDevice for Gpu { } fn init_config_features(&mut self) -> Result<()> { - self.base.device_features = 1u64 << VIRTIO_F_VERSION_1 - | 1u64 << VIRTIO_F_RING_INDIRECT_DESC - | 1u64 << VIRTIO_F_RING_EVENT_IDX; + self.base.device_features = (1u64 << VIRTIO_F_VERSION_1) + | (1u64 << VIRTIO_F_RING_INDIRECT_DESC) + | (1u64 << VIRTIO_F_RING_EVENT_IDX); if self.cfg.edid { self.base.device_features |= 1 << VIRTIO_GPU_F_EDID; } diff --git a/virtio/src/device/net.rs b/virtio/src/device/net.rs index 08a1fa4df82cebfc5c0acc3aaad41c217c461eee..e5fcbb288b399c43ea98b87c5aa361781cd30a45 100644 --- a/virtio/src/device/net.rs +++ b/virtio/src/device/net.rs @@ -1480,22 +1480,22 @@ impl VirtioDevice for Net { } fn init_config_features(&mut self) -> Result<()> { - self.base.device_features = 1 << VIRTIO_F_VERSION_1 - | 1 << VIRTIO_NET_F_CSUM - | 1 << VIRTIO_NET_F_GUEST_CSUM - | 1 << VIRTIO_NET_F_GUEST_TSO4 - | 1 << VIRTIO_NET_F_GUEST_TSO6 - | 1 << VIRTIO_NET_F_GUEST_UFO - | 1 << VIRTIO_NET_F_HOST_TSO4 - | 1 << VIRTIO_NET_F_HOST_TSO6 - | 1 << VIRTIO_NET_F_HOST_UFO - | 1 << VIRTIO_NET_F_CTRL_RX - | 1 << VIRTIO_NET_F_CTRL_VLAN - | 1 << VIRTIO_NET_F_CTRL_RX_EXTRA - | 1 << VIRTIO_NET_F_CTRL_MAC_ADDR - | 1 << VIRTIO_NET_F_CTRL_VQ - | 1 << VIRTIO_F_RING_INDIRECT_DESC - | 1 << VIRTIO_F_RING_EVENT_IDX; + self.base.device_features = (1 << VIRTIO_F_VERSION_1) + | (1 << VIRTIO_NET_F_CSUM) + | (1 << VIRTIO_NET_F_GUEST_CSUM) + | (1 << VIRTIO_NET_F_GUEST_TSO4) + | (1 << VIRTIO_NET_F_GUEST_TSO6) + | (1 << VIRTIO_NET_F_GUEST_UFO) + | (1 << VIRTIO_NET_F_HOST_TSO4) + | (1 << VIRTIO_NET_F_HOST_TSO6) + | (1 << VIRTIO_NET_F_HOST_UFO) + | (1 << VIRTIO_NET_F_CTRL_RX) + | (1 << VIRTIO_NET_F_CTRL_VLAN) + | (1 << VIRTIO_NET_F_CTRL_RX_EXTRA) + | (1 << VIRTIO_NET_F_CTRL_MAC_ADDR) + | (1 << VIRTIO_NET_F_CTRL_VQ) + | (1 << VIRTIO_F_RING_INDIRECT_DESC) + | (1 << VIRTIO_F_RING_EVENT_IDX); let mut locked_config = self.config_space.lock().unwrap(); @@ -1512,7 +1512,7 @@ impl VirtioDevice for Net { if let Some(tap) = self.taps.as_ref().map(|t| &t[0]) { if !tap.has_ufo() { self.base.device_features &= - !(1 << VIRTIO_NET_F_GUEST_UFO | 1 << VIRTIO_NET_F_HOST_UFO); + !((1 << VIRTIO_NET_F_GUEST_UFO) | (1 << VIRTIO_NET_F_HOST_UFO)); } } @@ -1579,7 +1579,7 @@ impl VirtioDevice for Net { let ctrl_info = Arc::new(Mutex::new(CtrlInfo::new(self.config_space.clone()))); self.ctrl_info = Some(ctrl_info.clone()); let driver_features = self.base.driver_features; - if (driver_features & 1 << VIRTIO_NET_F_CTRL_VQ != 0) && (queue_num % 2 != 0) { + if (driver_features & (1 << VIRTIO_NET_F_CTRL_VQ) != 0) && (queue_num % 2 != 0) { let ctrl_queue = queues[queue_num - 1].clone(); let ctrl_queue_evt = queue_evts[queue_num - 1].clone(); @@ -1798,6 +1798,7 @@ impl MigrationHook for Net {} #[cfg(test)] mod tests { use super::*; + use crate::tests::eventloop_init; #[test] fn test_net_init() { @@ -1963,7 +1964,7 @@ mod tests { #[test] fn test_iothread() { - EventLoop::object_init(&None).unwrap(); + eventloop_init(); let mut net = Net::new(NetworkInterfaceConfig::default(), NetDevcfg::default()); net.net_cfg.iothread = Some("iothread".to_string()); @@ -1976,7 +1977,5 @@ mod tests { } else { assert!(false); } - - EventLoop::loop_clean(); } } diff --git a/virtio/src/device/serial.rs b/virtio/src/device/serial.rs index 6f5a1bada2845f5204e126a2e69fbcea30e00ecf..7ea0293bad7421131ec619ce1e1ffe2d2df62709 100644 --- a/virtio/src/device/serial.rs +++ b/virtio/src/device/serial.rs @@ -224,9 +224,9 @@ impl VirtioDevice for Serial { } fn init_config_features(&mut self) -> Result<()> { - self.base.device_features = 1_u64 << VIRTIO_F_VERSION_1 - | 1_u64 << VIRTIO_CONSOLE_F_SIZE - | 1_u64 << VIRTIO_CONSOLE_F_MULTIPORT; + self.base.device_features = (1_u64 << VIRTIO_F_VERSION_1) + | (1_u64 << VIRTIO_CONSOLE_F_SIZE) + | (1_u64 << VIRTIO_CONSOLE_F_MULTIPORT); Ok(()) } diff --git a/virtio/src/lib.rs b/virtio/src/lib.rs index bfa0ef5db08e847178b8bb100fe63aa758f34fb9..c18637513b50ffc2b0f24ee68368cfab5cfa3ddd 100644 --- a/virtio/src/lib.rs +++ b/virtio/src/lib.rs @@ -553,9 +553,9 @@ pub trait VirtioDevice: Send + AsAny { } let features = if page == 0 { - u64::from(self.driver_features(1)) << 32 | u64::from(v) + (u64::from(self.driver_features(1)) << 32) | u64::from(v) } else { - u64::from(v) << 32 | u64::from(self.driver_features(0)) + (u64::from(v) << 32) | u64::from(self.driver_features(0)) }; self.virtio_base_mut().driver_features = features; } @@ -680,9 +680,9 @@ pub trait VirtioDevice: Send + AsAny { let queue_select = self.virtio_base().queue_select; let queues_config = &mut self.virtio_base_mut().queues_config; - return queues_config + queues_config .get_mut(queue_select as usize) - .with_context(|| "queue_select overflows"); + .with_context(|| "queue_select overflows") } /// Get ISR register. @@ -740,7 +740,7 @@ pub trait VirtioDevice: Send + AsAny { /// # Arguments /// /// * `_configs` - The related configs for device. - /// eg: DriveConfig and VirtioBlkDevConfig for virtio blk device. + /// eg: DriveConfig and VirtioBlkDevConfig for virtio blk device. fn update_config(&mut self, _configs: Vec>) -> Result<()> { bail!("Unsupported to update configuration") } @@ -934,6 +934,8 @@ mod tests { use address_space::{AddressSpace, GuestAddress, HostMemMapping, Region}; use devices::sysbus::{SysBus, IRQ_BASE, IRQ_MAX}; + use machine_manager::config::IothreadConfig; + use machine_manager::event_loop::EventLoop; pub const MEMORY_SIZE: u64 = 1024 * 1024; @@ -986,4 +988,18 @@ mod tests { .unwrap(); sys_space } + + pub fn eventloop_init() { + let thread_name = "io1".to_string(); + // spawn io thread + let io_conf = IothreadConfig { + classtype: "iothread".to_string(), + id: thread_name.clone(), + #[cfg(target_env = "ohos")] + qos: None, + #[cfg(target_env = "ohos")] + bundle_name: None, + }; + EventLoop::object_init(&Some(vec![io_conf])).unwrap(); + } } diff --git a/virtio/src/vhost/kernel/net.rs b/virtio/src/vhost/kernel/net.rs index 1131bac37dcf6d6ef06a499a8fee3f6b254b8ccd..0c2e792ff3eee614b6c4313a454ee08e1942f5f0 100644 --- a/virtio/src/vhost/kernel/net.rs +++ b/virtio/src/vhost/kernel/net.rs @@ -166,13 +166,13 @@ impl VirtioDevice for Net { vhost_features &= !(1_u64 << VIRTIO_F_ACCESS_PLATFORM); let mut device_features = vhost_features; - device_features |= 1 << VIRTIO_F_VERSION_1 - | 1 << VIRTIO_NET_F_CSUM - | 1 << VIRTIO_NET_F_GUEST_CSUM - | 1 << VIRTIO_NET_F_GUEST_TSO4 - | 1 << VIRTIO_NET_F_GUEST_UFO - | 1 << VIRTIO_NET_F_HOST_TSO4 - | 1 << VIRTIO_NET_F_HOST_UFO; + device_features |= (1 << VIRTIO_F_VERSION_1) + | (1 << VIRTIO_NET_F_CSUM) + | (1 << VIRTIO_NET_F_GUEST_CSUM) + | (1 << VIRTIO_NET_F_GUEST_TSO4) + | (1 << VIRTIO_NET_F_GUEST_UFO) + | (1 << VIRTIO_NET_F_HOST_TSO4) + | (1 << VIRTIO_NET_F_HOST_UFO); let mut locked_config = self.config_space.lock().unwrap(); @@ -240,7 +240,7 @@ impl VirtioDevice for Net { let queues = self.base.queues.clone(); let queue_num = queues.len(); let driver_features = self.base.driver_features; - if (driver_features & 1 << VIRTIO_NET_F_CTRL_VQ != 0) && (queue_num % 2 != 0) { + if (driver_features & (1 << VIRTIO_NET_F_CTRL_VQ) != 0) && (queue_num % 2 != 0) { let ctrl_queue = queues[queue_num - 1].clone(); let ctrl_queue_evt = queue_evts[queue_num - 1].clone(); let ctrl_info = Arc::new(Mutex::new(CtrlInfo::new(self.config_space.clone()))); diff --git a/virtio/src/vhost/user/block.rs b/virtio/src/vhost/user/block.rs index 4e0757f9fc0e309a0b032d6f71d660dc18bee843..e0293f59e5eef20bffc81d46fdd0ff7267bf0df8 100644 --- a/virtio/src/vhost/user/block.rs +++ b/virtio/src/vhost/user/block.rs @@ -138,9 +138,9 @@ impl VirtioDevice for Block { let protocol_features = locked_client .get_protocol_features() .with_context(|| "Failed to get protocol features for vhost-user blk")?; - let supported_protocol_features = 1 << VHOST_USER_PROTOCOL_F_MQ - | 1 << VHOST_USER_PROTOCOL_F_CONFIG - | 1 << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD; + let supported_protocol_features = (1 << VHOST_USER_PROTOCOL_F_MQ) + | (1 << VHOST_USER_PROTOCOL_F_CONFIG) + | (1 << VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD); self.protocol_features = supported_protocol_features & protocol_features; locked_client .set_protocol_features(self.protocol_features) @@ -183,15 +183,15 @@ impl VirtioDevice for Block { } drop(locked_client); - self.base.device_features = 1_u64 << VIRTIO_F_VERSION_1 - | 1_u64 << VIRTIO_BLK_F_SIZE_MAX - | 1_u64 << VIRTIO_BLK_F_TOPOLOGY - | 1_u64 << VIRTIO_BLK_F_BLK_SIZE - | 1_u64 << VIRTIO_BLK_F_FLUSH - | 1_u64 << VIRTIO_BLK_F_DISCARD - | 1_u64 << VIRTIO_BLK_F_WRITE_ZEROES - | 1_u64 << VIRTIO_BLK_F_SEG_MAX - | 1_u64 << VIRTIO_BLK_F_RO; + self.base.device_features = (1_u64 << VIRTIO_F_VERSION_1) + | (1_u64 << VIRTIO_BLK_F_SIZE_MAX) + | (1_u64 << VIRTIO_BLK_F_TOPOLOGY) + | (1_u64 << VIRTIO_BLK_F_BLK_SIZE) + | (1_u64 << VIRTIO_BLK_F_FLUSH) + | (1_u64 << VIRTIO_BLK_F_DISCARD) + | (1_u64 << VIRTIO_BLK_F_WRITE_ZEROES) + | (1_u64 << VIRTIO_BLK_F_SEG_MAX) + | (1_u64 << VIRTIO_BLK_F_RO); if self.blk_cfg.num_queues.unwrap_or(1) > 1 { self.base.device_features |= 1_u64 << VIRTIO_BLK_F_MQ; } diff --git a/virtio/src/vhost/user/net.rs b/virtio/src/vhost/user/net.rs index fc98344638fee0dc706ed85270db05dd98f7d88e..69458e491c6120f0860fdac7f33a8c2a09a14717 100644 --- a/virtio/src/vhost/user/net.rs +++ b/virtio/src/vhost/user/net.rs @@ -147,14 +147,14 @@ impl VirtioDevice for Net { .get_features() .with_context(|| "Failed to get features for vhost-user net")?; - let features = 1 << VIRTIO_F_VERSION_1 - | 1 << VIRTIO_NET_F_GUEST_CSUM - | 1 << VIRTIO_NET_F_GUEST_TSO4 - | 1 << VIRTIO_NET_F_GUEST_UFO - | 1 << VIRTIO_NET_F_HOST_TSO4 - | 1 << VIRTIO_NET_F_HOST_UFO - | 1 << VIRTIO_NET_F_MRG_RXBUF - | 1 << VIRTIO_F_RING_EVENT_IDX; + let features = (1 << VIRTIO_F_VERSION_1) + | (1 << VIRTIO_NET_F_GUEST_CSUM) + | (1 << VIRTIO_NET_F_GUEST_TSO4) + | (1 << VIRTIO_NET_F_GUEST_UFO) + | (1 << VIRTIO_NET_F_HOST_TSO4) + | (1 << VIRTIO_NET_F_HOST_UFO) + | (1 << VIRTIO_NET_F_MRG_RXBUF) + | (1 << VIRTIO_F_RING_EVENT_IDX); self.base.device_features &= features; let mut locked_config = self.config_space.lock().unwrap();