Exemplo n.º 1
0
/*
 * page fault handler
 * - it deals with 4 scenarios:
 *   - expand user space stack
 *   - swap process in
 *   - do copy-on-write
 *   - handle segment fault
 */
void trap_memory_handler(struct user_context *user_ctx)
{
	unsigned long addr = (unsigned long)user_ctx->addr;
	unsigned int page_index = PAGE_UINDEX(addr);
	struct my_pte *ptep = current->page_table + page_index;
	int ret;

	_enter("pid = %u, at %p(%u), code = %d",
			current->pid, addr, page_index, user_ctx->code);

	switch (user_ctx->code) {
	case YALNIX_MAPERR:
		/* expand stack */
		if (!ptep->swap && page_index == current->stack_start - 1) {
			task_vm_expand_stack(current, 1);
			break;
		}

		/* swap process in */
		if (ptep->swap) {
			ret = swap_in(current);
			if (ret == EIO) {
				sys_tty_write(0, "Abort! Swap In error!\n",
						64, user_ctx);
				sys_exit(ret, user_ctx);
			}
		}

		break;
	case YALNIX_ACCERR:
		break;
	default:
#ifdef COW
		/* do copy-on-write for the parent and children */
		if (ptep->cow && ptep->prot == PROT_READ) {
			task_cow_copy_page(current, page_index);
			break;
		}
#endif
		/* if tried to write text segment just abort it */
		if (ptep->prot == (PROT_READ | PROT_EXEC)) {
			sys_tty_write(0, "Abort! Segment Fault!\n",
					64, user_ctx);
			sys_exit(ERROR, user_ctx);
		}

		break;
	}

	_leave();
	return;
}
Exemplo n.º 2
0
void console_putc(char ch)
{
	sysPrxForUser.trace("console_putc(ch=0x%x)", ch);
	sys_tty_write(0, vm::var<char>(ch), 1, vm::var<u32>{});
}
Exemplo n.º 3
0
void trap_kernel_handler(struct user_context *user_ctx)
{
	_debug("...... in %s, code = %p\n",
			__func__, user_ctx->code & ~YALNIX_PREFIX);

	switch (user_ctx->code) {
	case YALNIX_FORK:
		SET_RET(user_ctx, sys_fork(user_ctx));
		break;
	case YALNIX_EXEC:
		sys_exec((char *)user_ctx->regs[0], (char **)user_ctx->regs[1],
				user_ctx);
		break;
	case YALNIX_EXIT:
		sys_exit(user_ctx->regs[0], user_ctx);
		break;
	case YALNIX_WAIT:
		if (!FROM_USER_SPACE(user_ctx->regs[0])) {
			_error("Bad man! Please pass user space pointer!\n");
			sys_exit(ERROR, user_ctx);
		}
		SET_RET(user_ctx, sys_wait((int *)user_ctx->regs[0], user_ctx));
		break;
	case YALNIX_GETPID:
		SET_RET(user_ctx, sys_getpid());
		break;
	case YALNIX_BRK:
		SET_RET(user_ctx, sys_brk(user_ctx->regs[0]));
		break;
	case YALNIX_DELAY:
		SET_RET(user_ctx, sys_delay(user_ctx->regs[0], user_ctx));
		break;
	case YALNIX_TTY_READ:
		if (!FROM_USER_SPACE(user_ctx->regs[1])) {
			_error("Bad man! Please pass user space pointer!\n");
			sys_exit(ERROR, user_ctx);
		}
		SET_RET(user_ctx, sys_tty_read(user_ctx->regs[0],
				(char *)user_ctx->regs[1],
				user_ctx->regs[2],
				user_ctx));
		break;
	case YALNIX_TTY_WRITE:
		if (!FROM_USER_SPACE(user_ctx->regs[1])) {
			_error("Bad man! Please pass user space pointer!\n");
			sys_exit(ERROR, user_ctx);
		}
		SET_RET(user_ctx, sys_tty_write(user_ctx->regs[0],
				(char *)user_ctx->regs[1],
				user_ctx->regs[2],
				user_ctx));
		break;
	case YALNIX_PIPE_INIT:
		if (!FROM_USER_SPACE(user_ctx->regs[0])) {
			_error("Bad man! Please pass user space pointer!\n");
			sys_exit(ERROR, user_ctx);
		}
		SET_RET(user_ctx, sys_pipe_init((unsigned int *)
					user_ctx->regs[0]));
		break;
	case YALNIX_PIPE_READ:
		if (!FROM_USER_SPACE(user_ctx->regs[1])) {
			_error("Bad man! Please pass user space pointer!\n");
			sys_exit(ERROR, user_ctx);
		}
		SET_RET(user_ctx, sys_pipe_read(user_ctx->regs[0],
					(char *)user_ctx->regs[1],
					user_ctx->regs[2],
					user_ctx));
		break;
	case YALNIX_PIPE_WRITE:
		if (!FROM_USER_SPACE(user_ctx->regs[1])) {
			_error("Bad man! Please pass user space pointer!\n");
			sys_exit(ERROR, user_ctx);
		}
		SET_RET(user_ctx, sys_pipe_write(user_ctx->regs[0],
					(char *)user_ctx->regs[1],
					user_ctx->regs[2],
					user_ctx));
		break;
	case YALNIX_LOCK_INIT:
		if (!FROM_USER_SPACE(user_ctx->regs[0])) {
			_error("Bad man! Please pass user space pointer!\n");
			sys_exit(ERROR, user_ctx);
		}
		SET_RET(user_ctx, sys_lock_init((unsigned int *)
					user_ctx->regs[0]));
		break;
	case YALNIX_LOCK_ACQUIRE:
		SET_RET(user_ctx, sys_lock_acquire(user_ctx->regs[0],
						user_ctx));
		break;
	case YALNIX_LOCK_RELEASE:
		SET_RET(user_ctx, sys_lock_release(user_ctx->regs[0]));
		break;
	case YALNIX_CVAR_INIT:
		if (!FROM_USER_SPACE(user_ctx->regs[0])) {
			_error("Bad man! Please pass user space pointer!\n");
			sys_exit(ERROR, user_ctx);
		}
		SET_RET(user_ctx, sys_cvar_init((unsigned int *)
					user_ctx->regs[0]));
		break;
	case YALNIX_CVAR_WAIT:
		SET_RET(user_ctx, sys_cvar_wait(user_ctx->regs[0],
					user_ctx->regs[1],
					user_ctx));
		break;
	case YALNIX_CVAR_SIGNAL:
		SET_RET(user_ctx, sys_cvar_signal(user_ctx->regs[0]));
		break;
	case YALNIX_CVAR_BROADCAST:
		SET_RET(user_ctx, sys_cvar_broadcast(user_ctx->regs[0]));
		break;
	case YALNIX_RECLAIM:
		SET_RET(user_ctx, sys_reclaim(user_ctx->regs[0]));
		break;
	case YALNIX_CUSTOM_0:
		SET_RET(user_ctx, sys_fork_share(user_ctx));
		break;
	}

	return;
}
Exemplo n.º 4
0
error_code console_write(vm::ptr<char> data, u32 len)
{
	sysPrxForUser.trace("console_write(data=*0x%x, len=%d)", data, len);
	sys_tty_write(0, data, len, vm::var<u32>{});
	return CELL_OK;
}