[arch][arm64] Add fault handler table
Allows executing an instruction with a custom fault recovery handler. Can be used with Load/Store Unprivileged to safely access user-space memory. Change-Id: If5390de06182e4d0409b30a8e6a1b93b7acc77b6
This commit is contained in:
committed by
Travis Geiselbrecht
parent
570791c5f1
commit
1b578624ee
@@ -27,6 +27,14 @@
|
||||
|
||||
#define SHUTDOWN_ON_FATAL 1
|
||||
|
||||
struct fault_handler_table_entry {
|
||||
uint64_t pc;
|
||||
uint64_t fault_handler;
|
||||
};
|
||||
|
||||
extern struct fault_handler_table_entry __fault_handler_table_start[];
|
||||
extern struct fault_handler_table_entry __fault_handler_table_end[];
|
||||
|
||||
static void dump_iframe(const struct arm64_iframe_long *iframe)
|
||||
{
|
||||
printf("iframe %p:\n", iframe);
|
||||
@@ -44,6 +52,7 @@ static void dump_iframe(const struct arm64_iframe_long *iframe)
|
||||
|
||||
void arm64_sync_exception(struct arm64_iframe_long *iframe)
|
||||
{
|
||||
struct fault_handler_table_entry *fault_handler;
|
||||
uint32_t esr = ARM64_READ_SYSREG(esr_el1);
|
||||
uint32_t ec = esr >> 26;
|
||||
uint32_t il = (esr >> 25) & 0x1;
|
||||
@@ -59,6 +68,13 @@ void arm64_sync_exception(struct arm64_iframe_long *iframe)
|
||||
}
|
||||
#endif
|
||||
|
||||
for (fault_handler = __fault_handler_table_start; fault_handler < __fault_handler_table_end; fault_handler++) {
|
||||
if (fault_handler->pc == iframe->elr) {
|
||||
iframe->elr = fault_handler->fault_handler;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
printf("sync_exception\n");
|
||||
dump_iframe(iframe);
|
||||
|
||||
|
||||
@@ -85,3 +85,12 @@ ldp \ra, \rb, [sp], #16
|
||||
cmp \tmp, \new_ptr_end
|
||||
b.lo .Lcalloc_bootmem_aligned_clear_loop\@
|
||||
.endm
|
||||
|
||||
/* Set fault handler for next instruction */
|
||||
.macro set_fault_handler, handler
|
||||
.Lfault_location\@:
|
||||
.pushsection .rodata.fault_handler_table
|
||||
.quad .Lfault_location\@
|
||||
.quad \handler
|
||||
.popsection
|
||||
.endm
|
||||
|
||||
@@ -48,6 +48,9 @@ SECTIONS
|
||||
|
||||
.rodata : ALIGN(8) {
|
||||
__rodata_start = .;
|
||||
__fault_handler_table_start = .;
|
||||
KEEP(*(.rodata.fault_handler_table))
|
||||
__fault_handler_table_end = .;
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
INCLUDE "arch/shared_rodata_sections.ld"
|
||||
. = ALIGN(8);
|
||||
|
||||
Reference in New Issue
Block a user