diff --git a/src/arch/x86_64/interrupt/handler.rs b/src/arch/x86_64/interrupt/handler.rs index 7601925ab1..1ab987d852 100644 --- a/src/arch/x86_64/interrupt/handler.rs +++ b/src/arch/x86_64/interrupt/handler.rs @@ -361,8 +361,8 @@ macro_rules! interrupt_stack { // XXX: Apparently we cannot use $expr and check for bool exhaustiveness, so we will have to // use idents directly instead. ($name:ident, $save1:ident!, $save2:ident!, $rstor2:ident!, $rstor1:ident!, is_paranoid: $is_paranoid:expr_2021, |$stack:ident| $code:block) => { - #[naked] - pub unsafe extern "C" fn $name() { unsafe { + #[unsafe(naked)] + pub unsafe extern "C" fn $name() { unsafe extern "C" fn inner($stack: &mut $crate::arch::x86_64::interrupt::InterruptStack) { $code } @@ -405,7 +405,7 @@ macro_rules! interrupt_stack { PCR_GDT_OFFSET = const(core::mem::offset_of!(crate::gdt::ProcessorControlRegion, gdt)), ); - }} + } }; ($name:ident, |$stack:ident| $code:block) => { interrupt_stack!($name, swapgs_iff_ring3_fast!, nop!, nop!, swapgs_iff_ring3_fast!, is_paranoid: false, |$stack| $code); }; ($name:ident, @paranoid, |$stack:ident| $code:block) => { interrupt_stack!($name, nop!, conditional_swapgs_paranoid!, conditional_swapgs_back_paranoid!, nop!, is_paranoid: true, |$stack| $code); } @@ -414,8 +414,8 @@ macro_rules! interrupt_stack { #[macro_export] macro_rules! interrupt { ($name:ident, || $code:block) => { - #[naked] - pub unsafe extern "C" fn $name() { unsafe { + #[unsafe(naked)] + pub unsafe extern "C" fn $name() { unsafe extern "C" fn inner() { $code } @@ -447,15 +447,15 @@ macro_rules! interrupt { inner = sym inner, ); - }} + } }; } #[macro_export] macro_rules! interrupt_error { ($name:ident, |$stack:ident, $error_code:ident| $code:block) => { - #[naked] - pub unsafe extern "C" fn $name() { unsafe { + #[unsafe(naked)] + pub unsafe extern "C" fn $name() { unsafe extern "C" fn inner($stack: &mut $crate::arch::x86_64::interrupt::handler::InterruptStack, $error_code: usize) { $code } @@ -500,7 +500,7 @@ macro_rules! interrupt_error { inner = sym inner, rax_offset = const(::core::mem::size_of::<$crate::interrupt::handler::PreservedRegisters>() + ::core::mem::size_of::<$crate::interrupt::handler::ScratchRegisters>() - 8), ); - }} + } }; } diff --git a/src/arch/x86_64/interrupt/syscall.rs b/src/arch/x86_64/interrupt/syscall.rs index 58275580f4..b6f8bc8f46 100644 --- a/src/arch/x86_64/interrupt/syscall.rs +++ b/src/arch/x86_64/interrupt/syscall.rs @@ -91,11 +91,10 @@ pub unsafe extern "C" fn __inner_syscall_instruction(stack: *mut InterruptStack) } } -#[naked] +#[unsafe(naked)] #[allow(named_asm_labels)] pub unsafe extern "C" fn syscall_instruction() { - unsafe { - core::arch::naked_asm!(concat!( + core::arch::naked_asm!(concat!( // Yes, this is magic. No, you don't need to understand "swapgs;", // Swap KGSBASE with GSBASE, allowing fast TSS access. "mov gs:[{sp}], rsp;", // Save userspace stack pointer @@ -200,7 +199,6 @@ pub unsafe extern "C" fn syscall_instruction() { ss_sel = const(SegmentSelector::new(gdt::GDT_USER_DATA as u16, x86::Ring::Ring3).bits()), cs_sel = const(SegmentSelector::new(gdt::GDT_USER_CODE as u16, x86::Ring::Ring3).bits()), ); - } } unsafe extern "C" { // TODO: macro? diff --git a/src/arch/x86_64/mod.rs b/src/arch/x86_64/mod.rs index b66eae5ce5..40417aeb61 100644 --- a/src/arch/x86_64/mod.rs +++ b/src/arch/x86_64/mod.rs @@ -23,30 +23,28 @@ pub mod flags { // TODO: Maybe support rewriting relocations (using LD's --emit-relocs) when working with entire // functions? -#[naked] +#[unsafe(naked)] #[unsafe(link_section = ".usercopy-fns")] pub unsafe extern "C" fn arch_copy_to_user(dst: usize, src: usize, len: usize) -> u8 { - unsafe { - // TODO: spectre_v1 + // TODO: spectre_v1 - core::arch::naked_asm!(alternative!( - feature: "smap", - then: [" - xor eax, eax - mov rcx, rdx - stac - rep movsb - clac - ret - "], - default: [" - xor eax, eax - mov rcx, rdx - rep movsb - ret - "] - )); - } + core::arch::naked_asm!(alternative!( + feature: "smap", + then: [" + xor eax, eax + mov rcx, rdx + stac + rep movsb + clac + ret + "], + default: [" + xor eax, eax + mov rcx, rdx + rep movsb + ret + "] + )); } pub use arch_copy_to_user as arch_copy_from_user; diff --git a/src/arch/x86_shared/interrupt/exception.rs b/src/arch/x86_shared/interrupt/exception.rs index 05b0647412..e14859e2f8 100644 --- a/src/arch/x86_shared/interrupt/exception.rs +++ b/src/arch/x86_shared/interrupt/exception.rs @@ -49,7 +49,7 @@ interrupt_stack!(debug, @paranoid, |stack| { interrupt_stack!(non_maskable, @paranoid, |stack| { #[cfg(feature = "profiling")] - crate::profiling::nmi_handler(stack); + unsafe { crate::profiling::nmi_handler(stack) }; #[cfg(not(feature = "profiling"))] { diff --git a/src/arch/x86_shared/interrupt/irq.rs b/src/arch/x86_shared/interrupt/irq.rs index 6b91016983..1284f0d085 100644 --- a/src/arch/x86_shared/interrupt/irq.rs +++ b/src/arch/x86_shared/interrupt/irq.rs @@ -309,7 +309,7 @@ interrupt!(lapic_timer, || { }); #[cfg(feature = "profiling")] interrupt!(aux_timer, || { - lapic_eoi(); + unsafe { lapic_eoi() }; crate::ipi::ipi(IpiKind::Profile, IpiTarget::Other); }); diff --git a/src/context/arch/x86_64.rs b/src/context/arch/x86_64.rs index c77d4d4dba..ac673cf70a 100644 --- a/src/context/arch/x86_64.rs +++ b/src/context/arch/x86_64.rs @@ -332,19 +332,18 @@ pub unsafe fn switch_to(prev: &mut super::Context, next: &mut super::Context) { } // Check disassembly! -#[naked] +#[unsafe(naked)] unsafe extern "sysv64" fn switch_to_inner(_prev: &mut Context, _next: &mut Context) { - unsafe { - use Context as Cx; + use Context as Cx; - core::arch::naked_asm!( - // As a quick reminder for those who are unfamiliar with the System V ABI (extern "C"): - // - // - the current parameters are passed in the registers `rdi`, `rsi`, - // - we can modify scratch registers, e.g. rax - // - we cannot change callee-preserved registers arbitrarily, e.g. rbx, which is why we - // store them here in the first place. - concat!(" + core::arch::naked_asm!( + // As a quick reminder for those who are unfamiliar with the System V ABI (extern "C"): + // + // - the current parameters are passed in the registers `rdi`, `rsi`, + // - we can modify scratch registers, e.g. rax + // - we cannot change callee-preserved registers arbitrarily, e.g. rbx, which is why we + // store them here in the first place. + concat!(" // Save old registers, and load new ones mov [rdi + {off_rbx}], rbx mov rbx, [rsi + {off_rbx}] @@ -386,19 +385,18 @@ unsafe extern "sysv64" fn switch_to_inner(_prev: &mut Context, _next: &mut Conte "), - off_rflags = const(offset_of!(Cx, rflags)), + off_rflags = const(offset_of!(Cx, rflags)), - off_rbx = const(offset_of!(Cx, rbx)), - off_r12 = const(offset_of!(Cx, r12)), - off_r13 = const(offset_of!(Cx, r13)), - off_r14 = const(offset_of!(Cx, r14)), - off_r15 = const(offset_of!(Cx, r15)), - off_rbp = const(offset_of!(Cx, rbp)), - off_rsp = const(offset_of!(Cx, rsp)), + off_rbx = const(offset_of!(Cx, rbx)), + off_r12 = const(offset_of!(Cx, r12)), + off_r13 = const(offset_of!(Cx, r13)), + off_r14 = const(offset_of!(Cx, r14)), + off_r15 = const(offset_of!(Cx, r15)), + off_rbp = const(offset_of!(Cx, rbp)), + off_rsp = const(offset_of!(Cx, rsp)), - switch_hook = sym crate::context::switch_finish_hook, - ); - } + switch_hook = sym crate::context::switch_finish_hook, + ); } /// Allocates a new identically mapped ktable and empty utable (same memory on x86_64). diff --git a/src/main.rs b/src/main.rs index b34e1e2ce7..9fffe327f8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,10 +30,10 @@ // Overflows are very, very bad in kernel code as it may provide an attack vector for // userspace applications, and it is only checked in debug builds // TODO: address ocurrances and then deny -#![warn(clippy::integer_arithmetic)] +#![warn(clippy::arithmetic_side_effects)] // Avoid panicking in the kernel without information about the panic. Use expect // TODO: address ocurrances and then deny -#![warn(clippy::result_unwrap_used)] +#![warn(clippy::unwrap_used)] // This is usually a serious issue - a missing import of a define where it is interpreted // as a catch-all variable in a match, for example #![deny(unreachable_patterns)] @@ -41,18 +41,15 @@ #![deny(unused_must_use)] #![warn(static_mut_refs)] // FIXME deny once all occurences are fixed #![feature(allocator_api)] +#![feature(if_let_guard)] #![feature(int_roundings)] #![feature(iter_next_chunk)] -#![feature(let_chains)] -#![feature(naked_functions)] -#![feature(slice_as_chunks)] +#![feature(iterator_try_collect)] #![feature(sync_unsafe_cell)] +#![feature(thread_local)] #![feature(variant_count)] #![cfg_attr(not(test), no_std)] #![cfg_attr(not(test), no_main)] -#![feature(if_let_guard)] -#![feature(iterator_try_collect)] -#![feature(new_zeroed_alloc)] #[macro_use] extern crate alloc; diff --git a/src/profiling.rs b/src/profiling.rs index 5d80918322..7d420d7dcc 100644 --- a/src/profiling.rs +++ b/src/profiling.rs @@ -64,23 +64,25 @@ impl RingBuffer { } pub unsafe fn extend(&self, mut slice: &[usize]) -> usize { let mut n = 0; - for mut sender_slice in self.sender_owned() { + for mut sender_slice in unsafe { self.sender_owned() } { while !slice.is_empty() && !sender_slice.is_empty() { - sender_slice[0].get().write(slice[0]); + unsafe { sender_slice[0].get().write(slice[0]) }; slice = &slice[1..]; sender_slice = &sender_slice[1..]; n += 1; } } - self.advance_tail(n); + unsafe { self.advance_tail(n) }; n } pub unsafe fn peek(&self) -> [&[usize]; 2] { - self.receiver_owned() - .map(|slice| core::slice::from_raw_parts(slice.as_ptr().cast(), slice.len())) + unsafe { + self.receiver_owned() + .map(|slice| core::slice::from_raw_parts(slice.as_ptr().cast(), slice.len())) + } } pub unsafe fn advance(&self, n: usize) { - self.advance_head(n) + unsafe { self.advance_head(n) } } pub fn create() -> &'static Self { Box::leak(Box::new(Self { @@ -168,7 +170,7 @@ pub unsafe fn nmi_handler(stack: &InterruptStack) { let mut buf = [0_usize; 32]; buf[0] = stack.iret.rip & !(1 << 63); - buf[1] = x86::time::rdtsc() as usize; + buf[1] = unsafe { x86::time::rdtsc() } as usize; let mut bp = stack.preserved.rbp; @@ -179,8 +181,8 @@ pub unsafe fn nmi_handler(stack: &InterruptStack) { { break; } - let ip = ((bp + 8) as *const usize).read(); - bp = (bp as *const usize).read(); + let ip = unsafe { ((bp + 8) as *const usize).read() }; + bp = unsafe { (bp as *const usize).read() }; if ip < crate::kernel_executable_offsets::__text_start() || ip >= crate::kernel_executable_offsets::__text_end() @@ -192,7 +194,7 @@ pub unsafe fn nmi_handler(stack: &InterruptStack) { len = i + 1; } - let _ = profiling.extend(&buf[..len]); + let _ = unsafe { profiling.extend(&buf[..len]) }; } pub unsafe fn init() { let percpu = PercpuBlock::current(); @@ -207,8 +209,8 @@ pub unsafe fn init() { profiling as *const _ as *mut _, core::sync::atomic::Ordering::SeqCst, ); - (core::ptr::addr_of!(percpu.profiling) as *mut Option<&'static RingBuffer>) - .write(Some(profiling)); + unsafe { (core::ptr::addr_of!(percpu.profiling) as *mut Option<&'static RingBuffer>) + .write(Some(profiling)) }; } static ACK: AtomicU32 = AtomicU32::new(0); @@ -225,8 +227,6 @@ pub fn maybe_run_profiling_helper_forever(cpu_id: LogicalCpuId) { for i in 33..255 { crate::idt::IDTS .write() - .as_mut() - .unwrap() .get_mut(&cpu_id) .unwrap() .entries[i]