diff mbox series

[1/1] riscv: restore global data pointer in trap handler

Message ID 20200926065139.25331-1-xypron.glpk@gmx.de
State Superseded
Delegated to: Andes
Headers show
Series [1/1] riscv: restore global data pointer in trap handler | expand

Commit Message

Heinrich Schuchardt Sept. 26, 2020, 6:51 a.m. UTC
The gp register is used to store U-Boot's global data pointer. We should
not assume that an UEFI application leaves the gp register unchanged as
the UEFI specifications does not define who is the owner of the gp and tp
registers.

So the following sequence should be followed in the trap handler:

* save the caller's gp register
* restore the global data pointer
* serve interrupts or print crash dump and reset
* restore the caller's gp register

Cc: Abner Chang <abner.chang@hpe.com>
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
 arch/riscv/lib/interrupts.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

--
2.28.0
diff mbox series

Patch

diff --git a/arch/riscv/lib/interrupts.c b/arch/riscv/lib/interrupts.c
index cd47e64487..11505c8655 100644
--- a/arch/riscv/lib/interrupts.c
+++ b/arch/riscv/lib/interrupts.c
@@ -110,6 +110,16 @@  int disable_interrupts(void)
 ulong handle_trap(ulong cause, ulong epc, ulong tval, struct pt_regs *regs)
 {
 	ulong is_irq, irq;
+	volatile gd_t *caller_gd;
+
+	/*
+	 * An UEFI application may have changed gd.
+	 * Save the caller's gd. Restore U-Boot's gd.
+	 */
+	if (CONFIG_IS_ENABLED(EFI_LOADER)) {
+		caller_gd = gd;
+		efi_restore_gd();
+	}

 	is_irq = (cause & MCAUSE_INT);
 	irq = (cause & ~MCAUSE_INT);
@@ -132,6 +142,9 @@  ulong handle_trap(ulong cause, ulong epc, ulong tval, struct pt_regs *regs)
 		_exit_trap(cause, epc, tval, regs);
 	}

+	if (CONFIG_IS_ENABLED(EFI_LOADER))
+		set_gd(caller_gd);
+
 	return epc;
 }