1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

fix handling of system calls

- miss understood the ABI manual
=> push the wrong registers on the stack
This commit is contained in:
Stefan Lankes 2015-07-12 16:34:50 +02:00
parent 49cc6ade16
commit 969c67ccce
2 changed files with 29 additions and 20 deletions

View file

@ -310,6 +310,8 @@ Lno_remap:
; Set CR0 (PM-bit is already set)
mov eax, cr0
and eax, ~(1 << 2) ; disable FPU emulation
or eax, (1 << 1) ; enable FPU montitoring
and eax, ~(1 << 30) ; enable caching
and eax, ~(1 << 29) ; disable write through caching
and eax, ~(1 << 16) ; allow kernel write access to read-only pages
@ -528,14 +530,15 @@ global isrsyscall
align 8
; used to realize system calls
isrsyscall:
cli
; IF flag is already cleared => see processor.c
; cli
; save registers accross function call
push r11
push r8
push r9
push r10
push rbp
push r11
push rdx
push rcx
push rbx
push rdi
push rsi
@ -543,41 +546,43 @@ isrsyscall:
call get_kernel_stack
; restore registers
mov r11, [rsp+56]
mov r10, [rsp+48]
mov rbp, [rsp+40]
mov rdx, [rsp+32]
mov rcx, [rsp+24]
mov rbx, [rsp+16]
mov r8, [rsp+56]
mov r9, [rsp+48]
mov r10, [rsp+40]
mov r11, [rsp+32]
mov rdx, [rsp+24]
; see below
; mov rcx, [rsp+16]
mov rdi, [rsp+8]
mov rsi, [rsp+0]
xchg rsp, rax ; => rax contains pointer to the kernel stack
push rax ; contains original rsp
sti
; syscall stores in rcx the return address
; => r10 for the temporary storage of the 4th argument
; => exchange the value to get the correct order
xchg rcx, r10
; => using of r12 for the temporary storage of the 4th argument
mov rcx, r12
; during the system call, HermitCore allows interrupts
sti
call syscall_handler
cli
; restore user-level stack
pop r10
mov rsp, r10
pop rsi
pop rdi
pop rbx
pop rcx
pop rdx
pop rbp
pop r10
pop r11
sti
pop r10
pop r9
pop r8
; EFLAGS (and IF flag) will be restored by sysret
; sti
o64 sysret
global switch_context

View file

@ -223,7 +223,8 @@ int cpu_detection(void) {
wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_LMA | EFER_SCE);
wrmsr(MSR_STAR, (0x1BULL << 48) | (0x08ULL << 32));
wrmsr(MSR_LSTAR, (size_t) &isrsyscall);
wrmsr(MSR_SYSCALL_MASK, 0); // we didn't clear RFLAGS during an interrupt
// clear IF flag during an interrupt
wrmsr(MSR_SYSCALL_MASK, (1 << 9));
} else kputs("Processor doesn't support syscalls\n");
if (has_nx())
@ -286,6 +287,9 @@ int cpu_detection(void) {
kprintf("Maximum input value for hypervisor: 0x%x\n", a);
}
if (first_time)
kprintf("CR0 0x%llx, CR4 0x%llx\n", read_cr0(), read_cr4());
return 0;
}