/* * Execute a 32-bit system call on behalf of the current thread. */ void dosyscall(void) { /* * Need space on the stack to store syscall arguments. */ long syscall_args[MAXSYSARGS]; struct sysent *se; int64_t ret; syscall_mstate(LMS_TRAP, LMS_SYSTEM); ASSERT(curproc->p_model == DATAMODEL_ILP32); CPU_STATS_ENTER_K(); CPU_STATS_ADDQ(CPU, sys, syscall, 1); CPU_STATS_EXIT_K(); se = syscall_entry(curthread, syscall_args); /* * syscall_entry() copied all 8 arguments into syscall_args. */ ret = se->sy_callc(syscall_args[0], syscall_args[1], syscall_args[2], syscall_args[3], syscall_args[4], syscall_args[5], syscall_args[6], syscall_args[7]); syscall_exit(curthread, (int)ret & 0xffffffffu, (int)(ret >> 32)); syscall_mstate(LMS_SYSTEM, LMS_TRAP); }
/** * Handle system calls. Interrupts are enabled when this function is * called. * * @param user_context The userland context (CPU registers as they * where when system call instruction was called in userland) */ void syscall_handle(regs_t *registers) { /* When a syscall is executed in userland, register rdi contains * the number of the syscall. Registers rsi, rdx and rcx contain the * arguments of the syscall. The userland code expects that after * returning from the syscall instruction the return value of the * syscall is found in register rax. Before entering this function * the userland context has been saved to user_context and after * returning from this function the userland context will be * restored from user_context. */ registers->rax = syscall_entry(registers->rdi, registers->rsi, registers->rdx, registers->rcx); }