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

Function cpu_fork

freebsd/amd64/amd64/vm_machdep.c:144–270  ·  view source on GitHub ↗

* Finish a fork operation, with process p2 nearly set up. * Copy and update the pcb, set up the stack so that the child * ready to run and return to user mode. */

Source from the content-addressed store, hash-verified

142 * ready to run and return to user mode.
143 */
144void
145cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
146{
147 struct proc *p1;
148 struct pcb *pcb2;
149 struct mdproc *mdp1, *mdp2;
150 struct proc_ldt *pldt;
151
152 p1 = td1->td_proc;
153 if ((flags & RFPROC) == 0) {
154 if ((flags & RFMEM) == 0) {
155 /* unshare user LDT */
156 mdp1 = &p1->p_md;
157 mtx_lock(&dt_lock);
158 if ((pldt = mdp1->md_ldt) != NULL &&
159 pldt->ldt_refcnt > 1 &&
160 user_ldt_alloc(p1, 1) == NULL)
161 panic("could not copy LDT");
162 mtx_unlock(&dt_lock);
163 }
164 return;
165 }
166
167 /* Ensure that td1's pcb is up to date. */
168 fpuexit(td1);
169 update_pcb_bases(td1->td_pcb);
170
171 /* Point the stack and pcb to the actual location */
172 set_top_of_stack_td(td2);
173 td2->td_pcb = pcb2 = get_pcb_td(td2);
174
175 /* Copy td1's pcb */
176 bcopy(td1->td_pcb, pcb2, sizeof(*pcb2));
177
178 /* Properly initialize pcb_save */
179 pcb2->pcb_save = get_pcb_user_save_pcb(pcb2);
180 bcopy(get_pcb_user_save_td(td1), get_pcb_user_save_pcb(pcb2),
181 cpu_max_ext_state_size);
182
183 /* Point mdproc and then copy over td1's contents */
184 mdp2 = &p2->p_md;
185 bcopy(&p1->p_md, mdp2, sizeof(*mdp2));
186
187 /*
188 * Create a new fresh stack for the new process.
189 * Copy the trap frame for the return to user mode as if from a
190 * syscall. This copies most of the user mode register values.
191 */
192 td2->td_frame = (struct trapframe *)td2->td_md.md_stack_base - 1;
193 bcopy(td1->td_frame, td2->td_frame, sizeof(struct trapframe));
194
195 td2->td_frame->tf_rax = 0; /* Child returns zero */
196 td2->td_frame->tf_rflags &= ~PSL_C; /* success */
197 td2->td_frame->tf_rdx = 1;
198
199 /*
200 * If the parent process has the trap bit set (i.e. a debugger
201 * had single stepped the process to the system call), we need

Callers

nothing calls this directly

Calls 11

fpuexitFunction · 0.85
set_top_of_stack_tdFunction · 0.85
set_pcb_flags_rawFunction · 0.85
amd64_set_ldt_dataFunction · 0.85
user_ldt_allocFunction · 0.70
get_pcb_tdFunction · 0.70
get_pcb_user_save_pcbFunction · 0.70
get_pcb_user_save_tdFunction · 0.70
mtx_lockFunction · 0.50
panicFunction · 0.50
mtx_unlockFunction · 0.50

Tested by

no test coverage detected