From ecbd11ded90af326823f9b585f1c8720c4d5b525 Mon Sep 17 00:00:00 2001 From: Teddy Astie Date: Sun, 28 Dec 2025 03:14:45 +0100 Subject: [PATCH 1/2] misc: Migrate to Rust Edition 2024 Update to the latest Rust edition and perform all the required changes. Signed-off-by: Teddy Astie --- Cargo.toml | 2 +- src/arch/aarch64/layout.rs | 14 ++++---- src/arch/aarch64/paging.rs | 10 +++--- src/arch/riscv64/layout.rs | 14 ++++---- src/arch/x86_64/gdt.rs | 2 +- src/arch/x86_64/layout.rs | 16 ++++----- src/arch/x86_64/paging.rs | 6 ++-- src/common.rs | 4 +-- src/delay.rs | 8 ++--- src/efi/runtime_services.rs | 70 +++++++++++++++++++------------------ src/main.rs | 6 ++-- src/pvh.rs | 6 ++-- 12 files changed, 81 insertions(+), 77 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d334615e..d36683de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "hypervisor-fw" version = "0.5.0" authors = ["The Rust Hypervisor Firmware Authors"] -edition = "2021" +edition = "2024" # Despite "panic-strategy": "abort" being set in x86_64-unknown-none.json, panic = "abort" is # needed here to make "cargo check" and "cargo clippy" run without errors. diff --git a/src/arch/aarch64/layout.rs b/src/arch/aarch64/layout.rs index b9606199..d22a5086 100644 --- a/src/arch/aarch64/layout.rs +++ b/src/arch/aarch64/layout.rs @@ -11,13 +11,13 @@ use crate::layout::{MemoryAttribute, MemoryDescriptor, MemoryLayout}; use super::paging::*; -extern "Rust" { - static code_start: UnsafeCell<()>; - static code_end: UnsafeCell<()>; - static data_start: UnsafeCell<()>; - static data_end: UnsafeCell<()>; - static stack_start: UnsafeCell<()>; - static stack_end: UnsafeCell<()>; +unsafe extern "Rust" { + unsafe static code_start: UnsafeCell<()>; + unsafe static code_end: UnsafeCell<()>; + unsafe static data_start: UnsafeCell<()>; + unsafe static data_end: UnsafeCell<()>; + unsafe static stack_start: UnsafeCell<()>; + unsafe static stack_end: UnsafeCell<()>; } pub mod map { diff --git a/src/arch/aarch64/paging.rs b/src/arch/aarch64/paging.rs index 471d4450..a1f92a6b 100644 --- a/src/arch/aarch64/paging.rs +++ b/src/arch/aarch64/paging.rs @@ -276,12 +276,14 @@ impl interface::Mmu for MemoryManagementUnit { // Prepare the memory attribute indirection register. self.setup_mair(); - let kernel_tables = &mut *KERNEL_TABLES.get(); + let kernel_tables = unsafe { &mut *KERNEL_TABLES.get() }; // Populate translation tables. - kernel_tables - .populate_tt_entries() - .map_err(MmuEnableError::Other)?; + unsafe { + kernel_tables + .populate_tt_entries() + .map_err(MmuEnableError::Other)?; + } // Set the "Translation Table Base Register". TTBR0_EL1.set_baddr(kernel_tables.phys_base_address()); diff --git a/src/arch/riscv64/layout.rs b/src/arch/riscv64/layout.rs index 68f9e908..627da76a 100644 --- a/src/arch/riscv64/layout.rs +++ b/src/arch/riscv64/layout.rs @@ -7,13 +7,13 @@ use core::{cell::UnsafeCell, ops::Range}; use crate::layout::{MemoryAttribute, MemoryDescriptor, MemoryLayout}; -extern "Rust" { - static code_start: UnsafeCell<()>; - static code_end: UnsafeCell<()>; - static data_start: UnsafeCell<()>; - static data_end: UnsafeCell<()>; - static stack_start: UnsafeCell<()>; - static stack_end: UnsafeCell<()>; +unsafe extern "Rust" { + unsafe static code_start: UnsafeCell<()>; + unsafe static code_end: UnsafeCell<()>; + unsafe static data_start: UnsafeCell<()>; + unsafe static data_end: UnsafeCell<()>; + unsafe static stack_start: UnsafeCell<()>; + unsafe static stack_end: UnsafeCell<()>; } pub fn code_range() -> Range { diff --git a/src/arch/x86_64/gdt.rs b/src/arch/x86_64/gdt.rs index 34aab85a..87889b80 100644 --- a/src/arch/x86_64/gdt.rs +++ b/src/arch/x86_64/gdt.rs @@ -50,6 +50,6 @@ impl Pointer { } // Our 64-bit GDT lives in RAM, so it can be accessed like any other global. -#[no_mangle] +#[unsafe(no_mangle)] static GDT64_PTR: Pointer = Pointer::new(&GDT64); static GDT64: [Descriptor; 3] = [Descriptor::empty(), Descriptor::CODE64, Descriptor::DATA64]; diff --git a/src/arch/x86_64/layout.rs b/src/arch/x86_64/layout.rs index 2a05cede..bd803c7a 100644 --- a/src/arch/x86_64/layout.rs +++ b/src/arch/x86_64/layout.rs @@ -5,14 +5,14 @@ use core::{cell::UnsafeCell, ops::Range}; use crate::layout::{MemoryAttribute, MemoryDescriptor, MemoryLayout}; -extern "Rust" { - static ram_min: UnsafeCell<()>; - static code_start: UnsafeCell<()>; - static code_end: UnsafeCell<()>; - static data_start: UnsafeCell<()>; - static data_end: UnsafeCell<()>; - static stack_start: UnsafeCell<()>; - static stack_end: UnsafeCell<()>; +unsafe extern "Rust" { + unsafe static ram_min: UnsafeCell<()>; + unsafe static code_start: UnsafeCell<()>; + unsafe static code_end: UnsafeCell<()>; + unsafe static data_start: UnsafeCell<()>; + unsafe static data_end: UnsafeCell<()>; + unsafe static stack_start: UnsafeCell<()>; + unsafe static stack_end: UnsafeCell<()>; } pub fn header_range() -> Range { diff --git a/src/arch/x86_64/paging.rs b/src/arch/x86_64/paging.rs index 1630b17a..0b209b03 100644 --- a/src/arch/x86_64/paging.rs +++ b/src/arch/x86_64/paging.rs @@ -14,11 +14,11 @@ const ADDRESS_SPACE_GIB: usize = 4; const TABLE: PageTable = PageTable::new(); // Put the Page Tables in static muts to make linking easier -#[no_mangle] +#[unsafe(no_mangle)] static L4_TABLE: SyncUnsafeCell = SyncUnsafeCell::new(PageTable::new()); -#[no_mangle] +#[unsafe(no_mangle)] static L3_TABLE: SyncUnsafeCell = SyncUnsafeCell::new(PageTable::new()); -#[no_mangle] +#[unsafe(no_mangle)] static L2_TABLES: SyncUnsafeCell<[PageTable; ADDRESS_SPACE_GIB]> = SyncUnsafeCell::new([TABLE; ADDRESS_SPACE_GIB]); diff --git a/src/common.rs b/src/common.rs index f0c1820a..3d40aae1 100644 --- a/src/common.rs +++ b/src/common.rs @@ -24,10 +24,10 @@ pub unsafe fn from_cstring(addr: u64) -> &'static [u8] { } let start = addr as *const u8; let mut size: usize = 0; - while start.add(size).read() != 0 { + while unsafe { start.add(size).read() } != 0 { size += 1; } - core::slice::from_raw_parts(start, size) + unsafe { core::slice::from_raw_parts(start, size) } } pub fn ascii_strip(s: &[u8]) -> &str { diff --git a/src/delay.rs b/src/delay.rs index 5b505bab..7783c94c 100644 --- a/src/delay.rs +++ b/src/delay.rs @@ -12,7 +12,7 @@ use core::arch::x86_64::_rdtsc; #[inline] unsafe fn rdtsc() -> u64 { let value: u64; - asm!("mrs {}, cntvct_el0", out(reg) value); + unsafe { asm!("mrs {}, cntvct_el0", out(reg) value) }; value } @@ -26,19 +26,19 @@ unsafe fn rdtsc() -> u64 { #[cfg(target_arch = "x86_64")] #[inline] unsafe fn rdtsc() -> u64 { - _rdtsc() + unsafe { _rdtsc() } } #[cfg(target_arch = "aarch64")] #[inline] unsafe fn pause() { - asm!("yield"); + unsafe { asm!("yield") } } #[cfg(target_arch = "x86_64")] #[inline] unsafe fn pause() { - asm!("pause"); + unsafe { asm!("pause") } } pub fn ndelay(ns: u64) { diff --git a/src/efi/runtime_services.rs b/src/efi/runtime_services.rs index fee334f1..26195fb0 100644 --- a/src/efi/runtime_services.rs +++ b/src/efi/runtime_services.rs @@ -46,40 +46,42 @@ pub static mut RS: SyncUnsafeCell = #[allow(clippy::missing_transmute_annotations)] unsafe fn fixup_at_virtual(descriptors: &[MemoryDescriptor]) { - #[allow(static_mut_refs)] - let st = ST.get_mut(); - #[allow(static_mut_refs)] - let rs = RS.get_mut(); - - let ptr = ALLOCATOR - .borrow() - .convert_internal_pointer(descriptors, (not_available as *const ()) as u64) - .unwrap(); - rs.get_time = transmute(ptr); - rs.set_time = transmute(ptr); - rs.get_wakeup_time = transmute(ptr); - rs.set_wakeup_time = transmute(ptr); - rs.get_variable = transmute(ptr); - rs.set_variable = transmute(ptr); - rs.get_next_variable_name = transmute(ptr); - rs.reset_system = transmute(ptr); - rs.update_capsule = transmute(ptr); - rs.query_capsule_capabilities = transmute(ptr); - rs.query_variable_info = transmute(ptr); - - let ct = st.configuration_table; - let ptr = ALLOCATOR - .borrow() - .convert_internal_pointer(descriptors, (ct as *const _) as u64) - .unwrap(); - st.configuration_table = ptr as *mut ConfigurationTable; - - let rs = st.runtime_services; - let ptr = ALLOCATOR - .borrow() - .convert_internal_pointer(descriptors, (rs as *const _) as u64) - .unwrap(); - st.runtime_services = ptr as *mut RuntimeServices; + unsafe { + #[allow(static_mut_refs)] + let st = ST.get_mut(); + #[allow(static_mut_refs)] + let rs = RS.get_mut(); + + let ptr = ALLOCATOR + .borrow() + .convert_internal_pointer(descriptors, (not_available as *const ()) as u64) + .unwrap(); + rs.get_time = transmute(ptr); + rs.set_time = transmute(ptr); + rs.get_wakeup_time = transmute(ptr); + rs.set_wakeup_time = transmute(ptr); + rs.get_variable = transmute(ptr); + rs.set_variable = transmute(ptr); + rs.get_next_variable_name = transmute(ptr); + rs.reset_system = transmute(ptr); + rs.update_capsule = transmute(ptr); + rs.query_capsule_capabilities = transmute(ptr); + rs.query_variable_info = transmute(ptr); + + let ct = st.configuration_table; + let ptr = ALLOCATOR + .borrow() + .convert_internal_pointer(descriptors, (ct as *const _) as u64) + .unwrap(); + st.configuration_table = ptr as *mut ConfigurationTable; + + let rs = st.runtime_services; + let ptr = ALLOCATOR + .borrow() + .convert_internal_pointer(descriptors, (rs as *const _) as u64) + .unwrap(); + st.runtime_services = ptr as *mut RuntimeServices; + } } pub extern "efiapi" fn not_available() -> Status { diff --git a/src/main.rs b/src/main.rs index 5928863d..0e3b1d7d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -178,7 +178,7 @@ fn boot_from_device( } #[cfg(target_arch = "x86_64")] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rust64_start(#[cfg(not(feature = "coreboot"))] pvh_info: &pvh::StartInfo) -> ! { serial::PORT.borrow_mut().init(); logger::init(); @@ -196,7 +196,7 @@ pub extern "C" fn rust64_start(#[cfg(not(feature = "coreboot"))] pvh_info: &pvh: } #[cfg(target_arch = "aarch64")] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rust64_start(x0: *const u8) -> ! { arch::aarch64::simd::setup_simd(); arch::aarch64::paging::setup(); @@ -221,7 +221,7 @@ pub extern "C" fn rust64_start(x0: *const u8) -> ! { } #[cfg(target_arch = "riscv64")] -#[no_mangle] +#[unsafe(no_mangle)] pub extern "C" fn rust64_start(a0: u64, a1: *const u8) -> ! { use crate::bootinfo::{EntryType, Info, MemoryEntry}; diff --git a/src/pvh.rs b/src/pvh.rs index ed7c8ad8..2338cc0b 100644 --- a/src/pvh.rs +++ b/src/pvh.rs @@ -76,8 +76,8 @@ impl Info for StartInfo { } // The PVH Boot Protocol starts at the 32-bit entrypoint to our firmware. -extern "C" { - fn ram32_start(); +unsafe extern "C" { + unsafe fn ram32_start(); } // The kind/name/desc of the PHV ELF Note are from xen/include/public/elfnote.h. @@ -99,7 +99,7 @@ struct Note { // This is: ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .quad ram32_start) #[cfg(not(test))] -#[link_section = ".note"] +#[unsafe(link_section = ".note")] #[used] static PVH_NOTE: Note = Note { name_size: size_of::() as u32, From 7dc9d3912e13995e0e1ed915bdae0d6b9b69a645 Mon Sep 17 00:00:00 2001 From: Teddy Astie Date: Sun, 28 Dec 2025 03:15:04 +0100 Subject: [PATCH 2/2] misc: Reformat using rust-fmt Signed-off-by: Teddy Astie --- src/arch/x86_64/paging.rs | 2 +- src/common.rs | 8 ++--- src/efi/block.rs | 2 +- src/efi/boot_services.rs | 4 +-- src/fat.rs | 2 +- src/integration.rs | 68 ++++++++++++++++++++++----------------- src/loader.rs | 5 ++- 7 files changed, 49 insertions(+), 42 deletions(-) diff --git a/src/arch/x86_64/paging.rs b/src/arch/x86_64/paging.rs index 0b209b03..795d9608 100644 --- a/src/arch/x86_64/paging.rs +++ b/src/arch/x86_64/paging.rs @@ -4,9 +4,9 @@ use core::cell::SyncUnsafeCell; use log::info; use x86_64::{ + PhysAddr, registers::control::Cr3, structures::paging::{PageSize, PageTable, PageTableFlags, PhysFrame, Size2MiB}, - PhysAddr, }; // Amount of memory we identity map in setup(), max 512 GiB. diff --git a/src/common.rs b/src/common.rs index 3d40aae1..bad224b2 100644 --- a/src/common.rs +++ b/src/common.rs @@ -3,16 +3,12 @@ #[macro_export] macro_rules! container_of { - ($ptr:ident, $container:ty, $field:ident) => {{ - (($ptr as usize) - core::mem::offset_of!($container, $field)) as *const $container - }}; + ($ptr:ident, $container:ty, $field:ident) => {{ (($ptr as usize) - core::mem::offset_of!($container, $field)) as *const $container }}; } #[macro_export] macro_rules! container_of_mut { - ($ptr:ident, $container:ty, $field:ident) => {{ - (($ptr as usize) - core::mem::offset_of!($container, $field)) as *mut $container - }}; + ($ptr:ident, $container:ty, $field:ident) => {{ (($ptr as usize) - core::mem::offset_of!($container, $field)) as *mut $container }}; } // SAFETY: Requires that addr point to a static, null-terminated C-string. diff --git a/src/efi/block.rs b/src/efi/block.rs index d0b75425..ec35f375 100644 --- a/src/efi/block.rs +++ b/src/efi/block.rs @@ -13,7 +13,7 @@ use r_efi::{ use crate::{ block::{SectorBuf, VirtioBlockDevice}, - part::{get_partitions, PartitionEntry}, + part::{PartitionEntry, get_partitions}, }; #[allow(dead_code)] diff --git a/src/efi/boot_services.rs b/src/efi/boot_services.rs index 26a93ec5..e8c5bbae 100644 --- a/src/efi/boot_services.rs +++ b/src/efi/boot_services.rs @@ -18,8 +18,8 @@ use r_efi::{eficall, eficall_abi}; use crate::fat; use super::{ - block, device_path::DevicePath, file, mem_file, new_image_handle, HandleType, HandleWrapper, - LoadedImageWrapper, ALLOCATOR, BLOCK_WRAPPERS, ST, + ALLOCATOR, BLOCK_WRAPPERS, HandleType, HandleWrapper, LoadedImageWrapper, ST, block, + device_path::DevicePath, file, mem_file, new_image_handle, }; pub static mut BS: SyncUnsafeCell = SyncUnsafeCell::new(efi::BootServices { diff --git a/src/fat.rs b/src/fat.rs index e717fe2e..0bcd45ca 100644 --- a/src/fat.rs +++ b/src/fat.rs @@ -903,7 +903,7 @@ impl<'a> Filesystem<'a> { break; } FileType::File => { - return Ok(self.get_file(de.cluster, de.size).unwrap().into()) + return Ok(self.get_file(de.cluster, de.size).unwrap().into()); } } } diff --git a/src/integration.rs b/src/integration.rs index 52822f68..aa29f618 100644 --- a/src/integration.rs +++ b/src/integration.rs @@ -257,40 +257,48 @@ mod tests { } fn prepare_tap(net: &GuestNetworkConfig) { - assert!(std::process::Command::new("bash") - .args([ - "-c", - &format!("sudo ip tuntap add name {} mode tap", net.tap_name), - ]) - .status() - .expect("Expected creating interface to work") - .success()); + assert!( + std::process::Command::new("bash") + .args([ + "-c", + &format!("sudo ip tuntap add name {} mode tap", net.tap_name), + ]) + .status() + .expect("Expected creating interface to work") + .success() + ); - assert!(std::process::Command::new("bash") - .args([ - "-c", - &format!("sudo ip addr add {}/24 dev {}", net.host_ip, net.tap_name), - ]) - .status() - .expect("Expected programming interface to work") - .success()); - - assert!(std::process::Command::new("bash") - .args(["-c", &format!("sudo ip link set dev {} up", net.tap_name)]) - .status() - .expect("Expected upping interface to work") - .success()); + assert!( + std::process::Command::new("bash") + .args([ + "-c", + &format!("sudo ip addr add {}/24 dev {}", net.host_ip, net.tap_name), + ]) + .status() + .expect("Expected programming interface to work") + .success() + ); + + assert!( + std::process::Command::new("bash") + .args(["-c", &format!("sudo ip link set dev {} up", net.tap_name)]) + .status() + .expect("Expected upping interface to work") + .success() + ); } fn cleanup_tap(net: &GuestNetworkConfig) { - assert!(std::process::Command::new("bash") - .args([ - "-c", - &format!("sudo ip tuntap de name {} mode tap", net.tap_name), - ]) - .status() - .expect("Expected deleting interface to work") - .success()); + assert!( + std::process::Command::new("bash") + .args([ + "-c", + &format!("sudo ip tuntap de name {} mode tap", net.tap_name), + ]) + .status() + .expect("Expected deleting interface to work") + .success() + ); } fn handle_child_output( diff --git a/src/loader.rs b/src/loader.rs index abf8d7d9..e9216e80 100644 --- a/src/loader.rs +++ b/src/loader.rs @@ -290,7 +290,10 @@ mod tests { assert_eq!(s, "/EFI/org.clearlinux/kernel-org.clearlinux.kvm.5.0.6-318"); let s = super::ascii_strip(&entry.cmdline); let s = s.trim_matches(char::from(0)); - assert_eq!(s, "root=PARTUUID=ae06d187-e9fc-4d3b-9e5b-8e6ff28e894f console=tty0 console=ttyS0,115200n8 console=hvc0 quiet init=/usr/lib/systemd/systemd-bootchart initcall_debug tsc=reliable no_timer_check noreplace-smp cryptomgr.notests rootfstype=ext4,btrfs,xfs kvm-intel.nested=1 rw"); + assert_eq!( + s, + "root=PARTUUID=ae06d187-e9fc-4d3b-9e5b-8e6ff28e894f console=tty0 console=ttyS0,115200n8 console=hvc0 quiet init=/usr/lib/systemd/systemd-bootchart initcall_debug tsc=reliable no_timer_check noreplace-smp cryptomgr.notests rootfstype=ext4,btrfs,xfs kvm-intel.nested=1 rw" + ); } macro_rules! entry_pattern_matches {