[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:
Arve Hjønnevåg
2015-07-16 18:10:03 -07:00
committed by Travis Geiselbrecht
parent 570791c5f1
commit 1b578624ee
3 changed files with 28 additions and 0 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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);