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