Nographic mode, fix userspace transition by setting kernel TLS back on syscall

This commit is contained in:
Jeremy Soller 2016-09-08 15:45:26 -06:00
parent fb0df8530d
commit a5d79d7957
6 changed files with 48 additions and 16 deletions

View file

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

View file

@ -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(); }
});

View file

@ -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::<usize>())).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::<usize>()) {
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);
}
}
}

View file

@ -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");
}

View file

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

View file

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