Jelajahi Sumber

Got signals working on x64.

Only a couple of minor tweaks were needed to get signals working on x64.
I'm now able to run the perf test, though I did see resident set
accounting issues. I also noticed an issue with TLS relocations where the
sign was wrong. I copied it from the x86 relocation, so I'm not sure if
that one has the same problem or not.
Evan Green 6 tahun lalu
induk
melakukan
54f2c36e2b
4 mengubah file dengan 12 tambahan dan 10 penghapusan
  1. 6 1
      apps/osbase/x64/osbasea.S
  2. 3 2
      include/minoca/kernel/x64.inc
  3. 2 6
      kernel/ps/x64/psarch.c
  4. 1 1
      lib/im/elf.c

+ 6 - 1
apps/osbase/x64/osbasea.S

@@ -177,8 +177,13 @@ Return Value:
 --*/
 
 FUNCTION(OspSignalHandler)
-    int     $3                  # TODO: Check this, it's never been run!
+    pushq   %rsi                # Save signal context, align stack.
+    CFI_ADJUST_CFA_OFFSET(8)    # Account for the push.
     call    OspProcessSignal    # Call the processing routine.
+    movl    $SystemCallRestoreContext, %edi     # Set system call number.
+    popq    %rsi                # Pop signal context as parameter two.
+    CFI_ADJUST_CFA_OFFSET(-8)   # Account for the popl.
+    callq   OsSystemCall        # Restore to before the signal handler.
     int     $3                  # Execution should never get back here.
 
 END_FUNCTION(OspSignalHandler)

+ 3 - 2
include/minoca/kernel/x64.inc

@@ -98,13 +98,14 @@ Environment:
 #define TRAP_FRAME_SIZE     192
 
 //
-// TODO: Fix these sizes.
+// Define the system call numbers used by assembly, and some relevant
+// structure sizes.
 //
 
 #define SystemCallRestoreContext 1
 #define SystemCallForkProcess 2
 #define PROCESSOR_CONTEXT_SIZE 284
-#define SIGNAL_CONTEXT_SIZE 28
+#define SIGNAL_CONTEXT_SIZE 48
 
 //
 // Define the minimum and maximum external interrupt vectors.

+ 2 - 6
kernel/ps/x64/psarch.c

@@ -182,12 +182,6 @@ Return Value:
     PKTHREAD Thread;
 
     Thread = KeGetCurrentThread();
-
-    //
-    // TODO: Check signal apply for x64. Alignment? Can signal handling be
-    // all C?
-    //
-
     ContextSp = TrapFrame->Rsp - X64_RED_ZONE - sizeof(SIGNAL_CONTEXT_X64);
     ContextSp = ALIGN_RANGE_DOWN(ContextSp, FPU_CONTEXT_ALIGNMENT);
     Context = (PVOID)ContextSp;
@@ -225,6 +219,7 @@ Return Value:
                                sizeof(TRAP_FRAME));
 
     TrapFrame->Rsp = ContextSp;
+    TrapFrame->Rsi = TrapFrame->Rsp;
     if ((Thread->FpuFlags & THREAD_FPU_FLAG_IN_USE) != 0) {
         Flags |= SIGNAL_CONTEXT_FLAG_FPU_VALID;
         if ((Thread->FpuFlags & THREAD_FPU_FLAG_OWNER) != 0) {
@@ -267,6 +262,7 @@ Return Value:
 
     Result &= MmUserWrite32(&(Context->Common.Flags), Flags);
     TrapFrame->Rsp -= sizeof(SIGNAL_PARAMETERS);
+    TrapFrame->Rdi = TrapFrame->Rsp;
     Status |= MmCopyToUserMode((PVOID)(TrapFrame->Rsp),
                                SignalParameters,
                                sizeof(SIGNAL_PARAMETERS));

+ 1 - 1
lib/im/elf.c

@@ -3987,7 +3987,7 @@ Return Value:
             ASSERT((SymbolImage != NULL) &&
                    (SymbolImage->TlsOffset != (UINTN)-1));
 
-            Address = SymbolImage->TlsOffset - SymbolValue + Addend;
+            Address = SymbolValue - SymbolImage->TlsOffset + Addend;
             break;
 
         //