Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp896394imm; Sun, 2 Sep 2018 02:52:42 -0700 (PDT) X-Google-Smtp-Source: ANB0Vdb+/6A5p1y12pPi0LQcudPyF+VixgXWRPcIDi+5glPHd89f0NjGwpamDwu5YGAWTXOTrMdR X-Received: by 2002:a63:5055:: with SMTP id q21-v6mr21602116pgl.397.1535881962816; Sun, 02 Sep 2018 02:52:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535881962; cv=none; d=google.com; s=arc-20160816; b=Q+ZYbKp8jyuQcciE6vRpImSDlM9iXrddIKxWUT+rNzxkmwkBgn2G87goef+lXJHfy9 aWYSENuKBB2FMSsCFAmCJ+JtB7Y3FPpyUrvxT+nUMJ42WVq/YF08UXjdSpabro2wKOtp VjnhxgRdl/hLqEoTOM43yOEMbKU/dbzR1YmAKLBvUsdU2vp/mOhhFhHaXjeOa24KUVzl nT4I+GcNJdSZFafoLyuCebTX0ScvBFZP92biSkeU3igU7R1P76PQzlIBpshcLPRMz2d0 8K6C1HTnH76cb6vhkgvwGiVZE18lDFkM9GbXnCpl4TBeKTSvfgho5mBJFVB9KYwG8Ijd 82Dw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :arc-authentication-results; bh=zXALBMr3746+mY7tBWPpAAVIINNMMBYU5wHm8bTZSms=; b=VcqYattSv4vgSJQ0aA5unUMnWh4nycnkuOltehUyQKJp0eiw+C9aT03+BqRXe1I5nc 0OIJZHsABinW+IYOqxR+ndiDbdkFBGqYVuwO83KpWEvhnU4mHM7K5wMhmJnrdpYqO2Gx fewSZumK4qOe1nScwfv87rqRigI4BiQNqJCNj043b40XDI2cfwBZqtuPGoyhdMw8jcFf ejKC4mgbyG/s6CT8lIVLHTyhsEIOhEg3RzIz6cUSspdzprByvC0N1TriA9Uty2B8Z6K6 3G6LuR8desCo39an6pyDKQ7E1dFulKzpucCoKs09Saxk83rzDjMsqNkg+5AZzO/EXMrp 25yw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g31-v6si14643884pld.158.2018.09.02.02.52.27; Sun, 02 Sep 2018 02:52:42 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726600AbeIBOC4 (ORCPT + 99 others); Sun, 2 Sep 2018 10:02:56 -0400 Received: from mga07.intel.com ([134.134.136.100]:58895 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726006AbeIBOCz (ORCPT ); Sun, 2 Sep 2018 10:02:55 -0400 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 02 Sep 2018 02:47:45 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,319,1531810800"; d="scan'208";a="69718287" Received: from sai-dev-mach.sc.intel.com ([143.183.140.52]) by orsmga007.jf.intel.com with ESMTP; 02 Sep 2018 02:47:45 -0700 From: Sai Praneeth Prakhya To: linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org Cc: ricardo.neri@intel.com, matt@codeblueprint.co.uk, Sai Praneeth , Lee Chun-Yi , Al Stone , Borislav Petkov , Ingo Molnar , Andy Lutomirski , Bhupesh Sharma , Peter Zijlstra , Ard Biesheuvel Subject: [PATCH V2 0/6] Add efi page fault handler to fix/recover from Date: Sun, 2 Sep 2018 02:46:28 -0700 Message-Id: <1535881594-25469-1-git-send-email-sai.praneeth.prakhya@intel.com> X-Mailer: git-send-email 2.7.4 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Sai Praneeth There may exist some buggy UEFI firmware implementations that access efi memory regions other than EFI_RUNTIME_SERVICES_ even after the kernel has assumed control of the platform. This violates UEFI specification. Hence, provide a debug config option which when enabled detects and fixes/recovers from page faults caused by buggy firmware. The above said illegal accesses trigger page fault in ring 0 because firmware executes at ring 0 and if unhandled it hangs the kernel. We provide an efi specific page fault handler to: 1. Avoid panics/hangs caused by buggy firmware. 2. Shout loud that the firmware is buggy and hence is not a kernel bug. Depending on the illegally accessed efi region, the efi page fault handler handles illegal accesses differently. 1. If the illegally accessed region is EFI_BOOT_SERVICES_, the efi page fault handler fixes it up by mapping the requested region. 2. If any other region (Eg: EFI_CONVENTIONAL_MEMORY or EFI_LOADER_), then the efi page fault handler freezes efi_rts_wq and schedules a new process. 3. If the access is to any other efi region like above but if the efi runtime service is efi_reset_system(), then the efi page fault handler will reboot the machine through BIOS. Illegal accesses to EFI_BOOT_SERVICES_ and to other regions are dealt differently in efi page fault handler because, *generally* EFI_BOOT_SERVICES_ regions are smaller in size relative to other efi regions and hence could be reserved and can be dynamically mapped. But other EFI regions like EFI_CONVENTIONAL_MEMORY and EFI_LOADER_ cannot be reserved as they are very huge in size and reserving them will make the kernel un-bootable. This issue was reported by Al Stone when he saw that reboot via EFI hangs the machine. Upon debugging, I found that it's efi_reset_system() that's touching memory regions which it shouldn't. To reproduce the same behavior, I have hacked OVMF and made efi_reset_system() buggy. Along with efi_reset_system(), I have also modified get_next_high_mono_count() and set_virtual_address_map(). They illegally access both boot time and other efi regions. Testing the patch set: ---------------------- 1. Download buggy firmware from here [1]. 2. Run a qemu instance with this buggy BIOS and boot mainline kernel. Add reboot=efi to the kernel command line arguments and after the kernel is up and running, type "reboot". The kernel should hang while rebooting. 3. With the same setup, boot kernel after applying patches and the reboot should work fine. Also please notice warning/error messages printed by kernel. Changes from RFC to V1: ----------------------- 1. Drop "long jump" technique of dealing with illegal access and instead use scheduling away from efi_rts_wq. Changes from V1 to V2: ----------------------- 1. Shortened config name to CONFIG_EFI_WARN_ON_ILLEGAL_ACCESS from CONFIG_EFI_WARN_ON_ILLEGAL_ACCESSES. 2. Made the config option available only to expert users. 3. efi_free_boot_services() should be called only when CONFIG_EFI_WARN_ON_ILLEGAL_ACCESS is not enabled. Previously, this was part of init/main.c file. As it is an architecture agnostic code, moved the change to arch/x86/platform/efi/quirks.c file. Note: ----- Patch set based on "next" branch in efi tree. [1] https://drive.google.com/drive/folders/1VozKTms92ifyVHAT0ZDQe55ZYL1UE5wt Sai Praneeth (6): efi: Make efi_rts_work accessible to efi page fault handler x86/efi: Remove __init attribute from memory mapping functions x86/efi: Permanently save the EFI_MEMORY_MAP passed by the firmware x86/efi: Add efi page fault handler to fixup/recover from page faults caused by firmware x86/mm: If in_atomic(), allocate pages without sleeping x86/efi: Introduce EFI_WARN_ON_ILLEGAL_ACCESS arch/x86/Kconfig | 21 ++++ arch/x86/include/asm/efi.h | 24 +++- arch/x86/mm/fault.c | 9 ++ arch/x86/mm/pageattr.c | 16 ++- arch/x86/platform/efi/efi.c | 10 +- arch/x86/platform/efi/efi_32.c | 2 +- arch/x86/platform/efi/efi_64.c | 9 +- arch/x86/platform/efi/quirks.c | 204 ++++++++++++++++++++++++++++++++ drivers/firmware/efi/efi.c | 6 +- drivers/firmware/efi/runtime-wrappers.c | 60 +++------- include/linux/efi.h | 53 ++++++++- 11 files changed, 351 insertions(+), 63 deletions(-) Suggested-by: Matt Fleming Based-on-code-from: Ricardo Neri Signed-off-by: Sai Praneeth Prakhya Cc: Lee Chun-Yi Cc: Al Stone Cc: Borislav Petkov Cc: Ingo Molnar Cc: Andy Lutomirski Cc: Bhupesh Sharma Cc: Peter Zijlstra Cc: Ard Biesheuvel -- 2.7.4