diff --git a/kernel/user-timer.cpp b/kernel/user-timer.cpp index e0a653b2..1fb0f7ed 100644 --- a/kernel/user-timer.cpp +++ b/kernel/user-timer.cpp @@ -19,6 +19,7 @@ #include +#include #include #include #include @@ -261,25 +262,43 @@ int sys_clock_nanosleep(clockid_t clockid, const struct timespec* user_duration, struct timespec* user_remainder) { + assert(Interrupt::IsEnabled()); + struct timespec time; + assert(Interrupt::IsEnabled()); Clock* clock = Time::GetClock(clockid); + assert(Interrupt::IsEnabled()); if ( !clock ) + { + assert(Interrupt::IsEnabled()); return -1; + } if ( !CopyFromUser(&time, user_duration, sizeof(time)) ) + { + assert(Interrupt::IsEnabled()); return -1; + } if ( !timespec_is_canonical(time) ) return errno = EINVAL, -1; + assert(Interrupt::IsEnabled()); time = flags & TIMER_ABSTIME ? clock->SleepUntil(time) : clock->SleepDelay(time); + assert(Interrupt::IsEnabled()); if ( user_remainder && !CopyToUser(user_remainder, &time, sizeof(time)) ) + { + assert(Interrupt::IsEnabled()); return -1; + } - return timespec_eq(time, timespec_nul()) ? 0 : (errno = EINTR, -1); + assert(Interrupt::IsEnabled()); + int result = timespec_eq(time, timespec_nul()) ? 0 : (errno = EINTR, -1); + assert(Interrupt::IsEnabled()); + return result; } int sys_timens(struct tmns* user_tmns) diff --git a/kernel/x64/syscall.S b/kernel/x64/syscall.S index c5f065c9..2eb5ab05 100644 --- a/kernel/x64/syscall.S +++ b/kernel/x64/syscall.S @@ -30,7 +30,17 @@ syscall_handler: pushq %rbp movq %rsp, %rbp + pushq %rax + sub $8, %rsp + + pushf + pop %r10 + mov $0x200, %r11 + test %r10, %r11 + jz 5f + # Make sure the requested system call is valid, if not, then fix it. + mov %rax, %r10 cmp $SYSCALL_MAX_NUM, %rax jae 3f @@ -44,6 +54,13 @@ syscall_handler: # Call the system call. callq *%rax + pushf + pop %rsi + mov $0x200, %r8 + test %rsi, %r8 + jz 6f + addq $16, %rsp + # Return to user-space, system call result in %rax:%rdx, errno in %ecx. popq %rbp movl errno, %ecx @@ -91,4 +108,25 @@ syscall_handler: xor %r8, %r8 jmp 2b +5: + mov $syscall_interrupt_string_before, %rdi + jmp 7f +6: + mov $syscall_interrupt_string_after, %rdi + jmp 7f +7: + add $8, %rsp + pop %rsi + call PanicF + .size syscall_handler, .-syscall_handler + + .section .rodata + .type syscall_interrupt_string_before, @object + .size syscall_interrupt_string_before, 56 +syscall_interrupt_string_before: + .string "System call %u exited without interrupts enabled before" + .type syscall_interrupt_string_after, @object + .size syscall_interrupt_string_after, 55 +syscall_interrupt_string_after: + .string "System call %u exited without interrupts enabled after"