AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
signal.c File Reference

aarch64: signals on the way back to user mode, and the signal handler's frame. More...

#include <core/system.h>
#include <core/arch.h>
#include <core/string.h>
#include <cpu/cpu.h>
#include <ds/hashmap.h>
#include <mm/mm.h>
#include <mm/pmap.h>
#include <mm/vm.h>
#include <sys/proc.h>
#include <sys/sched.h>
#include <sys/signal.h>
#include <sys/uaccess.h>
#include <aquila/syscall.h>

Go to the source code of this file.

Data Structures

struct  sigframe
 A signal handler's frame, on the user stack. More...

Macros

#define USER_FLAGS   0xF0000000UL

Functions

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_page * sigcode_in (struct vm_object *vm_object, size_t off)
 Makes the sigcode page, the first time a process touches it.
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 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.
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 call that a signal interrupted.
void arch_sigreturn (void)
 Returns from a signal handler, for sigreturn(): restores the registers, the signal mask and the FPU state that the handler's frame saved.

Variables

static const uint32_t sigcode []
static struct vm_pager sigcode_pager
static struct vm_object sigcode_object

Detailed Description

aarch64: signals on the way back to user mode, and the signal handler's frame.

This is the aarch64 side of docs/kernel/signals.md, and works as x86's sys/signal.c does. Every return to user mode goes through aarch64_return_to_user(), where the process takes its signals (signal_take()). A system call that a signal interrupted is either restarted, by going back to its svc with its first argument back in x0 (the result took its place), or fails with EINTR. A handler runs by rewriting the user context saved on the kernel stack.

The handler's frame, a struct sigframe on the user stack, holds the siginfo, the mask to restore, and the interrupted registers. The handler is called with the signal in x0, the siginfo in x1, and no ucontext in x2, and it returns (through x30) into the sigcode page, which makes the sigreturn system call.

Definition in file signal.c.

Macro Definition Documentation

◆ USER_FLAGS

#define USER_FLAGS   0xF0000000UL

Definition at line 36 of file signal.c.

Referenced by arch_sigreturn(), deliver(), and deliver().

Function Documentation

◆ aarch64_return_to_user()

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 call that a signal interrupted.

Parameters
rthe user context saved on the kernel stack
syscallwhether the thread is returning from a system call

Definition at line 201 of file signal.c.

References aarch64_return_to_user(), thread::arch, curthread, deliver(), ERESTARTNOHAND, ERESTARTSYS, aarch64_regs::orig_x0, thread::owner, aarch64_regs::pc, REGS_USER, thread::restarting, thread::sig_oldmask, thread::sig_oldmask_set, proc::sigaction, proc::sigmask, signal_take(), and aarch64_regs::x.

Referenced by aarch64_goto(), aarch64_irq(), aarch64_return_to_user(), abort(), arch_syscall(), and sync_dispatch().

◆ arch_sigcode_map()

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.

Parameters
procthe process
Returns
0, or a negative errno (-ENOMEM if there was no memory)

Definition at line 107 of file signal.c.

References arch_sigcode_map(), vm_entry::base, vm_entry::flags, kfree(), kmalloc(), M_ZERO, PAGE_SIZE, vm_object::pages, SIGCODE_ADDR, sigcode_object, vm_entry::size, vm_entry::vm_object, vm_object_incref(), vm_page_eq(), proc::vm_space, vm_space_insert(), and VM_URX.

Referenced by arch_sigcode_map(), and binfmt_fmt_load().

◆ arch_sigreturn()

void arch_sigreturn ( void )

Returns from a signal handler, for sigreturn(): restores the registers, the signal mask and the FPU state that the handler's frame saved.

A bad frame gets SIGSEGV.

Definition at line 247 of file signal.c.

References aarch64_fpsimd_restore(), arch_sigreturn(), curproc, curthread, sigframe::fpsimd, sigframe::fpsimd_valid, sigframe::mask, NULL, aarch64_regs::pstate, aarch64_thread::regs, sigframe::regs, SIG_UNMASKABLE, signal_force(), aarch64_regs::sp, and USER_FLAGS.

Referenced by arch_sigreturn(), and sys_sigreturn().

◆ deliver()

void deliver ( struct aarch64_regs * r,
int sig )
static

◆ sigcode_in()

struct vm_page * sigcode_in ( struct vm_object * vm_object,
size_t off )
static

Makes the sigcode page, the first time a process touches it.

The object keeps it, and every process maps it. Returns NULL if there's no memory.

Definition at line 64 of file signal.c.

References kfree(), kmalloc(), M_ZERO, memcpy(), mm_page_alloc(), mm_page_dealloc(), NULL, vm_page::off, vm_page::paddr, PAGE_SIZE, PHYS2VIRT, pmap_page_write(), vm_page::ref, sigcode, sigcode_in(), vm_page::vm_object, and vm_object_page_insert().

Referenced by sigcode_in().

◆ vm_page_eq()

int vm_page_eq ( void * a,
void * b )
static

Tells whether a page is at the offset that b points to (for the object's hashmap of pages).

Definition at line 56 of file signal.c.

References vm_page_eq().

Referenced by arch_sigcode_map(), vm_object_vnode(), vm_page_eq(), and vm_page_eq().

Variable Documentation

◆ sigcode

const uint32_t sigcode[]
static
Initial value:
= {
0xD2800000 | (SYS_sigreturn << 5) | 8,
0xD4000001,
0x00000000,
}

Definition at line 48 of file signal.c.

Referenced by sigcode_in().

◆ sigcode_object

struct vm_object sigcode_object
static
Initial value:
= {
.pager = &sigcode_pager,
.ref = 1,
}
static struct vm_pager sigcode_pager
Definition signal.c:95

Definition at line 99 of file signal.c.

Referenced by arch_sigcode_map().

◆ sigcode_pager

struct vm_pager sigcode_pager
static
Initial value:
= {
.in = sigcode_in,
}
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.
Definition signal.c:64

Definition at line 95 of file signal.c.