Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aarch64: implement signal handler #1154

Closed
wkozaczuk opened this issue Jun 27, 2021 · 0 comments
Closed

aarch64: implement signal handler #1154

wkozaczuk opened this issue Jun 27, 2021 · 0 comments
Labels

Comments

@wkozaczuk
Copy link
Collaborator

The preliminary implementation may look like this:

diff --git a/arch/aarch64/entry.S b/arch/aarch64/entry.S
index 556f89ad..80615fe3 100644
--- a/arch/aarch64/entry.S
+++ b/arch/aarch64/entry.S
@@ -206,18 +206,16 @@ entry_serror:
 call_signal_handler_thunk:
         .type call_signal_handler_thunk, @function
         .cfi_startproc simple
-        # stack contains a signal_frame
-        /*
-        .cfi_offset reg, offset
-        ...
-        mov x0, sp
-        call call_signal_handler
-        # FIXME: fpu
-
-        pop_pair...
-        add sp, sp, 16 # error_code
-        */
-        ret
+         # stack contains a signal_frame
+         msr     SPsel, #1
+         ldr     x0, [sp, #-40] //new sp modified in the original exception frame
+         mov     sp, x0
+         bl      call_signal_handler
+         pop_state_from_exception_frame
+         ldr     x30, [sp, #-40] //old sp saved in the copy of original exception frame in signal frame
+         mov     sp, x30
+         ldr     x30, [x30, #-48] //restore x30
+         eret
         .cfi_endproc
 
 // Keep fpu_state_save/load in sync with struct fpu_state in arch/aarch64/processor.hh
diff --git a/arch/aarch64/signal.cc b/arch/aarch64/signal.cc
index 7f3cbc15..5bded96a 100644
--- a/arch/aarch64/signal.cc
+++ b/arch/aarch64/signal.cc
@@ -14,6 +14,10 @@
 #include <arch-cpu.hh>
 #include <osv/debug.hh>
 
+namespace osv {
+extern struct sigaction signal_actions[];
+};
+
 namespace arch {
 
 struct signal_frame {
@@ -35,7 +39,23 @@ void build_signal_frame(exception_frame* ef,
                         const siginfo_t& si,
                         const struct sigaction& sa)
 {
-    void* sp = reinterpret_cast<void*>(ef->sp);
+    // If an alternative signal stack was defined for this thread with
+    // sigaltstack() and the SA_ONSTACK flag was specified, we should run
+    // the signal handler on that stack. Otherwise, we need to run further
+    // down the same stack the thread was using when it received the signal:
+    void *sp = nullptr;
+    if (sa.sa_flags & SA_ONSTACK) {
+        stack_t sigstack;
+        sigaltstack(nullptr, &sigstack);
+        if (!(sigstack.ss_flags & SS_DISABLE)) {
+            // ss_sp points to the beginning of the stack region, but x86
+            // stacks grow downward, from the end of the region
+            sp = sigstack.ss_sp + sigstack.ss_size;
+        }
+    }
+    if (!sp) {
+        sp = reinterpret_cast<void*>(ef->sp);
+    }
     sp -= sizeof(signal_frame);
     sp = align_down(sp, 16);
     signal_frame* frame = static_cast<signal_frame*>(sp);
@@ -50,5 +70,84 @@ void build_signal_frame(exception_frame* ef,
 
 void call_signal_handler(arch::signal_frame* frame)
 {
-    processor::halt_no_interrupts();
+    sched::fpu_lock fpu;
+    SCOPE_LOCK(fpu);
+    if (frame->sa.sa_flags & SA_SIGINFO) {
+        ucontext_t uc = {};
+        auto& mcontext = uc.uc_mcontext;
+        auto& f = frame->state;
+        mcontext.regs[0] = f.regs[0];
+        mcontext.regs[1] = f.regs[1];
+        mcontext.regs[2] = f.regs[2];
+        mcontext.regs[3] = f.regs[3];
+        mcontext.regs[4] = f.regs[4];
+        mcontext.regs[5] = f.regs[5];
+        mcontext.regs[6] = f.regs[6];
+        mcontext.regs[7] = f.regs[7];
+        mcontext.regs[8] = f.regs[8];
+        mcontext.regs[9] = f.regs[9];
+        mcontext.regs[10] = f.regs[20];
+        mcontext.regs[11] = f.regs[21];
+        mcontext.regs[12] = f.regs[22];
+        mcontext.regs[13] = f.regs[23];
+        mcontext.regs[14] = f.regs[24];
+        mcontext.regs[15] = f.regs[25];
+        mcontext.regs[16] = f.regs[26];
+        mcontext.regs[17] = f.regs[27];
+        mcontext.regs[18] = f.regs[28];
+        mcontext.regs[19] = f.regs[29];
+        mcontext.regs[20] = f.regs[20];
+        mcontext.regs[21] = f.regs[21];
+        mcontext.regs[22] = f.regs[22];
+        mcontext.regs[23] = f.regs[23];
+        mcontext.regs[24] = f.regs[24];
+        mcontext.regs[25] = f.regs[25];
+        mcontext.regs[26] = f.regs[26];
+        mcontext.regs[27] = f.regs[27];
+        mcontext.regs[28] = f.regs[28];
+        mcontext.regs[29] = f.regs[29];
+        mcontext.regs[30] = f.regs[30];
+        mcontext.sp = f.sp;
+        mcontext.pc = f.elr;
+        mcontext.pstate = f.spsr;
+        mcontext.fault_address = 22345; //TODO: Just to see if it shows
+       //mcontext.fault_address = f.???;//Should come from far_el1
+        frame->sa.sa_sigaction(frame->si.si_signo, &frame->si, &uc);
+        f.regs[0] = mcontext.regs[0];
+        f.regs[1] = mcontext.regs[1];
+        f.regs[2] = mcontext.regs[2];
+        f.regs[3] = mcontext.regs[3];
+        f.regs[4] = mcontext.regs[4];
+        f.regs[5] = mcontext.regs[5];
+        f.regs[6] = mcontext.regs[6];
+        f.regs[7] = mcontext.regs[7];
+        f.regs[8] = mcontext.regs[8];
+        f.regs[9] = mcontext.regs[9];
+        f.regs[10] = mcontext.regs[10];
+        f.regs[11] = mcontext.regs[11];
+        f.regs[12] = mcontext.regs[12];
+        f.regs[13] = mcontext.regs[13];
+        f.regs[14] = mcontext.regs[14];
+        f.regs[15] = mcontext.regs[15];
+        f.regs[16] = mcontext.regs[16];
+        f.regs[17] = mcontext.regs[17];
+        f.regs[18] = mcontext.regs[18];
+        f.regs[19] = mcontext.regs[19];
+        f.regs[20] = mcontext.regs[20];
+        f.regs[21] = mcontext.regs[21];
+        f.regs[22] = mcontext.regs[22];
+        f.regs[23] = mcontext.regs[23];
+        f.regs[24] = mcontext.regs[24];
+        f.regs[25] = mcontext.regs[25];
+        f.regs[26] = mcontext.regs[26];
+        f.regs[27] = mcontext.regs[27];
+        f.regs[28] = mcontext.regs[28];
+        f.regs[29] = mcontext.regs[29];
+        f.regs[30] = mcontext.regs[30];
+        f.sp = mcontext.sp;
+        f.elr = mcontext.pc;
+        f.spsr = mcontext.pstate;
+    } else {
+        frame->sa.sa_handler(frame->si.si_signo);
+    }
 }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant