Remove unnecessary unsafe blocks in naked functions

This commit is contained in:
bjorn3
2025-10-19 11:48:46 +02:00
parent 3c3eaa0004
commit b09659ac25
9 changed files with 103 additions and 123 deletions
+10 -12
View File
@@ -368,7 +368,7 @@ macro_rules! exception_stack {
($name:ident, |$stack:ident| $code:block) => {
#[unsafe(naked)]
#[unsafe(no_mangle)]
pub unsafe extern "C" fn $name(stack: &mut $crate::arch::aarch64::interrupt::InterruptStack) { unsafe {
pub unsafe extern "C" fn $name(stack: &mut $crate::arch::aarch64::interrupt::InterruptStack) {
unsafe extern "C" fn inner($stack: &mut $crate::arch::aarch64::interrupt::InterruptStack) { unsafe {
$code
}}
@@ -390,19 +390,17 @@ macro_rules! exception_stack {
"eret\n",
), sym inner);
}}
}
};
}
#[unsafe(naked)]
pub unsafe extern "C" fn enter_usermode() -> ! {
unsafe {
core::arch::naked_asm!(concat!(
"blr x28\n",
// Restore all userspace registers
pop_special!(),
pop_scratch!(),
pop_preserved!(),
"eret\n",
));
}
core::arch::naked_asm!(concat!(
"blr x28\n",
// Restore all userspace registers
pop_special!(),
pop_scratch!(),
pop_preserved!(),
"eret\n",
));
}
+4 -6
View File
@@ -39,10 +39,9 @@ pub use arch_copy_to_user as arch_copy_from_user;
#[unsafe(naked)]
#[unsafe(link_section = ".usercopy-fns")]
pub unsafe extern "C" fn arch_copy_to_user(dst: usize, src: usize, len: usize) -> u8 {
unsafe {
// x0, x1, x2
core::arch::naked_asm!(
"
// x0, x1, x2
core::arch::naked_asm!(
"
mov x4, x0
mov x0, 0
2:
@@ -60,8 +59,7 @@ pub unsafe extern "C" fn arch_copy_to_user(dst: usize, src: usize, len: usize) -
3:
ret
"
);
}
);
}
pub const KFX_SIZE: usize = 1024;
+11 -13
View File
@@ -302,17 +302,15 @@ macro_rules! pop_registers {
#[unsafe(naked)]
pub unsafe extern "C" fn enter_usermode() -> ! {
unsafe {
core::arch::naked_asm!(concat!(
"jalr s11\n",
"li t0, 1 << 8\n", // force U mode on sret
"csrc sstatus, t0\n",
"li t0, 0x6000\n", // set FS to dirty (enable FPU in U mode)
"csrs sstatus, t0\n",
"addi t0, sp, 32 * 8\n", // save S mode stack to percpu
"sd t0, 8(tp)\n",
pop_registers!(),
"sret\n",
))
}
core::arch::naked_asm!(concat!(
"jalr s11\n",
"li t0, 1 << 8\n", // force U mode on sret
"csrc sstatus, t0\n",
"li t0, 0x6000\n", // set FS to dirty (enable FPU in U mode)
"csrs sstatus, t0\n",
"addi t0, sp, 32 * 8\n", // save S mode stack to percpu
"sd t0, 8(tp)\n",
pop_registers!(),
"sret\n",
))
}
+3 -5
View File
@@ -18,9 +18,8 @@ pub use arch_copy_to_user as arch_copy_from_user;
#[unsafe(link_section = ".usercopy-fns")]
#[unsafe(naked)]
pub unsafe extern "C" fn arch_copy_to_user(dst: usize, src: usize, len: usize) -> u8 {
unsafe {
naked_asm!(
"
naked_asm!(
"
addi sp, sp, -16
sd fp, 0(sp)
sd ra, 8(sp)
@@ -57,8 +56,7 @@ pub unsafe extern "C" fn arch_copy_to_user(dst: usize, src: usize, len: usize) -
5: mv a0, x0
ret
"
)
}
)
}
pub const KFX_SIZE: usize = 1024;
+19 -23
View File
@@ -267,7 +267,7 @@ macro_rules! interrupt_stack {
// use idents directly instead.
($name:ident, |$stack:ident| $code:block) => {
#[unsafe(naked)]
pub unsafe extern "C" fn $name() { unsafe {
pub unsafe extern "C" fn $name() {
unsafe extern "fastcall" fn inner($stack: &mut $crate::arch::x86::interrupt::InterruptStack) {
// TODO: Force the declarations to specify unsafe?
@@ -308,7 +308,7 @@ macro_rules! interrupt_stack {
),
inner = sym inner,
);
}}
}
};
($name:ident, |$stack:ident| $code:block) => { interrupt_stack!($name, |$stack| $code); };
($name:ident, @paranoid, |$stack:ident| $code:block) => { interrupt_stack!($name, |$stack| $code); }
@@ -318,7 +318,7 @@ macro_rules! interrupt_stack {
macro_rules! interrupt {
($name:ident, || $code:block) => {
#[unsafe(naked)]
pub unsafe extern "C" fn $name() { unsafe {
pub unsafe extern "C" fn $name() {
unsafe extern "C" fn inner() {
$code
}
@@ -350,7 +350,7 @@ macro_rules! interrupt {
),
inner = sym inner,
);
}}
}
};
}
@@ -358,7 +358,7 @@ macro_rules! interrupt {
macro_rules! interrupt_error {
($name:ident, |$stack:ident, $error_code:ident| $code:block) => {
#[unsafe(naked)]
pub unsafe extern "C" fn $name() { unsafe {
pub unsafe extern "C" fn $name() {
unsafe extern "C" fn inner($stack: &mut $crate::arch::x86::interrupt::handler::InterruptErrorStack) {
let $error_code: usize = $stack.code;
$code
@@ -406,22 +406,20 @@ macro_rules! interrupt_error {
"iretd\n",
),
inner = sym inner);
}}
}
};
}
#[unsafe(naked)]
unsafe extern "C" fn usercopy_trampoline() {
unsafe {
core::arch::naked_asm!(
"
core::arch::naked_asm!(
"
pop esi
pop edi
mov eax, 1
ret
"
);
}
);
}
impl ArchIntCtx for InterruptStack {
@@ -443,17 +441,15 @@ impl ArchIntCtx for InterruptStack {
#[unsafe(naked)]
pub unsafe extern "C" fn enter_usermode() {
unsafe {
core::arch::naked_asm!(concat!(
// TODO: Unmap PTI
// $crate::arch::x86::pti::unmap();
core::arch::naked_asm!(concat!(
// TODO: Unmap PTI
// $crate::arch::x86::pti::unmap();
// Exit kernel TLS segment
exit_gs!(),
// Restore all userspace registers
pop_preserved!(),
pop_scratch!(),
"iretd\n",
))
}
// Exit kernel TLS segment
exit_gs!(),
// Restore all userspace registers
pop_preserved!(),
pop_scratch!(),
"iretd\n",
))
}
+13 -15
View File
@@ -19,25 +19,23 @@ pub mod flags {
#[unsafe(naked)]
#[unsafe(link_section = ".usercopy-fns")]
pub unsafe extern "C" fn arch_copy_to_user(dst: usize, src: usize, len: usize) -> u8 {
unsafe {
core::arch::naked_asm!(
"
push edi
push esi
core::arch::naked_asm!(
"
push edi
push esi
mov edi, [esp + 12] # dst
mov esi, [esp + 16] # src
mov ecx, [esp + 20] # len
rep movsb
mov edi, [esp + 12] # dst
mov esi, [esp + 16] # src
mov ecx, [esp + 20] # len
rep movsb
pop esi
pop edi
pop esi
pop edi
xor eax, eax
ret
xor eax, eax
ret
"
);
}
);
}
pub use arch_copy_to_user as arch_copy_from_user;
+23 -25
View File
@@ -292,9 +292,8 @@ pub unsafe fn switch_to(prev: &mut super::Context, next: &mut super::Context) {
#[unsafe(naked)]
unsafe extern "C" fn switch_to_inner(_prev: &mut Context, _next: &mut Context) {
unsafe {
core::arch::naked_asm!(
"
core::arch::naked_asm!(
"
str x19, [x0, #{off_x19}]
ldr x19, [x1, #{off_x19}]
@@ -368,29 +367,28 @@ unsafe extern "C" fn switch_to_inner(_prev: &mut Context, _next: &mut Context) {
b {switch_hook}
",
off_x19 = const(offset_of!(Context, x19)),
off_x20 = const(offset_of!(Context, x20)),
off_x21 = const(offset_of!(Context, x21)),
off_x22 = const(offset_of!(Context, x22)),
off_x23 = const(offset_of!(Context, x23)),
off_x24 = const(offset_of!(Context, x24)),
off_x25 = const(offset_of!(Context, x25)),
off_x26 = const(offset_of!(Context, x26)),
off_x27 = const(offset_of!(Context, x27)),
off_x28 = const(offset_of!(Context, x28)),
off_x29 = const(offset_of!(Context, fp)),
off_x30 = const(offset_of!(Context, lr)),
off_elr_el1 = const(offset_of!(Context, elr_el1)),
off_sp_el0 = const(offset_of!(Context, sp_el0)),
off_tpidr_el0 = const(offset_of!(Context, tpidr_el0)),
off_tpidrro_el0 = const(offset_of!(Context, tpidrro_el0)),
off_spsr_el1 = const(offset_of!(Context, spsr_el1)),
off_esr_el1 = const(offset_of!(Context, esr_el1)),
off_sp = const(offset_of!(Context, sp)),
off_x19 = const(offset_of!(Context, x19)),
off_x20 = const(offset_of!(Context, x20)),
off_x21 = const(offset_of!(Context, x21)),
off_x22 = const(offset_of!(Context, x22)),
off_x23 = const(offset_of!(Context, x23)),
off_x24 = const(offset_of!(Context, x24)),
off_x25 = const(offset_of!(Context, x25)),
off_x26 = const(offset_of!(Context, x26)),
off_x27 = const(offset_of!(Context, x27)),
off_x28 = const(offset_of!(Context, x28)),
off_x29 = const(offset_of!(Context, fp)),
off_x30 = const(offset_of!(Context, lr)),
off_elr_el1 = const(offset_of!(Context, elr_el1)),
off_sp_el0 = const(offset_of!(Context, sp_el0)),
off_tpidr_el0 = const(offset_of!(Context, tpidr_el0)),
off_tpidrro_el0 = const(offset_of!(Context, tpidrro_el0)),
off_spsr_el1 = const(offset_of!(Context, spsr_el1)),
off_esr_el1 = const(offset_of!(Context, esr_el1)),
off_sp = const(offset_of!(Context, sp)),
switch_hook = sym crate::context::switch_finish_hook,
);
}
switch_hook = sym crate::context::switch_finish_hook,
);
}
/// Allocates a new empty utable
+2 -4
View File
@@ -154,8 +154,7 @@ pub unsafe fn switch_to(prev: &mut super::Context, next: &mut super::Context) {
#[unsafe(naked)]
unsafe extern "C" fn switch_to_inner(prev: &mut Context, next: &mut Context) {
unsafe {
core::arch::naked_asm!(r#"
core::arch::naked_asm!(r#"
sd s1, {off_s1}(a0)
ld s1, {off_s1}(a1)
@@ -225,8 +224,7 @@ unsafe extern "C" fn switch_to_inner(prev: &mut Context, next: &mut Context) {
off_sstatus = const(offset_of!(Context, sstatus)),
switch_hook = sym crate::context::switch_finish_hook,
);
}
);
}
/// Allocates a new empty utable
+18 -20
View File
@@ -256,17 +256,16 @@ pub unsafe fn switch_to(prev: &mut super::Context, next: &mut super::Context) {
// Check disassembly!
#[unsafe(naked)]
unsafe extern "cdecl" fn switch_to_inner() {
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 `edi`, `esi`,
// - we can modify scratch registers, e.g. rax
// - we cannot change callee-preserved registers arbitrarily, e.g. ebx, 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 `edi`, `esi`,
// - we can modify scratch registers, e.g. rax
// - we cannot change callee-preserved registers arbitrarily, e.g. ebx, which is why we
// store them here in the first place.
"
// ecx is prev, edx is next
// Save old registers, and load new ones
@@ -302,19 +301,18 @@ unsafe extern "cdecl" fn switch_to_inner() {
// Note that switch_finish_hook will be responsible for executing `ret`.
jmp {switch_hook}
"),
",
off_eflags = const(offset_of!(Cx, eflags)),
off_eflags = const(offset_of!(Cx, eflags)),
off_ebx = const(offset_of!(Cx, ebx)),
off_edi = const(offset_of!(Cx, edi)),
off_esi = const(offset_of!(Cx, esi)),
off_ebp = const(offset_of!(Cx, ebp)),
off_esp = const(offset_of!(Cx, esp)),
off_ebx = const(offset_of!(Cx, ebx)),
off_edi = const(offset_of!(Cx, edi)),
off_esi = const(offset_of!(Cx, esi)),
off_ebp = const(offset_of!(Cx, ebp)),
off_esp = const(offset_of!(Cx, esp)),
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)