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