Author: andrew
Date: Thu Apr 20 13:56:30 2017
New Revision: 317192
URL: https://svnweb.freebsd.org/changeset/base/317192

Log:
  Push loading curthread into assembly in the synchronous exception handlers.
  This will help investigating the performance impact of moving parts of the
  switch statement in do_el0_sync into assembly.
  
  Sponsored by: DARPA, AFRL

Modified:
  head/sys/arm64/arm64/exception.S
  head/sys/arm64/arm64/genassym.c
  head/sys/arm64/arm64/trap.c

Modified: head/sys/arm64/arm64/exception.S
==============================================================================
--- head/sys/arm64/arm64/exception.S    Thu Apr 20 13:56:06 2017        
(r317191)
+++ head/sys/arm64/arm64/exception.S    Thu Apr 20 13:56:30 2017        
(r317192)
@@ -143,7 +143,8 @@ __FBSDID("$FreeBSD$");
 
 ENTRY(handle_el1h_sync)
        save_registers 1
-       mov     x0, sp
+       ldr     x0, [x18, #PC_CURTHREAD]
+       mov     x1, sp
        bl      do_el1h_sync
        restore_registers 1
        eret
@@ -163,7 +164,9 @@ END(handle_el1h_error)
 
 ENTRY(handle_el0_sync)
        save_registers 0
-       mov     x0, sp
+       ldr     x0, [x18, #PC_CURTHREAD]
+       mov     x1, sp
+       str     x1, [x0, #TD_FRAME]
        bl      do_el0_sync
        do_ast
        restore_registers 0

Modified: head/sys/arm64/arm64/genassym.c
==============================================================================
--- head/sys/arm64/arm64/genassym.c     Thu Apr 20 13:56:06 2017        
(r317191)
+++ head/sys/arm64/arm64/genassym.c     Thu Apr 20 13:56:30 2017        
(r317192)
@@ -57,6 +57,7 @@ ASSYM(SF_UC, offsetof(struct sigframe, s
 
 ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
 ASSYM(TD_FLAGS, offsetof(struct thread, td_flags));
+ASSYM(TD_FRAME, offsetof(struct thread, td_frame));
 ASSYM(TD_LOCK, offsetof(struct thread, td_lock));
 
 ASSYM(TF_SIZE, sizeof(struct trapframe));

Modified: head/sys/arm64/arm64/trap.c
==============================================================================
--- head/sys/arm64/arm64/trap.c Thu Apr 20 13:56:06 2017        (r317191)
+++ head/sys/arm64/arm64/trap.c Thu Apr 20 13:56:30 2017        (r317192)
@@ -72,8 +72,8 @@ __FBSDID("$FreeBSD$");
 extern register_t fsu_intr_fault;
 
 /* Called from exception.S */
-void do_el1h_sync(struct trapframe *);
-void do_el0_sync(struct trapframe *);
+void do_el1h_sync(struct thread *, struct trapframe *);
+void do_el0_sync(struct thread *, struct trapframe *);
 void do_el0_error(struct trapframe *);
 static void print_registers(struct trapframe *frame);
 
@@ -130,23 +130,20 @@ cpu_fetch_syscall_args(struct thread *td
 #include "../../kern/subr_syscall.c"
 
 static void
-svc_handler(struct trapframe *frame)
+svc_handler(struct thread *td, struct trapframe *frame)
 {
        struct syscall_args sa;
-       struct thread *td;
        int error;
 
-       td = curthread;
-
        error = syscallenter(td, &sa);
        syscallret(td, error, &sa);
 }
 
 static void
-data_abort(struct trapframe *frame, uint64_t esr, uint64_t far, int lower)
+data_abort(struct thread *td, struct trapframe *frame, uint64_t esr,
+    uint64_t far, int lower)
 {
        struct vm_map *map;
-       struct thread *td;
        struct proc *p;
        struct pcb *pcb;
        vm_prot_t ftype;
@@ -167,7 +164,6 @@ data_abort(struct trapframe *frame, uint
        }
 #endif
 
-       td = curthread;
        pcb = td->td_pcb;
 
        /*
@@ -261,7 +257,7 @@ print_registers(struct trapframe *frame)
 }
 
 void
-do_el1h_sync(struct trapframe *frame)
+do_el1h_sync(struct thread *td, struct trapframe *frame)
 {
        uint32_t exception;
        uint64_t esr, far;
@@ -276,14 +272,14 @@ do_el1h_sync(struct trapframe *frame)
 #endif
 
        CTR4(KTR_TRAP,
-           "do_el1_sync: curthread: %p, esr %lx, elr: %lx, frame: %p",
-           curthread, esr, frame->tf_elr, frame);
+           "do_el1_sync: curthread: %p, esr %lx, elr: %lx, frame: %p", td,
+           esr, frame->tf_elr, frame);
 
        switch(exception) {
        case EXCP_FP_SIMD:
        case EXCP_TRAP_FP:
 #ifdef VFP
-               if ((curthread->td_pcb->pcb_fpflags & PCB_FP_KERN) != 0) {
+               if ((td->td_pcb->pcb_fpflags & PCB_FP_KERN) != 0) {
                        vfp_restore_state();
                } else
 #endif
@@ -297,7 +293,7 @@ do_el1h_sync(struct trapframe *frame)
        case EXCP_DATA_ABORT:
                far = READ_SPECIALREG(far_el1);
                intr_enable();
-               data_abort(frame, esr, far, 0);
+               data_abort(td, frame, esr, far, 0);
                break;
        case EXCP_BRK:
 #ifdef KDTRACE_HOOKS
@@ -338,9 +334,8 @@ el0_excp_unknown(struct trapframe *frame
 }
 
 void
-do_el0_sync(struct trapframe *frame)
+do_el0_sync(struct thread *td, struct trapframe *frame)
 {
-       struct thread *td;
        uint32_t exception;
        uint64_t esr, far;
 
@@ -349,9 +344,6 @@ do_el0_sync(struct trapframe *frame)
            ("Invalid pcpu address from userland: %p (tpidr %lx)",
             get_pcpu(), READ_SPECIALREG(tpidr_el1)));
 
-       td = curthread;
-       td->td_frame = frame;
-
        esr = frame->tf_esr;
        exception = ESR_ELx_EXCEPTION(esr);
        switch (exception) {
@@ -364,8 +356,8 @@ do_el0_sync(struct trapframe *frame)
        intr_enable();
 
        CTR4(KTR_TRAP,
-           "do_el0_sync: curthread: %p, esr %lx, elr: %lx, frame: %p",
-           curthread, esr, frame->tf_elr, frame);
+           "do_el0_sync: curthread: %p, esr %lx, elr: %lx, frame: %p", td, esr,
+           frame->tf_elr, frame);
 
        switch(exception) {
        case EXCP_FP_SIMD:
@@ -377,12 +369,12 @@ do_el0_sync(struct trapframe *frame)
 #endif
                break;
        case EXCP_SVC:
-               svc_handler(frame);
+               svc_handler(td, frame);
                break;
        case EXCP_INSN_ABORT_L:
        case EXCP_DATA_ABORT_L:
        case EXCP_DATA_ABORT:
-               data_abort(frame, esr, far, 1);
+               data_abort(td, frame, esr, far, 1);
                break;
        case EXCP_UNKNOWN:
                el0_excp_unknown(frame, far);
@@ -418,10 +410,10 @@ do_el0_sync(struct trapframe *frame)
                break;
        }
 
-       KASSERT((curthread->td_pcb->pcb_fpflags & ~PCB_FP_USERMASK) == 0,
+       KASSERT((td->td_pcb->pcb_fpflags & ~PCB_FP_USERMASK) == 0,
            ("Kernel VFP flags set while entering userspace"));
        KASSERT(
-           curthread->td_pcb->pcb_fpusaved == &curthread->td_pcb->pcb_fpustate,
+           td->td_pcb->pcb_fpusaved == &td->td_pcb->pcb_fpustate,
            ("Kernel VFP state in use when entering userspace"));
 }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to