From 5b890102fb32de0ca0f7c3e7a776454b6d0bd583 Mon Sep 17 00:00:00 2001 From: yufeng <321353225@qq.com> Date: Thu, 19 Sep 2024 02:12:41 +0800 Subject: [PATCH] fix: Fix debug build caused by `kcontext_switch_pt` --- Makefile | 8 +- example/src/main.rs | 2 +- src/components/kcontext/aarch64.rs | 108 +++++++++++---------- src/components/kcontext/loongarch64.rs | 126 ++++++++++++------------- src/components/kcontext/mod.rs | 4 + src/components/kcontext/riscv64.rs | 26 +++-- src/components/kcontext/x86_64.rs | 116 ++++++++++++----------- 7 files changed, 207 insertions(+), 183 deletions(-) diff --git a/Makefile b/Makefile index 116d5a3..cb2e7ac 100644 --- a/Makefile +++ b/Makefile @@ -3,10 +3,10 @@ all: test-build: - cargo build --release --all-features --target riscv64gc-unknown-none-elf - cargo build --release --all-features --target aarch64-unknown-none-softfloat - cargo build --release --all-features --target x86_64-unknown-none - cargo build --release --all-features --target loongarch64-unknown-none + cargo build --all-features --target riscv64gc-unknown-none-elf + cargo build --all-features --target aarch64-unknown-none-softfloat + cargo build --all-features --target x86_64-unknown-none + cargo build --all-features --target loongarch64-unknown-none test-clippy: cargo clippy --all-features --target riscv64gc-unknown-none-elf diff --git a/example/src/main.rs b/example/src/main.rs index 67f4677..78c6fd5 100644 --- a/example/src/main.rs +++ b/example/src/main.rs @@ -130,7 +130,7 @@ define_entry!(main); fn panic(info: &PanicInfo) -> ! { if let Some(location) = info.location() { log::error!( - "[kernel] Panicked at {}:{} {}", + "[kernel] Panicked at {}:{} \n\t{}", location.file(), location.line(), info.message().unwrap() diff --git a/src/components/kcontext/aarch64.rs b/src/components/kcontext/aarch64.rs index b4c5728..52812e2 100644 --- a/src/components/kcontext/aarch64.rs +++ b/src/components/kcontext/aarch64.rs @@ -4,6 +4,42 @@ use crate::PageTable; use crate::components::kcontext::KContextArgs; +/// Save the task context registers. +macro_rules! save_callee_regs { + () => { + " + mrs x3, tpidr_el1 + mov x4, sp + stp x4, x3, [x0] + stp x19, x20, [x0, 2 * 8] + stp x21, x22, [x0, 4 * 8] + stp x23, x24, [x0, 6 * 8] + stp x25, x26, [x0, 8 * 8] + stp x27, x28, [x0, 10 * 8] + stp x27, x28, [x0, 10 * 8] + stp x29, x30, [x0, 12 * 8] + " + }; +} + +/// Restore the task context registers. +macro_rules! restore_callee_regs { + () => { + " + ldp x4, x3, [x1] + ldp x19, x20, [x1, 2 * 8] + ldp x21, x22, [x1, 4 * 8] + ldp x23, x24, [x1, 6 * 8] + ldp x25, x26, [x1, 8 * 8] + ldp x27, x28, [x1, 10 * 8] + ldp x27, x28, [x1, 10 * 8] + ldp x29, x30, [x1, 12 * 8] + msr tpidr_el1, x3 + mov sp, x4 + " + }; +} + /// Kernel Context /// /// Kernel Context is used to switch context between kernel task. @@ -91,32 +127,11 @@ impl IndexMut for KContext { pub unsafe extern "C" fn context_switch(from: *mut KContext, to: *const KContext) { core::arch::asm!( // Save Kernel Context. - " - mrs x3, tpidr_el1 - mov x4, sp - stp x4, x3, [x0] - stp x19, x20, [x0, 2 * 8] - stp x21, x22, [x0, 4 * 8] - stp x23, x24, [x0, 6 * 8] - stp x25, x26, [x0, 8 * 8] - stp x27, x28, [x0, 10 * 8] - stp x27, x28, [x0, 10 * 8] - stp x29, x30, [x0, 12 * 8] - ", + save_callee_regs!(), // Restore Kernel Context. - " - ldp x4, x3, [x1] - ldp x19, x20, [x1, 2 * 8] - ldp x21, x22, [x1, 4 * 8] - ldp x23, x24, [x1, 6 * 8] - ldp x25, x26, [x1, 8 * 8] - ldp x27, x28, [x1, 10 * 8] - ldp x27, x28, [x1, 10 * 8] - ldp x29, x30, [x1, 12 * 8] - msr tpidr_el1, x3 - mov sp, x4 - ret - ", + restore_callee_regs!(), + // Return to the caller. + "ret", options(noreturn) ) } @@ -124,26 +139,27 @@ pub unsafe extern "C" fn context_switch(from: *mut KContext, to: *const KContext /// Context Switch With Page Table /// /// Save the context of current task and switch to new task. -#[naked] +#[inline] pub unsafe extern "C" fn context_switch_pt( from: *mut KContext, to: *const KContext, pt_token: PageTable, +) { + context_switch_pt_impl(from, to, pt_token.0.0); +} + +/// Context Switch With Page Table Implement +/// +/// The detail implementation of [context_switch_pt]. +#[naked] +unsafe extern "C" fn context_switch_pt_impl( + from: *mut KContext, + to: *const KContext, + pt_token: usize, ) { core::arch::asm!( // Save Kernel Context. - " - mrs x3, tpidr_el1 - mov x4, sp - stp x4, x3, [x0] - stp x19, x20, [x0, 2 * 8] - stp x21, x22, [x0, 4 * 8] - stp x23, x24, [x0, 6 * 8] - stp x25, x26, [x0, 8 * 8] - stp x27, x28, [x0, 10 * 8] - stp x27, x28, [x0, 10 * 8] - stp x29, x30, [x0, 12 * 8] - ", + save_callee_regs!(), // Switch to new page table. " msr ttbr0_el1, x2 @@ -152,19 +168,9 @@ pub unsafe extern "C" fn context_switch_pt( isb ", // Restore Kernel Context. - " - ldp x4, x3, [x1] - ldp x19, x20, [x1, 2 * 8] - ldp x21, x22, [x1, 4 * 8] - ldp x23, x24, [x1, 6 * 8] - ldp x25, x26, [x1, 8 * 8] - ldp x27, x28, [x1, 10 * 8] - ldp x27, x28, [x1, 10 * 8] - ldp x29, x30, [x1, 12 * 8] - msr tpidr_el1, x3 - mov sp, x4 - ret - ", + restore_callee_regs!(), + // Return to the caller. + "ret", options(noreturn) ) } diff --git a/src/components/kcontext/loongarch64.rs b/src/components/kcontext/loongarch64.rs index d504d66..08dda7d 100644 --- a/src/components/kcontext/loongarch64.rs +++ b/src/components/kcontext/loongarch64.rs @@ -5,6 +5,48 @@ use core::{ use crate::{components::kcontext::KContextArgs, components::pagetable::PageTable}; +/// Save the task context registers. +macro_rules! save_callee_regs { + () => { + " + st.d $sp, $a0, 0*8 + st.d $tp, $a0, 1*8 + st.d $s9, $a0, 2*8 + st.d $s0, $a0, 3*8 + st.d $s1, $a0, 4*8 + st.d $s2, $a0, 5*8 + st.d $s3, $a0, 6*8 + st.d $s4, $a0, 7*8 + st.d $s5, $a0, 8*8 + st.d $s6, $a0, 9*8 + st.d $s7, $a0, 10*8 + st.d $s8, $a0, 11*8 + st.d $ra, $a0, 12*8 + " + }; +} + +/// Restore the task context registers. +macro_rules! restore_callee_regs { + () => { + " + ld.d $sp, $a1, 0*8 + ld.d $tp, $a1, 1*8 + ld.d $s9, $a1, 2*8 + ld.d $s0, $a1, 3*8 + ld.d $s1, $a1, 4*8 + ld.d $s2, $a1, 5*8 + ld.d $s3, $a1, 6*8 + ld.d $s4, $a1, 7*8 + ld.d $s5, $a1, 8*8 + ld.d $s6, $a1, 9*8 + ld.d $s7, $a1, 10*8 + ld.d $s8, $a1, 11*8 + ld.d $ra, $a1, 12*8 + " + }; +} + /// Kernel Context /// /// Kernel Context is used to switch context between kernel task. @@ -92,38 +134,11 @@ impl IndexMut for KContext { pub unsafe extern "C" fn context_switch(from: *mut KContext, to: *const KContext) { core::arch::asm!( // Save Kernel Context. - " - st.d $sp, $a0, 0*8 - st.d $tp, $a0, 1*8 - st.d $s9, $a0, 2*8 - st.d $s0, $a0, 3*8 - st.d $s1, $a0, 4*8 - st.d $s2, $a0, 5*8 - st.d $s3, $a0, 6*8 - st.d $s4, $a0, 7*8 - st.d $s5, $a0, 8*8 - st.d $s6, $a0, 9*8 - st.d $s7, $a0, 10*8 - st.d $s8, $a0, 11*8 - st.d $ra, $a0, 12*8 - ", + save_callee_regs!(), // Restore Kernel Context. - " - ld.d $sp, $a1, 0*8 - ld.d $tp, $a1, 1*8 - ld.d $s9, $a1, 2*8 - ld.d $s0, $a1, 3*8 - ld.d $s1, $a1, 4*8 - ld.d $s2, $a1, 5*8 - ld.d $s3, $a1, 6*8 - ld.d $s4, $a1, 7*8 - ld.d $s5, $a1, 8*8 - ld.d $s6, $a1, 9*8 - ld.d $s7, $a1, 10*8 - ld.d $s8, $a1, 11*8 - ld.d $ra, $a1, 12*8 - ret - ", + restore_callee_regs!(), + // Return to the caller. + "ret", options(noreturn) ) } @@ -131,29 +146,27 @@ pub unsafe extern "C" fn context_switch(from: *mut KContext, to: *const KContext /// Context Switch With Page Table /// /// Save the context of current task and switch to new task. -#[naked] +#[inline] pub unsafe extern "C" fn context_switch_pt( from: *mut KContext, to: *const KContext, pt_token: PageTable, +) { + context_switch_pt_impl(from, to, pt_token.0.0); +} + +/// Context Switch With Page Table Implement +/// +/// The detail implementation of [context_switch_pt]. +#[naked] +unsafe extern "C" fn context_switch_pt_impl( + from: *mut KContext, + to: *const KContext, + pt_token: usize, ) { core::arch::asm!( // Save Kernel Context. - " - st.d $sp, $a0, 0*8 - st.d $tp, $a0, 1*8 - st.d $s9, $a0, 2*8 - st.d $s0, $a0, 3*8 - st.d $s1, $a0, 4*8 - st.d $s2, $a0, 5*8 - st.d $s3, $a0, 6*8 - st.d $s4, $a0, 7*8 - st.d $s5, $a0, 8*8 - st.d $s6, $a0, 9*8 - st.d $s7, $a0, 10*8 - st.d $s8, $a0, 11*8 - st.d $ra, $a0, 12*8 - ", + save_callee_regs!(), // Switch to new page table. // Write PageTable to pgdl(CSR 0x19) " @@ -162,22 +175,9 @@ pub unsafe extern "C" fn context_switch_pt( invtlb 0x00, $r0, $r0 ", // Restore Kernel Context. - " - ld.d $sp, $a1, 0*8 - ld.d $tp, $a1, 1*8 - ld.d $s9, $a1, 2*8 - ld.d $s0, $a1, 3*8 - ld.d $s1, $a1, 4*8 - ld.d $s2, $a1, 5*8 - ld.d $s3, $a1, 6*8 - ld.d $s4, $a1, 7*8 - ld.d $s5, $a1, 8*8 - ld.d $s6, $a1, 9*8 - ld.d $s7, $a1, 10*8 - ld.d $s8, $a1, 11*8 - ld.d $ra, $a1, 12*8 - ret - ", + restore_callee_regs!(), + // Return to the caller. + "ret", options(noreturn) ) } diff --git a/src/components/kcontext/mod.rs b/src/components/kcontext/mod.rs index f92ec41..3f55712 100644 --- a/src/components/kcontext/mod.rs +++ b/src/components/kcontext/mod.rs @@ -2,6 +2,8 @@ //! //! +use crate::pub_use_arch; + super::define_arch_mods!(); /// Kernel Context Arg Type. @@ -16,3 +18,5 @@ pub enum KContextArgs { /// Kernel Program Counter KPC, } + +pub_use_arch!(context_switch, context_switch_pt); diff --git a/src/components/kcontext/riscv64.rs b/src/components/kcontext/riscv64.rs index 812db08..b5d6c7d 100644 --- a/src/components/kcontext/riscv64.rs +++ b/src/components/kcontext/riscv64.rs @@ -8,7 +8,7 @@ use crate::PageTable; use crate::components::kcontext::KContextArgs; /// Save the task context registers. -macro_rules! save_kcontext_regs { +macro_rules! save_callee_regs { () => { " sd sp, 0*8(a0) @@ -31,7 +31,7 @@ macro_rules! save_kcontext_regs { } /// Restore the task context registers. -macro_rules! restore_kcontext_regs { +macro_rules! restore_callee_regs { () => { " ld sp, 0*8(a1) @@ -150,9 +150,9 @@ impl IndexMut for KContext { pub unsafe extern "C" fn context_switch(from: *mut KContext, to: *const KContext) { core::arch::asm!( // Save Kernel Context. - save_kcontext_regs!(), + save_callee_regs!(), // Restore Kernel Context. - restore_kcontext_regs!(), + restore_callee_regs!(), // Return to the caller. ret!(), options(noreturn) @@ -162,15 +162,27 @@ pub unsafe extern "C" fn context_switch(from: *mut KContext, to: *const KContext /// Context Switch With Page Table /// /// Save the context of current task and switch to new task. -#[naked] +#[inline] pub unsafe extern "C" fn context_switch_pt( from: *mut KContext, to: *const KContext, pt_token: PageTable, +) { + context_switch_pt_impl(from, to, pt_token.0.0); +} + +/// Context Switch With Page Table Implement +/// +/// The detail implementation of [context_switch_pt]. +#[naked] +unsafe extern "C" fn context_switch_pt_impl( + from: *mut KContext, + to: *const KContext, + pt_token: usize, ) { core::arch::asm!( // Save Kernel Context. - save_kcontext_regs!(), + save_callee_regs!(), // Switch to new page table. " srli a2, a2, 12 @@ -180,7 +192,7 @@ pub unsafe extern "C" fn context_switch_pt( sfence.vma ", // Restore Kernel Context. - restore_kcontext_regs!(), + restore_callee_regs!(), // Return to the caller. ret!(), options(noreturn) diff --git a/src/components/kcontext/x86_64.rs b/src/components/kcontext/x86_64.rs index 165c692..0285a86 100644 --- a/src/components/kcontext/x86_64.rs +++ b/src/components/kcontext/x86_64.rs @@ -6,6 +6,47 @@ use crate::PageTable; use crate::components::kcontext::KContextArgs; +/// Save the task context registers. +macro_rules! save_callee_regs { + () => { + " + mov [rdi + 0 * 8], rsp + mov [rdi + 2 * 8], rbx + mov [rdi + 3 * 8], rbp + mov [rdi + 4 * 8], r12 + mov [rdi + 5 * 8], r13 + mov [rdi + 6 * 8], r14 + mov [rdi + 7 * 8], r15 + mov [rdi + 8 * 8], r8 # save old rip to stack + + mov ecx, 0xC0000100 + rdmsr + mov [rdi + 1*8], eax # push fabase + mov [rdi + 1*8+4], edx + " + }; +} + +/// Restore the task context registers. +macro_rules! restore_callee_regs { + () => { + " + mov ecx, 0xC0000100 + mov eax, [rsi + 1*8] + mov edx, [rsi + 1*8+4] + wrmsr # pop fsbase + mov rsp, [rsi + 0 * 8] + mov rbx, [rsi + 2 * 8] + mov rbp, [rsi + 3 * 8] + mov r12, [rsi + 4 * 8] + mov r13, [rsi + 5 * 8] + mov r14, [rsi + 6 * 8] + mov r15, [rsi + 7 * 8] + mov r8, [rsi + 8 * 8] + " + }; +} + /// Kernel Context /// /// Kernel Context is used to switch context between kernel task. @@ -110,36 +151,11 @@ pub unsafe extern "C" fn context_switch(from: *mut KContext, to: *const KContext // Save Kernel Context. " pop r8 - - mov [rdi + 0 * 8], rsp - mov [rdi + 2 * 8], rbx - mov [rdi + 3 * 8], rbp - mov [rdi + 4 * 8], r12 - mov [rdi + 5 * 8], r13 - mov [rdi + 6 * 8], r14 - mov [rdi + 7 * 8], r15 - mov [rdi + 8 * 8], r8 # save old rip to stack - - mov ecx, 0xC0000100 - rdmsr - mov [rdi + 1*8], eax # push fabase - mov [rdi + 1*8+4], edx ", + save_callee_regs!(), // Restore Kernel Context. - " - mov ecx, 0xC0000100 - mov eax, [rsi + 1*8] - mov edx, [rsi + 1*8+4] - wrmsr # pop fsbase - mov rsp, [rsi + 0 * 8] - mov rbx, [rsi + 2 * 8] - mov rbp, [rsi + 3 * 8] - mov r12, [rsi + 4 * 8] - mov r13, [rsi + 5 * 8] - mov r14, [rsi + 6 * 8] - mov r15, [rsi + 7 * 8] - mov r8, [rsi + 8 * 8] - + restore_callee_regs!(), + " push r8 ret ", @@ -150,11 +166,23 @@ pub unsafe extern "C" fn context_switch(from: *mut KContext, to: *const KContext /// Context Switch With Page Table /// /// Save the context of current task and switch to new task. -#[naked] +#[inline] pub unsafe extern "C" fn context_switch_pt( from: *mut KContext, to: *const KContext, pt_token: PageTable, +) { + context_switch_pt_impl(from, to, pt_token.0.0); +} + +/// Context Switch With Page Table Implement +/// +/// The detail implementation of [context_switch_pt]. +#[naked] +unsafe extern "C" fn context_switch_pt_impl( + from: *mut KContext, + to: *const KContext, + pt_token: usize, ) { core::arch::asm!( // consume the return address(rip) in the stack @@ -165,40 +193,14 @@ pub unsafe extern "C" fn context_switch_pt( mov r9, rdx ", // Save Kernel Context. - " - mov [rdi + 0 * 8], rsp - mov [rdi + 2 * 8], rbx - mov [rdi + 3 * 8], rbp - mov [rdi + 4 * 8], r12 - mov [rdi + 5 * 8], r13 - mov [rdi + 6 * 8], r14 - mov [rdi + 7 * 8], r15 - mov [rdi + 8 * 8], r8 # save old rip to stack - - mov ecx, 0xC0000100 - rdmsr - mov [rdi + 1*8], eax # push fabase - mov [rdi + 1*8+4], edx - ", + save_callee_regs!(), // Switch to new page table. " mov cr3, r9 ", // Restore Kernel Context. + restore_callee_regs!(), " - mov ecx, 0xC0000100 - mov eax, [rsi + 1*8] - mov edx, [rsi + 1*8+4] - wrmsr # pop fsbase - mov rsp, [rsi + 0 * 8] - mov rbx, [rsi + 2 * 8] - mov rbp, [rsi + 3 * 8] - mov r12, [rsi + 4 * 8] - mov r13, [rsi + 5 * 8] - mov r14, [rsi + 6 * 8] - mov r15, [rsi + 7 * 8] - mov r8, [rsi + 8 * 8] - push r8 ret ",