good execution of nested nmi
This commit is contained in:
@@ -41,11 +41,54 @@ interrupt_stack!(debug, @paranoid, |stack| {
|
||||
}
|
||||
});
|
||||
|
||||
fn report_word(label: &str, addr: u64) {
|
||||
let val : u64;
|
||||
unsafe {
|
||||
core::arch::asm!("mov {rval}, [{maddr}]", rval = out(reg) val, maddr = in(reg) addr);
|
||||
}
|
||||
println!("> {:<8} : 0x{:016x}", label, val);
|
||||
}
|
||||
|
||||
fn print_interrupt_stack() {
|
||||
unsafe {
|
||||
let cs: u64;
|
||||
let ss: u64;
|
||||
core::arch::asm!("mov {}, cs", out(reg) cs);
|
||||
core::arch::asm!("mov {}, ss", out(reg) ss);
|
||||
|
||||
let btm: u64 = crate::gdt::KPCR.tss.0.ist[0];
|
||||
println!("Interrupt Stack [BTM:0x{:016x}] CS:{} SS:{}", btm, cs, ss);
|
||||
|
||||
report_word("O.SS ", btm - 1*8);
|
||||
report_word("O.RSP ", btm - 2*8);
|
||||
report_word("O.RFLAGS", btm - 3*8);
|
||||
report_word("O.CS ", btm - 4*8);
|
||||
report_word("O.RIP ", btm - 5*8);
|
||||
|
||||
report_word("Temp.RDX", btm - 6*8);
|
||||
report_word("NMI.XVar", btm - 7*8);
|
||||
|
||||
report_word("I.SS ", btm - 8*8);
|
||||
report_word("I.RSP ", btm - 9*8);
|
||||
report_word("I.RFLAGS", btm - 10*8);
|
||||
report_word("I.CS ", btm - 11*8);
|
||||
report_word("I.RIP ", btm - 12*8);
|
||||
|
||||
report_word("S.SS ", btm - 13*8);
|
||||
report_word("S.RSP ", btm - 14*8);
|
||||
report_word("S.RFLAGS", btm - 15*8);
|
||||
report_word("S.CS ", btm - 16*8);
|
||||
report_word("S.RIP ", btm - 17*8);
|
||||
}
|
||||
}
|
||||
|
||||
nmi_handler!(non_maskable, |stack| {
|
||||
println!("Non-maskable interrupt");
|
||||
print_interrupt_stack();
|
||||
// stack.dump();
|
||||
println!(" CS: {}", stack.iret.cs);
|
||||
//println!(" CS: {}", stack.iret.cs);
|
||||
println!("CPU ID: {}",crate::cpu_id());
|
||||
//stack_trace();
|
||||
|
||||
use crate::time::realtime;
|
||||
|
||||
@@ -55,16 +98,26 @@ nmi_handler!(non_maskable, |stack| {
|
||||
// Page Fault
|
||||
let addr = 0xDEADC0DE as *mut u8;
|
||||
let n = core::ptr::read(addr);
|
||||
//println!("Value is {}", n);
|
||||
println!("Value is {}", n);
|
||||
// core::arch::asm!(
|
||||
// "
|
||||
// mov rdx, [0xDEADC0DE]
|
||||
// ");
|
||||
|
||||
// wait
|
||||
let mut a = 545614;
|
||||
for i in 0..10_000_000_000_u128 {
|
||||
match i % 3 {
|
||||
0 => a/= 465,
|
||||
_ => a*=146564,
|
||||
}
|
||||
}
|
||||
println!("Waited ({})",a);
|
||||
//loop{}
|
||||
|
||||
let time = realtime();
|
||||
println!("Exiting NMI inner: {}", time);
|
||||
print_interrupt_stack();
|
||||
});
|
||||
|
||||
interrupt_stack!(breakpoint, |stack| {
|
||||
|
||||
@@ -453,15 +453,6 @@ macro_rules! interrupt_stack {
|
||||
($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_rules! print_interrupt_stack {
|
||||
() => { "
|
||||
mov rdi, rsp
|
||||
call {printStack}
|
||||
"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! nmi_handler {
|
||||
($name:ident, |$stack:ident| $code:block) => {
|
||||
@@ -474,83 +465,9 @@ macro_rules! nmi_handler {
|
||||
unsafe {
|
||||
$ code
|
||||
}
|
||||
}
|
||||
fn hnmi(){
|
||||
println!("-> Handler NMI");
|
||||
}
|
||||
unsafe extern "C" fn reportWord(label: &str, rsp: u64, addr: u64) {
|
||||
let val : u64;
|
||||
core::arch::asm!("mov {rval}, [{maddr}]", rval = out(reg) val, maddr = in(reg) addr);
|
||||
print!("> {:} : 0x{:016x}", label, val);
|
||||
if(addr-4 == rsp) { print!(" <-TOP>"); } else {}
|
||||
if(addr == rsp) { print!(" <-RSP>"); } else {}
|
||||
println!("");
|
||||
}
|
||||
unsafe extern "C" fn printStack() {
|
||||
unsafe {
|
||||
let mut rsp: u64;
|
||||
let cs: u64;
|
||||
core::arch::asm!("mov {}, rdi", out(reg) rsp);
|
||||
core::arch::asm!("mov {}, cs", out(reg) cs);
|
||||
|
||||
let btm: u64 = crate::gdt::KPCR.tss.0.ist[0];
|
||||
let mut val: u64;
|
||||
println!("Interrupt Stack [BTM:0x{:016x},RSP:0x{:016x}] ({:} bytes) CS:{}", btm, rsp, btm - rsp, cs);
|
||||
|
||||
reportWord("O.SS ", rsp, btm - 1*8);
|
||||
reportWord("O.RSP ", rsp, btm - 2*8);
|
||||
reportWord("O.RFLAGS", rsp, btm - 3*8);
|
||||
reportWord("O.CS ", rsp, btm - 4*8);
|
||||
reportWord("O.RIP ", rsp, btm - 5*8);
|
||||
|
||||
reportWord("Temp.RDX", rsp, btm - 6*8);
|
||||
reportWord("NMI.XVar", rsp, btm - 7*8);
|
||||
|
||||
reportWord("I.SS ", rsp, btm - 8*8);
|
||||
reportWord("I.RSP ", rsp, btm - 9*8);
|
||||
reportWord("I.RFLAGS", rsp, btm - 10*8);
|
||||
reportWord("I.CS ", rsp, btm - 11*8);
|
||||
reportWord("I.RIP ", rsp, btm - 12*8);
|
||||
|
||||
reportWord("S.SS ", rsp, btm - 13*8);
|
||||
reportWord("S.RSP ", rsp, btm - 14*8);
|
||||
reportWord("S.RFLAGS", rsp, btm - 15*8);
|
||||
reportWord("S.CS ", rsp, btm - 16*8);
|
||||
reportWord("S.RIP ", rsp, btm - 17*8);
|
||||
}
|
||||
}
|
||||
unsafe extern "C" fn printV() {
|
||||
unsafe{
|
||||
core::arch::asm!("
|
||||
mov rbx, rdi
|
||||
");
|
||||
let mut var: usize;
|
||||
core::arch::asm!("mov {}, rbx", out(reg) var);
|
||||
println!("val: {:016x}",var);
|
||||
}
|
||||
}
|
||||
fn vnmi(){
|
||||
unsafe{
|
||||
println!("-> Var NMI");
|
||||
}
|
||||
}
|
||||
fn fnmi(){
|
||||
println!("-> First NMI");
|
||||
}
|
||||
fn nnmi(){
|
||||
println!("-> Nested NMI");
|
||||
}
|
||||
fn onmi(){
|
||||
println!("-> Out NMI");
|
||||
}
|
||||
core::arch::asm!(concat!(
|
||||
"
|
||||
//call {hnmi}
|
||||
sub rsp, $(50*8)
|
||||
",
|
||||
print_interrupt_stack!(),
|
||||
"
|
||||
add rsp, $(50*8)
|
||||
push rdx
|
||||
|
||||
cmp QWORD PTR [rsp + 8*2], {GDT_KERNEL_CODE}
|
||||
@@ -558,29 +475,27 @@ macro_rules! nmi_handler {
|
||||
",
|
||||
// not from user space
|
||||
"
|
||||
//call {vnmi}
|
||||
mov rdi, [rsp - 8]
|
||||
//call {printV}
|
||||
|
||||
cmp QWORD PTR [rsp - 8], $1
|
||||
je nested_nmi
|
||||
",
|
||||
// if nmi stack
|
||||
"
|
||||
lea rdx, [rsp + 6*8]
|
||||
cmp [rsp + 4*8], rdx
|
||||
cmp rdx, [rsp + 4*8]
|
||||
ja first_nmi
|
||||
|
||||
sub rdx, $((5*3+2)*8)
|
||||
cmp rdx, [rsp + 4*8]
|
||||
jb first_nmi
|
||||
",
|
||||
// nested nmi
|
||||
"
|
||||
nested_nmi:
|
||||
//call {nnmi}
|
||||
|
||||
/// ! repalce with address of repeat nmi and end repeat nmi
|
||||
mov rdx, 0x080beb1c
|
||||
mov rdx, 0xffffff00000735d0
|
||||
cmp rdx, [rsp + 8]
|
||||
ja 1f
|
||||
mov rdx, 0x080beb41
|
||||
mov rdx, 0xffffff00000735f5
|
||||
cmp rdx, [rsp + 8]
|
||||
ja nested_nmi_out
|
||||
",
|
||||
@@ -595,7 +510,10 @@ macro_rules! nmi_handler {
|
||||
pushf
|
||||
push {GDT_KERNEL_CODE}
|
||||
//replace address repeat nmi
|
||||
push 0x080beb1c
|
||||
mov rdx, 0xffffff00000735d0
|
||||
push rdx
|
||||
|
||||
add rsp, $(6*8)
|
||||
",
|
||||
// nested nmi out
|
||||
"
|
||||
@@ -607,16 +525,14 @@ macro_rules! nmi_handler {
|
||||
"
|
||||
first_nmi:
|
||||
mov rdx, [rsp]
|
||||
push $1
|
||||
//call {fnmi}
|
||||
push $1
|
||||
",
|
||||
//print_interrupt_stack!(),
|
||||
// first copy (saved)
|
||||
"
|
||||
sub rsp, $(5*8)
|
||||
|
||||
.rept 5
|
||||
push [rsp + 11*8]
|
||||
push [rsp + 11*8]
|
||||
.endr
|
||||
",
|
||||
//second copy
|
||||
@@ -627,9 +543,9 @@ macro_rules! nmi_handler {
|
||||
add rsp, $(10*8)
|
||||
|
||||
.rept 5
|
||||
push [rsp - 6*8]
|
||||
push [rsp - 6*8]
|
||||
.endr
|
||||
sub rsp, $(5*8)
|
||||
sub rsp, $(5*8)
|
||||
",
|
||||
//normal continuation
|
||||
"
|
||||
@@ -657,13 +573,6 @@ macro_rules! nmi_handler {
|
||||
|
||||
mov QWORD PTR [rsp + 5*8], $0
|
||||
|
||||
//call {onmi}
|
||||
sub rsp, $(50*8)
|
||||
",
|
||||
print_interrupt_stack!(),
|
||||
"
|
||||
add rsp, $(50*8)
|
||||
|
||||
iretq
|
||||
",
|
||||
|
||||
@@ -671,16 +580,8 @@ macro_rules! nmi_handler {
|
||||
|
||||
inner = sym inner,
|
||||
|
||||
hnmi = sym hnmi,
|
||||
vnmi = sym vnmi,
|
||||
fnmi = sym fnmi,
|
||||
nnmi = sym nnmi,
|
||||
onmi = sym onmi,
|
||||
printStack = sym printStack,
|
||||
printV = sym printV,
|
||||
|
||||
GDT_KERNEL_CODE = const(crate::gdt::GDT_KERNEL_CODE),
|
||||
GDT_KERNEL_DATA = const(crate::gdt::GDT_KERNEL_DATA),
|
||||
GDT_KERNEL_CODE = const(crate::gdt::GDT_KERNEL_CODE << 3),
|
||||
GDT_KERNEL_DATA = const(crate::gdt::GDT_KERNEL_DATA << 3),
|
||||
|
||||
// IA32_GS_BASE = const(x86::msr::IA32_GS_BASE),
|
||||
// KERNEL_PERCPU_SHIFT = const(crate::KERNEL_PERCPU_SHIFT),
|
||||
|
||||
Reference in New Issue
Block a user