* Set that machine state for performing an upcall that starts * the entry function with the given argument. */
| 618 | * the entry function with the given argument. |
| 619 | */ |
| 620 | void |
| 621 | cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg, |
| 622 | stack_t *stack) |
| 623 | { |
| 624 | |
| 625 | /* |
| 626 | * Do any extra cleaning that needs to be done. |
| 627 | * The thread may have optional components |
| 628 | * that are not present in a fresh thread. |
| 629 | * This may be a recycled thread so make it look |
| 630 | * as though it's newly allocated. |
| 631 | */ |
| 632 | cpu_thread_clean(td); |
| 633 | |
| 634 | #ifdef COMPAT_FREEBSD32 |
| 635 | if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) { |
| 636 | /* |
| 637 | * Set the trap frame to point at the beginning of the entry |
| 638 | * function. |
| 639 | */ |
| 640 | td->td_frame->tf_rbp = 0; |
| 641 | td->td_frame->tf_rsp = |
| 642 | (((uintptr_t)stack->ss_sp + stack->ss_size - 4) & ~0x0f) - 4; |
| 643 | td->td_frame->tf_rip = (uintptr_t)entry; |
| 644 | |
| 645 | /* Return address sentinel value to stop stack unwinding. */ |
| 646 | suword32((void *)td->td_frame->tf_rsp, 0); |
| 647 | |
| 648 | /* Pass the argument to the entry point. */ |
| 649 | suword32((void *)(td->td_frame->tf_rsp + sizeof(int32_t)), |
| 650 | (uint32_t)(uintptr_t)arg); |
| 651 | |
| 652 | return; |
| 653 | } |
| 654 | #endif |
| 655 | |
| 656 | /* |
| 657 | * Set the trap frame to point at the beginning of the uts |
| 658 | * function. |
| 659 | */ |
| 660 | td->td_frame->tf_rbp = 0; |
| 661 | td->td_frame->tf_rsp = |
| 662 | ((register_t)stack->ss_sp + stack->ss_size) & ~0x0f; |
| 663 | td->td_frame->tf_rsp -= 8; |
| 664 | td->td_frame->tf_rip = (register_t)entry; |
| 665 | td->td_frame->tf_ds = _udatasel; |
| 666 | td->td_frame->tf_es = _udatasel; |
| 667 | td->td_frame->tf_fs = _ufssel; |
| 668 | td->td_frame->tf_gs = _ugssel; |
| 669 | td->td_frame->tf_flags = TF_HASSEGS; |
| 670 | |
| 671 | /* Return address sentinel value to stop stack unwinding. */ |
| 672 | suword((void *)td->td_frame->tf_rsp, 0); |
| 673 | |
| 674 | /* Pass the argument to the entry point. */ |
| 675 | td->td_frame->tf_rdi = (register_t)arg; |
| 676 | } |
| 677 |
no test coverage detected