summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandrew <andrew@FreeBSD.org>2017-05-30 13:16:06 +0000
committerandrew <andrew@FreeBSD.org>2017-05-30 13:16:06 +0000
commitc9ac1eb880a7fae7a6e36d7bd563e21d7c41eaad (patch)
treef5d54d68bb38226f54b6af2195635abe2236cce3
parentf354de911172b86d13bfda0df1c76729f9609fd2 (diff)
downloadFreeBSD-src-c9ac1eb880a7fae7a6e36d7bd563e21d7c41eaad.zip
FreeBSD-src-c9ac1eb880a7fae7a6e36d7bd563e21d7c41eaad.tar.gz
MFC r317192:
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.
-rw-r--r--sys/arm64/arm64/exception.S7
-rw-r--r--sys/arm64/arm64/genassym.c1
-rw-r--r--sys/arm64/arm64/trap.c36
3 files changed, 20 insertions, 24 deletions
diff --git a/sys/arm64/arm64/exception.S b/sys/arm64/arm64/exception.S
index 432c4d4..515d3fe 100644
--- a/sys/arm64/arm64/exception.S
+++ b/sys/arm64/arm64/exception.S
@@ -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
diff --git a/sys/arm64/arm64/genassym.c b/sys/arm64/arm64/genassym.c
index 8d75ffa..6d68d75 100644
--- a/sys/arm64/arm64/genassym.c
+++ b/sys/arm64/arm64/genassym.c
@@ -57,6 +57,7 @@ ASSYM(SF_UC, offsetof(struct sigframe, sf_uc));
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));
diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c
index 5f2d7e6..027c562 100644
--- a/sys/arm64/arm64/trap.c
+++ b/sys/arm64/arm64/trap.c
@@ -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, struct syscall_args *sa)
#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, uint64_t esr, uint64_t far, int lower)
}
#endif
- td = curthread;
pcb = td->td_pcb;
/*
@@ -258,7 +254,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;
@@ -273,8 +269,8 @@ 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:
@@ -286,7 +282,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
@@ -327,9 +323,8 @@ el0_excp_unknown(struct trapframe *frame, uint64_t far)
}
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;
@@ -338,9 +333,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) {
@@ -353,8 +345,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:
@@ -366,12 +358,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);
OpenPOWER on IntegriCloud