add some code for linux like nmi handling
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1 +1 @@
|
||||
target
|
||||
.idea
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user