From fa19730c61ba1d365daf5d8684142492b78017a2 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Wed, 1 May 2019 17:12:49 +0000 Subject: [PATCH] Restore x18 in efi_arch_leave. Some UEFI implementations trash this register and, as we use it as a platform register, the kernel doesn't save it before calling into the UEFI runtime services. As we have a copy in tpidr_el1 restore from there when exiting the EFI environment. PR: 237234, 237055 Reviewed by: manu Tested On: Ampere eMAG MFC after: 2 weeks Sponsored by: DARPA, AFRL Sponsored by: Ampere Computing (hardware) Differential Revision: https://reviews.freebsd.org/D20127 --- sys/arm64/arm64/efirt_machdep.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sys/arm64/arm64/efirt_machdep.c b/sys/arm64/arm64/efirt_machdep.c index cf092ff0dab7..545d93b66ed0 100644 --- a/sys/arm64/arm64/efirt_machdep.c +++ b/sys/arm64/arm64/efirt_machdep.c @@ -259,6 +259,16 @@ efi_arch_leave(void) { struct thread *td; + /* + * Restore the pcpu pointer. Some UEFI implementations trash it and + * we don't store it before calling into them. To fix this we need + * to restore it after returning to the kernel context. As reading + * curthread will access x18 we need to restore it before loading + * the thread pointer. + */ + __asm __volatile( + "mrs x18, tpidr_el1 \n" + ); td = curthread; __asm __volatile( "msr ttbr0_el1, %0 \n"