Commit graph

8693 commits

Author SHA1 Message Date
implicitfield a08d1637e2 Kernel: Add FUSE support
This adds both the fuse device (used for communication between the
kernel and the filesystem) and filesystem implementation itself.
2024-05-07 16:54:27 -06:00
Dan Klishch cc5bacf886 Kernel: Allow annotating initially loaded executable segments
This allows marking regions as VirtualMemoryRangeFlags::SyscallCode in
static executables.
2024-05-07 16:36:38 -06:00
Hendiadyoin1 b17f080dcc Kernel/riscv: Use new DeviceTree helpers in PCI initializations
This also changes the PCI interface slightly to be a bit nicer to work
with.
2024-05-02 07:44:13 -06:00
Hendiadyoin1 8ea8b7a6e5 Kernel/MM: Parse /memreserve/ blocks in FDT based memory mapping mode
These seem to be actually used in the RPi FDTs
2024-05-02 07:44:13 -06:00
Hendiadyoin1 2b13769dd5 Kernel/MM: Skip non static reserved memory regions instead of crashing
Crashing seems a bit harsh, so let's just skip them instead, as they
actually show up in the device tree of RPis.
2024-05-02 07:44:13 -06:00
Sönke Holz b363abb082 Kernel/aarch64: Explicitly allow float instrs in {load,store}_fpu_state
LLVM 18 otherwise throws errors, as we use '-mgeneral-regs-only' in the
kernel.
The functions had to be moved into a .S, as there is no
'-mno-general-regs-only' and also no nice way to remove
'-mgeneral-regs-only' for a single .cpp file.
2024-04-30 06:32:58 -06:00
Idan Horowitz dfa2c98497 Kernel: Support the RISC-V PLIC
By supporting the RISC-V PLIC (Platform-Level Interrupt Controller)
we can now handle device (external) interrupts.
2024-04-30 06:01:26 -06:00
Idan Horowitz 0a2d520b15 Kernel: Handle CLINT interrupts separately from normal interrupts
Since CLINT interrupts are wired directly into the hart, instead of
going through an interrupt controller (the PLIC), trying to handle them
through the normal numbered-interrupt mechanism will just complicate it
for no reason.
Instead we now handle them directly in the trap handler.
2024-04-30 06:01:26 -06:00
Idan Horowitz 002bba4a97 Kernel: Configure PCI interrupt routing based on the FDT 2024-04-30 06:01:26 -06:00
Idan Horowitz 7102d90b2b Kernel: Verify we are running on hart 0
This is already an implicit assumption when we initialize our CPU id.
2024-04-30 06:01:26 -06:00
Idan Horowitz d3e285c253 Kernel: Deduplicate HardwareTimerBase::frequency()/ticks_per_second() 2024-04-30 06:01:26 -06:00
Liav A. b9df8deba2 Kernel/USB: Don't include UHCIController.h in USBPipe.h
The USB::Pipe is abstracted from the actual USB host controller
implementation, so don't include the UHCIController.h file.
Also, we missed an include to UserOrKernelBuffer.h, so this is added to
ensure the code can still compile.
2024-04-28 22:30:48 +02:00
Liav A. 2bba9411ca Kernel: Use the AK SetOnce container class in various cases
We have many places in the kernel code that we have boolean flags that
are only set once, and never reset again but are checked multiple times
before and after the time they're being set, which matches the purpose
of the SetOnce class.
2024-04-26 23:46:23 -06:00
Sönke Holz 01f1d2daaa Kernel/riscv64: Don't clobber the boot info argument in enable_paging
"register asm" variables don't preserve the register value, so the call
to calculate_physical_to_link_time_address_offset in the asm input
operands is allowed to clobber a0.
2024-04-26 15:01:31 -06:00
Timothy Flynn ab602cfc2c Kernel: Colorize log message for capabilities that have not been pledged
The log message can be hard to spot in a sea of debug messages. Colorize
it to make the message more immediately pop out.
2024-04-26 09:29:02 -04:00
Idan Horowitz 7339409575 Kernel: Properly initialize NVMe admin queue depth
We were reading the value instead of setting it (as required by the
specification). This worked only when we booted with a bootloader which
initialized NVMe before us.
2024-04-26 09:52:56 +02:00
Idan Horowitz a2b2209ea5 Kernel: Fix definition of CAP_TO_MASK
The default type for integer literals is signed int, so we were
accidentally smearing those bits to the upper 32 bit of the result.
This resulted in extremely unreasonable timeouts.
2024-04-26 09:52:56 +02:00
Idan Horowitz 543fc4d0fc Kernel: Support automatic configuration of PCI bridges based on the FDT
This let's us actually boot with RISC-V.
2024-04-26 09:52:56 +02:00
Idan Horowitz 08d4b231e1 Kernel: Take EnumerableDeviceIdentifier by const ref instead of by value
It's 48 bytes.
2024-04-26 09:52:56 +02:00
Idan Horowitz f6ae9f8a6d Kernel: Reset enumerated buses bitmap before enumerating PCI devices
This allows this method to be used more than once.
2024-04-26 09:52:56 +02:00
Idan Horowitz 95aff1cf13 Kernel: Remove unused IterationDecision in enumerate_attached_devices 2024-04-26 09:52:56 +02:00
Idan Horowitz e350d3b2c6 Kernel: Use PCI:Class:ID::Bridge instead of magic value 2024-04-26 09:52:56 +02:00
Idan Horowitz 519be6e626 Kernel: Use correctly-sized read when checking PCI host bridge function
We were accidentally doing a 16-bit read instead of an 8-bit read,
meaning we would also read the 'CACHE_LINE_SIZE' field immediately
following it, and never actually continue.
2024-04-26 09:52:56 +02:00
Timothy Flynn fecd08ce64 Everywhere: Remove 'clang-format off' comments that are no longer needed 2024-04-24 16:50:01 -04:00
Timothy Flynn ec492a1a08 Everywhere: Run clang-format
The following command was used to clang-format these files:

    clang-format-18 -i $(find . \
        -not \( -path "./\.*" -prune \) \
        -not \( -path "./Base/*" -prune \) \
        -not \( -path "./Build/*" -prune \) \
        -not \( -path "./Toolchain/*" -prune \) \
        -not \( -path "./Ports/*" -prune \) \
        -type f -name "*.cpp" -o -name "*.mm" -o -name "*.h")

There are a couple of weird cases where clang-format now thinks that a
pointer access in an initializer list, e.g. `m_member(ptr->foo)`, is a
lambda return statement, and it puts spaces around the `->`.
2024-04-24 16:50:01 -04:00
Sönke Holz 511e411def Kernel/riscv64: Implement Processor::read_cpu_counter
This simply reads the current cycle count from the cycle CSR.
x86-64 uses the similar rdtsc instruction here, which also may or may
not tick at a constant rate.
2024-04-21 13:37:32 -06:00
Sönke Holz c57e39d52b Kernel/riscv64: Don't flush the entire TLB in Processor::flush_tlb_local 2024-04-21 13:37:06 -06:00
implicitfield c15b473c1a Kernel/FATFS: Only read the requested blocks in read_bytes_locked()
This dramatically improves performance when working with large files,
since we no longer re-read the entire file for each read.
2024-04-21 15:34:33 +02:00
implicitfield 5bc87ad1a5 Kernel/FATFS: Free an inode's clusters upon removal 2024-04-21 15:34:33 +02:00
implicitfield 32692f032c Kernel/FATFS: Keep the FSInfo sector's free cluster count in sync 2024-04-21 15:34:33 +02:00
implicitfield bd76dd2dc2 Kernel/FATFS: Initialize special directory entries 2024-04-21 15:34:33 +02:00
implicitfield 66e1f8812f Kernel/FATFS: Don't ignore special entries when traversing directories 2024-04-21 15:34:33 +02:00
Undefine 31174c43bf Kernel/FATFS: Implement a hacky replace_child
This is not a proper implementation, but it's good enough to get
the write support fully working.
2024-04-21 15:34:33 +02:00
Undefine 511b298a1d Kernel/FATFS: Implement remove_child 2024-04-21 15:34:33 +02:00
Undefine 3b39a2f71b Kernel/FATFS: Implement add_child 2024-04-21 15:34:33 +02:00
Undefine 2952401c58 Kernel/FATFS: Implement create_child
This is a large commit because it implements a lot of stuff to make
add_child simpler to get working. This allows us to create new files
on a FAT partition.
2024-04-21 15:34:33 +02:00
Undefine 098518cc57 Kernel/FATFS: Implement file modification
This is the first part of write support, it allows for full file
modification, but no creating or removing files yet.

Co-Authored-By: implicitfield <114500360+implicitfield@users.noreply.github.com>
2024-04-21 15:34:33 +02:00
Undefine fde7bd9190 Kernel/FATFS: Make the debug logs nicer
They now look the same way as the ones in Ext2FS inodes which are
quite nice for debugging.
2024-04-21 15:34:33 +02:00
Undefine 33f00a7efb Kernel/FATFS: Cache the cluster list and don't cache the InodeMetadata
Caching the cluster list allows us to fill the two fields in the
InodeMetadata. While at it, don't cache the metadata as when we
have write support having to keep both InodeMetadata and FATEntry
correct is going to get very annoying.
2024-04-21 15:34:33 +02:00
Undefine d4badfac72 Kernel/FATFS: Store cluster list instead of block list
Once we have write support, managing clusters is going to be
way easier than managing blocks.
2024-04-21 15:34:33 +02:00
Undefine 92d58a91a6 Kernel/FATFS: Read the FAT32 FSInfo structure
This structure contains information about free clusters which
is going to be useful when allocating clusters.
2024-04-21 15:34:33 +02:00
Undefine 7e251c3b4f Kernel/FATFS: Return ENOTSUP on chown and chmod 2024-04-21 15:34:33 +02:00
Undefine eb2721d650 Kernel/FATFS: Pass the FATEntry location to FATInode constructor
This is going to be necessary to flush the metadata later on.
2024-04-21 15:34:33 +02:00
Undefine de574b9ed9 Kernel/FATFS: Improve error propagation in FATInode 2024-04-21 15:34:33 +02:00
implicitfield 0f828768bb Kernel/FATFS: Implement fat_write 2024-04-21 15:34:33 +02:00
implicitfield a6a1508601 Kernel/FATFS: Fix reading from large 12-bit FATs
12-bit FATs aren't necessarily block-aligned, so in the worst case
we'll have to reach into the next block to perform the read properly.
2024-04-21 15:34:33 +02:00
Undefine 1350c555f6 Kernel/FATFS: Factor out the FAT reading to a function
Move the FAT reading code to a fat_read function in FATFS and move the
required functions to FATFS too.
2024-04-21 15:34:33 +02:00
implicitfield b9d7e2db93 Kernel/FATFS: Prefer read_block() over raw_read()
`raw_read()` has proven to be a source of subtle bugs that occur as a
result of the cache and disk contents being out of sync.
2024-04-21 15:34:33 +02:00
implicitfield b1af97810e Kernel/FATFS: Avoid creating reference bindings to packed struct members
dbgln() will always take its arguments by reference when possible, which
causes UB when dealing with packed structs. To avoid this, we now
explicitly copy all members whose alignment requirements aren't met.
2024-04-21 15:34:33 +02:00
Sönke Holz 243d7003a2 Kernel+LibC+LibELF: Move TLS handling to userspace
This removes the allocate_tls syscall and adds an archctl option to set
the fs_base for the current thread on x86-64, since you can't set that
register from userspace. enter_thread_context loads the fs_base for the
next thread on each context switch.
This also moves tpidr_el0 (the thread pointer register on AArch64) to
the register state, so it gets properly saved/restored on context
switches.

The userspace TLS allocation code is kept pretty similar to the original
kernel TLS code, aside from a couple of style changes.

We also have to add a new argument "tls_pointer" to
SC_create_thread_params, as we otherwise can't prevent race conditions
between setting the thread pointer register and signal handling code
that might be triggered before the thread pointer was set, which could
use TLS.
2024-04-19 16:46:47 -06:00
Sönke Holz 216089c7a1 Kernel: Add a Thread member for arch-specific data
This will be used to store the fs_base value on x86-64, which is needed
for thread-local storage.
2024-04-19 16:46:47 -06:00
Sönke Holz 57f4f8caf8 Kernel+LibC: Introduce new archctl syscall
This syscall will be used for architecture-specific operations.
2024-04-19 16:46:47 -06:00
Andrew Kaster a65c385057 Kernel: Don't try to copy empty Vector in sys$recvmsg
If there's no fds to copy in a message with proper space for an
SCM_RIGHTS set of cmsg headers, then don't try to copy them.

This avoids a Kernel panic when recvmsg-ing, as copy_to_user(p, 0, 0)
hits a VERIFY.
2024-04-19 16:38:55 -04:00
Dan Klishch 5ed7cd6e32 Everywhere: Use east const in more places
These changes are compatible with clang-format 16 and will be mandatory
when we eventually bump clang-format version. So, since there are no
real downsides, let's commit them now.
2024-04-19 06:31:19 -04:00
Sönke Holz bee7070da0 Kernel: Do not use -mcmodel=large for x86_64 kernel
Small position independent code model (which we end up using after this
change) is suitable for us since the kernel is not expected to grow more
than 2Gb in size. This might be a bit risky since this model is not
mentioned anywhere except for System V ABI document but experiments show
that the kernel compiled with this change works just fine.
2024-04-18 13:14:33 -06:00
implicitfield 1159cd9390 AK+Kernel+LibSanitizer: Implement __ubsan_handle_function_type_mismatch 2024-04-18 13:14:33 -06:00
Sönke Holz 6cd130ec8e Kernel/riscv64: Increment sepc before re-enabling interrupts
This otherwise caused a race condition between the signal dispatcher
(which sets sepc to the signal trampoline) and sepc being updated in the
trap handler.
We obviously have to keep the sepc set by the signal dispatcher and not
increment it afterwards.
2024-04-17 11:24:34 -06:00
Space Meyer 5d89d3090e Kernel: Add KCOV recursion debugging 2024-04-15 21:16:22 -06:00
Space Meyer bba94804c2 Kernel: Deduplicate backtrace printing 2024-04-15 21:16:22 -06:00
Space Meyer a721e4d507 Kernel: Track KCOVInstance via Process instead of HashMap
While this clutters Process.cpp a tiny bit, I feel that it's worth it:
- 2x speed on the kcov_loop benchmark. Likely more during fuzzing.
- Overall code complexity is going down with this change.
- By reducing the code reachable from __sanitizer_cov_trace_pc code,
  we can now instrument more code.
2024-04-15 21:16:22 -06:00
Space Meyer fdc0328ce3 Kernel: Exclude individual functions from coverage instrumentation
Sticking this to the function source has multiple benefits:
- We instrument more code, by not excluding entire files.
- NO_SANITIZE_COVERAGE can be used in Header files.
- Keeping the info with the source code, means if a function or
  file is moved around, the NO_SANITIZE_COVERAGE moves with it.
2024-04-15 21:16:22 -06:00
Space Meyer ca89116a46 Kernel: Only build kcov object files, if feature is enabled 2024-04-15 21:16:22 -06:00
Space Meyer 106d4636a4 Revert "Kernel+SystemServer: Make KCOVDevice a character device"
This reverts commit 9dbec601b0.

For KCOV to be performant (or at least not even slower) we need to
mmap the PC buffer from both user and kernel space at the same time.
You can't mmap a character device, so this change didn't make sense.

Plus even if we did invent a new method to exfiltrate the coverage
information out of the kernel, it would be incompatible with existing
kernel fuzzers. That would be kind of annoying. 🙃
2024-04-15 21:16:22 -06:00
Sönke Holz ec5cfc031e Kernel/riscv64: Add Linux boot header
This allows us to boot via U-Boot's booti command.
2024-03-25 14:30:39 -06:00
Sönke Holz 1a312f4265 Kernel/riscv64: Only enable interrupts in trap handler if they were on
Always enabling interrupts is in hindsight obviously a bug, as trapping
code that has interrupts disabled very likely expects that they stay
disabled.
2024-03-25 14:21:41 -06:00
Sönke Holz 6a223c6210 Kernel/riscv64: Set g_total_processors to a hard-coded value of 1
This value is used by the NVMe driver to determine the number of queues
to create.
2024-03-25 14:20:39 -06:00
Sönke Holz 58a2e6412c Kernel/riscv64: Implement Processor::pause 2024-03-25 14:20:39 -06:00
Sönke Holz 040e0fe88c Kernel/riscv64: Implement microseconds_delay
This simple delay loop uses the time CSR to wait for the given amount
of time. The tick frequency of the CSR is read from the
/cpus/timebase-frequency devicetree property.
2024-03-25 14:20:39 -06:00
Sönke Holz 6654021655 Kernel/riscv64: Don't hard-code the page fault reason on RISC-V
Instead, rewrite the region page fault handling code to not use
PageFault::type() on RISC-V.

I split Region::handle_fault into having a RISC-V-specific
implementation, as I am not sure if I cover all page fault handling edge
cases by solely relying on MM's own region metadata.
We should probably also take the processor-provided page fault reason
into account, if we decide to merge these two implementations in the
future.
2024-03-25 14:18:38 -06:00
Sönke Holz 496a7541a2 Kernel/riscv64: Implement the signal trampoline 2024-03-25 14:17:32 -06:00
Sönke Holz 66f8d0f031 Kernel/riscv64: Add support for handling traps from userspace
This commit also removes the unnecessary user_sp RegisterState member.
We never use the kernel stack pointer on entry, so we can simply always
store the stack pointer of the previous privilege mode in sp.

Also remove the sp member from mcontext, as RISC-V doesn't have a
dedicated stack pointer register.
sp is defined to be x2 (x[1] in our case) by the ABI.

I probably accidentally included sp while copying the struct from
aarch64.
2024-03-25 14:14:43 -06:00
Sönke Holz afe9a12412 Kernel/riscv64: Handle syscalls
sepc has to be incremented before the call to syscall_handler,
as we otherwise would return to the ecall instruction, resulting in an
infinite trap loop.
We can't increment it after syscall_handler, as sepc might get changed
while handling the syscall.
2024-03-25 14:11:43 -06:00
Sönke Holz 04ca9f393f Kernel/riscv64: Implement create_thread 2024-03-25 14:10:05 -06:00
Sönke Holz 65724efac3 Kernel/riscv64: Implement fork 2024-03-25 14:10:05 -06:00
Sönke Holz faede8c93a Kernel/riscv64: Implement execve 2024-03-25 14:10:05 -06:00
Sönke Holz 6daa0da3c6 Kernel/NVMe: Fix calculation of "Maximum Queue Entries Supported" field
The value of this field is incremented by one, as a value of 0 for this
field means 1 entry supported.

A value of 0xffff for CAP.MQES would incorrectly by truncated to 0x0000,
if we don't increase the bit width of the return type.
2024-03-25 14:08:28 -06:00
Sönke Holz 378fa09a5a Kernel/riscv64: Fix typo (CSR::SATP::Mode::{Sv67 => Sv57}) 2024-03-20 10:36:10 -06:00
Tom Finet b9cfb50f71 Kernel/Net: Add TCPSocket timer for TimeWait moving to Closed
RFC9293 states that from the TimeWait state the TCPSocket
should wait the MSL (2mins) for delayed segments to expire
so that their sequence numbers do not clash with a new
connection's sequence numbers using the same ip address
and port number. The wait also ensures the remote TCP peer
has received the ACK to their FIN segment.
2024-03-14 18:33:19 -06:00
mrkubax10 eb0d56a4ed Kernel/Net: Implement support for RTL8168C
Please be aware that I only have NIC with chip version 6 so
this is the only one that I have tested. Rest was implemented
via looking at Linux rtl8169 driver. Also thanks to IdanHo
for some initial work.
2024-03-13 22:09:54 -06:00
Liav A 0734de9f9a Kernel+Userland: Add mount MS_SRCHIDDEN option
Either we mount from a loop device or other source, the user might want
to obfuscate the given source for security reasons, so this option will
ensure this will happen.
If passed during a mount, the source will be hidden when reading from
the /sys/kernel/df node.
2024-03-13 15:33:47 -06:00
Liav A 0d2e4a7e67 Kernel/FileSystem: Add the DevLoopFS filesystem
Similarly to DevPtsFS, this filesystem is about exposing loop device
nodes easily in /dev/loop, so userspace doesn't need to do anything in
order to use new devices immediately.
2024-03-13 15:33:47 -06:00
Liav A 11ead5c84f Kernel: Get RefPtr<Device> from the DeviceManagement::get_device method
Instead of returning a raw pointer, which could be technically invalid
when using it in the caller function, we return a valid RefPtr of such
device.

This ensures that the code in DevPtsFS is now safe from a rare race
condition in which the SlavePTY device is gone but we still have a
pointer to it.
2024-03-13 15:33:47 -06:00
Liav A 5dcf03ad9a Kernel/Devices: Introduce the LoopDevice device
This device is a block device that allows a user to effectively treat an
Inode as a block device.

The static construction method is given an OpenFileDescription reference
but validates that:
- The description has a valid custody (so it's not some arbitrary file).
  Failing this requirement will yield EINVAL.
- The description custody points to an Inode which is a regular file, as
  we only support (seekable) regular files. Failing this requirement
  will yield ENOTSUP.

LoopDevice can be used to mount a regular file on the filesystem like
other supported types of (physical) block devices.
2024-03-13 15:33:47 -06:00
Timothy Flynn 4b777397b5 Kernel: Define bitwise operations for KeyModifier
This type is designed to be use as a flag. Define bitwise operations for
convenience.
2024-03-06 07:46:18 +01:00
Timothy Flynn 836d93f7e3 Kernel: Replace C-idioms with AK types in RTL8168 network adapter
Instead of using C-arrays, and manually counting their lengths, use
AK::Array. And pass these arrays around as spans, instead of as pointer-
and-length pairs.
2024-03-04 20:00:52 +01:00
Idan Horowitz 209c588ed1 Kernel: Switch a couple of signal dispatch dbglns to dbgln_if
These are pretty spammy when using strace.
2024-03-02 09:10:14 +01:00
Hendiadyoin1 b0fc5bea91 Kernel/PCI: Prefer structured bindings when iterating over HashMaps
This makes `Access::rescan_hardware` look a bit nicer.
2024-03-01 14:05:53 -07:00
Hendiadyoin1 3e3b34ab8a Kernel/NVMe: Use a struct for the namespace features, instead of a Tuple 2024-03-01 14:05:53 -07:00
Sönke Holz cdc0c9f094 Kernel/Storage: Don't allocate IRQs in NVMeCntlr when nvme_poll passed 2024-02-25 17:20:40 -07:00
Liav A fff49ab6d3 Kernel/FileSystem: Avoid double locking m_inode_lock in the Ext2 driver 2024-02-24 16:45:26 -07:00
Liav A b63a1dda63 Kernel/FileSystem: Enforce locking of m_inode_lock when truncating Inode
Such operation is almost equivalent to writing on an Inode, so lock the
Inode m_inode_lock exclusively.
All FileSystem Inode implementations then override a new method called
truncate_locked which should implement the actual truncating.
2024-02-24 16:45:26 -07:00
Hendiadyoin1 53dd04e219 Kernel/riscv64: Read the timebase-frequency from the device tree 2024-02-24 16:43:44 -07:00
Hendiadyoin1 3941277940 Kernel/riscv64: Get the kernel command line from the device tree
This also hides the fdt dump by default now,
it can be activated by adding `dump_fdt` to the kernel command line
2024-02-24 16:43:44 -07:00
Hendiadyoin1 a99bd8eda6 Kernel/riscv64: Initialize PCI controllers using the device tree
Currently the search path is limited to `/soc/pci*` but this is enough
to get it to work on qemu.
2024-02-24 16:43:44 -07:00
Hediadyoin1 7309427d2f Kernel/riscv64: Unflatten the DeviceTree 2024-02-24 16:43:44 -07:00
Hendiadyoin1 d3f6b03733 Kernel/riscv64: Take the memory map from the FDT and dump it
For this the BootInfo struct was made architecture specific
2024-02-24 16:43:44 -07:00
Sönke Holz 1fc0c84017 Kernel/riscv64: Implement Processor::assume_context
This code is based on the aarch64 implementation.
2024-02-24 16:42:58 -07:00
Sönke Holz 726865592c Kernel/riscv64: Implement Processor::switch_context
This code is based on the aarch64 implementation.
2024-02-24 16:42:58 -07:00
Sönke Holz 494e026ca7 Kernel/riscv64: Implement Processor::init_context
This code is based on the aarch64 implementation.
2024-02-24 16:42:58 -07:00
Sönke Holz efdc433ebc Kernel/riscv64: Implement thread_context_first_enter
thread_context_first_enter reuses the context restoring code in the
trap handler, just like other arches already do.

The `ld x2, 1*8(sp)` is unnecessary in the trap handler, as the stack
pointer should be equal to the stack pointer slot in the RegisterState
if the trap is from supervisor mode (and we currently don't support
user traps).
This load will however make us unable to reuse that code for
thread_context_first_enter.
2024-02-24 16:42:58 -07:00