X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/47388162eff1ff692a152b98b5b12d547067a026..7adb15b6dcf5e168299d7b37219522427f73b0c9:/sys/platform/vkernel/i386/cpu_regs.c diff --git a/sys/platform/vkernel/i386/cpu_regs.c b/sys/platform/vkernel/i386/cpu_regs.c index 548abea28d..d5d52a408a 100644 --- a/sys/platform/vkernel/i386/cpu_regs.c +++ b/sys/platform/vkernel/i386/cpu_regs.c @@ -64,7 +64,6 @@ #include #include #include -#include #include #include @@ -502,158 +501,6 @@ sys_sigreturn(struct sigreturn_args *uap) return(EJUSTRETURN); } -/* - * Stack frame on entry to function. %eax will contain the function vector, - * %ecx will contain the function data. flags, ecx, and eax will have - * already been pushed on the stack. - */ -struct upc_frame { - register_t eax; - register_t ecx; - register_t edx; - register_t flags; - register_t oldip; -}; - -void -sendupcall(struct vmupcall *vu, int morepending) -{ - struct lwp *lp = curthread->td_lwp; - struct trapframe *regs; - struct upcall upcall; - struct upc_frame upc_frame; - int crit_count = 0; - - /* - * If we are a virtual kernel running an emulated user process - * context, switch back to the virtual kernel context before - * trying to post the signal. - */ - if (lp->lwp_vkernel && lp->lwp_vkernel->ve) { - lp->lwp_md.md_regs->tf_trapno = 0; - vkernel_trap(lp, lp->lwp_md.md_regs); - } - - /* - * Get the upcall data structure - */ - if (copyin(lp->lwp_upcall, &upcall, sizeof(upcall)) || - copyin((char *)upcall.upc_uthread + upcall.upc_critoff, &crit_count, sizeof(int)) - ) { - vu->vu_pending = 0; - kprintf("bad upcall address\n"); - return; - } - - /* - * If the data structure is already marked pending or has a critical - * section count, mark the data structure as pending and return - * without doing an upcall. vu_pending is left set. - */ - if (upcall.upc_pending || crit_count >= vu->vu_pending) { - if (upcall.upc_pending < vu->vu_pending) { - upcall.upc_pending = vu->vu_pending; - copyout(&upcall.upc_pending, &lp->lwp_upcall->upc_pending, - sizeof(upcall.upc_pending)); - } - return; - } - - /* - * We can run this upcall now, clear vu_pending. - * - * Bump our critical section count and set or clear the - * user pending flag depending on whether more upcalls are - * pending. The user will be responsible for calling - * upc_dispatch(-1) to process remaining upcalls. - */ - vu->vu_pending = 0; - upcall.upc_pending = morepending; - ++crit_count; - copyout(&upcall.upc_pending, &lp->lwp_upcall->upc_pending, - sizeof(upcall.upc_pending)); - copyout(&crit_count, (char *)upcall.upc_uthread + upcall.upc_critoff, - sizeof(int)); - - /* - * Construct a stack frame and issue the upcall - */ - regs = lp->lwp_md.md_regs; - upc_frame.eax = regs->tf_eax; - upc_frame.ecx = regs->tf_ecx; - upc_frame.edx = regs->tf_edx; - upc_frame.flags = regs->tf_eflags; - upc_frame.oldip = regs->tf_eip; - if (copyout(&upc_frame, (void *)(regs->tf_esp - sizeof(upc_frame)), - sizeof(upc_frame)) != 0) { - kprintf("bad stack on upcall\n"); - } else { - regs->tf_eax = (register_t)vu->vu_func; - regs->tf_ecx = (register_t)vu->vu_data; - regs->tf_edx = (register_t)lp->lwp_upcall; - regs->tf_eip = (register_t)vu->vu_ctx; - regs->tf_esp -= sizeof(upc_frame); - } -} - -/* - * fetchupcall occurs in the context of a system call, which means that - * we have to return EJUSTRETURN in order to prevent eax and edx from - * being overwritten by the syscall return value. - * - * if vu is not NULL we return the new context in %edx, the new data in %ecx, - * and the function pointer in %eax. - */ -int -fetchupcall (struct vmupcall *vu, int morepending, void *rsp) -{ - struct upc_frame upc_frame; - struct lwp *lp = curthread->td_lwp; - struct trapframe *regs; - int error; - struct upcall upcall; - int crit_count; - - regs = lp->lwp_md.md_regs; - - error = copyout(&morepending, &lp->lwp_upcall->upc_pending, sizeof(int)); - if (error == 0) { - if (vu) { - /* - * This jumps us to the next ready context. - */ - vu->vu_pending = 0; - error = copyin(lp->lwp_upcall, &upcall, sizeof(upcall)); - crit_count = 0; - if (error == 0) - error = copyin((char *)upcall.upc_uthread + upcall.upc_critoff, &crit_count, sizeof(int)); - ++crit_count; - if (error == 0) - error = copyout(&crit_count, (char *)upcall.upc_uthread + upcall.upc_critoff, sizeof(int)); - regs->tf_eax = (register_t)vu->vu_func; - regs->tf_ecx = (register_t)vu->vu_data; - regs->tf_edx = (register_t)lp->lwp_upcall; - regs->tf_eip = (register_t)vu->vu_ctx; - regs->tf_esp = (register_t)rsp; - } else { - /* - * This returns us to the originally interrupted code. - */ - error = copyin(rsp, &upc_frame, sizeof(upc_frame)); - regs->tf_eax = upc_frame.eax; - regs->tf_ecx = upc_frame.ecx; - regs->tf_edx = upc_frame.edx; - regs->tf_eflags = (regs->tf_eflags & ~PSL_USERCHANGE) | - (upc_frame.flags & PSL_USERCHANGE); - regs->tf_eip = upc_frame.oldip; - regs->tf_esp = (register_t)((char *)rsp + sizeof(upc_frame)); - } - } - if (error == 0) - error = EJUSTRETURN; - return(error); -} - /* * cpu_idle() represents the idle LWKT. You cannot return from this function * (unless you want to blow things up!). Instead we look for runnable threads