Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1460384 > unrolled thread

[GIT PULL 0/2] EFI urgent fixes

Started byMatt Fleming <matt@codeblueprint.co.uk>
First post2016-08-11 12:50 +0200
Last post2016-08-11 18:30 +0200
Articles 5 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [GIT PULL 0/2] EFI urgent fixes Matt Fleming <matt@codeblueprint.co.uk> - 2016-08-11 12:50 +0200
    [PATCH 2/2] efi/capsule: Allocate whole capsule into virtual memory Matt Fleming <matt@codeblueprint.co.uk> - 2016-08-11 12:50 +0200
      [tip:efi/urgent] efi/capsule: Allocate whole capsule into virtual  memory tip-bot for Austin Christ <tipbot@zytor.com> - 2016-08-11 18:30 +0200
    [PATCH 1/2] x86/platform/uv: Skip UV runtime services mapping in the efi_runtime_disabled case Matt Fleming <matt@codeblueprint.co.uk> - 2016-08-11 12:50 +0200
      [tip:efi/urgent] x86/platform/uv: Skip UV runtime services mapping  in the efi_runtime_disabled case tip-bot for Alex Thorlton <tipbot@zytor.com> - 2016-08-11 18:30 +0200

#1460384 — [GIT PULL 0/2] EFI urgent fixes

FromMatt Fleming <matt@codeblueprint.co.uk>
Date2016-08-11 12:50 +0200
Subject[GIT PULL 0/2] EFI urgent fixes
Message-ID<s4VIJ-2F7-5@gated-at.bofh.it>
Please pull the following two patches that fix EFI issues in v4.7.
They're both tagged for stable.

The following changes since commit 29b4817d4018df78086157ea3a55c1d9424a7cfc:

  Linux 4.8-rc1 (2016-08-07 18:18:00 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi.git tags/efi-urgent

for you to fetch changes up to be6743b7f66c7d8bf7f8a48de9d86a66a177c3a2:

  efi/capsule: Allocate whole capsule into virtual memory (2016-08-09 11:32:55 +0100)

----------------------------------------------------------------
 * Fix a boot crash on SGI/UV when kexec'ing a kernel with the "noefi"
   kernel parameter - Alex Thorlton

 * Wholly map EFI capsules with vmap() instead of just the first page
   with kmap(), so that the capsule driver works on Qualcomm QDF2432,
   and because the UEFI specification requires the capsule to be fully
   mapped into the kernel's virtual address space - Austin Christ

----------------------------------------------------------------
Alex Thorlton (1):
      x86/platform/uv: Skip UV runtime services mapping in the efi_runtime_disabled case

Austin Christ (1):
      efi/capsule: Allocate whole capsule into virtual memory

 arch/x86/platform/uv/bios_uv.c        | 3 ++-
 drivers/firmware/efi/capsule-loader.c | 8 +++++---
 drivers/firmware/efi/capsule.c        | 6 +++---
 3 files changed, 10 insertions(+), 7 deletions(-)

[toc] | [next] | [standalone]


#1460386 — [PATCH 2/2] efi/capsule: Allocate whole capsule into virtual memory

FromMatt Fleming <matt@codeblueprint.co.uk>
Date2016-08-11 12:50 +0200
Subject[PATCH 2/2] efi/capsule: Allocate whole capsule into virtual memory
Message-ID<s4VIJ-2F7-11@gated-at.bofh.it>
In reply to#1460384
From: Austin Christ <austinwc@codeaurora.org>

According to UEFI 2.6 section 7.5.3, the capsule should be in contiguous
virtual memory and firmware may consume the capsule immediately. To
correctly implement this functionality, the kernel driver needs to vmap
the entire capsule at the time it is made available to firmware.

The virtual allocation of the capsule update has been changed from kmap,
which was only allocating the first page of the update, to vmap, and
allocates the entire data payload.

Signed-off-by: Austin Christ <austinwc@codeaurora.org>
Reviewed-by: Matt Fleming <matt@codeblueprint.co.uk>
Reviewed-by: Lee, Chun-Yi <jlee@suse.com>
Cc: Bryan O'Donoghue <pure.logic@nexus-software.ie>
Cc: Kweh Hock Leong <hock.leong.kweh@intel.com>
Cc: <stable@vger.kernel.org> # v4.7
Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
---
 drivers/firmware/efi/capsule-loader.c | 8 +++++---
 drivers/firmware/efi/capsule.c        | 6 +++---
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c
index c99c24bc79b0..9ae6c116c474 100644
--- a/drivers/firmware/efi/capsule-loader.c
+++ b/drivers/firmware/efi/capsule-loader.c
@@ -16,6 +16,7 @@
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/efi.h>
+#include <linux/vmalloc.h>
 
 #define NO_FURTHER_WRITE_ACTION -1
 
@@ -108,14 +109,15 @@ static ssize_t efi_capsule_submit_update(struct capsule_info *cap_info)
 	int ret;
 	void *cap_hdr_temp;
 
-	cap_hdr_temp = kmap(cap_info->pages[0]);
+	cap_hdr_temp = vmap(cap_info->pages, cap_info->index,
+			VM_MAP, PAGE_KERNEL);
 	if (!cap_hdr_temp) {
-		pr_debug("%s: kmap() failed\n", __func__);
+		pr_debug("%s: vmap() failed\n", __func__);
 		return -EFAULT;
 	}
 
 	ret = efi_capsule_update(cap_hdr_temp, cap_info->pages);
-	kunmap(cap_info->pages[0]);
+	vunmap(cap_hdr_temp);
 	if (ret) {
 		pr_err("%s: efi_capsule_update() failed\n", __func__);
 		return ret;
diff --git a/drivers/firmware/efi/capsule.c b/drivers/firmware/efi/capsule.c
index 53b9fd2293ee..6eedff45e6d7 100644
--- a/drivers/firmware/efi/capsule.c
+++ b/drivers/firmware/efi/capsule.c
@@ -190,9 +190,9 @@ efi_capsule_update_locked(efi_capsule_header_t *capsule,
  * map the capsule described by @capsule with its data in @pages and
  * send it to the firmware via the UpdateCapsule() runtime service.
  *
- * @capsule must be a virtual mapping of the first page in @pages
- * (@pages[0]) in the kernel address space. That is, a
- * capsule_header_t that describes the entire contents of the capsule
+ * @capsule must be a virtual mapping of the complete capsule update in the
+ * kernel address space, as the capsule can be consumed immediately.
+ * A capsule_header_t that describes the entire contents of the capsule
  * must be at the start of the first data page.
  *
  * Even though this function will validate that the firmware supports
-- 
2.7.3

[toc] | [prev] | [next] | [standalone]


#1460667 — [tip:efi/urgent] efi/capsule: Allocate whole capsule into virtual memory

Fromtip-bot for Austin Christ <tipbot@zytor.com>
Date2016-08-11 18:30 +0200
Subject[tip:efi/urgent] efi/capsule: Allocate whole capsule into virtual memory
Message-ID<s511N-6al-79@gated-at.bofh.it>
In reply to#1460386
Commit-ID:  6862e6ad95e984991a6ceec592cf67831658f928
Gitweb:     http://git.kernel.org/tip/6862e6ad95e984991a6ceec592cf67831658f928
Author:     Austin Christ <austinwc@codeaurora.org>
AuthorDate: Thu, 11 Aug 2016 11:42:00 +0100
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Thu, 11 Aug 2016 13:55:36 +0200

efi/capsule: Allocate whole capsule into virtual memory

According to UEFI 2.6 section 7.5.3, the capsule should be in contiguous
virtual memory and firmware may consume the capsule immediately. To
correctly implement this functionality, the kernel driver needs to vmap
the entire capsule at the time it is made available to firmware.

The virtual allocation of the capsule update has been changed from kmap,
which was only allocating the first page of the update, to vmap, and
allocates the entire data payload.

Signed-off-by: Austin Christ <austinwc@codeaurora.org>
Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
Reviewed-by: Matt Fleming <matt@codeblueprint.co.uk>
Reviewed-by: Lee, Chun-Yi <jlee@suse.com>
Cc: <stable@vger.kernel.org> # v4.7
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Bryan O'Donoghue <pure.logic@nexus-software.ie>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kweh Hock Leong <hock.leong.kweh@intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: http://lkml.kernel.org/r/1470912120-22831-3-git-send-email-matt@codeblueprint.co.uk
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 drivers/firmware/efi/capsule-loader.c | 8 +++++---
 drivers/firmware/efi/capsule.c        | 6 +++---
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c
index c99c24b..9ae6c11 100644
--- a/drivers/firmware/efi/capsule-loader.c
+++ b/drivers/firmware/efi/capsule-loader.c
@@ -16,6 +16,7 @@
 #include <linux/slab.h>
 #include <linux/mutex.h>
 #include <linux/efi.h>
+#include <linux/vmalloc.h>
 
 #define NO_FURTHER_WRITE_ACTION -1
 
@@ -108,14 +109,15 @@ static ssize_t efi_capsule_submit_update(struct capsule_info *cap_info)
 	int ret;
 	void *cap_hdr_temp;
 
-	cap_hdr_temp = kmap(cap_info->pages[0]);
+	cap_hdr_temp = vmap(cap_info->pages, cap_info->index,
+			VM_MAP, PAGE_KERNEL);
 	if (!cap_hdr_temp) {
-		pr_debug("%s: kmap() failed\n", __func__);
+		pr_debug("%s: vmap() failed\n", __func__);
 		return -EFAULT;
 	}
 
 	ret = efi_capsule_update(cap_hdr_temp, cap_info->pages);
-	kunmap(cap_info->pages[0]);
+	vunmap(cap_hdr_temp);
 	if (ret) {
 		pr_err("%s: efi_capsule_update() failed\n", __func__);
 		return ret;
diff --git a/drivers/firmware/efi/capsule.c b/drivers/firmware/efi/capsule.c
index 53b9fd2..6eedff4 100644
--- a/drivers/firmware/efi/capsule.c
+++ b/drivers/firmware/efi/capsule.c
@@ -190,9 +190,9 @@ efi_capsule_update_locked(efi_capsule_header_t *capsule,
  * map the capsule described by @capsule with its data in @pages and
  * send it to the firmware via the UpdateCapsule() runtime service.
  *
- * @capsule must be a virtual mapping of the first page in @pages
- * (@pages[0]) in the kernel address space. That is, a
- * capsule_header_t that describes the entire contents of the capsule
+ * @capsule must be a virtual mapping of the complete capsule update in the
+ * kernel address space, as the capsule can be consumed immediately.
+ * A capsule_header_t that describes the entire contents of the capsule
  * must be at the start of the first data page.
  *
  * Even though this function will validate that the firmware supports

[toc] | [prev] | [next] | [standalone]


#1460395 — [PATCH 1/2] x86/platform/uv: Skip UV runtime services mapping in the efi_runtime_disabled case

FromMatt Fleming <matt@codeblueprint.co.uk>
Date2016-08-11 12:50 +0200
Subject[PATCH 1/2] x86/platform/uv: Skip UV runtime services mapping in the efi_runtime_disabled case
Message-ID<s4VIJ-2F7-31@gated-at.bofh.it>
In reply to#1460384
From: Alex Thorlton <athorlton@sgi.com>

This problem has actually been in the UV code for a while, but we didn't
catch it until recently, because we had been relying on EFI_OLD_MEMMAP
to allow our systems to boot for a period of time.  We noticed the issue
when trying to kexec a recent community kernel, where we hit this NULL
pointer dereference in efi_sync_low_kernel_mappings:

[    0.337515] BUG: unable to handle kernel NULL pointer dereference at 0000000000000880
[    0.346276] IP: [<ffffffff8105df8d>] efi_sync_low_kernel_mappings+0x5d/0x1b0

The problem doesn't show up with EFI_OLD_MEMMAP because we skip the
chunk of setup_efi_state that sets the efi_loader_signature for the
kexec'd kernel.  When the kexec'd kernel boots, it won't set EFI_BOOT in
setup_arch, so we completely avoid the bug.

We always kexec with noefi on the command line, so this shouldn't be an
issue, but since we're not actually checking for efi_runtime_disabled in
uv_bios_init, we end up trying to do EFI runtime callbacks when we
shouldn't be. This patch just adds a check for efi_runtime_disabled in
uv_bios_init so that we don't map in uv_systab when runtime_disabled ==
true.

Signed-off-by: Alex Thorlton <athorlton@sgi.com>
Cc: Russ Anderson <rja@sgi.com>
Cc: Mike Travis <travis@sgi.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: <stable@vger.kernel.org> # v4.7
Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
---
 arch/x86/platform/uv/bios_uv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/x86/platform/uv/bios_uv.c b/arch/x86/platform/uv/bios_uv.c
index 66b2166ea4a1..0df8a0370d32 100644
--- a/arch/x86/platform/uv/bios_uv.c
+++ b/arch/x86/platform/uv/bios_uv.c
@@ -187,7 +187,8 @@ EXPORT_SYMBOL_GPL(uv_bios_set_legacy_vga_target);
 void uv_bios_init(void)
 {
 	uv_systab = NULL;
-	if ((efi.uv_systab == EFI_INVALID_TABLE_ADDR) || !efi.uv_systab) {
+	if ((efi.uv_systab == EFI_INVALID_TABLE_ADDR) ||
+	    !efi.uv_systab || efi_runtime_disabled()) {
 		pr_crit("UV: UVsystab: missing\n");
 		return;
 	}
-- 
2.7.3

[toc] | [prev] | [next] | [standalone]


#1460661 — [tip:efi/urgent] x86/platform/uv: Skip UV runtime services mapping in the efi_runtime_disabled case

Fromtip-bot for Alex Thorlton <tipbot@zytor.com>
Date2016-08-11 18:30 +0200
Subject[tip:efi/urgent] x86/platform/uv: Skip UV runtime services mapping in the efi_runtime_disabled case
Message-ID<s511N-6al-65@gated-at.bofh.it>
In reply to#1460395
Commit-ID:  f72075c9eda8a43aeea2f9dbb8d187afd4a76f0b
Gitweb:     http://git.kernel.org/tip/f72075c9eda8a43aeea2f9dbb8d187afd4a76f0b
Author:     Alex Thorlton <athorlton@sgi.com>
AuthorDate: Thu, 11 Aug 2016 11:41:59 +0100
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Thu, 11 Aug 2016 13:55:36 +0200

x86/platform/uv: Skip UV runtime services mapping in the efi_runtime_disabled case

This problem has actually been in the UV code for a while, but we didn't
catch it until recently, because we had been relying on EFI_OLD_MEMMAP
to allow our systems to boot for a period of time.  We noticed the issue
when trying to kexec a recent community kernel, where we hit this NULL
pointer dereference in efi_sync_low_kernel_mappings():

 [    0.337515] BUG: unable to handle kernel NULL pointer dereference at 0000000000000880
 [    0.346276] IP: [<ffffffff8105df8d>] efi_sync_low_kernel_mappings+0x5d/0x1b0

The problem doesn't show up with EFI_OLD_MEMMAP because we skip the
chunk of setup_efi_state() that sets the efi_loader_signature for the
kexec'd kernel.  When the kexec'd kernel boots, it won't set EFI_BOOT in
setup_arch, so we completely avoid the bug.

We always kexec with noefi on the command line, so this shouldn't be an
issue, but since we're not actually checking for efi_runtime_disabled in
uv_bios_init(), we end up trying to do EFI runtime callbacks when we
shouldn't be. This patch just adds a check for efi_runtime_disabled in
uv_bios_init() so that we don't map in uv_systab when runtime_disabled ==
true.

Signed-off-by: Alex Thorlton <athorlton@sgi.com>
Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
Cc: <stable@vger.kernel.org> # v4.7
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Borislav Petkov <bp@suse.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Travis <travis@sgi.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Russ Anderson <rja@sgi.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: http://lkml.kernel.org/r/1470912120-22831-2-git-send-email-matt@codeblueprint.co.uk
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/platform/uv/bios_uv.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/x86/platform/uv/bios_uv.c b/arch/x86/platform/uv/bios_uv.c
index 66b2166..0df8a03 100644
--- a/arch/x86/platform/uv/bios_uv.c
+++ b/arch/x86/platform/uv/bios_uv.c
@@ -187,7 +187,8 @@ EXPORT_SYMBOL_GPL(uv_bios_set_legacy_vga_target);
 void uv_bios_init(void)
 {
 	uv_systab = NULL;
-	if ((efi.uv_systab == EFI_INVALID_TABLE_ADDR) || !efi.uv_systab) {
+	if ((efi.uv_systab == EFI_INVALID_TABLE_ADDR) ||
+	    !efi.uv_systab || efi_runtime_disabled()) {
 		pr_crit("UV: UVsystab: missing\n");
 		return;
 	}

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web