]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
efi/arm64: Check whether x18 is preserved by runtime services calls
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Thu, 8 Mar 2018 08:00:13 +0000 (08:00 +0000)
committerIngo Molnar <mingo@kernel.org>
Fri, 9 Mar 2018 07:58:22 +0000 (08:58 +0100)
Whether or not we will ever decide to start using x18 as a platform
register in Linux is uncertain, but by that time, we will need to
ensure that UEFI runtime services calls don't corrupt it.

So let's start issuing warnings now for this, and increase the
likelihood that these firmware images have all been replaced by that time.

This has been fixed on the EDK2 side in commit:

  6d73863b5464 ("BaseTools/tools_def AARCH64: mark register x18 as reserved")

dated July 13, 2017.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Acked-by: Will Deacon <will.deacon@arm.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Matt Fleming <matt@codeblueprint.co.uk>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: http://lkml.kernel.org/r/20180308080020.22828-6-ard.biesheuvel@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/arm64/include/asm/efi.h
arch/arm64/kernel/Makefile
arch/arm64/kernel/efi-rt-wrapper.S [new file with mode: 0644]
arch/arm64/kernel/efi.c

index 8389050328bba2c272b2fe7c6818083ff206d908..192d791f11036747704fedbc0839b37a4c1e49fc 100644 (file)
@@ -31,7 +31,7 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
 ({                                                                     \
        efi_##f##_t *__f;                                               \
        __f = p->f;                                                     \
-       __f(args);                                                      \
+       __efi_rt_asm_wrapper(__f, #f, args);                            \
 })
 
 #define arch_efi_call_virt_teardown()                                  \
@@ -40,6 +40,8 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
        efi_virtmap_unload();                                           \
 })
 
+efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...);
+
 #define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT)
 
 /* arch specific definitions used by the stub code */
index b87541360f43824e6df20961af87a3154f1f7c0f..6a4bd80c75bd2a7a10c960b7b3752f1b0820f12c 100644 (file)
@@ -38,7 +38,8 @@ arm64-obj-$(CONFIG_CPU_PM)            += sleep.o suspend.o
 arm64-obj-$(CONFIG_CPU_IDLE)           += cpuidle.o
 arm64-obj-$(CONFIG_JUMP_LABEL)         += jump_label.o
 arm64-obj-$(CONFIG_KGDB)               += kgdb.o
-arm64-obj-$(CONFIG_EFI)                        += efi.o efi-entry.stub.o
+arm64-obj-$(CONFIG_EFI)                        += efi.o efi-entry.stub.o               \
+                                          efi-rt-wrapper.o
 arm64-obj-$(CONFIG_PCI)                        += pci.o
 arm64-obj-$(CONFIG_ARMV8_DEPRECATED)   += armv8_deprecated.o
 arm64-obj-$(CONFIG_ACPI)               += acpi.o
diff --git a/arch/arm64/kernel/efi-rt-wrapper.S b/arch/arm64/kernel/efi-rt-wrapper.S
new file mode 100644 (file)
index 0000000..05235eb
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2018 Linaro Ltd <ard.biesheuvel@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/linkage.h>
+
+ENTRY(__efi_rt_asm_wrapper)
+       stp     x29, x30, [sp, #-32]!
+       mov     x29, sp
+
+       /*
+        * Register x18 is designated as the 'platform' register by the AAPCS,
+        * which means firmware running at the same exception level as the OS
+        * (such as UEFI) should never touch it.
+        */
+       stp     x1, x18, [sp, #16]
+
+       /*
+        * We are lucky enough that no EFI runtime services take more than
+        * 5 arguments, so all are passed in registers rather than via the
+        * stack.
+        */
+       mov     x8, x0
+       mov     x0, x2
+       mov     x1, x3
+       mov     x2, x4
+       mov     x3, x5
+       mov     x4, x6
+       blr     x8
+
+       ldp     x1, x2, [sp, #16]
+       cmp     x2, x18
+       ldp     x29, x30, [sp], #32
+       b.ne    0f
+       ret
+0:     b       efi_handle_corrupted_x18        // tail call
+ENDPROC(__efi_rt_asm_wrapper)
index a8bf1c892b9065ca40ed4b263317deced2b8d693..4f9acb5fbe97053504d2d61c60a083093f1382f0 100644 (file)
@@ -126,3 +126,9 @@ bool efi_poweroff_required(void)
 {
        return efi_enabled(EFI_RUNTIME_SERVICES);
 }
+
+asmlinkage efi_status_t efi_handle_corrupted_x18(efi_status_t s, const char *f)
+{
+       pr_err_ratelimited(FW_BUG "register x18 corrupted by EFI %s\n", f);
+       return s;
+}