Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F154773027
D38984.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D38984.id.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D38984: arm64: add fault address to trapframe
Attached
Detach File
Event Timeline
Log In to Comment