]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 17 Jan 2017 10:43:06 +0000 (11:43 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 17 Jan 2017 10:43:06 +0000 (11:43 +0100)
added patches:
efi-libstub-arm-pass-latest-memory-map-to-the-kernel.patch
efi-x86-prune-invalid-memory-map-entries-and-fix-boot-regression.patch
gpio-move-freeing-of-gpio-hogs-before-numbing-of-the-device.patch
nl80211-fix-sched-scan-netlink-socket-owner-destruction.patch
perf-x86-intel-uncore-fix-hardcoded-socket-0-assumption-in-the-haswell-init-code.patch
x86-efi-don-t-allocate-memmap-through-memblock-after-mm_init.patch
xfs-timely-free-truncated-dirty-pages.patch

queue-4.9/efi-libstub-arm-pass-latest-memory-map-to-the-kernel.patch [new file with mode: 0644]
queue-4.9/efi-x86-prune-invalid-memory-map-entries-and-fix-boot-regression.patch [new file with mode: 0644]
queue-4.9/gpio-move-freeing-of-gpio-hogs-before-numbing-of-the-device.patch [new file with mode: 0644]
queue-4.9/nl80211-fix-sched-scan-netlink-socket-owner-destruction.patch [new file with mode: 0644]
queue-4.9/perf-x86-intel-uncore-fix-hardcoded-socket-0-assumption-in-the-haswell-init-code.patch [new file with mode: 0644]
queue-4.9/series
queue-4.9/x86-efi-don-t-allocate-memmap-through-memblock-after-mm_init.patch [new file with mode: 0644]
queue-4.9/xfs-timely-free-truncated-dirty-pages.patch [new file with mode: 0644]

diff --git a/queue-4.9/efi-libstub-arm-pass-latest-memory-map-to-the-kernel.patch b/queue-4.9/efi-libstub-arm-pass-latest-memory-map-to-the-kernel.patch
new file mode 100644 (file)
index 0000000..de7dfdb
--- /dev/null
@@ -0,0 +1,220 @@
+From abfb7b686a3e5be27bf81db62f9c5c895b76f5d1 Mon Sep 17 00:00:00 2001
+From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Date: Sat, 24 Dec 2016 13:59:23 +0000
+Subject: efi/libstub/arm*: Pass latest memory map to the kernel
+
+From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+
+commit abfb7b686a3e5be27bf81db62f9c5c895b76f5d1 upstream.
+
+As reported by James Morse, the current libstub code involving the
+annotated memory map only works somewhat correctly by accident, due
+to the fact that a pool allocation happens to be reused immediately,
+retaining its former contents on most implementations of the
+UEFI boot services.
+
+Instead of juggling memory maps, which makes the code more complex than
+it needs to be, simply put placeholder values into the FDT for the memory
+map parameters, and only write the actual values after ExitBootServices()
+has been called.
+
+Reported-by: James Morse <james.morse@arm.com>
+Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Cc: Jeffrey Hugo <jhugo@codeaurora.org>
+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-arm-kernel@lists.infradead.org
+Cc: linux-efi@vger.kernel.org
+Fixes: ed9cc156c42f ("efi/libstub: Use efi_exit_boot_services() in FDT")
+Link: http://lkml.kernel.org/r/1482587963-20183-2-git-send-email-ard.biesheuvel@linaro.org
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/firmware/efi/libstub/efistub.h |    8 ---
+ drivers/firmware/efi/libstub/fdt.c     |   87 +++++++++++++++++++++------------
+ 2 files changed, 56 insertions(+), 39 deletions(-)
+
+--- a/drivers/firmware/efi/libstub/efistub.h
++++ b/drivers/firmware/efi/libstub/efistub.h
+@@ -30,14 +30,6 @@ efi_status_t efi_file_close(void *handle
+ unsigned long get_dram_base(efi_system_table_t *sys_table_arg);
+-efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
+-                      unsigned long orig_fdt_size,
+-                      void *fdt, int new_fdt_size, char *cmdline_ptr,
+-                      u64 initrd_addr, u64 initrd_size,
+-                      efi_memory_desc_t *memory_map,
+-                      unsigned long map_size, unsigned long desc_size,
+-                      u32 desc_ver);
+-
+ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
+                                           void *handle,
+                                           unsigned long *new_fdt_addr,
+--- a/drivers/firmware/efi/libstub/fdt.c
++++ b/drivers/firmware/efi/libstub/fdt.c
+@@ -16,13 +16,10 @@
+ #include "efistub.h"
+-efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
+-                      unsigned long orig_fdt_size,
+-                      void *fdt, int new_fdt_size, char *cmdline_ptr,
+-                      u64 initrd_addr, u64 initrd_size,
+-                      efi_memory_desc_t *memory_map,
+-                      unsigned long map_size, unsigned long desc_size,
+-                      u32 desc_ver)
++static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
++                             unsigned long orig_fdt_size,
++                             void *fdt, int new_fdt_size, char *cmdline_ptr,
++                             u64 initrd_addr, u64 initrd_size)
+ {
+       int node, num_rsv;
+       int status;
+@@ -101,25 +98,23 @@ efi_status_t update_fdt(efi_system_table
+       if (status)
+               goto fdt_set_fail;
+-      fdt_val64 = cpu_to_fdt64((u64)(unsigned long)memory_map);
++      fdt_val64 = U64_MAX; /* placeholder */
+       status = fdt_setprop(fdt, node, "linux,uefi-mmap-start",
+                            &fdt_val64,  sizeof(fdt_val64));
+       if (status)
+               goto fdt_set_fail;
+-      fdt_val32 = cpu_to_fdt32(map_size);
++      fdt_val32 = U32_MAX; /* placeholder */
+       status = fdt_setprop(fdt, node, "linux,uefi-mmap-size",
+                            &fdt_val32,  sizeof(fdt_val32));
+       if (status)
+               goto fdt_set_fail;
+-      fdt_val32 = cpu_to_fdt32(desc_size);
+       status = fdt_setprop(fdt, node, "linux,uefi-mmap-desc-size",
+                            &fdt_val32, sizeof(fdt_val32));
+       if (status)
+               goto fdt_set_fail;
+-      fdt_val32 = cpu_to_fdt32(desc_ver);
+       status = fdt_setprop(fdt, node, "linux,uefi-mmap-desc-ver",
+                            &fdt_val32, sizeof(fdt_val32));
+       if (status)
+@@ -148,6 +143,43 @@ fdt_set_fail:
+       return EFI_LOAD_ERROR;
+ }
++static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map)
++{
++      int node = fdt_path_offset(fdt, "/chosen");
++      u64 fdt_val64;
++      u32 fdt_val32;
++      int err;
++
++      if (node < 0)
++              return EFI_LOAD_ERROR;
++
++      fdt_val64 = cpu_to_fdt64((unsigned long)*map->map);
++      err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-start",
++                                &fdt_val64, sizeof(fdt_val64));
++      if (err)
++              return EFI_LOAD_ERROR;
++
++      fdt_val32 = cpu_to_fdt32(*map->map_size);
++      err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-size",
++                                &fdt_val32, sizeof(fdt_val32));
++      if (err)
++              return EFI_LOAD_ERROR;
++
++      fdt_val32 = cpu_to_fdt32(*map->desc_size);
++      err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-desc-size",
++                                &fdt_val32, sizeof(fdt_val32));
++      if (err)
++              return EFI_LOAD_ERROR;
++
++      fdt_val32 = cpu_to_fdt32(*map->desc_ver);
++      err = fdt_setprop_inplace(fdt, node, "linux,uefi-mmap-desc-ver",
++                                &fdt_val32, sizeof(fdt_val32));
++      if (err)
++              return EFI_LOAD_ERROR;
++
++      return EFI_SUCCESS;
++}
++
+ #ifndef EFI_FDT_ALIGN
+ #define EFI_FDT_ALIGN EFI_PAGE_SIZE
+ #endif
+@@ -243,20 +275,10 @@ efi_status_t allocate_new_fdt_and_exit_b
+                       goto fail;
+               }
+-              /*
+-               * Now that we have done our final memory allocation (and free)
+-               * we can get the memory map key  needed for
+-               * exit_boot_services().
+-               */
+-              status = efi_get_memory_map(sys_table, &map);
+-              if (status != EFI_SUCCESS)
+-                      goto fail_free_new_fdt;
+-
+               status = update_fdt(sys_table,
+                                   (void *)fdt_addr, fdt_size,
+                                   (void *)*new_fdt_addr, new_fdt_size,
+-                                  cmdline_ptr, initrd_addr, initrd_size,
+-                                  memory_map, map_size, desc_size, desc_ver);
++                                  cmdline_ptr, initrd_addr, initrd_size);
+               /* Succeeding the first time is the expected case. */
+               if (status == EFI_SUCCESS)
+@@ -266,20 +288,16 @@ efi_status_t allocate_new_fdt_and_exit_b
+                       /*
+                        * We need to allocate more space for the new
+                        * device tree, so free existing buffer that is
+-                       * too small.  Also free memory map, as we will need
+-                       * to get new one that reflects the free/alloc we do
+-                       * on the device tree buffer.
++                       * too small.
+                        */
+                       efi_free(sys_table, new_fdt_size, *new_fdt_addr);
+-                      sys_table->boottime->free_pool(memory_map);
+                       new_fdt_size += EFI_PAGE_SIZE;
+               } else {
+                       pr_efi_err(sys_table, "Unable to construct new device tree.\n");
+-                      goto fail_free_mmap;
++                      goto fail_free_new_fdt;
+               }
+       }
+-      sys_table->boottime->free_pool(memory_map);
+       priv.runtime_map = runtime_map;
+       priv.runtime_entry_count = &runtime_entry_count;
+       status = efi_exit_boot_services(sys_table, handle, &map, &priv,
+@@ -288,6 +306,16 @@ efi_status_t allocate_new_fdt_and_exit_b
+       if (status == EFI_SUCCESS) {
+               efi_set_virtual_address_map_t *svam;
++              status = update_fdt_memmap((void *)*new_fdt_addr, &map);
++              if (status != EFI_SUCCESS) {
++                      /*
++                       * The kernel won't get far without the memory map, but
++                       * may still be able to print something meaningful so
++                       * return success here.
++                       */
++                      return EFI_SUCCESS;
++              }
++
+               /* Install the new virtual address map */
+               svam = sys_table->runtime->set_virtual_address_map;
+               status = svam(runtime_entry_count * desc_size, desc_size,
+@@ -319,9 +347,6 @@ efi_status_t allocate_new_fdt_and_exit_b
+       pr_efi_err(sys_table, "Exit boot services failed.\n");
+-fail_free_mmap:
+-      sys_table->boottime->free_pool(memory_map);
+-
+ fail_free_new_fdt:
+       efi_free(sys_table, new_fdt_size, *new_fdt_addr);
diff --git a/queue-4.9/efi-x86-prune-invalid-memory-map-entries-and-fix-boot-regression.patch b/queue-4.9/efi-x86-prune-invalid-memory-map-entries-and-fix-boot-regression.patch
new file mode 100644 (file)
index 0000000..3d3f5ea
--- /dev/null
@@ -0,0 +1,149 @@
+From 0100a3e67a9cef64d72cd3a1da86f3ddbee50363 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Mon, 12 Dec 2016 18:42:28 -0500
+Subject: efi/x86: Prune invalid memory map entries and fix boot regression
+
+From: Peter Jones <pjones@redhat.com>
+
+commit 0100a3e67a9cef64d72cd3a1da86f3ddbee50363 upstream.
+
+Some machines, such as the Lenovo ThinkPad W541 with firmware GNET80WW
+(2.28), include memory map entries with phys_addr=0x0 and num_pages=0.
+
+These machines fail to boot after the following commit,
+
+  commit 8e80632fb23f ("efi/esrt: Use efi_mem_reserve() and avoid a kmalloc()")
+
+Fix this by removing such bogus entries from the memory map.
+
+Furthermore, currently the log output for this case (with efi=debug)
+looks like:
+
+ [    0.000000] efi: mem45: [Reserved           |   |  |  |  |  |  |  |  |  |  |  |  ] range=[0x0000000000000000-0xffffffffffffffff] (0MB)
+
+This is clearly wrong, and also not as informative as it could be.  This
+patch changes it so that if we find obviously invalid memory map
+entries, we print an error and skip those entries.  It also detects the
+display of the address range calculation overflow, so the new output is:
+
+ [    0.000000] efi: [Firmware Bug]: Invalid EFI memory map entries:
+ [    0.000000] efi: mem45: [Reserved           |   |  |  |  |  |  |  |   |  |  |  |  ] range=[0x0000000000000000-0x0000000000000000] (invalid)
+
+It also detects memory map sizes that would overflow the physical
+address, for example phys_addr=0xfffffffffffff000 and
+num_pages=0x0200000000000001, and prints:
+
+ [    0.000000] efi: [Firmware Bug]: Invalid EFI memory map entries:
+ [    0.000000] efi: mem45: [Reserved           |   |  |  |  |  |  |  |   |  |  |  |  ] range=[phys_addr=0xfffffffffffff000-0x20ffffffffffffffff] (invalid)
+
+It then removes these entries from the memory map.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+[ardb: refactor for clarity with no functional changes, avoid PAGE_SHIFT]
+Signed-off-by: Matt Fleming <matt@codeblueprint.co.uk>
+[Matt: Include bugzilla info in commit log]
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=191121
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/platform/efi/efi.c |   66 ++++++++++++++++++++++++++++++++++++++++++++
+ include/linux/efi.h         |    1 
+ 2 files changed, 67 insertions(+)
+
+--- a/arch/x86/platform/efi/efi.c
++++ b/arch/x86/platform/efi/efi.c
+@@ -210,6 +210,70 @@ int __init efi_memblock_x86_reserve_rang
+       return 0;
+ }
++#define OVERFLOW_ADDR_SHIFT   (64 - EFI_PAGE_SHIFT)
++#define OVERFLOW_ADDR_MASK    (U64_MAX << OVERFLOW_ADDR_SHIFT)
++#define U64_HIGH_BIT          (~(U64_MAX >> 1))
++
++static bool __init efi_memmap_entry_valid(const efi_memory_desc_t *md, int i)
++{
++      u64 end = (md->num_pages << EFI_PAGE_SHIFT) + md->phys_addr - 1;
++      u64 end_hi = 0;
++      char buf[64];
++
++      if (md->num_pages == 0) {
++              end = 0;
++      } else if (md->num_pages > EFI_PAGES_MAX ||
++                 EFI_PAGES_MAX - md->num_pages <
++                 (md->phys_addr >> EFI_PAGE_SHIFT)) {
++              end_hi = (md->num_pages & OVERFLOW_ADDR_MASK)
++                      >> OVERFLOW_ADDR_SHIFT;
++
++              if ((md->phys_addr & U64_HIGH_BIT) && !(end & U64_HIGH_BIT))
++                      end_hi += 1;
++      } else {
++              return true;
++      }
++
++      pr_warn_once(FW_BUG "Invalid EFI memory map entries:\n");
++
++      if (end_hi) {
++              pr_warn("mem%02u: %s range=[0x%016llx-0x%llx%016llx] (invalid)\n",
++                      i, efi_md_typeattr_format(buf, sizeof(buf), md),
++                      md->phys_addr, end_hi, end);
++      } else {
++              pr_warn("mem%02u: %s range=[0x%016llx-0x%016llx] (invalid)\n",
++                      i, efi_md_typeattr_format(buf, sizeof(buf), md),
++                      md->phys_addr, end);
++      }
++      return false;
++}
++
++static void __init efi_clean_memmap(void)
++{
++      efi_memory_desc_t *out = efi.memmap.map;
++      const efi_memory_desc_t *in = out;
++      const efi_memory_desc_t *end = efi.memmap.map_end;
++      int i, n_removal;
++
++      for (i = n_removal = 0; in < end; i++) {
++              if (efi_memmap_entry_valid(in, i)) {
++                      if (out != in)
++                              memcpy(out, in, efi.memmap.desc_size);
++                      out = (void *)out + efi.memmap.desc_size;
++              } else {
++                      n_removal++;
++              }
++              in = (void *)in + efi.memmap.desc_size;
++      }
++
++      if (n_removal > 0) {
++              u64 size = efi.memmap.nr_map - n_removal;
++
++              pr_warn("Removing %d invalid memory map entries.\n", n_removal);
++              efi_memmap_install(efi.memmap.phys_map, size);
++      }
++}
++
+ void __init efi_print_memmap(void)
+ {
+       efi_memory_desc_t *md;
+@@ -472,6 +536,8 @@ void __init efi_init(void)
+               }
+       }
++      efi_clean_memmap();
++
+       if (efi_enabled(EFI_DBG))
+               efi_print_memmap();
+ }
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -103,6 +103,7 @@ typedef    struct {
+ #define EFI_PAGE_SHIFT                12
+ #define EFI_PAGE_SIZE         (1UL << EFI_PAGE_SHIFT)
++#define EFI_PAGES_MAX         (U64_MAX >> EFI_PAGE_SHIFT)
+ typedef struct {
+       u32 type;
diff --git a/queue-4.9/gpio-move-freeing-of-gpio-hogs-before-numbing-of-the-device.patch b/queue-4.9/gpio-move-freeing-of-gpio-hogs-before-numbing-of-the-device.patch
new file mode 100644 (file)
index 0000000..684351e
--- /dev/null
@@ -0,0 +1,46 @@
+From 5018ada69a04c8ac21d74bd682fceb8e42dc0f96 Mon Sep 17 00:00:00 2001
+From: Geert Uytterhoeven <geert@linux-m68k.org>
+Date: Mon, 19 Dec 2016 18:29:23 +0100
+Subject: gpio: Move freeing of GPIO hogs before numbing of the device
+
+From: Geert Uytterhoeven <geert@linux-m68k.org>
+
+commit 5018ada69a04c8ac21d74bd682fceb8e42dc0f96 upstream.
+
+When removing a gpiochip that uses GPIO hogging (e.g. by unloading the
+chip's DT overlay), a warning is printed:
+
+    gpio gpiochip8: REMOVING GPIOCHIP WITH GPIOS STILL REQUESTED
+
+This happens because gpiochip_free_hogs() is called after the gdev->chip
+pointer is reset to NULL. Hence __gpiod_free() cannot determine the
+chip in use, and cannot clear flags nor call the optional chip-specific
+.free() callback.
+
+Move the call to gpiochip_free_hogs() up to fix this.
+
+Fixes: ff2b135922992756 ("gpio: make the gpiochip a real device")
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpio/gpiolib.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -1317,12 +1317,12 @@ void gpiochip_remove(struct gpio_chip *c
+       /* FIXME: should the legacy sysfs handling be moved to gpio_device? */
+       gpiochip_sysfs_unregister(gdev);
++      gpiochip_free_hogs(chip);
+       /* Numb the device, cancelling all outstanding operations */
+       gdev->chip = NULL;
+       gpiochip_irqchip_remove(chip);
+       acpi_gpiochip_remove(chip);
+       gpiochip_remove_pin_ranges(chip);
+-      gpiochip_free_hogs(chip);
+       of_gpiochip_remove(chip);
+       /*
+        * We accept no more calls into the driver from this point, so
diff --git a/queue-4.9/nl80211-fix-sched-scan-netlink-socket-owner-destruction.patch b/queue-4.9/nl80211-fix-sched-scan-netlink-socket-owner-destruction.patch
new file mode 100644 (file)
index 0000000..2a49801
--- /dev/null
@@ -0,0 +1,61 @@
+From 753aacfd2e95df6a0caf23c03dc309020765bea9 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Thu, 5 Jan 2017 10:57:14 +0100
+Subject: nl80211: fix sched scan netlink socket owner destruction
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 753aacfd2e95df6a0caf23c03dc309020765bea9 upstream.
+
+A single netlink socket might own multiple interfaces *and* a
+scheduled scan request (which might belong to another interface),
+so when it goes away both may need to be destroyed.
+
+Remove the schedule_scan_stop indirection to fix this - it's only
+needed for interface destruction because of the way this works
+right now, with a single work taking care of all interfaces.
+
+Fixes: 93a1e86ce10e4 ("nl80211: Stop scheduled scan if netlink client disappears")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/wireless/nl80211.c |   16 +++++++---------
+ 1 file changed, 7 insertions(+), 9 deletions(-)
+
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -14402,13 +14402,17 @@ static int nl80211_netlink_notify(struct
+       list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
+               bool schedule_destroy_work = false;
+-              bool schedule_scan_stop = false;
+               struct cfg80211_sched_scan_request *sched_scan_req =
+                       rcu_dereference(rdev->sched_scan_req);
+               if (sched_scan_req && notify->portid &&
+-                  sched_scan_req->owner_nlportid == notify->portid)
+-                      schedule_scan_stop = true;
++                  sched_scan_req->owner_nlportid == notify->portid) {
++                      sched_scan_req->owner_nlportid = 0;
++
++                      if (rdev->ops->sched_scan_stop &&
++                          rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
++                              schedule_work(&rdev->sched_scan_stop_wk);
++              }
+               list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
+                       cfg80211_mlme_unregister_socket(wdev, notify->portid);
+@@ -14439,12 +14443,6 @@ static int nl80211_netlink_notify(struct
+                               spin_unlock(&rdev->destroy_list_lock);
+                               schedule_work(&rdev->destroy_work);
+                       }
+-              } else if (schedule_scan_stop) {
+-                      sched_scan_req->owner_nlportid = 0;
+-
+-                      if (rdev->ops->sched_scan_stop &&
+-                          rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
+-                              schedule_work(&rdev->sched_scan_stop_wk);
+               }
+       }
diff --git a/queue-4.9/perf-x86-intel-uncore-fix-hardcoded-socket-0-assumption-in-the-haswell-init-code.patch b/queue-4.9/perf-x86-intel-uncore-fix-hardcoded-socket-0-assumption-in-the-haswell-init-code.patch
new file mode 100644 (file)
index 0000000..34c2061
--- /dev/null
@@ -0,0 +1,55 @@
+From 6d6daa20945f3f598e56e18d1f926c08754f5801 Mon Sep 17 00:00:00 2001
+From: Prarit Bhargava <prarit@redhat.com>
+Date: Thu, 5 Jan 2017 10:09:25 -0500
+Subject: perf/x86/intel/uncore: Fix hardcoded socket 0 assumption in the Haswell init code
+
+From: Prarit Bhargava <prarit@redhat.com>
+
+commit 6d6daa20945f3f598e56e18d1f926c08754f5801 upstream.
+
+hswep_uncore_cpu_init() uses a hardcoded physical package id 0 for the boot
+cpu. This works as long as the boot CPU is actually on the physical package
+0, which is normaly the case after power on / reboot.
+
+But it fails with a NULL pointer dereference when a kdump kernel is started
+on a secondary socket which has a different physical package id because the
+locigal package translation for physical package 0 does not exist.
+
+Use the logical package id of the boot cpu instead of hard coded 0.
+
+[ tglx: Rewrote changelog once more ]
+
+Fixes: cf6d445f6897 ("perf/x86/uncore: Track packages, not per CPU data")
+Signed-off-by: Prarit Bhargava <prarit@redhat.com>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
+Cc: Borislav Petkov <bp@suse.de>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Harish Chegondi <harish.chegondi@intel.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Kan Liang <kan.liang@intel.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Stephane Eranian <eranian@google.com>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Vince Weaver <vincent.weaver@maine.edu>
+Link: http://lkml.kernel.org/r/1483628965-2890-1-git-send-email-prarit@redhat.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/events/intel/uncore_snbep.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/x86/events/intel/uncore_snbep.c
++++ b/arch/x86/events/intel/uncore_snbep.c
+@@ -2686,7 +2686,7 @@ static struct intel_uncore_type *hswep_m
+ void hswep_uncore_cpu_init(void)
+ {
+-      int pkg = topology_phys_to_logical_pkg(0);
++      int pkg = boot_cpu_data.logical_proc_id;
+       if (hswep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores)
+               hswep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores;
index 56daa001b165a6d1b58e15e07ceb01d5e8eae3ad..c9545d18d18df54429a474a4a42ea6c94c744bd9 100644 (file)
@@ -28,3 +28,10 @@ kvm-x86-add-align16-instruction-flag.patch
 kvm-x86-add-asm_safe-wrapper.patch
 kvm-x86-emulate-fxsave-and-fxrstor.patch
 kvm-x86-introduce-segmented_write_std.patch
+efi-libstub-arm-pass-latest-memory-map-to-the-kernel.patch
+perf-x86-intel-uncore-fix-hardcoded-socket-0-assumption-in-the-haswell-init-code.patch
+efi-x86-prune-invalid-memory-map-entries-and-fix-boot-regression.patch
+x86-efi-don-t-allocate-memmap-through-memblock-after-mm_init.patch
+nl80211-fix-sched-scan-netlink-socket-owner-destruction.patch
+gpio-move-freeing-of-gpio-hogs-before-numbing-of-the-device.patch
+xfs-timely-free-truncated-dirty-pages.patch
diff --git a/queue-4.9/x86-efi-don-t-allocate-memmap-through-memblock-after-mm_init.patch b/queue-4.9/x86-efi-don-t-allocate-memmap-through-memblock-after-mm_init.patch
new file mode 100644 (file)
index 0000000..95b0d0e
--- /dev/null
@@ -0,0 +1,163 @@
+From 20b1e22d01a4b0b11d3a1066e9feb04be38607ec Mon Sep 17 00:00:00 2001
+From: Nicolai Stange <nicstange@gmail.com>
+Date: Thu, 5 Jan 2017 13:51:29 +0100
+Subject: x86/efi: Don't allocate memmap through memblock after mm_init()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nicolai Stange <nicstange@gmail.com>
+
+commit 20b1e22d01a4b0b11d3a1066e9feb04be38607ec upstream.
+
+With the following commit:
+
+  4bc9f92e64c8 ("x86/efi-bgrt: Use efi_mem_reserve() to avoid copying image data")
+
+...  efi_bgrt_init() calls into the memblock allocator through
+efi_mem_reserve() => efi_arch_mem_reserve() *after* mm_init() has been called.
+
+Indeed, KASAN reports a bad read access later on in efi_free_boot_services():
+
+  BUG: KASAN: use-after-free in efi_free_boot_services+0xae/0x24c
+            at addr ffff88022de12740
+  Read of size 4 by task swapper/0/0
+  page:ffffea0008b78480 count:0 mapcount:-127
+  mapping:          (null) index:0x1 flags: 0x5fff8000000000()
+  [...]
+  Call Trace:
+   dump_stack+0x68/0x9f
+   kasan_report_error+0x4c8/0x500
+   kasan_report+0x58/0x60
+   __asan_load4+0x61/0x80
+   efi_free_boot_services+0xae/0x24c
+   start_kernel+0x527/0x562
+   x86_64_start_reservations+0x24/0x26
+   x86_64_start_kernel+0x157/0x17a
+   start_cpu+0x5/0x14
+
+The instruction at the given address is the first read from the memmap's
+memory, i.e. the read of md->type in efi_free_boot_services().
+
+Note that the writes earlier in efi_arch_mem_reserve() don't splat because
+they're done through early_memremap()ed addresses.
+
+So, after memblock is gone, allocations should be done through the "normal"
+page allocator. Introduce a helper, efi_memmap_alloc() for this. Use
+it from efi_arch_mem_reserve(), efi_free_boot_services() and, for the sake
+of consistency, from efi_fake_memmap() as well.
+
+Note that for the latter, the memmap allocations cease to be page aligned.
+This isn't needed though.
+
+Tested-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Nicolai Stange <nicstange@gmail.com>
+Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Cc: Dave Young <dyoung@redhat.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Matt Fleming <matt@codeblueprint.co.uk>
+Cc: Mika Penttilä <mika.penttila@nextfour.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: linux-efi@vger.kernel.org
+Fixes: 4bc9f92e64c8 ("x86/efi-bgrt: Use efi_mem_reserve() to avoid copying image data")
+Link: http://lkml.kernel.org/r/20170105125130.2815-1-nicstange@gmail.com
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/platform/efi/quirks.c  |    4 ++--
+ drivers/firmware/efi/fake_mem.c |    3 +--
+ drivers/firmware/efi/memmap.c   |   38 ++++++++++++++++++++++++++++++++++++++
+ include/linux/efi.h             |    1 +
+ 4 files changed, 42 insertions(+), 4 deletions(-)
+
+--- a/arch/x86/platform/efi/quirks.c
++++ b/arch/x86/platform/efi/quirks.c
+@@ -214,7 +214,7 @@ void __init efi_arch_mem_reserve(phys_ad
+       new_size = efi.memmap.desc_size * num_entries;
+-      new_phys = memblock_alloc(new_size, 0);
++      new_phys = efi_memmap_alloc(num_entries);
+       if (!new_phys) {
+               pr_err("Could not allocate boot services memmap\n");
+               return;
+@@ -355,7 +355,7 @@ void __init efi_free_boot_services(void)
+       }
+       new_size = efi.memmap.desc_size * num_entries;
+-      new_phys = memblock_alloc(new_size, 0);
++      new_phys = efi_memmap_alloc(num_entries);
+       if (!new_phys) {
+               pr_err("Failed to allocate new EFI memmap\n");
+               return;
+--- a/drivers/firmware/efi/fake_mem.c
++++ b/drivers/firmware/efi/fake_mem.c
+@@ -71,8 +71,7 @@ void __init efi_fake_memmap(void)
+       }
+       /* allocate memory for new EFI memmap */
+-      new_memmap_phy = memblock_alloc(efi.memmap.desc_size * new_nr_map,
+-                                      PAGE_SIZE);
++      new_memmap_phy = efi_memmap_alloc(new_nr_map);
+       if (!new_memmap_phy)
+               return;
+--- a/drivers/firmware/efi/memmap.c
++++ b/drivers/firmware/efi/memmap.c
+@@ -9,6 +9,44 @@
+ #include <linux/efi.h>
+ #include <linux/io.h>
+ #include <asm/early_ioremap.h>
++#include <linux/memblock.h>
++#include <linux/slab.h>
++
++static phys_addr_t __init __efi_memmap_alloc_early(unsigned long size)
++{
++      return memblock_alloc(size, 0);
++}
++
++static phys_addr_t __init __efi_memmap_alloc_late(unsigned long size)
++{
++      unsigned int order = get_order(size);
++      struct page *p = alloc_pages(GFP_KERNEL, order);
++
++      if (!p)
++              return 0;
++
++      return PFN_PHYS(page_to_pfn(p));
++}
++
++/**
++ * efi_memmap_alloc - Allocate memory for the EFI memory map
++ * @num_entries: Number of entries in the allocated map.
++ *
++ * Depending on whether mm_init() has already been invoked or not,
++ * either memblock or "normal" page allocation is used.
++ *
++ * Returns the physical address of the allocated memory map on
++ * success, zero on failure.
++ */
++phys_addr_t __init efi_memmap_alloc(unsigned int num_entries)
++{
++      unsigned long size = num_entries * efi.memmap.desc_size;
++
++      if (slab_is_available())
++              return __efi_memmap_alloc_late(size);
++
++      return __efi_memmap_alloc_early(size);
++}
+ /**
+  * __efi_memmap_init - Common code for mapping the EFI memory map
+--- a/include/linux/efi.h
++++ b/include/linux/efi.h
+@@ -931,6 +931,7 @@ static inline efi_status_t efi_query_var
+ #endif
+ extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr);
++extern phys_addr_t __init efi_memmap_alloc(unsigned int num_entries);
+ extern int __init efi_memmap_init_early(struct efi_memory_map_data *data);
+ extern int __init efi_memmap_init_late(phys_addr_t addr, unsigned long size);
+ extern void __init efi_memmap_unmap(void);
diff --git a/queue-4.9/xfs-timely-free-truncated-dirty-pages.patch b/queue-4.9/xfs-timely-free-truncated-dirty-pages.patch
new file mode 100644 (file)
index 0000000..4b8d23a
--- /dev/null
@@ -0,0 +1,81 @@
+From 0a417b8dc1f10b03e8f558b8a831f07ec4c23795 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Wed, 11 Jan 2017 10:20:04 -0800
+Subject: xfs: Timely free truncated dirty pages
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jan Kara <jack@suse.cz>
+
+commit 0a417b8dc1f10b03e8f558b8a831f07ec4c23795 upstream.
+
+Commit 99579ccec4e2 "xfs: skip dirty pages in ->releasepage()" started
+to skip dirty pages in xfs_vm_releasepage() which also has the effect
+that if a dirty page is truncated, it does not get freed by
+block_invalidatepage() and is lingering in LRU list waiting for reclaim.
+So a simple loop like:
+
+while true; do
+       dd if=/dev/zero of=file bs=1M count=100
+       rm file
+done
+
+will keep using more and more memory until we hit low watermarks and
+start pagecache reclaim which will eventually reclaim also the truncate
+pages. Keeping these truncated (and thus never usable) pages in memory
+is just a waste of memory, is unnecessarily stressing page cache
+reclaim, and reportedly also leads to anonymous mmap(2) returning ENOMEM
+prematurely.
+
+So instead of just skipping dirty pages in xfs_vm_releasepage(), return
+to old behavior of skipping them only if they have delalloc or unwritten
+buffers and fix the spurious warnings by warning only if the page is
+clean.
+
+CC: Brian Foster <bfoster@redhat.com>
+CC: Vlastimil Babka <vbabka@suse.cz>
+Reported-by: Petr Tůma <petr.tuma@d3s.mff.cuni.cz>
+Fixes: 99579ccec4e271c3d4d4e7c946058766812afdab
+Signed-off-by: Jan Kara <jack@suse.cz>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/xfs/xfs_aops.c |   19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+--- a/fs/xfs/xfs_aops.c
++++ b/fs/xfs/xfs_aops.c
+@@ -1158,19 +1158,22 @@ xfs_vm_releasepage(
+        * block_invalidatepage() can send pages that are still marked dirty
+        * but otherwise have invalidated buffers.
+        *
+-       * We've historically freed buffers on the latter. Instead, quietly
+-       * filter out all dirty pages to avoid spurious buffer state warnings.
+-       * This can likely be removed once shrink_active_list() is fixed.
++       * We want to release the latter to avoid unnecessary buildup of the
++       * LRU, skip the former and warn if we've left any lingering
++       * delalloc/unwritten buffers on clean pages. Skip pages with delalloc
++       * or unwritten buffers and warn if the page is not dirty. Otherwise
++       * try to release the buffers.
+        */
+-      if (PageDirty(page))
+-              return 0;
+-
+       xfs_count_page_state(page, &delalloc, &unwritten);
+-      if (WARN_ON_ONCE(delalloc))
++      if (delalloc) {
++              WARN_ON_ONCE(!PageDirty(page));
+               return 0;
+-      if (WARN_ON_ONCE(unwritten))
++      }
++      if (unwritten) {
++              WARN_ON_ONCE(!PageDirty(page));
+               return 0;
++      }
+       return try_to_free_buffers(page);
+ }