* 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. */
| 421 | * return to userspace for the new thread. |
| 422 | */ |
| 423 | void |
| 424 | cpu_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; |
nothing calls this directly
no test coverage detected