summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThaminda Edirisooriya <thaminda@google.com>2015-09-10 10:55:17 -0700
committerRonald G. Minnich <rminnich@gmail.com>2015-09-15 18:04:37 +0000
commitd9653e1328f8ec07bc1e1fc082f404130c2eee77 (patch)
tree894915bf5a1c8e1fcfba9c840234217e6e18848e
parent59598b2e475b50e359c821e35fe1ab60dfce641e (diff)
riscv-trap-handling: Add functionality, prevent stack corruption
Trap handling code was bugged in that it loaded in the wrong stack pointer, overwriting the space the processor uses to talk to its host for doing device requests. Fix this issue, as well as add support for handling misaligned loads the same way we handle misaligned stores. Change-Id: I68ba3a114b7167b3212bb0bed181a7595f0b97d8 Signed-off-by: Thaminda Edirisooriya <thaminda@google.com> Reviewed-on: http://review.coreboot.org/11620 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
-rw-r--r--src/arch/riscv/include/arch/exception.h2
-rw-r--r--src/arch/riscv/trap_handler.c29
-rw-r--r--src/arch/riscv/trap_util.S2
3 files changed, 31 insertions, 2 deletions
diff --git a/src/arch/riscv/include/arch/exception.h b/src/arch/riscv/include/arch/exception.h
index 4318cba8b6..28b9279707 100644
--- a/src/arch/riscv/include/arch/exception.h
+++ b/src/arch/riscv/include/arch/exception.h
@@ -55,7 +55,7 @@ static inline void exception_init(void)
void trap_handler(trapframe* tf);
void handle_supervisor_call(trapframe* tf);
-//void handleMisalignedLoad(trapframe *tf);
+void handleMisalignedLoad(trapframe *tf);
void handle_misaligned_store(trapframe *tf);
#endif
diff --git a/src/arch/riscv/trap_handler.c b/src/arch/riscv/trap_handler.c
index d4c9b87352..61480379b2 100644
--- a/src/arch/riscv/trap_handler.c
+++ b/src/arch/riscv/trap_handler.c
@@ -162,6 +162,35 @@ void trap_handler(trapframe *tf) {
while(1);
}
+void handleMisalignedLoad(trapframe *tf) {
+ printk(BIOS_DEBUG, "Trapframe ptr: %p\n", tf);
+ printk(BIOS_DEBUG, "Stored sp: %p\n", (void*) tf->gpr[2]);
+ insn_t faultingInstruction = 0;
+ uintptr_t faultingInstructionAddr = tf->epc;
+ asm("move t0, %0" : /* No outputs */ : "r"(faultingInstructionAddr));
+ asm("lw t0, 0(t0)");
+ asm("move %0, t0" : "=r"(faultingInstruction));
+ printk(BIOS_DEBUG, "Faulting instruction: 0x%x\n", faultingInstruction);
+ insn_t widthMask = 0x7000;
+ insn_t memWidth = (faultingInstruction & widthMask) >> 12;
+ insn_t destMask = 0xF80;
+ insn_t destRegister = (faultingInstruction & destMask) >> 7;
+ printk(BIOS_DEBUG, "Width: 0x%x\n", memWidth);
+ if (memWidth == 3) {
+ // load double, handle the issue
+ void* badAddress = (void*) tf->badvaddr;
+ memcpy(&(tf->gpr[destRegister]), badAddress, 8);
+ } else {
+ // panic, this should not have happened
+ printk(BIOS_DEBUG, "Code should not reach this path, misaligned on a non-64 bit store/load\n");
+ while(1);
+ }
+
+ // return to where we came from
+ write_csr(mepc, read_csr(mepc) + 4);
+ asm volatile("j machine_call_return");
+}
+
void handle_misaligned_store(trapframe *tf) {
printk(BIOS_DEBUG, "Trapframe ptr: %p\n", tf);
printk(BIOS_DEBUG, "Stored sp: %p\n", (void*) tf->gpr[2]);
diff --git a/src/arch/riscv/trap_util.S b/src/arch/riscv/trap_util.S
index 9701aaf1f6..274dca6960 100644
--- a/src/arch/riscv/trap_util.S
+++ b/src/arch/riscv/trap_util.S
@@ -112,7 +112,7 @@
supervisor_trap_entry:
csrw mscratch, sp
# load in the top of the machine stack
- la sp, 0x80FFF0
+ la sp, 0x80FFF0 - 64
1:addi sp,sp,-320
save_tf
move a0,sp