add some code for linux like nmi handling

This commit is contained in:
vandechat96
2023-05-03 23:28:58 +02:00
parent 6013640ad7
commit fd31a78c01
4 changed files with 153 additions and 6 deletions

2
.gitignore vendored
View File

@@ -1 +1 @@
target
.idea

View File

@@ -41,7 +41,7 @@ interrupt_stack!(debug, @paranoid, |stack| {
}
});
interrupt_stack!(non_maskable, @paranoid, |stack| {
nmi_handler!(non_maskable, |stack| {
println!("Non-maskable interrupt");
stack.dump();
});

View File

@@ -406,12 +406,21 @@ macro_rules! interrupt_stack {
$code
}
}
fn function_name(){
println!("hello");
}
fn function_name2(){
println!("hello 2");
}
core::arch::asm!(concat!(
// Backup all userspace registers to stack
$save1!(),
"push rax\n",
push_scratch!(),
push_preserved!(),
"
//call {p}
",
$save2!(),
@@ -434,9 +443,15 @@ macro_rules! interrupt_stack {
pop_scratch!(),
$rstor1!(),
"
// call {p2}
",
"iretq\n",
),
p = sym function_name,
p2 = sym function_name2,
inner = sym inner,
IA32_GS_BASE = const(x86::msr::IA32_GS_BASE),
KERNEL_PERCPU_SHIFT = const(crate::KERNEL_PERCPU_SHIFT),
@@ -452,6 +467,138 @@ macro_rules! interrupt_stack {
($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!, save_and_set_gsbase_paranoid!, restore_gsbase_paranoid!, nop!, is_paranoid: true, |$stack| $code); }
}
#[macro_export]
macro_rules! nmi_handler {
($name:ident, |$stack:ident| $code:block) => {
#[naked]
#[allow(named_asm_labels)]
pub unsafe extern "C" fn $ name() {
unsafe extern "C" fn inner( $ stack: &mut $ crate::arch::x86_64::interrupt::InterruptStack) {
# [allow(unused_unsafe)]
unsafe {
$ code
}
}
core::arch::asm!(concat!(
"
push rdx
// replace test come from kernel
cmp QWORD PTR [rsp + 8*2], {GDT_KERNEL_CODE}
jne first_nmi
",
// not from user space
"
cmp QWORD PTR [rsp -8], $1
je nested_nmi
",
// if nmi stack
"
lea rdx, [rsp + 6*8]
cmp 4*8[rsp], rdx
ja first_nmi
",
// nested nmi
"
nested_nmi:
/// ! repalce with address of repeat nmi and end repeat nmi
mov rdx, 0x080a3352
cmp rdx, 8[rsp]
ja 1f
mov rdx, 0x080a3377
cmp rdx, 8[rsp]
ja nested_nmi_out
",
// prepare
"
1:
lea rdx, -1*8[rsp]
mov rsp, rdx
lea rdx, -10*8[rsp]
push {GDT_KERNEL_DATA}
push rdx
pushf
push {GDT_KERNEL_CODE}
//replace address repeat nmi
push 0x080a3352
",
// nested nmi out
"
nested_nmi_out:
pop rdx
iretq
",
// first nmi
"
first_nmi:
mov rdx, [rsp]
push $1
",
// first copy
"
sub rsp, $(5*8)
.rept 5
push 11*8[rsp]
.endr
",
//second copy
"
repeat_nmi:
mov QWORD PTR 10*8[rsp], $1
add rsp, $(10*8)
.rept 5
push -6*8[rsp]
.endr
sub rsp, $(5*8)
",
//normal continuation
"
end_repeat_nmi:
",
swapgs_iff_ring3_fast!(),
"
push rax
",
push_scratch!(),
push_preserved!(),
// save_and_set_gsbase_paranoid!(),
"
mov rdi,rsp
call {inner}
",
// restore_gbase_paranoid!(),
pop_preserved!(),
pop_scratch!(),
swapgs_iff_ring3_fast!(),
"
7:
add rsp,$6*8
mov QWORD PTR 5*8[rsp], $0
iretq
",
),
inner = sym inner,
GDT_KERNEL_CODE = const(crate::gdt::GDT_KERNEL_CODE),
GDT_KERNEL_DATA = const(crate::gdt::GDT_KERNEL_DATA),
options(noreturn),
);
}
}
}
#[macro_export]
macro_rules! interrupt {

View File

@@ -33,7 +33,7 @@ use self::flag::{MapFlags, PhysmapFlags, WaitFlags};
use self::number::*;
use crate::context::ContextId;
use crate::interrupt::exception::{divide_by_zero, non_maskable};
use crate::interrupt::exception::divide_by_zero;
use crate::interrupt::InterruptStack;
use crate::scheme::{FileHandle, SchemeNamespace, memory::MemoryScheme};
@@ -63,9 +63,9 @@ pub mod validate;
fn nmi_t() -> Result<usize>{
println!("Yo");
unsafe {
//non_maskable();
}
// unsafe {
// divide_by_zero();
// }
Ok(0)
}