xref: /freebsd/share/man/man9/cpu_machdep.9 (revision b670c9bafc0e31c7609969bf374b2e80bdc00211)
1.\"-
2.\" SPDX-License-Identifier: BSD-2-Clause
3.\"
4.\" Copyright (c) 2024 (holder)
5.\"
6.\" This software was developed by SRI International, the University of
7.\" Cambridge Computer Laboratory (Department of Computer Science and
8.\" Technology), and Capabilities Limited under Defense Advanced Research
9.\" Projects Agency (DARPA) Contract No. FA8750-24-C-B047 ("DEC").
10.\"
11.Dd January 31, 2025
12.Dt cpu_machdep 9
13.Os
14.Sh NAME
15.Nm cpu_machdep ,
16.Nm cpu_copy_thread ,
17.Nm cpu_exec_vmspace_reuse ,
18.Nm cpu_exit ,
19.Nm cpu_fetch_syscall_args ,
20.Nm cpu_fork ,
21.Nm cpu_fork_kthread_handler ,
22.Nm cpu_idle ,
23.Nm cpu_idle_wakeup ,
24.Nm cpu_procctl ,
25.Nm cpu_set_syscall_retval ,
26.Nm cpu_set_upcall ,
27.Nm cpu_set_user_tls ,
28.Nm cpu_switch ,
29.Nm cpu_sync_core ,
30.Nm cpu_thread_alloc ,
31.Nm cpu_thread_clean ,
32.Nm cpu_thread_exit ,
33.Nm cpu_thread_free ,
34.Nm cpu_throw ,
35.Nm cpu_update_pcb
36.Nd machine-dependent interfaces to handle CPU and thread state
37.Sh SYNOPSIS
38.In sys/proc.h
39.In sys/ptrace.h
40.Ft void
41.Fn cpu_copy_thread "struct thread *td" "struct thread *td0"
42.Ft bool
43.Fn cpu_exec_vmspace_reuse "struct proc *p" "struct vm_map *map"
44.Ft void
45.Fn cpu_exit "struct thread *td"
46.Ft int
47.Fn cpu_fetch_syscall_args "struct thread *td"
48.Ft void
49.Fo cpu_fork
50.Fa "struct thread *td1" "struct proc *p2" "struct thread *td2" "int flags"
51.Fc
52.Ft void
53.Fo cpu_fork_kthread_handler
54.Fa "struct thread *td" "void (*func)(void *)" "void *arg"
55.Fc
56.Ft void
57.Fn cpu_idle "int busy"
58.Ft int
59.Fn cpu_idle_wakeup "int cpu"
60.Ft int
61.Fo cpu_procctl
62.Fa "struct thread *td" "int idtype" "id_t id" "int com" "void *data"
63.Fc
64.Ft int
65.Fn cpu_ptrace "struct thread *_td" "int req" "void *addr" "int data"
66.Ft void
67.Fn cpu_set_syscall_retval "struct thread *td" "int error"
68.Ft int
69.Fo cpu_set_upcall
70.Fa "struct thread *td" "void (*entry)(void *)" "void *arg" "stack_t *stack"
71.Fc
72.Ft int
73.Fn cpu_set_user_tls "struct thread *td" "void *tls_base" "int thr_flags"
74.Ft void
75.Fn cpu_switch "struct thread *old" "struct thread *new" "struct mtx *mtx"
76.Ft void
77.Fn cpu_sync_core "void"
78.Ft void
79.Fn cpu_thread_alloc "struct thread *td"
80.Ft void
81.Fn cpu_thread_clean "struct thread *td"
82.Ft void
83.Fn cpu_thread_exit "struct thread *td"
84.Ft void
85.Fn cpu_thread_free "struct thread *td"
86.Ft void
87.Fn cpu_throw "struct thread *old" "struct thread *new"
88.Ft void
89.Fn cpu_update_pcb "struct thread *td"
90.Sh DESCRIPTION
91These functions provide architecture-specific implementations of
92machine-independent abstractions.
93.Pp
94.Fn cpu_exec_vmspace_reuse
95returns true if
96.Fn exec_new_vmspace
97can reuse an existing
98.Vt struct vmspace
99.Pq Fa map
100for the process
101.Fa p
102during
103.Xr execve 2 .
104This is only invoked if
105.Fa map
106is not shared with any other consumers.
107If this returns false,
108.Fn exec_new_vmspace
109will create a new
110.Vt struct vmspace .
111.Pp
112.Fn cpu_exit
113releases machine-dependent resources other than the address space for the
114process containing
115.Fa td
116during process exit.
117.Pp
118.Fn cpu_fork
119copies and updates machine-dependent state
120(for example, the pcb and user registers) from the forking thread
121.Fa td1
122in an existing process to the new thread
123.Fa td2
124in the new process
125.Fa p2 .
126This function must set up the new thread's kernel stack and pcb so that
127.Fa td2
128calls
129.Fn fork_exit
130when it begins execution passing a pointer to
131.Fn fork_return
132as the
133.Fa callout
134argument and
135.Fa td2
136as the
137.Fa arg
138argument.
139.Pp
140.Fn cpu_fork_kthread_handler
141adjusts a new thread's initial pcb and/or kernel stack to pass
142.Fa func
143and
144.Fa arg
145as the
146.Fa callout
147and
148.Fa arg
149arguments to
150.Fn fork_exit .
151This must be called before a new thread is scheduled to run and is
152used to set the
153.Dq main
154function for kernel threads.
155.Pp
156.Fn cpu_copy_thread
157copies machine-dependent state (for example, the pcb and user registers) from
158.Fa td
159to
160.Fa td0
161when creating a new thread in the same process.
162This function must set up the new thread's kernel stack and pcb so that
163.Fa td0
164calls
165.Fn fork_exit
166when it begins execution passing a pointer to
167.Fn fork_return
168as the
169.Fa callout
170argument and
171.Fa td0
172as the
173.Fa arg
174argument.
175.Pp
176.Fn cpu_set_upcall
177updates a new thread's initial user register state to call
178.Fa entry
179with
180.Fa arg
181as the sole argument using the user stack described in
182.Fa stack .
183.Pp
184.Fn cpu_set_user_tls
185sets a new thread's initial user thread pointer register to
186reference the user TLS base pointer
187.Fa tls_base .
188The
189.Fa thr_flags
190argument provides flags bits, from the same namespace as
191.Va flags
192member of the
193.Vt struct thr_param
194argument to the
195.Xr thr_new 2
196syscall.
197.Pp
198.Fn cpu_update_pcb
199updates the pcb of the current thread with current user register values.
200This is invoked before writing out register notes in a core dump.
201This function typically only has to update user registers for the current
202thread that are saved in the pcb during context switches rather than
203in the trapframe on kernel entry.
204.Pp
205Note that when
206.Fn cpu_update_pcb
207is used,
208threads in a process other than the current thread are stopped,
209typically by
210.Fn thread_single .
211The pcbs of those stopped threads should already be updated by
212.Fn cpu_switch .
213.Pp
214.Fn cpu_fetch_syscall_args
215fetches the current system call arguments for the native FreeBSD ABI from the
216current thread's user register state and/or user stack.
217The arguments are saved in the
218.Fa td_sa
219member of
220.Fa td .
221.Pp
222.Fn cpu_set_syscall_retval
223updates the user register state for
224.Fa td
225to store system call error and return values.
226If
227.Fa error
228is 0,
229indicate success and return the two values in
230.Fa td_retval .
231If
232.Fa error
233is
234.Dv ERESTART,
235adjust the user PC to re-invoke the current system call after returning
236to user mode.
237If
238.Fa error
239is
240.Dv EJUSTRETURN ,
241leave the current user register state unchanged.
242For any other value of
243.Fa error ,
244indicate error and return
245.Fa error
246as the error code.
247.Pp
248.Fn cpu_idle
249waits for the next interrupt to occur on the current CPU.
250If an architecture supports low power idling,
251this function should place the CPU into a low power state while waiting.
252.Fa busy
253is a hint from the scheduler.
254If
255.Fa busy
256is non-zero,
257the scheduler expects a short sleep,
258so the CPU should prefer low-latency over maximum power savings.
259If
260.Fa busy
261is zero,
262the CPU should maximumize power savings including deferring unnecessary
263clock interrupts via
264.Fn cpu_idleclock .
265.Pp
266.Fn cpu_idle_wakeup
267awakens the idle CPU with the ID
268.Fa cpu
269from a low-power state.
270.Pp
271.Fn cpu_procctl
272handles any machine-dependent
273.Xr procctl 2
274requests.
275.Pp
276.Fn cpu_ptrace
277handles any machine-dependent
278.Xr ptrace 2
279requests.
280.Pp
281.Fn cpu_switch
282switches the current CPU between threads by swapping register state.
283This function saves the current CPU register state in the pcb of
284.Fa old
285and loads register values from the pcb of
286.Fa new
287before returning.
288While the pcb generally contains caller-save kernel register state,
289it can also contain user registers that are not saved in the trapframe.
290.Pp
291After saving the current CPU register state of
292.Fa old ,
293.Fn cpu_switch
294stores
295.Fa mtx
296in the
297.Fa td_lock
298member of
299.Fa old
300transferring ownership of the old thread.
301No data belonging to
302.Fa old
303can be accessed after that store.
304Specifically, the old thread's kernel stack must not be accessed after
305this point.
306.Pp
307When
308.Dv SCHED_ULE
309is being used,
310this function must wait (via spinning) for the
311.Fa td_lock
312member of
313.Fa new
314to change to a value not equal to
315.Va &blocked_lock
316before loading register values from
317.Fa new
318or accessing its kernel stack.
319.Pp
320From the caller's perspective,
321.Fn cpu_switch
322returns when
323.Fa old
324is rescheduled in the future,
325possibly on a different CPU.
326However, the implementation of
327.Fn cpu_switch
328returns immediately on the same CPU into the previously-saved context of
329.Fa new .
330.Pp
331.Fn cpu_throw
332is similar to
333.Fn cpu_switch
334but does not save any state for
335.Fa old
336or write to the old thread's
337.Fa td_lock
338member.
339.Pp
340.Fn cpu_sync_core
341ensures that all possible speculation and out-of-order execution is
342serialized on the current CPU.
343Note that this is called from an IPI handler so only has to handle
344additional serialization beyond that provided by handling an IPI.
345.Ss Thread Object Lifecycle
346These functions support the management of machine-dependent thread
347state in conjunction with a thread object's lifecycle.
348.Pp
349The general model is that a thread object is allocated each time a
350new kernel thread is created either by system calls like
351.Xr fork 2
352or
353.Xr thr_new 2
354or when kernel-only threads are created via
355.Xr kproc_create 9 ,
356.Xr kproc_kthread_add 9 ,
357or
358.Xr kthread_add 9 .
359When a kernel thread exits,
360the thread object is freed.
361However, there is one special case to support an optimization where each
362free process object caches a thread object.
363When a process exits, the last thread object is not freed but remains
364attached to the process.
365When the process object is later reused for a new process in
366.Xr fork 2 ,
367the kernel recycles that last thread object and uses it as the initial
368thread in the new process.
369When a thread is recycled, some of the steps in the thread allocation
370and free cycle are skipped as an optimization.
371.Pp
372.Fn cpu_thread_alloc
373initializes machine-dependent fields in
374.Fa td
375after allocating a new kernel stack.
376This function typically sets the
377.Fa td_pcb
378and initial
379.Fa td_frame
380pointers.
381.Fn cpu_thread_alloc
382is called both when allocating a new thread object and
383when a recycled thread allocates a new kernel stack.
384Note that this function is
385.Em not
386called if a recycled thread reuses its existing kernel stack.
387.Pp
388.Fn cpu_thread_clean
389releases any machine-dependent resources for the last thread in a
390process during
391.Xr wait 2 .
392The thread is a candidate for recycling so should be reset to run as a
393new thread in case it is recycled by a future
394.Xr fork 2 .
395.Pp
396.Fn cpu_thread_exit
397cleans any machine-dependent state in
398.Fa td
399while it is exiting.
400This is called by the exiting thread so cannot free state needed during
401in-kernel execution.
402.Pp
403.Fn cpu_thread_free
404releases any machine-dependent state in
405.Fa td
406when it is being freed.
407This is called for any thread that was not the last thread in a process
408once it has finished execution.
409.Sh SEE ALSO
410.Xr fork 2 ,
411.Xr procctl 2 ,
412.Xr ptrace 2 ,
413.Xr thr_new 2 ,
414.Xr wait 2 ,
415.Xr kproc_create 9 ,
416.Xr kproc_kthread_add 9 ,
417.Xr kthread_add 9 ,
418.Xr mi_switch 9
419.Sh AUTHORS
420This manual page was
421developed by SRI International, the University of Cambridge Computer
422Laboratory (Department of Computer Science and Technology), and
423Capabilities Limited under contract
424.Pq FA8750-24-C-B047
425.Pq Do DEC Dc .
426