From: Greg Kroah-Hartman Date: Tue, 17 Jan 2017 10:43:06 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.9.5~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b4540b0d3a4cfd48e000ea3ef0c6de8de0f0b635;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches 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 --- 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 index 00000000000..de7dfdb7f80 --- /dev/null +++ b/queue-4.9/efi-libstub-arm-pass-latest-memory-map-to-the-kernel.patch @@ -0,0 +1,220 @@ +From abfb7b686a3e5be27bf81db62f9c5c895b76f5d1 Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +Date: Sat, 24 Dec 2016 13:59:23 +0000 +Subject: efi/libstub/arm*: Pass latest memory map to the kernel + +From: Ard Biesheuvel + +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 +Signed-off-by: Ard Biesheuvel +Cc: Jeffrey Hugo +Cc: Linus Torvalds +Cc: Matt Fleming +Cc: Peter Zijlstra +Cc: Thomas Gleixner +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..3d3f5ea9522 --- /dev/null +++ b/queue-4.9/efi-x86-prune-invalid-memory-map-entries-and-fix-boot-regression.patch @@ -0,0 +1,149 @@ +From 0100a3e67a9cef64d72cd3a1da86f3ddbee50363 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Mon, 12 Dec 2016 18:42:28 -0500 +Subject: efi/x86: Prune invalid memory map entries and fix boot regression + +From: Peter Jones + +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 +Signed-off-by: Ard Biesheuvel +[ardb: refactor for clarity with no functional changes, avoid PAGE_SHIFT] +Signed-off-by: Matt Fleming +[Matt: Include bugzilla info in commit log] +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Link: https://bugzilla.kernel.org/show_bug.cgi?id=191121 +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..684351e6e77 --- /dev/null +++ b/queue-4.9/gpio-move-freeing-of-gpio-hogs-before-numbing-of-the-device.patch @@ -0,0 +1,46 @@ +From 5018ada69a04c8ac21d74bd682fceb8e42dc0f96 Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven +Date: Mon, 19 Dec 2016 18:29:23 +0100 +Subject: gpio: Move freeing of GPIO hogs before numbing of the device + +From: Geert Uytterhoeven + +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 +Signed-off-by: Linus Walleij +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..2a4980189da --- /dev/null +++ b/queue-4.9/nl80211-fix-sched-scan-netlink-socket-owner-destruction.patch @@ -0,0 +1,61 @@ +From 753aacfd2e95df6a0caf23c03dc309020765bea9 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Thu, 5 Jan 2017 10:57:14 +0100 +Subject: nl80211: fix sched scan netlink socket owner destruction + +From: Johannes Berg + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..34c2061edd5 --- /dev/null +++ b/queue-4.9/perf-x86-intel-uncore-fix-hardcoded-socket-0-assumption-in-the-haswell-init-code.patch @@ -0,0 +1,55 @@ +From 6d6daa20945f3f598e56e18d1f926c08754f5801 Mon Sep 17 00:00:00 2001 +From: Prarit Bhargava +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 + +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 +Cc: Alexander Shishkin +Cc: Arnaldo Carvalho de Melo +Cc: Borislav Petkov +Cc: H. Peter Anvin +Cc: Harish Chegondi +Cc: Jiri Olsa +Cc: Kan Liang +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Stephane Eranian +Cc: Thomas Gleixner +Cc: Vince Weaver +Link: http://lkml.kernel.org/r/1483628965-2890-1-git-send-email-prarit@redhat.com +Signed-off-by: Ingo Molnar +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-4.9/series b/queue-4.9/series index 56daa001b16..c9545d18d18 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -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 index 00000000000..95b0d0ea616 --- /dev/null +++ b/queue-4.9/x86-efi-don-t-allocate-memmap-through-memblock-after-mm_init.patch @@ -0,0 +1,163 @@ +From 20b1e22d01a4b0b11d3a1066e9feb04be38607ec Mon Sep 17 00:00:00 2001 +From: Nicolai Stange +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 + +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 +Signed-off-by: Nicolai Stange +Reviewed-by: Ard Biesheuvel +Cc: Dave Young +Cc: Linus Torvalds +Cc: Matt Fleming +Cc: Mika Penttilä +Cc: Peter Zijlstra +Cc: Thomas Gleixner +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + #include + #include ++#include ++#include ++ ++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 index 00000000000..4b8d23a0c6e --- /dev/null +++ b/queue-4.9/xfs-timely-free-truncated-dirty-pages.patch @@ -0,0 +1,81 @@ +From 0a417b8dc1f10b03e8f558b8a831f07ec4c23795 Mon Sep 17 00:00:00 2001 +From: Jan Kara +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 + +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 +CC: Vlastimil Babka +Reported-by: Petr Tůma +Fixes: 99579ccec4e271c3d4d4e7c946058766812afdab +Signed-off-by: Jan Kara +Reviewed-by: Brian Foster +Signed-off-by: Darrick J. Wong +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + }