summaryrefslogtreecommitdiffstats
path: root/include/linux/efi.h
diff options
context:
space:
mode:
authorSai Praneeth2018-09-11 21:15:22 +0200
committerArd Biesheuvel2018-09-26 12:14:55 +0200
commit3425d934fc0312f62024163736a7afe4de20c10f (patch)
treeb7127ae04326c7e9bab17c8c812d5bb21b527827 /include/linux/efi.h
parentefi: Make efi_rts_work accessible to efi page fault handler (diff)
downloadkernel-qcow2-linux-3425d934fc0312f62024163736a7afe4de20c10f.tar.gz
kernel-qcow2-linux-3425d934fc0312f62024163736a7afe4de20c10f.tar.xz
kernel-qcow2-linux-3425d934fc0312f62024163736a7afe4de20c10f.zip
efi/x86: Handle page faults occurring while running EFI runtime services
Memory accesses performed by UEFI runtime services should be limited to: - reading/executing from EFI_RUNTIME_SERVICES_CODE memory regions - reading/writing from/to EFI_RUNTIME_SERVICES_DATA memory regions - reading/writing by-ref arguments - reading/writing from/to the stack. Accesses outside these regions may cause the kernel to hang because the memory region requested by the firmware isn't mapped in efi_pgd, which causes a page fault in ring 0 and the kernel fails to handle it, leading to die(). To save kernel from hanging, add an EFI specific page fault handler which recovers from such faults by 1. If the efi runtime service is efi_reset_system(), reboot the machine through BIOS. 2. If the efi runtime service is _not_ efi_reset_system(), then freeze efi_rts_wq and schedule a new process. The EFI page fault handler offers us two advantages: 1. Avoid potential hangs caused by buggy firmware. 2. Shout loud that the firmware is buggy and hence is not a kernel bug. Tested-by: Bhupesh Sharma <bhsharma@redhat.com> Suggested-by: Matt Fleming <matt@codeblueprint.co.uk> Based-on-code-from: Ricardo Neri <ricardo.neri@intel.com> Signed-off-by: Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> [ardb: clarify commit log] Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Diffstat (limited to 'include/linux/efi.h')
-rw-r--r--include/linux/efi.h8
1 files changed, 7 insertions, 1 deletions
diff --git a/include/linux/efi.h b/include/linux/efi.h
index a929d2bf41fa..845174e113ce 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1662,8 +1662,13 @@ struct linux_efi_tpm_eventlog {
extern int efi_tpm_eventlog_init(void);
-/* efi_runtime_service() function identifiers */
+/*
+ * efi_runtime_service() function identifiers.
+ * "NONE" is used by efi_recover_from_page_fault() to check if the page
+ * fault happened while executing an efi runtime service.
+ */
enum efi_rts_ids {
+ NONE,
GET_TIME,
SET_TIME,
GET_WAKEUP_TIME,
@@ -1673,6 +1678,7 @@ enum efi_rts_ids {
SET_VARIABLE,
QUERY_VARIABLE_INFO,
GET_NEXT_HIGH_MONO_COUNT,
+ RESET_SYSTEM,
UPDATE_CAPSULE,
QUERY_CAPSULE_CAPS,
};