From d1db3570cecf21ffc19689f58e8cd205f2dc1ee4 Mon Sep 17 00:00:00 2001 From: vandechat96 Date: Fri, 26 May 2023 15:04:53 +0200 Subject: [PATCH] good execution of nested nmi --- src/arch/x86_64/interrupt/exception.rs | 57 ++++++++++- src/arch/x86_64/interrupt/handler.rs | 133 ++++--------------------- 2 files changed, 72 insertions(+), 118 deletions(-) diff --git a/src/arch/x86_64/interrupt/exception.rs b/src/arch/x86_64/interrupt/exception.rs index a4f1b11..34aaced 100644 --- a/src/arch/x86_64/interrupt/exception.rs +++ b/src/arch/x86_64/interrupt/exception.rs @@ -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| { diff --git a/src/arch/x86_64/interrupt/handler.rs b/src/arch/x86_64/interrupt/handler.rs index 290f7ee..79b8f60 100644 --- a/src/arch/x86_64/interrupt/handler.rs +++ b/src/arch/x86_64/interrupt/handler.rs @@ -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),