[coreboot-gerrit] New patch to review for coreboot: riscv-trap-handling: add functionality and prevent stack corruption

Thaminda Edirisooriya (thaminda@google.com) gerrit at coreboot.org
Thu Sep 10 17:50:09 CET 2015


Thaminda Edirisooriya (thaminda at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11619

-gerrit

commit 688d96c1358ece8cf4d3acca0e04718f698f3a95
Author: Thaminda Edirisooriya <thaminda at google.com>
Date:   Thu Sep 10 10:46:20 2015 -0700

    riscv-trap-handling: add functionality and 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 it's host
    for doing device requests. Fix this issue, as well as add misaligned
    load handling to match misaligned store.
    
    Change-Id: I1a7d3d4ae4bb3cbccaad39b5b3c4fbc01b6b4336
    Signed-off-by: Thaminda Edirisooriya <thaminda at google.com>
---
 src/arch/riscv/include/arch/exception.h |  2 +-
 src/arch/riscv/trap_handler.c           | 29 +++++++++++++++++++++++++++++
 src/arch/riscv/trap_util.S              |  2 +-
 src/arch/riscv/virtual_memory.c         |  2 +-
 4 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/src/arch/riscv/include/arch/exception.h b/src/arch/riscv/include/arch/exception.h
index 4318cba..28b9279 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 d4c9b87..6148037 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 9701aaf..274dca6 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
diff --git a/src/arch/riscv/virtual_memory.c b/src/arch/riscv/virtual_memory.c
index 2095bfa..0163a45 100644
--- a/src/arch/riscv/virtual_memory.c
+++ b/src/arch/riscv/virtual_memory.c
@@ -107,7 +107,7 @@ void initVirtualMemory(void) {
 	printk(BIOS_DEBUG, "Initializing virtual memory...\n");
 	uintptr_t physicalStart = 0x1000000; // TODO: Figure out how to grab this from cbfs
 	uintptr_t virtualStart = 0xffffffff81000000;
-	uintptr_t pageTableStart = 0x1f0000;
+	uintptr_t pageTableStart = 0x1400000;
 	init_vm(virtualStart, physicalStart, pageTableStart);
 	mb();
 	printk(BIOS_DEBUG, "Finished initializing virtual memory, starting walk...\n");



More information about the coreboot-gerrit mailing list