33#include <aquila/syscall.h>
36#define USER_FLAGS 0xF0000000UL
40 struct aquila_siginfo
info;
49 0xD2800000 | (SYS_sigreturn << 5) | 8,
58 return ((
struct vm_page *) a)->off == *(
size_t *) b;
80 asm volatile(
"dc cvau, %0; dsb ish; ic ivau, %0; dsb ish; isb"
153 int fault = sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || sig == SIGFPE;
155 memset(&frame, 0,
sizeof(frame));
156 frame.
info = (
struct aquila_siginfo) {
174 if (r->
sp < 4096 || copyout(uframe, &frame,
sizeof(frame)))
181 r->
pc = sa->sa_handler;
187 sigset_t block = sa->sa_mask | (sa->sa_flags & SA_NODEFER ? 0 : 1UL << sig);
190 if (sa->sa_flags & SA_RESETHAND)
255 if ((f & 15) || copyin(&frame, (
void *) f,
sizeof(frame))) {
void aarch64_return_to_user(struct aarch64_regs *r, int syscall)
Takes the current thread's signals on its way back to user mode, and restarts or fails the system cal...
#define FPSIMD_STATE_SIZE
static const uint32_t sigcode[]
static void deliver(struct aarch64_regs *r, int sig)
Sets up the user context r so that the handler of sig runs when it's returned to.
static int vm_page_eq(void *a, void *b)
Tells whether a page is at the offset that b points to (for the object's hashmap of pages).
static struct vm_object sigcode_object
static struct vm_pager sigcode_pager
void arch_sigreturn(void)
Returns from a signal handler, for sigreturn(): restores the registers, the signal mask and the FPU s...
int arch_sigcode_map(struct proc *proc)
Maps the page with the code that calls sigreturn() (the sigcode) into a process's new address space.
static struct vm_page * sigcode_in(struct vm_object *vm_object, size_t off)
Makes the sigcode page, the first time a process touches it.
void * aarch64_fpsimd_current(struct thread *thread)
Returns a thread's FP/SIMD state as it is now, saving it from the registers first if they hold it.
void aarch64_fpsimd_restore(struct thread *thread, const void *state)
Gives a thread back the FP/SIMD state that a signal frame kept, for sigreturn().
struct vm_page * mm_page_alloc(void)
Allocates a free page of physical memory.
void mm_page_dealloc(paddr_t paddr)
Frees a page of physical memory, back to the zone it came from.
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
void kfree(void *)
Frees an object that kmalloc() gave.
void * memset(void *dst, int c, size_t n)
Sets n bytes to c.
void * memcpy(void *dst, const void *src, size_t n)
Copies n bytes; dst and src must not overlap.
int pmap_page_write(paddr_t paddr, off_t off, size_t size, void *buf)
Writes to a page of physical memory, through the kernel's mapping.
void signal_exit(int sig)
Ends the current process because of a signal.
void signal_force(struct proc *proc, int signal)
Sends a signal that can't be blocked or ignored, such as the SIGSEGV of a fault: if the process block...
int signal_take(void)
Takes the current process's pending signals, on the way back to user mode: ignored ones are dropped,...
__PTRDIFF_TYPE__ intptr_t
unsigned long long int uint64_t
What an exception saves on the kernel stack (cpu/vectors.S): the context it interrupted.
A thread's aarch64 state (thread->arch).
struct aarch64_regs * regs
struct aquila_sigaction sigaction[SIG_MAX+1]
its signal actions
struct vm_space vm_space
its address space
sigset_t sigmask
its blocked signals, a bit (1 << sig) each
A signal handler's frame, on the user stack.
uint8_t fpsimd[FPSIMD_STATE_SIZE]
struct aquila_siginfo info
int sig_oldmask_set
in sigsuspend() or pselect(): the signal mask they replaced, which the handler's frame keeps (sigretu...
int restarting
whether the call is a restart (a stop interrupted it, and no handler ran); restart_until is the deadl...
void * arch
the architecture's own data: its registers, its kernel stack
struct proc * owner
its process
uintptr_t fault_addr
the address of its last fault, the si_addr of the signal it raised
A mapping (map entry): a range of an address space, its permissions, and where its pages come from.
uint32_t flags
its permissions and flags (VM_*)
vaddr_t base
where the mapping starts in its address space
struct vm_object * vm_object
its object: what its other pages come from (a file)
A vm object: what a mapping's pages come from (a file), and its pages that have been read in.
struct hashmap * pages
its pages that have been read in, by their offset
A page of physical memory (pages[] has one for every page of RAM).
size_t off
its offset in its object or anon
size_t ref
how many references it has
struct vm_object * vm_object
the object it belongs to, or NULL
paddr_t paddr
its physical address
int vm_space_insert(struct vm_space *vm_space, struct vm_entry *vm_entry)
Adds a map entry to an address space, in address order.
int vm_object_page_insert(struct vm_object *vm_object, struct vm_page *vm_page)
Adds a page to a vm object, at the page's offset (vm_page->off).
#define VM_URX
user read/execute
void vm_object_incref(struct vm_object *vm_object)
Adds a reference to a vm object: one more mapping of it.