MCPcopy Create free account
hub / github.com/F-Stack/f-stack / cpu_copy_thread

Function cpu_copy_thread

freebsd/amd64/amd64/vm_machdep.c:559–614  ·  view source on GitHub ↗

* Initialize machine state, mostly pcb and trap frame for a new * thread, about to return to userspace. Put enough state in the new * thread's PCB to get it to go back to the fork_return(), which * finalizes the thread state and handles peculiarities of the first * return to userspace for the new thread. */

Source from the content-addressed store, hash-verified

557 * return to userspace for the new thread.
558 */
559void
560cpu_copy_thread(struct thread *td, struct thread *td0)
561{
562 struct pcb *pcb2;
563
564 pcb2 = td->td_pcb;
565
566 /*
567 * Copy the upcall pcb. This loads kernel regs.
568 * Those not loaded individually below get their default
569 * values here.
570 */
571 update_pcb_bases(td0->td_pcb);
572 bcopy(td0->td_pcb, pcb2, sizeof(*pcb2));
573 clear_pcb_flags(pcb2, PCB_FPUINITDONE | PCB_USERFPUINITDONE |
574 PCB_KERNFPU);
575 pcb2->pcb_save = get_pcb_user_save_pcb(pcb2);
576 bcopy(get_pcb_user_save_td(td0), pcb2->pcb_save,
577 cpu_max_ext_state_size);
578 set_pcb_flags_raw(pcb2, PCB_FULL_IRET);
579
580 /*
581 * Create a new fresh stack for the new thread.
582 */
583 bcopy(td0->td_frame, td->td_frame, sizeof(struct trapframe));
584
585 /* If the current thread has the trap bit set (i.e. a debugger had
586 * single stepped the process to the system call), we need to clear
587 * the trap flag from the new frame. Otherwise, the new thread will
588 * receive a (likely unexpected) SIGTRAP when it executes the first
589 * instruction after returning to userland.
590 */
591 td->td_frame->tf_rflags &= ~PSL_T;
592
593 /*
594 * Set registers for trampoline to user mode. Leave space for the
595 * return address on stack. These are the kernel mode register values.
596 */
597 pcb2->pcb_r12 = (register_t)fork_return; /* trampoline arg */
598 pcb2->pcb_rbp = 0;
599 pcb2->pcb_rsp = (register_t)td->td_frame - sizeof(void *); /* trampoline arg */
600 pcb2->pcb_rbx = (register_t)td; /* trampoline arg */
601 pcb2->pcb_rip = (register_t)fork_trampoline;
602 /*
603 * If we didn't copy the pcb, we'd need to do the following registers:
604 * pcb2->pcb_dr*: cloned above.
605 * pcb2->pcb_savefpu: cloned above.
606 * pcb2->pcb_onfault: cloned above (always NULL here?).
607 * pcb2->pcb_[fg]sbase: cloned above
608 */
609
610 /* Setup to release spin count in fork_exit(). */
611 td->td_md.md_spinlock_count = 1;
612 td->td_md.md_saved_flags = PSL_KERNEL | PSL_I;
613 pmap_thread_init_invl_gen(td);
614}
615
616/*

Callers

nothing calls this directly

Calls 4

clear_pcb_flagsFunction · 0.85
set_pcb_flags_rawFunction · 0.85
get_pcb_user_save_pcbFunction · 0.70
get_pcb_user_save_tdFunction · 0.70

Tested by

no test coverage detected