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| {
|
nmi_handler!(non_maskable, |stack| {
|
||||||
println!("Non-maskable interrupt");
|
println!("Non-maskable interrupt");
|
||||||
|
print_interrupt_stack();
|
||||||
// stack.dump();
|
// stack.dump();
|
||||||
println!(" CS: {}", stack.iret.cs);
|
//println!(" CS: {}", stack.iret.cs);
|
||||||
println!("CPU ID: {}",crate::cpu_id());
|
println!("CPU ID: {}",crate::cpu_id());
|
||||||
|
//stack_trace();
|
||||||
|
|
||||||
use crate::time::realtime;
|
use crate::time::realtime;
|
||||||
|
|
||||||
@@ -55,16 +98,26 @@ nmi_handler!(non_maskable, |stack| {
|
|||||||
// Page Fault
|
// Page Fault
|
||||||
let addr = 0xDEADC0DE as *mut u8;
|
let addr = 0xDEADC0DE as *mut u8;
|
||||||
let n = core::ptr::read(addr);
|
let n = core::ptr::read(addr);
|
||||||
//println!("Value is {}", n);
|
println!("Value is {}", n);
|
||||||
// core::arch::asm!(
|
// core::arch::asm!(
|
||||||
// "
|
// "
|
||||||
// mov rdx, [0xDEADC0DE]
|
// 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{}
|
//loop{}
|
||||||
|
|
||||||
let time = realtime();
|
let time = realtime();
|
||||||
println!("Exiting NMI inner: {}", time);
|
println!("Exiting NMI inner: {}", time);
|
||||||
|
print_interrupt_stack();
|
||||||
});
|
});
|
||||||
|
|
||||||
interrupt_stack!(breakpoint, |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); }
|
($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_export]
|
||||||
macro_rules! nmi_handler {
|
macro_rules! nmi_handler {
|
||||||
($name:ident, |$stack:ident| $code:block) => {
|
($name:ident, |$stack:ident| $code:block) => {
|
||||||
@@ -474,83 +465,9 @@ macro_rules! nmi_handler {
|
|||||||
unsafe {
|
unsafe {
|
||||||
$ code
|
$ 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!(
|
core::arch::asm!(concat!(
|
||||||
"
|
"
|
||||||
//call {hnmi}
|
|
||||||
sub rsp, $(50*8)
|
|
||||||
",
|
|
||||||
print_interrupt_stack!(),
|
|
||||||
"
|
|
||||||
add rsp, $(50*8)
|
|
||||||
push rdx
|
push rdx
|
||||||
|
|
||||||
cmp QWORD PTR [rsp + 8*2], {GDT_KERNEL_CODE}
|
cmp QWORD PTR [rsp + 8*2], {GDT_KERNEL_CODE}
|
||||||
@@ -558,29 +475,27 @@ macro_rules! nmi_handler {
|
|||||||
",
|
",
|
||||||
// not from user space
|
// not from user space
|
||||||
"
|
"
|
||||||
//call {vnmi}
|
|
||||||
mov rdi, [rsp - 8]
|
|
||||||
//call {printV}
|
|
||||||
|
|
||||||
cmp QWORD PTR [rsp - 8], $1
|
cmp QWORD PTR [rsp - 8], $1
|
||||||
je nested_nmi
|
je nested_nmi
|
||||||
",
|
",
|
||||||
// if nmi stack
|
// if nmi stack
|
||||||
"
|
"
|
||||||
lea rdx, [rsp + 6*8]
|
lea rdx, [rsp + 6*8]
|
||||||
cmp [rsp + 4*8], rdx
|
cmp rdx, [rsp + 4*8]
|
||||||
ja first_nmi
|
ja first_nmi
|
||||||
|
|
||||||
|
sub rdx, $((5*3+2)*8)
|
||||||
|
cmp rdx, [rsp + 4*8]
|
||||||
|
jb first_nmi
|
||||||
",
|
",
|
||||||
// nested nmi
|
// nested nmi
|
||||||
"
|
"
|
||||||
nested_nmi:
|
nested_nmi:
|
||||||
//call {nnmi}
|
|
||||||
|
|
||||||
/// ! repalce with address of repeat nmi and end repeat nmi
|
/// ! repalce with address of repeat nmi and end repeat nmi
|
||||||
mov rdx, 0x080beb1c
|
mov rdx, 0xffffff00000735d0
|
||||||
cmp rdx, [rsp + 8]
|
cmp rdx, [rsp + 8]
|
||||||
ja 1f
|
ja 1f
|
||||||
mov rdx, 0x080beb41
|
mov rdx, 0xffffff00000735f5
|
||||||
cmp rdx, [rsp + 8]
|
cmp rdx, [rsp + 8]
|
||||||
ja nested_nmi_out
|
ja nested_nmi_out
|
||||||
",
|
",
|
||||||
@@ -595,7 +510,10 @@ macro_rules! nmi_handler {
|
|||||||
pushf
|
pushf
|
||||||
push {GDT_KERNEL_CODE}
|
push {GDT_KERNEL_CODE}
|
||||||
//replace address repeat nmi
|
//replace address repeat nmi
|
||||||
push 0x080beb1c
|
mov rdx, 0xffffff00000735d0
|
||||||
|
push rdx
|
||||||
|
|
||||||
|
add rsp, $(6*8)
|
||||||
",
|
",
|
||||||
// nested nmi out
|
// nested nmi out
|
||||||
"
|
"
|
||||||
@@ -607,16 +525,14 @@ macro_rules! nmi_handler {
|
|||||||
"
|
"
|
||||||
first_nmi:
|
first_nmi:
|
||||||
mov rdx, [rsp]
|
mov rdx, [rsp]
|
||||||
push $1
|
push $1
|
||||||
//call {fnmi}
|
|
||||||
",
|
",
|
||||||
//print_interrupt_stack!(),
|
|
||||||
// first copy (saved)
|
// first copy (saved)
|
||||||
"
|
"
|
||||||
sub rsp, $(5*8)
|
sub rsp, $(5*8)
|
||||||
|
|
||||||
.rept 5
|
.rept 5
|
||||||
push [rsp + 11*8]
|
push [rsp + 11*8]
|
||||||
.endr
|
.endr
|
||||||
",
|
",
|
||||||
//second copy
|
//second copy
|
||||||
@@ -627,9 +543,9 @@ macro_rules! nmi_handler {
|
|||||||
add rsp, $(10*8)
|
add rsp, $(10*8)
|
||||||
|
|
||||||
.rept 5
|
.rept 5
|
||||||
push [rsp - 6*8]
|
push [rsp - 6*8]
|
||||||
.endr
|
.endr
|
||||||
sub rsp, $(5*8)
|
sub rsp, $(5*8)
|
||||||
",
|
",
|
||||||
//normal continuation
|
//normal continuation
|
||||||
"
|
"
|
||||||
@@ -657,13 +573,6 @@ macro_rules! nmi_handler {
|
|||||||
|
|
||||||
mov QWORD PTR [rsp + 5*8], $0
|
mov QWORD PTR [rsp + 5*8], $0
|
||||||
|
|
||||||
//call {onmi}
|
|
||||||
sub rsp, $(50*8)
|
|
||||||
",
|
|
||||||
print_interrupt_stack!(),
|
|
||||||
"
|
|
||||||
add rsp, $(50*8)
|
|
||||||
|
|
||||||
iretq
|
iretq
|
||||||
",
|
",
|
||||||
|
|
||||||
@@ -671,16 +580,8 @@ macro_rules! nmi_handler {
|
|||||||
|
|
||||||
inner = sym inner,
|
inner = sym inner,
|
||||||
|
|
||||||
hnmi = sym hnmi,
|
GDT_KERNEL_CODE = const(crate::gdt::GDT_KERNEL_CODE << 3),
|
||||||
vnmi = sym vnmi,
|
GDT_KERNEL_DATA = const(crate::gdt::GDT_KERNEL_DATA << 3),
|
||||||
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),
|
|
||||||
|
|
||||||
// IA32_GS_BASE = const(x86::msr::IA32_GS_BASE),
|
// IA32_GS_BASE = const(x86::msr::IA32_GS_BASE),
|
||||||
// KERNEL_PERCPU_SHIFT = const(crate::KERNEL_PERCPU_SHIFT),
|
// KERNEL_PERCPU_SHIFT = const(crate::KERNEL_PERCPU_SHIFT),
|
||||||
|
|||||||
Reference in New Issue
Block a user