diff --git a/krun-sys/Cargo.toml b/krun-sys/Cargo.toml index 59acdc9e1..60a633a1a 100644 --- a/krun-sys/Cargo.toml +++ b/krun-sys/Cargo.toml @@ -1,13 +1,15 @@ [package] name = "krun-sys" version = "1.11.1" -edition = "2021" -rust-version = "1.77.0" +edition = "2024" +rust-version = "1.85.0" description = "Rust bindings for libkrun" repository = "https://github.com/containers/libkrun" license = "Apache-2.0" links = "krun" +[workspace] + [build-dependencies] bindgen = { version = "0.72.1", default-features = false } pkg-config = { version = "0.3", default-features = false } diff --git a/src/arch/Cargo.toml b/src/arch/Cargo.toml index a60963abb..0bc4d7eb4 100644 --- a/src/arch/Cargo.toml +++ b/src/arch/Cargo.toml @@ -2,7 +2,7 @@ name = "krun-arch" version = "0.1.0-1.18.0" authors = ["The libkrun Authors"] -edition = "2021" +edition = "2024" description = "Architecture-specific VM support for libkrun" license = "Apache-2.0" repository = "https://github.com/containers/libkrun" diff --git a/src/arch/src/aarch64/linux/regs.rs b/src/arch/src/aarch64/linux/regs.rs index 483825183..450f4d228 100644 --- a/src/arch/src/aarch64/linux/regs.rs +++ b/src/arch/src/aarch64/linux/regs.rs @@ -10,11 +10,11 @@ use std::{mem, mem::offset_of, num::TryFromIntError, result}; use crate::ArchMemoryInfo; use kvm_bindings::{ - kvm_regs, user_pt_regs, KVM_REG_ARM64, KVM_REG_ARM64_SYSREG, KVM_REG_ARM64_SYSREG_CRM_MASK, + KVM_REG_ARM_CORE, KVM_REG_ARM64, KVM_REG_ARM64_SYSREG, KVM_REG_ARM64_SYSREG_CRM_MASK, KVM_REG_ARM64_SYSREG_CRM_SHIFT, KVM_REG_ARM64_SYSREG_CRN_MASK, KVM_REG_ARM64_SYSREG_CRN_SHIFT, KVM_REG_ARM64_SYSREG_OP0_MASK, KVM_REG_ARM64_SYSREG_OP0_SHIFT, KVM_REG_ARM64_SYSREG_OP1_MASK, KVM_REG_ARM64_SYSREG_OP1_SHIFT, KVM_REG_ARM64_SYSREG_OP2_MASK, KVM_REG_ARM64_SYSREG_OP2_SHIFT, - KVM_REG_ARM_CORE, KVM_REG_SIZE_U64, + KVM_REG_SIZE_U64, kvm_regs, user_pt_regs, }; use kvm_ioctls::VcpuFd; diff --git a/src/arch/src/aarch64/mod.rs b/src/arch/src/aarch64/mod.rs index b3168ac93..f4c705c8e 100644 --- a/src/arch/src/aarch64/mod.rs +++ b/src/arch/src/aarch64/mod.rs @@ -18,10 +18,10 @@ pub use self::macos::*; use std::fmt::Debug; use crate::{ + ArchMemoryInfo, aarch64::layout::{ DRAM_MEM_MAX_SIZE, DRAM_MEM_START_EFI, DRAM_MEM_START_KERNEL, FIRMWARE_START, }, - ArchMemoryInfo, }; use vm_memory::{GuestAddress, GuestMemoryMmap}; use vmm_sys_util::align_upwards; diff --git a/src/arch/src/lib.rs b/src/arch/src/lib.rs index 10f4de073..f2365171e 100644 --- a/src/arch/src/lib.rs +++ b/src/arch/src/lib.rs @@ -29,8 +29,8 @@ pub mod aarch64; #[cfg(target_arch = "aarch64")] pub use aarch64::{ - arch_memory_regions, configure_system, layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE, - layout::IRQ_MAX, layout::RESET_VECTOR, Error, MMIO_MEM_START, + Error, MMIO_MEM_START, arch_memory_regions, configure_system, layout::CMDLINE_MAX_SIZE, + layout::IRQ_BASE, layout::IRQ_MAX, layout::RESET_VECTOR, }; /// Module for riscv64 related functionality. @@ -39,8 +39,8 @@ pub mod riscv64; #[cfg(target_arch = "riscv64")] pub use riscv64::{ - arch_memory_regions, configure_system, layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE, - layout::IRQ_MAX, layout::RESET_VECTOR, Error, MMIO_MEM_START, + Error, MMIO_MEM_START, arch_memory_regions, configure_system, layout::CMDLINE_MAX_SIZE, + layout::IRQ_BASE, layout::IRQ_MAX, layout::RESET_VECTOR, }; /// Module for x86_64 related functionality. @@ -49,9 +49,9 @@ pub mod x86_64; #[cfg(target_arch = "x86_64")] pub use crate::x86_64::{ - arch_memory_regions, configure_system, layout::CMDLINE_MAX_SIZE, layout::FIRMWARE_SIZE, + Error, arch_memory_regions, configure_system, layout::CMDLINE_MAX_SIZE, layout::FIRMWARE_SIZE, layout::FIRMWARE_START, layout::IRQ_BASE, layout::IRQ_MAX, layout::MMIO_MEM_START, - layout::RESET_VECTOR, Error, + layout::RESET_VECTOR, }; /// Type for returning public functions outcome. diff --git a/src/arch/src/riscv64/linux/regs.rs b/src/arch/src/riscv64/linux/regs.rs index c99bad91e..60c0e148c 100644 --- a/src/arch/src/riscv64/linux/regs.rs +++ b/src/arch/src/riscv64/linux/regs.rs @@ -5,7 +5,7 @@ use std::mem::offset_of; use std::result; use super::super::get_fdt_addr; -use kvm_bindings::{kvm_riscv_core, KVM_REG_RISCV_CORE}; +use kvm_bindings::{KVM_REG_RISCV_CORE, kvm_riscv_core}; use kvm_ioctls::VcpuFd; use vm_memory::GuestMemoryMmap; diff --git a/src/arch/src/riscv64/mod.rs b/src/arch/src/riscv64/mod.rs index e76c35720..2e3648e9b 100644 --- a/src/arch/src/riscv64/mod.rs +++ b/src/arch/src/riscv64/mod.rs @@ -11,7 +11,7 @@ pub use self::linux::*; use std::fmt::Debug; -use crate::{riscv64::layout::FIRMWARE_START, ArchMemoryInfo}; +use crate::{ArchMemoryInfo, riscv64::layout::FIRMWARE_START}; use vm_memory::{Address, GuestAddress, GuestMemory, GuestMemoryMmap}; use vmm_sys_util::align_upwards; diff --git a/src/arch/src/x86_64/interrupts.rs b/src/arch/src/x86_64/interrupts.rs index 1633215b7..4851a33f3 100644 --- a/src/arch/src/x86_64/interrupts.rs +++ b/src/arch/src/x86_64/interrupts.rs @@ -95,7 +95,7 @@ mod tests { v.iter_mut() .for_each(|x| *x = set_apic_delivery_mode(*x, 2)); - let after: Vec = v.iter().map(|x| ((*x & !0x700) | ((2) << 8))).collect(); + let after: Vec = v.iter().map(|x| (*x & !0x700) | ((2) << 8)).collect(); assert_eq!(v, after); } diff --git a/src/arch/src/x86_64/mod.rs b/src/arch/src/x86_64/mod.rs index 7c4b6c83d..fcb57f763 100644 --- a/src/arch/src/x86_64/mod.rs +++ b/src/arch/src/x86_64/mod.rs @@ -21,7 +21,7 @@ use crate::x86_64::layout::{EBDA_START, FIRST_ADDR_PAST_32BITS, MMIO_MEM_START}; #[cfg(feature = "tee")] use crate::x86_64::layout::{FIRMWARE_SIZE, FIRMWARE_START}; use crate::{ArchMemoryInfo, InitrdConfig}; -use arch_gen::x86::bootparam::{boot_params, E820_RAM}; +use arch_gen::x86::bootparam::{E820_RAM, boot_params}; use vm_memory::Bytes; use vm_memory::{Address, ByteValued, GuestAddress, GuestMemoryMmap}; use vmm_sys_util::align_upwards; @@ -182,10 +182,10 @@ pub fn arch_memory_regions( let page_size: usize = unsafe { libc::sysconf(libc::_SC_PAGESIZE).try_into().unwrap() }; let size = align_upwards!(size, page_size); - if let Some(kernel_load_addr) = kernel_load_addr { - if size < (kernel_load_addr + kernel_size as u64) as usize { - panic!("Kernel doesn't fit in RAM"); - } + if let Some(kernel_load_addr) = kernel_load_addr + && size < (kernel_load_addr + kernel_size as u64) as usize + { + panic!("Kernel doesn't fit in RAM"); } // It's safe to cast MMIO_MEM_START to usize because it fits in a u32 variable @@ -462,12 +462,14 @@ mod tests { // Exercise the scenario where the field storing the length of the e820 entry table is // is bigger than the allocated memory. params.e820_entries = params.e820_map.len() as u8 + 1; - assert!(add_e820_entry( - &mut params, - e820_map[0].addr, - e820_map[0].size, - e820_map[0].type_ - ) - .is_err()); + assert!( + add_e820_entry( + &mut params, + e820_map[0].addr, + e820_map[0].size, + e820_map[0].type_ + ) + .is_err() + ); } } diff --git a/src/arch/src/x86_64/mptable.rs b/src/arch/src/x86_64/mptable.rs index 1b4511453..9e22e0664 100644 --- a/src/arch/src/x86_64/mptable.rs +++ b/src/arch/src/x86_64/mptable.rs @@ -81,7 +81,7 @@ pub const MAX_SUPPORTED_CPUS: u32 = 254; // Convenience macro for making arrays of diverse character types. macro_rules! char_array { - ($t:ty; $( $c:expr ),*) => ( [ $( $c as $t ),* ] ) + ($t:ty; $( $c:expr_2021 ),*) => ( [ $( $c as $t ),* ] ) } // Most of these variables are sourced from the Intel MP Spec 1.4. @@ -376,7 +376,7 @@ mod tests { let mut buf: Vec = vec![0; mpc_table.0.length as usize]; mem.write_volatile_to(mpc_offset, &mut buf, mpc_table.0.length as usize) .unwrap(); - sum.write(&buf).unwrap(); + sum.write_all(&buf).unwrap(); assert_eq!(sum.0, 0); } diff --git a/src/arch/src/x86_64/msr.rs b/src/arch/src/x86_64/msr.rs index 8a3d0db0e..655c13c90 100644 --- a/src/arch/src/x86_64/msr.rs +++ b/src/arch/src/x86_64/msr.rs @@ -5,7 +5,7 @@ use std::result; use arch_gen::x86::msr_index::*; -use kvm_bindings::{kvm_msr_entry, MsrList, Msrs}; +use kvm_bindings::{MsrList, Msrs, kvm_msr_entry}; use kvm_ioctls::{Kvm, VcpuFd}; #[derive(Debug)] @@ -55,7 +55,7 @@ const MSR_IA32_PRED_CMD: u32 = 0x0000_0049; // Creates a MsrRange of one msr given as argument. macro_rules! SINGLE_MSR { - ($msr:expr) => { + ($msr:expr_2021) => { MsrRange { base: $msr, nmsrs: 1, @@ -65,7 +65,7 @@ macro_rules! SINGLE_MSR { // Creates a MsrRange of with msr base and count given as arguments. macro_rules! MSR_RANGE { - ($first:expr, $count:expr) => { + ($first:expr_2021, $count:expr_2021) => { MsrRange { base: $first, nmsrs: $count, diff --git a/src/arch_gen/Cargo.toml b/src/arch_gen/Cargo.toml index 5dad64c27..55d1320f5 100644 --- a/src/arch_gen/Cargo.toml +++ b/src/arch_gen/Cargo.toml @@ -2,7 +2,7 @@ name = "krun-arch-gen" version = "0.1.0-1.18.0" authors = ["The libkrun Authors"] -edition = "2021" +edition = "2024" description = "Generated architecture-specific definitions for libkrun" license = "Apache-2.0" repository = "https://github.com/containers/libkrun" diff --git a/src/arch_gen/src/x86/bootparam.rs b/src/arch_gen/src/x86/bootparam.rs index 7958d0076..690de91a5 100644 --- a/src/arch_gen/src/x86/bootparam.rs +++ b/src/arch_gen/src/x86/bootparam.rs @@ -22,11 +22,11 @@ impl __IncompleteArrayField { } #[inline] pub unsafe fn as_slice(&self, len: usize) -> &[T] { - ::std::slice::from_raw_parts(self.as_ptr(), len) + unsafe { ::std::slice::from_raw_parts(self.as_ptr(), len) } } #[inline] pub unsafe fn as_mut_slice(&mut self, len: usize) -> &mut [T] { - ::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len) + unsafe { ::std::slice::from_raw_parts_mut(self.as_mut_ptr(), len) } } } impl ::std::fmt::Debug for __IncompleteArrayField { diff --git a/src/aws_nitro/Cargo.toml b/src/aws_nitro/Cargo.toml index 3db64b14d..c2da65793 100644 --- a/src/aws_nitro/Cargo.toml +++ b/src/aws_nitro/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "krun-aws-nitro" version = "0.1.0-1.18.0" -edition = "2021" +edition = "2024" description = "AWS Nitro Enclaves support for libkrun" license = "Apache-2.0" repository = "https://github.com/containers/libkrun" diff --git a/src/aws_nitro/src/enclave/args_writer.rs b/src/aws_nitro/src/enclave/args_writer.rs index 277d213e0..ac52d07f7 100644 --- a/src/aws_nitro/src/enclave/args_writer.rs +++ b/src/aws_nitro/src/enclave/args_writer.rs @@ -1,9 +1,9 @@ // SPDX-License-Identifier: Apache-2.0 -use crate::enclave::{proxy::DeviceProxyList, VsockPortOffset}; +use crate::enclave::{VsockPortOffset, proxy::DeviceProxyList}; use libc::c_int; use nitro_enclaves::launch::PollTimeout; -use nix::poll::{poll, PollFd, PollFlags, PollTimeout as NixPollTimeout}; +use nix::poll::{PollFd, PollFlags, PollTimeout as NixPollTimeout, poll}; use std::{ ffi::{self, CString}, fmt, @@ -12,7 +12,7 @@ use std::{ os::fd::AsFd, str::FromStr, }; -use vsock::{VsockAddr, VsockListener, VsockStream, VMADDR_CID_ANY}; +use vsock::{VMADDR_CID_ANY, VsockAddr, VsockListener, VsockStream}; // A known byte that libkrun-awsnitro and the enclave initramfs will exchange to confirm that startup // was successful and the initramfs is ready to begin reading enclave arguments. diff --git a/src/aws_nitro/src/enclave/mod.rs b/src/aws_nitro/src/enclave/mod.rs index 54b728d89..cf2f92ee4 100644 --- a/src/aws_nitro/src/enclave/mod.rs +++ b/src/aws_nitro/src/enclave/mod.rs @@ -3,14 +3,14 @@ pub(crate) mod args_writer; pub(crate) mod proxy; -use super::error::{return_code, start, Error}; +use super::error::{Error, return_code, start}; use args_writer::EnclaveArgsWriter; use nitro_enclaves::{ - launch::{ImageType, Launcher, MemoryInfo, PollTimeout, StartFlags}, Device, + launch::{ImageType, Launcher, MemoryInfo, PollTimeout, StartFlags}, }; use proxy::{ - net::NetProxy, output::OutputProxy, signal_handler::SignalHandler, DeviceProxy, DeviceProxyList, + DeviceProxy, DeviceProxyList, net::NetProxy, output::OutputProxy, signal_handler::SignalHandler, }; use std::{ env, @@ -22,7 +22,7 @@ use std::{ thread::{self, JoinHandle}, }; use tar::HeaderMode; -use vsock::{VsockAddr, VsockListener, VMADDR_CID_ANY}; +use vsock::{VMADDR_CID_ANY, VsockAddr, VsockListener}; const KRUN_NITRO_EIF_PATH_ENV_VAR: &str = "KRUN_NITRO_EIF_PATH"; const KRUN_NITRO_EIF_PATH_DEFAULT: &str = "/krun-awsnitro/krun-awsnitro.eif"; @@ -255,8 +255,10 @@ impl NitroEnclave { fn start_console_debug(&self, cid: u32) -> Result<(), proxy::Error> { let mut output = OutputProxy::new(&self.output_path, true)?; let mut vsock_rcv = output.vsock(cid)?; - let _: JoinHandle> = thread::spawn(move || loop { - output.rcv(&mut vsock_rcv)?; + let _: JoinHandle> = thread::spawn(move || { + loop { + output.rcv(&mut vsock_rcv)?; + } }); Ok(()) diff --git a/src/aws_nitro/src/enclave/proxy/mod.rs b/src/aws_nitro/src/enclave/proxy/mod.rs index eace1d2d7..4ac11360c 100644 --- a/src/aws_nitro/src/enclave/proxy/mod.rs +++ b/src/aws_nitro/src/enclave/proxy/mod.rs @@ -57,22 +57,24 @@ impl DeviceProxyList { // Receiver thread. Receive data from the vsock and perform some proxy-dependent // action with the data. - let rcv: JoinHandle> = thread::spawn(move || loop { - // Proxy rcv method returns the number of bytes read from the vsock. - match proxy.rcv(&mut vsock_rcv) { - // Zero bytes read indicates the enclave has closed the vsock connection. - // Notify the sender thread that the vsock was closed. - Ok(0) => { - let _ = tx.send(()); - return Ok(()); - } - // Bytes were read, continue the receive process. - Ok(_) => continue, - // An error occured, exit the receiver thread and notify the sender thread to - // also exit. - Err(e) => { - let _ = tx.send(()); - return Err(e); + let rcv: JoinHandle> = thread::spawn(move || { + loop { + // Proxy rcv method returns the number of bytes read from the vsock. + match proxy.rcv(&mut vsock_rcv) { + // Zero bytes read indicates the enclave has closed the vsock connection. + // Notify the sender thread that the vsock was closed. + Ok(0) => { + let _ = tx.send(()); + return Ok(()); + } + // Bytes were read, continue the receive process. + Ok(_) => continue, + // An error occured, exit the receiver thread and notify the sender thread to + // also exit. + Err(e) => { + let _ = tx.send(()); + return Err(e); + } } } }); diff --git a/src/aws_nitro/src/enclave/proxy/proxies/net.rs b/src/aws_nitro/src/enclave/proxy/proxies/net.rs index 3a68a8645..d05900705 100644 --- a/src/aws_nitro/src/enclave/proxy/proxies/net.rs +++ b/src/aws_nitro/src/enclave/proxy/proxies/net.rs @@ -1,9 +1,9 @@ // SPDX-License-Identifier: Apache-2.0 use crate::enclave::{ + VsockPortOffset, args_writer::EnclaveArg, proxy::{DeviceProxy, Error, Result}, - VsockPortOffset, }; use std::{ io::{ErrorKind, Read, Write}, @@ -14,7 +14,7 @@ use std::{ }, time::Duration, }; -use vsock::{VsockAddr, VsockListener, VsockStream, VMADDR_CID_ANY}; +use vsock::{VMADDR_CID_ANY, VsockAddr, VsockListener, VsockStream}; /// Network proxy. Forwards data to/from a UNIX socket and vsock within an enclave to provide /// network access. diff --git a/src/aws_nitro/src/enclave/proxy/proxies/output.rs b/src/aws_nitro/src/enclave/proxy/proxies/output.rs index 53280a1e5..5b19cb4fd 100644 --- a/src/aws_nitro/src/enclave/proxy/proxies/output.rs +++ b/src/aws_nitro/src/enclave/proxy/proxies/output.rs @@ -1,9 +1,9 @@ // SPDX-License-Identifier: Apache-2.0 use crate::enclave::{ + VsockPortOffset, args_writer::EnclaveArg, proxy::{DeviceProxy, Error}, - VsockPortOffset, }; use std::{ fs::File, @@ -11,7 +11,7 @@ use std::{ io::{Read, Write}, path::PathBuf, }; -use vsock::{VsockAddr, VsockListener, VsockStream, VMADDR_CID_ANY, VMADDR_CID_HYPERVISOR}; +use vsock::{VMADDR_CID_ANY, VMADDR_CID_HYPERVISOR, VsockAddr, VsockListener, VsockStream}; type Result = std::result::Result; diff --git a/src/aws_nitro/src/enclave/proxy/proxies/signal_handler.rs b/src/aws_nitro/src/enclave/proxy/proxies/signal_handler.rs index 3d0483010..0d66c726d 100644 --- a/src/aws_nitro/src/enclave/proxy/proxies/signal_handler.rs +++ b/src/aws_nitro/src/enclave/proxy/proxies/signal_handler.rs @@ -1,18 +1,18 @@ // SPDX-License-Identifier: Apache-2.0 use crate::enclave::{ - proxy::{EnclaveArg, Error, Result}, DeviceProxy, VsockPortOffset, + proxy::{EnclaveArg, Error, Result}, }; use signal_hook::consts::SIGTERM; use std::{ io::{ErrorKind, Read, Write}, sync::{ - atomic::{AtomicBool, Ordering}, Arc, + atomic::{AtomicBool, Ordering}, }, }; -use vsock::{VsockAddr, VsockListener, VsockStream, VMADDR_CID_ANY}; +use vsock::{VMADDR_CID_ANY, VsockAddr, VsockListener, VsockStream}; /// Signal handler proxy. Forwards signals from the host to the enclave. Currently, only SIGTERM is /// supported. diff --git a/src/cpuid/Cargo.toml b/src/cpuid/Cargo.toml index 8066b3c49..bbbfa98d5 100644 --- a/src/cpuid/Cargo.toml +++ b/src/cpuid/Cargo.toml @@ -2,7 +2,7 @@ name = "krun-cpuid" version = "0.1.0-1.18.0" authors = ["The libkrun Authors"] -edition = "2021" +edition = "2024" description = "CPUID handling for libkrun" license = "Apache-2.0" repository = "https://github.com/containers/libkrun" diff --git a/src/cpuid/src/bit_helper.rs b/src/cpuid/src/bit_helper.rs index 68e06654b..9c5ec564f 100644 --- a/src/cpuid/src/bit_helper.rs +++ b/src/cpuid/src/bit_helper.rs @@ -81,7 +81,7 @@ impl BitRangeExt for BitRange { } macro_rules! bit_range { - ($msb_index:expr, $lsb_index:expr) => { + ($msb_index:expr_2021, $lsb_index:expr_2021) => { BitRange { msb_index: $msb_index, lsb_index: $lsb_index, diff --git a/src/cpuid/src/brand_string.rs b/src/cpuid/src/brand_string.rs index 825a11fd4..01fdac93b 100644 --- a/src/cpuid/src/brand_string.rs +++ b/src/cpuid/src/brand_string.rs @@ -86,12 +86,12 @@ impl BrandString { match vendor_id { VENDOR_ID_INTEL => { let mut this = BrandString::from_bytes_unchecked(BRAND_STRING_INTEL); - if let Ok(host_bstr) = BrandString::from_host_cpuid() { - if let Some(freq) = host_bstr.find_freq() { - this.push_bytes(b" @ ").unwrap(); - this.push_bytes(freq) - .expect("Unexpected frequency information in host CPUID"); - } + if let Ok(host_bstr) = BrandString::from_host_cpuid() + && let Some(freq) = host_bstr.find_freq() + { + this.push_bytes(b" @ ").unwrap(); + this.push_bytes(freq) + .expect("Unexpected frequency information in host CPUID"); } this } @@ -304,7 +304,7 @@ impl BrandString { #[cfg(test)] mod tests { - use std::iter::repeat; + use std::iter::repeat_n; use super::*; @@ -374,7 +374,7 @@ mod tests { // Test BrandString::push_bytes() // let actual_len = bstr.as_bytes().len(); - let mut old_bytes: Vec = repeat(0).take(actual_len).collect(); + let mut old_bytes: Vec = repeat_n(0, actual_len).collect(); old_bytes.copy_from_slice(bstr.as_bytes()); assert_eq!( bstr.push_bytes(&_overflow), @@ -389,7 +389,7 @@ mod tests { match BrandString::from_host_cpuid() { Ok(bstr) => { for leaf in 0x8000_0002..=0x8000_0004_u32 { - let host_regs = unsafe { host_cpuid(leaf) }; + let host_regs = host_cpuid(leaf); assert_eq!(bstr.get_reg_for_leaf(leaf, Reg::EAX), host_regs.eax); assert_eq!(bstr.get_reg_for_leaf(leaf, Reg::EBX), host_regs.ebx); assert_eq!(bstr.get_reg_for_leaf(leaf, Reg::ECX), host_regs.ecx); @@ -399,7 +399,7 @@ mod tests { Err(Error::NotSupported) => { // from_host_cpuid() should only fail if the host CPU doesn't support // CPUID leaves up to 0x80000004, so let's make sure that's what happened. - let host_regs = unsafe { host_cpuid(0x8000_0000) }; + let host_regs = host_cpuid(0x8000_0000); assert!(host_regs.eax < 0x8000_0004); } _ => panic!("This function should not return another type of error"), diff --git a/src/cpuid/src/template/c3.rs b/src/cpuid/src/template/c3.rs index 8aec89ebe..9be22c147 100644 --- a/src/cpuid/src/template/c3.rs +++ b/src/cpuid/src/template/c3.rs @@ -4,7 +4,7 @@ use crate::bit_helper::BitHelper; use crate::cpu_leaf::*; use crate::transformer::*; -use kvm_bindings::{kvm_cpuid_entry2, CpuId}; +use kvm_bindings::{CpuId, kvm_cpuid_entry2}; fn update_feature_info_entry(entry: &mut kvm_cpuid_entry2, _vm_spec: &VmSpec) -> Result<(), Error> { use crate::cpu_leaf::leaf_0x1::*; diff --git a/src/cpuid/src/template/t2.rs b/src/cpuid/src/template/t2.rs index b1232f5dd..94108a2af 100644 --- a/src/cpuid/src/template/t2.rs +++ b/src/cpuid/src/template/t2.rs @@ -4,7 +4,7 @@ use crate::bit_helper::BitHelper; use crate::cpu_leaf::*; use crate::transformer::*; -use kvm_bindings::{kvm_cpuid_entry2, CpuId}; +use kvm_bindings::{CpuId, kvm_cpuid_entry2}; fn update_feature_info_entry(entry: &mut kvm_cpuid_entry2, _vm_spec: &VmSpec) -> Result<(), Error> { use crate::cpu_leaf::leaf_0x1::*; diff --git a/src/cpuid/src/transformer/common.rs b/src/cpuid/src/transformer/common.rs index 9c09b10e4..e6b8ea96c 100644 --- a/src/cpuid/src/transformer/common.rs +++ b/src/cpuid/src/transformer/common.rs @@ -6,7 +6,7 @@ use crate::bit_helper::BitHelper; use crate::common::get_cpuid; use crate::transformer::Error::FamError; -use kvm_bindings::{kvm_cpuid_entry2, CpuId}; +use kvm_bindings::{CpuId, kvm_cpuid_entry2}; // constants for setting the fields of kvm_cpuid2 structures // CPUID bits in ebx, ecx, and edx. @@ -145,7 +145,7 @@ mod tests { assert_eq!(get_max_cpus_per_package(4).unwrap(), 4); assert_eq!(get_max_cpus_per_package(6).unwrap(), 8); - assert!(get_max_cpus_per_package(u8::max_value()).is_err()); + assert!(get_max_cpus_per_package(u8::MAX).is_err()); } fn check_update_feature_info_entry(cpu_count: u8, expected_htt: bool) { diff --git a/src/cpuid/src/transformer/mod.rs b/src/cpuid/src/transformer/mod.rs index 763c49626..2acd95e5d 100644 --- a/src/cpuid/src/transformer/mod.rs +++ b/src/cpuid/src/transformer/mod.rs @@ -5,7 +5,7 @@ pub mod amd; pub mod common; pub mod intel; -pub use kvm_bindings::{kvm_cpuid_entry2, CpuId}; +pub use kvm_bindings::{CpuId, kvm_cpuid_entry2}; use crate::brand_string::BrandString; use crate::brand_string::Reg as BsReg; @@ -132,9 +132,11 @@ mod tests { let mut cpuid = CpuId::new(num_entries).unwrap(); let vm_spec = VmSpec::new(0, 1, false, false); cpuid.as_mut_slice()[0].function = PROCESSED_FN; - assert!(MockCpuidTransformer {} - .process_cpuid(&mut cpuid, &vm_spec.unwrap()) - .is_ok()); + assert!( + MockCpuidTransformer {} + .process_cpuid(&mut cpuid, &vm_spec.unwrap()) + .is_ok() + ); assert!(cpuid.as_mut_slice().len() == num_entries); for entry in cpuid.as_mut_slice().iter() { diff --git a/src/devices/Cargo.toml b/src/devices/Cargo.toml index eacb6cc97..0a72563c7 100644 --- a/src/devices/Cargo.toml +++ b/src/devices/Cargo.toml @@ -2,7 +2,7 @@ name = "krun-devices" version = "0.1.0-1.18.0" authors = ["The libkrun Authors"] -edition = "2021" +edition = "2024" build = "build.rs" description = "Virtual device emulation for libkrun" license = "Apache-2.0" diff --git a/src/devices/src/bus.rs b/src/devices/src/bus.rs index e47e13ac3..77a42ce9a 100644 --- a/src/devices/src/bus.rs +++ b/src/devices/src/bus.rs @@ -266,9 +266,10 @@ mod tests { let mut bus = Bus::new(); let mut data = [1, 2, 3, 4]; - assert!(bus - .insert(Arc::new(Mutex::new(DummyDevice)), 0x10, 0x10) - .is_ok()); + assert!( + bus.insert(Arc::new(Mutex::new(DummyDevice)), 0x10, 0x10) + .is_ok() + ); assert!(bus.write(0, 0x10, &data)); let bus_clone = bus.clone(); assert!(bus.read(0, 0x10, &mut data)); diff --git a/src/devices/src/fdt/aarch64.rs b/src/devices/src/fdt/aarch64.rs index a3135472a..7e5ee6ff1 100644 --- a/src/devices/src/fdt/aarch64.rs +++ b/src/devices/src/fdt/aarch64.rs @@ -9,9 +9,9 @@ use std::collections::HashMap; use std::fmt::Debug; use std::{io, result}; -use crate::legacy::gic::GICDevice; -use crate::legacy::IrqChip; use crate::DeviceType; +use crate::legacy::IrqChip; +use crate::legacy::gic::GICDevice; use arch::aarch64::layout::{GTIMER_HYP, GTIMER_PHYS, GTIMER_SEC, GTIMER_VIRT}; use arch::{ArchMemoryInfo, InitrdConfig}; use vm_fdt::{Error as FdtError, FdtWriter}; diff --git a/src/devices/src/fdt/riscv64.rs b/src/devices/src/fdt/riscv64.rs index 9d6a5a41b..c9431833b 100644 --- a/src/devices/src/fdt/riscv64.rs +++ b/src/devices/src/fdt/riscv64.rs @@ -5,9 +5,9 @@ use std::collections::HashMap; use std::fmt::Debug; use std::{io, result}; -use crate::legacy::aia::AIADevice; -use crate::legacy::IrqChip; use crate::DeviceType; +use crate::legacy::IrqChip; +use crate::legacy::aia::AIADevice; use arch::riscv64::get_fdt_addr; use arch::riscv64::layout::IRQ_BASE; use arch::{ArchMemoryInfo, InitrdConfig}; diff --git a/src/devices/src/legacy/aarch64/gpio.rs b/src/devices/src/legacy/aarch64/gpio.rs index 7f9c32174..6ca9b51de 100644 --- a/src/devices/src/legacy/aarch64/gpio.rs +++ b/src/devices/src/legacy/aarch64/gpio.rs @@ -29,10 +29,10 @@ const GPIORIE: u64 = 0x414; // Raw Interrupt Status Register const GPIOMIS: u64 = 0x418; // Masked Interrupt Status Register const GPIOIC: u64 = 0x41c; // Interrupt Clear Register const GPIOAFSEL: u64 = 0x420; // Mode Control Select Register - // From 0x424 to 0xFDC => reserved space. - // From 0xFE0 to 0xFFC => Peripheral and PrimeCell Identification Registers which are Read Only registers. - // These registers can conceptually be treated as a 32-bit register, and PartNumber[11:0] is used to identify the peripheral. - // We are putting the expected values (look at 'Reset value' column from above mentioned document) in an array. +// From 0x424 to 0xFDC => reserved space. +// From 0xFE0 to 0xFFC => Peripheral and PrimeCell Identification Registers which are Read Only registers. +// These registers can conceptually be treated as a 32-bit register, and PartNumber[11:0] is used to identify the peripheral. +// We are putting the expected values (look at 'Reset value' column from above mentioned document) in an array. const GPIO_ID: [u8; 8] = [0x61, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1]; // ID Margins const GPIO_ID_LOW: u64 = 0xfe0; @@ -165,14 +165,13 @@ impl Gpio { } fn trigger_gpio_interrupt(&self) { - if let Some(intc) = &self.intc { - if let Err(e) = intc + if let Some(intc) = &self.intc + && let Err(e) = intc .lock() .unwrap() .set_irq(self.irq_line, Some(&self.interrupt_evt)) - { - warn!("Error signalling irq: {e:?}"); - } + { + warn!("Error signalling irq: {e:?}"); } } } diff --git a/src/devices/src/legacy/aarch64/serial.rs b/src/devices/src/legacy/aarch64/serial.rs index 5d75f12d7..da799ab62 100644 --- a/src/devices/src/legacy/aarch64/serial.rs +++ b/src/devices/src/legacy/aarch64/serial.rs @@ -15,9 +15,9 @@ use utils::byte_order::{read_le_u32, write_le_u32}; use utils::epoll::{EpollEvent, EventSet}; use utils::eventfd::EventFd; +use crate::Error as DeviceError; use crate::bus::BusDevice; use crate::legacy::{IrqChip, ReadableFd}; -use crate::Error as DeviceError; /* Registers */ const UARTDR: u64 = 0; @@ -402,17 +402,17 @@ impl Subscriber for Serial { return; } - if let Some(input) = self.input.as_mut() { - if input.as_raw_fd() == source { - let mut out = [0u8; 32]; - match input.read(&mut out[..]) { - Ok(count) => { - self.queue_input_bytes(&out[..count]) - .unwrap_or_else(|e| warn!("Serial error on input: {e:?}")); - } - Err(e) => { - warn!("error while reading stdin: {e:?}"); - } + if let Some(input) = self.input.as_mut() + && input.as_raw_fd() == source + { + let mut out = [0u8; 32]; + match input.read(&mut out[..]) { + Ok(count) => { + self.queue_input_bytes(&out[..count]) + .unwrap_or_else(|e| warn!("Serial error on input: {e:?}")); + } + Err(e) => { + warn!("error while reading stdin: {e:?}"); } } } diff --git a/src/devices/src/legacy/gicv3.rs b/src/devices/src/legacy/gicv3.rs index df5bffbd9..a8cd66201 100644 --- a/src/devices/src/legacy/gicv3.rs +++ b/src/devices/src/legacy/gicv3.rs @@ -2,11 +2,11 @@ use std::convert::TryInto; use std::io; use std::sync::Arc; +use crate::Error as DeviceError; use crate::bus::BusDevice; +use crate::legacy::VcpuList; use crate::legacy::gic::GICDevice; use crate::legacy::irqchip::IrqChipT; -use crate::legacy::VcpuList; -use crate::Error as DeviceError; use utils::eventfd::EventFd; diff --git a/src/devices/src/legacy/hvfgicv3.rs b/src/devices/src/legacy/hvfgicv3.rs index c831bba15..b15500f70 100644 --- a/src/devices/src/legacy/hvfgicv3.rs +++ b/src/devices/src/legacy/hvfgicv3.rs @@ -4,13 +4,13 @@ use std::io; use std::sync::LazyLock; +use crate::Error as DeviceError; use crate::bus::BusDevice; use crate::legacy::gic::GICDevice; use crate::legacy::irqchip::IrqChipT; -use crate::Error as DeviceError; -use hvf::bindings::{hv_gic_config_t, hv_ipa_t, hv_return_t, HV_SUCCESS}; use hvf::Error; +use hvf::bindings::{HV_SUCCESS, hv_gic_config_t, hv_ipa_t, hv_return_t}; use utils::eventfd::EventFd; // Device trees specific constants diff --git a/src/devices/src/legacy/i8042.rs b/src/devices/src/legacy/i8042.rs index 669dc1fec..735e59911 100644 --- a/src/devices/src/legacy/i8042.rs +++ b/src/devices/src/legacy/i8042.rs @@ -209,10 +209,10 @@ impl BusDevice for I8042Device { // Check if we still have data in the internal buffer. If so, we need to trigger // another interrupt, to let the guest know they need to issue another read from // port 0x60. - if (self.status & SB_OUT_DATA_AVAIL) != 0 { - if let Err(Error::KbdInterruptFailure(err)) = self.trigger_kbd_interrupt() { - warn!("Failed to trigger i8042 kbd interrupt {err:?}"); - } + if (self.status & SB_OUT_DATA_AVAIL) != 0 + && let Err(Error::KbdInterruptFailure(err)) = self.trigger_kbd_interrupt() + { + warn!("Failed to trigger i8042 kbd interrupt {err:?}"); } } _ => {} diff --git a/src/devices/src/legacy/ioapic.rs b/src/devices/src/legacy/ioapic.rs index af752c906..c57123cfb 100644 --- a/src/devices/src/legacy/ioapic.rs +++ b/src/devices/src/legacy/ioapic.rs @@ -1,9 +1,9 @@ use crossbeam_channel::unbounded; #[cfg(not(feature = "tdx"))] -use kvm_bindings::{kvm_enable_cap, KVM_CAP_SPLIT_IRQCHIP}; +use kvm_bindings::{KVM_CAP_SPLIT_IRQCHIP, kvm_enable_cap}; use kvm_bindings::{ - kvm_irq_routing_entry, kvm_irq_routing_entry__bindgen_ty_1, kvm_irq_routing_msi, KvmIrqRouting, - KVM_IRQ_ROUTING_MSI, + KVM_IRQ_ROUTING_MSI, KvmIrqRouting, kvm_irq_routing_entry, kvm_irq_routing_entry__bindgen_ty_1, + kvm_irq_routing_msi, }; use kvm_ioctls::{Error, VmFd}; @@ -11,9 +11,9 @@ use kvm_ioctls::{Error, VmFd}; use utils::eventfd::EventFd; use utils::worker_message::WorkerMessage; +use crate::Error as DeviceError; use crate::bus::BusDevice; use crate::legacy::irqchip::IrqChipT; -use crate::Error as DeviceError; const IOAPIC_BASE: u32 = 0xfec0_0000; const APIC_DEFAULT_ADDRESS: u32 = 0xfee0_0000; diff --git a/src/devices/src/legacy/irqchip.rs b/src/devices/src/legacy/irqchip.rs index ed33bd2a8..118f0d980 100644 --- a/src/devices/src/legacy/irqchip.rs +++ b/src/devices/src/legacy/irqchip.rs @@ -1,11 +1,11 @@ use std::sync::{Arc, Mutex}; +use crate::Error as DeviceError; use crate::bus::BusDevice; #[cfg(target_arch = "riscv64")] use crate::legacy::aia::AIADevice; #[cfg(target_arch = "aarch64")] use crate::legacy::gic::GICDevice; -use crate::Error as DeviceError; use utils::eventfd::EventFd; @@ -158,8 +158,8 @@ pub mod test_utils { } } - impl Into for DummyIrqChip { - fn into(self) -> IrqChip { + impl From for IrqChip { + fn from(_val: DummyIrqChip) -> Self { Arc::new(Mutex::new(IrqChipDevice::new( Box::new(DummyIrqChip::new()), ))) diff --git a/src/devices/src/legacy/kvmaia.rs b/src/devices/src/legacy/kvmaia.rs index 17763dfb9..8479455b6 100644 --- a/src/devices/src/legacy/kvmaia.rs +++ b/src/devices/src/legacy/kvmaia.rs @@ -3,10 +3,10 @@ use std::io; +use crate::Error as DeviceError; use crate::bus::BusDevice; use crate::legacy::aia::AIADevice; use crate::legacy::irqchip::IrqChipT; -use crate::Error as DeviceError; use kvm_ioctls::{DeviceFd, VmFd}; use utils::eventfd::EventFd; diff --git a/src/devices/src/legacy/kvmgicv2.rs b/src/devices/src/legacy/kvmgicv2.rs index fcf764f8e..c591365f9 100644 --- a/src/devices/src/legacy/kvmgicv2.rs +++ b/src/devices/src/legacy/kvmgicv2.rs @@ -3,10 +3,10 @@ use std::io; +use crate::Error as DeviceError; use crate::bus::BusDevice; use crate::legacy::gic::GICDevice; use crate::legacy::irqchip::IrqChipT; -use crate::Error as DeviceError; use kvm_ioctls::{DeviceFd, VmFd}; use utils::eventfd::EventFd; diff --git a/src/devices/src/legacy/kvmgicv3.rs b/src/devices/src/legacy/kvmgicv3.rs index a25bbb330..a6479ab34 100644 --- a/src/devices/src/legacy/kvmgicv3.rs +++ b/src/devices/src/legacy/kvmgicv3.rs @@ -3,10 +3,10 @@ use std::io; +use crate::Error as DeviceError; use crate::bus::BusDevice; use crate::legacy::gic::GICDevice; use crate::legacy::irqchip::IrqChipT; -use crate::Error as DeviceError; use kvm_ioctls::{DeviceFd, Error, VmFd}; use utils::eventfd::EventFd; diff --git a/src/devices/src/legacy/kvmioapic.rs b/src/devices/src/legacy/kvmioapic.rs index 57b63e7e9..71ae4789e 100644 --- a/src/devices/src/legacy/kvmioapic.rs +++ b/src/devices/src/legacy/kvmioapic.rs @@ -3,11 +3,11 @@ use std::io; +use crate::Error as DeviceError; use crate::bus::BusDevice; use crate::legacy::irqchip::IrqChipT; -use crate::Error as DeviceError; -use kvm_bindings::{kvm_pit_config, KVM_PIT_SPEAKER_DUMMY}; +use kvm_bindings::{KVM_PIT_SPEAKER_DUMMY, kvm_pit_config}; use kvm_ioctls::{Error, VmFd}; use utils::eventfd::EventFd; diff --git a/src/devices/src/legacy/rtc_pl031.rs b/src/devices/src/legacy/rtc_pl031.rs index 4960e596d..a5cd5118b 100644 --- a/src/devices/src/legacy/rtc_pl031.rs +++ b/src/devices/src/legacy/rtc_pl031.rs @@ -28,11 +28,11 @@ const RTCIMSC: u64 = 0x10; // Interrupt Mask Set or Clear Register. const RTCRIS: u64 = 0x14; // Raw Interrupt Status. const RTCMIS: u64 = 0x18; // Masked Interrupt Status. const RTCICR: u64 = 0x1c; // Interrupt Clear Register. - // From 0x020 to 0xFDC => reserved space. - // From 0xFE0 to 0x1000 => Peripheral and PrimeCell Identification Registers which are Read Only registers. - // AMBA standard devices have CIDs (Cell IDs) and PIDs (Peripheral IDs). The linux kernel will look for these in order to assert the identity - // of these devices (i.e look at the `amba_device_try_add` function). - // We are putting the expected values (look at 'Reset value' column from above mentioned document) in an array. +// From 0x020 to 0xFDC => reserved space. +// From 0xFE0 to 0x1000 => Peripheral and PrimeCell Identification Registers which are Read Only registers. +// AMBA standard devices have CIDs (Cell IDs) and PIDs (Peripheral IDs). The linux kernel will look for these in order to assert the identity +// of these devices (i.e look at the `amba_device_try_add` function). +// We are putting the expected values (look at 'Reset value' column from above mentioned document) in an array. const PL031_ID: [u8; 8] = [0x31, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1]; // We are only interested in the margins. const AMBA_ID_LOW: u64 = 0xFE0; diff --git a/src/devices/src/legacy/vcpu.rs b/src/devices/src/legacy/vcpu.rs index a6d5a3dbb..201c40cec 100644 --- a/src/devices/src/legacy/vcpu.rs +++ b/src/devices/src/legacy/vcpu.rs @@ -5,10 +5,10 @@ use std::sync::Mutex; use arch::aarch64::layout::VTIMER_IRQ; use arch::aarch64::sysreg::*; use hvf::bindings::{ - hv_sys_reg_t_HV_SYS_REG_CNTHCTL_EL2, hv_sys_reg_t_HV_SYS_REG_MDCCINT_EL1, hv_vcpu_get_sys_reg, - hv_vcpu_set_sys_reg, HV_SUCCESS, + HV_SUCCESS, hv_sys_reg_t_HV_SYS_REG_CNTHCTL_EL2, hv_sys_reg_t_HV_SYS_REG_MDCCINT_EL1, + hv_vcpu_get_sys_reg, hv_vcpu_set_sys_reg, }; -use hvf::{vcpu_request_exit, Vcpus}; +use hvf::{Vcpus, vcpu_request_exit}; // See https://developer.arm.com/documentation/ddi0595/2020-12/AArch64-Registers/ICC-IAR0-EL1--Interrupt-Controller-Interrupt-Acknowledge-Register-0 const GIC_INTID_SPURIOUS: u32 = 1023; @@ -172,11 +172,7 @@ impl Vcpus for VcpuList { &val as *const _ as *mut _, ) }; - if ret == HV_SUCCESS { - Some(val) - } else { - None - } + if ret == HV_SUCCESS { Some(val) } else { None } } SYSREG_MDCCINT_EL1 => { let val: u64 = 0; @@ -187,11 +183,7 @@ impl Vcpus for VcpuList { &val as *const _ as *mut _, ) }; - if ret == HV_SUCCESS { - Some(val) - } else { - None - } + if ret == HV_SUCCESS { Some(val) } else { None } } _ => None, } diff --git a/src/devices/src/legacy/x86_64/serial.rs b/src/devices/src/legacy/x86_64/serial.rs index 9ac6dccc2..2078277f4 100644 --- a/src/devices/src/legacy/x86_64/serial.rs +++ b/src/devices/src/legacy/x86_64/serial.rs @@ -272,17 +272,17 @@ impl Subscriber for Serial { return; } - if let Some(input) = self.input.as_mut() { - if input.as_raw_fd() == source { - let mut out = [0u8; 32]; - match input.read(&mut out[..]) { - Ok(count) => { - self.raw_input(&out[..count]) - .unwrap_or_else(|e| warn!("Serial error on input: {e}")); - } - Err(e) => { - warn!("error while reading stdin: {e:?}"); - } + if let Some(input) = self.input.as_mut() + && input.as_raw_fd() == source + { + let mut out = [0u8; 32]; + match input.read(&mut out[..]) { + Ok(count) => { + self.raw_input(&out[..count]) + .unwrap_or_else(|e| warn!("Serial error on input: {e}")); + } + Err(e) => { + warn!("error while reading stdin: {e:?}"); } } } @@ -399,7 +399,7 @@ mod tests { let mut serial = Serial::new_out(intr_evt, Box::new(serial_out.clone())); // Invalid write of multiple chars at once. - serial.write(0, u64::from(DATA), &[b'x', b'y']); + serial.write(0, u64::from(DATA), b"xy"); // Valid one char at a time writes. RAW_INPUT_BUF .iter() @@ -501,7 +501,7 @@ mod tests { // counter doesn't change (for 0 it blocks) assert!(intr_evt.write(1).is_ok()); serial.write(0, u64::from(IER), &[IER_THR_BIT]); - serial.write(0, u64::from(DATA), &[b'a']); + serial.write(0, u64::from(DATA), b"a"); assert_eq!(intr_evt.read().unwrap(), 2); let mut data = [0u8]; @@ -533,9 +533,9 @@ mod tests { let mut serial = Serial::new_sink(EventFd::new(utils::eventfd::EFD_NONBLOCK).unwrap()); serial.write(0, u64::from(MCR), &[MCR_LOOP_BIT]); - serial.write(0, u64::from(DATA), &[b'a']); - serial.write(0, u64::from(DATA), &[b'b']); - serial.write(0, u64::from(DATA), &[b'c']); + serial.write(0, u64::from(DATA), b"a"); + serial.write(0, u64::from(DATA), b"b"); + serial.write(0, u64::from(DATA), b"c"); let mut data = [0u8]; serial.read(0, u64::from(MSR), &mut data[..]); diff --git a/src/devices/src/virtio/bindings.rs b/src/devices/src/virtio/bindings.rs index f25a248f3..3f04e7fcf 100644 --- a/src/devices/src/virtio/bindings.rs +++ b/src/devices/src/virtio/bindings.rs @@ -60,7 +60,7 @@ pub unsafe fn pread64( count: libc::size_t, offset: off64_t, ) -> libc::ssize_t { - libc::pread64(fd, buf, count, offset) + unsafe { libc::pread64(fd, buf, count, offset) } } #[cfg(target_os = "macos")] pub unsafe fn pread64( @@ -69,7 +69,7 @@ pub unsafe fn pread64( count: libc::size_t, offset: off64_t, ) -> libc::ssize_t { - libc::pread(fd, buf, count, offset) + unsafe { libc::pread(fd, buf, count, offset) } } #[cfg(target_os = "linux")] @@ -79,7 +79,7 @@ pub unsafe fn preadv64( iovcnt: libc::c_int, offset: off64_t, ) -> libc::ssize_t { - libc::preadv64(fd, iov, iovcnt, offset) + unsafe { libc::preadv64(fd, iov, iovcnt, offset) } } #[cfg(target_os = "macos")] pub unsafe fn preadv64( @@ -88,7 +88,7 @@ pub unsafe fn preadv64( iovcnt: libc::c_int, offset: off64_t, ) -> libc::ssize_t { - libc::preadv(fd, iov, iovcnt, offset) + unsafe { libc::preadv(fd, iov, iovcnt, offset) } } #[cfg(target_os = "linux")] @@ -98,7 +98,7 @@ pub unsafe fn pwrite64( count: libc::size_t, offset: off64_t, ) -> libc::ssize_t { - libc::pwrite64(fd, buf, count, offset) + unsafe { libc::pwrite64(fd, buf, count, offset) } } #[cfg(target_os = "macos")] pub unsafe fn pwrite64( @@ -107,7 +107,7 @@ pub unsafe fn pwrite64( count: libc::size_t, offset: off64_t, ) -> libc::ssize_t { - libc::pwrite(fd, buf, count, offset) + unsafe { libc::pwrite(fd, buf, count, offset) } } #[cfg(target_os = "linux")] @@ -117,7 +117,7 @@ pub unsafe fn pwritev64( iovcnt: libc::c_int, offset: off64_t, ) -> libc::ssize_t { - libc::pwritev64(fd, iov, iovcnt, offset) + unsafe { libc::pwritev64(fd, iov, iovcnt, offset) } } #[cfg(target_os = "macos")] pub unsafe fn pwritev64( @@ -126,7 +126,7 @@ pub unsafe fn pwritev64( iovcnt: libc::c_int, offset: off64_t, ) -> libc::ssize_t { - libc::pwritev(fd, iov, iovcnt, offset) + unsafe { libc::pwritev(fd, iov, iovcnt, offset) } } #[cfg(target_os = "linux")] @@ -136,7 +136,7 @@ pub unsafe fn fstatat64( buf: *mut stat64, flags: libc::c_int, ) -> libc::c_int { - libc::fstatat64(dirfd, pathname, buf, flags) + unsafe { libc::fstatat64(dirfd, pathname, buf, flags) } } #[cfg(target_os = "macos")] pub unsafe fn fstatat64( @@ -145,7 +145,7 @@ pub unsafe fn fstatat64( buf: *mut stat64, flags: libc::c_int, ) -> libc::c_int { - libc::fstatat(dirfd, pathname, buf, flags) + unsafe { libc::fstatat(dirfd, pathname, buf, flags) } } #[cfg(target_os = "linux")] @@ -155,7 +155,7 @@ pub unsafe fn fallocate64( offset: off64_t, len: off64_t, ) -> libc::c_int { - libc::fallocate64(fd, mode, offset, len) + unsafe { libc::fallocate64(fd, mode, offset, len) } } #[cfg(target_os = "macos")] pub unsafe fn fallocate64( @@ -169,34 +169,34 @@ pub unsafe fn fallocate64( #[cfg(target_os = "linux")] pub unsafe fn ftruncate64(fd: libc::c_int, length: off64_t) -> libc::c_int { - libc::ftruncate64(fd, length) + unsafe { libc::ftruncate64(fd, length) } } #[cfg(target_os = "macos")] pub unsafe fn ftruncate64(fd: libc::c_int, length: off64_t) -> libc::c_int { - libc::ftruncate(fd, length) + unsafe { libc::ftruncate(fd, length) } } #[cfg(target_os = "linux")] pub unsafe fn lseek64(fd: libc::c_int, offset: off64_t, whence: libc::c_int) -> off64_t { - libc::lseek64(fd, offset, whence) + unsafe { libc::lseek64(fd, offset, whence) } } #[cfg(target_os = "macos")] pub unsafe fn lseek64(fd: libc::c_int, offset: off64_t, whence: libc::c_int) -> off64_t { - libc::lseek(fd, offset, whence) + unsafe { libc::lseek(fd, offset, whence) } } #[cfg(target_os = "macos")] pub unsafe fn statvfs64(path: *const libc::c_char, buf: *mut statvfs64) -> libc::c_int { - libc::statvfs(path, buf) + unsafe { libc::statvfs(path, buf) } } #[cfg(target_os = "linux")] pub unsafe fn fstatvfs64(fd: libc::c_int, buf: *mut statvfs64) -> libc::c_int { - libc::fstatvfs64(fd, buf) + unsafe { libc::fstatvfs64(fd, buf) } } #[cfg(target_os = "macos")] pub unsafe fn fstatvfs64(fd: libc::c_int, buf: *mut statvfs64) -> libc::c_int { - libc::fstatvfs(fd, buf) + unsafe { libc::fstatvfs(fd, buf) } } #[cfg(target_os = "linux")] @@ -206,7 +206,7 @@ pub unsafe fn mknodat( mode: libc::mode_t, dev: libc::dev_t, ) -> libc::c_int { - libc::mknodat(dirfd, pathname, mode, dev) + unsafe { libc::mknodat(dirfd, pathname, mode, dev) } } #[cfg(target_os = "macos")] pub unsafe fn mknodat( diff --git a/src/devices/src/virtio/block/device.rs b/src/devices/src/virtio/block/device.rs index c943b10e0..46f6b7a15 100644 --- a/src/devices/src/virtio/block/device.rs +++ b/src/devices/src/virtio/block/device.rs @@ -19,11 +19,11 @@ use std::sync::{Arc, Mutex}; use std::thread::JoinHandle; use imago::{ - file::File as ImagoFile, qcow2::Qcow2, raw::Raw, vmdk::Vmdk, DynStorage, FormatDriverBuilder, - PermissiveImplicitOpenGate, Storage, StorageOpenOptions, SyncFormatAccess, + DynStorage, FormatDriverBuilder, PermissiveImplicitOpenGate, Storage, StorageOpenOptions, + SyncFormatAccess, file::File as ImagoFile, qcow2::Qcow2, raw::Raw, vmdk::Vmdk, }; use log::{error, warn}; -use utils::eventfd::{EventFd, EFD_NONBLOCK}; +use utils::eventfd::{EFD_NONBLOCK, EventFd}; use virtio_bindings::{ virtio_blk::*, virtio_config::VIRTIO_F_VERSION_1, virtio_ring::VIRTIO_RING_F_EVENT_IDX, }; @@ -31,13 +31,13 @@ use vm_memory::{ByteValued, GuestMemoryMmap}; use super::worker::BlockWorker; use super::{ - super::{ActivateResult, DeviceQueue, DeviceState, QueueConfig, VirtioDevice, TYPE_BLOCK}, + super::{ActivateResult, DeviceQueue, DeviceState, QueueConfig, TYPE_BLOCK, VirtioDevice}, Error, NUM_QUEUES, QUEUE_CONFIG, SECTOR_SHIFT, SECTOR_SIZE, }; use crate::virtio::{ - block::{ImageType, SyncMode}, ActivateError, InterruptTransport, + block::{ImageType, SyncMode}, }; /// Configuration options for disk caching. diff --git a/src/devices/src/virtio/block/worker.rs b/src/devices/src/virtio/block/worker.rs index 943662fee..7aabe052a 100644 --- a/src/devices/src/virtio/block/worker.rs +++ b/src/devices/src/virtio/block/worker.rs @@ -203,10 +203,10 @@ impl BlockWorker { error!("failed to add used elements to the queue: {e:?}"); } - if self.device_queue.queue.needs_notification(mem).unwrap() { - if let Err(e) = self.interrupt.try_signal_used_queue() { - error!("error signalling queue: {e:?}"); - } + if self.device_queue.queue.needs_notification(mem).unwrap() + && let Err(e) = self.interrupt.try_signal_used_queue() + { + error!("error signalling queue: {e:?}"); } } } diff --git a/src/devices/src/virtio/console/console_control.rs b/src/devices/src/virtio/console/console_control.rs index 1716a0313..2fbd44bed 100644 --- a/src/devices/src/virtio/console/console_control.rs +++ b/src/devices/src/virtio/console/console_control.rs @@ -2,8 +2,8 @@ use std::collections::VecDeque; use std::ops::Deref; use std::sync::{Arc, Mutex}; -use utils::eventfd::EventFd; use utils::eventfd::EFD_NONBLOCK; +use utils::eventfd::EventFd; use vm_memory::{ByteValued, GuestMemoryMmap}; use crate::virtio::console::defs::control_event::{ diff --git a/src/devices/src/virtio/console/device.rs b/src/devices/src/virtio/console/device.rs index b1022a38e..3bfb02f15 100644 --- a/src/devices/src/virtio/console/device.rs +++ b/src/devices/src/virtio/console/device.rs @@ -18,7 +18,7 @@ use crate::virtio::console::console_control::{ use crate::virtio::console::defs::QUEUE_SIZE; use crate::virtio::console::port::Port; use crate::virtio::console::port_queue_mapping::{ - num_queues, port_id_to_queue_idx, QueueDirection, + QueueDirection, num_queues, port_id_to_queue_idx, }; use crate::virtio::{InterruptTransport, PortDescription, VmmExitObserver}; @@ -178,10 +178,10 @@ impl Console { Ok(cmd) => cmd, Err(e) => { log::error!( - "Failed to read VirtioConsoleControl struct: {e:?}, struct len = {len}, head.len = {head_len}", - len = size_of::(), - head_len = head.len, - ); + "Failed to read VirtioConsoleControl struct: {e:?}, struct len = {len}, head.len = {head_len}", + len = size_of::(), + head_len = head.len, + ); continue; } }; diff --git a/src/devices/src/virtio/console/event_handler.rs b/src/devices/src/virtio/console/event_handler.rs index 1dd9712b9..be5600c3c 100644 --- a/src/devices/src/virtio/console/event_handler.rs +++ b/src/devices/src/virtio/console/event_handler.rs @@ -5,7 +5,7 @@ use utils::epoll::{EpollEvent, EventSet}; use super::device::Console; use crate::virtio::console::device::{CONTROL_RXQ_INDEX, CONTROL_TXQ_INDEX}; -use crate::virtio::console::port_queue_mapping::{queue_idx_to_port_id, QueueDirection}; +use crate::virtio::console::port_queue_mapping::{QueueDirection, queue_idx_to_port_id}; use crate::virtio::device::VirtioDevice; impl Console { diff --git a/src/devices/src/virtio/console/port_io.rs b/src/devices/src/virtio/console/port_io.rs index be515ab81..6d89a2c08 100644 --- a/src/devices/src/virtio/console/port_io.rs +++ b/src/devices/src/virtio/console/port_io.rs @@ -1,16 +1,16 @@ use libc::{ - fcntl, F_GETFL, F_SETFL, O_NONBLOCK, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO, TIOCGWINSZ, + F_GETFL, F_SETFL, O_NONBLOCK, STDERR_FILENO, STDIN_FILENO, STDOUT_FILENO, TIOCGWINSZ, fcntl, }; use log::Level; use nix::errno::Errno; use nix::ioctl_read_bad; -use nix::poll::{poll, PollFd, PollFlags, PollTimeout}; +use nix::poll::{PollFd, PollFlags, PollTimeout, poll}; use nix::unistd::{dup, isatty}; use std::fs::File; use std::io::{self, ErrorKind}; use std::os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd}; -use utils::eventfd::EventFd; use utils::eventfd::EFD_NONBLOCK; +use utils::eventfd::EventFd; use vm_memory::bitmap::Bitmap; use vm_memory::{VolatileMemoryError, VolatileSlice, WriteVolatile}; diff --git a/src/devices/src/virtio/descriptor_utils.rs b/src/devices/src/virtio/descriptor_utils.rs index 1a40642f9..e19c4a5ba 100644 --- a/src/devices/src/virtio/descriptor_utils.rs +++ b/src/devices/src/virtio/descriptor_utils.rs @@ -6,7 +6,7 @@ use std::cmp; use std::collections::VecDeque; use std::fmt::{self, Display}; use std::io::{self, Read, Write}; -use std::mem::{size_of, MaybeUninit}; +use std::mem::{MaybeUninit, size_of}; use std::ops::Deref; use std::ptr::copy_nonoverlapping; use std::result; @@ -276,7 +276,7 @@ impl<'a> Reader<'a> { return Err(io::Error::new( io::ErrorKind::UnexpectedEof, "failed to fill whole buffer", - )) + )); } Ok(n) => count -= n, Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} @@ -423,7 +423,7 @@ impl<'a> Writer<'a> { return Err(io::Error::new( io::ErrorKind::WriteZero, "failed to write whole buffer", - )) + )); } Ok(n) => count -= n, Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} @@ -565,7 +565,7 @@ mod tests { assert_eq!(reader.bytes_read(), 0); let mut buffer = [0_u8; 64]; - if let Err(_) = reader.read_exact(&mut buffer) { + if reader.read_exact(&mut buffer).is_err() { panic!("read_exact should not fail here"); } @@ -605,15 +605,15 @@ mod tests { assert_eq!(writer.available_bytes(), 106); assert_eq!(writer.bytes_written(), 0); - let mut buffer = [0_u8; 64]; - if let Err(_) = writer.write_all(&mut buffer) { + let buffer = [0_u8; 64]; + if writer.write_all(&buffer).is_err() { panic!("write_all should not fail here"); } assert_eq!(writer.available_bytes(), 42); assert_eq!(writer.bytes_written(), 64); - match writer.write(&mut buffer) { + match writer.write(&buffer) { Err(_) => panic!("write should not fail here"), Ok(length) => assert_eq!(length, 42), } @@ -739,7 +739,7 @@ mod tests { ) .expect("create_descriptor_chain failed"); let mut writer = Writer::new(&memory, chain_writer).expect("failed to create Writer"); - if let Err(_) = writer.write_obj(secret) { + if writer.write_obj(secret).is_err() { panic!("write_obj should not fail here"); } @@ -777,8 +777,7 @@ mod tests { let mut reader = Reader::new(&memory, chain).expect("failed to create Reader"); - let mut buf = Vec::with_capacity(1024); - buf.resize(1024, 0); + let mut buf = vec![0; 1024]; assert_eq!( reader @@ -929,7 +928,7 @@ mod tests { .expect("create_descriptor_chain failed"); let mut reader = Reader::new(&memory, chain).expect("failed to create Reader"); - if let Ok(_) = reader.split_at(256) { + if reader.split_at(256).is_ok() { panic!("successfully split Reader with out of bounds offset"); } } diff --git a/src/devices/src/virtio/device.rs b/src/devices/src/virtio/device.rs index bb2c669d6..20c170e02 100644 --- a/src/devices/src/virtio/device.rs +++ b/src/devices/src/virtio/device.rs @@ -53,7 +53,7 @@ impl DeviceState { Self::Inactive => { warn!("DeviceState::signal_used_queue() called, but device is not activated") } - Self::Activated(_, ref interrupt) => interrupt.signal_used_queue(), + Self::Activated(_, interrupt) => interrupt.signal_used_queue(), } } } diff --git a/src/devices/src/virtio/fs/device.rs b/src/devices/src/virtio/fs/device.rs index bc877bc24..bb1d39ec7 100644 --- a/src/devices/src/virtio/fs/device.rs +++ b/src/devices/src/virtio/fs/device.rs @@ -2,11 +2,11 @@ use crossbeam_channel::Sender; use std::cmp; use std::io::Write; -use std::sync::atomic::{AtomicI32, AtomicU64, Ordering}; use std::sync::Arc; +use std::sync::atomic::{AtomicI32, AtomicU64, Ordering}; use std::thread::JoinHandle; -use utils::eventfd::{EventFd, EFD_NONBLOCK}; +use utils::eventfd::{EFD_NONBLOCK, EventFd}; #[cfg(target_os = "macos")] use utils::worker_message::WorkerMessage; use virtio_bindings::{virtio_config::VIRTIO_F_VERSION_1, virtio_ring::VIRTIO_RING_F_EVENT_IDX}; @@ -16,9 +16,9 @@ use super::super::{ ActivateError, ActivateResult, DeviceQueue, DeviceState, FsError, QueueConfig, VirtioDevice, VirtioShmRegion, }; +use super::ExportTable; use super::passthrough; use super::worker::FsWorker; -use super::ExportTable; use super::{defs, defs::uapi}; use crate::virtio::InterruptTransport; diff --git a/src/devices/src/virtio/fs/filesystem.rs b/src/devices/src/virtio/fs/filesystem.rs index ef286e312..27fa65661 100644 --- a/src/devices/src/virtio/fs/filesystem.rs +++ b/src/devices/src/virtio/fs/filesystem.rs @@ -163,7 +163,7 @@ pub trait ZeroCopyReader { return Err(io::Error::new( io::ErrorKind::WriteZero, "failed to fill whole buffer", - )) + )); } Ok(n) => { count -= n; @@ -253,7 +253,7 @@ pub trait ZeroCopyWriter { return Err(io::Error::new( io::ErrorKind::UnexpectedEof, "failed to write whole buffer", - )) + )); } Ok(n) => { // No need for checked math here because we verified that `off + count` will not diff --git a/src/devices/src/virtio/fs/linux/passthrough.rs b/src/devices/src/virtio/fs/linux/passthrough.rs index e5ca21a03..b1f579d16 100644 --- a/src/devices/src/virtio/fs/linux/passthrough.rs +++ b/src/devices/src/virtio/fs/linux/passthrough.rs @@ -2,20 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -use std::collections::btree_map; use std::collections::BTreeMap; +use std::collections::btree_map; use std::convert::TryInto; use std::ffi::{CStr, CString}; use std::fs::File; use std::io; -use std::mem::{self, size_of, MaybeUninit}; +use std::mem::{self, MaybeUninit, size_of}; use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; use std::str::FromStr; use std::sync::atomic::{AtomicBool, AtomicI32, AtomicU64, Ordering}; use std::sync::{Arc, RwLock}; use std::time::Duration; -use caps::{has_cap, CapSet, Capability}; +use caps::{CapSet, Capability, has_cap}; use nix::{request_code_none, request_code_read}; use vm_memory::ByteValued; @@ -71,7 +71,7 @@ struct LinuxDirent64 { unsafe impl ByteValued for LinuxDirent64 {} macro_rules! scoped_cred { - ($name:ident, $ty:ty, $syscall_nr:expr) => { + ($name:ident, $ty:ty, $syscall_nr:expr_2021) => { #[derive(Debug)] struct $name; @@ -776,23 +776,23 @@ impl PassthroughFs { fn do_release(&self, inode: Inode, handle: Handle) -> io::Result<()> { let mut handles = self.handles.write().unwrap(); - if let btree_map::Entry::Occupied(e) = handles.entry(handle) { - if e.get().inode == inode { - if e.get().exported.load(Ordering::Relaxed) { - self.cfg - .export_table - .as_ref() - .unwrap() - .lock() - .unwrap() - .remove(&(self.cfg.export_fsid, handle)); - } - - // We don't need to close the file here because that will happen automatically when - // the last `Arc` is dropped. - e.remove(); - return Ok(()); + if let btree_map::Entry::Occupied(e) = handles.entry(handle) + && e.get().inode == inode + { + if e.get().exported.load(Ordering::Relaxed) { + self.cfg + .export_table + .as_ref() + .unwrap() + .lock() + .unwrap() + .remove(&(self.cfg.export_fsid, handle)); } + + // We don't need to close the file here because that will happen automatically when + // the last `Arc` is dropped. + e.remove(); + return Ok(()); } Err(ebadf()) diff --git a/src/devices/src/virtio/fs/macos/passthrough.rs b/src/devices/src/virtio/fs/macos/passthrough.rs index 53680bd92..98828d580 100644 --- a/src/devices/src/virtio/fs/macos/passthrough.rs +++ b/src/devices/src/virtio/fs/macos/passthrough.rs @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -use std::collections::btree_map; use std::collections::BTreeMap; use std::collections::HashMap; +use std::collections::btree_map; use std::ffi::{CStr, CString}; use std::fs::File; use std::io; @@ -16,13 +16,13 @@ use std::sync::atomic::{AtomicBool, AtomicI32, AtomicI64, AtomicU64, Ordering}; use std::sync::{Arc, Mutex, RwLock}; use std::time::Duration; -use crossbeam_channel::{unbounded, Sender}; +use crossbeam_channel::{Sender, unbounded}; use nix::errno::Errno; use utils::worker_message::WorkerMessage; use crate::virtio::fs::filesystem::SecContext; -use super::super::super::linux_errno::{linux_error, LINUX_ERANGE}; +use super::super::super::linux_errno::{LINUX_ERANGE, linux_error}; use super::super::bindings; use super::super::filesystem::{ Context, DirEntry, Entry, ExportTable, Extensions, FileSystem, FsOptions, GetxattrReply, @@ -256,10 +256,11 @@ fn get_xattr_lstat( } fn is_valid_owner(owner: Option<(u32, u32)>) -> bool { - if let Some(owner) = owner { - if owner.0 < UID_MAX && owner.1 < UID_MAX { - return true; - } + if let Some(owner) = owner + && owner.0 < UID_MAX + && owner.1 < UID_MAX + { + return true; } false @@ -286,7 +287,7 @@ fn set_xattr_stat( } else { let (orig_uid, orig_gid, orig_mode) = match file { InodeHandle::Fd(fd) => get_xattr_fstat(*fd, st)?, - InodeHandle::Path(ref c_path) => get_xattr_lstat(c_path, st)?, + InodeHandle::Path(c_path) => get_xattr_lstat(c_path, st)?, }; let (uid, gid) = match owner { @@ -418,7 +419,7 @@ fn lstat(c_path: &CString, host: bool) -> io::Result { fn istat(ihandle: &InodeHandle, host: bool) -> io::Result { match ihandle { InodeHandle::Fd(fd) => fstat(*fd, host), - InodeHandle::Path(ref c_path) => lstat(c_path, host), + InodeHandle::Path(c_path) => lstat(c_path, host), } } @@ -835,10 +836,10 @@ impl PassthroughFs { if let Ok(st) = fstat(fd, false) { let new_mode = clear_suid_sgid(st.st_mode as u32); - if new_mode != st.st_mode as u32 { - if let Err(err) = set_xattr_stat(&ihandle, Some(st), None, Some(new_mode)) { - error!("Couldn't clear suid/sgid for inode {inode}: {err}"); - } + if new_mode != st.st_mode as u32 + && let Err(err) = set_xattr_stat(&ihandle, Some(st), None, Some(new_mode)) + { + error!("Couldn't clear suid/sgid for inode {inode}: {err}"); } } } @@ -872,13 +873,13 @@ impl PassthroughFs { fn do_release(&self, inode: Inode, handle: Handle) -> io::Result<()> { let mut handles = self.handles.write().unwrap(); - if let btree_map::Entry::Occupied(e) = handles.entry(handle) { - if e.get().inode == inode { - // We don't need to close the file here because that will happen automatically when - // the last `Arc` is dropped. - e.remove(); - return Ok(()); - } + if let btree_map::Entry::Occupied(e) = handles.entry(handle) + && e.get().inode == inode + { + // We don't need to close the file here because that will happen automatically when + // the last `Arc` is dropped. + e.remove(); + return Ok(()); } Err(ebadf()) @@ -961,11 +962,11 @@ impl PassthroughFs { } if res == 0 { - if let Some(unlinked_fd) = unlinked_fd { - if let Err(err) = self.store_unlinked_fd(unlinked_fd) { - unsafe { libc::close(unlinked_fd) }; - warn!("Couldn't store unlinked fd \"{}\": {err}", unlinked_fd); - } + if let Some(unlinked_fd) = unlinked_fd + && let Err(err) = self.store_unlinked_fd(unlinked_fd) + { + unsafe { libc::close(unlinked_fd) }; + warn!("Couldn't store unlinked fd \"{}\": {err}", unlinked_fd); } Ok(()) } else { @@ -1665,7 +1666,7 @@ impl FileSystem for PassthroughFs { // Safe because this doesn't modify any memory and we check the return value. let res = match ihandle { InodeHandle::Fd(fd) => unsafe { libc::futimens(fd, tvs.as_ptr()) }, - InodeHandle::Path(ref c_path) => unsafe { + InodeHandle::Path(c_path) => unsafe { let fd = libc::open(c_path.as_ptr(), libc::O_SYMLINK | libc::O_CLOEXEC); let res = libc::futimens(fd, tvs.as_ptr()); libc::close(fd); diff --git a/src/devices/src/virtio/fs/multikey.rs b/src/devices/src/virtio/fs/multikey.rs index 8dc35a447..e6d0bdaf0 100644 --- a/src/devices/src/virtio/fs/multikey.rs +++ b/src/devices/src/virtio/fs/multikey.rs @@ -75,10 +75,9 @@ where /// associated with the main key is updated, the value associated with the alternate key is /// removed, and the old value associated with the main key is returned. pub fn insert(&mut self, k1: K1, k2: K2, v: V) -> Option { - let oldval = if let Some(oldkey) = self.alt.insert(k2.clone(), k1.clone()) { - self.main.remove(&oldkey) - } else { - None + let oldval = match self.alt.insert(k2.clone(), k1.clone()) { + Some(oldkey) => self.main.remove(&oldkey), + _ => None, }; self.main .insert(k1, (k2.clone(), v)) diff --git a/src/devices/src/virtio/fs/read_only.rs b/src/devices/src/virtio/fs/read_only.rs index e975f2dda..88cc7e126 100644 --- a/src/devices/src/virtio/fs/read_only.rs +++ b/src/devices/src/virtio/fs/read_only.rs @@ -13,8 +13,8 @@ use crossbeam_channel::Sender; use std::ffi::CStr; use std::io; -use std::sync::atomic::AtomicI32; use std::sync::Arc; +use std::sync::atomic::AtomicI32; use std::time::Duration; #[cfg(target_os = "macos")] diff --git a/src/devices/src/virtio/fs/server.rs b/src/devices/src/virtio/fs/server.rs index a6b436a35..9cf15a8fa 100644 --- a/src/devices/src/virtio/fs/server.rs +++ b/src/devices/src/virtio/fs/server.rs @@ -12,8 +12,8 @@ use std::ffi::{CStr, CString}; use std::fs::File; use std::io::{self, Read, Write}; use std::mem::size_of; -use std::sync::atomic::{AtomicI32, AtomicU64, Ordering}; use std::sync::Arc; +use std::sync::atomic::{AtomicI32, AtomicU64, Ordering}; use vm_memory::ByteValued; diff --git a/src/devices/src/virtio/fs/worker.rs b/src/devices/src/virtio/fs/worker.rs index c612b3e9b..2022e8b9e 100644 --- a/src/devices/src/virtio/fs/worker.rs +++ b/src/devices/src/virtio/fs/worker.rs @@ -5,8 +5,8 @@ use utils::worker_message::WorkerMessage; use std::io; use std::os::fd::AsRawFd; -use std::sync::atomic::AtomicI32; use std::sync::Arc; +use std::sync::atomic::AtomicI32; use std::thread; use utils::epoll::{ControlOperation, Epoll, EpollEvent, EventSet}; diff --git a/src/devices/src/virtio/gpu/device.rs b/src/devices/src/virtio/gpu/device.rs index 04f619c27..548312184 100644 --- a/src/devices/src/virtio/gpu/device.rs +++ b/src/devices/src/virtio/gpu/device.rs @@ -5,15 +5,15 @@ use crossbeam_channel::Sender; use vm_memory::{ByteValued, GuestMemoryMmap}; use super::super::{ - fs::ExportTable, ActivateError, ActivateResult, DeviceQueue, DeviceState, QueueConfig, - VirtioDevice, VirtioShmRegion, + ActivateError, ActivateResult, DeviceQueue, DeviceState, QueueConfig, VirtioDevice, + VirtioShmRegion, fs::ExportTable, }; use super::defs; use super::defs::uapi; use super::defs::uapi::virtio_gpu_config; use super::worker::Worker; -use crate::virtio::display::DisplayInfo; use crate::virtio::InterruptTransport; +use crate::virtio::display::DisplayInfo; use krun_display::DisplayBackend; #[cfg(target_os = "macos")] use utils::worker_message::WorkerMessage; diff --git a/src/devices/src/virtio/gpu/virtio_gpu.rs b/src/devices/src/virtio/gpu/virtio_gpu.rs index 43b4ef7ec..67edb5f26 100644 --- a/src/devices/src/virtio/gpu/virtio_gpu.rs +++ b/src/devices/src/virtio/gpu/virtio_gpu.rs @@ -9,11 +9,11 @@ use std::sync::{Arc, Mutex}; use super::super::Queue as VirtQueue; use super::protocol::GpuResponse::*; use super::protocol::{ - GpuResponse, GpuResponsePlaneInfo, VirtioGpuResult, VIRTIO_GPU_BLOB_FLAG_CREATE_GUEST_HANDLE, - VIRTIO_GPU_BLOB_MEM_HOST3D, VIRTIO_GPU_MAX_SCANOUTS, + GpuResponse, GpuResponsePlaneInfo, VIRTIO_GPU_BLOB_FLAG_CREATE_GUEST_HANDLE, + VIRTIO_GPU_BLOB_MEM_HOST3D, VIRTIO_GPU_MAX_SCANOUTS, VirtioGpuResult, }; #[cfg(target_os = "macos")] -use crossbeam_channel::{unbounded, Sender}; +use crossbeam_channel::{Sender, unbounded}; use krun_display::{ DisplayBackend, DisplayBackendBasicFramebuffer, DisplayBackendInstance, Rect, ResourceFormat, }; @@ -26,16 +26,16 @@ use rutabaga_gfx::RUTABAGA_MEM_HANDLE_TYPE_DMABUF; use rutabaga_gfx::RUTABAGA_MEM_HANDLE_TYPE_OPAQUE_FD; #[cfg(all(feature = "virgl_resource_map2", target_os = "linux"))] use rutabaga_gfx::RUTABAGA_MEM_HANDLE_TYPE_SHM; -use rutabaga_gfx::{ - ResourceCreate3D, ResourceCreateBlob, Rutabaga, RutabagaBuilder, RutabagaChannel, - RutabagaFence, RutabagaFenceHandler, RutabagaIovec, Transfer3D, RUTABAGA_CHANNEL_TYPE_WAYLAND, - RUTABAGA_MAP_CACHE_MASK, -}; #[cfg(target_os = "linux")] use rutabaga_gfx::{ RUTABAGA_CHANNEL_TYPE_PW, RUTABAGA_CHANNEL_TYPE_X11, RUTABAGA_MAP_ACCESS_MASK, RUTABAGA_MAP_ACCESS_READ, RUTABAGA_MAP_ACCESS_RW, RUTABAGA_MAP_ACCESS_WRITE, }; +use rutabaga_gfx::{ + RUTABAGA_CHANNEL_TYPE_WAYLAND, RUTABAGA_MAP_CACHE_MASK, ResourceCreate3D, ResourceCreateBlob, + Rutabaga, RutabagaBuilder, RutabagaChannel, RutabagaFence, RutabagaFenceHandler, RutabagaIovec, + Transfer3D, +}; #[cfg(target_os = "macos")] use utils::worker_message::WorkerMessage; use vm_memory::{GuestAddress, GuestMemory, GuestMemoryMmap, VolatileSlice}; @@ -240,14 +240,14 @@ impl VirtioGpu { }]; #[cfg(target_os = "linux")] - if let Ok(x_display) = env::var("DISPLAY") { - if let Some(x_display) = x_display.strip_prefix(":") { - let x_path = PathBuf::from(format!("/tmp/.X11-unix/X{x_display}")); - rutabaga_channels.push(RutabagaChannel { - base_channel: x_path, - channel_type: RUTABAGA_CHANNEL_TYPE_X11, - }); - } + if let Ok(x_display) = env::var("DISPLAY") + && let Some(x_display) = x_display.strip_prefix(":") + { + let x_path = PathBuf::from(format!("/tmp/.X11-unix/X{x_display}")); + rutabaga_channels.push(RutabagaChannel { + base_channel: x_path, + channel_type: RUTABAGA_CHANNEL_TYPE_X11, + }); } #[cfg(target_os = "linux")] if let Ok(pw_sock_dir) = env::var("PIPEWIRE_RUNTIME_DIR") @@ -322,7 +322,9 @@ impl VirtioGpu { ) { Some(rutabaga) => rutabaga, None => { - warn!("Failed to create virtio_gpu backend with the requested parameters. Falling back to safe defaults."); + warn!( + "Failed to create virtio_gpu backend with the requested parameters. Falling back to safe defaults." + ); Self::create_fallback_rutabaga( mem.clone(), queue_ctl.clone(), diff --git a/src/devices/src/virtio/gpu/worker.rs b/src/devices/src/virtio/gpu/worker.rs index e00186c46..843d45a46 100644 --- a/src/devices/src/virtio/gpu/worker.rs +++ b/src/devices/src/virtio/gpu/worker.rs @@ -3,14 +3,14 @@ use std::os::fd::{AsRawFd, BorrowedFd}; use std::sync::{Arc, Mutex}; use std::thread; -use nix::fcntl::{fcntl, FcntlArg, OFlag}; +use nix::fcntl::{FcntlArg, OFlag, fcntl}; use utils::eventfd::EventFd; #[cfg(target_os = "macos")] use crossbeam_channel::Sender; use rutabaga_gfx::{ - ResourceCreate3D, ResourceCreateBlob, RutabagaFence, Transfer3D, - RUTABAGA_PIPE_BIND_RENDER_TARGET, RUTABAGA_PIPE_TEXTURE_2D, + RUTABAGA_PIPE_BIND_RENDER_TARGET, RUTABAGA_PIPE_TEXTURE_2D, ResourceCreate3D, + ResourceCreateBlob, RutabagaFence, Transfer3D, }; #[cfg(target_os = "macos")] use utils::worker_message::WorkerMessage; @@ -19,7 +19,7 @@ use vm_memory::{GuestAddress, GuestMemoryMmap}; use super::super::descriptor_utils::{Reader, Writer}; use super::super::{DeviceQueue, GpuError, Queue as VirtQueue}; use super::protocol::{ - virtio_gpu_ctrl_hdr, virtio_gpu_mem_entry, GpuCommand, GpuResponse, VirtioGpuResult, + GpuCommand, GpuResponse, VirtioGpuResult, virtio_gpu_ctrl_hdr, virtio_gpu_mem_entry, }; use super::virtio_gpu::VirtioGpu; use crate::virtio::display::DisplayInfo; @@ -105,10 +105,10 @@ impl Worker { error!("Failed to read control_evt: {e:?}"); continue; } - if self.process_queue(&mut virtio_gpu, &self.control_queue.clone()) { - if let Err(e) = self.interrupt.try_signal_used_queue() { - error!("Error signaling queue: {e:?}"); - } + if self.process_queue(&mut virtio_gpu, &self.control_queue.clone()) + && let Err(e) = self.interrupt.try_signal_used_queue() + { + error!("Error signaling queue: {e:?}"); } } } diff --git a/src/devices/src/virtio/input/device.rs b/src/devices/src/virtio/input/device.rs index c62a1c6e8..8bb544c68 100644 --- a/src/devices/src/virtio/input/device.rs +++ b/src/devices/src/virtio/input/device.rs @@ -3,18 +3,18 @@ use std::io::Write; use std::thread::JoinHandle; use log::{debug, error}; -use utils::eventfd::{EventFd, EFD_NONBLOCK}; +use utils::eventfd::{EFD_NONBLOCK, EventFd}; use vm_memory::GuestMemoryMmap; use super::super::{ ActivateError, ActivateResult, DeviceQueue, DeviceState, QueueConfig, VirtioDevice, }; use super::worker::InputWorker; -use super::{defs, defs::uapi, InputError}; +use super::{InputError, defs, defs::uapi}; +use crate::virtio::InterruptTransport; use crate::virtio::input::defs::config_select; use crate::virtio::input::defs::config_select::VIRTIO_INPUT_CFG_UNSET; -use crate::virtio::InterruptTransport; use krun_input::{ InputAbsInfo, InputConfigBackend, InputConfigInstance, InputDeviceIds, InputEventProviderBackend, InputQueryConfig, diff --git a/src/devices/src/virtio/input/passthrough.rs b/src/devices/src/virtio/input/passthrough.rs index 0f6b434da..6eea0e277 100644 --- a/src/devices/src/virtio/input/passthrough.rs +++ b/src/devices/src/virtio/input/passthrough.rs @@ -2,7 +2,7 @@ use krun_input::{ InputAbsInfo, InputBackendError, InputDeviceIds, InputEvent, InputEventsImpl, InputQueryConfig, ObjectNew, }; -use nix::fcntl::{fcntl, OFlag, F_GETFL, F_SETFL}; +use nix::fcntl::{F_GETFL, F_SETFL, OFlag, fcntl}; use nix::{errno::Errno, ioctl_read, ioctl_read_buf, unistd}; use std::mem; use std::os::fd::{AsFd, AsRawFd, BorrowedFd, RawFd}; @@ -175,7 +175,7 @@ ioctl_read_buf!(eviocgprop, b'E', 0x09, u8); unsafe fn eviocgbit(fd: RawFd, evt: u8, buf: &mut [u8]) -> Result { let ioctl_num = nix::request_code_read!(b'E', 0x20 + evt, buf.len()); - let n = libc::ioctl(fd, ioctl_num as _, buf.as_mut_ptr()); + let n = unsafe { libc::ioctl(fd, ioctl_num as _, buf.as_mut_ptr()) }; if n < 0 { return Err(Errno::last()); } @@ -185,7 +185,7 @@ unsafe fn eviocgbit(fd: RawFd, evt: u8, buf: &mut [u8]) -> Result { unsafe fn eviocgabs(fd: RawFd, axis: u8, abs_info: &mut LinuxAbsInfo) -> Result { let ioctl_num = nix::request_code_read!(b'E', 0x40 + axis, size_of::()); - let n = libc::ioctl(fd, ioctl_num as _, abs_info as *mut _); + let n = unsafe { libc::ioctl(fd, ioctl_num as _, abs_info as *mut _) }; if n < 0 { return Err(Errno::last()); } diff --git a/src/devices/src/virtio/input/worker.rs b/src/devices/src/virtio/input/worker.rs index 70d8836c3..a52f6a960 100644 --- a/src/devices/src/virtio/input/worker.rs +++ b/src/devices/src/virtio/input/worker.rs @@ -9,8 +9,8 @@ use virtio_bindings::virtio_input; use vm_memory::{ByteValued, GuestMemoryMmap}; use super::super::DeviceQueue; -use crate::virtio::descriptor_utils::{Reader, Writer}; use crate::virtio::InterruptTransport; +use crate::virtio::descriptor_utils::{Reader, Writer}; use krun_input::{InputEventProviderBackend, InputEventProviderInstance, InputEventsImpl}; // Create a wrapper type to work around orphan rules diff --git a/src/devices/src/virtio/net/device.rs b/src/devices/src/virtio/net/device.rs index 9d4b4a1fc..1ccce6557 100644 --- a/src/devices/src/virtio/net/device.rs +++ b/src/devices/src/virtio/net/device.rs @@ -4,14 +4,14 @@ // Portions Copyright 2017 The Chromium OS Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the THIRD-PARTY file. +use crate::Error as DeviceError; use crate::virtio::net::Result; use crate::virtio::net::{NUM_QUEUES, QUEUE_CONFIG}; use crate::virtio::queue::Error as QueueError; use crate::virtio::{ ActivateError, ActivateResult, DeviceQueue, DeviceState, InterruptTransport, QueueConfig, - VirtioDevice, TYPE_NET, + TYPE_NET, VirtioDevice, }; -use crate::Error as DeviceError; use super::backend::{ReadError, WriteError}; use super::worker::NetWorker; diff --git a/src/devices/src/virtio/net/tap.rs b/src/devices/src/virtio/net/tap.rs index 1c8bde34e..156246ea1 100644 --- a/src/devices/src/virtio/net/tap.rs +++ b/src/devices/src/virtio/net/tap.rs @@ -1,8 +1,8 @@ use libc::{ - c_char, c_int, ifreq, IFF_NO_PI, IFF_TAP, IFF_VNET_HDR, TUN_F_CSUM, TUN_F_TSO4, TUN_F_TSO6, - TUN_F_UFO, + IFF_NO_PI, IFF_TAP, IFF_VNET_HDR, TUN_F_CSUM, TUN_F_TSO4, TUN_F_TSO6, TUN_F_UFO, c_char, c_int, + ifreq, }; -use nix::fcntl::{fcntl, open, FcntlArg, OFlag}; +use nix::fcntl::{FcntlArg, OFlag, fcntl, open}; use nix::sys::stat::Mode; use nix::unistd::{read, write}; use nix::{ioctl_write_int, ioctl_write_ptr}; @@ -96,7 +96,7 @@ impl NetBackend for Tap { Ok(f) => f, #[allow(unreachable_patterns)] Err(nix::Error::EAGAIN | nix::Error::EWOULDBLOCK) => { - return Err(ReadError::NothingRead) + return Err(ReadError::NothingRead); } Err(e) => { return Err(ReadError::Internal(e)); diff --git a/src/devices/src/virtio/net/unixgram.rs b/src/devices/src/virtio/net/unixgram.rs index 600b6b41b..5495be0ed 100644 --- a/src/devices/src/virtio/net/unixgram.rs +++ b/src/devices/src/virtio/net/unixgram.rs @@ -1,7 +1,7 @@ -use nix::fcntl::{fcntl, FcntlArg, OFlag}; +use nix::fcntl::{FcntlArg, OFlag, fcntl}; use nix::sys::socket::{ - bind, connect, getsockopt, recv, send, setsockopt, socket, sockopt, AddressFamily, MsgFlags, - SockFlag, SockType, UnixAddr, + AddressFamily, MsgFlags, SockFlag, SockType, UnixAddr, bind, connect, getsockopt, recv, send, + setsockopt, socket, sockopt, }; use nix::unistd::unlink; use std::os::fd::{AsRawFd, OwnedFd, RawFd}; @@ -117,7 +117,7 @@ impl NetBackend for Unixgram { Ok(f) => f, #[allow(unreachable_patterns)] Err(nix::Error::EAGAIN | nix::Error::EWOULDBLOCK) => { - return Err(ReadError::NothingRead) + return Err(ReadError::NothingRead); } Err(e) => { return Err(ReadError::Internal(e)); diff --git a/src/devices/src/virtio/net/unixstream.rs b/src/devices/src/virtio/net/unixstream.rs index 023be6b28..c1b7ba722 100644 --- a/src/devices/src/virtio/net/unixstream.rs +++ b/src/devices/src/virtio/net/unixstream.rs @@ -1,6 +1,6 @@ use nix::sys::socket::{ - connect, getsockopt, recv, send, setsockopt, socket, sockopt, AddressFamily, MsgFlags, - SockFlag, SockType, UnixAddr, + AddressFamily, MsgFlags, SockFlag, SockType, UnixAddr, connect, getsockopt, recv, send, + setsockopt, socket, sockopt, }; use std::{ os::fd::{AsRawFd, OwnedFd, RawFd}, @@ -86,7 +86,7 @@ impl Unixstream { Ok(size) => bytes_read += size, #[allow(unreachable_patterns)] Err(nix::Error::EAGAIN | nix::Error::EWOULDBLOCK) => { - return Err(ReadError::NothingRead) + return Err(ReadError::NothingRead); } Err(e) => return Err(ReadError::Internal(e)), } diff --git a/src/devices/src/virtio/net/worker.rs b/src/devices/src/virtio/net/worker.rs index db20fd112..4e2fbb330 100644 --- a/src/devices/src/virtio/net/worker.rs +++ b/src/devices/src/virtio/net/worker.rs @@ -6,9 +6,9 @@ use crate::virtio::net::unixstream::Unixstream; use crate::virtio::net::{MAX_BUFFER_SIZE, QUEUE_SIZE}; use crate::virtio::{DeviceQueue, InterruptTransport}; +use super::VNET_HDR_LEN; use super::backend::{NetBackend, ReadError, WriteError}; use super::device::{FrontendError, RxError, TxError, VirtioNetBackend}; -use super::VNET_HDR_LEN; #[cfg(target_os = "macos")] use std::os::fd::RawFd; @@ -143,8 +143,12 @@ impl NetWorker { if event_set.contains(EventSet::HANG_UP) || event_set.contains(EventSet::READ_HANG_UP) { - log::error!("Got {event_set:?} on backend fd, virtio-net will stop working"); - eprintln!("LIBKRUN VIRTIO-NET FATAL: Backend process seems to have quit or crashed! Networking is now disabled!"); + log::error!( + "Got {event_set:?} on backend fd, virtio-net will stop working" + ); + eprintln!( + "LIBKRUN VIRTIO-NET FATAL: Backend process seems to have quit or crashed! Networking is now disabled!" + ); } else { if event_set.contains(EventSet::IN) { self.process_backend_socket_readable() @@ -383,7 +387,7 @@ impl NetWorker { break; } Err(e @ WriteError::Internal(_) | e @ WriteError::ProcessNotRunning) => { - return Err(TxError::Backend(e)) + return Err(TxError::Backend(e)); } } } diff --git a/src/devices/src/virtio/queue.rs b/src/devices/src/virtio/queue.rs index 2fb74289d..6991aa69a 100644 --- a/src/devices/src/virtio/queue.rs +++ b/src/devices/src/virtio/queue.rs @@ -8,7 +8,7 @@ use std::cmp::min; use std::fmt::{self, Debug, Display}; use std::num::Wrapping; -use std::sync::atomic::{fence, Ordering}; +use std::sync::atomic::{Ordering, fence}; use virtio_bindings::virtio_ring::VRING_USED_F_NO_NOTIFY; use vm_memory::{ Address, ByteValued, Bytes, GuestAddress, GuestMemory, GuestMemoryError, GuestMemoryMmap, @@ -254,11 +254,7 @@ impl<'a> DescriptorChain<'a> { next: desc.next, }; - if chain.is_valid() { - Some(chain) - } else { - None - } + if chain.is_valid() { Some(chain) } else { None } } fn is_valid(&self) -> bool { diff --git a/src/devices/src/virtio/rng/device.rs b/src/devices/src/virtio/rng/device.rs index c008c6189..b8f25ece7 100644 --- a/src/devices/src/virtio/rng/device.rs +++ b/src/devices/src/virtio/rng/device.rs @@ -1,4 +1,4 @@ -use rand::{rngs::OsRng, TryRngCore}; +use rand::{TryRngCore, rngs::OsRng}; use utils::eventfd::EventFd; use vm_memory::{Bytes, GuestMemoryMmap}; diff --git a/src/devices/src/virtio/rng/event_handler.rs b/src/devices/src/virtio/rng/event_handler.rs index 614e8b30d..5196bada7 100644 --- a/src/devices/src/virtio/rng/event_handler.rs +++ b/src/devices/src/virtio/rng/event_handler.rs @@ -3,7 +3,7 @@ use std::os::unix::io::AsRawFd; use polly::event_manager::{EventManager, Subscriber}; use utils::epoll::{EpollEvent, EventSet}; -use super::device::{Rng, REQ_INDEX}; +use super::device::{REQ_INDEX, Rng}; use crate::virtio::device::VirtioDevice; impl Rng { diff --git a/src/devices/src/virtio/vhost_user/device.rs b/src/devices/src/virtio/vhost_user/device.rs index 973efce43..bb79d24d6 100644 --- a/src/devices/src/virtio/vhost_user/device.rs +++ b/src/devices/src/virtio/vhost_user/device.rs @@ -14,7 +14,7 @@ use std::sync::{Arc, Mutex}; use log::{debug, error, warn}; use polly::event_manager::{EventManager, Subscriber}; use utils::epoll::{EpollEvent, EventSet}; -use utils::eventfd::{EventFd, EFD_NONBLOCK}; +use utils::eventfd::{EFD_NONBLOCK, EventFd}; use vhost::vhost_user::message::VhostUserConfigFlags; use vhost::vhost_user::{Frontend, VhostUserFrontend, VhostUserProtocolFeatures}; use vhost::{VhostBackend, VhostUserMemoryRegionInfo, VringConfigData}; @@ -100,9 +100,7 @@ impl VhostUserDevice { let mut frontend = Frontend::from_stream(stream, num_queues as u64); // Get available features from backend - let avail_features = frontend - .get_features() - .map_err(|e| io::Error::new(ErrorKind::Other, e))?; + let avail_features = frontend.get_features().map_err(io::Error::other)?; debug!("{}: backend features: 0x{:x}", device_name, avail_features); @@ -111,9 +109,7 @@ impl VhostUserDevice { let avail_features = avail_features & !VHOST_USER_F_PROTOCOL_FEATURES; if has_protocol_features { - let protocol_features = frontend - .get_protocol_features() - .map_err(|e| io::Error::new(ErrorKind::Other, e))?; + let protocol_features = frontend.get_protocol_features().map_err(io::Error::other)?; let mut our_protocol_features = VhostUserProtocolFeatures::empty(); if protocol_features.contains(VhostUserProtocolFeatures::CONFIG) { @@ -125,15 +121,13 @@ impl VhostUserDevice { frontend .set_protocol_features(our_protocol_features) - .map_err(|e| io::Error::new(ErrorKind::Other, e))?; + .map_err(io::Error::other)?; } // Determine actual queue count - may require protocol feature negotiation let actual_num_queues = if num_queues == 0 { if has_protocol_features { - let backend_queue_num = frontend - .get_queue_num() - .map_err(|e| io::Error::new(ErrorKind::Other, e))?; + let backend_queue_num = frontend.get_queue_num().map_err(io::Error::other)?; debug!( "{}: backend reports {} queues available", @@ -190,9 +184,7 @@ impl VhostUserDevice { self.acked_features }; - frontend - .set_owner() - .map_err(|e| io::Error::new(ErrorKind::Other, e))?; + frontend.set_owner().map_err(io::Error::other)?; // Only share memory regions that have file backing (memfd) let regions: Vec = mem @@ -210,7 +202,7 @@ impl VhostUserDevice { "{}: failed to convert memory regions: {:?}", self.device_name, e ); - io::Error::new(ErrorKind::Other, e) + io::Error::other(e) })?; debug!( @@ -221,13 +213,13 @@ impl VhostUserDevice { frontend.set_mem_table(®ions).map_err(|e| { error!("{}: set_mem_table failed: {:?}", self.device_name, e); - io::Error::new(ErrorKind::Other, e) + io::Error::other(e) })?; // If protocol features not negotiated, this triggers automatic ring enabling frontend .set_features(backend_feature_bits) - .map_err(|e| io::Error::new(ErrorKind::Other, e))?; + .map_err(io::Error::other)?; let vring_call_event = EventFd::new(EFD_NONBLOCK)?; @@ -236,12 +228,12 @@ impl VhostUserDevice { frontend .set_vring_num(queue_index, queue.actual_size()) - .map_err(|e| io::Error::new(ErrorKind::Other, e))?; + .map_err(io::Error::other)?; // Set vring base frontend .set_vring_base(queue_index, 0) - .map_err(|e| io::Error::new(ErrorKind::Other, e))?; + .map_err(io::Error::other)?; // Vring addresses in queue are GPAs, but vhost-user protocol expects VMM VAs let desc_table_gpa = queue.desc_table.0; @@ -287,7 +279,7 @@ impl VhostUserDevice { .set_vring_addr(queue_index, &vring_config) .map_err(|e| { error!("{}: set_vring_addr failed: {:?}", self.device_name, e); - io::Error::new(ErrorKind::Other, e) + io::Error::other(e) })?; // Create vhost-compatible EventFd from the raw fd @@ -297,7 +289,7 @@ impl VhostUserDevice { .set_vring_kick(queue_index, &kick_fd) .map_err(|e| { error!("{}: set_vring_kick failed: {:?}", self.device_name, e); - io::Error::new(ErrorKind::Other, e) + io::Error::other(e) })?; std::mem::forget(kick_fd); // Don't close the fd twice @@ -306,7 +298,7 @@ impl VhostUserDevice { .set_vring_call(queue_index, &call_fd) .map_err(|e| { error!("{}: set_vring_call failed: {:?}", self.device_name, e); - io::Error::new(ErrorKind::Other, e) + io::Error::other(e) })?; std::mem::forget(call_fd); // Don't close the fd twice @@ -315,7 +307,7 @@ impl VhostUserDevice { if self.has_protocol_features { frontend .set_vring_enable(queue_index, true) - .map_err(|e| io::Error::new(ErrorKind::Other, e))?; + .map_err(io::Error::other)?; } else { debug!( "{}: vring {} already enabled (protocol features not negotiated)", @@ -363,33 +355,33 @@ impl VirtioDevice for VhostUserDevice { fn read_config(&self, offset: u64, data: &mut [u8]) { // Fetch config from backend on every read (same as QEMU/crosvm) // No caching to avoid invalidation issues - if self.has_protocol_features { - if let Ok(mut frontend) = self.frontend.lock() { - match frontend.get_config( - offset as u32, - data.len() as u32, - VhostUserConfigFlags::empty(), - data, - ) { - Ok((_, returned_buf)) => { - if data.len() <= returned_buf.len() { - data.copy_from_slice(&returned_buf[..data.len()]); - debug!( - "{}: read {} bytes from config at offset {}", - self.device_name, - data.len(), - offset - ); - return; - } - } - Err(e) => { + if self.has_protocol_features + && let Ok(mut frontend) = self.frontend.lock() + { + match frontend.get_config( + offset as u32, + data.len() as u32, + VhostUserConfigFlags::empty(), + data, + ) { + Ok((_, returned_buf)) => { + if data.len() <= returned_buf.len() { + data.copy_from_slice(&returned_buf[..data.len()]); debug!( - "{}: failed to read config from backend: {:?}", - self.device_name, e + "{}: read {} bytes from config at offset {}", + self.device_name, + data.len(), + offset ); + return; } } + Err(e) => { + debug!( + "{}: failed to read config from backend: {:?}", + self.device_name, e + ); + } } } diff --git a/src/devices/src/virtio/vsock/device.rs b/src/devices/src/virtio/vsock/device.rs index a61043b4c..1c019dcd5 100644 --- a/src/devices/src/virtio/vsock/device.rs +++ b/src/devices/src/virtio/vsock/device.rs @@ -17,9 +17,9 @@ use super::super::{ ActivateError, ActivateResult, DeviceQueue, DeviceState, Queue as VirtQueue, QueueConfig, VirtioDevice, }; +use super::TsiFlags; use super::muxer::VsockMuxer; use super::packet::VsockPacket; -use super::TsiFlags; use super::{defs, defs::uapi}; use crate::virtio::InterruptTransport; diff --git a/src/devices/src/virtio/vsock/event_handler.rs b/src/devices/src/virtio/vsock/event_handler.rs index b7fb15799..641eb26ef 100644 --- a/src/devices/src/virtio/vsock/event_handler.rs +++ b/src/devices/src/virtio/vsock/event_handler.rs @@ -10,7 +10,7 @@ use std::os::unix::io::AsRawFd; use polly::event_manager::{EventManager, Subscriber}; use utils::epoll::{EpollEvent, EventSet}; -use super::device::{Vsock, EVQ_INDEX, RXQ_INDEX, TXQ_INDEX}; +use super::device::{EVQ_INDEX, RXQ_INDEX, TXQ_INDEX, Vsock}; use crate::virtio::VirtioDevice; impl Vsock { diff --git a/src/devices/src/virtio/vsock/mod.rs b/src/devices/src/virtio/vsock/mod.rs index c307c5443..e429a9b22 100644 --- a/src/devices/src/virtio/vsock/mod.rs +++ b/src/devices/src/virtio/vsock/mod.rs @@ -20,8 +20,8 @@ mod tsi_dgram; mod tsi_stream; mod unix; -pub use self::defs::uapi::VIRTIO_ID_VSOCK as TYPE_VSOCK; pub use self::defs::TsiFlags; +pub use self::defs::uapi::VIRTIO_ID_VSOCK as TYPE_VSOCK; pub use self::device::Vsock; use bitflags::bitflags; diff --git a/src/devices/src/virtio/vsock/muxer.rs b/src/devices/src/virtio/vsock/muxer.rs index f4c10247e..1012ad3cf 100644 --- a/src/devices/src/virtio/vsock/muxer.rs +++ b/src/devices/src/virtio/vsock/muxer.rs @@ -4,9 +4,11 @@ use std::path::PathBuf; use std::sync::{Arc, Mutex, RwLock}; use super::super::Queue as VirtQueue; +use super::TsiFlags; +use super::VsockError; use super::defs; use super::defs::uapi; -use super::muxer_rxq::{rx_to_pkt, MuxerRxQ}; +use super::muxer_rxq::{MuxerRxQ, rx_to_pkt}; use super::muxer_thread::MuxerThread; use super::packet::{TsiConnectReq, TsiGetnameRsp, VsockPacket}; use super::proxy::{Proxy, ProxyRemoval, ProxyUpdate}; @@ -16,9 +18,7 @@ use super::timesync::TimesyncThread; use super::tsi_dgram::TsiDgramProxy; use super::tsi_stream::TsiStreamProxy; use super::unix::UnixProxy; -use super::TsiFlags; -use super::VsockError; -use crossbeam_channel::{unbounded, Sender}; +use crossbeam_channel::{Sender, unbounded}; use utils::epoll::{ControlOperation, Epoll, EpollEvent, EventSet}; use vm_memory::GuestMemoryMmap; @@ -243,18 +243,18 @@ impl VsockMuxer { } ProxyRemoval::Deferred => { info!("deferring proxy removal: {id}"); - if let Some(reaper_sender) = &self.reaper_sender { - if reaper_sender.send(id).is_err() { - self.proxy_map.write().unwrap().remove(&id); - } + if let Some(reaper_sender) = &self.reaper_sender + && reaper_sender.send(id).is_err() + { + self.proxy_map.write().unwrap().remove(&id); } } } - if update.signal_queue { - if let Some(interrupt) = &self.interrupt { - interrupt.signal_used_queue(); - } + if update.signal_queue + && let Some(interrupt) = &self.interrupt + { + interrupt.signal_used_queue(); } } @@ -545,41 +545,41 @@ impl VsockMuxer { if let Some(update) = proxy.lock().unwrap().confirm_connect(pkt) { self.process_proxy_update(id, update); } - } else if let Some(ref mut ipc_map) = &mut self.unix_ipc_port_map { - if let Some((path, listen)) = ipc_map.get(&pkt.dst_port()) { - let mem = self.mem.as_ref().unwrap(); - let queue = self.queue.as_ref().unwrap(); - if *listen { - warn!("Attempting to connect a socket that is listening, sending rst"); - let rx = MuxerRx::Reset { - local_port: pkt.dst_port(), - peer_port: pkt.src_port(), - }; - push_packet(self.cid, rx, &self.rxq, queue, mem); - return; - } - let rxq = self.rxq.clone(); - - let mut unix = UnixProxy::new( - id, - self.cid, - pkt.dst_port(), - pkt.src_port(), - mem.clone(), - queue.clone(), - rxq, - path.to_path_buf(), - ) - .unwrap(); - let tsi = TsiConnectReq { - peer_port: 0, - addr: SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0).into(), + } else if let Some(ipc_map) = &mut self.unix_ipc_port_map + && let Some((path, listen)) = ipc_map.get(&pkt.dst_port()) + { + let mem = self.mem.as_ref().unwrap(); + let queue = self.queue.as_ref().unwrap(); + if *listen { + warn!("Attempting to connect a socket that is listening, sending rst"); + let rx = MuxerRx::Reset { + local_port: pkt.dst_port(), + peer_port: pkt.src_port(), }; - let update = unix.connect(pkt, tsi); - unix.confirm_connect(pkt); - proxy_map.insert(id, Mutex::new(Box::new(unix))); - self.process_proxy_update(id, update); + push_packet(self.cid, rx, &self.rxq, queue, mem); + return; } + let rxq = self.rxq.clone(); + + let mut unix = UnixProxy::new( + id, + self.cid, + pkt.dst_port(), + pkt.src_port(), + mem.clone(), + queue.clone(), + rxq, + path.to_path_buf(), + ) + .unwrap(); + let tsi = TsiConnectReq { + peer_port: 0, + addr: SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), 0).into(), + }; + let update = unix.connect(pkt, tsi); + unix.confirm_connect(pkt); + proxy_map.insert(id, Mutex::new(Box::new(unix))); + self.process_proxy_update(id, update); } } diff --git a/src/devices/src/virtio/vsock/muxer_thread.rs b/src/devices/src/virtio/vsock/muxer_thread.rs index e58ae7922..1db435c10 100644 --- a/src/devices/src/virtio/vsock/muxer_thread.rs +++ b/src/devices/src/virtio/vsock/muxer_thread.rs @@ -5,16 +5,16 @@ use std::sync::{Arc, Mutex}; use std::thread; use super::super::Queue as VirtQueue; -use super::muxer::{push_packet, MuxerRx, ProxyMap}; +use super::muxer::{MuxerRx, ProxyMap, push_packet}; use super::muxer_rxq::MuxerRxQ; use super::proxy::{NewProxyType, Proxy, ProxyRemoval, ProxyUpdate}; use super::tsi_stream::TsiStreamProxy; +use crate::virtio::InterruptTransport; use crate::virtio::vsock::defs; use crate::virtio::vsock::unix::{UnixAcceptorProxy, UnixProxy}; -use crate::virtio::InterruptTransport; use crossbeam_channel::Sender; -use rand::{rng, rngs::ThreadRng, Rng}; +use rand::{Rng, rng, rngs::ThreadRng}; use utils::epoll::{ControlOperation, Epoll, EpollEvent, EventSet}; use vm_memory::GuestMemoryMmap; diff --git a/src/devices/src/virtio/vsock/packet.rs b/src/devices/src/virtio/vsock/packet.rs index 51b3cf1b2..b7e23db51 100644 --- a/src/devices/src/virtio/vsock/packet.rs +++ b/src/devices/src/virtio/vsock/packet.rs @@ -24,7 +24,7 @@ use std::os::raw::c_char; use std::result; #[cfg(target_os = "linux")] -use nix::sys::socket::{sockaddr, AddressFamily}; +use nix::sys::socket::{AddressFamily, sockaddr}; use nix::sys::socket::{SockaddrLike, SockaddrStorage}; use utils::byte_order; use vm_memory::{self, Address, GuestAddress, GuestMemory, GuestMemoryError}; @@ -654,10 +654,10 @@ impl VsockPacket { } pub fn write_connect_rsp(&mut self, rsp: TsiConnectRsp) { - if self.buf_size >= 4 { - if let Some(buf) = self.buf_mut() { - byte_order::write_le_u32(&mut buf[0..], rsp.result as u32); - } + if self.buf_size >= 4 + && let Some(buf) = self.buf_mut() + { + byte_order::write_le_u32(&mut buf[0..], rsp.result as u32); } } @@ -677,29 +677,29 @@ impl VsockPacket { } pub fn write_getname_rsp(&mut self, rsp: TsiGetnameRsp) { - if self.buf_size >= 132 { - if let Some(buf) = self.buf_mut() { - byte_order::write_le_u32(&mut buf[0..], rsp.result as u32); - byte_order::write_le_u32(&mut buf[4..], rsp.addr_len); - let addr_ptr = rsp.addr.as_ptr(); - let slice = unsafe { - std::slice::from_raw_parts(addr_ptr as *const u8, rsp.addr.len() as usize) + if self.buf_size >= 132 + && let Some(buf) = self.buf_mut() + { + byte_order::write_le_u32(&mut buf[0..], rsp.result as u32); + byte_order::write_le_u32(&mut buf[4..], rsp.addr_len); + let addr_ptr = rsp.addr.as_ptr(); + let slice = unsafe { + std::slice::from_raw_parts(addr_ptr as *const u8, rsp.addr.len() as usize) + }; + buf[8..(rsp.addr.len() + 8) as usize].copy_from_slice(slice); + + // On macOS, convert BSD sockaddr (u8 sa_len + u8 sa_family) to + // Linux wire format (u16 sa_family). Also translate macOS AF_* + // values to their Linux equivalents (e.g. AF_INET6: 30 → 10). + #[cfg(target_os = "macos")] + { + let bsd_family = buf[9]; + let linux_family: u16 = match bsd_family as i32 { + libc::AF_INET => defs::LINUX_AF_INET, + libc::AF_INET6 => defs::LINUX_AF_INET6, + _ => 0, // AF_UNSPEC }; - buf[8..(rsp.addr.len() + 8) as usize].copy_from_slice(slice); - - // On macOS, convert BSD sockaddr (u8 sa_len + u8 sa_family) to - // Linux wire format (u16 sa_family). Also translate macOS AF_* - // values to their Linux equivalents (e.g. AF_INET6: 30 → 10). - #[cfg(target_os = "macos")] - { - let bsd_family = buf[9]; - let linux_family: u16 = match bsd_family as i32 { - libc::AF_INET => defs::LINUX_AF_INET, - libc::AF_INET6 => defs::LINUX_AF_INET6, - _ => 0, // AF_UNSPEC - }; - byte_order::write_le_u16(&mut buf[8..], linux_family); - } + byte_order::write_le_u16(&mut buf[8..], linux_family); } } } @@ -738,10 +738,10 @@ impl VsockPacket { } pub fn write_listen_rsp(&mut self, rsp: TsiListenRsp) { - if self.buf_size >= 4 { - if let Some(buf) = self.buf_mut() { - byte_order::write_le_u32(&mut buf[0..], rsp.result as u32); - } + if self.buf_size >= 4 + && let Some(buf) = self.buf_mut() + { + byte_order::write_le_u32(&mut buf[0..], rsp.result as u32); } } @@ -757,10 +757,10 @@ impl VsockPacket { } pub fn write_accept_rsp(&mut self, rsp: TsiAcceptRsp) { - if self.buf_size >= 4 { - if let Some(buf) = self.buf_mut() { - byte_order::write_le_u32(&mut buf[0..], rsp.result as u32); - } + if self.buf_size >= 4 + && let Some(buf) = self.buf_mut() + { + byte_order::write_le_u32(&mut buf[0..], rsp.result as u32); } } @@ -778,10 +778,10 @@ impl VsockPacket { } pub fn write_time_sync(&mut self, time: u64) { - if self.buf_size >= 8 { - if let Some(buf) = self.buf_mut() { - byte_order::write_le_u64(&mut buf[0..], time); - } + if self.buf_size >= 8 + && let Some(buf) = self.buf_mut() + { + byte_order::write_le_u64(&mut buf[0..], time); } } } diff --git a/src/devices/src/virtio/vsock/timesync.rs b/src/devices/src/virtio/vsock/timesync.rs index 206c4c1fb..0ca017596 100644 --- a/src/devices/src/virtio/vsock/timesync.rs +++ b/src/devices/src/virtio/vsock/timesync.rs @@ -37,24 +37,24 @@ impl TimesyncThread { fn send_time(&self, time: u64) { let mut queue = self.queue_mutex.lock().unwrap(); - if let Some(head) = queue.pop(&self.mem) { - if let Ok(mut pkt) = VsockPacket::from_rx_virtq_head(&head) { - pkt.set_op(uapi::VSOCK_OP_RW) - .set_src_cid(uapi::VSOCK_HOST_CID) - .set_dst_cid(self.cid) - .set_src_port(TSYNC_PORT) - .set_dst_port(TSYNC_PORT) - .set_type(uapi::VSOCK_TYPE_DGRAM); + if let Some(head) = queue.pop(&self.mem) + && let Ok(mut pkt) = VsockPacket::from_rx_virtq_head(&head) + { + pkt.set_op(uapi::VSOCK_OP_RW) + .set_src_cid(uapi::VSOCK_HOST_CID) + .set_dst_cid(self.cid) + .set_src_port(TSYNC_PORT) + .set_dst_port(TSYNC_PORT) + .set_type(uapi::VSOCK_TYPE_DGRAM); - pkt.write_time_sync(time); - pkt.set_len(pkt.buf().unwrap().len() as u32); - if let Err(e) = - queue.add_used(&self.mem, head.index, pkt.hdr().len() as u32 + pkt.len()) - { - error!("failed to add used elements to the queue: {e:?}"); - } - self.interrupt.signal_used_queue(); + pkt.write_time_sync(time); + pkt.set_len(pkt.buf().unwrap().len() as u32); + if let Err(e) = + queue.add_used(&self.mem, head.index, pkt.hdr().len() as u32 + pkt.len()) + { + error!("failed to add used elements to the queue: {e:?}"); } + self.interrupt.signal_used_queue(); } } diff --git a/src/devices/src/virtio/vsock/tsi_dgram.rs b/src/devices/src/virtio/vsock/tsi_dgram.rs index de0850c37..e96b8a5cd 100644 --- a/src/devices/src/virtio/vsock/tsi_dgram.rs +++ b/src/devices/src/virtio/vsock/tsi_dgram.rs @@ -5,20 +5,20 @@ use std::os::fd::OwnedFd; use std::os::unix::io::{AsRawFd, RawFd}; use std::sync::{Arc, Mutex}; -use nix::fcntl::{fcntl, FcntlArg, OFlag}; +use nix::fcntl::{FcntlArg, OFlag, fcntl}; #[cfg(target_os = "linux")] use nix::sys::socket::UnixAddr; use nix::sys::socket::{ - bind, connect, getpeername, recv, send, sendto, socket, AddressFamily, MsgFlags, SockFlag, - SockType, SockaddrIn, SockaddrLike, SockaddrStorage, + AddressFamily, MsgFlags, SockFlag, SockType, SockaddrIn, SockaddrLike, SockaddrStorage, bind, + connect, getpeername, recv, send, sendto, socket, }; +use super::super::Queue as VirtQueue; #[cfg(target_os = "macos")] use super::super::linux_errno::linux_errno_raw; -use super::super::Queue as VirtQueue; use super::defs; use super::defs::uapi; -use super::muxer::{push_packet, MuxerRx}; +use super::muxer::{MuxerRx, push_packet}; use super::muxer_rxq::MuxerRxQ; use super::packet::{ TsiAcceptReq, TsiConnectReq, TsiGetnameRsp, TsiListenReq, TsiSendtoAddr, VsockPacket, diff --git a/src/devices/src/virtio/vsock/tsi_stream.rs b/src/devices/src/virtio/vsock/tsi_stream.rs index c819398d3..66694b633 100644 --- a/src/devices/src/virtio/vsock/tsi_stream.rs +++ b/src/devices/src/virtio/vsock/tsi_stream.rs @@ -14,18 +14,18 @@ use libc::EINVAL; #[cfg(target_os = "macos")] use libc::EINVAL; use nix::errno::Errno; -use nix::fcntl::{fcntl, FcntlArg, OFlag}; +use nix::fcntl::{FcntlArg, OFlag, fcntl}; use nix::sys::socket::{ - accept, bind, connect, getpeername, listen, recv, send, setsockopt, shutdown, socket, sockopt, AddressFamily, Backlog, MsgFlags, Shutdown, SockFlag, SockType, SockaddrLike, SockaddrStorage, + accept, bind, connect, getpeername, listen, recv, send, setsockopt, shutdown, socket, sockopt, }; +use super::super::Queue as VirtQueue; #[cfg(target_os = "macos")] use super::super::linux_errno::linux_errno_raw; -use super::super::Queue as VirtQueue; use super::defs; use super::defs::uapi; -use super::muxer::{push_packet, MuxerRx}; +use super::muxer::{MuxerRx, push_packet}; use super::muxer_rxq::MuxerRxQ; use super::packet::{ TsiAcceptReq, TsiConnectReq, TsiGetnameRsp, TsiListenReq, TsiSendtoAddr, VsockPacket, @@ -227,10 +227,10 @@ impl TsiStreamProxy { let unixsock_path = self.get_unixsock_path(&addr); // If the userspace process in the guest has already created the socket, // we need to unlink it to take ownership of the node in the filesystem. - if let Some(path) = &unixsock_path { - if let Err(e) = fs::remove_file(path) { - debug!("error removing socket: {e}"); - } + if let Some(path) = &unixsock_path + && let Err(e) = fs::remove_file(path) + { + debug!("error removing socket: {e}"); } match bind(self.fd.as_raw_fd(), &addr) { @@ -431,25 +431,25 @@ impl TsiStreamProxy { } fn get_unixsock_path(&self, addr: &SockaddrStorage) -> Option { - if let Some(addr) = addr.as_unix_addr() { - if let Some(path) = addr.path() { - // SockaddrStorage doesn't clean up NULLs. This is fine when - // using addr with other nix methods, but we need to clean them - // up to be able to treat it as a path with other Rust crates. - let path_str = path.to_str()?.replace("\0", ""); - debug!("unix socket path_str={path_str}"); - - match fs::metadata(&path_str) { - Ok(metadata) => { - if metadata.file_type().is_socket() { - debug!("unix socket path is socket"); - return PathBuf::from_str(&path_str).ok(); - } else { - debug!("unix socket path is NOT a socket"); - } + if let Some(addr) = addr.as_unix_addr() + && let Some(path) = addr.path() + { + // SockaddrStorage doesn't clean up NULLs. This is fine when + // using addr with other nix methods, but we need to clean them + // up to be able to treat it as a path with other Rust crates. + let path_str = path.to_str()?.replace("\0", ""); + debug!("unix socket path_str={path_str}"); + + match fs::metadata(&path_str) { + Ok(metadata) => { + if metadata.file_type().is_socket() { + debug!("unix socket path is socket"); + return PathBuf::from_str(&path_str).ok(); + } else { + debug!("unix socket path is NOT a socket"); } - Err(e) => debug!("metadata failed with {e}"), } + Err(e) => debug!("metadata failed with {e}"), } } diff --git a/src/devices/src/virtio/vsock/unix.rs b/src/devices/src/virtio/vsock/unix.rs index 2f51c05fa..34ebc46c0 100644 --- a/src/devices/src/virtio/vsock/unix.rs +++ b/src/devices/src/virtio/vsock/unix.rs @@ -4,10 +4,10 @@ use super::{ }; use nix::errno::Errno; -use nix::fcntl::{fcntl, FcntlArg, OFlag}; +use nix::fcntl::{FcntlArg, OFlag, fcntl}; use nix::sys::socket::{ - accept, bind, connect, listen, recv, send, shutdown, socket, AddressFamily, Backlog, MsgFlags, - Shutdown, SockFlag, SockType, UnixAddr, + AddressFamily, Backlog, MsgFlags, Shutdown, SockFlag, SockType, UnixAddr, accept, bind, + connect, listen, recv, send, shutdown, socket, }; use std::collections::HashMap; use std::num::Wrapping; @@ -16,10 +16,10 @@ use std::os::unix::io::{AsRawFd, RawFd}; use std::path::PathBuf; use std::sync::{Arc, Mutex}; +use super::super::Queue as VirtQueue; #[cfg(target_os = "macos")] use super::super::linux_errno::linux_errno_raw; -use super::super::Queue as VirtQueue; -use super::muxer::{push_packet, MuxerRx}; +use super::muxer::{MuxerRx, push_packet}; use super::muxer_rxq::MuxerRxQ; use super::packet::{TsiAcceptReq, TsiConnectReq, TsiListenReq, TsiSendtoAddr, VsockPacket}; use super::proxy::{NewProxyType, Proxy, ProxyError, ProxyStatus, ProxyUpdate}; diff --git a/src/hvf/Cargo.toml b/src/hvf/Cargo.toml index 510ec48a4..8b90cdded 100644 --- a/src/hvf/Cargo.toml +++ b/src/hvf/Cargo.toml @@ -2,7 +2,7 @@ name = "krun-hvf" version = "0.1.0-1.18.0" authors = ["The libkrun Authors"] -edition = "2021" +edition = "2024" description = "Apple Hypervisor.framework backend for libkrun" license = "Apache-2.0" repository = "https://github.com/containers/libkrun" diff --git a/src/hvf/src/bindings.rs b/src/hvf/src/bindings.rs index f2cd1ed40..a6a7ceadf 100644 --- a/src/hvf/src/bindings.rs +++ b/src/hvf/src/bindings.rs @@ -873,7 +873,7 @@ const _: () = { ["Alignment of fd_set"][::std::mem::align_of::() - 4usize]; ["Offset of field: fd_set::fds_bits"][::std::mem::offset_of!(fd_set, fds_bits) - 0usize]; }; -extern "C" { +unsafe extern "C" { pub fn __darwin_check_fd_set_overflow( arg1: ::std::os::raw::c_int, arg2: *const ::std::os::raw::c_void, @@ -912,10 +912,10 @@ pub const HV_MEMORY_WRITE: _bindgen_ty_2 = 2; pub const HV_MEMORY_EXEC: _bindgen_ty_2 = 4; pub type _bindgen_ty_2 = ::std::os::raw::c_uint; pub type hv_memory_flags_t = u64; -extern "C" { +unsafe extern "C" { pub fn os_retain(object: *mut ::std::os::raw::c_void) -> *mut ::std::os::raw::c_void; } -extern "C" { +unsafe extern "C" { pub fn os_release(object: *mut ::std::os::raw::c_void); } #[repr(C)] @@ -4369,251 +4369,251 @@ pub type hv_interrupt_type_t = u32; pub const hv_cache_type_t_HV_CACHE_TYPE_DATA: hv_cache_type_t = 0; pub const hv_cache_type_t_HV_CACHE_TYPE_INSTRUCTION: hv_cache_type_t = 1; pub type hv_cache_type_t = u32; -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_create( vcpu: *mut hv_vcpu_t, exit: *mut *mut hv_vcpu_exit_t, config: hv_vcpu_config_t, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_destroy(vcpu: hv_vcpu_t) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_get_reg(vcpu: hv_vcpu_t, reg: hv_reg_t, value: *mut u64) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_set_reg(vcpu: hv_vcpu_t, reg: hv_reg_t, value: u64) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_get_simd_fp_reg( vcpu: hv_vcpu_t, reg: hv_simd_fp_reg_t, value: *mut hv_simd_fp_uchar16_t, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_set_simd_fp_reg( vcpu: hv_vcpu_t, reg: hv_simd_fp_reg_t, value: hv_simd_fp_uchar16_t, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_get_sys_reg(vcpu: hv_vcpu_t, reg: hv_sys_reg_t, value: *mut u64) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_set_sys_reg(vcpu: hv_vcpu_t, reg: hv_sys_reg_t, value: u64) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_get_pending_interrupt( vcpu: hv_vcpu_t, type_: hv_interrupt_type_t, pending: *mut bool, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_set_pending_interrupt( vcpu: hv_vcpu_t, type_: hv_interrupt_type_t, pending: bool, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_get_trap_debug_exceptions(vcpu: hv_vcpu_t, value: *mut bool) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_set_trap_debug_exceptions(vcpu: hv_vcpu_t, value: bool) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_get_trap_debug_reg_accesses(vcpu: hv_vcpu_t, value: *mut bool) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_set_trap_debug_reg_accesses(vcpu: hv_vcpu_t, value: bool) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_run(vcpu: hv_vcpu_t) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpus_exit(vcpus: *mut hv_vcpu_t, vcpu_count: u32) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_get_exec_time(vcpu: hv_vcpu_t, time: *mut u64) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_get_vtimer_mask(vcpu: hv_vcpu_t, vtimer_is_masked: *mut bool) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_set_vtimer_mask(vcpu: hv_vcpu_t, vtimer_is_masked: bool) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_get_vtimer_offset(vcpu: hv_vcpu_t, vtimer_offset: *mut u64) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_set_vtimer_offset(vcpu: hv_vcpu_t, vtimer_offset: u64) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_create(gic_config: hv_gic_config_t) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_set_spi(intid: u32, level: bool) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_send_msi(address: hv_ipa_t, intid: u32) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_get_distributor_reg( reg: hv_gic_distributor_reg_t, value: *mut u64, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_set_distributor_reg(reg: hv_gic_distributor_reg_t, value: u64) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_get_redistributor_base( vcpu: hv_vcpu_t, redistributor_base_address: *mut hv_ipa_t, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_get_redistributor_reg( vcpu: hv_vcpu_t, reg: hv_gic_redistributor_reg_t, value: *mut u64, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_set_redistributor_reg( vcpu: hv_vcpu_t, reg: hv_gic_redistributor_reg_t, value: u64, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_get_icc_reg( vcpu: hv_vcpu_t, reg: hv_gic_icc_reg_t, value: *mut u64, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_set_icc_reg(vcpu: hv_vcpu_t, reg: hv_gic_icc_reg_t, value: u64) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_get_ich_reg( vcpu: hv_vcpu_t, reg: hv_gic_ich_reg_t, value: *mut u64, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_set_ich_reg(vcpu: hv_vcpu_t, reg: hv_gic_ich_reg_t, value: u64) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_get_icv_reg( vcpu: hv_vcpu_t, reg: hv_gic_icv_reg_t, value: *mut u64, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_set_icv_reg(vcpu: hv_vcpu_t, reg: hv_gic_icv_reg_t, value: u64) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_get_msi_reg(reg: hv_gic_msi_reg_t, value: *mut u64) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_set_msi_reg(reg: hv_gic_msi_reg_t, value: u64) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_set_state( gic_state_data: *const ::std::os::raw::c_void, gic_state_size: usize, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_reset() -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_config_create() -> hv_gic_config_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_config_set_distributor_base( config: hv_gic_config_t, distributor_base_address: hv_ipa_t, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_config_set_redistributor_base( config: hv_gic_config_t, redistributor_base_address: hv_ipa_t, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_config_set_msi_region_base( config: hv_gic_config_t, msi_region_base_address: hv_ipa_t, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_config_set_msi_interrupt_range( config: hv_gic_config_t, msi_intid_base: u32, msi_intid_count: u32, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_get_distributor_size(distributor_size: *mut usize) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_get_distributor_base_alignment( distributor_base_alignment: *mut usize, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_get_redistributor_region_size( redistributor_region_size: *mut usize, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_get_redistributor_size(redistributor_size: *mut usize) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_get_redistributor_base_alignment( redistributor_base_alignment: *mut usize, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_get_msi_region_size(msi_region_size: *mut usize) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_get_msi_region_base_alignment( msi_region_base_alignment: *mut usize, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_get_spi_interrupt_range( spi_intid_base: *mut u32, spi_intid_count: *mut u32, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_get_intid(interrupt: hv_gic_intid_t, intid: *mut u32) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_state_create() -> hv_gic_state_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_state_get_size(state: hv_gic_state_t, gic_state_size: *mut usize) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_gic_state_get_data( state: hv_gic_state_t, gic_state_data: *mut ::std::os::raw::c_void, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_config_create() -> hv_vcpu_config_t; } pub const hv_feature_reg_t_HV_FEATURE_REG_ID_AA64DFR0_EL1: hv_feature_reg_t = 0; @@ -4629,30 +4629,30 @@ pub const hv_feature_reg_t_HV_FEATURE_REG_CTR_EL0: hv_feature_reg_t = 9; pub const hv_feature_reg_t_HV_FEATURE_REG_CLIDR_EL1: hv_feature_reg_t = 10; pub const hv_feature_reg_t_HV_FEATURE_REG_DCZID_EL0: hv_feature_reg_t = 11; pub type hv_feature_reg_t = u32; -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_config_get_feature_reg( config: hv_vcpu_config_t, feature_reg: hv_feature_reg_t, value: *mut u64, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vcpu_config_get_ccsidr_el1_sys_reg_values( config: hv_vcpu_config_t, cache_type: hv_cache_type_t, values: *mut u64, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vm_get_max_vcpu_count(max_vcpu_count: *mut u32) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vm_create(config: hv_vm_config_t) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vm_destroy() -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vm_map( addr: *mut ::std::os::raw::c_void, ipa: hv_ipa_t, @@ -4660,53 +4660,53 @@ extern "C" { flags: hv_memory_flags_t, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vm_unmap(ipa: hv_ipa_t, size: usize) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vm_protect(ipa: hv_ipa_t, size: usize, flags: hv_memory_flags_t) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vm_config_create() -> hv_vm_config_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vm_config_get_max_ipa_size(ipa_bit_length: *mut u32) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vm_config_get_default_ipa_size(ipa_bit_length: *mut u32) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vm_config_set_ipa_size(config: hv_vm_config_t, ipa_bit_length: u32) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vm_config_get_ipa_size( config: hv_vm_config_t, ipa_bit_length: *mut u32, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vm_config_get_el2_supported(el2_supported: *mut bool) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vm_config_get_el2_enabled( config: hv_vm_config_t, el2_enabled: *mut bool, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vm_config_set_el2_enabled(config: hv_vm_config_t, el2_enabled: bool) -> hv_return_t; } pub const HV_ALLOCATE_DEFAULT: _bindgen_ty_3 = 0; pub type _bindgen_ty_3 = ::std::os::raw::c_uint; pub type hv_allocate_flags_t = u64; -extern "C" { +unsafe extern "C" { pub fn hv_vm_allocate( uvap: *mut *mut ::std::os::raw::c_void, size: usize, flags: hv_allocate_flags_t, ) -> hv_return_t; } -extern "C" { +unsafe extern "C" { pub fn hv_vm_deallocate(uva: *mut ::std::os::raw::c_void, size: usize) -> hv_return_t; } pub type __builtin_va_list = *mut ::std::os::raw::c_char; diff --git a/src/hvf/src/lib.rs b/src/hvf/src/lib.rs index e6928fc90..c7478becd 100644 --- a/src/hvf/src/lib.rs +++ b/src/hvf/src/lib.rs @@ -23,10 +23,10 @@ use std::sync::{Arc, LazyLock}; use std::time::Duration; #[cfg(all(target_arch = "aarch64", target_os = "macos"))] -use arch::aarch64::sysreg::{sys_reg_name, SYSREG_MASK}; +use arch::aarch64::sysreg::{SYSREG_MASK, sys_reg_name}; use log::debug; -extern "C" { +unsafe extern "C" { pub fn mach_absolute_time() -> u64; } @@ -126,7 +126,7 @@ impl Display for Error { match self { EnableEL2 => write!(f, "Error enabling EL2 mode in HVF"), - FindSymbol(ref err) => write!(f, "Couldn't find symbol in HVF library: {err}"), + FindSymbol(err) => write!(f, "Couldn't find symbol in HVF library: {err}"), MemoryMap => write!(f, "Error registering memory region in HVF"), MemoryUnmap => write!(f, "Error unregistering memory region in HVF"), NestedCheck => write!( @@ -553,21 +553,21 @@ impl HvfVcpu<'_> { pub fn run(&mut self, vcpu_list: Arc) -> Result, Error> { let pending_irq = vcpu_list.has_pending_irq(self.vcpuid); - if let Some(mmio_read) = self.pending_mmio_read.take() { - if mmio_read.srt < 31 { - let val = match mmio_read.len { - 1 => u8::from_le_bytes(self.mmio_buf[0..1].try_into().unwrap()) as u64, - 2 => u16::from_le_bytes(self.mmio_buf[0..2].try_into().unwrap()) as u64, - 4 => u32::from_le_bytes(self.mmio_buf[0..4].try_into().unwrap()) as u64, - 8 => u64::from_le_bytes(self.mmio_buf[0..8].try_into().unwrap()), - _ => panic!( - "unsupported mmio pa={} len={}", - mmio_read.addr, mmio_read.len - ), - }; - - self.write_reg(mmio_read.srt, val)?; - } + if let Some(mmio_read) = self.pending_mmio_read.take() + && mmio_read.srt < 31 + { + let val = match mmio_read.len { + 1 => u8::from_le_bytes(self.mmio_buf[0..1].try_into().unwrap()) as u64, + 2 => u16::from_le_bytes(self.mmio_buf[0..2].try_into().unwrap()) as u64, + 4 => u32::from_le_bytes(self.mmio_buf[0..4].try_into().unwrap()) as u64, + 8 => u64::from_le_bytes(self.mmio_buf[0..8].try_into().unwrap()), + _ => panic!( + "unsupported mmio pa={} len={}", + mmio_read.addr, mmio_read.len + ), + }; + + self.write_reg(mmio_read.srt, val)?; } if self.pending_advance_pc { diff --git a/src/kernel/Cargo.toml b/src/kernel/Cargo.toml index 044b326ef..34dde25dd 100644 --- a/src/kernel/Cargo.toml +++ b/src/kernel/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "krun-kernel" version = "0.1.0-1.18.0" -edition = "2021" +edition = "2024" description = "Kernel loading support for libkrun" license = "Apache-2.0" repository = "https://github.com/containers/libkrun" diff --git a/src/libkrun/Cargo.toml b/src/libkrun/Cargo.toml index 4e54bf99c..ad496dd9d 100644 --- a/src/libkrun/Cargo.toml +++ b/src/libkrun/Cargo.toml @@ -2,7 +2,7 @@ name = "libkrun" version = "1.18.0" authors = ["The libkrun Authors"] -edition = "2021" +edition = "2024" description = "A dynamic library providing Virtualization-based process isolation capabilities" build = "build.rs" license = "Apache-2.0" diff --git a/src/libkrun/build.rs b/src/libkrun/build.rs index 633dc9aff..ec8a28fdc 100644 --- a/src/libkrun/build.rs +++ b/src/libkrun/build.rs @@ -7,7 +7,9 @@ fn main() { #[cfg(target_os = "macos")] println!( "cargo:rustc-cdylib-link-arg=-Wl,-install_name,libkrun.{}.dylib,-compatibility_version,{}.0.0,-current_version,{}.{}.0", - std::env::var("CARGO_PKG_VERSION_MAJOR").unwrap(), std::env::var("CARGO_PKG_VERSION_MAJOR").unwrap(), - std::env::var("CARGO_PKG_VERSION_MAJOR").unwrap(), std::env::var("CARGO_PKG_VERSION_MINOR").unwrap() + std::env::var("CARGO_PKG_VERSION_MAJOR").unwrap(), + std::env::var("CARGO_PKG_VERSION_MAJOR").unwrap(), + std::env::var("CARGO_PKG_VERSION_MAJOR").unwrap(), + std::env::var("CARGO_PKG_VERSION_MINOR").unwrap() ); } diff --git a/src/libkrun/src/lib.rs b/src/libkrun/src/lib.rs index a7b7eee6a..36bfff870 100644 --- a/src/libkrun/src/lib.rs +++ b/src/libkrun/src/lib.rs @@ -3,13 +3,13 @@ extern crate log; use crossbeam_channel::unbounded; #[cfg(feature = "blk")] +use devices::virtio::CacheType; +#[cfg(feature = "blk")] use devices::virtio::block::{ImageType, SyncMode}; #[cfg(feature = "gpu")] use devices::virtio::gpu::display::DisplayInfo; #[cfg(feature = "net")] use devices::virtio::net::device::VirtioNetBackend; -#[cfg(feature = "blk")] -use devices::virtio::CacheType; use env_logger::{Env, Target}; #[cfg(feature = "gpu")] use krun_display::DisplayBackend; @@ -19,13 +19,13 @@ use once_cell::sync::Lazy; use polly::event_manager::EventManager; #[cfg(all(feature = "blk", not(feature = "tee")))] use rand::distr::{Alphanumeric, SampleString}; -use std::collections::hash_map::Entry; use std::collections::HashMap; +use std::collections::hash_map::Entry; use std::convert::TryInto; use std::env; #[cfg(target_os = "linux")] use std::ffi::CString; -use std::ffi::{c_void, CStr}; +use std::ffi::{CStr, c_void}; use std::fs::File; use std::io::IsTerminal; #[cfg(target_os = "linux")] @@ -33,9 +33,9 @@ use std::os::fd::AsRawFd; use std::os::fd::{BorrowedFd, FromRawFd, RawFd}; use std::path::PathBuf; use std::slice; -use std::sync::atomic::{AtomicI32, Ordering}; use std::sync::LazyLock; use std::sync::Mutex; +use std::sync::atomic::{AtomicI32, Ordering}; use utils::eventfd::EventFd; use vmm::resources::{ DefaultVirtioConsoleConfig, PortConfig, SerialConsoleConfig, TsiFlags, VirtioConsoleConfigMode, @@ -52,7 +52,7 @@ use vmm::vmm_config::fs::FsDeviceConfig; use vmm::vmm_config::kernel_bundle::KernelBundle; #[cfg(feature = "tee")] use vmm::vmm_config::kernel_bundle::{InitrdBundle, QbootBundle}; -use vmm::vmm_config::kernel_cmdline::{KernelCmdlineConfig, DEFAULT_KERNEL_CMDLINE}; +use vmm::vmm_config::kernel_cmdline::{DEFAULT_KERNEL_CMDLINE, KernelCmdlineConfig}; use vmm::vmm_config::machine_config::VmConfig; #[cfg(feature = "net")] use vmm::vmm_config::net::NetworkInterfaceConfig; @@ -62,7 +62,7 @@ use vmm::vmm_config::vsock::VsockDeviceConfig; use aws_nitro::enclave::NitroEnclave; #[cfg(feature = "gpu")] -use devices::virtio::display::{DisplayInfoEdid, PhysicalSize, MAX_DISPLAYS}; +use devices::virtio::display::{DisplayInfoEdid, MAX_DISPLAYS, PhysicalSize}; #[cfg(feature = "input")] use krun_input::{InputConfigBackend, InputEventProviderBackend}; @@ -309,7 +309,7 @@ impl ContextConfig { } fn add_vsock_port(&mut self, port: u32, filepath: PathBuf, listen: bool) { - if let Some(ref mut map) = &mut self.unix_ipc_port_map { + if let Some(map) = &mut self.unix_ipc_port_map { map.insert(port, (filepath, listen)); } else { let mut map: HashMap = HashMap::new(); @@ -443,7 +443,7 @@ fn log_level_to_filter_str(level: u32) -> &'static str { } } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_set_log_level(level: u32) -> i32 { let filter = log_level_to_filter_str(level); env_logger::Builder::from_env(Env::default().default_filter_or(filter)) @@ -471,9 +471,10 @@ mod log_defs { } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_init_log(target: RawFd, level: u32, style: u32, options: u32) -> i32 { - let target = match target { + unsafe { + let target = match target { ..-1 => return -libc::EINVAL, -1 => Target::default(), 0 /* stdin */ => return -libc::EINVAL, @@ -482,38 +483,39 @@ pub unsafe extern "C" fn krun_init_log(target: RawFd, level: u32, style: u32, op fd => Target::Pipe(Box::new(File::from_raw_fd(fd))), }; - let filter = log_level_to_filter_str(level); + let filter = log_level_to_filter_str(level); - let write_style = match style { - log_defs::KRUN_LOG_STYLE_AUTO => "auto", - log_defs::KRUN_LOG_STYLE_ALWAYS => "always", - log_defs::KRUN_LOG_STYLE_NEVER => "never", - _ => return -libc::EINVAL, - }; + let write_style = match style { + log_defs::KRUN_LOG_STYLE_AUTO => "auto", + log_defs::KRUN_LOG_STYLE_ALWAYS => "always", + log_defs::KRUN_LOG_STYLE_NEVER => "never", + _ => return -libc::EINVAL, + }; - let use_env = match options { - 0 => true, - log_defs::KRUN_LOG_OPTION_NO_ENV => false, - _ => return -libc::EINVAL, - }; + let use_env = match options { + 0 => true, + log_defs::KRUN_LOG_OPTION_NO_ENV => false, + _ => return -libc::EINVAL, + }; - let mut builder = if use_env { - env_logger::Builder::from_env( - Env::new() - .default_filter_or(filter) - .default_write_style_or(write_style), - ) - } else { - let mut builder = env_logger::Builder::new(); - builder.parse_filters(filter).parse_write_style(write_style); - builder - }; - builder.format_timestamp_micros().target(target).init(); + let mut builder = if use_env { + env_logger::Builder::from_env( + Env::new() + .default_filter_or(filter) + .default_write_style_or(write_style), + ) + } else { + let mut builder = env_logger::Builder::new(); + builder.parse_filters(filter).parse_write_style(write_style); + builder + }; + builder.format_timestamp_micros().target(target).init(); - KRUN_SUCCESS + KRUN_SUCCESS + } } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_create_ctx() -> i32 { let shutdown_efd = if cfg!(target_arch = "aarch64") && cfg!(target_os = "macos") { Some(EventFd::new(utils::eventfd::EFD_NONBLOCK).unwrap()) @@ -539,7 +541,7 @@ pub extern "C" fn krun_create_ctx() -> i32 { ctx_id } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_free_ctx(ctx_id: u32) -> i32 { match CTX_MAP.lock().unwrap().remove(&ctx_id) { Some(_) => KRUN_SUCCESS, @@ -547,7 +549,7 @@ pub extern "C" fn krun_free_ctx(ctx_id: u32) -> i32 { } } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_set_vm_config(ctx_id: u32, num_vcpus: u8, ram_mib: u32) -> i32 { let mem_size_mib: usize = match ram_mib.try_into() { Ok(size) => size, @@ -577,48 +579,50 @@ pub extern "C" fn krun_set_vm_config(ctx_id: u32, num_vcpus: u8, ram_mib: u32) - } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(not(feature = "tee"))] pub unsafe extern "C" fn krun_set_root(ctx_id: u32, c_root_path: *const c_char) -> i32 { - let root_path = match CStr::from_ptr(c_root_path).to_str() { - Ok(root) => root, - Err(_) => return -libc::EINVAL, - }; - - let fs_id = "/dev/root".to_string(); - let shared_dir = root_path.to_string(); + unsafe { + let root_path = match CStr::from_ptr(c_root_path).to_str() { + Ok(root) => root, + Err(_) => return -libc::EINVAL, + }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - cfg.vmr.add_fs_device(FsDeviceConfig { - fs_id, - shared_dir, - // Default to a conservative 512 MB window. - shm_size: Some(1 << 29), - allow_root_dir_delete: false, - read_only: false, - }); + let fs_id = "/dev/root".to_string(); + let shared_dir = root_path.to_string(); + + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + cfg.vmr.add_fs_device(FsDeviceConfig { + fs_id, + shared_dir, + // Default to a conservative 512 MB window. + shm_size: Some(1 << 29), + allow_root_dir_delete: false, + read_only: false, + }); + } + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, - } - KRUN_SUCCESS + KRUN_SUCCESS + } } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(not(feature = "tee"))] pub unsafe extern "C" fn krun_add_virtiofs( ctx_id: u32, c_tag: *const c_char, c_path: *const c_char, ) -> i32 { - krun_add_virtiofs3(ctx_id, c_tag, c_path, 0, false) + unsafe { krun_add_virtiofs3(ctx_id, c_tag, c_path, 0, false) } } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(not(feature = "tee"))] pub unsafe extern "C" fn krun_add_virtiofs2( ctx_id: u32, @@ -626,11 +630,11 @@ pub unsafe extern "C" fn krun_add_virtiofs2( c_path: *const c_char, shm_size: u64, ) -> i32 { - krun_add_virtiofs3(ctx_id, c_tag, c_path, shm_size, false) + unsafe { krun_add_virtiofs3(ctx_id, c_tag, c_path, shm_size, false) } } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(not(feature = "tee"))] pub unsafe extern "C" fn krun_add_virtiofs3( ctx_id: u32, @@ -639,47 +643,49 @@ pub unsafe extern "C" fn krun_add_virtiofs3( shm_size: u64, read_only: bool, ) -> i32 { - if c_tag.is_null() || c_path.is_null() { - return -libc::EINVAL; - } - - let tag = match CStr::from_ptr(c_tag).to_str() { - Ok(tag) => tag, - Err(_) => return -libc::EINVAL, - }; - let path = match CStr::from_ptr(c_path).to_str() { - Ok(path) => path, - Err(_) => return -libc::EINVAL, - }; + unsafe { + if c_tag.is_null() || c_path.is_null() { + return -libc::EINVAL; + } - let shm = if shm_size > 0 { - match shm_size.try_into() { - Ok(s) => Some(s), + let tag = match CStr::from_ptr(c_tag).to_str() { + Ok(tag) => tag, Err(_) => return -libc::EINVAL, - } - } else { - None - }; + }; + let path = match CStr::from_ptr(c_path).to_str() { + Ok(path) => path, + Err(_) => return -libc::EINVAL, + }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - cfg.vmr.add_fs_device(FsDeviceConfig { - fs_id: tag.to_string(), - shared_dir: path.to_string(), - shm_size: shm, - allow_root_dir_delete: false, - read_only, - }); + let shm = if shm_size > 0 { + match shm_size.try_into() { + Ok(s) => Some(s), + Err(_) => return -libc::EINVAL, + } + } else { + None + }; + + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + cfg.vmr.add_fs_device(FsDeviceConfig { + fs_id: tag.to_string(), + shared_dir: path.to_string(), + shm_size: shm, + allow_root_dir_delete: false, + read_only, + }); + } + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, - } - KRUN_SUCCESS + KRUN_SUCCESS + } } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(not(feature = "tee"))] pub unsafe extern "C" fn krun_set_mapped_volumes( _ctx_id: u32, @@ -689,7 +695,7 @@ pub unsafe extern "C" fn krun_set_mapped_volumes( } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(feature = "blk")] pub unsafe extern "C" fn krun_add_disk( ctx_id: u32, @@ -697,41 +703,43 @@ pub unsafe extern "C" fn krun_add_disk( c_disk_path: *const c_char, read_only: bool, ) -> i32 { - let disk_path = match CStr::from_ptr(c_disk_path).to_str() { - Ok(disk) => disk, - Err(_) => return -libc::EINVAL, - }; + unsafe { + let disk_path = match CStr::from_ptr(c_disk_path).to_str() { + Ok(disk) => disk, + Err(_) => return -libc::EINVAL, + }; - let block_id = match CStr::from_ptr(c_block_id).to_str() { - Ok(block_id) => block_id, - Err(_) => return -libc::EINVAL, - }; + let block_id = match CStr::from_ptr(c_block_id).to_str() { + Ok(block_id) => block_id, + Err(_) => return -libc::EINVAL, + }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - let block_device_config = BlockDeviceConfig { - block_id: block_id.to_string(), - cache_type: CacheType::auto(disk_path), - disk_image_path: disk_path.to_string(), - disk_image_format: ImageType::Raw, - is_disk_read_only: read_only, - direct_io: false, - #[cfg(not(target_os = "macos"))] - sync_mode: SyncMode::Full, - #[cfg(target_os = "macos")] - sync_mode: SyncMode::Relaxed, - }; - cfg.add_block_cfg(block_device_config); + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + let block_device_config = BlockDeviceConfig { + block_id: block_id.to_string(), + cache_type: CacheType::auto(disk_path), + disk_image_path: disk_path.to_string(), + disk_image_format: ImageType::Raw, + is_disk_read_only: read_only, + direct_io: false, + #[cfg(not(target_os = "macos"))] + sync_mode: SyncMode::Full, + #[cfg(target_os = "macos")] + sync_mode: SyncMode::Relaxed, + }; + cfg.add_block_cfg(block_device_config); + } + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, - } - KRUN_SUCCESS + KRUN_SUCCESS + } } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(feature = "blk")] pub unsafe extern "C" fn krun_add_disk2( ctx_id: u32, @@ -740,46 +748,48 @@ pub unsafe extern "C" fn krun_add_disk2( disk_format: u32, read_only: bool, ) -> i32 { - let disk_path = match CStr::from_ptr(c_disk_path).to_str() { - Ok(disk) => disk, - Err(_) => return -libc::EINVAL, - }; + unsafe { + let disk_path = match CStr::from_ptr(c_disk_path).to_str() { + Ok(disk) => disk, + Err(_) => return -libc::EINVAL, + }; - let block_id = match CStr::from_ptr(c_block_id).to_str() { - Ok(block_id) => block_id, - Err(_) => return -libc::EINVAL, - }; + let block_id = match CStr::from_ptr(c_block_id).to_str() { + Ok(block_id) => block_id, + Err(_) => return -libc::EINVAL, + }; - let format = match ImageType::try_from(disk_format) { - Ok(format) => format, - Err(_) => return -libc::EINVAL, - }; + let format = match ImageType::try_from(disk_format) { + Ok(format) => format, + Err(_) => return -libc::EINVAL, + }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - let block_device_config = BlockDeviceConfig { - block_id: block_id.to_string(), - cache_type: CacheType::auto(disk_path), - disk_image_path: disk_path.to_string(), - disk_image_format: format, - is_disk_read_only: read_only, - direct_io: false, - #[cfg(not(target_os = "macos"))] - sync_mode: SyncMode::Full, - #[cfg(target_os = "macos")] - sync_mode: SyncMode::Relaxed, - }; - cfg.add_block_cfg(block_device_config); + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + let block_device_config = BlockDeviceConfig { + block_id: block_id.to_string(), + cache_type: CacheType::auto(disk_path), + disk_image_path: disk_path.to_string(), + disk_image_format: format, + is_disk_read_only: read_only, + direct_io: false, + #[cfg(not(target_os = "macos"))] + sync_mode: SyncMode::Full, + #[cfg(target_os = "macos")] + sync_mode: SyncMode::Relaxed, + }; + cfg.add_block_cfg(block_device_config); + } + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, - } - KRUN_SUCCESS + KRUN_SUCCESS + } } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(feature = "blk")] pub unsafe extern "C" fn krun_add_disk3( ctx_id: u32, @@ -790,108 +800,114 @@ pub unsafe extern "C" fn krun_add_disk3( direct_io: bool, sync_mode: u32, ) -> i32 { - let disk_path = match CStr::from_ptr(c_disk_path).to_str() { - Ok(disk) => disk, - Err(_) => return -libc::EINVAL, - }; + unsafe { + let disk_path = match CStr::from_ptr(c_disk_path).to_str() { + Ok(disk) => disk, + Err(_) => return -libc::EINVAL, + }; - let block_id = match CStr::from_ptr(c_block_id).to_str() { - Ok(block_id) => block_id, - Err(_) => return -libc::EINVAL, - }; + let block_id = match CStr::from_ptr(c_block_id).to_str() { + Ok(block_id) => block_id, + Err(_) => return -libc::EINVAL, + }; - let format = match ImageType::try_from(disk_format) { - Ok(fmt) => fmt, - Err(_) => return -libc::EINVAL, - }; + let format = match ImageType::try_from(disk_format) { + Ok(fmt) => fmt, + Err(_) => return -libc::EINVAL, + }; - let sync_mode = match SyncMode::try_from(sync_mode) { - Ok(mode) => mode, - Err(_) => return -libc::EINVAL, - }; + let sync_mode = match SyncMode::try_from(sync_mode) { + Ok(mode) => mode, + Err(_) => return -libc::EINVAL, + }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - let block_device_config = BlockDeviceConfig { - block_id: block_id.to_string(), - cache_type: CacheType::auto(disk_path), - disk_image_path: disk_path.to_string(), - disk_image_format: format, - is_disk_read_only: read_only, - direct_io, - sync_mode, - }; - cfg.add_block_cfg(block_device_config); + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + let block_device_config = BlockDeviceConfig { + block_id: block_id.to_string(), + cache_type: CacheType::auto(disk_path), + disk_image_path: disk_path.to_string(), + disk_image_format: format, + is_disk_read_only: read_only, + direct_io, + sync_mode, + }; + cfg.add_block_cfg(block_device_config); + } + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, - } - KRUN_SUCCESS + KRUN_SUCCESS + } } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(feature = "blk")] pub unsafe extern "C" fn krun_set_root_disk(ctx_id: u32, c_disk_path: *const c_char) -> i32 { - let disk_path = match CStr::from_ptr(c_disk_path).to_str() { - Ok(disk) => disk, - Err(_) => return -libc::EINVAL, - }; + unsafe { + let disk_path = match CStr::from_ptr(c_disk_path).to_str() { + Ok(disk) => disk, + Err(_) => return -libc::EINVAL, + }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - let block_device_config = BlockDeviceConfig { - block_id: "root".to_string(), - cache_type: CacheType::auto(disk_path), - disk_image_path: disk_path.to_string(), - disk_image_format: ImageType::Raw, - is_disk_read_only: false, - direct_io: false, - #[cfg(not(target_os = "macos"))] - sync_mode: SyncMode::Full, - #[cfg(target_os = "macos")] - sync_mode: SyncMode::Relaxed, - }; - cfg.set_root_block_cfg(block_device_config); + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + let block_device_config = BlockDeviceConfig { + block_id: "root".to_string(), + cache_type: CacheType::auto(disk_path), + disk_image_path: disk_path.to_string(), + disk_image_format: ImageType::Raw, + is_disk_read_only: false, + direct_io: false, + #[cfg(not(target_os = "macos"))] + sync_mode: SyncMode::Full, + #[cfg(target_os = "macos")] + sync_mode: SyncMode::Relaxed, + }; + cfg.set_root_block_cfg(block_device_config); + } + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, - } - KRUN_SUCCESS + KRUN_SUCCESS + } } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(feature = "blk")] pub unsafe extern "C" fn krun_set_data_disk(ctx_id: u32, c_disk_path: *const c_char) -> i32 { - let disk_path = match CStr::from_ptr(c_disk_path).to_str() { - Ok(disk) => disk, - Err(_) => return -libc::EINVAL, - }; + unsafe { + let disk_path = match CStr::from_ptr(c_disk_path).to_str() { + Ok(disk) => disk, + Err(_) => return -libc::EINVAL, + }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - let block_device_config = BlockDeviceConfig { - block_id: "data".to_string(), - cache_type: CacheType::auto(disk_path), - disk_image_path: disk_path.to_string(), - disk_image_format: ImageType::Raw, - is_disk_read_only: false, - direct_io: false, - #[cfg(not(target_os = "macos"))] - sync_mode: SyncMode::Full, - #[cfg(target_os = "macos")] - sync_mode: SyncMode::Relaxed, - }; - cfg.set_data_block_cfg(block_device_config); + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + let block_device_config = BlockDeviceConfig { + block_id: "data".to_string(), + cache_type: CacheType::auto(disk_path), + disk_image_path: disk_path.to_string(), + disk_image_format: ImageType::Raw, + is_disk_read_only: false, + direct_io: false, + #[cfg(not(target_os = "macos"))] + sync_mode: SyncMode::Full, + #[cfg(target_os = "macos")] + sync_mode: SyncMode::Relaxed, + }; + cfg.set_data_block_cfg(block_device_config); + } + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, - } - KRUN_SUCCESS + KRUN_SUCCESS + } } /* @@ -946,7 +962,7 @@ const NET_ALL_FEATURES: u32 = NET_FEATURE_CSUM | NET_FEATURE_HOST_UFO; #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(feature = "net")] pub unsafe extern "C" fn krun_add_net_unixstream( ctx_id: u32, @@ -956,56 +972,58 @@ pub unsafe extern "C" fn krun_add_net_unixstream( features: u32, flags: u32, ) -> i32 { - let path = if !c_path.is_null() { - match CStr::from_ptr(c_path).to_str() { - Ok(path) => Some(PathBuf::from(path)), - Err(_) => None, - } - } else { - None - }; + unsafe { + let path = if !c_path.is_null() { + match CStr::from_ptr(c_path).to_str() { + Ok(path) => Some(PathBuf::from(path)), + Err(_) => None, + } + } else { + None + }; - if fd >= 0 && path.is_some() { - return -libc::EINVAL; - } - if fd < 0 && path.is_none() { - return -libc::EINVAL; - } - let backend = if let Some(path) = path { - VirtioNetBackend::UnixstreamPath(path) - } else { - VirtioNetBackend::UnixstreamFd(fd) - }; + if fd >= 0 && path.is_some() { + return -libc::EINVAL; + } + if fd < 0 && path.is_none() { + return -libc::EINVAL; + } + let backend = if let Some(path) = path { + VirtioNetBackend::UnixstreamPath(path) + } else { + VirtioNetBackend::UnixstreamFd(fd) + }; - let mac: [u8; 6] = match slice::from_raw_parts(c_mac, 6).try_into() { - Ok(m) => m, - Err(_) => return -libc::EINVAL, - }; + let mac: [u8; 6] = match slice::from_raw_parts(c_mac, 6).try_into() { + Ok(m) => m, + Err(_) => return -libc::EINVAL, + }; - if (flags & !NET_FLAG_DHCP_CLIENT) != 0 { - return -libc::EINVAL; - } - let enable_dhcp_client: bool = flags & NET_FLAG_DHCP_CLIENT != 0; + if (flags & !NET_FLAG_DHCP_CLIENT) != 0 { + return -libc::EINVAL; + } + let enable_dhcp_client: bool = flags & NET_FLAG_DHCP_CLIENT != 0; - if (features & !NET_ALL_FEATURES) != 0 { - return -libc::EINVAL; - } + if (features & !NET_ALL_FEATURES) != 0 { + return -libc::EINVAL; + } - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - create_virtio_net(cfg, backend, mac, features); - if enable_dhcp_client { - cfg.vmr.dhcp_client = true; + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + create_virtio_net(cfg, backend, mac, features); + if enable_dhcp_client { + cfg.vmr.dhcp_client = true; + } } + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, + KRUN_SUCCESS } - KRUN_SUCCESS } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(feature = "net")] pub unsafe extern "C" fn krun_add_net_unixgram( ctx_id: u32, @@ -1015,58 +1033,60 @@ pub unsafe extern "C" fn krun_add_net_unixgram( features: u32, flags: u32, ) -> i32 { - let path = if !c_path.is_null() { - match CStr::from_ptr(c_path).to_str() { - Ok(path) => Some(PathBuf::from(path)), - Err(_) => None, - } - } else { - None - }; + unsafe { + let path = if !c_path.is_null() { + match CStr::from_ptr(c_path).to_str() { + Ok(path) => Some(PathBuf::from(path)), + Err(_) => None, + } + } else { + None + }; - if fd >= 0 && path.is_some() { - return -libc::EINVAL; - } - if fd < 0 && path.is_none() { - return -libc::EINVAL; - } + if fd >= 0 && path.is_some() { + return -libc::EINVAL; + } + if fd < 0 && path.is_none() { + return -libc::EINVAL; + } - let mac: [u8; 6] = match slice::from_raw_parts(c_mac, 6).try_into() { - Ok(m) => m, - Err(_) => return -libc::EINVAL, - }; + let mac: [u8; 6] = match slice::from_raw_parts(c_mac, 6).try_into() { + Ok(m) => m, + Err(_) => return -libc::EINVAL, + }; - if (features & !NET_ALL_FEATURES) != 0 { - return -libc::EINVAL; - } + if (features & !NET_ALL_FEATURES) != 0 { + return -libc::EINVAL; + } - if (flags & !NET_FLAG_ALL) != 0 { - return -libc::EINVAL; - } - let send_vfkit_magic: bool = flags & NET_FLAG_VFKIT != 0; - let enable_dhcp_client: bool = flags & NET_FLAG_DHCP_CLIENT != 0; + if (flags & !NET_FLAG_ALL) != 0 { + return -libc::EINVAL; + } + let send_vfkit_magic: bool = flags & NET_FLAG_VFKIT != 0; + let enable_dhcp_client: bool = flags & NET_FLAG_DHCP_CLIENT != 0; - let backend = if let Some(path) = path { - VirtioNetBackend::UnixgramPath(path, send_vfkit_magic) - } else { - VirtioNetBackend::UnixgramFd(fd) - }; + let backend = if let Some(path) = path { + VirtioNetBackend::UnixgramPath(path, send_vfkit_magic) + } else { + VirtioNetBackend::UnixgramFd(fd) + }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - create_virtio_net(cfg, backend, mac, features); - if enable_dhcp_client { - cfg.vmr.dhcp_client = true; + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + create_virtio_net(cfg, backend, mac, features); + if enable_dhcp_client { + cfg.vmr.dhcp_client = true; + } } + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, + KRUN_SUCCESS } - KRUN_SUCCESS } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(all(target_os = "linux", feature = "net"))] pub unsafe extern "C" fn krun_add_net_tap( ctx_id: u32, @@ -1075,50 +1095,54 @@ pub unsafe extern "C" fn krun_add_net_tap( features: u32, flags: u32, ) -> i32 { - let tap_name = match CStr::from_ptr(c_tap_name).to_str() { - Ok(tap_name) => tap_name.to_string(), - Err(e) => { - debug!("Error parsing tap_name: {e:?}"); - return -libc::EINVAL; - } - }; + unsafe { + let tap_name = match CStr::from_ptr(c_tap_name).to_str() { + Ok(tap_name) => tap_name.to_string(), + Err(e) => { + debug!("Error parsing tap_name: {e:?}"); + return -libc::EINVAL; + } + }; - let mac: [u8; 6] = match slice::from_raw_parts(c_mac, 6).try_into() { - Ok(m) => m, - Err(_) => return -libc::EINVAL, - }; + let mac: [u8; 6] = match slice::from_raw_parts(c_mac, 6).try_into() { + Ok(m) => m, + Err(_) => return -libc::EINVAL, + }; - if (features & !NET_ALL_FEATURES) != 0 { - return -libc::EINVAL; - } + if (features & !NET_ALL_FEATURES) != 0 { + return -libc::EINVAL; + } - if features & (NET_FEATURE_GUEST_TSO4 | NET_FEATURE_GUEST_TSO6 | NET_FEATURE_GUEST_UFO) != 0 - && features & NET_FEATURE_GUEST_CSUM == 0 - { - debug!("Network tap backend requires GUEST_CSUM to be requested if any of GUEST_TSO4, GUEST_TSO6 and/or GUEST_UFO are required"); - return -libc::EINVAL; - } + if features & (NET_FEATURE_GUEST_TSO4 | NET_FEATURE_GUEST_TSO6 | NET_FEATURE_GUEST_UFO) != 0 + && features & NET_FEATURE_GUEST_CSUM == 0 + { + debug!( + "Network tap backend requires GUEST_CSUM to be requested if any of GUEST_TSO4, GUEST_TSO6 and/or GUEST_UFO are required" + ); + return -libc::EINVAL; + } - if (flags & !NET_FLAG_DHCP_CLIENT) != 0 { - return -libc::EINVAL; - } - let enable_dhcp_client: bool = flags & NET_FLAG_DHCP_CLIENT != 0; + if (flags & !NET_FLAG_DHCP_CLIENT) != 0 { + return -libc::EINVAL; + } + let enable_dhcp_client: bool = flags & NET_FLAG_DHCP_CLIENT != 0; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - create_virtio_net(cfg, VirtioNetBackend::Tap(tap_name), mac, features); - if enable_dhcp_client { - cfg.vmr.dhcp_client = true; + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + create_virtio_net(cfg, VirtioNetBackend::Tap(tap_name), mac, features); + if enable_dhcp_client { + cfg.vmr.dhcp_client = true; + } } + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, + KRUN_SUCCESS } - KRUN_SUCCESS } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(all(not(target_os = "linux"), feature = "net"))] pub unsafe extern "C" fn krun_add_net_tap( _ctx_id: u32, @@ -1131,7 +1155,7 @@ pub unsafe extern "C" fn krun_add_net_tap( } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(feature = "net")] pub unsafe extern "C" fn krun_set_passt_fd(ctx_id: u32, fd: c_int) -> i32 { if fd < 0 { @@ -1153,333 +1177,353 @@ pub unsafe extern "C" fn krun_set_passt_fd(ctx_id: u32, fd: c_int) -> i32 { } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(feature = "net")] pub unsafe extern "C" fn krun_set_gvproxy_path(ctx_id: u32, c_path: *const c_char) -> i32 { - let path_str = match CStr::from_ptr(c_path).to_str() { - Ok(path) => path, - Err(e) => { - debug!("Error parsing gvproxy_path: {e:?}"); - return -libc::EINVAL; - } - }; + unsafe { + let path_str = match CStr::from_ptr(c_path).to_str() { + Ok(path) => path, + Err(e) => { + debug!("Error parsing gvproxy_path: {e:?}"); + return -libc::EINVAL; + } + }; - let path = PathBuf::from(path_str); + let path = PathBuf::from(path_str); - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - // The legacy interface only supports a single network interface. - if cfg.net_index != 0 { - return -libc::EINVAL; + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + // The legacy interface only supports a single network interface. + if cfg.net_index != 0 { + return -libc::EINVAL; + } + cfg.legacy_net_cfg = Some(LegacyNetworkConfig::VirtioNetGvproxy(path)); } - cfg.legacy_net_cfg = Some(LegacyNetworkConfig::VirtioNetGvproxy(path)); + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, + KRUN_SUCCESS } - KRUN_SUCCESS } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(feature = "net")] pub unsafe extern "C" fn krun_set_net_mac(ctx_id: u32, c_mac: *const u8) -> i32 { - let mac: [u8; 6] = match slice::from_raw_parts(c_mac, 6).try_into() { - Ok(m) => m, - Err(_) => return -libc::EINVAL, - }; + unsafe { + let mac: [u8; 6] = match slice::from_raw_parts(c_mac, 6).try_into() { + Ok(m) => m, + Err(_) => return -libc::EINVAL, + }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - cfg.set_net_mac(mac); + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + cfg.set_net_mac(mac); + } + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, + KRUN_SUCCESS } - KRUN_SUCCESS } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_set_port_map(ctx_id: u32, c_port_map: *const *const c_char) -> i32 { - let mut port_map = HashMap::new(); - let port_map_array: &[*const c_char] = slice::from_raw_parts(c_port_map, MAX_ARGS); - for item in port_map_array.iter().take(MAX_ARGS) { - if item.is_null() { - break; - } else { - let s = match CStr::from_ptr(*item).to_str() { - Ok(s) => s, - Err(_) => return -libc::EINVAL, - }; - let port_tuple: Vec<&str> = s.split(':').collect(); - if port_tuple.len() != 2 { - return -libc::EINVAL; - } - let host_port: u16 = match port_tuple[0].parse() { - Ok(p) => p, - Err(_) => return -libc::EINVAL, - }; - let guest_port: u16 = match port_tuple[1].parse() { - Ok(p) => p, - Err(_) => return -libc::EINVAL, - }; + unsafe { + let mut port_map = HashMap::new(); + let port_map_array: &[*const c_char] = slice::from_raw_parts(c_port_map, MAX_ARGS); + for item in port_map_array.iter().take(MAX_ARGS) { + if item.is_null() { + break; + } else { + let s = match CStr::from_ptr(*item).to_str() { + Ok(s) => s, + Err(_) => return -libc::EINVAL, + }; + let port_tuple: Vec<&str> = s.split(':').collect(); + if port_tuple.len() != 2 { + return -libc::EINVAL; + } + let host_port: u16 = match port_tuple[0].parse() { + Ok(p) => p, + Err(_) => return -libc::EINVAL, + }; + let guest_port: u16 = match port_tuple[1].parse() { + Ok(p) => p, + Err(_) => return -libc::EINVAL, + }; - if port_map.contains_key(&guest_port) { - return -libc::EINVAL; - } - for hp in port_map.values() { - if *hp == host_port { + if port_map.contains_key(&guest_port) { return -libc::EINVAL; } + for hp in port_map.values() { + if *hp == host_port { + return -libc::EINVAL; + } + } + port_map.insert(guest_port, host_port); } - port_map.insert(guest_port, host_port); } - } - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - if cfg.vsock_config == VsockConfig::Disabled { - return -libc::ENODEV; - } - if cfg.set_port_map(port_map).is_err() { - return -libc::EINVAL; + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + if cfg.vsock_config == VsockConfig::Disabled { + return -libc::ENODEV; + } + if cfg.set_port_map(port_map).is_err() { + return -libc::EINVAL; + } } + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, - } - KRUN_SUCCESS + KRUN_SUCCESS + } } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_set_rlimits(ctx_id: u32, c_rlimits: *const *const c_char) -> i32 { - let rlimits = if c_rlimits.is_null() { - return -libc::EINVAL; - } else { - let mut strvec = Vec::new(); + unsafe { + let rlimits = if c_rlimits.is_null() { + return -libc::EINVAL; + } else { + let mut strvec = Vec::new(); - let array: &[*const c_char] = slice::from_raw_parts(c_rlimits, MAX_ARGS); - for item in array.iter().take(MAX_ARGS) { - if item.is_null() { - break; - } else { - let s = match CStr::from_ptr(*item).to_str() { - Ok(s) => s, - Err(_) => return -libc::EINVAL, - }; - strvec.push(s); + let array: &[*const c_char] = slice::from_raw_parts(c_rlimits, MAX_ARGS); + for item in array.iter().take(MAX_ARGS) { + if item.is_null() { + break; + } else { + let s = match CStr::from_ptr(*item).to_str() { + Ok(s) => s, + Err(_) => return -libc::EINVAL, + }; + strvec.push(s); + } } - } - format!("\"{}\"", strvec.join(",")) - }; + format!("\"{}\"", strvec.join(",")) + }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - ctx_cfg.get_mut().set_rlimits(rlimits); + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + ctx_cfg.get_mut().set_rlimits(rlimits); + } + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, - } - KRUN_SUCCESS + KRUN_SUCCESS + } } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_set_workdir(ctx_id: u32, c_workdir_path: *const c_char) -> i32 { - let workdir_path = match CStr::from_ptr(c_workdir_path).to_str() { - Ok(workdir) => workdir, - Err(_) => return -libc::EINVAL, - }; + unsafe { + let workdir_path = match CStr::from_ptr(c_workdir_path).to_str() { + Ok(workdir) => workdir, + Err(_) => return -libc::EINVAL, + }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - ctx_cfg.get_mut().set_workdir(workdir_path.to_string()); + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + ctx_cfg.get_mut().set_workdir(workdir_path.to_string()); + } + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, - } - KRUN_SUCCESS + KRUN_SUCCESS + } } unsafe fn collapse_str_array(array: &[*const c_char]) -> Result { - let mut strvec = Vec::new(); + unsafe { + let mut strvec = Vec::new(); - for item in array.iter().take(MAX_ARGS) { - if item.is_null() { - break; - } else { - let s = CStr::from_ptr(*item).to_str()?; - strvec.push(format!("\"{s}\"")); + for item in array.iter().take(MAX_ARGS) { + if item.is_null() { + break; + } else { + let s = CStr::from_ptr(*item).to_str()?; + strvec.push(format!("\"{s}\"")); + } } - } - Ok(strvec.join(" ")) + Ok(strvec.join(" ")) + } } #[allow(clippy::format_collect)] #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_set_exec( ctx_id: u32, c_exec_path: *const c_char, c_argv: *const *const c_char, c_envp: *const *const c_char, ) -> i32 { - let exec_path = match CStr::from_ptr(c_exec_path).to_str() { - Ok(path) => path, - Err(e) => { - debug!("Error parsing exec_path: {e:?}"); - return -libc::EINVAL; - } - }; - - let args = if !c_argv.is_null() { - let argv_array: &[*const c_char] = slice::from_raw_parts(c_argv, MAX_ARGS); - match collapse_str_array(argv_array) { - Ok(s) => s, + unsafe { + let exec_path = match CStr::from_ptr(c_exec_path).to_str() { + Ok(path) => path, Err(e) => { - debug!("Error parsing args: {e:?}"); + debug!("Error parsing exec_path: {e:?}"); return -libc::EINVAL; } - } - } else { - "".to_string() - }; + }; - let env = if !c_envp.is_null() { - let envp_array: &[*const c_char] = slice::from_raw_parts(c_envp, MAX_ARGS); - match collapse_str_array(envp_array) { - Ok(s) => s, - Err(e) => { - debug!("Error parsing args: {e:?}"); - return -libc::EINVAL; + let args = if !c_argv.is_null() { + let argv_array: &[*const c_char] = slice::from_raw_parts(c_argv, MAX_ARGS); + match collapse_str_array(argv_array) { + Ok(s) => s, + Err(e) => { + debug!("Error parsing args: {e:?}"); + return -libc::EINVAL; + } } - } - } else { - env::vars() - .map(|(key, value)| format!(" {key}=\"{value}\"")) - .collect() - }; + } else { + "".to_string() + }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - cfg.set_exec_path(exec_path.to_string()); - cfg.set_env(env); - cfg.set_args(args); + let env = if !c_envp.is_null() { + let envp_array: &[*const c_char] = slice::from_raw_parts(c_envp, MAX_ARGS); + match collapse_str_array(envp_array) { + Ok(s) => s, + Err(e) => { + debug!("Error parsing args: {e:?}"); + return -libc::EINVAL; + } + } + } else { + env::vars() + .map(|(key, value)| format!(" {key}=\"{value}\"")) + .collect() + }; + + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + cfg.set_exec_path(exec_path.to_string()); + cfg.set_env(env); + cfg.set_args(args); + } + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, - } - KRUN_SUCCESS + KRUN_SUCCESS + } } -#[allow(clippy::format_collect)] -#[allow(clippy::missing_safety_doc)] -#[no_mangle] -pub unsafe extern "C" fn krun_set_env(ctx_id: u32, c_envp: *const *const c_char) -> i32 { - let env = if !c_envp.is_null() { - let envp_array: &[*const c_char] = slice::from_raw_parts(c_envp, MAX_ARGS); - match collapse_str_array(envp_array) { - Ok(s) => s, - Err(e) => { - debug!("Error parsing args: {e:?}"); - return -libc::EINVAL; +#[allow(clippy::format_collect)] +#[allow(clippy::missing_safety_doc)] +#[unsafe(no_mangle)] +pub unsafe extern "C" fn krun_set_env(ctx_id: u32, c_envp: *const *const c_char) -> i32 { + unsafe { + let env = if !c_envp.is_null() { + let envp_array: &[*const c_char] = slice::from_raw_parts(c_envp, MAX_ARGS); + match collapse_str_array(envp_array) { + Ok(s) => s, + Err(e) => { + debug!("Error parsing args: {e:?}"); + return -libc::EINVAL; + } + } + } else { + env::vars() + .map(|(key, value)| format!(" {key}=\"{value}\"")) + .collect() + }; + + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + cfg.set_env(env); } + Entry::Vacant(_) => return -libc::ENOENT, } - } else { - env::vars() - .map(|(key, value)| format!(" {key}=\"{value}\"")) - .collect() - }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - cfg.set_env(env); - } - Entry::Vacant(_) => return -libc::ENOENT, + KRUN_SUCCESS } - - KRUN_SUCCESS } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(feature = "tee")] pub unsafe extern "C" fn krun_set_tee_config_file(ctx_id: u32, c_filepath: *const c_char) -> i32 { - let filepath = match CStr::from_ptr(c_filepath).to_str() { - Ok(f) => f, - Err(_) => return -libc::EINVAL, - }; + unsafe { + let filepath = match CStr::from_ptr(c_filepath).to_str() { + Ok(f) => f, + Err(_) => return -libc::EINVAL, + }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - cfg.set_tee_config_file(PathBuf::from(filepath.to_string())); + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + cfg.set_tee_config_file(PathBuf::from(filepath.to_string())); + } + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, - } - KRUN_SUCCESS + KRUN_SUCCESS + } } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_add_vsock_port( ctx_id: u32, port: u32, c_filepath: *const c_char, ) -> i32 { - krun_add_vsock_port2(ctx_id, port, c_filepath, false) + unsafe { krun_add_vsock_port2(ctx_id, port, c_filepath, false) } } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_add_vsock_port2( ctx_id: u32, port: u32, c_filepath: *const c_char, listen: bool, ) -> i32 { - #[cfg(feature = "aws-nitro")] - if listen { - return -libc::EINVAL; - } - - let filepath = match CStr::from_ptr(c_filepath).to_str() { - Ok(f) => PathBuf::from(f.to_string()), - Err(_) => return -libc::EINVAL, - }; + unsafe { + #[cfg(feature = "aws-nitro")] + if listen { + return -libc::EINVAL; + } - if listen { - match filepath.try_exists() { - Ok(true) => return -libc::EEXIST, + let filepath = match CStr::from_ptr(c_filepath).to_str() { + Ok(f) => PathBuf::from(f.to_string()), Err(_) => return -libc::EINVAL, - _ => {} + }; + + if listen { + match filepath.try_exists() { + Ok(true) => return -libc::EEXIST, + Err(_) => return -libc::EINVAL, + _ => {} + } } - } - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - if cfg.vsock_config == VsockConfig::Disabled { - return -libc::ENODEV; + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + if cfg.vsock_config == VsockConfig::Disabled { + return -libc::ENODEV; + } + cfg.add_vsock_port(port, filepath, listen); } - cfg.add_vsock_port(port, filepath, listen); + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, - } - KRUN_SUCCESS + KRUN_SUCCESS + } } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_set_gpu_options(ctx_id: u32, virgl_flags: u32) -> i32 { match CTX_MAP.lock().unwrap().entry(ctx_id) { Entry::Occupied(mut ctx_cfg) => { @@ -1493,7 +1537,7 @@ pub unsafe extern "C" fn krun_set_gpu_options(ctx_id: u32, virgl_flags: u32) -> } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_set_gpu_options2( ctx_id: u32, virgl_flags: u32, @@ -1513,7 +1557,7 @@ pub unsafe extern "C" fn krun_set_gpu_options2( #[cfg(not(feature = "gpu"))] #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_set_display_backend( _ctx_id: u32, _features: u32, @@ -1525,7 +1569,7 @@ pub extern "C" fn krun_set_display_backend( #[cfg(feature = "gpu")] #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_set_display_backend( ctx_id: u32, vtable: *const c_void, @@ -1557,7 +1601,7 @@ pub extern "C" fn krun_set_display_backend( #[cfg(not(feature = "input"))] #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_add_input_device( _ctx_id: u32, _config_backend: *const c_void, @@ -1570,7 +1614,7 @@ pub extern "C" fn krun_add_input_device( #[cfg(feature = "input")] #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_add_input_device_fd(ctx_id: u32, input_fd: i32) -> i32 { use devices::virtio::input::passthrough::PassthroughInputBackend; use krun_input::{IntoInputConfig, IntoInputEvents}; @@ -1600,7 +1644,7 @@ pub extern "C" fn krun_add_input_device_fd(ctx_id: u32, input_fd: i32) -> i32 { #[cfg(feature = "input")] #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_add_input_device( ctx_id: u32, config_backend: *const InputConfigBackend<'static>, @@ -1635,14 +1679,14 @@ pub unsafe extern "C" fn krun_add_input_device( #[cfg(not(feature = "input"))] #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_add_input_device_fd(_ctx_id: u32, _input_fd: i32) -> i32 { -libc::ENOTSUP } #[cfg(feature = "gpu")] #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_add_display(ctx_id: u32, width: u32, height: u32) -> i32 { match CTX_MAP.lock().unwrap().entry(ctx_id) { Entry::Occupied(mut ctx_cfg) => { @@ -1660,13 +1704,13 @@ pub unsafe extern "C" fn krun_add_display(ctx_id: u32, width: u32, height: u32) #[cfg(not(feature = "gpu"))] #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_add_display(_ctx_id: u32, _width: u32, _height: u32) -> i32 { -libc::ENOTSUP } #[cfg(feature = "gpu")] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_display_set_refresh_rate( ctx_id: u32, display_id: u32, @@ -1687,7 +1731,7 @@ pub extern "C" fn krun_display_set_refresh_rate( } #[cfg(not(feature = "gpu"))] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_display_set_refresh_rate( _ctx_id: u32, _display_id: u32, @@ -1697,7 +1741,7 @@ pub extern "C" fn krun_display_set_refresh_rate( } #[cfg(feature = "gpu")] -#[no_mangle] +#[unsafe(no_mangle)] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn krun_display_set_edid( ctx_id: u32, @@ -1722,7 +1766,7 @@ pub unsafe extern "C" fn krun_display_set_edid( } #[cfg(not(feature = "gpu"))] -#[no_mangle] +#[unsafe(no_mangle)] #[allow(clippy::missing_safety_doc)] pub unsafe extern "C" fn krun_display_set_edid( _ctx_id: u32, @@ -1734,7 +1778,7 @@ pub unsafe extern "C" fn krun_display_set_edid( } #[cfg(feature = "gpu")] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_display_set_physical_size( ctx_id: u32, display_id: u32, @@ -1754,7 +1798,7 @@ pub extern "C" fn krun_display_set_physical_size( } #[cfg(not(feature = "gpu"))] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_display_set_physical_size( _ctx_id: u32, _display_id: u32, @@ -1765,7 +1809,7 @@ pub extern "C" fn krun_display_set_physical_size( } #[cfg(feature = "gpu")] -#[no_mangle] +#[unsafe(no_mangle)] #[allow(clippy::missing_safety_doc)] pub extern "C" fn krun_display_set_dpi(ctx_id: u32, display_id: u32, dpi: u32) -> i32 { with_cfg(ctx_id, |cfg| { @@ -1781,13 +1825,13 @@ pub extern "C" fn krun_display_set_dpi(ctx_id: u32, display_id: u32, dpi: u32) - } #[cfg(not(feature = "gpu"))] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_display_set_dpi(_ctx_id: u32, _display_id: u32, _dpi: u32) -> i32 { -libc::ENOTSUP } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(feature = "vhost-user")] pub unsafe extern "C" fn krun_add_vhost_user_device( ctx_id: u32, @@ -1799,7 +1843,7 @@ pub unsafe extern "C" fn krun_add_vhost_user_device( ) -> i32 { use vmm::resources::VhostUserDeviceConfig; - let socket_path_str = match CStr::from_ptr(socket_path).to_str() { + let socket_path_str = match unsafe { CStr::from_ptr(socket_path) }.to_str() { Ok(s) => s, Err(_) => return -libc::EINVAL, }; @@ -1811,7 +1855,7 @@ pub unsafe extern "C" fn krun_add_vhost_user_device( let name_opt = if name.is_null() { None } else { - match CStr::from_ptr(name).to_str() { + match unsafe { CStr::from_ptr(name) }.to_str() { Ok(s) if !s.is_empty() => Some(s.to_string()), _ => None, } @@ -1824,7 +1868,7 @@ pub unsafe extern "C" fn krun_add_vhost_user_device( let mut sizes = Vec::new(); let mut i = 0; loop { - let size = *queue_sizes.add(i); + let size = unsafe { *queue_sizes.add(i) }; if size == 0 { break; } @@ -1838,7 +1882,7 @@ pub unsafe extern "C" fn krun_add_vhost_user_device( } sizes } else { - std::slice::from_raw_parts(queue_sizes, num_queues as usize).to_vec() + unsafe { std::slice::from_raw_parts(queue_sizes, num_queues as usize) }.to_vec() }; match CTX_MAP.lock().unwrap().entry(ctx_id) { @@ -1858,7 +1902,7 @@ pub unsafe extern "C" fn krun_add_vhost_user_device( } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] #[cfg(not(feature = "vhost-user"))] pub unsafe extern "C" fn krun_add_vhost_user_device( _ctx_id: u32, @@ -1872,7 +1916,7 @@ pub unsafe extern "C" fn krun_add_vhost_user_device( } #[allow(unused_assignments)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_get_shutdown_eventfd(ctx_id: u32) -> i32 { match CTX_MAP.lock().unwrap().entry(ctx_id) { Entry::Occupied(mut ctx_cfg) => { @@ -1891,29 +1935,31 @@ pub extern "C" fn krun_get_shutdown_eventfd(ctx_id: u32) -> i32 { } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_set_console_output(ctx_id: u32, c_filepath: *const c_char) -> i32 { - let filepath = match CStr::from_ptr(c_filepath).to_str() { - Ok(f) => f, - Err(_) => return -libc::EINVAL, - }; + unsafe { + let filepath = match CStr::from_ptr(c_filepath).to_str() { + Ok(f) => f, + Err(_) => return -libc::EINVAL, + }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - if cfg.console_output.is_some() { - -libc::EINVAL - } else { - cfg.console_output = Some(PathBuf::from(filepath.to_string())); - KRUN_SUCCESS + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + if cfg.console_output.is_some() { + -libc::EINVAL + } else { + cfg.console_output = Some(PathBuf::from(filepath.to_string())); + KRUN_SUCCESS + } } + Entry::Vacant(_) => -libc::ENOENT, } - Entry::Vacant(_) => -libc::ENOENT, } } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_set_nested_virt(ctx_id: u32, enabled: bool) -> i32 { match CTX_MAP.lock().unwrap().entry(ctx_id) { Entry::Occupied(mut ctx_cfg) => { @@ -1926,7 +1972,7 @@ pub unsafe extern "C" fn krun_set_nested_virt(ctx_id: u32, enabled: bool) -> i32 } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_check_nested_virt() -> i32 { #[cfg(target_os = "macos")] match hvf::check_nested_virt() { @@ -1966,7 +2012,7 @@ const KRUN_FEATURE_INTEL_TDX: u64 = 8; const KRUN_FEATURE_AWS_NITRO: u64 = 9; const KRUN_FEATURE_VIRGL_RESOURCE_MAP2: u64 = 10; -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_has_feature(feature: u64) -> c_int { let supported = match feature { KRUN_FEATURE_NET => cfg!(feature = "net"), @@ -1989,11 +2035,11 @@ pub extern "C" fn krun_has_feature(feature: u64) -> c_int { /// Returns the maximum number of vCPUs that can be created by this hypervisor, /// or a negative error code on failure. #[cfg(any(target_os = "macos", target_os = "linux"))] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_get_max_vcpus() -> i32 { #[cfg(target_os = "macos")] { - use hvf::bindings::{hv_vm_get_max_vcpu_count, HV_SUCCESS}; + use hvf::bindings::{HV_SUCCESS, hv_vm_get_max_vcpu_count}; let mut max_vcpu_count: u32 = 0; let ret = unsafe { hv_vm_get_max_vcpu_count(&mut max_vcpu_count as *mut u32) }; if ret == HV_SUCCESS { @@ -2018,7 +2064,7 @@ pub extern "C" fn krun_get_max_vcpus() -> i32 { } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_split_irqchip(ctx_id: u32, enable: bool) -> i32 { if enable && !cfg!(target_arch = "x86_64") { return -libc::EINVAL; @@ -2034,35 +2080,37 @@ pub extern "C" fn krun_split_irqchip(ctx_id: u32, enable: bool) -> i32 { } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_set_smbios_oem_strings( ctx_id: u32, oem_strings: *const *const c_char, ) -> i32 { - if oem_strings.is_null() { - return -libc::EINVAL; - } + unsafe { + if oem_strings.is_null() { + return -libc::EINVAL; + } - let cstr_ptr_slice = slice::from_raw_parts(oem_strings, MAX_ARGS); + let cstr_ptr_slice = slice::from_raw_parts(oem_strings, MAX_ARGS); - let mut oem_strings = Vec::new(); + let mut oem_strings = Vec::new(); - for cstr_ptr in cstr_ptr_slice.iter().take_while(|p| !p.is_null()) { - let Ok(s) = CStr::from_ptr(*cstr_ptr).to_str() else { - return -libc::EINVAL; - }; - oem_strings.push(s.to_string()); - } + for cstr_ptr in cstr_ptr_slice.iter().take_while(|p| !p.is_null()) { + let Ok(s) = CStr::from_ptr(*cstr_ptr).to_str() else { + return -libc::EINVAL; + }; + oem_strings.push(s.to_string()); + } - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - ctx_cfg.get_mut().vmr.smbios_oem_strings = - (!oem_strings.is_empty()).then_some(oem_strings) + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + ctx_cfg.get_mut().vmr.smbios_oem_strings = + (!oem_strings.is_empty()).then_some(oem_strings) + } + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, - } - KRUN_SUCCESS + KRUN_SUCCESS + } } #[cfg(feature = "net")] @@ -2134,7 +2182,7 @@ fn map_kernel(ctx_id: u32, kernel_path: &PathBuf) -> i32 { #[cfg(feature = "tee")] #[allow(clippy::format_collect)] #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_set_kernel(_ctx_id: u32, _c_kernel_path: *const c_char) -> i32 { -libc::EOPNOTSUPP } @@ -2142,7 +2190,7 @@ pub unsafe extern "C" fn krun_set_kernel(_ctx_id: u32, _c_kernel_path: *const c_ #[cfg(not(feature = "tee"))] #[allow(clippy::format_collect)] #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_set_kernel( ctx_id: u32, c_kernel_path: *const c_char, @@ -2150,102 +2198,110 @@ pub unsafe extern "C" fn krun_set_kernel( c_initramfs_path: *const c_char, c_cmdline: *const c_char, ) -> i32 { - let path = match CStr::from_ptr(c_kernel_path).to_str() { - Ok(path) => PathBuf::from(path), - Err(e) => { - error!("Error parsing kernel_path: {e:?}"); - return -libc::EINVAL; - } - }; - - let format = match kernel_format { - // For raw kernels in x86_64, we map the kernel into the - // process and treat it as a bundled kernel. - #[cfg(all(target_arch = "x86_64", not(feature = "tee")))] - 0 => return map_kernel(ctx_id, &path), - #[cfg(target_arch = "aarch64")] - 0 => KernelFormat::Raw, - 1 => KernelFormat::Elf, - 2 => KernelFormat::PeGz, - 3 => KernelFormat::ImageBz2, - 4 => KernelFormat::ImageGz, - 5 => KernelFormat::ImageZstd, - _ => { - return -libc::EINVAL; - } - }; - - let (initramfs_path, initramfs_size) = if !c_initramfs_path.is_null() { - match CStr::from_ptr(c_initramfs_path).to_str() { - Ok(path) => { - let path = PathBuf::from(path); - let size = match std::fs::metadata(&path) { - Ok(metadata) => metadata.len(), - Err(e) => { - error!("Can't read initramfs metadata: {e:?}"); - return -libc::EINVAL; - } - }; - (Some(path), size) - } + unsafe { + let path = match CStr::from_ptr(c_kernel_path).to_str() { + Ok(path) => PathBuf::from(path), Err(e) => { - error!("Error parsing initramfs path: {e:?}"); + error!("Error parsing kernel_path: {e:?}"); return -libc::EINVAL; } - } - } else { - (None, 0) - }; + }; - let cmdline = if !c_cmdline.is_null() { - match CStr::from_ptr(c_cmdline).to_str() { - Ok(cmdline) => Some(cmdline.to_string()), - Err(e) => { - error!("Error parsing kernel cmdline: {e:?}"); + let format = match kernel_format { + // For raw kernels in x86_64, we map the kernel into the + // process and treat it as a bundled kernel. + #[cfg(all(target_arch = "x86_64", not(feature = "tee")))] + 0 => return map_kernel(ctx_id, &path), + #[cfg(target_arch = "aarch64")] + 0 => KernelFormat::Raw, + 1 => KernelFormat::Elf, + 2 => KernelFormat::PeGz, + 3 => KernelFormat::ImageBz2, + 4 => KernelFormat::ImageGz, + 5 => KernelFormat::ImageZstd, + _ => { return -libc::EINVAL; } - } - } else { - None - }; + }; - let external_kernel = ExternalKernel { - path, - format, - initramfs_path, - initramfs_size, - cmdline, - }; + let (initramfs_path, initramfs_size) = if !c_initramfs_path.is_null() { + match CStr::from_ptr(c_initramfs_path).to_str() { + Ok(path) => { + let path = PathBuf::from(path); + let size = match std::fs::metadata(&path) { + Ok(metadata) => metadata.len(), + Err(e) => { + error!("Can't read initramfs metadata: {e:?}"); + return -libc::EINVAL; + } + }; + (Some(path), size) + } + Err(e) => { + error!("Error parsing initramfs path: {e:?}"); + return -libc::EINVAL; + } + } + } else { + (None, 0) + }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => ctx_cfg.get_mut().vmr.set_external_kernel(external_kernel), - Entry::Vacant(_) => return -libc::ENOENT, - } + let cmdline = if !c_cmdline.is_null() { + match CStr::from_ptr(c_cmdline).to_str() { + Ok(cmdline) => Some(cmdline.to_string()), + Err(e) => { + error!("Error parsing kernel cmdline: {e:?}"); + return -libc::EINVAL; + } + } + } else { + None + }; - KRUN_SUCCESS + let external_kernel = ExternalKernel { + path, + format, + initramfs_path, + initramfs_size, + cmdline, + }; + + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + ctx_cfg.get_mut().vmr.set_external_kernel(external_kernel) + } + Entry::Vacant(_) => return -libc::ENOENT, + } + + KRUN_SUCCESS + } } #[cfg(not(feature = "tee"))] #[allow(clippy::format_collect)] #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_set_firmware(ctx_id: u32, c_firmware_path: *const c_char) -> i32 { - let path = match CStr::from_ptr(c_firmware_path).to_str() { - Ok(path) => PathBuf::from(path), - Err(e) => { - error!("Error parsing firmware_path: {e:?}"); - return -libc::EINVAL; - } - }; + unsafe { + let path = match CStr::from_ptr(c_firmware_path).to_str() { + Ok(path) => PathBuf::from(path), + Err(e) => { + error!("Error parsing firmware_path: {e:?}"); + return -libc::EINVAL; + } + }; - let firmware_config = FirmwareConfig { path }; + let firmware_config = FirmwareConfig { path }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => ctx_cfg.get_mut().vmr.set_firmware_config(firmware_config), - Entry::Vacant(_) => return -libc::ENOENT, - } + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + ctx_cfg.get_mut().vmr.set_firmware_config(firmware_config) + } + Entry::Vacant(_) => return -libc::ENOENT, + } - KRUN_SUCCESS + KRUN_SUCCESS + } } unsafe fn load_krunfw_payload( @@ -2292,7 +2348,7 @@ unsafe fn load_krunfw_payload( Ok(()) } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_setuid(ctx_id: u32, uid: libc::uid_t) -> i32 { match CTX_MAP.lock().unwrap().entry(ctx_id) { Entry::Occupied(mut ctx_cfg) => { @@ -2305,7 +2361,7 @@ pub extern "C" fn krun_setuid(ctx_id: u32, uid: libc::uid_t) -> i32 { KRUN_SUCCESS } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_setgid(ctx_id: u32, gid: libc::gid_t) -> i32 { match CTX_MAP.lock().unwrap().entry(ctx_id) { Entry::Occupied(mut ctx_cfg) => { @@ -2320,95 +2376,97 @@ pub extern "C" fn krun_setgid(ctx_id: u32, gid: libc::gid_t) -> i32 { #[cfg(all(feature = "blk", not(feature = "tee")))] #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_set_root_disk_remount( ctx_id: u32, c_device: *const c_char, c_fstype: *const c_char, c_options: *const c_char, ) -> i32 { - let device = match CStr::from_ptr(c_device).to_str() { - Ok(device) => device.to_string(), - Err(e) => { - error!("Error parsing device path: {e:?}"); - return -libc::EINVAL; - } - }; - - let fstype = if !c_fstype.is_null() { - match CStr::from_ptr(c_fstype).to_str() { - Ok(fstype) => { - if fstype == "auto" { - None - } else { - Some(fstype.to_string()) - } - } + unsafe { + let device = match CStr::from_ptr(c_device).to_str() { + Ok(device) => device.to_string(), Err(e) => { - error!("Error parsing fstype: {e:?}"); + error!("Error parsing device path: {e:?}"); return -libc::EINVAL; } - } - } else { - None - }; + }; - let options = if !c_options.is_null() { - match CStr::from_ptr(c_options).to_str() { - Ok(options) => Some(options.to_string()), - Err(e) => { - error!("Error parsing options: {e:?}"); - return -libc::EINVAL; + let fstype = if !c_fstype.is_null() { + match CStr::from_ptr(c_fstype).to_str() { + Ok(fstype) => { + if fstype == "auto" { + None + } else { + Some(fstype.to_string()) + } + } + Err(e) => { + error!("Error parsing fstype: {e:?}"); + return -libc::EINVAL; + } } - } - } else { - None - }; - - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let ctx_cfg = ctx_cfg.get_mut(); + } else { + None + }; - if ctx_cfg.vmr.fs.iter().any(|fs| fs.fs_id == "/dev/root") { - error!("Root filesystem already configured"); - return -libc::EINVAL; + let options = if !c_options.is_null() { + match CStr::from_ptr(c_options).to_str() { + Ok(options) => Some(options.to_string()), + Err(e) => { + error!("Error parsing options: {e:?}"); + return -libc::EINVAL; + } } + } else { + None + }; - if ctx_cfg.block_cfgs.is_empty() { - error!("No block devices configured"); - return -libc::EINVAL; - } + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let ctx_cfg = ctx_cfg.get_mut(); - // To boot from a filesystem other than virtiofs, - // we need to setup a temporary root from which init.krun can be executed. - // Otherwise, it would have to be copied to the target filesystem beforehand. - // Instead, init.krun will run from virtiofs and then switch to the real root. - let root_dir_suffix = Alphanumeric.sample_string(&mut rand::rng(), 6); - let empty_root = env::temp_dir().join(format!("krun-empty-root-{root_dir_suffix}")); + if ctx_cfg.vmr.fs.iter().any(|fs| fs.fs_id == "/dev/root") { + error!("Root filesystem already configured"); + return -libc::EINVAL; + } - if let Err(e) = std::fs::create_dir_all(&empty_root) { - error!("Failed to create empty root directory: {e:?}"); - return -libc::EINVAL; - } + if ctx_cfg.block_cfgs.is_empty() { + error!("No block devices configured"); + return -libc::EINVAL; + } - ctx_cfg.vmr.add_fs_device(FsDeviceConfig { - fs_id: "/dev/root".into(), - shared_dir: empty_root.to_string_lossy().into(), - // Default to a conservative 512 MB window. - shm_size: Some(1 << 29), - allow_root_dir_delete: true, - read_only: false, - }); + // To boot from a filesystem other than virtiofs, + // we need to setup a temporary root from which init.krun can be executed. + // Otherwise, it would have to be copied to the target filesystem beforehand. + // Instead, init.krun will run from virtiofs and then switch to the real root. + let root_dir_suffix = Alphanumeric.sample_string(&mut rand::rng(), 6); + let empty_root = env::temp_dir().join(format!("krun-empty-root-{root_dir_suffix}")); - ctx_cfg.set_block_root(device, fstype, options); - } - Entry::Vacant(_) => return -libc::ENOENT, - }; + if let Err(e) = std::fs::create_dir_all(&empty_root) { + error!("Failed to create empty root directory: {e:?}"); + return -libc::EINVAL; + } - KRUN_SUCCESS + ctx_cfg.vmr.add_fs_device(FsDeviceConfig { + fs_id: "/dev/root".into(), + shared_dir: empty_root.to_string_lossy().into(), + // Default to a conservative 512 MB window. + shm_size: Some(1 << 29), + allow_root_dir_delete: true, + read_only: false, + }); + + ctx_cfg.set_block_root(device, fstype, options); + } + Entry::Vacant(_) => return -libc::ENOENT, + }; + + KRUN_SUCCESS + } } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_disable_implicit_console(ctx_id: u32) -> i32 { match CTX_MAP.lock().unwrap().entry(ctx_id) { Entry::Occupied(mut ctx_cfg) => { @@ -2421,7 +2479,7 @@ pub extern "C" fn krun_disable_implicit_console(ctx_id: u32) -> i32 { KRUN_SUCCESS } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_disable_implicit_vsock(ctx_id: u32) -> i32 { match CTX_MAP.lock().unwrap().entry(ctx_id) { Entry::Occupied(mut ctx_cfg) => { @@ -2434,7 +2492,7 @@ pub extern "C" fn krun_disable_implicit_vsock(ctx_id: u32) -> i32 { KRUN_SUCCESS } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn krun_add_vsock(ctx_id: u32, tsi_features: u32) -> i32 { let tsi_flags = match TsiFlags::from_bits(tsi_features) { Some(flags) => flags, @@ -2461,7 +2519,7 @@ pub extern "C" fn krun_add_vsock(ctx_id: u32, tsi_features: u32) -> i32 { } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_add_virtio_console_default( ctx_id: u32, input_fd: libc::c_int, @@ -2489,7 +2547,7 @@ pub unsafe extern "C" fn krun_add_virtio_console_default( } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_add_virtio_console_multiport(ctx_id: u32) -> i32 { match CTX_MAP.lock().unwrap().entry(ctx_id) { Entry::Occupied(mut ctx_cfg) => { @@ -2507,51 +2565,53 @@ pub unsafe extern "C" fn krun_add_virtio_console_multiport(ctx_id: u32) -> i32 { } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_add_console_port_tty( ctx_id: u32, console_id: u32, name: *const libc::c_char, tty_fd: libc::c_int, ) -> i32 { - if tty_fd < 0 { - return -libc::EINVAL; - } - - let name_str = if name.is_null() { - String::new() - } else { - match CStr::from_ptr(name).to_str() { - Ok(s) => s.to_string(), - Err(_) => return -libc::EINVAL, + unsafe { + if tty_fd < 0 { + return -libc::EINVAL; } - }; - if !BorrowedFd::borrow_raw(tty_fd).is_terminal() { - return -libc::ENOTTY; - } + let name_str = if name.is_null() { + String::new() + } else { + match CStr::from_ptr(name).to_str() { + Ok(s) => s.to_string(), + Err(_) => return -libc::EINVAL, + } + }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); + if !BorrowedFd::borrow_raw(tty_fd).is_terminal() { + return -libc::ENOTTY; + } - match cfg.vmr.virtio_consoles.get_mut(console_id as usize) { - Some(VirtioConsoleConfigMode::Explicit(ports)) => { - ports.push(PortConfig::Tty { - name: name_str, - tty_fd, - }); - KRUN_SUCCESS + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + + match cfg.vmr.virtio_consoles.get_mut(console_id as usize) { + Some(VirtioConsoleConfigMode::Explicit(ports)) => { + ports.push(PortConfig::Tty { + name: name_str, + tty_fd, + }); + KRUN_SUCCESS + } + _ => -libc::EINVAL, } - _ => -libc::EINVAL, } + Entry::Vacant(_) => -libc::ENOENT, } - Entry::Vacant(_) => -libc::ENOENT, } } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_add_console_port_inout( ctx_id: u32, console_id: u32, @@ -2559,37 +2619,39 @@ pub unsafe extern "C" fn krun_add_console_port_inout( input_fd: c_int, output_fd: c_int, ) -> i32 { - let name_str = if name.is_null() { - String::new() - } else { - match CStr::from_ptr(name).to_str() { - Ok(s) => s.to_string(), - Err(_) => return -libc::EINVAL, - } - }; - - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); + unsafe { + let name_str = if name.is_null() { + String::new() + } else { + match CStr::from_ptr(name).to_str() { + Ok(s) => s.to_string(), + Err(_) => return -libc::EINVAL, + } + }; - match cfg.vmr.virtio_consoles.get_mut(console_id as usize) { - Some(VirtioConsoleConfigMode::Explicit(ports)) => { - ports.push(PortConfig::InOut { - name: name_str, - input_fd, - output_fd, - }); - KRUN_SUCCESS + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + + match cfg.vmr.virtio_consoles.get_mut(console_id as usize) { + Some(VirtioConsoleConfigMode::Explicit(ports)) => { + ports.push(PortConfig::InOut { + name: name_str, + input_fd, + output_fd, + }); + KRUN_SUCCESS + } + _ => -libc::EINVAL, } - _ => -libc::EINVAL, } + Entry::Vacant(_) => -libc::ENOENT, } - Entry::Vacant(_) => -libc::ENOENT, } } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_add_serial_console_default( ctx_id: u32, input_fd: c_int, @@ -2610,24 +2672,26 @@ pub unsafe extern "C" fn krun_add_serial_console_default( } #[allow(clippy::missing_safety_doc)] -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn krun_set_kernel_console(ctx_id: u32, console_id: *const c_char) -> i32 { - let console_id = match CStr::from_ptr(console_id).to_str() { - Ok(id) => id.to_string(), - Err(_) => return -libc::EINVAL, - }; - match CTX_MAP.lock().unwrap().entry(ctx_id) { - Entry::Occupied(mut ctx_cfg) => { - let cfg = ctx_cfg.get_mut(); - cfg.vmr.kernel_console = Some(console_id); + unsafe { + let console_id = match CStr::from_ptr(console_id).to_str() { + Ok(id) => id.to_string(), + Err(_) => return -libc::EINVAL, + }; + match CTX_MAP.lock().unwrap().entry(ctx_id) { + Entry::Occupied(mut ctx_cfg) => { + let cfg = ctx_cfg.get_mut(); + cfg.vmr.kernel_console = Some(console_id); + } + Entry::Vacant(_) => return -libc::ENOENT, } - Entry::Vacant(_) => return -libc::ENOENT, - } - KRUN_SUCCESS + KRUN_SUCCESS + } } -#[no_mangle] +#[unsafe(no_mangle)] #[allow(unreachable_code)] pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 { #[cfg(target_os = "linux")] @@ -2780,18 +2844,18 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 { ctx_cfg.vmr.set_console_output(console_output); } - if let Some(gid) = ctx_cfg.vmm_gid { - if unsafe { libc::setgid(gid) } != 0 { - error!("Failed to set gid {gid}"); - return -std::io::Error::last_os_error().raw_os_error().unwrap(); - } + if let Some(gid) = ctx_cfg.vmm_gid + && unsafe { libc::setgid(gid) } != 0 + { + error!("Failed to set gid {gid}"); + return -std::io::Error::last_os_error().raw_os_error().unwrap(); } - if let Some(uid) = ctx_cfg.vmm_uid { - if unsafe { libc::setuid(uid) } != 0 { - error!("Failed to set uid {uid}"); - return -std::io::Error::last_os_error().raw_os_error().unwrap(); - } + if let Some(uid) = ctx_cfg.vmm_uid + && unsafe { libc::setuid(uid) } != 0 + { + error!("Failed to set uid {uid}"); + return -std::io::Error::last_os_error().raw_os_error().unwrap(); } let (sender, _receiver) = unbounded(); @@ -2834,7 +2898,7 @@ pub extern "C" fn krun_start_enter(ctx_id: u32) -> i32 { } #[cfg(feature = "aws-nitro")] -#[no_mangle] +#[unsafe(no_mangle)] fn krun_start_enter_nitro(ctx_id: u32) -> i32 { let ctx_cfg = match CTX_MAP.lock().unwrap().remove(&ctx_id) { Some(ctx_cfg) => ctx_cfg, diff --git a/src/polly/Cargo.toml b/src/polly/Cargo.toml index b5e0f5bfe..1e32e44b8 100644 --- a/src/polly/Cargo.toml +++ b/src/polly/Cargo.toml @@ -2,7 +2,7 @@ name = "krun-polly" version = "0.1.0-1.18.0" authors = ["The libkrun Authors"] -edition = "2021" +edition = "2024" description = "Event-driven I/O polling for libkrun" license = "Apache-2.0" repository = "https://github.com/containers/libkrun" diff --git a/src/polly/src/event_manager.rs b/src/polly/src/event_manager.rs index 0a42df0d8..3f822294c 100644 --- a/src/polly/src/event_manager.rs +++ b/src/polly/src/event_manager.rs @@ -514,17 +514,23 @@ mod tests { .unwrap(); // At this point ev2 is not registered. Check that unregistering it throws an error. - assert!(event_manager - .unregister(dummy_subscriber.lock().unwrap().event_fd_2.as_raw_fd()) - .is_err()); + assert!( + event_manager + .unregister(dummy_subscriber.lock().unwrap().event_fd_2.as_raw_fd()) + .is_err() + ); // Try to unregister ev1 twice. Only the first call should be successful. - assert!(event_manager - .unregister(dummy_subscriber.lock().unwrap().event_fd_1.as_raw_fd()) - .is_ok()); - assert!(event_manager - .unregister(dummy_subscriber.lock().unwrap().event_fd_1.as_raw_fd()) - .is_err()); + assert!( + event_manager + .unregister(dummy_subscriber.lock().unwrap().event_fd_1.as_raw_fd()) + .is_ok() + ); + assert!( + event_manager + .unregister(dummy_subscriber.lock().unwrap().event_fd_1.as_raw_fd()) + .is_err() + ); } #[test] diff --git a/src/rutabaga_gfx/Cargo.toml b/src/rutabaga_gfx/Cargo.toml index f8e8efa2c..d06bc619a 100644 --- a/src/rutabaga_gfx/Cargo.toml +++ b/src/rutabaga_gfx/Cargo.toml @@ -2,7 +2,7 @@ name = "krun-rutabaga-gfx" version = "0.1.0-1.18.0" authors = ["The libkrun Authors"] -edition = "2021" +edition = "2024" description = "[highly unstable] Handling virtio-gpu protocols" license-file = "LICENSE" repository = "https://github.com/containers/libkrun" diff --git a/src/rutabaga_gfx/ffi/Cargo.lock b/src/rutabaga_gfx/ffi/Cargo.lock new file mode 100644 index 000000000..4f9dbfe3b --- /dev/null +++ b/src/rutabaga_gfx/ffi/Cargo.lock @@ -0,0 +1,230 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "krun-rutabaga-gfx" +version = "0.1.0-1.18.0" +dependencies = [ + "anyhow", + "cfg-if", + "libc", + "log", + "nix", + "pkg-config", + "remain", + "thiserror", + "vmm-sys-util", + "winapi", + "zerocopy", +] + +[[package]] +name = "krun-rutabaga-gfx-ffi" +version = "0.1.0-1.18.0" +dependencies = [ + "krun-rutabaga-gfx", + "libc", + "log", + "once_cell", +] + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "nix" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags 2.11.1", + "cfg-if", + "cfg_aliases", + "libc", + "memoffset", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "remain" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7ef12e84481ab4006cb942f8682bba28ece7270743e649442027c5db87df126" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "vmm-sys-util" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d21f366bf22bfba3e868349978766a965cbe628c323d58e026be80b8357ab789" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "zerocopy" +version = "0.8.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/src/rutabaga_gfx/ffi/Cargo.toml b/src/rutabaga_gfx/ffi/Cargo.toml index 48f48a804..ae1fa04e6 100644 --- a/src/rutabaga_gfx/ffi/Cargo.toml +++ b/src/rutabaga_gfx/ffi/Cargo.toml @@ -2,7 +2,7 @@ name = "krun-rutabaga-gfx-ffi" version = "0.1.0-1.18.0" authors = ["The libkrun Authors"] -edition = "2021" +edition = "2024" description = "Handling virtio-gpu protocols with C API" license-file = "LICENSE" repository = "https://github.com/containers/libkrun" diff --git a/src/rutabaga_gfx/ffi/src/lib.rs b/src/rutabaga_gfx/ffi/src/lib.rs index ff5f83ce5..268bf0cf5 100644 --- a/src/rutabaga_gfx/ffi/src/lib.rs +++ b/src/rutabaga_gfx/ffi/src/lib.rs @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -///! C-bindings for the rutabaga_gfx crate +//! C-bindings for the rutabaga_gfx crate extern crate rutabaga_gfx; use std::convert::TryInto; @@ -15,7 +15,6 @@ use std::panic::catch_unwind; use std::panic::AssertUnwindSafe; use std::path::PathBuf; use std::ptr::copy_nonoverlapping; -use std::ptr::null; use std::ptr::null_mut; use std::slice::from_raw_parts; use std::slice::from_raw_parts_mut; @@ -35,7 +34,7 @@ static S_DEBUG_HANDLER: OnceCell> = OnceCell::new(); fn log_error(debug_string: String) { // Although this should be only called from a single-thread environment, add locking to // to reduce the amount of unsafe code blocks. - if let Some(ref handler_mutex) = S_DEBUG_HANDLER.get() { + if let Some(handler_mutex) = S_DEBUG_HANDLER.get() { let cstring = CString::new(debug_string.as_str()).expect("CString creation failed"); let debug = RutabagaDebug { @@ -158,15 +157,15 @@ fn create_ffi_debug_handler( RutabagaDebugHandler::new(move |rutabaga_debug| debug_cb(user_data, &rutabaga_debug)) } -#[no_mangle] +#[unsafe(no_mangle)] /// # Safety /// - `capset_names` must be a null-terminated C-string. pub unsafe extern "C" fn rutabaga_calculate_capset_mask( capset_names: *const c_char, capset_mask: &mut u64, -) -> i32 { +) -> i32 { unsafe { catch_unwind(AssertUnwindSafe(|| { - if capset_names == null() { + if capset_names.is_null() { return -EINVAL; } @@ -177,20 +176,20 @@ pub unsafe extern "C" fn rutabaga_calculate_capset_mask( NO_ERROR })) .unwrap_or(-ESRCH) -} +}} /// # Safety /// - If `(*builder).channels` is not null, the caller must ensure `(*channels).channels` points to /// a valid array of `struct rutabaga_channel` of size `(*channels).num_channels`. /// - The `channel_name` field of `struct rutabaga_channel` must be a null-terminated C-string. -#[no_mangle] -pub unsafe extern "C" fn rutabaga_init(builder: &rutabaga_builder, ptr: &mut *mut rutabaga) -> i32 { +#[unsafe(no_mangle)] +pub unsafe extern "C" fn rutabaga_init(builder: &rutabaga_builder, ptr: &mut *mut rutabaga) -> i32 { unsafe { catch_unwind(AssertUnwindSafe(|| { - let fence_handler = create_ffi_fence_handler((*builder).user_data, (*builder).fence_cb); + let fence_handler = create_ffi_fence_handler(builder.user_data, builder.fence_cb); let mut debug_handler_opt: Option = None; - if let Some(func) = (*builder).debug_cb { - let debug_handler = create_ffi_debug_handler((*builder).user_data, func); + if let Some(func) = builder.debug_cb { + let debug_handler = create_ffi_debug_handler(builder.user_data, func); S_DEBUG_HANDLER .set(Mutex::new(debug_handler.clone())) .expect("once_cell set failed"); @@ -198,7 +197,7 @@ pub unsafe extern "C" fn rutabaga_init(builder: &rutabaga_builder, ptr: &mut *mu } let mut rutabaga_channels_opt = None; - if let Some(channels) = (*builder).channels { + if let Some(channels) = builder.channels { let mut rutabaga_channels: Vec = Vec::new(); let channels_slice = from_raw_parts(channels.channels, channels.num_channels); @@ -219,16 +218,16 @@ pub unsafe extern "C" fn rutabaga_init(builder: &rutabaga_builder, ptr: &mut *mu } let mut component_type = RutabagaComponentType::CrossDomain; - if (*builder).capset_mask == 0 { + if builder.capset_mask == 0 { component_type = RutabagaComponentType::Rutabaga2D; } - let rutabaga_wsi = match (*builder).wsi { + let rutabaga_wsi = match builder.wsi { RUTABAGA_WSI_SURFACELESS => RutabagaWsi::Surfaceless, _ => return -EINVAL, }; - let result = RutabagaBuilder::new(component_type, (*builder).capset_mask) + let result = RutabagaBuilder::new(component_type, 0, builder.capset_mask) .set_use_external_blob(false) .set_use_egl(true) .set_wsi(rutabaga_wsi) @@ -241,21 +240,21 @@ pub unsafe extern "C" fn rutabaga_init(builder: &rutabaga_builder, ptr: &mut *mu NO_ERROR })) .unwrap_or(-ESRCH) -} +}} /// # Safety /// - `ptr` must have been created by `rutabaga_init`. -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rutabaga_finish(ptr: &mut *mut rutabaga) -> i32 { catch_unwind(AssertUnwindSafe(|| { - unsafe { Box::from_raw(*ptr) }; + unsafe { drop(Box::from_raw(*ptr)) }; *ptr = null_mut(); NO_ERROR })) .unwrap_or(-ESRCH) } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rutabaga_get_num_capsets(ptr: &mut rutabaga, num_capsets: &mut u32) -> i32 { catch_unwind(AssertUnwindSafe(|| { *num_capsets = ptr.get_num_capsets(); @@ -264,7 +263,7 @@ pub extern "C" fn rutabaga_get_num_capsets(ptr: &mut rutabaga, num_capsets: &mut .unwrap_or(-ESRCH) } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rutabaga_get_capset_info( ptr: &mut rutabaga, capset_index: u32, @@ -285,14 +284,14 @@ pub extern "C" fn rutabaga_get_capset_info( /// # Safety /// - `capset` must point an array of bytes of size `capset_size`. -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn rutabaga_get_capset( ptr: &mut rutabaga, capset_id: u32, version: u32, capset: *mut u8, capset_size: u32, -) -> i32 { +) -> i32 { unsafe { catch_unwind(AssertUnwindSafe(|| { let size: usize = capset_size.try_into().map_err(|_e| -EINVAL).unwrap(); let result = ptr.get_capset(capset_id, version); @@ -301,9 +300,9 @@ pub unsafe extern "C" fn rutabaga_get_capset( NO_ERROR })) .unwrap_or(-ESRCH) -} +}} -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rutabaga_context_create( ptr: &mut rutabaga, ctx_id: u32, @@ -330,7 +329,7 @@ pub extern "C" fn rutabaga_context_create( .unwrap_or(-ESRCH) } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rutabaga_context_destroy(ptr: &mut rutabaga, ctx_id: u32) -> i32 { catch_unwind(AssertUnwindSafe(|| { let result = ptr.destroy_context(ctx_id); @@ -339,7 +338,7 @@ pub extern "C" fn rutabaga_context_destroy(ptr: &mut rutabaga, ctx_id: u32) -> i .unwrap_or(-ESRCH) } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rutabaga_context_attach_resource( ptr: &mut rutabaga, ctx_id: u32, @@ -352,7 +351,7 @@ pub extern "C" fn rutabaga_context_attach_resource( .unwrap_or(-ESRCH) } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rutabaga_context_detach_resource( ptr: &mut rutabaga, ctx_id: u32, @@ -365,7 +364,7 @@ pub extern "C" fn rutabaga_context_detach_resource( .unwrap_or(-ESRCH) } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rutabaga_resource_create_3d( ptr: &mut rutabaga, resource_id: u32, @@ -384,14 +383,14 @@ pub extern "C" fn rutabaga_resource_create_3d( /// - Each iovec must point to valid memory starting at `iov_base` with length `iov_len`. /// - Each iovec must valid until the resource's backing is explictly detached or the resource is /// is unreferenced. -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn rutabaga_resource_attach_backing( ptr: &mut rutabaga, resource_id: u32, iovecs: &rutabaga_iovecs, -) -> i32 { +) -> i32 { unsafe { catch_unwind(AssertUnwindSafe(|| { - let slice = from_raw_parts((*iovecs).iovecs, (*iovecs).num_iovecs); + let slice = from_raw_parts(iovecs.iovecs, iovecs.num_iovecs); let vecs = slice .iter() .map(|iov| RutabagaIovec { @@ -404,9 +403,9 @@ pub unsafe extern "C" fn rutabaga_resource_attach_backing( return_result(result) })) .unwrap_or(-ESRCH) -} +}} -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rutabaga_resource_detach_backing(ptr: &mut rutabaga, resource_id: u32) -> i32 { catch_unwind(AssertUnwindSafe(|| { let result = ptr.detach_backing(resource_id); @@ -418,14 +417,14 @@ pub extern "C" fn rutabaga_resource_detach_backing(ptr: &mut rutabaga, resource_ /// # Safety /// - If `iovecs` is not null, the caller must ensure `(*iovecs).iovecs` points to a valid array of /// iovecs of size `(*iovecs).num_iovecs`. -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn rutabaga_resource_transfer_read( ptr: &mut rutabaga, ctx_id: u32, resource_id: u32, transfer: &rutabaga_transfer, buf: Option<&iovec>, -) -> i32 { +) -> i32 { unsafe { catch_unwind(AssertUnwindSafe(|| { let mut slice_opt = None; if let Some(iovec) = buf { @@ -439,9 +438,9 @@ pub unsafe extern "C" fn rutabaga_resource_transfer_read( return_result(result) })) .unwrap_or(-ESRCH) -} +}} -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rutabaga_resource_transfer_write( ptr: &mut rutabaga, ctx_id: u32, @@ -462,7 +461,7 @@ pub extern "C" fn rutabaga_resource_transfer_write( /// transfered to rutabaga. /// - Each iovec must valid until the resource's backing is explictly detached or the resource is /// is unreferenced. -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn rutabaga_resource_create_blob( ptr: &mut rutabaga, ctx_id: u32, @@ -470,11 +469,11 @@ pub unsafe extern "C" fn rutabaga_resource_create_blob( create_blob: &rutabaga_create_blob, iovecs: Option<&rutabaga_iovecs>, handle: Option<&rutabaga_handle>, -) -> i32 { +) -> i32 { unsafe { catch_unwind(AssertUnwindSafe(|| { let mut iovecs_opt: Option> = None; if let Some(iovs) = iovecs { - let slice = from_raw_parts((*iovs).iovecs, (*iovs).num_iovecs); + let slice = from_raw_parts(iovs.iovecs, iovs.num_iovecs); let vecs = slice .iter() .map(|iov| RutabagaIovec { @@ -489,9 +488,9 @@ pub unsafe extern "C" fn rutabaga_resource_create_blob( if let Some(hnd) = handle { handle_opt = Some(RutabagaHandle { os_handle: RutabagaDescriptor::from_raw_descriptor( - (*hnd).os_handle.try_into().unwrap(), + hnd.os_handle.try_into().unwrap(), ), - handle_type: (*hnd).handle_type, + handle_type: hnd.handle_type, }); } @@ -501,9 +500,9 @@ pub unsafe extern "C" fn rutabaga_resource_create_blob( return_result(result) })) .unwrap_or(-ESRCH) -} +}} -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rutabaga_resource_unref(ptr: &mut rutabaga, resource_id: u32) -> i32 { catch_unwind(AssertUnwindSafe(|| { let result = ptr.unref_resource(resource_id); @@ -514,7 +513,7 @@ pub extern "C" fn rutabaga_resource_unref(ptr: &mut rutabaga, resource_id: u32) /// # Safety /// Caller owns raw descriptor on success and is responsible for closing it. -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rutabaga_resource_export_blob( ptr: &mut rutabaga, resource_id: u32, @@ -524,14 +523,14 @@ pub extern "C" fn rutabaga_resource_export_blob( let result = ptr.export_blob(resource_id); let hnd = return_on_error!(result); - (*handle).handle_type = hnd.handle_type; - (*handle).os_handle = hnd.os_handle.into_raw_descriptor() as i64; + handle.handle_type = hnd.handle_type; + handle.os_handle = hnd.os_handle.into_raw_descriptor() as i64; NO_ERROR })) .unwrap_or(-ESRCH) } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rutabaga_resource_map( ptr: &mut rutabaga, resource_id: u32, @@ -540,14 +539,14 @@ pub extern "C" fn rutabaga_resource_map( catch_unwind(AssertUnwindSafe(|| { let result = ptr.map(resource_id); let internal_map = return_on_error!(result); - (*mapping).ptr = internal_map.ptr as *mut c_void; - (*mapping).size = internal_map.size; + mapping.ptr = internal_map.ptr as *mut c_void; + mapping.size = internal_map.size; NO_ERROR })) .unwrap_or(-ESRCH) } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rutabaga_resource_unmap(ptr: &mut rutabaga, resource_id: u32) -> i32 { catch_unwind(AssertUnwindSafe(|| { let result = ptr.unmap(resource_id); @@ -556,7 +555,7 @@ pub extern "C" fn rutabaga_resource_unmap(ptr: &mut rutabaga, resource_id: u32) .unwrap_or(-ESRCH) } -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rutabaga_resource_map_info( ptr: &mut rutabaga, resource_id: u32, @@ -572,11 +571,11 @@ pub extern "C" fn rutabaga_resource_map_info( /// # Safety /// - `commands` must point to a contiguous memory region of `size` bytes. -#[no_mangle] +#[unsafe(no_mangle)] pub unsafe extern "C" fn rutabaga_submit_command( ptr: &mut rutabaga, cmd: &rutabaga_command, -) -> i32 { +) -> i32 { unsafe { catch_unwind(AssertUnwindSafe(|| { let cmd_slice = from_raw_parts_mut(cmd.cmd, cmd.cmd_size as usize); let fence_ids = from_raw_parts(cmd.fence_ids, cmd.num_in_fences as usize); @@ -584,9 +583,9 @@ pub unsafe extern "C" fn rutabaga_submit_command( return_result(result) })) .unwrap_or(-ESRCH) -} +}} -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rutabaga_create_fence(ptr: &mut rutabaga, fence: &rutabaga_fence) -> i32 { catch_unwind(AssertUnwindSafe(|| { let result = ptr.create_fence(*fence); diff --git a/src/rutabaga_gfx/src/cross_domain/mod.rs b/src/rutabaga_gfx/src/cross_domain/mod.rs index 72ffd4742..c1ffbd7d2 100644 --- a/src/rutabaga_gfx/src/cross_domain/mod.rs +++ b/src/rutabaga_gfx/src/cross_domain/mod.rs @@ -6,18 +6,18 @@ //! boundaries. #[cfg(feature = "x")] -use libc::{c_int, FUTEX_WAKE_BITSET}; +use libc::{FUTEX_WAKE_BITSET, c_int}; use libc::{O_ACCMODE, O_WRONLY}; use log::{error, info}; -use nix::fcntl::{fcntl, FcntlArg}; +use nix::fcntl::{FcntlArg, fcntl}; #[cfg(feature = "x")] -use nix::sys::mman::{mmap, munmap, MapFlags, ProtFlags}; +use nix::sys::mman::{MapFlags, ProtFlags, mmap, munmap}; use std::cmp::max; use std::collections::BTreeMap as Map; use std::collections::VecDeque; use std::convert::TryInto; use std::ffi::c_void; -use std::fs::{read_link, File}; +use std::fs::{File, read_link}; use std::io::{Seek, SeekFrom}; use std::mem::size_of; use std::os::fd::AsFd; @@ -25,38 +25,38 @@ use std::os::fd::AsRawFd; #[cfg(feature = "x")] use std::ptr; use std::ptr::NonNull; -use std::sync::atomic::AtomicBool; -#[cfg(feature = "x")] -use std::sync::atomic::{AtomicU32, Ordering}; use std::sync::Arc; use std::sync::Condvar; use std::sync::Mutex; +use std::sync::atomic::AtomicBool; +#[cfg(feature = "x")] +use std::sync::atomic::{AtomicU32, Ordering}; use std::thread; use zerocopy::FromBytes; use zerocopy::Immutable; use zerocopy::IntoBytes; +use crate::DrmFormat; +use crate::ImageAllocationInfo; +use crate::ImageMemoryRequirements; +use crate::RutabagaGralloc; +use crate::RutabagaGrallocFlags; use crate::cross_domain::cross_domain_protocol::*; +use crate::cross_domain::sys::Receiver; +use crate::cross_domain::sys::Sender; +use crate::cross_domain::sys::SystemStream; +use crate::cross_domain::sys::WaitContext; use crate::cross_domain::sys::channel; use crate::cross_domain::sys::channel_signal; use crate::cross_domain::sys::channel_wait; use crate::cross_domain::sys::read_volatile; use crate::cross_domain::sys::write_volatile; -use crate::cross_domain::sys::Receiver; -use crate::cross_domain::sys::Sender; -use crate::cross_domain::sys::SystemStream; -use crate::cross_domain::sys::WaitContext; use crate::rutabaga_core::ExportTable; use crate::rutabaga_core::RutabagaComponent; use crate::rutabaga_core::RutabagaContext; use crate::rutabaga_core::RutabagaResource; use crate::rutabaga_os::SafeDescriptor; use crate::rutabaga_utils::*; -use crate::DrmFormat; -use crate::ImageAllocationInfo; -use crate::ImageMemoryRequirements; -use crate::RutabagaGralloc; -use crate::RutabagaGrallocFlags; mod cross_domain_protocol; mod sys; @@ -481,7 +481,7 @@ impl CrossDomainWorker { .ok_or(RutabagaError::InvalidCrossDomainItemId)?; match item { - CrossDomainItem::WaylandReadPipe(ref mut file) => { + CrossDomainItem::WaylandReadPipe(file) => { let ring_write = RingWrite::WriteFromFile(cmd_read, file, event.readable); bytes_read = self.state.write_to_ring::( @@ -517,7 +517,7 @@ impl CrossDomainWorker { .ok_or(RutabagaError::InvalidCrossDomainItemId)?; match item { - CrossDomainItem::Eventfd(ref mut file) => { + CrossDomainItem::Eventfd(file) => { let ring_write = RingWrite::WriteFromFile(cmd_read, file, event.readable); self.state.write_to_ring::( diff --git a/src/rutabaga_gfx/src/cross_domain/sys/epoll_internal.rs b/src/rutabaga_gfx/src/cross_domain/sys/epoll_internal.rs index 5c2c2206c..73d613dc9 100644 --- a/src/rutabaga_gfx/src/cross_domain/sys/epoll_internal.rs +++ b/src/rutabaga_gfx/src/cross_domain/sys/epoll_internal.rs @@ -9,11 +9,11 @@ use std::os::unix::io::FromRawFd; use std::os::unix::io::OwnedFd; use libc::c_int; +use nix::Result; use nix::errno::Errno; use nix::sys::epoll::EpollCreateFlags; use nix::sys::epoll::EpollFlags; use nix::sys::epoll::EpollOp; -use nix::Result; #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] #[repr(transparent)] diff --git a/src/rutabaga_gfx/src/cross_domain/sys/mod.rs b/src/rutabaga_gfx/src/cross_domain/sys/mod.rs index f42316e28..5e2421614 100644 --- a/src/rutabaga_gfx/src/cross_domain/sys/mod.rs +++ b/src/rutabaga_gfx/src/cross_domain/sys/mod.rs @@ -15,12 +15,12 @@ cfg_if::cfg_if! { } } +pub use platform::Receiver; +pub use platform::Sender; +pub use platform::SystemStream; +pub use platform::WaitContext; pub use platform::channel; pub use platform::channel_signal; pub use platform::channel_wait; pub use platform::read_volatile; pub use platform::write_volatile; -pub use platform::Receiver; -pub use platform::Sender; -pub use platform::SystemStream; -pub use platform::WaitContext; diff --git a/src/rutabaga_gfx/src/cross_domain/sys/stub.rs b/src/rutabaga_gfx/src/cross_domain/sys/stub.rs index 150631f2c..0936aff08 100644 --- a/src/rutabaga_gfx/src/cross_domain/sys/stub.rs +++ b/src/rutabaga_gfx/src/cross_domain/sys/stub.rs @@ -5,10 +5,10 @@ use std::fs::File; use std::sync::Arc; -use super::super::cross_domain_protocol::CrossDomainInitV1; -use super::super::cross_domain_protocol::CrossDomainSendReceiveBase; use super::super::CrossDomainContext; use super::super::CrossDomainState; +use super::super::cross_domain_protocol::CrossDomainInitV1; +use super::super::cross_domain_protocol::CrossDomainSendReceiveBase; use crate::cross_domain::CrossDomainEvent; use crate::cross_domain::CrossDomainToken; use crate::rutabaga_utils::RutabagaError; diff --git a/src/rutabaga_gfx/src/cross_domain/sys/unix.rs b/src/rutabaga_gfx/src/cross_domain/sys/unix.rs index e889456e7..88142b50a 100644 --- a/src/rutabaga_gfx/src/cross_domain/sys/unix.rs +++ b/src/rutabaga_gfx/src/cross_domain/sys/unix.rs @@ -13,10 +13,6 @@ use nix::sys::epoll::EpollCreateFlags; use nix::sys::epoll::EpollFlags; use nix::sys::eventfd::EfdFlags; use nix::sys::eventfd::EventFd; -use nix::sys::socket::connect; -use nix::sys::socket::recvmsg; -use nix::sys::socket::sendmsg; -use nix::sys::socket::socket; use nix::sys::socket::AddressFamily; use nix::sys::socket::ControlMessage; use nix::sys::socket::ControlMessageOwned; @@ -24,30 +20,34 @@ use nix::sys::socket::MsgFlags; use nix::sys::socket::SockFlag; use nix::sys::socket::SockType; use nix::sys::socket::UnixAddr; +use nix::sys::socket::connect; +use nix::sys::socket::recvmsg; +use nix::sys::socket::sendmsg; +use nix::sys::socket::socket; use nix::unistd::pipe; use nix::unistd::read; use nix::unistd::write; -use super::super::add_item; -use super::super::cross_domain_protocol::CROSS_DOMAIN_ID_TYPE_READ_PIPE; -use super::super::cross_domain_protocol::CROSS_DOMAIN_ID_TYPE_VIRTGPU_BLOB; use super::super::CrossDomainContext; use super::super::CrossDomainItem; use super::super::CrossDomainJob; use super::super::CrossDomainState; +use super::super::add_item; +use super::super::cross_domain_protocol::CROSS_DOMAIN_ID_TYPE_READ_PIPE; +use super::super::cross_domain_protocol::CROSS_DOMAIN_ID_TYPE_VIRTGPU_BLOB; use super::epoll_internal::Epoll; use super::epoll_internal::EpollEvent; -use crate::cross_domain::cross_domain_protocol::{ - CrossDomainInitV1, CrossDomainSendReceiveBase, CROSS_DOMAIN_ID_TYPE_SHM, -}; +use crate::RutabagaError; +use crate::RutabagaResult; use crate::cross_domain::CrossDomainEvent; use crate::cross_domain::CrossDomainToken; use crate::cross_domain::WAIT_CONTEXT_MAX; +use crate::cross_domain::cross_domain_protocol::{ + CROSS_DOMAIN_ID_TYPE_SHM, CrossDomainInitV1, CrossDomainSendReceiveBase, +}; use crate::rutabaga_os::AsRawDescriptor; use crate::rutabaga_os::FromRawDescriptor; use crate::rutabaga_os::RawDescriptor; -use crate::RutabagaError; -use crate::RutabagaResult; pub type SystemStream = File; diff --git a/src/rutabaga_gfx/src/generated/virgl_debug_callback_bindings.rs b/src/rutabaga_gfx/src/generated/virgl_debug_callback_bindings.rs index a6d4e3819..63f2480f5 100644 --- a/src/rutabaga_gfx/src/generated/virgl_debug_callback_bindings.rs +++ b/src/rutabaga_gfx/src/generated/virgl_debug_callback_bindings.rs @@ -8,7 +8,7 @@ */ #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub mod stdio { - extern "C" { + unsafe extern "C" { pub fn vsnprintf( __s: *mut ::std::os::raw::c_char, __maxlen: ::std::os::raw::c_ulong, @@ -29,7 +29,7 @@ pub mod stdio { } #[cfg(target_arch = "arm")] pub mod stdio { - extern "C" { + unsafe extern "C" { pub fn vsnprintf( __s: *mut ::std::os::raw::c_char, __maxlen: ::std::os::raw::c_uint, @@ -48,7 +48,7 @@ pub mod stdio { } #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] pub mod stdio { - extern "C" { + unsafe extern "C" { pub fn vsnprintf( __s: *mut ::std::os::raw::c_char, __maxlen: ::std::os::raw::c_ulong, @@ -70,6 +70,6 @@ pub type virgl_debug_callback_type = ::std::option::Option< unsafe extern "C" fn(fmt: *const ::std::os::raw::c_char, ap: stdio::va_list), >; -extern "C" { +unsafe extern "C" { pub fn virgl_set_debug_callback(cb: virgl_debug_callback_type) -> virgl_debug_callback_type; } diff --git a/src/rutabaga_gfx/src/generated/virgl_renderer_bindings.rs b/src/rutabaga_gfx/src/generated/virgl_renderer_bindings.rs index 970e500d1..d80a0ede6 100644 --- a/src/rutabaga_gfx/src/generated/virgl_renderer_bindings.rs +++ b/src/rutabaga_gfx/src/generated/virgl_renderer_bindings.rs @@ -2,7 +2,7 @@ #[cfg(feature = "virgl_renderer")] #[link(name = "virglrenderer")] -extern "C" {} +unsafe extern "C" {} pub const VIRGL_RENDERER_CALLBACKS_VERSION: u32 = 3; pub const VIRGL_RENDERER_USE_EGL: u32 = 1; @@ -107,24 +107,24 @@ pub struct virgl_renderer_callbacks { ) -> ::std::os::raw::c_int, >, } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_init( cookie: *mut ::std::os::raw::c_void, flags: ::std::os::raw::c_int, cb: *mut virgl_renderer_callbacks, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_poll(); } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_get_cursor_data( resource_id: u32, width: *mut u32, height: *mut u32, ) -> *mut ::std::os::raw::c_void; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_get_rect( resource_id: ::std::os::raw::c_int, iov: *mut iovec, @@ -136,13 +136,13 @@ extern "C" { height: ::std::os::raw::c_int, ); } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_get_fd_for_texture( tex_id: u32, fd: *mut ::std::os::raw::c_int, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_get_fd_for_texture2( tex_id: u32, fd: *mut ::std::os::raw::c_int, @@ -197,46 +197,46 @@ pub struct virgl_renderer_supported_structures { pub in_stype_version: u32, pub out_supported_structures_mask: u32, } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_resource_create( args: *mut virgl_renderer_resource_create_args, iov: *mut iovec, num_iovs: u32, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_resource_import_eglimage( args: *mut virgl_renderer_resource_create_args, image: *mut ::std::os::raw::c_void, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_resource_unref(res_handle: u32); } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_resource_set_priv(res_handle: u32, priv_: *mut ::std::os::raw::c_void); } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_resource_get_priv(res_handle: u32) -> *mut ::std::os::raw::c_void; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_context_create( handle: u32, nlen: u32, name: *const ::std::os::raw::c_char, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_context_destroy(handle: u32); } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_submit_cmd( buffer: *mut ::std::os::raw::c_void, ctx_id: ::std::os::raw::c_int, ndw: ::std::os::raw::c_int, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_transfer_read_iov( handle: u32, ctx_id: u32, @@ -249,7 +249,7 @@ extern "C" { iovec_cnt: ::std::os::raw::c_int, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_transfer_write_iov( handle: u32, ctx_id: u32, @@ -262,42 +262,42 @@ extern "C" { iovec_cnt: ::std::os::raw::c_uint, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_get_cap_set(set: u32, max_ver: *mut u32, max_size: *mut u32); } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_fill_caps(set: u32, version: u32, caps: *mut ::std::os::raw::c_void); } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_resource_attach_iov( res_handle: ::std::os::raw::c_int, iov: *mut iovec, num_iovs: ::std::os::raw::c_int, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_resource_detach_iov( res_handle: ::std::os::raw::c_int, iov: *mut *mut iovec, num_iovs: *mut ::std::os::raw::c_int, ); } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_create_fence( client_fence_id: ::std::os::raw::c_int, ctx_id: u32, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_force_ctx_0(); } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_ctx_attach_resource( ctx_id: ::std::os::raw::c_int, res_handle: ::std::os::raw::c_int, ); } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_ctx_detach_resource( ctx_id: ::std::os::raw::c_int, res_handle: ::std::os::raw::c_int, @@ -316,28 +316,28 @@ pub struct virgl_renderer_resource_info { pub stride: u32, pub drm_fourcc: ::std::os::raw::c_int, } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_resource_get_info( res_handle: ::std::os::raw::c_int, info: *mut virgl_renderer_resource_info, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_cleanup(cookie: *mut ::std::os::raw::c_void); } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_reset(); } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_get_poll_fd() -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_execute( execute_args: *mut ::std::os::raw::c_void, execute_size: u32, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_context_create_with_flags( ctx_id: u32, ctx_flags: u32, @@ -366,12 +366,12 @@ impl Default for virgl_renderer_resource_create_blob_args { } } } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_resource_create_blob( args: *const virgl_renderer_resource_create_blob_args, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_resource_map( res_handle: u32, map: *mut *mut ::std::os::raw::c_void, @@ -379,7 +379,7 @@ extern "C" { ) -> ::std::os::raw::c_int; } #[cfg(feature = "virgl_resource_map2")] -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_resource_map2( res_handle: u32, map: *const ::std::os::raw::c_void, @@ -388,23 +388,23 @@ extern "C" { flags: i32, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_resource_unmap(res_handle: u32) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_resource_get_map_info( res_handle: u32, map_info: *mut u32, ) -> ::std::os::raw::c_int; } #[cfg(target_os = "macos")] -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_resource_get_map_ptr( res_handle: u32, map_ptr: *mut u64, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_resource_export_blob( res_id: u32, fd_type: *mut u32, @@ -420,18 +420,18 @@ pub struct virgl_renderer_resource_import_blob_args { pub fd: ::std::os::raw::c_int, pub size: u64, } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_resource_import_blob( args: *const virgl_renderer_resource_import_blob_args, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_export_fence( client_fence_id: u32, fd: *mut ::std::os::raw::c_int, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_context_create_fence( ctx_id: u32, flags: u32, @@ -439,9 +439,9 @@ extern "C" { fence_id: u64, ) -> ::std::os::raw::c_int; } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_context_poll(ctx_id: u32); } -extern "C" { +unsafe extern "C" { pub fn virgl_renderer_context_get_poll_fd(ctx_id: u32) -> ::std::os::raw::c_int; } diff --git a/src/rutabaga_gfx/src/lib.rs b/src/rutabaga_gfx/src/lib.rs index 06c75ae2f..6f03ea473 100644 --- a/src/rutabaga_gfx/src/lib.rs +++ b/src/rutabaga_gfx/src/lib.rs @@ -21,10 +21,10 @@ mod rutabaga_snapshot; mod rutabaga_utils; mod virgl_renderer; -pub use crate::rutabaga_core::calculate_capset_mask; -pub use crate::rutabaga_core::calculate_capset_names; pub use crate::rutabaga_core::Rutabaga; pub use crate::rutabaga_core::RutabagaBuilder; +pub use crate::rutabaga_core::calculate_capset_mask; +pub use crate::rutabaga_core::calculate_capset_names; pub use crate::rutabaga_gralloc::DrmFormat; pub use crate::rutabaga_gralloc::ImageAllocationInfo; pub use crate::rutabaga_gralloc::ImageMemoryRequirements; diff --git a/src/rutabaga_gfx/src/macros.rs b/src/rutabaga_gfx/src/macros.rs index e813bd788..d0110d5ae 100644 --- a/src/rutabaga_gfx/src/macros.rs +++ b/src/rutabaga_gfx/src/macros.rs @@ -6,7 +6,7 @@ #[macro_export] macro_rules! checked_range { - ($x:expr; <= $y:expr) => { + ($x:expr_2021; <= $y:expr_2021) => { if $x <= $y { Ok(()) } else { @@ -23,7 +23,7 @@ macro_rules! checked_range { #[macro_export] macro_rules! checked_arithmetic { - ($x:ident $op:ident $y:ident $op_name:expr) => { + ($x:ident $op:ident $y:ident $op_name:expr_2021) => { $x.$op($y).ok_or_else(|| RutabagaError::CheckedArithmetic { field1: (stringify!($x), $x as usize), field2: (stringify!($y), $y as usize), diff --git a/src/rutabaga_gfx/src/rutabaga_2d.rs b/src/rutabaga_gfx/src/rutabaga_2d.rs index 417e67952..0a306e63d 100644 --- a/src/rutabaga_gfx/src/rutabaga_2d.rs +++ b/src/rutabaga_gfx/src/rutabaga_2d.rs @@ -4,9 +4,9 @@ //! rutabaga_2d: Handles 2D virtio-gpu hypercalls. +use std::cmp::Ordering; use std::cmp::max; use std::cmp::min; -use std::cmp::Ordering; use std::io::IoSliceMut; use crate::rutabaga_core::Rutabaga2DInfo; diff --git a/src/rutabaga_gfx/src/rutabaga_gralloc/gralloc.rs b/src/rutabaga_gfx/src/rutabaga_gralloc/gralloc.rs index 2908cd6cd..e3b9129b7 100644 --- a/src/rutabaga_gfx/src/rutabaga_gralloc/gralloc.rs +++ b/src/rutabaga_gfx/src/rutabaga_gralloc/gralloc.rs @@ -16,8 +16,8 @@ use crate::rutabaga_gralloc::minigbm::MinigbmDevice; use crate::rutabaga_gralloc::system_gralloc::SystemGralloc; #[cfg(feature = "vulkano")] use crate::rutabaga_gralloc::vulkano_gralloc::VulkanoGralloc; -use crate::rutabaga_os::round_up_to_page_size; use crate::rutabaga_os::MappedRegion; +use crate::rutabaga_os::round_up_to_page_size; use crate::rutabaga_utils::*; /* diff --git a/src/rutabaga_gfx/src/rutabaga_gralloc/vulkano_gralloc.rs b/src/rutabaga_gfx/src/rutabaga_gralloc/vulkano_gralloc.rs index 5ed01e1bb..8ae6975af 100644 --- a/src/rutabaga_gfx/src/rutabaga_gralloc/vulkano_gralloc.rs +++ b/src/rutabaga_gfx/src/rutabaga_gralloc/vulkano_gralloc.rs @@ -16,11 +16,14 @@ use std::convert::TryInto; use std::sync::Arc; use log::warn; -use vulkano::device::physical::PhysicalDeviceType; +use vulkano::LoadingError; +use vulkano::VulkanError; +use vulkano::VulkanLibrary; use vulkano::device::Device; use vulkano::device::DeviceCreateInfo; use vulkano::device::DeviceCreationError; use vulkano::device::QueueCreateInfo; +use vulkano::device::physical::PhysicalDeviceType; use vulkano::image; use vulkano::image::ImageCreationError; use vulkano::image::ImageDimensions; @@ -31,7 +34,6 @@ use vulkano::instance::InstanceCreateInfo; use vulkano::instance::InstanceCreationError; use vulkano::instance::InstanceExtensions; use vulkano::instance::Version; -use vulkano::memory::pool::AllocFromRequirementsFilter; use vulkano::memory::DedicatedAllocation; use vulkano::memory::DeviceMemory; use vulkano::memory::DeviceMemoryError; @@ -42,10 +44,8 @@ use vulkano::memory::MemoryAllocateInfo; use vulkano::memory::MemoryMapError; use vulkano::memory::MemoryRequirements; use vulkano::memory::MemoryType; +use vulkano::memory::pool::AllocFromRequirementsFilter; use vulkano::sync::Sharing; -use vulkano::LoadingError; -use vulkano::VulkanError; -use vulkano::VulkanLibrary; use crate::rutabaga_gralloc::gralloc::Gralloc; use crate::rutabaga_gralloc::gralloc::ImageAllocationInfo; diff --git a/src/rutabaga_gfx/src/rutabaga_gralloc/vulkano_gralloc/sys/unix.rs b/src/rutabaga_gfx/src/rutabaga_gralloc/vulkano_gralloc/sys/unix.rs index f949a6567..8c9421c2e 100644 --- a/src/rutabaga_gfx/src/rutabaga_gralloc/vulkano_gralloc/sys/unix.rs +++ b/src/rutabaga_gfx/src/rutabaga_gralloc/vulkano_gralloc/sys/unix.rs @@ -12,14 +12,14 @@ use vulkano::memory::ExternalMemoryHandleType; use vulkano::memory::MemoryAllocateInfo; use vulkano::memory::MemoryImportInfo; +use crate::RutabagaError; +use crate::RutabagaHandle; +use crate::RutabagaResult; use crate::rutabaga_gralloc::vulkano_gralloc::VulkanoGralloc; use crate::rutabaga_os::FromRawDescriptor; use crate::rutabaga_os::IntoRawDescriptor; use crate::rutabaga_utils::RUTABAGA_MEM_HANDLE_TYPE_DMABUF; use crate::rutabaga_utils::RUTABAGA_MEM_HANDLE_TYPE_OPAQUE_FD; -use crate::RutabagaError; -use crate::RutabagaHandle; -use crate::RutabagaResult; impl VulkanoGralloc { /// Get the extensions that should be enabled. diff --git a/src/rutabaga_gfx/src/rutabaga_gralloc/vulkano_gralloc/sys/windows.rs b/src/rutabaga_gfx/src/rutabaga_gralloc/vulkano_gralloc/sys/windows.rs index 0fcbdf56c..debd283e3 100644 --- a/src/rutabaga_gfx/src/rutabaga_gralloc/vulkano_gralloc/sys/windows.rs +++ b/src/rutabaga_gfx/src/rutabaga_gralloc/vulkano_gralloc/sys/windows.rs @@ -11,12 +11,12 @@ use vulkano::memory::ExternalMemoryHandleType; use vulkano::memory::MemoryAllocateInfo; use vulkano::memory::MemoryImportInfo; -use crate::rutabaga_gralloc::vulkano_gralloc::VulkanoGralloc; -use crate::rutabaga_os::AsRawDescriptor; -use crate::rutabaga_utils::RUTABAGA_MEM_HANDLE_TYPE_OPAQUE_WIN32; use crate::RutabagaError; use crate::RutabagaHandle; use crate::RutabagaResult; +use crate::rutabaga_gralloc::vulkano_gralloc::VulkanoGralloc; +use crate::rutabaga_os::AsRawDescriptor; +use crate::rutabaga_utils::RUTABAGA_MEM_HANDLE_TYPE_OPAQUE_WIN32; impl VulkanoGralloc { /// Get the extensions that should be enabled. diff --git a/src/rutabaga_gfx/src/rutabaga_os/memory_mapping.rs b/src/rutabaga_gfx/src/rutabaga_os/memory_mapping.rs index 6fadec2ad..6f5405442 100644 --- a/src/rutabaga_gfx/src/rutabaga_os/memory_mapping.rs +++ b/src/rutabaga_gfx/src/rutabaga_os/memory_mapping.rs @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -use crate::rutabaga_os::sys::platform::MemoryMapping as PlatformMapping; use crate::rutabaga_os::SafeDescriptor; +use crate::rutabaga_os::sys::platform::MemoryMapping as PlatformMapping; use crate::rutabaga_utils::RutabagaMapping; use crate::rutabaga_utils::RutabagaResult; diff --git a/src/rutabaga_gfx/src/rutabaga_os/shm.rs b/src/rutabaga_gfx/src/rutabaga_os/shm.rs index be6a3326d..0e3d3de93 100644 --- a/src/rutabaga_gfx/src/rutabaga_os/shm.rs +++ b/src/rutabaga_gfx/src/rutabaga_os/shm.rs @@ -4,12 +4,12 @@ use std::ffi::CString; -use crate::rutabaga_os::sys::platform::SharedMemory as SysUtilSharedMemory; use crate::rutabaga_os::AsRawDescriptor; use crate::rutabaga_os::FromRawDescriptor; use crate::rutabaga_os::IntoRawDescriptor; use crate::rutabaga_os::RawDescriptor; use crate::rutabaga_os::SafeDescriptor; +use crate::rutabaga_os::sys::platform::SharedMemory as SysUtilSharedMemory; use crate::rutabaga_utils::RutabagaResult; pub struct SharedMemory(pub(crate) SysUtilSharedMemory); diff --git a/src/rutabaga_gfx/src/rutabaga_os/sys/stub/descriptor.rs b/src/rutabaga_gfx/src/rutabaga_os/sys/stub/descriptor.rs index 73d41c10e..ca775adca 100644 --- a/src/rutabaga_gfx/src/rutabaga_os/sys/stub/descriptor.rs +++ b/src/rutabaga_gfx/src/rutabaga_os/sys/stub/descriptor.rs @@ -109,7 +109,7 @@ macro_rules! FromRawDescriptor { ($name:ident) => { impl FromRawDescriptor for $name { unsafe fn from_raw_descriptor(descriptor: RawDescriptor) -> Self { - $name::from_raw_fd(descriptor) + unsafe { $name::from_raw_fd(descriptor) } } } }; diff --git a/src/rutabaga_gfx/src/rutabaga_os/sys/stub/mod.rs b/src/rutabaga_gfx/src/rutabaga_os/sys/stub/mod.rs index b34581ae0..9ecfde0f7 100644 --- a/src/rutabaga_gfx/src/rutabaga_os/sys/stub/mod.rs +++ b/src/rutabaga_gfx/src/rutabaga_os/sys/stub/mod.rs @@ -6,8 +6,8 @@ pub mod descriptor; pub mod memory_mapping; pub mod shm; +pub use shm::SharedMemory; #[allow(unused_imports)] pub use shm::round_up_to_page_size; -pub use shm::SharedMemory; pub use memory_mapping::MemoryMapping; diff --git a/src/rutabaga_gfx/src/rutabaga_os/sys/stub/shm.rs b/src/rutabaga_gfx/src/rutabaga_os/sys/stub/shm.rs index 9c43d8e8f..2670f7a4f 100644 --- a/src/rutabaga_gfx/src/rutabaga_os/sys/stub/shm.rs +++ b/src/rutabaga_gfx/src/rutabaga_os/sys/stub/shm.rs @@ -4,9 +4,9 @@ use std::ffi::CStr; +use crate::rutabaga_os::RawDescriptor; use crate::rutabaga_os::descriptor::AsRawDescriptor; use crate::rutabaga_os::descriptor::IntoRawDescriptor; -use crate::rutabaga_os::RawDescriptor; use crate::rutabaga_utils::RutabagaError; use crate::rutabaga_utils::RutabagaResult; diff --git a/src/rutabaga_gfx/src/rutabaga_os/sys/unix/descriptor.rs b/src/rutabaga_gfx/src/rutabaga_os/sys/unix/descriptor.rs index 73d41c10e..ca775adca 100644 --- a/src/rutabaga_gfx/src/rutabaga_os/sys/unix/descriptor.rs +++ b/src/rutabaga_gfx/src/rutabaga_os/sys/unix/descriptor.rs @@ -109,7 +109,7 @@ macro_rules! FromRawDescriptor { ($name:ident) => { impl FromRawDescriptor for $name { unsafe fn from_raw_descriptor(descriptor: RawDescriptor) -> Self { - $name::from_raw_fd(descriptor) + unsafe { $name::from_raw_fd(descriptor) } } } }; diff --git a/src/rutabaga_gfx/src/rutabaga_os/sys/unix/memory_mapping.rs b/src/rutabaga_gfx/src/rutabaga_os/sys/unix/memory_mapping.rs index 581d3c971..fba73b0a7 100644 --- a/src/rutabaga_gfx/src/rutabaga_os/sys/unix/memory_mapping.rs +++ b/src/rutabaga_gfx/src/rutabaga_os/sys/unix/memory_mapping.rs @@ -7,10 +7,10 @@ use std::os::fd::AsFd; use std::ptr::NonNull; use libc::c_void; -use nix::sys::mman::mmap; -use nix::sys::mman::munmap; use nix::sys::mman::MapFlags; use nix::sys::mman::ProtFlags; +use nix::sys::mman::mmap; +use nix::sys::mman::munmap; use crate::rutabaga_os::descriptor::SafeDescriptor; use crate::rutabaga_utils::RutabagaError; diff --git a/src/rutabaga_gfx/src/rutabaga_os/sys/unix/mod.rs b/src/rutabaga_gfx/src/rutabaga_os/sys/unix/mod.rs index b34581ae0..9ecfde0f7 100644 --- a/src/rutabaga_gfx/src/rutabaga_os/sys/unix/mod.rs +++ b/src/rutabaga_gfx/src/rutabaga_os/sys/unix/mod.rs @@ -6,8 +6,8 @@ pub mod descriptor; pub mod memory_mapping; pub mod shm; +pub use shm::SharedMemory; #[allow(unused_imports)] pub use shm::round_up_to_page_size; -pub use shm::SharedMemory; pub use memory_mapping::MemoryMapping; diff --git a/src/rutabaga_gfx/src/rutabaga_os/sys/unix/shm.rs b/src/rutabaga_gfx/src/rutabaga_os/sys/unix/shm.rs index a01ced204..67a8f2b1c 100644 --- a/src/rutabaga_gfx/src/rutabaga_os/sys/unix/shm.rs +++ b/src/rutabaga_gfx/src/rutabaga_os/sys/unix/shm.rs @@ -7,16 +7,16 @@ use std::ffi::CStr; use std::os::unix::io::OwnedFd; use libc::off_t; -use nix::sys::memfd::memfd_create; use nix::sys::memfd::MFdFlags; +use nix::sys::memfd::memfd_create; +use nix::unistd::SysconfVar; use nix::unistd::ftruncate; use nix::unistd::sysconf; -use nix::unistd::SysconfVar; use vmm_sys_util::align_upwards; +use crate::rutabaga_os::RawDescriptor; use crate::rutabaga_os::descriptor::AsRawDescriptor; use crate::rutabaga_os::descriptor::IntoRawDescriptor; -use crate::rutabaga_os::RawDescriptor; use crate::rutabaga_utils::RutabagaError; use crate::rutabaga_utils::RutabagaResult; diff --git a/src/rutabaga_gfx/src/rutabaga_os/sys/windows/mod.rs b/src/rutabaga_gfx/src/rutabaga_os/sys/windows/mod.rs index 22f6db190..2ecc112bc 100644 --- a/src/rutabaga_gfx/src/rutabaga_os/sys/windows/mod.rs +++ b/src/rutabaga_gfx/src/rutabaga_os/sys/windows/mod.rs @@ -6,7 +6,7 @@ pub mod descriptor; pub mod memory_mapping; pub mod shm; -pub use shm::round_up_to_page_size; pub use shm::SharedMemory; +pub use shm::round_up_to_page_size; pub use memory_mapping::MemoryMapping; diff --git a/src/rutabaga_gfx/src/rutabaga_os/sys/windows/shm.rs b/src/rutabaga_gfx/src/rutabaga_os/sys/windows/shm.rs index 2afe7a1f5..b50d4a1bc 100644 --- a/src/rutabaga_gfx/src/rutabaga_os/sys/windows/shm.rs +++ b/src/rutabaga_gfx/src/rutabaga_os/sys/windows/shm.rs @@ -4,10 +4,10 @@ use std::ffi::CStr; -use crate::rutabaga_os::descriptor::AsRawDescriptor; -use crate::rutabaga_os::descriptor::IntoRawDescriptor; use crate::rutabaga_os::RawDescriptor; use crate::rutabaga_os::SafeDescriptor; +use crate::rutabaga_os::descriptor::AsRawDescriptor; +use crate::rutabaga_os::descriptor::IntoRawDescriptor; use crate::rutabaga_utils::RutabagaError; use crate::rutabaga_utils::RutabagaResult; diff --git a/src/rutabaga_gfx/src/rutabaga_utils.rs b/src/rutabaga_gfx/src/rutabaga_utils.rs index 1377ddccf..912200a7a 100644 --- a/src/rutabaga_gfx/src/rutabaga_utils.rs +++ b/src/rutabaga_gfx/src/rutabaga_utils.rs @@ -19,6 +19,10 @@ use nix::Error as NixError; use remain::sorted; use thiserror::Error; #[cfg(feature = "vulkano")] +use vulkano::LoadingError; +#[cfg(feature = "vulkano")] +use vulkano::VulkanError; +#[cfg(feature = "vulkano")] use vulkano::device::DeviceCreationError; #[cfg(feature = "vulkano")] use vulkano::image::ImageCreationError; @@ -28,10 +32,6 @@ use vulkano::instance::InstanceCreationError; use vulkano::memory::DeviceMemoryError; #[cfg(feature = "vulkano")] use vulkano::memory::MemoryMapError; -#[cfg(feature = "vulkano")] -use vulkano::LoadingError; -#[cfg(feature = "vulkano")] -use vulkano::VulkanError; use crate::rutabaga_os::SafeDescriptor; diff --git a/src/rutabaga_gfx/src/virgl_renderer.rs b/src/rutabaga_gfx/src/virgl_renderer.rs index a2627ca0d..c6adb753c 100644 --- a/src/rutabaga_gfx/src/virgl_renderer.rs +++ b/src/rutabaga_gfx/src/virgl_renderer.rs @@ -19,9 +19,9 @@ use std::os::unix::io::AsRawFd; use std::panic::catch_unwind; use std::process::abort; use std::ptr::null_mut; +use std::sync::Arc; use std::sync::atomic::AtomicBool; use std::sync::atomic::Ordering; -use std::sync::Arc; use log::debug; use log::error; @@ -212,7 +212,7 @@ extern "C" fn write_context_fence(cookie: *mut c_void, ctx_id: u32, ring_idx: u6 unsafe extern "C" fn write_fence(cookie: *mut c_void, fence: u32) { catch_unwind(|| { assert!(!cookie.is_null()); - let cookie = &*(cookie as *mut RutabagaCookie); + let cookie = unsafe { &*(cookie as *mut RutabagaCookie) }; // Call fence completion callback if let Some(handler) = &cookie.fence_handler { @@ -231,7 +231,7 @@ unsafe extern "C" fn write_fence(cookie: *mut c_void, fence: u32) { unsafe extern "C" fn get_server_fd(cookie: *mut c_void, version: u32) -> c_int { catch_unwind(|| { assert!(!cookie.is_null()); - let cookie = &mut *(cookie as *mut RutabagaCookie); + let cookie = unsafe { &mut *(cookie as *mut RutabagaCookie) }; if version != 0 { return -1; @@ -470,10 +470,10 @@ impl RutabagaComponent for VirglRenderer { fn poll_descriptor(&self) -> Option { // Safe because it can be called anytime and returns -1 in the event of an error. let fd = unsafe { virgl_renderer_get_poll_fd() }; - if fd >= 0 { - if let Ok(dup_fd) = SafeDescriptor::try_from(&fd as &dyn AsRawFd) { - return Some(dup_fd); - } + if fd >= 0 + && let Ok(dup_fd) = SafeDescriptor::try_from(&fd as &dyn AsRawFd) + { + return Some(dup_fd); } None } diff --git a/src/smbios/Cargo.toml b/src/smbios/Cargo.toml index 161858644..ebdf74153 100644 --- a/src/smbios/Cargo.toml +++ b/src/smbios/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "krun-smbios" version = "0.1.0-1.18.0" -edition = "2021" +edition = "2024" description = "SMBIOS table generation for libkrun" license = "Apache-2.0" repository = "https://github.com/containers/libkrun" diff --git a/src/utils/Cargo.toml b/src/utils/Cargo.toml index f24921bc4..5b2e88757 100644 --- a/src/utils/Cargo.toml +++ b/src/utils/Cargo.toml @@ -2,7 +2,7 @@ name = "krun-utils" version = "0.1.0-1.18.0" authors = ["The libkrun Authors"] -edition = "2021" +edition = "2024" description = "Utility helpers for libkrun" license = "Apache-2.0" repository = "https://github.com/containers/libkrun" diff --git a/src/utils/src/byte_order.rs b/src/utils/src/byte_order.rs index 753ef8870..957301766 100644 --- a/src/utils/src/byte_order.rs +++ b/src/utils/src/byte_order.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 macro_rules! generate_read_fn { - ($fn_name: ident, $data_type: ty, $byte_type: ty, $type_size: expr, $endian_type: ident) => { + ($fn_name: ident, $data_type: ty, $byte_type: ty, $type_size: expr_2021, $endian_type: ident) => { pub fn $fn_name(input: &[$byte_type]) -> $data_type { assert!($type_size == std::mem::size_of::<$data_type>()); let mut array = [0u8; $type_size]; @@ -47,7 +47,7 @@ generate_write_fn!(write_be_u32, u32, u8, to_be_bytes); mod tests { use super::*; macro_rules! byte_order_test_read_write { - ($test_name: ident, $write_fn_name: ident, $read_fn_name: ident, $is_be: expr, $data_type: ty) => { + ($test_name: ident, $write_fn_name: ident, $read_fn_name: ident, $is_be: expr_2021, $data_type: ty) => { #[test] fn $test_name() { #[allow(overflowing_literals)] diff --git a/src/utils/src/linux/epoll.rs b/src/utils/src/linux/epoll.rs index e41544582..ba687d105 100644 --- a/src/utils/src/linux/epoll.rs +++ b/src/utils/src/linux/epoll.rs @@ -7,9 +7,9 @@ use std::os::unix::io::{AsRawFd, RawFd}; use bitflags::bitflags; use libc::{ - epoll_create1, epoll_ctl, epoll_event, epoll_wait, EPOLLERR, EPOLLET, EPOLLEXCLUSIVE, EPOLLHUP, - EPOLLIN, EPOLLONESHOT, EPOLLOUT, EPOLLPRI, EPOLLRDHUP, EPOLLWAKEUP, EPOLL_CLOEXEC, - EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD, + EPOLL_CLOEXEC, EPOLL_CTL_ADD, EPOLL_CTL_DEL, EPOLL_CTL_MOD, EPOLLERR, EPOLLET, EPOLLEXCLUSIVE, + EPOLLHUP, EPOLLIN, EPOLLONESHOT, EPOLLOUT, EPOLLPRI, EPOLLRDHUP, EPOLLWAKEUP, epoll_create1, + epoll_ctl, epoll_event, epoll_wait, }; use crate::syscall::SyscallReturnCode; @@ -266,35 +266,43 @@ mod tests { // For EPOLL_CTL_ADD behavior we will try to add some fds with different event masks into // the interest list of epoll instance. - assert!(epoll - .ctl(ControlOperation::Add, event_fd_1.as_raw_fd(), &event_1) - .is_ok()); + assert!( + epoll + .ctl(ControlOperation::Add, event_fd_1.as_raw_fd(), &event_1) + .is_ok() + ); // We can't add twice the same fd to epoll interest list. - assert!(epoll - .ctl(ControlOperation::Add, event_fd_1.as_raw_fd(), &event_1) - .is_err()); + assert!( + epoll + .ctl(ControlOperation::Add, event_fd_1.as_raw_fd(), &event_1) + .is_err() + ); let event_fd_2 = EventFd::new(libc::EFD_NONBLOCK).unwrap(); event_fd_2.write(1).unwrap(); - assert!(epoll - .ctl( - ControlOperation::Add, - event_fd_2.as_raw_fd(), - // For this fd, we want an Event instance that has `data` field set to other - // value than the value of the fd and `events` without EPOLLIN type set. - &EpollEvent::new(EventSet::OUT, 10) - ) - .is_ok()); + assert!( + epoll + .ctl( + ControlOperation::Add, + event_fd_2.as_raw_fd(), + // For this fd, we want an Event instance that has `data` field set to other + // value than the value of the fd and `events` without EPOLLIN type set. + &EpollEvent::new(EventSet::OUT, 10) + ) + .is_ok() + ); // For the following eventfd we won't write anything to its counter, so we expect EPOLLIN // event to not be available for this fd, even if we say that we want to monitor this type // of event via EPOLL_CTL_ADD operation. let event_fd_3 = EventFd::new(libc::EFD_NONBLOCK).unwrap(); let event_3 = EpollEvent::new(EventSet::OUT | EventSet::IN, event_fd_3.as_raw_fd() as u64); - assert!(epoll - .ctl(ControlOperation::Add, event_fd_3.as_raw_fd(), &event_3) - .is_ok()); + assert!( + epoll + .ctl(ControlOperation::Add, event_fd_3.as_raw_fd(), &event_3) + .is_ok() + ); // Let's check `epoll_wait()` behavior for our epoll instance. let mut ready_events = vec![EpollEvent::default(); EVENT_BUFFER_SIZE]; @@ -328,19 +336,23 @@ mod tests { // We create here a new Event with some events, other than those previously set, // that we want to monitor this time on event_fd_1. event_1 = EpollEvent::new(EventSet::OUT, 20); - assert!(epoll - .ctl(ControlOperation::Modify, event_fd_1.as_raw_fd(), &event_1) - .is_ok()); + assert!( + epoll + .ctl(ControlOperation::Modify, event_fd_1.as_raw_fd(), &event_1) + .is_ok() + ); let event_fd_4 = EventFd::new(libc::EFD_NONBLOCK).unwrap(); // Can't modify a fd that wasn't added to epoll interest list. - assert!(epoll - .ctl( - ControlOperation::Modify, - event_fd_4.as_raw_fd(), - &EpollEvent::default() - ) - .is_err()); + assert!( + epoll + .ctl( + ControlOperation::Modify, + event_fd_4.as_raw_fd(), + &EpollEvent::default() + ) + .is_err() + ); let _ = epoll .wait(MAX_EVENTS, DEFAULT__TIMEOUT, &mut ready_events[..]) @@ -352,13 +364,15 @@ mod tests { assert_eq!(ready_events[0].events(), EventSet::OUT.bits()); // Now let's set for a fd to not have any events monitored. - assert!(epoll - .ctl( - ControlOperation::Modify, - event_fd_1.as_raw_fd(), - &EpollEvent::default() - ) - .is_ok()); + assert!( + epoll + .ctl( + ControlOperation::Modify, + event_fd_1.as_raw_fd(), + &EpollEvent::default() + ) + .is_ok() + ); // In this particular case we expect to remain only with 2 fds in the ready list. ev_count = epoll @@ -367,13 +381,15 @@ mod tests { assert_eq!(ev_count, 2); // Let's also delete a fd from the interest list. - assert!(epoll - .ctl( - ControlOperation::Delete, - event_fd_2.as_raw_fd(), - &EpollEvent::default() - ) - .is_ok()); + assert!( + epoll + .ctl( + ControlOperation::Delete, + event_fd_2.as_raw_fd(), + &EpollEvent::default() + ) + .is_ok() + ); // We expect to have only one fd remained in the ready list (event_fd_3). ev_count = epoll @@ -385,12 +401,14 @@ mod tests { assert_eq!(ready_events[0].events(), EventSet::OUT.bits()); // If we try to remove a fd from epoll interest list that wasn't added before it will fail. - assert!(epoll - .ctl( - ControlOperation::Delete, - event_fd_4.as_raw_fd(), - &EpollEvent::default() - ) - .is_err()); + assert!( + epoll + .ctl( + ControlOperation::Delete, + event_fd_4.as_raw_fd(), + &EpollEvent::default() + ) + .is_err() + ); } } diff --git a/src/utils/src/macos/epoll.rs b/src/utils/src/macos/epoll.rs index 28005a19f..cae27154a 100644 --- a/src/utils/src/macos/epoll.rs +++ b/src/utils/src/macos/epoll.rs @@ -375,7 +375,7 @@ impl AsRawFd for Epoll { mod tests { use super::*; - use crate::eventfd::{EventFd, EFD_NONBLOCK}; + use crate::eventfd::{EFD_NONBLOCK, EventFd}; #[test] fn test_event_ops() { @@ -419,25 +419,29 @@ mod tests { // For EPOLL_CTL_ADD behavior we will try to add some fds with different event masks into // the interest list of epoll instance. - assert!(epoll - .ctl( - ControlOperation::Add, - event_fd_1.as_raw_fd() as i32, - &event_1 - ) - .is_ok()); + assert!( + epoll + .ctl( + ControlOperation::Add, + event_fd_1.as_raw_fd() as i32, + &event_1 + ) + .is_ok() + ); let event_fd_2 = EventFd::new(EFD_NONBLOCK).unwrap(); event_fd_2.write(1).unwrap(); - assert!(epoll - .ctl( - ControlOperation::Add, - event_fd_2.as_raw_fd() as i32, - // For this fd, we want an Event instance that has `data` field set to other - // value than the value of the fd and `events` without EPOLLIN type set. - &EpollEvent::new(EventSet::IN, 10) - ) - .is_ok()); + assert!( + epoll + .ctl( + ControlOperation::Add, + event_fd_2.as_raw_fd() as i32, + // For this fd, we want an Event instance that has `data` field set to other + // value than the value of the fd and `events` without EPOLLIN type set. + &EpollEvent::new(EventSet::IN, 10) + ) + .is_ok() + ); // Let's check `epoll_wait()` behavior for our epoll instance. let mut ready_events = vec![EpollEvent::default(); EVENT_BUFFER_SIZE]; @@ -458,13 +462,15 @@ mod tests { assert_eq!(ready_events[1].events(), EventSet::IN.bits()); // Let's also delete a fd from the interest list. - assert!(epoll - .ctl( - ControlOperation::Delete, - event_fd_2.as_raw_fd() as i32, - &EpollEvent::default() - ) - .is_ok()); + assert!( + epoll + .ctl( + ControlOperation::Delete, + event_fd_2.as_raw_fd() as i32, + &EpollEvent::default() + ) + .is_ok() + ); // We expect to have only one fd remained in the ready list (event_fd_3). ev_count = epoll diff --git a/src/utils/src/macos/eventfd.rs b/src/utils/src/macos/eventfd.rs index c66ffbad7..d31f0cc44 100644 --- a/src/utils/src/macos/eventfd.rs +++ b/src/utils/src/macos/eventfd.rs @@ -11,7 +11,7 @@ use std::os::unix::io::{AsRawFd, RawFd}; use std::{io, result}; use nix::errno::Errno; -use nix::fcntl::{fcntl, FcntlArg, OFlag}; +use nix::fcntl::{FcntlArg, OFlag, fcntl}; use nix::unistd::{dup, pipe, read, write}; pub const EFD_NONBLOCK: i32 = 1; diff --git a/src/utils/src/pollable_channel.rs b/src/utils/src/pollable_channel.rs index bc9ad8883..bd7939473 100644 --- a/src/utils/src/pollable_channel.rs +++ b/src/utils/src/pollable_channel.rs @@ -1,4 +1,4 @@ -use crate::eventfd::{EventFd, EFD_NONBLOCK, EFD_SEMAPHORE}; +use crate::eventfd::{EFD_NONBLOCK, EFD_SEMAPHORE, EventFd}; use std::collections::VecDeque; use std::io; use std::io::ErrorKind; @@ -10,8 +10,8 @@ use crate::windows::{AsRawFd, RawFd}; use std::os::fd::{AsFd, AsRawFd, BorrowedFd, RawFd}; /// A multiple producer single consumer channel that can be listened to by a file descriptor -pub fn pollable_channel( -) -> io::Result<(PollableChannelSender, PollableChannelReciever)> { +pub fn pollable_channel() +-> io::Result<(PollableChannelSender, PollableChannelReciever)> { let eventfd = EventFd::new(EFD_NONBLOCK | EFD_SEMAPHORE)?; let inner = Arc::new(Inner { diff --git a/src/utils/src/signal.rs b/src/utils/src/signal.rs index ea375dcaf..f4b2439d8 100644 --- a/src/utils/src/signal.rs +++ b/src/utils/src/signal.rs @@ -1,7 +1,7 @@ use libc::c_int; pub use vmm_sys_util::signal::*; -extern "C" { +unsafe extern "C" { fn __libc_current_sigrtmin() -> c_int; fn __libc_current_sigrtmax() -> c_int; } diff --git a/src/utils/src/windows/epoll.rs b/src/utils/src/windows/epoll.rs index 45bcd30b5..d880cf043 100644 --- a/src/utils/src/windows/epoll.rs +++ b/src/utils/src/windows/epoll.rs @@ -40,10 +40,10 @@ use super::{AsRawFd, RawFd}; use windows_sys::Win32::Foundation::{ CloseHandle, HANDLE, INVALID_HANDLE_VALUE, WAIT_TIMEOUT as WAIT_TIMEOUT_CODE, }; -use windows_sys::Win32::System::Threading::INFINITE; use windows_sys::Win32::System::IO::{ CreateIoCompletionPort, GetQueuedCompletionStatusEx, OVERLAPPED_ENTRY, }; +use windows_sys::Win32::System::Threading::INFINITE; // Generic access mask requesting all permissions the caller is allowed. // https://learn.microsoft.com/en-us/windows/win32/secauthz/access-mask @@ -513,12 +513,16 @@ mod tests { epoll .ctl(ControlOperation::Delete, ev, &EpollEvent::default()) .unwrap(); - assert!(epoll - .ctl(ControlOperation::Delete, ev, &EpollEvent::default()) - .is_err()); - assert!(epoll - .ctl(ControlOperation::Modify, ev, &EpollEvent::default()) - .is_err()); + assert!( + epoll + .ctl(ControlOperation::Delete, ev, &EpollEvent::default()) + .is_err() + ); + assert!( + epoll + .ctl(ControlOperation::Modify, ev, &EpollEvent::default()) + .is_err() + ); close(ev); } @@ -536,9 +540,11 @@ mod tests { epoll2 .ctl(ControlOperation::Delete, ev, &EpollEvent::default()) .unwrap(); - assert!(epoll - .ctl(ControlOperation::Delete, ev, &EpollEvent::default()) - .is_err()); + assert!( + epoll + .ctl(ControlOperation::Delete, ev, &EpollEvent::default()) + .is_err() + ); close(ev); } diff --git a/src/utils/src/windows/eventfd.rs b/src/utils/src/windows/eventfd.rs index eb87c47d0..f3f68eaa3 100644 --- a/src/utils/src/windows/eventfd.rs +++ b/src/utils/src/windows/eventfd.rs @@ -5,7 +5,7 @@ use std::{io, result}; use windows_sys::Win32::Foundation::{CloseHandle, HANDLE, WAIT_OBJECT_0}; use windows_sys::Win32::System::Threading::{ - CreateEventW, ResetEvent, SetEvent, WaitForSingleObject, INFINITE, + CreateEventW, INFINITE, ResetEvent, SetEvent, WaitForSingleObject, }; use super::{AsRawFd, RawFd}; diff --git a/src/vmm/Cargo.toml b/src/vmm/Cargo.toml index 377f9c731..c16bd6ff9 100644 --- a/src/vmm/Cargo.toml +++ b/src/vmm/Cargo.toml @@ -2,7 +2,7 @@ name = "krun-vmm" version = "0.1.0-1.18.0" authors = ["The libkrun Authors"] -edition = "2021" +edition = "2024" build = "build.rs" description = "Virtual machine monitor for libkrun" license = "Apache-2.0" diff --git a/src/vmm/src/builder.rs b/src/vmm/src/builder.rs index b92b931d4..f2b6f4853 100644 --- a/src/vmm/src/builder.rs +++ b/src/vmm/src/builder.rs @@ -3,9 +3,9 @@ //! Enables pre-boot setup, instantiation and booting of a Firecracker VMM. +use crossbeam_channel::Sender; #[cfg(target_os = "macos")] use crossbeam_channel::unbounded; -use crossbeam_channel::Sender; use kernel::cmdline::Cmdline; #[cfg(target_os = "macos")] use std::collections::HashMap; @@ -45,7 +45,7 @@ use devices::legacy::{IoApic, IrqChipT}; use devices::legacy::{IrqChip, IrqChipDevice}; #[cfg(all(target_os = "linux", target_arch = "aarch64"))] use devices::legacy::{KvmGicV2, KvmGicV3}; -use devices::virtio::{port_io, MmioTransport, PortDescription, VirtioDevice, Vsock}; +use devices::virtio::{MmioTransport, PortDescription, VirtioDevice, Vsock, port_io}; #[cfg(feature = "tee")] use kbs_types::Tee; @@ -75,7 +75,7 @@ use devices::virtio::display::DisplayInfo; #[cfg(feature = "gpu")] use devices::virtio::display::NoopDisplayBackend; #[cfg(not(any(feature = "tee", feature = "aws-nitro")))] -use devices::virtio::{fs::ExportTable, VirtioShmRegion}; +use devices::virtio::{VirtioShmRegion, fs::ExportTable}; use flate2::read::GzDecoder; #[cfg(feature = "gpu")] use krun_display::DisplayBackend; @@ -90,8 +90,6 @@ use nix::unistd::isatty; use polly::event_manager::{Error as EventManagerError, EventManager}; use utils::eventfd::EventFd; use utils::worker_message::WorkerMessage; -#[cfg(all(target_arch = "x86_64", not(feature = "tee")))] -use vm_memory::mmap::MmapRegion; #[cfg(not(any(feature = "tee", feature = "aws-nitro")))] use vm_memory::Address; use vm_memory::Bytes; @@ -101,6 +99,8 @@ use vm_memory::FileOffset; use vm_memory::GuestMemory; #[cfg(all(target_arch = "x86_64", not(feature = "tee")))] use vm_memory::GuestRegionMmap; +#[cfg(all(target_arch = "x86_64", not(feature = "tee")))] +use vm_memory::mmap::MmapRegion; use vm_memory::{GuestAddress, GuestMemoryMmap}; /// Errors associated with starting the instance. @@ -1405,8 +1405,11 @@ fn load_payload( // kernel_size bytes. Regions don't overlap as dest is newly allocated memfd-backed // memory and source is from kernel bundle. unsafe { - let dest = region.as_ptr() as *mut u8; - std::ptr::copy_nonoverlapping(kernel_data.as_ptr(), dest, kernel_size); + std::ptr::copy_nonoverlapping( + kernel_data.as_ptr(), + region.as_ptr(), + kernel_size, + ); } debug!("Copied kernel data to file-backed region"); @@ -1657,12 +1660,12 @@ pub fn create_guest_memory( // Only write firmware if data exists AND this isn't an ExternalKernel payload // (ExternalKernel does direct kernel boot and doesn't use EFI firmware) - if !matches!(payload, Payload::ExternalKernel(_)) { - if let Some(firmware_data) = firmware_data.as_ref() { - guest_mem - .write(firmware_data, GuestAddress(arch_mem_info.firmware_addr)) - .map_err(StartMicrovmError::FirmwareInvalidAddress)?; - } + if !matches!(payload, Payload::ExternalKernel(_)) + && let Some(firmware_data) = firmware_data.as_ref() + { + guest_mem + .write(firmware_data, GuestAddress(arch_mem_info.firmware_addr)) + .map_err(StartMicrovmError::FirmwareInvalidAddress)?; } let payload_config = PayloadConfig { @@ -1747,15 +1750,13 @@ pub fn setup_serial_device( .map_err(StartMicrovmError::Internal)?; let has_input = input.is_some(); let serial = Arc::new(Mutex::new(Serial::new(interrupt_evt, out, input))); - if has_input { - if let Err(e) = event_manager.add_subscriber(serial.clone()) { - // TODO: We just log this message, and immediately return Ok, instead of returning the - // actual error because this operation always fails with EPERM when adding a fd which - // has been redirected to /dev/null via dup2 (this may happen inside the jailer). - // Find a better solution to this (and think about the state of the serial device - // while we're at it). - warn!("Could not add serial input event to epoll: {e:?}"); - } + if has_input && let Err(e) = event_manager.add_subscriber(serial.clone()) { + // TODO: We just log this message, and immediately return Ok, instead of returning the + // actual error because this operation always fails with EPERM when adding a fd which + // has been redirected to /dev/null via dup2 (this may happen inside the jailer). + // Find a better solution to this (and think about the state of the serial device + // while we're at it). + warn!("Could not add serial input event to epoll: {e:?}"); } Ok(serial) } @@ -1781,7 +1782,7 @@ fn attach_legacy_devices( } macro_rules! register_irqfd_evt { - ($evt: ident, $index: expr) => {{ + ($evt: ident, $index: expr_2021) => {{ vm.fd() .register_irqfd(&pio_device_manager.$evt, $index) .map_err(|e| { @@ -2083,10 +2084,11 @@ fn autoconfigure_console_ports( use self::StartMicrovmError::*; let mut console_output_path: Option = None; - if let Some(path) = vm_resources.console_output.clone() { - if !vm_resources.disable_implicit_console && creating_implicit_console { - console_output_path = Some(path) - } + if let Some(path) = vm_resources.console_output.clone() + && !vm_resources.disable_implicit_console + && creating_implicit_console + { + console_output_path = Some(path) } if let Some(console_output_path) = console_output_path { @@ -2543,7 +2545,7 @@ pub mod tests { let (guest_memory, _arch_memory_info, _shm_manager, _payload_config) = default_guest_memory(128).unwrap(); let vm = setup_vm(&guest_memory, false).unwrap(); - let _kvmioapic = KvmIoapic::new(&vm.fd()).unwrap(); + let _kvmioapic = KvmIoapic::new(vm.fd()).unwrap(); // Dummy entry_addr, vcpus will not boot. let entry_addr = GuestAddress(0); diff --git a/src/vmm/src/device_manager/hvf/mmio.rs b/src/vmm/src/device_manager/hvf/mmio.rs index 6fd545465..eb2ab551b 100644 --- a/src/vmm/src/device_manager/hvf/mmio.rs +++ b/src/vmm/src/device_manager/hvf/mmio.rs @@ -292,10 +292,9 @@ impl MMIODeviceManager { if let Some(dev_info) = self .id_to_dev_info .get(&(device_type, device_id.to_string())) + && let Some((_, device)) = self.bus.get_device(dev_info.addr) { - if let Some((_, device)) = self.bus.get_device(dev_info.addr) { - return Some(device); - } + return Some(device); } None } @@ -427,9 +426,11 @@ mod tests { let mut cmdline = kernel_cmdline::Cmdline::new(4096); let dummy = Arc::new(Mutex::new(DummyDevice::new())); - assert!(device_manager - .register_virtio_device(guest_mem, dummy, &mut cmdline, 0, "dummy") - .is_ok()); + assert!( + device_manager + .register_virtio_device(guest_mem, dummy, &mut cmdline, 0, "dummy") + .is_ok() + ); } #[test] @@ -544,9 +545,11 @@ mod tests { if let Ok(addr) = device_manager.register_virtio_device(guest_mem, dummy, &mut cmdline, type_id, &id) { - assert!(device_manager - .get_device(DeviceType::Virtio(type_id), &id) - .is_some()); + assert!( + device_manager + .get_device(DeviceType::Virtio(type_id), &id) + .is_some() + ); assert_eq!( addr, device_manager.id_to_dev_info[&(DeviceType::Virtio(type_id), id.clone())].addr @@ -557,8 +560,10 @@ mod tests { ); } let id = "bar"; - assert!(device_manager - .get_device(DeviceType::Virtio(type_id), &id) - .is_none()); + assert!( + device_manager + .get_device(DeviceType::Virtio(type_id), &id) + .is_none() + ); } } diff --git a/src/vmm/src/device_manager/kvm/mmio.rs b/src/vmm/src/device_manager/kvm/mmio.rs index f2e0a687b..f295d9955 100644 --- a/src/vmm/src/device_manager/kvm/mmio.rs +++ b/src/vmm/src/device_manager/kvm/mmio.rs @@ -288,10 +288,9 @@ impl MMIODeviceManager { if let Some(dev_info) = self .id_to_dev_info .get(&(device_type, device_id.to_string())) + && let Some((_, device)) = self.bus.get_device(dev_info.addr) { - if let Some((_, device)) = self.bus.get_device(dev_info.addr) { - return Some(device); - } + return Some(device); } None } @@ -389,7 +388,7 @@ mod tests { } fn queue_config(&self) -> &[QueueConfig] { - &QUEUE_CONFIG + QUEUE_CONFIG } fn read_config(&self, offset: u64, data: &mut [u8]) { @@ -433,9 +432,11 @@ mod tests { let mut cmdline = kernel_cmdline::Cmdline::new(4096); let dummy = Arc::new(Mutex::new(DummyDevice::new())); - assert!(device_manager - .register_virtio_device(vm.fd(), guest_mem, dummy, &mut cmdline, 0, "dummy") - .is_ok()); + assert!( + device_manager + .register_virtio_device(vm.fd(), guest_mem, dummy, &mut cmdline, 0, "dummy") + .is_ok() + ); } #[test] @@ -563,9 +564,11 @@ mod tests { type_id, &id, ) { - assert!(device_manager - .get_device(DeviceType::Virtio(type_id), &id) - .is_some()); + assert!( + device_manager + .get_device(DeviceType::Virtio(type_id), &id) + .is_some() + ); assert_eq!( addr, device_manager.id_to_dev_info[&(DeviceType::Virtio(type_id), id.clone())].addr @@ -576,8 +579,10 @@ mod tests { ); } let id = "bar"; - assert!(device_manager - .get_device(DeviceType::Virtio(type_id), id) - .is_none()); + assert!( + device_manager + .get_device(DeviceType::Virtio(type_id), id) + .is_none() + ); } } diff --git a/src/vmm/src/linux/tee/amdsnp/launch/util/impl_const_id.rs b/src/vmm/src/linux/tee/amdsnp/launch/util/impl_const_id.rs index ad8ec8867..24eeda395 100644 --- a/src/vmm/src/linux/tee/amdsnp/launch/util/impl_const_id.rs +++ b/src/vmm/src/linux/tee/amdsnp/launch/util/impl_const_id.rs @@ -9,7 +9,7 @@ macro_rules! impl_const_id { $(#[$outer:meta])* $visibility:vis $trait:ident => $id_ty:ty; $( - $iocty:ty = $val:expr + $iocty:ty = $val:expr_2021 ),* $(,)* ) => { $(#[$outer])* diff --git a/src/vmm/src/linux/tee/amdsnp/mod.rs b/src/vmm/src/linux/tee/amdsnp/mod.rs index 1474a0be8..bb5bb346d 100644 --- a/src/vmm/src/linux/tee/amdsnp/mod.rs +++ b/src/vmm/src/linux/tee/amdsnp/mod.rs @@ -10,7 +10,7 @@ use arch::x86_64::layout::*; use launch::{error::FirmwareError, firmware::Firmware, *}; -use kvm_bindings::{kvm_enc_region, CpuId, KVM_CPUID_FLAG_SIGNIFCANT_INDEX}; +use kvm_bindings::{CpuId, KVM_CPUID_FLAG_SIGNIFCANT_INDEX, kvm_enc_region}; use kvm_ioctls::VmFd; use vm_memory::{ Bytes, GuestAddress, GuestMemory, GuestMemoryMmap, GuestMemoryRegion, GuestRegionMmap, diff --git a/src/vmm/src/linux/vstate.rs b/src/vmm/src/linux/vstate.rs index 05e58fbd7..c64ba817f 100644 --- a/src/vmm/src/linux/vstate.rs +++ b/src/vmm/src/linux/vstate.rs @@ -7,7 +7,7 @@ #[cfg(target_arch = "aarch64")] use arch::ArchMemoryInfo; -use crossbeam_channel::{unbounded, Receiver, Sender, TryRecvError}; +use crossbeam_channel::{Receiver, Sender, TryRecvError, unbounded}; use libc::{c_int, c_void, siginfo_t}; use std::cell::Cell; use std::fmt::{Display, Formatter}; @@ -19,9 +19,9 @@ use std::os::unix::io::RawFd; #[cfg(target_arch = "x86_64")] use std::env; use std::result; -use std::sync::atomic::{fence, Ordering}; #[cfg(not(test))] use std::sync::Barrier; +use std::sync::atomic::{Ordering, fence}; use std::thread; #[cfg(target_arch = "x86_64")] use std::time::Duration; @@ -41,25 +41,25 @@ use kbs_types::Tee; use crate::resources::TeeConfig; use crate::vmm_config::machine_config::CpuFeaturesTemplate; #[cfg(target_arch = "x86_64")] -use cpuid::{c3, filter_cpuid, t2, VmSpec}; +use cpuid::{VmSpec, c3, filter_cpuid, t2}; #[cfg(target_arch = "x86_64")] use kvm_bindings::{ - kvm_clock_data, kvm_debugregs, kvm_irqchip, kvm_lapic_state, kvm_mp_state, kvm_pit_state2, - kvm_regs, kvm_sregs, kvm_vcpu_events, kvm_xcrs, kvm_xsave, CpuId, MsrList, Msrs, - KVM_CLOCK_TSC_STABLE, KVM_IRQCHIP_IOAPIC, KVM_IRQCHIP_PIC_MASTER, KVM_IRQCHIP_PIC_SLAVE, - KVM_MAX_CPUID_ENTRIES, + CpuId, KVM_CLOCK_TSC_STABLE, KVM_IRQCHIP_IOAPIC, KVM_IRQCHIP_PIC_MASTER, KVM_IRQCHIP_PIC_SLAVE, + KVM_MAX_CPUID_ENTRIES, MsrList, Msrs, kvm_clock_data, kvm_debugregs, kvm_irqchip, + kvm_lapic_state, kvm_mp_state, kvm_pit_state2, kvm_regs, kvm_sregs, kvm_vcpu_events, kvm_xcrs, + kvm_xsave, }; use kvm_bindings::{ - kvm_create_guest_memfd, kvm_userspace_memory_region, kvm_userspace_memory_region2, KVM_API_VERSION, KVM_MEM_GUEST_MEMFD, KVM_SYSTEM_EVENT_RESET, KVM_SYSTEM_EVENT_SHUTDOWN, + kvm_create_guest_memfd, kvm_userspace_memory_region, kvm_userspace_memory_region2, }; #[cfg(feature = "tee")] -use kvm_bindings::{kvm_enable_cap, KVM_CAP_EXIT_HYPERCALL, KVM_MEMORY_EXIT_FLAG_PRIVATE}; +use kvm_bindings::{KVM_CAP_EXIT_HYPERCALL, KVM_MEMORY_EXIT_FLAG_PRIVATE, kvm_enable_cap}; #[cfg(not(target_arch = "riscv64"))] -use kvm_bindings::{kvm_memory_attributes, KVM_MEMORY_ATTRIBUTE_PRIVATE}; +use kvm_bindings::{KVM_MEMORY_ATTRIBUTE_PRIVATE, kvm_memory_attributes}; use kvm_ioctls::{Cap::*, *}; use utils::eventfd::EventFd; -use utils::signal::{register_signal_handler, sigrtmin, Killable}; +use utils::signal::{Killable, register_signal_handler, sigrtmin}; use utils::sm::StateMachine; #[cfg(feature = "tee")] use utils::worker_message::{MemoryProperties, WorkerMessage}; @@ -981,11 +981,11 @@ impl Vcpu { // Best-effort to clean up TLS. If the `Vcpu` was moved to another thread // _before_ running this, then there is nothing we can do. Self::TLS_VCPU_PTR.with(|cell: &VcpuCell| { - if let Some(vcpu_ptr) = cell.get() { - if std::ptr::eq(vcpu_ptr, self) { - Self::TLS_VCPU_PTR.with(|cell: &VcpuCell| cell.take()); - return Ok(()); - } + if let Some(vcpu_ptr) = cell.get() + && std::ptr::eq(vcpu_ptr, self) + { + Self::TLS_VCPU_PTR.with(|cell: &VcpuCell| cell.take()); + return Ok(()); } Err(Error::VcpuTlsNotPresent) }) @@ -1005,17 +1005,19 @@ impl Vcpu { where F: FnOnce(&mut Vcpu), { - Self::TLS_VCPU_PTR.with(|cell: &VcpuCell| { - if let Some(vcpu_ptr) = cell.get() { - // Dereferencing here is safe since `TLS_VCPU_PTR` is populated/non-empty, - // and it is being cleared on `Vcpu::drop` so there is no dangling pointer. - let vcpu_ref: &mut Vcpu = &mut *vcpu_ptr; - func(vcpu_ref); - Ok(()) - } else { - Err(Error::VcpuTlsNotPresent) - } - }) + unsafe { + Self::TLS_VCPU_PTR.with(|cell: &VcpuCell| { + if let Some(vcpu_ptr) = cell.get() { + // Dereferencing here is safe since `TLS_VCPU_PTR` is populated/non-empty, + // and it is being cleared on `Vcpu::drop` so there is no dangling pointer. + let vcpu_ref: &mut Vcpu = &mut *vcpu_ptr; + func(vcpu_ref); + Ok(()) + } else { + Err(Error::VcpuTlsNotPresent) + } + }) + } } /// Registers a signal handler which makes use of TLS and kvm immediate exit to @@ -1462,7 +1464,9 @@ impl Vcpu { )) .unwrap(); if !response_receiver.recv().unwrap() { - error!("Unable to convert memory with properties: gpa: 0x{gpa:x} size: 0x{size:x} to_private: {private}"); + error!( + "Unable to convert memory with properties: gpa: 0x{gpa:x} size: 0x{size:x} to_private: {private}" + ); return Err(Error::VcpuUnhandledKvmExit); } Ok(VcpuEmulation::Handled) @@ -1493,7 +1497,9 @@ impl Vcpu { )) .unwrap(); if !response_receiver.recv().unwrap() { - error!("Unable to convert memory with properties: gpa: 0x{gpa:x} size: 0x{size:x} to_private: {private}"); + error!( + "Unable to convert memory with properties: gpa: 0x{gpa:x} size: 0x{size:x} to_private: {private}" + ); return Err(Error::VcpuUnhandledKvmExit); } Ok(VcpuEmulation::Handled) @@ -1794,10 +1800,10 @@ mod tests { use super::*; #[cfg(target_arch = "aarch64")] - use crate::builder::create_guest_memory; - #[cfg(target_arch = "aarch64")] use crate::builder::Payload; #[cfg(target_arch = "aarch64")] + use crate::builder::create_guest_memory; + #[cfg(target_arch = "aarch64")] use crate::resources::VmResources; use devices; #[cfg(target_arch = "x86_64")] @@ -1824,7 +1830,7 @@ mod tests { let gm = GuestMemoryMmap::from_ranges(&[(GuestAddress(0), mem_size)]).unwrap(); let mut vm = Vm::new(kvm.fd()).expect("Cannot create new vm"); #[cfg(target_arch = "x86_64")] - let _kvmioapic = KvmIoapic::new(&vm.fd()).unwrap(); + let _kvmioapic = KvmIoapic::new(vm.fd()).unwrap(); assert!(vm.memory_init(&gm, kvm.max_memslots()).is_ok()); let exit_evt = EventFd::new(utils::eventfd::EFD_NONBLOCK).unwrap(); @@ -1903,21 +1909,24 @@ mod tests { nested_enabled: false, }; - assert!(vcpu - .configure_x86_64(&vm_mem, GuestAddress(0), &vcpu_config, true) - .is_ok()); + assert!( + vcpu.configure_x86_64(&vm_mem, GuestAddress(0), &vcpu_config, true) + .is_ok() + ); // Test configure while using the T2 template. vcpu_config.cpu_template = Some(CpuFeaturesTemplate::T2); - assert!(vcpu - .configure_x86_64(&vm_mem, GuestAddress(0), &vcpu_config, true) - .is_ok()); + assert!( + vcpu.configure_x86_64(&vm_mem, GuestAddress(0), &vcpu_config, true) + .is_ok() + ); // Test configure while using the C3 template. vcpu_config.cpu_template = Some(CpuFeaturesTemplate::C3); - assert!(vcpu - .configure_x86_64(&vm_mem, GuestAddress(0), &vcpu_config, true) - .is_ok()); + assert!( + vcpu.configure_x86_64(&vm_mem, GuestAddress(0), &vcpu_config, true) + .is_ok() + ); } #[cfg(target_arch = "aarch64")] @@ -1938,9 +1947,10 @@ mod tests { ) .unwrap(); - assert!(vcpu - .configure_aarch64(vm.fd(), &arch_memory_info, GuestAddress(0)) - .is_ok()); + assert!( + vcpu.configure_aarch64(vm.fd(), &arch_memory_info, GuestAddress(0)) + .is_ok() + ); // Try it for when vcpu id is NOT 0. let mut vcpu = Vcpu::new_aarch64( @@ -1950,9 +1960,10 @@ mod tests { ) .unwrap(); - assert!(vcpu - .configure_aarch64(vm.fd(), &arch_memory_info, GuestAddress(0)) - .is_ok()); + assert!( + vcpu.configure_aarch64(vm.fd(), &arch_memory_info, GuestAddress(0)) + .is_ok() + ); } #[test] diff --git a/src/vmm/src/macos/vstate.rs b/src/vmm/src/macos/vstate.rs index 92db6496b..4ae43d4e4 100644 --- a/src/vmm/src/macos/vstate.rs +++ b/src/vmm/src/macos/vstate.rs @@ -18,7 +18,7 @@ use super::super::{FC_EXIT_CODE_GENERIC_ERROR, FC_EXIT_CODE_OK}; use crate::vmm_config::machine_config::CpuFeaturesTemplate; use arch::ArchMemoryInfo; -use crossbeam_channel::{unbounded, Receiver, RecvTimeoutError, Sender}; +use crossbeam_channel::{Receiver, RecvTimeoutError, Sender, unbounded}; use devices::legacy::VcpuList; use hvf::{HvfVcpu, HvfVm, VcpuExit, Vcpus}; use utils::eventfd::EventFd; @@ -230,11 +230,11 @@ impl Vcpu { // Best-effort to clean up TLS. If the `Vcpu` was moved to another thread // _before_ running this, then there is nothing we can do. Self::TLS_VCPU_PTR.with(|cell: &VcpuCell| { - if let Some(vcpu_ptr) = cell.get() { - if std::ptr::eq(vcpu_ptr, self) { - Self::TLS_VCPU_PTR.with(|cell: &VcpuCell| cell.take()); - return Ok(()); - } + if let Some(vcpu_ptr) = cell.get() + && std::ptr::eq(vcpu_ptr, self) + { + Self::TLS_VCPU_PTR.with(|cell: &VcpuCell| cell.take()); + return Ok(()); } Err(Error::VcpuTlsNotPresent) }) diff --git a/src/vmm/src/resources.rs b/src/vmm/src/resources.rs index ffa9e6eac..4e1a4889e 100644 --- a/src/vmm/src/resources.rs +++ b/src/vmm/src/resources.rs @@ -405,7 +405,7 @@ mod tests { use crate::resources::VmResources; use crate::vmm_config::kernel_cmdline::KernelCmdlineConfig; use crate::vmm_config::machine_config::{CpuFeaturesTemplate, VmConfig, VmConfigError}; - use crate::vmm_config::vsock::tests::{default_config, TempSockFile}; + use crate::vmm_config::vsock::tests::{TempSockFile, default_config}; use crate::vstate::VcpuConfig; use utils::tempfile::TempFile; diff --git a/src/vmm/src/signal_handler.rs b/src/vmm/src/signal_handler.rs index fabe3855b..d1b3ac676 100644 --- a/src/vmm/src/signal_handler.rs +++ b/src/vmm/src/signal_handler.rs @@ -4,7 +4,7 @@ use std::os::unix::io::RawFd; use std::sync::atomic::{AtomicI32, Ordering}; -use libc::{_exit, c_int, c_void, siginfo_t, SIGBUS, SIGINT, SIGSEGV, SIGSYS, SIGWINCH}; +use libc::{_exit, SIGBUS, SIGINT, SIGSEGV, SIGSYS, SIGWINCH, c_int, c_void, siginfo_t}; use utils::signal::register_signal_handler; // The offset of `si_syscall` (offending syscall identifier) within the siginfo structure diff --git a/src/vmm/src/terminal.rs b/src/vmm/src/terminal.rs index a0721172b..5762dcce9 100644 --- a/src/vmm/src/terminal.rs +++ b/src/vmm/src/terminal.rs @@ -1,4 +1,4 @@ -use nix::sys::termios::{cfmakeraw, tcgetattr, tcsetattr, LocalFlags, SetArg, Termios}; +use nix::sys::termios::{LocalFlags, SetArg, Termios, cfmakeraw, tcgetattr, tcsetattr}; use std::os::fd::BorrowedFd; #[must_use] diff --git a/src/vmm/src/vmm_config/block.rs b/src/vmm/src/vmm_config/block.rs index 788be5a39..36464e315 100644 --- a/src/vmm/src/vmm_config/block.rs +++ b/src/vmm/src/vmm_config/block.rs @@ -3,8 +3,8 @@ use std::fmt; use std::sync::{Arc, Mutex}; use devices::virtio::{ - block::{ImageType, SyncMode}, Block, CacheType, + block::{ImageType, SyncMode}, }; #[derive(Debug)] diff --git a/src/vmm/src/vmm_config/machine_config.rs b/src/vmm/src/vmm_config/machine_config.rs index ff991f4e6..16feeb285 100644 --- a/src/vmm/src/vmm_config/machine_config.rs +++ b/src/vmm/src/vmm_config/machine_config.rs @@ -65,7 +65,10 @@ impl fmt::Display for VmConfig { .cpu_template .map_or("Uninitialized".to_string(), |c| c.to_string()); - write!(f, "{{ \"vcpu_count\": {vcpu_count:?}, \"mem_size_mib\": {mem_size:?}, \"ht_enabled\": {ht_enabled:?}, \"cpu_template\": {cpu_template:?} }}") + write!( + f, + "{{ \"vcpu_count\": {vcpu_count:?}, \"mem_size_mib\": {mem_size:?}, \"ht_enabled\": {ht_enabled:?}, \"cpu_template\": {cpu_template:?} }}" + ) } } diff --git a/src/vmm/src/vmm_config/net.rs b/src/vmm/src/vmm_config/net.rs index 444692d8f..525731c1f 100644 --- a/src/vmm/src/vmm_config/net.rs +++ b/src/vmm/src/vmm_config/net.rs @@ -6,8 +6,8 @@ use std::fmt; use std::result; use std::sync::{Arc, Mutex}; -use devices::virtio::net::device::VirtioNetBackend; use devices::virtio::Net; +use devices::virtio::net::device::VirtioNetBackend; pub struct NetworkInterfaceConfig { /// ID of the guest network interface. diff --git a/src/vmm/src/worker.rs b/src/vmm/src/worker.rs index d0131b994..2c28cc3be 100644 --- a/src/vmm/src/worker.rs +++ b/src/vmm/src/worker.rs @@ -9,14 +9,14 @@ use crossbeam_channel::Receiver; #[cfg(feature = "tee")] use crossbeam_channel::Sender; #[cfg(feature = "tee")] -use kvm_bindings::{kvm_memory_attributes, KVM_MEMORY_ATTRIBUTE_PRIVATE}; +use kvm_bindings::{KVM_MEMORY_ATTRIBUTE_PRIVATE, kvm_memory_attributes}; #[cfg(feature = "tee")] -use libc::{fallocate, madvise, FALLOC_FL_KEEP_SIZE, FALLOC_FL_PUNCH_HOLE, MADV_DONTNEED}; +use libc::{FALLOC_FL_KEEP_SIZE, FALLOC_FL_PUNCH_HOLE, MADV_DONTNEED, fallocate, madvise}; #[cfg(feature = "tee")] use std::ffi::c_void; #[cfg(feature = "tee")] use vm_memory::{ - guest_memory::GuestMemory, Address, GuestAddress, GuestMemoryRegion, MemoryRegionAddress, + Address, GuestAddress, GuestMemoryRegion, MemoryRegionAddress, guest_memory::GuestMemory, }; pub fn start_worker_thread( @@ -25,13 +25,16 @@ pub fn start_worker_thread( ) -> io::Result<()> { std::thread::Builder::new() .name("vmm worker".into()) - .spawn(move || loop { - match receiver.recv() { - Err(e) => error!("error receiving message from vmm worker thread: {e:?}"), - #[cfg(target_os = "macos")] - Ok(message) => vmm.lock().unwrap().match_worker_message(message), - #[cfg(target_os = "linux")] - Ok(message) => vmm.lock().unwrap().match_worker_message(message), + .spawn(move || { + loop { + let received = receiver.recv(); + match received { + Err(e) => error!("error receiving message from vmm worker thread: {e:?}"), + #[cfg(target_os = "macos")] + Ok(message) => vmm.lock().unwrap().match_worker_message(message), + #[cfg(target_os = "linux")] + Ok(message) => vmm.lock().unwrap().match_worker_message(message), + } } })?; Ok(()) @@ -93,7 +96,10 @@ impl super::Vmm { }; if self.kvm_vm().fd().set_memory_attributes(attr).is_err() { - error!("unable to set memory attributes for memory region corresponding to guest address 0x{:x}", properties.gpa); + error!( + "unable to set memory attributes for memory region corresponding to guest address 0x{:x}", + properties.gpa + ); sender.send(false).unwrap(); return; } @@ -133,7 +139,10 @@ impl super::Vmm { }; if ret < 0 { - error!("unable to advise kernel that memory region corresponding to GPA 0x{:x} will likely not be needed (madvise)", properties.gpa); + error!( + "unable to advise kernel that memory region corresponding to GPA 0x{:x} will likely not be needed (madvise)", + properties.gpa + ); sender.send(false).unwrap(); } } else { diff --git a/src/whp/Cargo.toml b/src/whp/Cargo.toml index d2e731486..4eb496a16 100644 --- a/src/whp/Cargo.toml +++ b/src/whp/Cargo.toml @@ -2,7 +2,7 @@ name = "krun-whp" version = "0.1.0-1.18.0" authors = ["The libkrun Authors"] -edition = "2021" +edition = "2024" description = "Windows Hypervisor Platform backend for libkrun" license = "Apache-2.0" repository = "https://github.com/containers/libkrun" diff --git a/src/whp/src/lib.rs b/src/whp/src/lib.rs index 268e5519e..c846d7c82 100644 --- a/src/whp/src/lib.rs +++ b/src/whp/src/lib.rs @@ -11,26 +11,25 @@ use std::sync::Arc; use log::{debug, error}; use windows_sys::Win32::Foundation::S_OK; use windows_sys::Win32::System::Hypervisor::{ - WHvCancelRunVirtualProcessor, WHvCapabilityCodeHypervisorPresent, WHvCreatePartition, - WHvCreateVirtualProcessor, WHvDeletePartition, WHvDeleteVirtualProcessor, - WHvEmulatorCreateEmulator, WHvEmulatorDestroyEmulator, WHvEmulatorTryIoEmulation, - WHvEmulatorTryMmioEmulation, WHvGetCapability, WHvGetVirtualProcessorRegisters, WHvMapGpaRange, - WHvMapGpaRangeFlagExecute, WHvMapGpaRangeFlagRead, WHvMapGpaRangeFlagWrite, - WHvPartitionPropertyCodeCpuidResultList, WHvPartitionPropertyCodeExtendedVmExits, - WHvPartitionPropertyCodeLocalApicEmulationMode, WHvPartitionPropertyCodeProcessorCount, - WHvRegisterInternalActivityState, WHvRequestInterrupt, WHvRunVirtualProcessor, - WHvRunVpExitReasonCanceled, WHvRunVpExitReasonInvalidVpRegisterValue, + WHV_CAPABILITY, WHV_EMULATOR_CALLBACKS, WHV_EMULATOR_STATUS, WHV_MEMORY_ACCESS_CONTEXT, + WHV_PARTITION_HANDLE, WHV_PARTITION_PROPERTY, WHV_PARTITION_PROPERTY_CODE, WHV_REGISTER_NAME, + WHV_REGISTER_VALUE, WHV_RUN_VP_EXIT_CONTEXT, WHV_VP_EXIT_CONTEXT, WHV_X64_CPUID_RESULT, + WHV_X64_IO_PORT_ACCESS_CONTEXT, WHvCancelRunVirtualProcessor, + WHvCapabilityCodeHypervisorPresent, WHvCreatePartition, WHvCreateVirtualProcessor, + WHvDeletePartition, WHvDeleteVirtualProcessor, WHvEmulatorCreateEmulator, + WHvEmulatorDestroyEmulator, WHvEmulatorTryIoEmulation, WHvEmulatorTryMmioEmulation, + WHvGetCapability, WHvGetVirtualProcessorRegisters, WHvMapGpaRange, WHvMapGpaRangeFlagExecute, + WHvMapGpaRangeFlagRead, WHvMapGpaRangeFlagWrite, WHvPartitionPropertyCodeCpuidResultList, + WHvPartitionPropertyCodeExtendedVmExits, WHvPartitionPropertyCodeLocalApicEmulationMode, + WHvPartitionPropertyCodeProcessorCount, WHvRegisterInternalActivityState, WHvRequestInterrupt, + WHvRunVirtualProcessor, WHvRunVpExitReasonCanceled, WHvRunVpExitReasonInvalidVpRegisterValue, WHvRunVpExitReasonMemoryAccess, WHvRunVpExitReasonUnrecoverableException, WHvRunVpExitReasonUnsupportedFeature, WHvRunVpExitReasonX64Cpuid, WHvRunVpExitReasonX64Halt, WHvRunVpExitReasonX64InterruptWindow, WHvRunVpExitReasonX64IoPortAccess, WHvRunVpExitReasonX64MsrAccess, WHvSetPartitionProperty, WHvSetVirtualProcessorRegisters, WHvSetupPartition, WHvX64LocalApicEmulationModeXApic, WHvX64RegisterDeliverabilityNotifications, WHvX64RegisterRax, WHvX64RegisterRbx, - WHvX64RegisterRcx, WHvX64RegisterRdx, WHvX64RegisterRip, WHV_CAPABILITY, - WHV_EMULATOR_CALLBACKS, WHV_EMULATOR_STATUS, WHV_MEMORY_ACCESS_CONTEXT, WHV_PARTITION_HANDLE, - WHV_PARTITION_PROPERTY, WHV_PARTITION_PROPERTY_CODE, WHV_REGISTER_NAME, WHV_REGISTER_VALUE, - WHV_RUN_VP_EXIT_CONTEXT, WHV_VP_EXIT_CONTEXT, WHV_X64_CPUID_RESULT, - WHV_X64_IO_PORT_ACCESS_CONTEXT, + WHvX64RegisterRcx, WHvX64RegisterRdx, WHvX64RegisterRip, }; use windows_sys::Win32::System::Performance::{QueryPerformanceCounter, QueryPerformanceFrequency}; diff --git a/tests/guest-agent/Cargo.toml b/tests/guest-agent/Cargo.toml index 47617a0e4..77fabb4a1 100644 --- a/tests/guest-agent/Cargo.toml +++ b/tests/guest-agent/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "guest-agent" -edition = "2021" +edition = "2024" [dependencies] test_cases = { path = "../test_cases", features = ["guest"] } diff --git a/tests/guest-agent/src/main.rs b/tests/guest-agent/src/main.rs index 668eb9688..fbb37b408 100644 --- a/tests/guest-agent/src/main.rs +++ b/tests/guest-agent/src/main.rs @@ -1,6 +1,6 @@ use anyhow::Context; use std::env::args; -use test_cases::{test_cases, TestCase}; +use test_cases::{TestCase, test_cases}; fn run_guest_agent(test_name: &str) -> anyhow::Result<()> { let tests = test_cases(); diff --git a/tests/macros/Cargo.toml b/tests/macros/Cargo.toml index e3afd344f..196719f7b 100644 --- a/tests/macros/Cargo.toml +++ b/tests/macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "macros" -edition = "2021" +edition = "2024" [lib] proc-macro = true diff --git a/tests/runner/Cargo.toml b/tests/runner/Cargo.toml index 8133341b8..56941606b 100644 --- a/tests/runner/Cargo.toml +++ b/tests/runner/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "runner" -edition = "2021" +edition = "2024" [dependencies] test_cases = { path = "../test_cases", features = ["host"] } diff --git a/tests/runner/src/main.rs b/tests/runner/src/main.rs index c7b1bbc8d..0ed9af130 100644 --- a/tests/runner/src/main.rs +++ b/tests/runner/src/main.rs @@ -1,6 +1,6 @@ use anyhow::Context; use clap::Parser; -use nix::sys::resource::{getrlimit, setrlimit, Resource}; +use nix::sys::resource::{Resource, getrlimit, setrlimit}; use std::env; use std::fs::{self, File}; use std::io::Write; @@ -8,7 +8,7 @@ use std::panic::catch_unwind; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use tempdir::TempDir; -use test_cases::{test_cases, Report, ShouldRun, Test, TestCase, TestOutcome, TestSetup}; +use test_cases::{Report, ShouldRun, Test, TestCase, TestOutcome, TestSetup, test_cases}; struct TestResult { name: String, @@ -42,7 +42,7 @@ fn start_vm(test_setup: TestSetup) -> anyhow::Result<()> { /// [`TestSetup::register_cleanup_pid`]. Sends SIGTERM first, waits up to 5s /// for graceful exit, then SIGKILL any survivors. fn kill_cleanup_pids(test_dir: &Path) { - use nix::sys::signal::{kill, Signal}; + use nix::sys::signal::{Signal, kill}; use nix::unistd::Pid; use std::io::BufRead; diff --git a/tests/test_cases/Cargo.toml b/tests/test_cases/Cargo.toml index 8c9bcc924..599959164 100644 --- a/tests/test_cases/Cargo.toml +++ b/tests/test_cases/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "test_cases" -edition = "2021" +edition = "2024" [features] host = ["krun-sys", "serde", "serde_json"] diff --git a/tests/test_cases/src/common.rs b/tests/test_cases/src/common.rs index 3d8881ff8..810347791 100644 --- a/tests/test_cases/src/common.rs +++ b/tests/test_cases/src/common.rs @@ -1,14 +1,14 @@ //! Common utilities used by multiple test use anyhow::Context; -use std::ffi::{c_char, CStr, CString}; +use std::ffi::{CStr, CString, c_char}; use std::fs; use std::fs::create_dir; use std::os::unix::ffi::OsStrExt; use std::path::{Path, PathBuf}; use std::ptr::null; -use crate::{krun_call, TestSetup}; +use crate::{TestSetup, krun_call}; use krun_sys::*; fn copy_guest_agent(dir: &Path) -> anyhow::Result<()> { diff --git a/tests/test_cases/src/krun.rs b/tests/test_cases/src/krun.rs index f9752159e..380dd874a 100644 --- a/tests/test_cases/src/krun.rs +++ b/tests/test_cases/src/krun.rs @@ -1,6 +1,6 @@ #[macro_export] macro_rules! krun_call { - ($func_call:expr) => {{ + ($func_call:expr_2021) => {{ let result = $func_call; if result < 0 { let err = std::io::Error::from_raw_os_error(-result); @@ -13,7 +13,7 @@ macro_rules! krun_call { #[macro_export] macro_rules! krun_call_u32 { - ($func_call:expr) => {{ + ($func_call:expr_2021) => {{ let result = $func_call; if result < 0 { let err = std::io::Error::from_raw_os_error(-result); diff --git a/tests/test_cases/src/rootfs.rs b/tests/test_cases/src/rootfs.rs index b9a36293e..2e9e1cd6b 100644 --- a/tests/test_cases/src/rootfs.rs +++ b/tests/test_cases/src/rootfs.rs @@ -5,7 +5,7 @@ //! The image tag is derived from the hash of the Containerfile content (`krun-test-`), //! so podman's layer cache makes rebuilds fast when the Containerfile hasn't changed. -use anyhow::{bail, Context}; +use anyhow::{Context, bail}; use std::fs; use std::io::Write; use std::path::Path; diff --git a/tests/test_cases/src/test_multiport_console.rs b/tests/test_cases/src/test_multiport_console.rs index b9c4c1fd6..8fcbf6033 100644 --- a/tests/test_cases/src/test_multiport_console.rs +++ b/tests/test_cases/src/test_multiport_console.rs @@ -7,8 +7,8 @@ mod host { use super::*; use crate::common::setup_fs_and_enter; - use crate::{krun_call, krun_call_u32}; use crate::{Test, TestSetup}; + use crate::{krun_call, krun_call_u32}; use krun_sys::*; use std::ffi::CString; use std::io::{BufRead, BufReader, Write}; diff --git a/tests/test_cases/src/test_net/gvproxy.rs b/tests/test_cases/src/test_net/gvproxy.rs index 0bd18ac02..e2e9d121d 100644 --- a/tests/test_cases/src/test_net/gvproxy.rs +++ b/tests/test_cases/src/test_net/gvproxy.rs @@ -1,6 +1,6 @@ //! Gvproxy backend for virtio-net test (macOS only) -use crate::{krun_call, ShouldRun, TestSetup}; +use crate::{ShouldRun, TestSetup, krun_call}; use krun_sys::{COMPAT_NET_FEATURES, NET_FLAG_DHCP_CLIENT, NET_FLAG_VFKIT}; use nix::libc; use std::ffi::CString; diff --git a/tests/test_cases/src/test_net/mod.rs b/tests/test_cases/src/test_net/mod.rs index 9eb973a81..06f964196 100644 --- a/tests/test_cases/src/test_net/mod.rs +++ b/tests/test_cases/src/test_net/mod.rs @@ -84,7 +84,7 @@ impl TestNet { mod host { use super::*; use crate::common::setup_fs_and_enter; - use crate::{krun_call, krun_call_u32, Test, TestOutcome, TestSetup}; + use crate::{Test, TestOutcome, TestSetup, krun_call, krun_call_u32}; use krun_sys::*; use std::thread; diff --git a/tests/test_cases/src/test_net/passt.rs b/tests/test_cases/src/test_net/passt.rs index 991ef0f9b..3d53daf51 100644 --- a/tests/test_cases/src/test_net/passt.rs +++ b/tests/test_cases/src/test_net/passt.rs @@ -1,6 +1,6 @@ //! Passt backend for virtio-net test -use crate::{krun_call, ShouldRun, TestSetup}; +use crate::{ShouldRun, TestSetup, krun_call}; use krun_sys::{COMPAT_NET_FEATURES, NET_FLAG_DHCP_CLIENT}; use nix::libc; use std::ffi::CString; diff --git a/tests/test_cases/src/test_net/tap.rs b/tests/test_cases/src/test_net/tap.rs index 9f1d7db7c..3b7e59c35 100644 --- a/tests/test_cases/src/test_net/tap.rs +++ b/tests/test_cases/src/test_net/tap.rs @@ -1,9 +1,9 @@ //! TAP backend for virtio-net test -use crate::{krun_call, ShouldRun, TestSetup}; +use crate::{ShouldRun, TestSetup, krun_call}; use krun_sys::{COMPAT_NET_FEATURES, NET_FLAG_DHCP_CLIENT}; use nix::libc; -use nix::sys::socket::{socket, AddressFamily, SockFlag, SockType}; +use nix::sys::socket::{AddressFamily, SockFlag, SockType, socket}; use std::ffi::CString; use std::fs::OpenOptions; use std::net::{Ipv4Addr, SocketAddrV4, UdpSocket}; diff --git a/tests/test_cases/src/test_net/vmnet_helper.rs b/tests/test_cases/src/test_net/vmnet_helper.rs index 657cc2e45..e2f7ad81d 100644 --- a/tests/test_cases/src/test_net/vmnet_helper.rs +++ b/tests/test_cases/src/test_net/vmnet_helper.rs @@ -1,6 +1,6 @@ //! vmnet-helper backend for virtio-net test (macOS only) -use crate::{krun_call, ShouldRun, TestSetup}; +use crate::{ShouldRun, TestSetup, krun_call}; use krun_sys::{ NET_FEATURE_CSUM, NET_FEATURE_GUEST_CSUM, NET_FEATURE_GUEST_TSO4, NET_FEATURE_HOST_TSO4, NET_FLAG_DHCP_CLIENT, diff --git a/tests/test_cases/src/test_net_perf.rs b/tests/test_cases/src/test_net_perf.rs index 4c9c7acbe..f43c4020a 100644 --- a/tests/test_cases/src/test_net_perf.rs +++ b/tests/test_cases/src/test_net_perf.rs @@ -153,7 +153,7 @@ impl TestNetPerf { mod host { use super::*; use crate::common::setup_fs_and_enter; - use crate::{krun_call, krun_call_u32, Test, TestOutcome, TestSetup}; + use crate::{Test, TestOutcome, TestSetup, krun_call, krun_call_u32}; use krun_sys::*; use std::process::{Child, Command, Stdio}; diff --git a/tests/test_cases/src/test_pjdfstest.rs b/tests/test_cases/src/test_pjdfstest.rs index 741895cb5..5bb6cafe0 100644 --- a/tests/test_cases/src/test_pjdfstest.rs +++ b/tests/test_cases/src/test_pjdfstest.rs @@ -6,7 +6,7 @@ pub struct TestPjdfstest; mod host { use super::*; use crate::common::setup_fs_and_enter_with_env; - use crate::{krun_call, krun_call_u32, ShouldRun, Test, TestOutcome, TestSetup}; + use crate::{ShouldRun, Test, TestOutcome, TestSetup, krun_call, krun_call_u32}; use krun_sys::*; use std::ffi::CString; diff --git a/tests/test_cases/src/test_tsi_tcp_guest_connect.rs b/tests/test_cases/src/test_tsi_tcp_guest_connect.rs index 426cdad05..c3bb6c33d 100644 --- a/tests/test_cases/src/test_tsi_tcp_guest_connect.rs +++ b/tests/test_cases/src/test_tsi_tcp_guest_connect.rs @@ -21,8 +21,8 @@ mod host { use super::*; use crate::common::setup_fs_and_enter; - use crate::{krun_call, krun_call_u32}; use crate::{Test, TestSetup}; + use crate::{krun_call, krun_call_u32}; use krun_sys::*; use std::thread; diff --git a/tests/test_cases/src/test_tsi_tcp_guest_listen.rs b/tests/test_cases/src/test_tsi_tcp_guest_listen.rs index 41e0ffc2d..4429dde9e 100644 --- a/tests/test_cases/src/test_tsi_tcp_guest_listen.rs +++ b/tests/test_cases/src/test_tsi_tcp_guest_listen.rs @@ -20,7 +20,7 @@ impl TestTsiTcpGuestListen { mod host { use super::*; use crate::common::setup_fs_and_enter; - use crate::{krun_call, krun_call_u32, Test, TestSetup}; + use crate::{Test, TestSetup, krun_call, krun_call_u32}; use krun_sys::*; use std::ffi::CString; use std::ptr::null; diff --git a/tests/test_cases/src/test_virtiofs_misc.rs b/tests/test_cases/src/test_virtiofs_misc.rs index 2bd8b69cb..bba8ae86d 100644 --- a/tests/test_cases/src/test_virtiofs_misc.rs +++ b/tests/test_cases/src/test_virtiofs_misc.rs @@ -7,8 +7,8 @@ mod host { use super::*; use crate::common::setup_fs_and_enter; - use crate::{krun_call, krun_call_u32}; use crate::{Test, TestOutcome, TestSetup}; + use crate::{krun_call, krun_call_u32}; use krun_sys::*; use std::io::Read; @@ -76,7 +76,7 @@ mod guest { use std::os::unix::fs::MetadataExt; use std::os::unix::io::AsRawFd; - use nix::fcntl::{fallocate, FallocateFlags}; + use nix::fcntl::{FallocateFlags, fallocate}; fn test_fallocate_basic() { let path = "/test_fallocate_basic"; diff --git a/tests/test_cases/src/test_virtiofs_root_ro.rs b/tests/test_cases/src/test_virtiofs_root_ro.rs index 1fff83ce2..4d50fd37f 100644 --- a/tests/test_cases/src/test_virtiofs_root_ro.rs +++ b/tests/test_cases/src/test_virtiofs_root_ro.rs @@ -15,8 +15,8 @@ mod host { use super::*; use crate::common::setup_rootfs; - use crate::{krun_call, krun_call_u32}; use crate::{Test, TestSetup}; + use crate::{krun_call, krun_call_u32}; use krun_sys::*; use std::ffi::CString; use std::fs; @@ -73,12 +73,12 @@ mod guest { use crate::Test; use nix::errno::Errno; use nix::libc; - use nix::sys::stat::{mknod, stat, Mode, SFlag}; + use nix::sys::stat::{Mode, SFlag, mknod, stat}; use nix::unistd::{mkfifo, truncate}; use std::fs; use std::fs::Permissions; use std::io::ErrorKind; - use std::os::unix::fs::{chown, symlink, PermissionsExt}; + use std::os::unix::fs::{PermissionsExt, chown, symlink}; use std::os::unix::net::UnixListener; use std::path::Path; diff --git a/tests/test_cases/src/test_vm_config.rs b/tests/test_cases/src/test_vm_config.rs index 9ccae5de1..207f2b460 100644 --- a/tests/test_cases/src/test_vm_config.rs +++ b/tests/test_cases/src/test_vm_config.rs @@ -10,8 +10,8 @@ mod host { use super::*; use crate::common::setup_fs_and_enter; - use crate::{krun_call, krun_call_u32}; use crate::{Test, TestSetup}; + use crate::{krun_call, krun_call_u32}; use krun_sys::*; impl Test for TestVmConfig { diff --git a/tests/test_cases/src/test_vsock_guest_connect.rs b/tests/test_cases/src/test_vsock_guest_connect.rs index bb0482f29..29f5da478 100644 --- a/tests/test_cases/src/test_vsock_guest_connect.rs +++ b/tests/test_cases/src/test_vsock_guest_connect.rs @@ -34,8 +34,8 @@ mod host { use super::*; use crate::common::setup_fs_and_enter; - use crate::{krun_call, krun_call_u32}; use crate::{Test, TestSetup}; + use crate::{krun_call, krun_call_u32}; use krun_sys::*; use std::ffi::CString; use std::io::Write; @@ -84,7 +84,7 @@ mod guest { use crate::Test; use nix::libc::VMADDR_CID_HOST; - use nix::sys::socket::{connect, socket, AddressFamily, SockFlag, SockType, VsockAddr}; + use nix::sys::socket::{AddressFamily, SockFlag, SockType, VsockAddr, connect, socket}; use std::io::Write; use std::os::fd::AsRawFd;