[linux] 01/01: [x86] efi-bgrt: Fix kernel panic when mapping BGRT data (Closes: #815125)
debian-kernel at lists.debian.org
debian-kernel at lists.debian.org
Sun Feb 21 03:31:31 UTC 2016
This is an automated email from the git hooks/post-receive script.
benh pushed a commit to branch sid
in repository linux.
commit 88d259a75c05e46ce19dd31cf037627d6fb572d4
Author: Ben Hutchings <ben at decadent.org.uk>
Date: Sat Feb 20 23:24:53 2016 +0000
[x86] efi-bgrt: Fix kernel panic when mapping BGRT data (Closes: #815125)
Plus the following fix-up.
---
debian/changelog | 7 +
...t-fix-kernel-panic-when-mapping-bgrt-data.patch | 180 +++++++++++++++++++++
...bgrt-replace-early_memremap-with-memremap.patch | 92 +++++++++++
debian/patches/series | 2 +
4 files changed, 281 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index 9628e6f..79499b6 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+linux (4.4.2-3) UNRELEASED; urgency=medium
+
+ * [x86] efi-bgrt: Fix kernel panic when mapping BGRT data (Closes: #815125)
+ * [x86] efi-bgrt: Replace early_memremap() with memremap()
+
+ -- Ben Hutchings <ben at decadent.org.uk> Sat, 20 Feb 2016 23:24:00 +0000
+
linux (4.4.2-2) unstable; urgency=medium
[ Ben Hutchings ]
diff --git a/debian/patches/bugfix/x86/x86-efi-bgrt-fix-kernel-panic-when-mapping-bgrt-data.patch b/debian/patches/bugfix/x86/x86-efi-bgrt-fix-kernel-panic-when-mapping-bgrt-data.patch
new file mode 100644
index 0000000..bcba95b
--- /dev/null
+++ b/debian/patches/bugfix/x86/x86-efi-bgrt-fix-kernel-panic-when-mapping-bgrt-data.patch
@@ -0,0 +1,180 @@
+From: Sai Praneeth <sai.praneeth.prakhya at intel.com>
+Date: Wed, 9 Dec 2015 15:41:08 -0800
+Subject: x86/efi-bgrt: Fix kernel panic when mapping BGRT data
+Origin: https://git.kernel.org/cgit/linux/kernel/git/mfleming/efi.git/commit?id=50a0cb565246f20d59cdb161778531e4b19d35ac
+Bug-Debian: https://bugs.debian.org/815125
+
+Starting with this commit 35eb8b81edd4 ("x86/efi: Build our own page
+table structures") efi regions have a separate page directory called
+"efi_pgd". In order to access any efi region we have to first shift %cr3
+to this page table. In the bgrt code we are trying to copy bgrt_header
+and image, but these regions fall under "EFI_BOOT_SERVICES_DATA"
+and to access these regions we have to shift %cr3 to efi_pgd and not
+doing so will cause page fault as shown below.
+
+[ 0.251599] Last level dTLB entries: 4KB 64, 2MB 0, 4MB 0, 1GB 4
+[ 0.259126] Freeing SMP alternatives memory: 32K (ffffffff8230e000 - ffffffff82316000)
+[ 0.271803] BUG: unable to handle kernel paging request at fffffffefce35002
+[ 0.279740] IP: [<ffffffff821bca49>] efi_bgrt_init+0x144/0x1fd
+[ 0.286383] PGD 300f067 PUD 0
+[ 0.289879] Oops: 0000 [#1] SMP
+[ 0.293566] Modules linked in:
+[ 0.297039] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.0-rc1-eywa-eywa-built-in-47041+ #2
+[ 0.306619] Hardware name: Intel Corporation Skylake Client platform/Skylake Y LPDDR3 RVP3, BIOS SKLSE2R1.R00.B104.B01.1511110114 11/11/2015
+[ 0.320925] task: ffffffff820134c0 ti: ffffffff82000000 task.ti: ffffffff82000000
+[ 0.329420] RIP: 0010:[<ffffffff821bca49>] [<ffffffff821bca49>] efi_bgrt_init+0x144/0x1fd
+[ 0.338821] RSP: 0000:ffffffff82003f18 EFLAGS: 00010246
+[ 0.344852] RAX: fffffffefce35000 RBX: fffffffefce35000 RCX: fffffffefce2b000
+[ 0.352952] RDX: 000000008a82b000 RSI: ffffffff8235bb80 RDI: 000000008a835000
+[ 0.361050] RBP: ffffffff82003f30 R08: 000000008a865000 R09: ffffffffff202850
+[ 0.369149] R10: ffffffff811ad62f R11: 0000000000000000 R12: 0000000000000000
+[ 0.377248] R13: ffff88016dbaea40 R14: ffffffff822622c0 R15: ffffffff82003fb0
+[ 0.385348] FS: 0000000000000000(0000) GS:ffff88016d800000(0000) knlGS:0000000000000000
+[ 0.394533] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 0.401054] CR2: fffffffefce35002 CR3: 000000000300c000 CR4: 00000000003406f0
+[ 0.409153] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[ 0.417252] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[ 0.425350] Stack:
+[ 0.427638] ffffffffffffffff ffffffff82256900 ffff88016dbaea40 ffffffff82003f40
+[ 0.436086] ffffffff821bbce0 ffffffff82003f88 ffffffff8219c0c2 0000000000000000
+[ 0.444533] ffffffff8219ba4a ffffffff822622c0 0000000000083000 00000000ffffffff
+[ 0.452978] Call Trace:
+[ 0.455763] [<ffffffff821bbce0>] efi_late_init+0x9/0xb
+[ 0.461697] [<ffffffff8219c0c2>] start_kernel+0x463/0x47f
+[ 0.467928] [<ffffffff8219ba4a>] ? set_init_arg+0x55/0x55
+[ 0.474159] [<ffffffff8219b120>] ? early_idt_handler_array+0x120/0x120
+[ 0.481669] [<ffffffff8219b5ee>] x86_64_start_reservations+0x2a/0x2c
+[ 0.488982] [<ffffffff8219b72d>] x86_64_start_kernel+0x13d/0x14c
+[ 0.495897] Code: 00 41 b4 01 48 8b 78 28 e8 09 36 01 00 48 85 c0 48 89 c3 75 13 48 c7 c7 f8 ac d3 81 31 c0 e8 d7 3b fb fe e9 b5 00 00 00 45 84 e4 <44> 8b 6b 02 74 0d be 06 00 00 00 48 89 df e8 ae 34 0$
+[ 0.518151] RIP [<ffffffff821bca49>] efi_bgrt_init+0x144/0x1fd
+[ 0.524888] RSP <ffffffff82003f18>
+[ 0.528851] CR2: fffffffefce35002
+[ 0.532615] ---[ end trace 7b06521e6ebf2aea ]---
+[ 0.537852] Kernel panic - not syncing: Attempted to kill the idle task!
+
+As said above one way to fix this bug is to shift %cr3 to efi_pgd but we
+are not doing that way because it leaks inner details of how we switch
+to EFI page tables into a new call site and it also adds duplicate code.
+Instead, we remove the call to efi_lookup_mapped_addr() and always
+perform early_mem*() instead of early_io*() because we want to remap RAM
+regions and not I/O regions. We also delete efi_lookup_mapped_addr()
+because we are no longer using it.
+
+Signed-off-by: Sai Praneeth Prakhya <sai.praneeth.prakhya at intel.com>
+Reported-by: Wendy Wang <wendy.wang at intel.com>
+Cc: Borislav Petkov <bp at suse.de>
+Cc: Josh Triplett <josh at joshtriplett.org>
+Cc: Ricardo Neri <ricardo.neri at intel.com>
+Cc: Ravi Shankar <ravi.v.shankar at intel.com>
+Signed-off-by: Matt Fleming <matt at codeblueprint.co.uk>
+---
+ arch/x86/platform/efi/efi-bgrt.c | 39 ++++++++++++++-------------------------
+ drivers/firmware/efi/efi.c | 32 --------------------------------
+ 2 files changed, 14 insertions(+), 57 deletions(-)
+
+--- a/arch/x86/platform/efi/efi-bgrt.c
++++ b/arch/x86/platform/efi/efi-bgrt.c
+@@ -28,8 +28,7 @@ struct bmp_header {
+ void __init efi_bgrt_init(void)
+ {
+ acpi_status status;
+- void __iomem *image;
+- bool ioremapped = false;
++ void *image;
+ struct bmp_header bmp_header;
+
+ if (acpi_disabled)
+@@ -70,20 +69,14 @@ void __init efi_bgrt_init(void)
+ return;
+ }
+
+- image = efi_lookup_mapped_addr(bgrt_tab->image_address);
++ image = early_memremap(bgrt_tab->image_address, sizeof(bmp_header));
+ if (!image) {
+- image = early_ioremap(bgrt_tab->image_address,
+- sizeof(bmp_header));
+- ioremapped = true;
+- if (!image) {
+- pr_err("Ignoring BGRT: failed to map image header memory\n");
+- return;
+- }
++ pr_err("Ignoring BGRT: failed to map image header memory\n");
++ return;
+ }
+
+- memcpy_fromio(&bmp_header, image, sizeof(bmp_header));
+- if (ioremapped)
+- early_iounmap(image, sizeof(bmp_header));
++ memcpy(&bmp_header, image, sizeof(bmp_header));
++ early_memunmap(image, sizeof(bmp_header));
+ bgrt_image_size = bmp_header.size;
+
+ bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL | __GFP_NOWARN);
+@@ -93,18 +86,14 @@ void __init efi_bgrt_init(void)
+ return;
+ }
+
+- if (ioremapped) {
+- image = early_ioremap(bgrt_tab->image_address,
+- bmp_header.size);
+- if (!image) {
+- pr_err("Ignoring BGRT: failed to map image memory\n");
+- kfree(bgrt_image);
+- bgrt_image = NULL;
+- return;
+- }
++ image = early_memremap(bgrt_tab->image_address, bmp_header.size);
++ if (!image) {
++ pr_err("Ignoring BGRT: failed to map image memory\n");
++ kfree(bgrt_image);
++ bgrt_image = NULL;
++ return;
+ }
+
+- memcpy_fromio(bgrt_image, image, bgrt_image_size);
+- if (ioremapped)
+- early_iounmap(image, bmp_header.size);
++ memcpy(bgrt_image, image, bgrt_image_size);
++ early_memunmap(image, bmp_header.size);
+ }
+--- a/drivers/firmware/efi/efi.c
++++ b/drivers/firmware/efi/efi.c
+@@ -324,38 +324,6 @@ u64 __init efi_mem_desc_end(efi_memory_d
+ return end;
+ }
+
+-/*
+- * We can't ioremap data in EFI boot services RAM, because we've already mapped
+- * it as RAM. So, look it up in the existing EFI memory map instead. Only
+- * callable after efi_enter_virtual_mode and before efi_free_boot_services.
+- */
+-void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
+-{
+- struct efi_memory_map *map;
+- void *p;
+- map = efi.memmap;
+- if (!map)
+- return NULL;
+- if (WARN_ON(!map->map))
+- return NULL;
+- for (p = map->map; p < map->map_end; p += map->desc_size) {
+- efi_memory_desc_t *md = p;
+- u64 size = md->num_pages << EFI_PAGE_SHIFT;
+- u64 end = md->phys_addr + size;
+- if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
+- md->type != EFI_BOOT_SERVICES_CODE &&
+- md->type != EFI_BOOT_SERVICES_DATA)
+- continue;
+- if (!md->virt_addr)
+- continue;
+- if (phys_addr >= md->phys_addr && phys_addr < end) {
+- phys_addr += md->virt_addr - md->phys_addr;
+- return (__force void __iomem *)(unsigned long)phys_addr;
+- }
+- }
+- return NULL;
+-}
+-
+ static __initdata efi_config_table_type_t common_tables[] = {
+ {ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20},
+ {ACPI_TABLE_GUID, "ACPI", &efi.acpi},
diff --git a/debian/patches/bugfix/x86/x86-efi-bgrt-replace-early_memremap-with-memremap.patch b/debian/patches/bugfix/x86/x86-efi-bgrt-replace-early_memremap-with-memremap.patch
new file mode 100644
index 0000000..e695fd9
--- /dev/null
+++ b/debian/patches/bugfix/x86/x86-efi-bgrt-replace-early_memremap-with-memremap.patch
@@ -0,0 +1,92 @@
+From: Matt Fleming <matt at codeblueprint.co.uk>
+Date: Mon, 21 Dec 2015 14:12:52 +0000
+Subject: x86/efi-bgrt: Replace early_memremap() with memremap()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+Origin: https://git.kernel.org/cgit/linux/kernel/git/mfleming/efi.git/commit?id=e2c90dd7e11e3025b46719a79fb4bb1e7a5cef9f
+Bug-Debian: https://bugs.debian.org/815125
+
+Môshe reported the following warning triggered on his machine since
+commit 50a0cb565246 ("x86/efi-bgrt: Fix kernel panic when mapping BGRT
+data"),
+
+ [ 0.026936] ------------[ cut here ]------------
+ [ 0.026941] WARNING: CPU: 0 PID: 0 at mm/early_ioremap.c:137 __early_ioremap+0x102/0x1bb()
+ [ 0.026941] Modules linked in:
+ [ 0.026944] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.4.0-rc1 #2
+ [ 0.026945] Hardware name: Dell Inc. XPS 13 9343/09K8G1, BIOS A05 07/14/2015
+ [ 0.026946] 0000000000000000 900f03d5a116524d ffffffff81c03e60 ffffffff813a3fff
+ [ 0.026948] 0000000000000000 ffffffff81c03e98 ffffffff810a0852 00000000d7b76000
+ [ 0.026949] 0000000000000000 0000000000000001 0000000000000001 000000000000017c
+ [ 0.026951] Call Trace:
+ [ 0.026955] [<ffffffff813a3fff>] dump_stack+0x44/0x55
+ [ 0.026958] [<ffffffff810a0852>] warn_slowpath_common+0x82/0xc0
+ [ 0.026959] [<ffffffff810a099a>] warn_slowpath_null+0x1a/0x20
+ [ 0.026961] [<ffffffff81d8c395>] __early_ioremap+0x102/0x1bb
+ [ 0.026962] [<ffffffff81d8c602>] early_memremap+0x13/0x15
+ [ 0.026964] [<ffffffff81d78361>] efi_bgrt_init+0x162/0x1ad
+ [ 0.026966] [<ffffffff81d778ec>] efi_late_init+0x9/0xb
+ [ 0.026968] [<ffffffff81d58ff5>] start_kernel+0x46f/0x49f
+ [ 0.026970] [<ffffffff81d58120>] ? early_idt_handler_array+0x120/0x120
+ [ 0.026972] [<ffffffff81d58339>] x86_64_start_reservations+0x2a/0x2c
+ [ 0.026974] [<ffffffff81d58485>] x86_64_start_kernel+0x14a/0x16d
+ [ 0.026977] ---[ end trace f9b3812eb8e24c58 ]---
+ [ 0.026978] efi_bgrt: Ignoring BGRT: failed to map image memory
+
+early_memremap() has an upper limit on the size of mapping it can
+handle which is ~200KB. Clearly the BGRT image on Môshe's machine is
+much larger than that.
+
+There's actually no reason to restrict ourselves to using the early_*
+version of memremap() - the ACPI BGRT driver is invoked late enough in
+boot that we can use the standard version, with the benefit that the
+late version allows mappings of arbitrary size.
+
+Reported-by: Môshe van der Sterre <me at moshe.nl>
+Tested-by: Môshe van der Sterre <me at moshe.nl>
+Signed-off-by: Matt Fleming <matt at codeblueprint.co.uk>
+Cc: Josh Triplett <josh at joshtriplett.org>
+Cc: Sai Praneeth Prakhya <sai.praneeth.prakhya at intel.com>
+Cc: Borislav Petkov <bp at suse.de>
+Link: http://lkml.kernel.org/r/1450707172-12561-1-git-send-email-matt@codeblueprint.co.uk
+Signed-off-by: Thomas Gleixner <tglx at linutronix.de>
+---
+ arch/x86/platform/efi/efi-bgrt.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/arch/x86/platform/efi/efi-bgrt.c
++++ b/arch/x86/platform/efi/efi-bgrt.c
+@@ -69,14 +69,14 @@ void __init efi_bgrt_init(void)
+ return;
+ }
+
+- image = early_memremap(bgrt_tab->image_address, sizeof(bmp_header));
++ image = memremap(bgrt_tab->image_address, sizeof(bmp_header), MEMREMAP_WB);
+ if (!image) {
+ pr_err("Ignoring BGRT: failed to map image header memory\n");
+ return;
+ }
+
+ memcpy(&bmp_header, image, sizeof(bmp_header));
+- early_memunmap(image, sizeof(bmp_header));
++ memunmap(image);
+ bgrt_image_size = bmp_header.size;
+
+ bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL | __GFP_NOWARN);
+@@ -86,7 +86,7 @@ void __init efi_bgrt_init(void)
+ return;
+ }
+
+- image = early_memremap(bgrt_tab->image_address, bmp_header.size);
++ image = memremap(bgrt_tab->image_address, bmp_header.size, MEMREMAP_WB);
+ if (!image) {
+ pr_err("Ignoring BGRT: failed to map image memory\n");
+ kfree(bgrt_image);
+@@ -95,5 +95,5 @@ void __init efi_bgrt_init(void)
+ }
+
+ memcpy(bgrt_image, image, bgrt_image_size);
+- early_memunmap(image, bmp_header.size);
++ memunmap(image);
+ }
diff --git a/debian/patches/series b/debian/patches/series
index ec1bad3..971ac10 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -130,3 +130,5 @@ bugfix/x86/x86-mm-fix-types-used-in-pgprot-cacheability-flags-t.patch
debian/i386-686-pae-pci-set-pci-nobios-by-default.patch
bugfix/all/iff_no_queue-fix-for-drivers-not-calling-ether_setup.patch
bugfix/arm/net-mv643xx_eth-fix-packet-corruption-with-tso-and-t.patch
+bugfix/x86/x86-efi-bgrt-fix-kernel-panic-when-mapping-bgrt-data.patch
+bugfix/x86/x86-efi-bgrt-replace-early_memremap-with-memremap.patch
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git
More information about the Kernel-svn-changes
mailing list