good execution of nested nmi

This commit is contained in:
vandechat96
2023-05-26 15:04:53 +02:00
parent ab458968bb
commit d1db3570ce
2 changed files with 72 additions and 118 deletions

View File

@@ -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| {

View File

@@ -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),