Ejemplo n.º 1
0
/* callback, runs in vcore context.  this sets up our initial context.  once we
 * become runnable again, we'll run the first bits of the vm ctx.  after that,
 * our context will be stopped and started and will just run whatever the guest
 * VM wants.  we'll never come back to this code or to run_vm(). */
static void __build_vm_ctx_cb(struct uthread *uth, void *arg)
{
	struct pthread_tcb *pthread = (struct pthread_tcb*)uth;
	struct vmctl *vmctl = (struct vmctl*)arg;
	struct vm_trapframe *vm_tf;

	__pthread_generic_yield(pthread);
	pthread->state = PTH_BLK_YIELDING;

	memset(&uth->u_ctx, 0, sizeof(struct user_context));
	uth->u_ctx.type = ROS_VM_CTX;
	vm_tf = &uth->u_ctx.tf.vm_tf;

	vm_tf->tf_guest_pcoreid = 0;	/* assuming only 1 guest core */

	copy_vmctl_to_vmtf(vmctl, vm_tf);

	/* other HW/GP regs are 0, which should be fine.  the FP state is still
	 * whatever we were running before, though this is pretty much unnecessary.
	 * we mostly don't want crazy crap in the uth->as, and a non-current_uthread
	 * VM ctx is supposed to have something in their FP state (like HW ctxs). */
	save_fp_state(&uth->as);
	uth->flags |= UTHREAD_FPSAVED | UTHREAD_SAVED;

	uthread_runnable(uth);
}
Ejemplo n.º 2
0
/* Prep a pthread to run a signal handler.  The original context of the pthread
 * is saved, and a new context with a new stack is set up to run the signal
 * handler the next time the pthread is run. */
static void __pthread_prep_sighandler(struct pthread_tcb *pthread,
                                      void (*entry)(void),
                                      struct siginfo *info)
{
	struct user_context *ctx;

	pthread->sigdata = alloc_sigdata();
	if (info != NULL)
		pthread->sigdata->info = *info;
	init_user_ctx(&pthread->sigdata->u_ctx,
	              (uintptr_t)entry,
	              (uintptr_t)pthread->sigdata->stack);
	if (pthread->uthread.flags & UTHREAD_SAVED) {
		ctx = &pthread->uthread.u_ctx;
		if (pthread->uthread.flags & UTHREAD_FPSAVED) {
			pthread->sigdata->as = pthread->uthread.as;
			pthread->uthread.flags &= ~UTHREAD_FPSAVED;
		}
	} else {
		assert(current_uthread == &pthread->uthread);
		ctx = &vcpd_of(vcore_id())->uthread_ctx;
		save_fp_state(&pthread->sigdata->as);
	}
	swap_user_contexts(ctx, &pthread->sigdata->u_ctx);
}
Ejemplo n.º 3
0
static long setup_sigcontext(struct rt_sigframe __user *frame,
	struct pt_regs *regs)
{
	struct sigcontext __user *sc = &frame->uc.uc_mcontext;
	long err;
	/* sc_regs is structured the same as the start of pt_regs */
	err = __copy_to_user(&sc->sc_regs, regs, sizeof(sc->sc_regs));
	/* Save the floating-point state. */
	if (has_fpu)
		err |= save_fp_state(regs, &sc->sc_fpregs);
	return err;
}