diff --git a/src/arch/x86/interrupt/handler.rs b/src/arch/x86/interrupt/handler.rs index 0c7f807dd6..1476027b43 100644 --- a/src/arch/x86/interrupt/handler.rs +++ b/src/arch/x86/interrupt/handler.rs @@ -206,19 +206,23 @@ macro_rules! pop_preserved { " }; } +// Must always happen after push_scratch macro_rules! enter_gs { () => { " // Enter kernel GS segment - push gs - push 0x18 - pop gs + mov ecx, gs + push ecx + mov ecx, 0x18 + mov gs, ecx " } } +// Must always happen before pop_scratch macro_rules! exit_gs { () => { " // Exit kernel GS segment - pop gs + pop ecx + mov gs, ecx " } } @@ -408,12 +412,11 @@ macro_rules! interrupt_error { #[naked] unsafe extern "C" fn usercopy_trampoline() { core::arch::asm!(" - mov eax, 1 - pop esi pop edi - ret 4 + mov eax, 1 + ret ", options(noreturn)); } diff --git a/src/arch/x86/mod.rs b/src/arch/x86/mod.rs index c2c38730a6..c1448191dc 100644 --- a/src/arch/x86/mod.rs +++ b/src/arch/x86/mod.rs @@ -52,37 +52,28 @@ pub mod flags { pub const FLAG_SINGLESTEP: usize = 1 << SHIFT_SINGLESTEP; pub const FLAG_INTERRUPTS: usize = 1 << 9; } -pub use arch_copy_to_user as arch_copy_from_user; - -#[inline(always)] -pub unsafe fn arch_copy_to_user(dst: usize, src: usize, len: usize) -> u8 { - arch_copy_to_user_inner(len, dst, src) -} #[naked] #[link_section = ".usercopy-fns"] -#[no_mangle] -pub unsafe extern "fastcall" fn arch_copy_to_user_inner(len: usize, dst: usize, src: usize) -> u8 { - // Explicitly specified __fastcall ABI: - // - // ECX = len, EDX = dst, src is pushed to the stack (earlier than the CALL return address, of - // course) +pub unsafe extern "C" fn arch_copy_to_user(dst: usize, src: usize, len: usize) -> u8 { core::arch::asm!(" - push edi - push esi + push edi + push esi - mov edi, edx - mov esi, [esp+12] + mov edi, [esp + 12] # dst + mov esi, [esp + 16] # src + mov ecx, [esp + 20] # len + rep movsb - xor eax, eax - rep movsb + pop esi + pop edi - pop esi - pop edi - - ret 4 + xor eax, eax + ret ", options(noreturn)); } +pub use arch_copy_to_user as arch_copy_from_user; + pub unsafe fn bootstrap_mem(bootstrap: &Bootstrap) -> &'static [u8] { core::slice::from_raw_parts(CurrentRmmArch::phys_to_virt(bootstrap.base.start_address()).data() as *const u8, bootstrap.page_count * PAGE_SIZE) }