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

Function cpu_copy_thread

freebsd/i386/i386/vm_machdep.c:423–482  ·  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

421 * return to userspace for the new thread.
422 */
423void
424cpu_copy_thread(struct thread *td, struct thread *td0)
425{
426 struct pcb *pcb2;
427
428 /* Point the pcb to the top of the stack. */
429 pcb2 = td->td_pcb;
430
431 /*
432 * Copy the upcall pcb. This loads kernel regs.
433 * Those not loaded individually below get their default
434 * values here.
435 */
436 bcopy(td0->td_pcb, pcb2, sizeof(*pcb2));
437 pcb2->pcb_flags &= ~(PCB_NPXINITDONE | PCB_NPXUSERINITDONE |
438 PCB_KERNNPX);
439 pcb2->pcb_save = get_pcb_user_save_pcb(pcb2);
440 bcopy(get_pcb_user_save_td(td0), pcb2->pcb_save,
441 cpu_max_ext_state_size);
442
443 /*
444 * Create a new fresh stack for the new thread.
445 */
446 bcopy(td0->td_frame, td->td_frame, sizeof(struct trapframe));
447
448 /* If the current thread has the trap bit set (i.e. a debugger had
449 * single stepped the process to the system call), we need to clear
450 * the trap flag from the new frame. Otherwise, the new thread will
451 * receive a (likely unexpected) SIGTRAP when it executes the first
452 * instruction after returning to userland.
453 */
454 td->td_frame->tf_eflags &= ~PSL_T;
455
456 /*
457 * Set registers for trampoline to user mode. Leave space for the
458 * return address on stack. These are the kernel mode register values.
459 */
460 pcb2->pcb_edi = 0;
461 pcb2->pcb_esi = (int)fork_return; /* trampoline arg */
462 pcb2->pcb_ebp = 0;
463 pcb2->pcb_esp = (int)td->td_frame - sizeof(void *); /* trampoline arg */
464 pcb2->pcb_ebx = (int)td; /* trampoline arg */
465 pcb2->pcb_eip = (int)fork_trampoline + setidt_disp;
466 pcb2->pcb_gs = rgs();
467 /*
468 * If we didn't copy the pcb, we'd need to do the following registers:
469 * pcb2->pcb_cr3: cloned above.
470 * pcb2->pcb_dr*: cloned above.
471 * pcb2->pcb_savefpu: cloned above.
472 * pcb2->pcb_flags: cloned above.
473 * pcb2->pcb_onfault: cloned above (always NULL here?).
474 * pcb2->pcb_gs: cloned above.
475 * pcb2->pcb_ext: cleared below.
476 */
477 pcb2->pcb_ext = NULL;
478
479 /* Setup to release spin count in fork_exit(). */
480 td->td_md.md_spinlock_count = 1;

Callers

nothing calls this directly

Calls 3

get_pcb_user_save_pcbFunction · 0.70
get_pcb_user_save_tdFunction · 0.70
rgsFunction · 0.50

Tested by

no test coverage detected