From a5d79d79579126e815ff3547e9f06fdd622d7973 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 8 Sep 2016 15:45:26 -0600 Subject: [PATCH] Nographic mode, fix userspace transition by setting kernel TLS back on syscall --- Makefile | 2 +- arch/x86_64/src/interrupt/exception.rs | 4 +++- arch/x86_64/src/interrupt/mod.rs | 20 ++++++++++++++------ arch/x86_64/src/interrupt/syscall.rs | 13 ++++++++++++- arch/x86_64/src/lib.rs | 21 ++++++++++++++++----- arch/x86_64/src/paging/mod.rs | 4 ++-- 6 files changed, 48 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 0bf1ea1..d879ba5 100644 --- a/Makefile +++ b/Makefile @@ -13,8 +13,8 @@ ifeq ($(ARCH),arm) else LD=ld QEMUFLAGS+=-enable-kvm -cpu host -machine q35 -smp 4 + QEMUFLAGS+=-nographic -vga none #,int,pcall - #-nographic #-device intel-iommu UNAME := $(shell uname) diff --git a/arch/x86_64/src/interrupt/exception.rs b/arch/x86_64/src/interrupt/exception.rs index 40f54d5..369f448 100644 --- a/arch/x86_64/src/interrupt/exception.rs +++ b/arch/x86_64/src/interrupt/exception.rs @@ -71,7 +71,9 @@ interrupt_error!(protection, { }); interrupt_error!(page, { - print!("Page fault\n"); + let cr2: usize; + asm!("mov rax, cr2" : "={rax}"(cr2) : : : "intel", "volatile"); + println!("Page fault: {:>016X}", cr2); stack_trace(); loop { halt(); } }); diff --git a/arch/x86_64/src/interrupt/mod.rs b/arch/x86_64/src/interrupt/mod.rs index d7c6ddc..ad93b1a 100644 --- a/arch/x86_64/src/interrupt/mod.rs +++ b/arch/x86_64/src/interrupt/mod.rs @@ -52,13 +52,21 @@ pub unsafe fn stack_trace() { //Maximum 64 frames let active_table = ActivePageTable::new(); for _frame in 0..64 { - if active_table.translate(VirtualAddress::new(rbp)).is_some() && active_table.translate(VirtualAddress::new(rbp + mem::size_of::())).is_some() { - let rip = *(rbp as *const usize).offset(1); - println!(" {:>016X}: {:>016X}", rbp, rip); - rbp = *(rbp as *const usize); + if let Some(rip_rbp) = rbp.checked_add(mem::size_of::()) { + if active_table.translate(VirtualAddress::new(rbp)).is_some() && active_table.translate(VirtualAddress::new(rip_rbp)).is_some() { + let rip = *(rip_rbp as *const usize); + if rip == 0 { + println!(" {:>016X}: EMPTY RETURN", rbp); + break; + } + println!(" {:>016X}: {:>016X}", rbp, rip); + rbp = *(rbp as *const usize); + } else { + println!(" {:>016X}: GUARD PAGE", rbp); + break; + } } else { - println!(" {:>016X}: GUARD PAGE", rbp); - break; + println!(" {:>016X}: RBP OVERFLOW", rbp); } } } diff --git a/arch/x86_64/src/interrupt/syscall.rs b/arch/x86_64/src/interrupt/syscall.rs index feac040..7dfaf38 100644 --- a/arch/x86_64/src/interrupt/syscall.rs +++ b/arch/x86_64/src/interrupt/syscall.rs @@ -22,8 +22,19 @@ pub unsafe extern fn syscall() { asm!("xchg bx, bx" : : "{rax}"(a) : : "intel", "volatile"); } + asm!("xchg bx, bx + push fs + push rax + mov rax, 0x18 + mov fs, ax + pop rax" + : : : : "intel", "volatile"); + inner(); // Interrupt return - asm!("iretq" : : : : "intel", "volatile"); + asm!("xchg bx, bx + pop fs + iretq" + : : : : "intel", "volatile"); } diff --git a/arch/x86_64/src/lib.rs b/arch/x86_64/src/lib.rs index 02a5ff3..fdcea65 100644 --- a/arch/x86_64/src/lib.rs +++ b/arch/x86_64/src/lib.rs @@ -48,7 +48,8 @@ macro_rules! interrupt { } // Push scratch registers - asm!("push rax + asm!("xchg bx, bx + push rax push rcx push rdx push rdi @@ -56,14 +57,19 @@ macro_rules! interrupt { push r8 push r9 push r10 - push r11" + push r11 + push fs + mov rax, 0x18 + mov fs, ax" : : : : "intel", "volatile"); // Call inner rust function inner(); // Pop scratch registers and return - asm!("pop r11 + asm!("xchg bx, bx + pop fs + pop r11 pop r10 pop r9 pop r8 @@ -98,14 +104,19 @@ macro_rules! interrupt_error { push r8 push r9 push r10 - push r11" + push r11 + push fs + mov rax, 0x18 + mov fs, ax" : : : : "intel", "volatile"); // Call inner rust function inner(); // Pop scratch registers, error code, and return - asm!("pop r11 + asm!("xchg bx, bx + pop fs + pop r11 pop r10 pop r9 pop r8 diff --git a/arch/x86_64/src/paging/mod.rs b/arch/x86_64/src/paging/mod.rs index f55e015..0c48f7a 100644 --- a/arch/x86_64/src/paging/mod.rs +++ b/arch/x86_64/src/paging/mod.rs @@ -303,8 +303,8 @@ impl Page { } pub fn containing_address(address: VirtualAddress) -> Page { - assert!(address.get() < 0x0000_8000_0000_0000 || address.get() >= 0xffff_8000_0000_0000, - "invalid address: 0x{:x}", address.get()); + //TODO assert!(address.get() < 0x0000_8000_0000_0000 || address.get() >= 0xffff_8000_0000_0000, + // "invalid address: 0x{:x}", address.get()); Page { number: address.get() / PAGE_SIZE } }