When detecting stack overflow in the kernel exception handler, use
`SP_EL0`, rather than `TPIDR_EL1` as the scratch register. This allows
us to use the `TPIDR_EL1` register as a CPU-banked register for other
purposes.
Use of `SP_EL0` is safe here since the stack overflow check occurs
during kernel exceptions and SP_EL0 will be restored by the user-space
context restore logic, overriding the clobber.
Add a new module for managing objects within a slab. The `Slab` struct
manages objects of a given set within a contiguous set of pages. It is
the handle to the underlying memory, allowing for objects to be
allocated, and free'd. It manages a free list of 'indexes' within the
object slots themselves.
Rather than returning a reference to the `OnceCell` wrapping the
allocator, return a static reference to the allocator itself. This
allows flexibility for how the allocator is wrapped.
Move the FrameList logic out of the physical memory allocator into its
own module. This allows `FrameList` to be shared between the physical
memory allocator and the slab allocator.
Create a new submodule within `memory`, `allocators` which contains all
memory allocators. Also split out the `Frame` struct from the `pg_alloc`
module, allowing it to be used by other modules.
When the secondary boots and derefes the boot_ctx pointer passed in as a
parameter, it reads NULL, causing the secondary to end up stuck in an
exception loop. The data is sat in the primary core's cache and hasn't
been flushed to RAM. Since the secondary starts without the MMU (and
caches) enabled, the CCI doesn't kick in and we read stale data.
Manually flush the boot_ctx data to RAM before waking up the secondary.
Since the test driver now outputs the test name, remove test name
printing in the signal tests.
Also flush stdout when the test has began running so if a problem
occures it's easier to know which test was running.
The `sys_clock_nanosleep` implementation was missing a `flags` parameter
in the second position. This meant that `rqtp` was interpreted as
`rmtp`, and when interrupted, `rmtp` would write to a garbage address
causing an `EFAULT`.
Fix the argument ordering.
Poll the wrapped future first, ensuring that the interrupt logic doesn't
short-circuit a future which is already ready.
This fixes an issue where `sys_wait4` would return `-EINTR` when
receiving a `SIGCHLD`. Since `SIGCHLD` indicates the wait condition
is met, the underlying future is ready and should return the PID
successfully rather than aborting.
This function is used to force the scheduler to reschedule another task,
avoiding the fast-path exit. Given the sheer number of task state
change points in the code, the fast-path exit code has become too
brittle.
Instead, check that the current task's state is still `Running` before
taking the fast-path short-circuit. The cost of one spinlock uncontended
lock-unlock cycle is worth the cost of avoiding many subtle scheduling
logic bugs.
Allow a `read()` on a tty to be interrupted by a syscall. This is the
fundamental fix for making '^C' interrupt a process like `cat` when it's
reading from `stdin`.