X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/47388162eff1ff692a152b98b5b12d547067a026..7adb15b6dcf5e168299d7b37219522427f73b0c9:/sys/platform/vkernel64/x86_64/cpu_regs.c diff --git a/sys/platform/vkernel64/x86_64/cpu_regs.c b/sys/platform/vkernel64/x86_64/cpu_regs.c index 566582c881..aad8884716 100644 --- a/sys/platform/vkernel64/x86_64/cpu_regs.c +++ b/sys/platform/vkernel64/x86_64/cpu_regs.c @@ -63,7 +63,6 @@ #include #include #include -#include #include #include @@ -507,158 +506,6 @@ sys_sigreturn(struct sigreturn_args *uap) return(EJUSTRETURN); } -/* - * Stack frame on entry to function. %rax will contain the function vector, - * %rcx will contain the function data. flags, rcx, and rax will have - * already been pushed on the stack. - */ -struct upc_frame { - register_t rax; - register_t rcx; - register_t rdx; - 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.rax = regs->tf_rax; - upc_frame.rcx = regs->tf_rcx; - upc_frame.rdx = regs->tf_rdx; - upc_frame.flags = regs->tf_rflags; - upc_frame.oldip = regs->tf_rip; - if (copyout(&upc_frame, (void *)(regs->tf_rsp - sizeof(upc_frame)), - sizeof(upc_frame)) != 0) { - kprintf("bad stack on upcall\n"); - } else { - regs->tf_rax = (register_t)vu->vu_func; - regs->tf_rcx = (register_t)vu->vu_data; - regs->tf_rdx = (register_t)lp->lwp_upcall; - regs->tf_rip = (register_t)vu->vu_ctx; - regs->tf_rsp -= 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_rax = (register_t)vu->vu_func; - regs->tf_rcx = (register_t)vu->vu_data; - regs->tf_rdx = (register_t)lp->lwp_upcall; - regs->tf_rip = (register_t)vu->vu_ctx; - regs->tf_rsp = (register_t)rsp; - } else { - /* - * This returns us to the originally interrupted code. - */ - error = copyin(rsp, &upc_frame, sizeof(upc_frame)); - regs->tf_rax = upc_frame.rax; - regs->tf_rcx = upc_frame.rcx; - regs->tf_rdx = upc_frame.rdx; - regs->tf_rflags = (regs->tf_rflags & ~PSL_USERCHANGE) | - (upc_frame.flags & PSL_USERCHANGE); - regs->tf_rip = upc_frame.oldip; - regs->tf_rsp = (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