Page MenuHomeFreeBSD

D38984.id.diff
No OneTemporary

D38984.id.diff

diff --git a/sys/arm64/arm64/exception.S b/sys/arm64/arm64/exception.S
--- a/sys/arm64/arm64/exception.S
+++ b/sys/arm64/arm64/exception.S
@@ -65,9 +65,10 @@
mrs x10, elr_el1
mrs x11, spsr_el1
mrs x12, esr_el1
+ mrs x13, far_el1
stp x18, lr, [sp, #(TF_SP - TF_X)]!
- str x10, [sp, #(TF_ELR)]
- stp x11, x12, [sp, #(TF_SPSR)]
+ stp x10, x11, [sp, #(TF_ELR)]
+ stp x12, x13, [sp, #(TF_ESR)]
mrs x18, tpidr_el1
.endm
@@ -211,25 +212,10 @@
END(handle_el1h_irq)
ENTRY(handle_el0_sync)
- /*
- * Read the fault address early. The current thread structure may
- * be transiently unmapped if it is part of a memory range being
- * promoted or demoted to/from a superpage. As this involves a
- * break-before-make sequence there is a short period of time where
- * an access will raise an exception. If this happens the fault
- * address will be changed to the kernel address so a later read of
- * far_el1 will give the wrong value.
- *
- * The earliest memory access that could trigger a fault is in a
- * function called by the save_registers macro so this is the latest
- * we can read the userspace value.
- */
- mrs x19, far_el1
save_registers 0
ldr x0, [x18, #PC_CURTHREAD]
mov x1, sp
str x1, [x0, #TD_FRAME]
- mov x2, x19
bl do_el0_sync
do_ast
restore_registers 0
diff --git a/sys/arm64/arm64/genassym.c b/sys/arm64/arm64/genassym.c
--- a/sys/arm64/arm64/genassym.c
+++ b/sys/arm64/arm64/genassym.c
@@ -77,4 +77,5 @@
ASSYM(TF_SP, offsetof(struct trapframe, tf_sp));
ASSYM(TF_ELR, offsetof(struct trapframe, tf_elr));
ASSYM(TF_SPSR, offsetof(struct trapframe, tf_spsr));
+ASSYM(TF_ESR, offsetof(struct trapframe, tf_esr));
ASSYM(TF_X, offsetof(struct trapframe, tf_x));
diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c
--- a/sys/arm64/arm64/trap.c
+++ b/sys/arm64/arm64/trap.c
@@ -76,7 +76,7 @@
/* Called from exception.S */
void do_el1h_sync(struct thread *, struct trapframe *);
-void do_el0_sync(struct thread *, struct trapframe *, uint64_t far);
+void do_el0_sync(struct thread *, struct trapframe *);
void do_el0_error(struct trapframe *);
void do_serror(struct trapframe *);
void unhandled_exception(struct trapframe *);
@@ -465,6 +465,7 @@
uint64_t esr, far;
int dfsc;
+ far = frame->tf_far;
/* Read the esr register to get the exception details */
esr = frame->tf_esr;
exception = ESR_ELx_EXCEPTION(esr);
@@ -502,7 +503,6 @@
break;
case EXCP_INSN_ABORT:
case EXCP_DATA_ABORT:
- far = READ_SPECIALREG(far_el1);
dfsc = esr & ISS_DATA_DFSC_MASK;
if (dfsc < nitems(abort_handlers) &&
abort_handlers[dfsc] != NULL) {
@@ -541,7 +541,7 @@
case EXCP_FPAC:
/* We can see this if the authentication on PAC fails */
print_registers(frame);
- printf(" far: %16lx\n", READ_SPECIALREG(far_el1));
+ print_gp_register("far", far);
panic("FPAC kernel exception");
break;
case EXCP_UNKNOWN:
@@ -552,18 +552,18 @@
/* FALLTHROUGH */
default:
print_registers(frame);
- print_gp_register("far", READ_SPECIALREG(far_el1));
+ print_gp_register("far", far);
panic("Unknown kernel exception %x esr_el1 %lx", exception,
esr);
}
}
void
-do_el0_sync(struct thread *td, struct trapframe *frame, uint64_t far)
+do_el0_sync(struct thread *td, struct trapframe *frame)
{
pcpu_bp_harden bp_harden;
uint32_t exception;
- uint64_t esr;
+ uint64_t esr, far;
int dfsc;
/* Check we have a sane environment when entering from userland */
@@ -571,6 +571,7 @@
("Invalid pcpu address from userland: %p (tpidr %lx)",
get_pcpu(), READ_SPECIALREG(tpidr_el1)));
+ far = frame->tf_far;
esr = frame->tf_esr;
exception = ESR_ELx_EXCEPTION(esr);
if (exception == EXCP_INSN_ABORT_L && far > VM_MAXUSER_ADDRESS) {
@@ -711,7 +712,7 @@
{
uint64_t esr, far;
- far = READ_SPECIALREG(far_el1);
+ far = frame->tf_far;
esr = frame->tf_esr;
print_registers(frame);
@@ -725,7 +726,7 @@
{
uint64_t esr, far;
- far = READ_SPECIALREG(far_el1);
+ far = frame->tf_far;
esr = frame->tf_esr;
print_registers(frame);
diff --git a/sys/arm64/include/frame.h b/sys/arm64/include/frame.h
--- a/sys/arm64/include/frame.h
+++ b/sys/arm64/include/frame.h
@@ -47,7 +47,7 @@
uint64_t tf_elr;
uint64_t tf_spsr;
uint64_t tf_esr;
- uint64_t pad; /* struct must be 16B aligned */
+ uint64_t tf_far;
uint64_t tf_x[30];
};

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 30, 10:16 AM (12 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32495452
Default Alt Text
D38984.id.diff (4 KB)

Event Timeline