Nographic mode, fix userspace transition by setting kernel TLS back on syscall
This commit is contained in:
parent
fb0df8530d
commit
a5d79d7957
2
Makefile
2
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)
|
||||
|
|
|
@ -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(); }
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue