From: Greg Kroah-Hartman Date: Sat, 12 Mar 2016 07:04:20 +0000 (-0800) Subject: 4.4-stable patches X-Git-Tag: v4.4.6~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d8546da0936af11533834bd8fd1c2fb8cf3e988a;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: arm-dts-dra7-do-not-gate-cpsw-clock-due-to-errata-i877.patch arm-mvebu-fix-overlap-of-crypto-sram-with-pcie-memory-window.patch arm-omap2-hwmod-introduce-ti-no-idle-dt-property.patch arm64-account-for-sparsemem-section-alignment-when-choosing-vmemmap-offset.patch asoc-dapm-fix-ctl-value-accesses-in-a-wrong-type.patch asoc-samsung-use-irq-safe-spin-lock-calls.patch asoc-wm8958-fix-enum-ctl-accesses-in-a-wrong-type.patch asoc-wm8994-fix-enum-ctl-accesses-in-a-wrong-type.patch can-gs_usb-fixed-disconnect-bug-by-removing-erroneous-use-of-kfree.patch cfg80211-wext-fix-message-ordering.patch dmaengine-at_xdmac-fix-residue-computation.patch drm-amdgpu-fix-error-handling-in-amdgpu_flip_work_func.patch drm-radeon-fix-error-handling-in-radeon_flip_work_func.patch gpu-ipu-v3-do-not-bail-out-on-missing-optional-port-nodes.patch iwlwifi-mvm-inc-pending-frames-counter-also-when-txing-non-sta.patch jffs2-reduce-the-breakage-on-recovery-from-halfway-failed-rename.patch kvm-cap-halt-polling-at-exactly-halt_poll_ns.patch kvm-mmu-fix-ept-0-pte.u-1-pte.w-0-cr0.wp-0-cr4.smep-1-efer.nx-0-combo.patch kvm-mmu-fix-reserved-bit-check-for-ept-0-cr0.wp-0-cr4.smep-1-efer.nx-0.patch kvm-ppc-book3s-hv-sanitize-special-purpose-register-values-on-guest-exit.patch kvm-s390-correct-fprs-on-sigp-stop-and-store-status.patch kvm-vmx-disable-pebs-before-a-guest-entry.patch mac80211-check-pn-correctly-for-gcmp-encrypted-fragmented-mpdus.patch mac80211-fix-public-action-frame-rx-in-ap-mode.patch mac80211-fix-use-of-uninitialised-values-in-rx-aggregation.patch mac80211-minstrel-change-expected-throughput-unit-back-to-kbps.patch mac80211-minstrel_ht-fix-a-logic-error-in-rts-cts-handling.patch mac80211-minstrel_ht-set-default-tx-aggregation-timeout-to-0.patch ncpfs-fix-a-braino-in-oom-handling-in-ncp_fill_cache.patch ovl-fix-working-on-distributed-fs-as-lower-layer.patch ovl-ignore-lower-entries-when-checking-purity-of-non-directory-entries.patch pci-allow-a-null-parent-pointer-in-pci_bus_assign_domain_nr.patch powerpc-fix-dedotify-for-binutils-2.26.patch powerpc-powernv-add-a-kmsg_dumper-that-flushes-console-output-on-panic.patch powerpc-powernv-fix-opal_console_flush-prototype-and-usages.patch revert-drm-radeon-call-hpd_irq_event-on-resume.patch revert-drm-radeon-pm-adjust-display-configuration-after-powerstate.patch s390-dasd-fix-diag-0x250-inline-assembly.patch s390-mm-four-page-table-levels-vs.-fork.patch tracing-fix-check-for-cpu-online-when-event-is-disabled.patch wext-fix-message-delay-ordering.patch x86-mm-fix-slow_virt_to_phys-for-x86_pae-again.patch --- diff --git a/queue-4.4/arm-dts-dra7-do-not-gate-cpsw-clock-due-to-errata-i877.patch b/queue-4.4/arm-dts-dra7-do-not-gate-cpsw-clock-due-to-errata-i877.patch new file mode 100644 index 00000000000..d1232638fa2 --- /dev/null +++ b/queue-4.4/arm-dts-dra7-do-not-gate-cpsw-clock-due-to-errata-i877.patch @@ -0,0 +1,70 @@ +From 0f514e690740e54815441a87708c3326f8aa8709 Mon Sep 17 00:00:00 2001 +From: Mugunthan V N +Date: Mon, 7 Mar 2016 01:41:22 -0700 +Subject: ARM: dts: dra7: do not gate cpsw clock due to errata i877 + +From: Mugunthan V N + +commit 0f514e690740e54815441a87708c3326f8aa8709 upstream. + +Errata id: i877 + +Description: +------------ +The RGMII 1000 Mbps Transmit timing is based on the output clock +(rgmiin_txc) being driven relative to the rising edge of an internal +clock and the output control/data (rgmiin_txctl/txd) being driven relative +to the falling edge of an internal clock source. If the internal clock +source is allowed to be static low (i.e., disabled) for an extended period +of time then when the clock is actually enabled the timing delta between +the rising edge and falling edge can change over the lifetime of the +device. This can result in the device switching characteristics degrading +over time, and eventually failing to meet the Data Manual Delay Time/Skew +specs. +To maintain RGMII 1000 Mbps IO Timings, SW should minimize the +duration that the Ethernet internal clock source is disabled. Note that +the device reset state for the Ethernet clock is "disabled". +Other RGMII modes (10 Mbps, 100Mbps) are not affected + +Workaround: +----------- +If the SoC Ethernet interface(s) are used in RGMII mode at 1000 Mbps, +SW should minimize the time the Ethernet internal clock source is disabled +to a maximum of 200 hours in a device life cycle. This is done by enabling +the clock as early as possible in IPL (QNX) or SPL/u-boot (Linux/Android) +by setting the register CM_GMAC_CLKSTCTRL[1:0]CLKTRCTRL = 0x2:SW_WKUP. + +So, do not allow to gate the cpsw clocks using ti,no-idle property in +cpsw node assuming 1000 Mbps is being used all the time. If someone does +not need 1000 Mbps and wants to gate clocks to cpsw, this property needs +to be deleted in their respective board files. + +Signed-off-by: Mugunthan V N +Signed-off-by: Grygorii Strashko +Signed-off-by: Lokesh Vutla +Signed-off-by: Paul Walmsley +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/boot/dts/dra7.dtsi | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/arch/arm/boot/dts/dra7.dtsi ++++ b/arch/arm/boot/dts/dra7.dtsi +@@ -1497,6 +1497,16 @@ + 0x48485200 0x2E00>; + #address-cells = <1>; + #size-cells = <1>; ++ ++ /* ++ * Do not allow gating of cpsw clock as workaround ++ * for errata i877. Keeping internal clock disabled ++ * causes the device switching characteristics ++ * to degrade over time and eventually fail to meet ++ * the data manual delay time/skew specs. ++ */ ++ ti,no-idle; ++ + /* + * rx_thresh_pend + * rx_pend diff --git a/queue-4.4/arm-mvebu-fix-overlap-of-crypto-sram-with-pcie-memory-window.patch b/queue-4.4/arm-mvebu-fix-overlap-of-crypto-sram-with-pcie-memory-window.patch new file mode 100644 index 00000000000..451a6fed6e5 --- /dev/null +++ b/queue-4.4/arm-mvebu-fix-overlap-of-crypto-sram-with-pcie-memory-window.patch @@ -0,0 +1,241 @@ +From d7d5a43c0d16760f25d892bf9329848167a8b8a4 Mon Sep 17 00:00:00 2001 +From: Thomas Petazzoni +Date: Tue, 8 Mar 2016 16:59:57 +0100 +Subject: ARM: mvebu: fix overlap of Crypto SRAM with PCIe memory window + +From: Thomas Petazzoni + +commit d7d5a43c0d16760f25d892bf9329848167a8b8a4 upstream. + +When the Crypto SRAM mappings were added to the Device Tree files +describing the Armada XP boards in commit c466d997bb16 ("ARM: mvebu: +define crypto SRAM ranges for all armada-xp boards"), the fact that +those mappings were overlaping with the PCIe memory aperture was +overlooked. Due to this, we currently have for all Armada XP platforms +a situation that looks like this: + +Memory mapping on Armada XP boards with internal registers at +0xf1000000: + + - 0x00000000 -> 0xf0000000 3.75G RAM + - 0xf0000000 -> 0xf1000000 16M NOR flashes (AXP GP / AXP DB) + - 0xf1000000 -> 0xf1100000 1M internal registers + - 0xf8000000 -> 0xffe0000 126M PCIe memory aperture + - 0xf8100000 -> 0xf8110000 64KB Crypto SRAM #0 => OVERLAPS WITH PCIE ! + - 0xf8110000 -> 0xf8120000 64KB Crypto SRAM #1 => OVERLAPS WITH PCIE ! + - 0xffe00000 -> 0xfff00000 1M PCIe I/O aperture + - 0xfff0000 -> 0xffffffff 1M BootROM + +The overlap means that when PCIe devices are added, depending on their +memory window needs, they might or might not be mapped into the +physical address space. Indeed, they will not be mapped if the area +allocated in the PCIe memory aperture by the PCI core overlaps with +one of the Crypto SRAM. Typically, a Intel IGB PCIe NIC that needs 8MB +of PCIe memory will see its PCIe memory window allocated from +0xf80000000 for 8MB, which overlaps with the Crypto SRAM windows. Due +to this, the PCIe window is not created, and any attempt to access the +PCIe window makes the kernel explode: + +[ 3.302213] igb: Copyright (c) 2007-2014 Intel Corporation. +[ 3.307841] pci 0000:00:09.0: enabling device (0140 -> 0143) +[ 3.313539] mvebu_mbus: cannot add window '4:f8', conflicts with another window +[ 3.320870] mvebu-pcie soc:pcie-controller: Could not create MBus window at [mem 0xf8000000-0xf87fffff]: -22 +[ 3.330811] Unhandled fault: external abort on non-linefetch (0x1008) at 0xf08c0018 + +This problem does not occur on Armada 370 boards, because we use the +following memory mapping (for boards that have internal registers at +0xf1000000): + + - 0x00000000 -> 0xf0000000 3.75G RAM + - 0xf0000000 -> 0xf1000000 16M NOR flashes (AXP GP / AXP DB) + - 0xf1000000 -> 0xf1100000 1M internal registers + - 0xf1100000 -> 0xf1110000 64KB Crypto SRAM #0 => OK ! + - 0xf8000000 -> 0xffe0000 126M PCIe memory + - 0xffe00000 -> 0xfff00000 1M PCIe I/O + - 0xfff0000 -> 0xffffffff 1M BootROM + +Obviously, the solution is to align the location of the Crypto SRAM +mappings of Armada XP to be similar with the ones on Armada 370, i.e +have them between the "internal registers" area and the beginning of +the PCIe aperture. + +However, we have a special case with the OpenBlocks AX3-4 platform, +which has a 128 MB NOR flash. Currently, this NOR flash is mapped from +0xf0000000 to 0xf8000000. This is possible because on OpenBlocks +AX3-4, the internal registers are not at 0xf1000000. And this explains +why the Crypto SRAM mappings were not configured at the same place on +Armada XP. + +Hence, the solution is two-fold: + + (1) Move the NOR flash mapping on Armada XP OpenBlocks AX3-4 from + 0xe8000000 to 0xf0000000. This frees the 0xf0000000 -> + 0xf80000000 space. + + (2) Move the Crypto SRAM mappings on Armada XP to be similar to + Armada 370 (except of course that Armada XP has two Crypto SRAM + and not one). + +After this patch, the memory mapping on Armada XP boards with +registers at 0xf1 is: + + - 0x00000000 -> 0xf0000000 3.75G RAM + - 0xf0000000 -> 0xf1000000 16M NOR flashes (AXP GP / AXP DB) + - 0xf1000000 -> 0xf1100000 1M internal registers + - 0xf1100000 -> 0xf1110000 64KB Crypto SRAM #0 + - 0xf1110000 -> 0xf1120000 64KB Crypto SRAM #1 + - 0xf8000000 -> 0xffe0000 126M PCIe memory + - 0xffe00000 -> 0xfff00000 1M PCIe I/O + - 0xfff0000 -> 0xffffffff 1M BootROM + +And the memory mapping for the special case of the OpenBlocks AX3-4 +(internal registers at 0xd0000000, NOR of 128 MB): + + - 0x00000000 -> 0xc0000000 3G RAM + - 0xd0000000 -> 0xd1000000 1M internal registers + - 0xe800000 -> 0xf0000000 128M NOR flash + - 0xf1100000 -> 0xf1110000 64KB Crypto SRAM #0 + - 0xf1110000 -> 0xf1120000 64KB Crypto SRAM #1 + - 0xf8000000 -> 0xffe0000 126M PCIe memory + - 0xffe00000 -> 0xfff00000 1M PCIe I/O + - 0xfff0000 -> 0xffffffff 1M BootROM + +Fixes: c466d997bb16 ("ARM: mvebu: define crypto SRAM ranges for all armada-xp boards") +Reported-by: Phil Sutter +Cc: Phil Sutter +Signed-off-by: Thomas Petazzoni +Acked-by: Gregory CLEMENT +Signed-off-by: Olof Johansson +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/boot/dts/armada-xp-axpwifiap.dts | 4 ++-- + arch/arm/boot/dts/armada-xp-db.dts | 4 ++-- + arch/arm/boot/dts/armada-xp-gp.dts | 4 ++-- + arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts | 4 ++-- + arch/arm/boot/dts/armada-xp-linksys-mamba.dts | 4 ++-- + arch/arm/boot/dts/armada-xp-matrix.dts | 4 ++-- + arch/arm/boot/dts/armada-xp-netgear-rn2120.dts | 4 ++-- + arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts | 6 +++--- + arch/arm/boot/dts/armada-xp-synology-ds414.dts | 4 ++-- + 9 files changed, 19 insertions(+), 19 deletions(-) + +--- a/arch/arm/boot/dts/armada-xp-axpwifiap.dts ++++ b/arch/arm/boot/dts/armada-xp-axpwifiap.dts +@@ -70,8 +70,8 @@ + soc { + ranges = ; ++ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000 ++ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>; + + pcie-controller { + status = "okay"; +--- a/arch/arm/boot/dts/armada-xp-db.dts ++++ b/arch/arm/boot/dts/armada-xp-db.dts +@@ -76,8 +76,8 @@ + ranges = ; ++ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000 ++ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>; + + devbus-bootcs { + status = "okay"; +--- a/arch/arm/boot/dts/armada-xp-gp.dts ++++ b/arch/arm/boot/dts/armada-xp-gp.dts +@@ -95,8 +95,8 @@ + ranges = ; ++ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000 ++ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>; + + devbus-bootcs { + status = "okay"; +--- a/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts ++++ b/arch/arm/boot/dts/armada-xp-lenovo-ix4-300d.dts +@@ -65,8 +65,8 @@ + soc { + ranges = ; ++ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000 ++ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>; + + pcie-controller { + status = "okay"; +--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts ++++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts +@@ -70,8 +70,8 @@ + soc { + ranges = ; ++ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000 ++ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>; + + pcie-controller { + status = "okay"; +--- a/arch/arm/boot/dts/armada-xp-matrix.dts ++++ b/arch/arm/boot/dts/armada-xp-matrix.dts +@@ -68,8 +68,8 @@ + soc { + ranges = ; ++ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000 ++ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>; + + internal-regs { + serial@12000 { +--- a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts ++++ b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts +@@ -64,8 +64,8 @@ + soc { + ranges = ; ++ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000 ++ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>; + + pcie-controller { + status = "okay"; +--- a/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts ++++ b/arch/arm/boot/dts/armada-xp-openblocks-ax3-4.dts +@@ -65,9 +65,9 @@ + soc { + ranges = ; ++ MBUS_ID(0x01, 0x2f) 0 0 0xe8000000 0x8000000 ++ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000 ++ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>; + + devbus-bootcs { + status = "okay"; +--- a/arch/arm/boot/dts/armada-xp-synology-ds414.dts ++++ b/arch/arm/boot/dts/armada-xp-synology-ds414.dts +@@ -78,8 +78,8 @@ + soc { + ranges = ; ++ MBUS_ID(0x09, 0x09) 0 0 0xf1100000 0x10000 ++ MBUS_ID(0x09, 0x05) 0 0 0xf1110000 0x10000>; + + pcie-controller { + status = "okay"; diff --git a/queue-4.4/arm-omap2-hwmod-introduce-ti-no-idle-dt-property.patch b/queue-4.4/arm-omap2-hwmod-introduce-ti-no-idle-dt-property.patch new file mode 100644 index 00000000000..b71ff824bc2 --- /dev/null +++ b/queue-4.4/arm-omap2-hwmod-introduce-ti-no-idle-dt-property.patch @@ -0,0 +1,89 @@ +From 2e18f5a1bc18e8af7031b3b26efde25307014837 Mon Sep 17 00:00:00 2001 +From: Lokesh Vutla +Date: Mon, 7 Mar 2016 01:41:21 -0700 +Subject: ARM: OMAP2+: hwmod: Introduce ti,no-idle dt property + +From: Lokesh Vutla + +commit 2e18f5a1bc18e8af7031b3b26efde25307014837 upstream. + +Introduce a dt property, ti,no-idle, that prevents an IP to idle at any +point. This is to handle Errata i877, which tells that GMAC clocks +cannot be disabled. + +Acked-by: Roger Quadros +Tested-by: Mugunthan V N +Signed-off-by: Lokesh Vutla +Signed-off-by: Sekhar Nori +Signed-off-by: Dave Gerlach +Acked-by: Rob Herring +Signed-off-by: Paul Walmsley +Signed-off-by: Greg Kroah-Hartman + +--- + Documentation/devicetree/bindings/arm/omap/omap.txt | 1 + + arch/arm/mach-omap2/omap_hwmod.c | 9 ++++++++- + arch/arm/mach-omap2/omap_hwmod.h | 3 +++ + 3 files changed, 12 insertions(+), 1 deletion(-) + +--- a/Documentation/devicetree/bindings/arm/omap/omap.txt ++++ b/Documentation/devicetree/bindings/arm/omap/omap.txt +@@ -23,6 +23,7 @@ Optional properties: + during suspend. + - ti,no-reset-on-init: When present, the module should not be reset at init + - ti,no-idle-on-init: When present, the module should not be idled at init ++- ti,no-idle: When present, the module is never allowed to idle. + + Example: + +--- a/arch/arm/mach-omap2/omap_hwmod.c ++++ b/arch/arm/mach-omap2/omap_hwmod.c +@@ -2200,6 +2200,11 @@ static int _enable(struct omap_hwmod *oh + */ + static int _idle(struct omap_hwmod *oh) + { ++ if (oh->flags & HWMOD_NO_IDLE) { ++ oh->_int_flags |= _HWMOD_SKIP_ENABLE; ++ return 0; ++ } ++ + pr_debug("omap_hwmod: %s: idling\n", oh->name); + + if (oh->_state != _HWMOD_STATE_ENABLED) { +@@ -2504,6 +2509,8 @@ static int __init _init(struct omap_hwmo + oh->flags |= HWMOD_INIT_NO_RESET; + if (of_find_property(np, "ti,no-idle-on-init", NULL)) + oh->flags |= HWMOD_INIT_NO_IDLE; ++ if (of_find_property(np, "ti,no-idle", NULL)) ++ oh->flags |= HWMOD_NO_IDLE; + } + + oh->_state = _HWMOD_STATE_INITIALIZED; +@@ -2630,7 +2637,7 @@ static void __init _setup_postsetup(stru + * XXX HWMOD_INIT_NO_IDLE does not belong in hwmod data - + * it should be set by the core code as a runtime flag during startup + */ +- if ((oh->flags & HWMOD_INIT_NO_IDLE) && ++ if ((oh->flags & (HWMOD_INIT_NO_IDLE | HWMOD_NO_IDLE)) && + (postsetup_state == _HWMOD_STATE_IDLE)) { + oh->_int_flags |= _HWMOD_SKIP_ENABLE; + postsetup_state = _HWMOD_STATE_ENABLED; +--- a/arch/arm/mach-omap2/omap_hwmod.h ++++ b/arch/arm/mach-omap2/omap_hwmod.h +@@ -525,6 +525,8 @@ struct omap_hwmod_omap4_prcm { + * or idled. + * HWMOD_OPT_CLKS_NEEDED: The optional clocks are needed for the module to + * operate and they need to be handled at the same time as the main_clk. ++ * HWMOD_NO_IDLE: Do not idle the hwmod at all. Useful to handle certain ++ * IPs like CPSW on DRA7, where clocks to this module cannot be disabled. + */ + #define HWMOD_SWSUP_SIDLE (1 << 0) + #define HWMOD_SWSUP_MSTANDBY (1 << 1) +@@ -541,6 +543,7 @@ struct omap_hwmod_omap4_prcm { + #define HWMOD_SWSUP_SIDLE_ACT (1 << 12) + #define HWMOD_RECONFIG_IO_CHAIN (1 << 13) + #define HWMOD_OPT_CLKS_NEEDED (1 << 14) ++#define HWMOD_NO_IDLE (1 << 15) + + /* + * omap_hwmod._int_flags definitions diff --git a/queue-4.4/arm64-account-for-sparsemem-section-alignment-when-choosing-vmemmap-offset.patch b/queue-4.4/arm64-account-for-sparsemem-section-alignment-when-choosing-vmemmap-offset.patch new file mode 100644 index 00000000000..d770adc7340 --- /dev/null +++ b/queue-4.4/arm64-account-for-sparsemem-section-alignment-when-choosing-vmemmap-offset.patch @@ -0,0 +1,58 @@ +From 36e5cd6b897e17d03008f81e075625d8e43e52d0 Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +Date: Tue, 8 Mar 2016 21:09:29 +0700 +Subject: arm64: account for sparsemem section alignment when choosing vmemmap offset + +From: Ard Biesheuvel + +commit 36e5cd6b897e17d03008f81e075625d8e43e52d0 upstream. + +Commit dfd55ad85e4a ("arm64: vmemmap: use virtual projection of linear +region") fixed an issue where the struct page array would overflow into the +adjacent virtual memory region if system RAM was placed so high up in +physical memory that its addresses were not representable in the build time +configured virtual address size. + +However, the fix failed to take into account that the vmemmap region needs +to be relatively aligned with respect to the sparsemem section size, so that +a sequence of page structs corresponding with a sparsemem section in the +linear region appears naturally aligned in the vmemmap region. + +So round up vmemmap to sparsemem section size. Since this essentially moves +the projection of the linear region up in memory, also revert the reduction +of the size of the vmemmap region. + +Fixes: dfd55ad85e4a ("arm64: vmemmap: use virtual projection of linear region") +Tested-by: Mark Langsdorf +Tested-by: David Daney +Tested-by: Robert Richter +Acked-by: Catalin Marinas +Signed-off-by: Ard Biesheuvel +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/include/asm/pgtable.h | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/arch/arm64/include/asm/pgtable.h ++++ b/arch/arm64/include/asm/pgtable.h +@@ -40,7 +40,7 @@ + * VMALLOC_END: extends to the available space below vmmemmap, PCI I/O space, + * fixed mappings and modules + */ +-#define VMEMMAP_SIZE ALIGN((1UL << (VA_BITS - PAGE_SHIFT - 1)) * sizeof(struct page), PUD_SIZE) ++#define VMEMMAP_SIZE ALIGN((1UL << (VA_BITS - PAGE_SHIFT)) * sizeof(struct page), PUD_SIZE) + + #ifndef CONFIG_KASAN + #define VMALLOC_START (VA_START) +@@ -52,7 +52,8 @@ + #define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K) + + #define VMEMMAP_START (VMALLOC_END + SZ_64K) +-#define vmemmap ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT)) ++#define vmemmap ((struct page *)VMEMMAP_START - \ ++ SECTION_ALIGN_DOWN(memstart_addr >> PAGE_SHIFT)) + + #define FIRST_USER_ADDRESS 0UL + diff --git a/queue-4.4/asoc-dapm-fix-ctl-value-accesses-in-a-wrong-type.patch b/queue-4.4/asoc-dapm-fix-ctl-value-accesses-in-a-wrong-type.patch new file mode 100644 index 00000000000..bd8c34aada0 --- /dev/null +++ b/queue-4.4/asoc-dapm-fix-ctl-value-accesses-in-a-wrong-type.patch @@ -0,0 +1,51 @@ +From 741338f99f16dc24d2d01ac777b0798ae9d10a90 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 29 Feb 2016 17:20:48 +0100 +Subject: ASoC: dapm: Fix ctl value accesses in a wrong type + +From: Takashi Iwai + +commit 741338f99f16dc24d2d01ac777b0798ae9d10a90 upstream. + +snd_soc_dapm_dai_link_get() and _put() access the associated ctl +values as value.integer.value[]. However, this is an enum ctl, and it +has to be accessed via value.enumerated.item[]. The former is long +while the latter is unsigned int, so they don't align. + +Fixes: c66150824b8a ('ASoC: dapm: add code to configure dai link parameters') +Signed-off-by: Takashi Iwai +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/soc-dapm.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/sound/soc/soc-dapm.c ++++ b/sound/soc/soc-dapm.c +@@ -3568,7 +3568,7 @@ static int snd_soc_dapm_dai_link_get(str + { + struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol); + +- ucontrol->value.integer.value[0] = w->params_select; ++ ucontrol->value.enumerated.item[0] = w->params_select; + + return 0; + } +@@ -3582,13 +3582,13 @@ static int snd_soc_dapm_dai_link_put(str + if (w->power) + return -EBUSY; + +- if (ucontrol->value.integer.value[0] == w->params_select) ++ if (ucontrol->value.enumerated.item[0] == w->params_select) + return 0; + +- if (ucontrol->value.integer.value[0] >= w->num_params) ++ if (ucontrol->value.enumerated.item[0] >= w->num_params) + return -EINVAL; + +- w->params_select = ucontrol->value.integer.value[0]; ++ w->params_select = ucontrol->value.enumerated.item[0]; + + return 0; + } diff --git a/queue-4.4/asoc-samsung-use-irq-safe-spin-lock-calls.patch b/queue-4.4/asoc-samsung-use-irq-safe-spin-lock-calls.patch new file mode 100644 index 00000000000..62ddd92132d --- /dev/null +++ b/queue-4.4/asoc-samsung-use-irq-safe-spin-lock-calls.patch @@ -0,0 +1,126 @@ +From 316fa9e09ad76e095b9d7e9350c628b918370a22 Mon Sep 17 00:00:00 2001 +From: Charles Keepax +Date: Thu, 18 Feb 2016 15:47:13 +0000 +Subject: ASoC: samsung: Use IRQ safe spin lock calls + +From: Charles Keepax + +commit 316fa9e09ad76e095b9d7e9350c628b918370a22 upstream. + +Lockdep warns of a potential lock inversion, i2s->lock is held numerous +times whilst we are under the substream lock (snd_pcm_stream_lock). If +we use the IRQ unsafe spin lock calls, you can also end up locking +snd_pcm_stream_lock whilst under i2s->lock (if an IRQ happens whilst we +are holding i2s->lock). This could result in deadlock. + +[ 18.147001] CPU0 CPU1 +[ 18.151509] ---- ---- +[ 18.156022] lock(&(&pri_dai->spinlock)->rlock); +[ 18.160701] local_irq_disable(); +[ 18.166622] lock(&(&substream->self_group.lock)->rlock); +[ 18.174595] lock(&(&pri_dai->spinlock)->rlock); +[ 18.181806] +[ 18.184408] lock(&(&substream->self_group.lock)->rlock); +[ 18.190045] +[ 18.190045] *** DEADLOCK *** + +This patch changes to using the irq safe spinlock calls, to avoid this +issue. + +Fixes: ce8bcdbb61d9 ("ASoC: samsung: i2s: Protect more registers with a spinlock") +Signed-off-by: Charles Keepax +Tested-by: Anand Moon +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/samsung/i2s.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +--- a/sound/soc/samsung/i2s.c ++++ b/sound/soc/samsung/i2s.c +@@ -480,10 +480,11 @@ static int i2s_set_sysclk(struct snd_soc + unsigned int cdcon_mask = 1 << i2s_regs->cdclkcon_off; + unsigned int rsrc_mask = 1 << i2s_regs->rclksrc_off; + u32 mod, mask, val = 0; ++ unsigned long flags; + +- spin_lock(i2s->lock); ++ spin_lock_irqsave(i2s->lock, flags); + mod = readl(i2s->addr + I2SMOD); +- spin_unlock(i2s->lock); ++ spin_unlock_irqrestore(i2s->lock, flags); + + switch (clk_id) { + case SAMSUNG_I2S_OPCLK: +@@ -574,11 +575,11 @@ static int i2s_set_sysclk(struct snd_soc + return -EINVAL; + } + +- spin_lock(i2s->lock); ++ spin_lock_irqsave(i2s->lock, flags); + mod = readl(i2s->addr + I2SMOD); + mod = (mod & ~mask) | val; + writel(mod, i2s->addr + I2SMOD); +- spin_unlock(i2s->lock); ++ spin_unlock_irqrestore(i2s->lock, flags); + + return 0; + } +@@ -589,6 +590,7 @@ static int i2s_set_fmt(struct snd_soc_da + struct i2s_dai *i2s = to_info(dai); + int lrp_shift, sdf_shift, sdf_mask, lrp_rlow, mod_slave; + u32 mod, tmp = 0; ++ unsigned long flags; + + lrp_shift = i2s->variant_regs->lrp_off; + sdf_shift = i2s->variant_regs->sdf_off; +@@ -648,7 +650,7 @@ static int i2s_set_fmt(struct snd_soc_da + return -EINVAL; + } + +- spin_lock(i2s->lock); ++ spin_lock_irqsave(i2s->lock, flags); + mod = readl(i2s->addr + I2SMOD); + /* + * Don't change the I2S mode if any controller is active on this +@@ -656,7 +658,7 @@ static int i2s_set_fmt(struct snd_soc_da + */ + if (any_active(i2s) && + ((mod & (sdf_mask | lrp_rlow | mod_slave)) != tmp)) { +- spin_unlock(i2s->lock); ++ spin_unlock_irqrestore(i2s->lock, flags); + dev_err(&i2s->pdev->dev, + "%s:%d Other DAI busy\n", __func__, __LINE__); + return -EAGAIN; +@@ -665,7 +667,7 @@ static int i2s_set_fmt(struct snd_soc_da + mod &= ~(sdf_mask | lrp_rlow | mod_slave); + mod |= tmp; + writel(mod, i2s->addr + I2SMOD); +- spin_unlock(i2s->lock); ++ spin_unlock_irqrestore(i2s->lock, flags); + + return 0; + } +@@ -675,6 +677,7 @@ static int i2s_hw_params(struct snd_pcm_ + { + struct i2s_dai *i2s = to_info(dai); + u32 mod, mask = 0, val = 0; ++ unsigned long flags; + + if (!is_secondary(i2s)) + mask |= (MOD_DC2_EN | MOD_DC1_EN); +@@ -743,11 +746,11 @@ static int i2s_hw_params(struct snd_pcm_ + return -EINVAL; + } + +- spin_lock(i2s->lock); ++ spin_lock_irqsave(i2s->lock, flags); + mod = readl(i2s->addr + I2SMOD); + mod = (mod & ~mask) | val; + writel(mod, i2s->addr + I2SMOD); +- spin_unlock(i2s->lock); ++ spin_unlock_irqrestore(i2s->lock, flags); + + samsung_asoc_init_dma_data(dai, &i2s->dma_playback, &i2s->dma_capture); + diff --git a/queue-4.4/asoc-wm8958-fix-enum-ctl-accesses-in-a-wrong-type.patch b/queue-4.4/asoc-wm8958-fix-enum-ctl-accesses-in-a-wrong-type.patch new file mode 100644 index 00000000000..cd60f1b1a94 --- /dev/null +++ b/queue-4.4/asoc-wm8958-fix-enum-ctl-accesses-in-a-wrong-type.patch @@ -0,0 +1,60 @@ +From d0784829ae3b0beeb69b476f017d5c8a2eb95198 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 29 Feb 2016 18:01:12 +0100 +Subject: ASoC: wm8958: Fix enum ctl accesses in a wrong type + +From: Takashi Iwai + +commit d0784829ae3b0beeb69b476f017d5c8a2eb95198 upstream. + +"MBC Mode", "VSS Mode", "VSS HPF Mode" and "Enhanced EQ Mode" ctls in +wm8958 codec driver are enum, while the current driver accesses +wrongly via value.integer.value[]. They have to be via +value.enumerated.item[] instead. + +Signed-off-by: Takashi Iwai +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/codecs/wm8958-dsp2.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/sound/soc/codecs/wm8958-dsp2.c ++++ b/sound/soc/codecs/wm8958-dsp2.c +@@ -459,7 +459,7 @@ static int wm8958_put_mbc_enum(struct sn + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994 *control = wm8994->wm8994; +- int value = ucontrol->value.integer.value[0]; ++ int value = ucontrol->value.enumerated.item[0]; + int reg; + + /* Don't allow on the fly reconfiguration */ +@@ -549,7 +549,7 @@ static int wm8958_put_vss_enum(struct sn + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994 *control = wm8994->wm8994; +- int value = ucontrol->value.integer.value[0]; ++ int value = ucontrol->value.enumerated.item[0]; + int reg; + + /* Don't allow on the fly reconfiguration */ +@@ -582,7 +582,7 @@ static int wm8958_put_vss_hpf_enum(struc + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994 *control = wm8994->wm8994; +- int value = ucontrol->value.integer.value[0]; ++ int value = ucontrol->value.enumerated.item[0]; + int reg; + + /* Don't allow on the fly reconfiguration */ +@@ -749,7 +749,7 @@ static int wm8958_put_enh_eq_enum(struct + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994 *control = wm8994->wm8994; +- int value = ucontrol->value.integer.value[0]; ++ int value = ucontrol->value.enumerated.item[0]; + int reg; + + /* Don't allow on the fly reconfiguration */ diff --git a/queue-4.4/asoc-wm8994-fix-enum-ctl-accesses-in-a-wrong-type.patch b/queue-4.4/asoc-wm8994-fix-enum-ctl-accesses-in-a-wrong-type.patch new file mode 100644 index 00000000000..711d0c8f784 --- /dev/null +++ b/queue-4.4/asoc-wm8994-fix-enum-ctl-accesses-in-a-wrong-type.patch @@ -0,0 +1,42 @@ +From 8019c0b37cd5a87107808300a496388b777225bf Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Mon, 29 Feb 2016 18:01:15 +0100 +Subject: ASoC: wm8994: Fix enum ctl accesses in a wrong type + +From: Takashi Iwai + +commit 8019c0b37cd5a87107808300a496388b777225bf upstream. + +The DRC Mode like "AIF1DRC1 Mode" and EQ Mode like "AIF1.1 EQ Mode" in +wm8994 codec driver are enum ctls, while the current driver accesses +wrongly via value.integer.value[]. They have to be via +value.enumerated.item[] instead. + +Signed-off-by: Takashi Iwai +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/codecs/wm8994.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/sound/soc/codecs/wm8994.c ++++ b/sound/soc/codecs/wm8994.c +@@ -362,7 +362,7 @@ static int wm8994_put_drc_enum(struct sn + struct wm8994 *control = wm8994->wm8994; + struct wm8994_pdata *pdata = &control->pdata; + int drc = wm8994_get_drc(kcontrol->id.name); +- int value = ucontrol->value.integer.value[0]; ++ int value = ucontrol->value.enumerated.item[0]; + + if (drc < 0) + return drc; +@@ -469,7 +469,7 @@ static int wm8994_put_retune_mobile_enum + struct wm8994 *control = wm8994->wm8994; + struct wm8994_pdata *pdata = &control->pdata; + int block = wm8994_get_retune_mobile_block(kcontrol->id.name); +- int value = ucontrol->value.integer.value[0]; ++ int value = ucontrol->value.enumerated.item[0]; + + if (block < 0) + return block; diff --git a/queue-4.4/can-gs_usb-fixed-disconnect-bug-by-removing-erroneous-use-of-kfree.patch b/queue-4.4/can-gs_usb-fixed-disconnect-bug-by-removing-erroneous-use-of-kfree.patch new file mode 100644 index 00000000000..e335d47b2d7 --- /dev/null +++ b/queue-4.4/can-gs_usb-fixed-disconnect-bug-by-removing-erroneous-use-of-kfree.patch @@ -0,0 +1,80 @@ +From e9a2d81b1761093386a0bb8a4f51642ac785ef63 Mon Sep 17 00:00:00 2001 +From: Maximilain Schneider +Date: Tue, 23 Feb 2016 01:17:28 +0000 +Subject: can: gs_usb: fixed disconnect bug by removing erroneous use of kfree() + +From: Maximilain Schneider + +commit e9a2d81b1761093386a0bb8a4f51642ac785ef63 upstream. + +gs_destroy_candev() erroneously calls kfree() on a struct gs_can *, which is +allocated through alloc_candev() and should instead be freed using +free_candev() alone. + +The inappropriate use of kfree() causes the kernel to hang when +gs_destroy_candev() is called. + +Only the struct gs_usb * which is allocated through kzalloc() should be freed +using kfree() when the device is disconnected. + +Signed-off-by: Maximilian Schneider +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/usb/gs_usb.c | 24 +++++++++++------------- + 1 file changed, 11 insertions(+), 13 deletions(-) + +--- a/drivers/net/can/usb/gs_usb.c ++++ b/drivers/net/can/usb/gs_usb.c +@@ -826,9 +826,8 @@ static struct gs_can *gs_make_candev(uns + static void gs_destroy_candev(struct gs_can *dev) + { + unregister_candev(dev->netdev); +- free_candev(dev->netdev); + usb_kill_anchored_urbs(&dev->tx_submitted); +- kfree(dev); ++ free_candev(dev->netdev); + } + + static int gs_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) +@@ -913,12 +912,15 @@ static int gs_usb_probe(struct usb_inter + for (i = 0; i < icount; i++) { + dev->canch[i] = gs_make_candev(i, intf); + if (IS_ERR_OR_NULL(dev->canch[i])) { ++ /* save error code to return later */ ++ rc = PTR_ERR(dev->canch[i]); ++ + /* on failure destroy previously created candevs */ + icount = i; +- for (i = 0; i < icount; i++) { ++ for (i = 0; i < icount; i++) + gs_destroy_candev(dev->canch[i]); +- dev->canch[i] = NULL; +- } ++ ++ usb_kill_anchored_urbs(&dev->rx_submitted); + kfree(dev); + return rc; + } +@@ -939,16 +941,12 @@ static void gs_usb_disconnect(struct usb + return; + } + +- for (i = 0; i < GS_MAX_INTF; i++) { +- struct gs_can *can = dev->canch[i]; +- +- if (!can) +- continue; +- +- gs_destroy_candev(can); +- } ++ for (i = 0; i < GS_MAX_INTF; i++) ++ if (dev->canch[i]) ++ gs_destroy_candev(dev->canch[i]); + + usb_kill_anchored_urbs(&dev->rx_submitted); ++ kfree(dev); + } + + static const struct usb_device_id gs_usb_table[] = { diff --git a/queue-4.4/cfg80211-wext-fix-message-ordering.patch b/queue-4.4/cfg80211-wext-fix-message-ordering.patch new file mode 100644 index 00000000000..2183bb691ea --- /dev/null +++ b/queue-4.4/cfg80211-wext-fix-message-ordering.patch @@ -0,0 +1,79 @@ +From cb150b9d23be6ee7f3a0fff29784f1c5b5ac514d Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Wed, 27 Jan 2016 13:29:34 +0100 +Subject: cfg80211/wext: fix message ordering + +From: Johannes Berg + +commit cb150b9d23be6ee7f3a0fff29784f1c5b5ac514d upstream. + +Since cfg80211 frequently takes actions from its netdev notifier +call, wireless extensions messages could still be ordered badly +since the wext netdev notifier, since wext is built into the +kernel, runs before the cfg80211 netdev notifier. For example, +the following can happen: + +5: wlan1: mtu 1500 qdisc mq state DOWN group default + link/ether 02:00:00:00:01:00 brd ff:ff:ff:ff:ff:ff +5: wlan1: + link/ether + +when setting the interface down causes the wext message. + +To also fix this, export the wireless_nlevent_flush() function +and also call it from the cfg80211 notifier. + +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/iw_handler.h | 6 ++++++ + net/wireless/core.c | 2 ++ + net/wireless/wext-core.c | 3 ++- + 3 files changed, 10 insertions(+), 1 deletion(-) + +--- a/include/net/iw_handler.h ++++ b/include/net/iw_handler.h +@@ -439,6 +439,12 @@ int dev_get_wireless_info(char *buffer, + /* Send a single event to user space */ + void wireless_send_event(struct net_device *dev, unsigned int cmd, + union iwreq_data *wrqu, const char *extra); ++#ifdef CONFIG_WEXT_CORE ++/* flush all previous wext events - if work is done from netdev notifiers */ ++void wireless_nlevent_flush(void); ++#else ++static inline void wireless_nlevent_flush(void) {} ++#endif + + /* We may need a function to send a stream of events to user space. + * More on that later... */ +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -1147,6 +1147,8 @@ static int cfg80211_netdev_notifier_call + return NOTIFY_DONE; + } + ++ wireless_nlevent_flush(); ++ + return NOTIFY_OK; + } + +--- a/net/wireless/wext-core.c ++++ b/net/wireless/wext-core.c +@@ -342,7 +342,7 @@ static const int compat_event_type_size[ + + /* IW event code */ + +-static void wireless_nlevent_flush(void) ++void wireless_nlevent_flush(void) + { + struct sk_buff *skb; + struct net *net; +@@ -355,6 +355,7 @@ static void wireless_nlevent_flush(void) + GFP_KERNEL); + } + } ++EXPORT_SYMBOL_GPL(wireless_nlevent_flush); + + static int wext_netdev_notifier_call(struct notifier_block *nb, + unsigned long state, void *ptr) diff --git a/queue-4.4/dmaengine-at_xdmac-fix-residue-computation.patch b/queue-4.4/dmaengine-at_xdmac-fix-residue-computation.patch new file mode 100644 index 00000000000..bfb460aaf8e --- /dev/null +++ b/queue-4.4/dmaengine-at_xdmac-fix-residue-computation.patch @@ -0,0 +1,101 @@ +From 25c5e9626ca4d40928dc9c44f009ce2ed0a739e7 Mon Sep 17 00:00:00 2001 +From: Ludovic Desroches +Date: Thu, 10 Mar 2016 10:17:55 +0100 +Subject: dmaengine: at_xdmac: fix residue computation + +From: Ludovic Desroches + +commit 25c5e9626ca4d40928dc9c44f009ce2ed0a739e7 upstream. + +When computing the residue we need two pieces of information: the current +descriptor and the remaining data of the current descriptor. To get +that information, we need to read consecutively two registers but we +can't do it in an atomic way. For that reason, we have to check manually +that current descriptor has not changed. + +Signed-off-by: Ludovic Desroches +Suggested-by: Cyrille Pitchen +Reported-by: David Engraf +Tested-by: David Engraf +Fixes: e1f7c9eee707 ("dmaengine: at_xdmac: creation of the atmel +eXtended DMA Controller driver") +Signed-off-by: Vinod Koul +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/dma/at_xdmac.c | 42 +++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 39 insertions(+), 3 deletions(-) + +--- a/drivers/dma/at_xdmac.c ++++ b/drivers/dma/at_xdmac.c +@@ -176,6 +176,7 @@ + #define AT_XDMAC_MAX_CHAN 0x20 + #define AT_XDMAC_MAX_CSIZE 16 /* 16 data */ + #define AT_XDMAC_MAX_DWIDTH 8 /* 64 bits */ ++#define AT_XDMAC_RESIDUE_MAX_RETRIES 5 + + #define AT_XDMAC_DMA_BUSWIDTHS\ + (BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) |\ +@@ -1383,8 +1384,8 @@ at_xdmac_tx_status(struct dma_chan *chan + struct at_xdmac_desc *desc, *_desc; + struct list_head *descs_list; + enum dma_status ret; +- int residue; +- u32 cur_nda, mask, value; ++ int residue, retry; ++ u32 cur_nda, check_nda, cur_ubc, mask, value; + u8 dwidth = 0; + unsigned long flags; + +@@ -1421,7 +1422,42 @@ at_xdmac_tx_status(struct dma_chan *chan + cpu_relax(); + } + ++ /* ++ * When processing the residue, we need to read two registers but we ++ * can't do it in an atomic way. AT_XDMAC_CNDA is used to find where ++ * we stand in the descriptor list and AT_XDMAC_CUBC is used ++ * to know how many data are remaining for the current descriptor. ++ * Since the dma channel is not paused to not loose data, between the ++ * AT_XDMAC_CNDA and AT_XDMAC_CUBC read, we may have change of ++ * descriptor. ++ * For that reason, after reading AT_XDMAC_CUBC, we check if we are ++ * still using the same descriptor by reading a second time ++ * AT_XDMAC_CNDA. If AT_XDMAC_CNDA has changed, it means we have to ++ * read again AT_XDMAC_CUBC. ++ * Memory barriers are used to ensure the read order of the registers. ++ * A max number of retries is set because unlikely it can never ends if ++ * we are transferring a lot of data with small buffers. ++ */ + cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc; ++ rmb(); ++ cur_ubc = at_xdmac_chan_read(atchan, AT_XDMAC_CUBC); ++ for (retry = 0; retry < AT_XDMAC_RESIDUE_MAX_RETRIES; retry++) { ++ rmb(); ++ check_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc; ++ ++ if (likely(cur_nda == check_nda)) ++ break; ++ ++ cur_nda = check_nda; ++ rmb(); ++ cur_ubc = at_xdmac_chan_read(atchan, AT_XDMAC_CUBC); ++ } ++ ++ if (unlikely(retry >= AT_XDMAC_RESIDUE_MAX_RETRIES)) { ++ ret = DMA_ERROR; ++ goto spin_unlock; ++ } ++ + /* + * Remove size of all microblocks already transferred and the current + * one. Then add the remaining size to transfer of the current +@@ -1434,7 +1470,7 @@ at_xdmac_tx_status(struct dma_chan *chan + if ((desc->lld.mbr_nda & 0xfffffffc) == cur_nda) + break; + } +- residue += at_xdmac_chan_read(atchan, AT_XDMAC_CUBC) << dwidth; ++ residue += cur_ubc << dwidth; + + dma_set_residue(txstate, residue); + diff --git a/queue-4.4/drm-amdgpu-fix-error-handling-in-amdgpu_flip_work_func.patch b/queue-4.4/drm-amdgpu-fix-error-handling-in-amdgpu_flip_work_func.patch new file mode 100644 index 00000000000..c3e43b3ed40 --- /dev/null +++ b/queue-4.4/drm-amdgpu-fix-error-handling-in-amdgpu_flip_work_func.patch @@ -0,0 +1,69 @@ +From 90e94b160c7f647ddffda707f5e3c0c66c170df8 Mon Sep 17 00:00:00 2001 +From: Mario Kleiner +Date: Tue, 1 Mar 2016 21:31:16 +0100 +Subject: drm/amdgpu: Fix error handling in amdgpu_flip_work_func. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mario Kleiner + +commit 90e94b160c7f647ddffda707f5e3c0c66c170df8 upstream. + +The patch e1d09dc0ccc6: "drm/amdgpu: Don't hang in +amdgpu_flip_work_func on disabled crtc." from Feb 19, 2016, leads to +the following static checker warning, as reported by Dan Carpenter in +https://lists.freedesktop.org/archives/dri-devel/2016-February/101987.html + +drivers/gpu/drm/amd/amdgpu/amdgpu_display.c:127 amdgpu_flip_work_func() warn: should this be 'repcnt == -1' +drivers/gpu/drm/amd/amdgpu/amdgpu_display.c:136 amdgpu_flip_work_func() error: double unlock 'spin_lock:&crtc->dev->event_lock' +drivers/gpu/drm/amd/amdgpu/amdgpu_display.c:136 amdgpu_flip_work_func() error: double unlock 'irqsave:flags' + +This patch fixes both reported problems: + +Change post-decrement of repcnt to pre-decrement, so +it can't underflow anymore, but still performs up to +three repetitions - three is the maximum one could +expect in practice. + +Move the spin_unlock_irqrestore to where it actually +belongs. + +Reviewed-by: Michel Dänzer +Reported-by: Dan Carpenter +Signed-off-by: Mario Kleiner +Cc: Michel Dänzer +Cc: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +@@ -96,7 +96,7 @@ static void amdgpu_flip_work_func(struct + * In practice this won't execute very often unless on very fast + * machines because the time window for this to happen is very small. + */ +- while (amdgpuCrtc->enabled && repcnt--) { ++ while (amdgpuCrtc->enabled && --repcnt) { + /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank + * start in hpos, and to the "fudged earlier" vblank start in + * vpos. +@@ -112,13 +112,13 @@ static void amdgpu_flip_work_func(struct + break; + + /* Sleep at least until estimated real start of hw vblank */ +- spin_unlock_irqrestore(&crtc->dev->event_lock, flags); + min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5); + if (min_udelay > vblank->framedur_ns / 2000) { + /* Don't wait ridiculously long - something is wrong */ + repcnt = 0; + break; + } ++ spin_unlock_irqrestore(&crtc->dev->event_lock, flags); + usleep_range(min_udelay, 2 * min_udelay); + spin_lock_irqsave(&crtc->dev->event_lock, flags); + }; diff --git a/queue-4.4/drm-radeon-fix-error-handling-in-radeon_flip_work_func.patch b/queue-4.4/drm-radeon-fix-error-handling-in-radeon_flip_work_func.patch new file mode 100644 index 00000000000..a6712c39e6e --- /dev/null +++ b/queue-4.4/drm-radeon-fix-error-handling-in-radeon_flip_work_func.patch @@ -0,0 +1,73 @@ +From 1e1490a38504419e349caa1b7d55d5c141a9bccb Mon Sep 17 00:00:00 2001 +From: Mario Kleiner +Date: Tue, 1 Mar 2016 21:31:17 +0100 +Subject: drm/radeon: Fix error handling in radeon_flip_work_func. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mario Kleiner + +commit 1e1490a38504419e349caa1b7d55d5c141a9bccb upstream. + +This is a port of the patch "drm/amdgpu: Fix error handling in amdgpu_flip_work_func." +to fix the following problem for radeon as well which was +reported against amdgpu: + +The patch e1d09dc0ccc6: "drm/amdgpu: Don't hang in +amdgpu_flip_work_func on disabled crtc." from Feb 19, 2016, leads to +the following static checker warning, as reported by Dan Carpenter in +https://lists.freedesktop.org/archives/dri-devel/2016-February/101987.html + +drivers/gpu/drm/amd/amdgpu/amdgpu_display.c:127 amdgpu_flip_work_func() warn: should this be 'repcnt == -1' +drivers/gpu/drm/amd/amdgpu/amdgpu_display.c:136 amdgpu_flip_work_func() error: double unlock 'spin_lock:&crtc->dev->event_lock' +drivers/gpu/drm/amd/amdgpu/amdgpu_display.c:136 amdgpu_flip_work_func() error: double unlock 'irqsave:flags' + +This patch fixes both reported problems: + +Change post-decrement of repcnt to pre-decrement, so +it can't underflow anymore, but still performs up to +three repetitions - three is the maximum one could +expect in practice. + +Move the spin_unlock_irqrestore to where it actually +belongs. + +Reviewed-by: Michel Dänzer +Reported-by: Dan Carpenter +Signed-off-by: Mario Kleiner +Cc: Michel Dänzer +Cc: Alex Deucher +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_display.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_display.c ++++ b/drivers/gpu/drm/radeon/radeon_display.c +@@ -455,7 +455,7 @@ static void radeon_flip_work_func(struct + * In practice this won't execute very often unless on very fast + * machines because the time window for this to happen is very small. + */ +- while (radeon_crtc->enabled && repcnt--) { ++ while (radeon_crtc->enabled && --repcnt) { + /* GET_DISTANCE_TO_VBLANKSTART returns distance to real vblank + * start in hpos, and to the "fudged earlier" vblank start in + * vpos. +@@ -471,13 +471,13 @@ static void radeon_flip_work_func(struct + break; + + /* Sleep at least until estimated real start of hw vblank */ +- spin_unlock_irqrestore(&crtc->dev->event_lock, flags); + min_udelay = (-hpos + 1) * max(vblank->linedur_ns / 1000, 5); + if (min_udelay > vblank->framedur_ns / 2000) { + /* Don't wait ridiculously long - something is wrong */ + repcnt = 0; + break; + } ++ spin_unlock_irqrestore(&crtc->dev->event_lock, flags); + usleep_range(min_udelay, 2 * min_udelay); + spin_lock_irqsave(&crtc->dev->event_lock, flags); + }; diff --git a/queue-4.4/gpu-ipu-v3-do-not-bail-out-on-missing-optional-port-nodes.patch b/queue-4.4/gpu-ipu-v3-do-not-bail-out-on-missing-optional-port-nodes.patch new file mode 100644 index 00000000000..38a9777d899 --- /dev/null +++ b/queue-4.4/gpu-ipu-v3-do-not-bail-out-on-missing-optional-port-nodes.patch @@ -0,0 +1,60 @@ +From 17e0521750399205f432966e602e125294879cdd Mon Sep 17 00:00:00 2001 +From: Philipp Zabel +Date: Mon, 4 Jan 2016 17:32:26 +0100 +Subject: gpu: ipu-v3: Do not bail out on missing optional port nodes + +From: Philipp Zabel + +commit 17e0521750399205f432966e602e125294879cdd upstream. + +The port nodes are documented as optional, treat them accordingly. + +Reported-by: Martin Fuzzey +Reported-by: Chris Healy +Signed-off-by: Philipp Zabel +Fixes: 304e6be652e2 ("gpu: ipu-v3: Assign of_node of child platform devices to corresponding ports") +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/ipu-v3/ipu-common.c | 21 ++++++++++++--------- + 1 file changed, 12 insertions(+), 9 deletions(-) + +--- a/drivers/gpu/ipu-v3/ipu-common.c ++++ b/drivers/gpu/ipu-v3/ipu-common.c +@@ -1050,6 +1050,17 @@ static int ipu_add_client_devices(struct + for (i = 0; i < ARRAY_SIZE(client_reg); i++) { + const struct ipu_platform_reg *reg = &client_reg[i]; + struct platform_device *pdev; ++ struct device_node *of_node; ++ ++ /* Associate subdevice with the corresponding port node */ ++ of_node = of_graph_get_port_by_id(dev->of_node, i); ++ if (!of_node) { ++ dev_info(dev, ++ "no port@%d node in %s, not using %s%d\n", ++ i, dev->of_node->full_name, ++ (i / 2) ? "DI" : "CSI", i % 2); ++ continue; ++ } + + pdev = platform_device_alloc(reg->name, id++); + if (!pdev) { +@@ -1057,17 +1068,9 @@ static int ipu_add_client_devices(struct + goto err_register; + } + ++ pdev->dev.of_node = of_node; + pdev->dev.parent = dev; + +- /* Associate subdevice with the corresponding port node */ +- pdev->dev.of_node = of_graph_get_port_by_id(dev->of_node, i); +- if (!pdev->dev.of_node) { +- dev_err(dev, "missing port@%d node in %s\n", i, +- dev->of_node->full_name); +- ret = -ENODEV; +- goto err_register; +- } +- + ret = platform_device_add_data(pdev, ®->pdata, + sizeof(reg->pdata)); + if (!ret) diff --git a/queue-4.4/iwlwifi-mvm-inc-pending-frames-counter-also-when-txing-non-sta.patch b/queue-4.4/iwlwifi-mvm-inc-pending-frames-counter-also-when-txing-non-sta.patch new file mode 100644 index 00000000000..97378f0aa93 --- /dev/null +++ b/queue-4.4/iwlwifi-mvm-inc-pending-frames-counter-also-when-txing-non-sta.patch @@ -0,0 +1,47 @@ +From fb896c44f88a75843a072cd6961b1615732f7811 Mon Sep 17 00:00:00 2001 +From: Liad Kaufman +Date: Sun, 14 Feb 2016 15:32:58 +0200 +Subject: iwlwifi: mvm: inc pending frames counter also when txing non-sta + +From: Liad Kaufman + +commit fb896c44f88a75843a072cd6961b1615732f7811 upstream. + +Until this patch, when TXing non-sta the pending_frames counter +wasn't increased, but it WAS decreased in +iwl_mvm_rx_tx_cmd_single(), what makes it negative in certain +conditions. This in turn caused much trouble when we need to +remove the station since we won't be waiting forever until +pending_frames gets 0. In certain cases, we were exhausting +the station table even in BSS mode, because we had a lot of +stale stations. + +Increase the counter also in iwl_mvm_tx_skb_non_sta() after a +successful TX to avoid this outcome. + +Signed-off-by: Liad Kaufman +Signed-off-by: Emmanuel Grumbach +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/iwlwifi/mvm/tx.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/net/wireless/iwlwifi/mvm/tx.c ++++ b/drivers/net/wireless/iwlwifi/mvm/tx.c +@@ -421,6 +421,15 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mv + return -1; + } + ++ /* ++ * Increase the pending frames counter, so that later when a reply comes ++ * in and the counter is decreased - we don't start getting negative ++ * values. ++ * Note that we don't need to make sure it isn't agg'd, since we're ++ * TXing non-sta ++ */ ++ atomic_inc(&mvm->pending_frames[sta_id]); ++ + return 0; + } + diff --git a/queue-4.4/jffs2-reduce-the-breakage-on-recovery-from-halfway-failed-rename.patch b/queue-4.4/jffs2-reduce-the-breakage-on-recovery-from-halfway-failed-rename.patch new file mode 100644 index 00000000000..d9ac3480ba6 --- /dev/null +++ b/queue-4.4/jffs2-reduce-the-breakage-on-recovery-from-halfway-failed-rename.patch @@ -0,0 +1,40 @@ +From f93812846f31381d35c04c6c577d724254355e7f Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Mon, 7 Mar 2016 23:07:10 -0500 +Subject: jffs2: reduce the breakage on recovery from halfway failed rename() + +From: Al Viro + +commit f93812846f31381d35c04c6c577d724254355e7f upstream. + +d_instantiate(new_dentry, old_inode) is absolutely wrong thing to +do - it will oops if new_dentry used to be positive, for starters. +What we need is d_invalidate() the target and be done with that. + +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/jffs2/dir.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/fs/jffs2/dir.c ++++ b/fs/jffs2/dir.c +@@ -843,9 +843,14 @@ static int jffs2_rename (struct inode *o + + pr_notice("%s(): Link succeeded, unlink failed (err %d). You now have a hard link\n", + __func__, ret); +- /* Might as well let the VFS know */ +- d_instantiate(new_dentry, d_inode(old_dentry)); +- ihold(d_inode(old_dentry)); ++ /* ++ * We can't keep the target in dcache after that. ++ * For one thing, we can't afford dentry aliases for directories. ++ * For another, if there was a victim, we _can't_ set new inode ++ * for that sucker and we have to trigger mount eviction - the ++ * caller won't do it on its own since we are returning an error. ++ */ ++ d_invalidate(new_dentry); + new_dir_i->i_mtime = new_dir_i->i_ctime = ITIME(now); + return ret; + } diff --git a/queue-4.4/kvm-cap-halt-polling-at-exactly-halt_poll_ns.patch b/queue-4.4/kvm-cap-halt-polling-at-exactly-halt_poll_ns.patch new file mode 100644 index 00000000000..5b5a2064857 --- /dev/null +++ b/queue-4.4/kvm-cap-halt-polling-at-exactly-halt_poll_ns.patch @@ -0,0 +1,40 @@ +From 313f636d5c490c9741d3f750dc8da33029edbc6b Mon Sep 17 00:00:00 2001 +From: David Matlack +Date: Tue, 8 Mar 2016 16:19:44 -0800 +Subject: kvm: cap halt polling at exactly halt_poll_ns + +From: David Matlack + +commit 313f636d5c490c9741d3f750dc8da33029edbc6b upstream. + +When growing halt-polling, there is no check that the poll time exceeds +the limit. It's possible for vcpu->halt_poll_ns grow once past +halt_poll_ns, and stay there until a halt which takes longer than +vcpu->halt_poll_ns. For example, booting a Linux guest with +halt_poll_ns=11000: + + ... kvm:kvm_halt_poll_ns: vcpu 0: halt_poll_ns 0 (shrink 10000) + ... kvm:kvm_halt_poll_ns: vcpu 0: halt_poll_ns 10000 (grow 0) + ... kvm:kvm_halt_poll_ns: vcpu 0: halt_poll_ns 20000 (grow 10000) + +Signed-off-by: David Matlack +Fixes: aca6ff29c4063a8d467cdee241e6b3bf7dc4a171 +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + virt/kvm/kvm_main.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -1961,6 +1961,9 @@ static void grow_halt_poll_ns(struct kvm + else + val *= halt_poll_ns_grow; + ++ if (val > halt_poll_ns) ++ val = halt_poll_ns; ++ + vcpu->halt_poll_ns = val; + trace_kvm_halt_poll_ns_grow(vcpu->vcpu_id, val, old); + } diff --git a/queue-4.4/kvm-mmu-fix-ept-0-pte.u-1-pte.w-0-cr0.wp-0-cr4.smep-1-efer.nx-0-combo.patch b/queue-4.4/kvm-mmu-fix-ept-0-pte.u-1-pte.w-0-cr0.wp-0-cr4.smep-1-efer.nx-0-combo.patch new file mode 100644 index 00000000000..025a912a1c3 --- /dev/null +++ b/queue-4.4/kvm-mmu-fix-ept-0-pte.u-1-pte.w-0-cr0.wp-0-cr4.smep-1-efer.nx-0-combo.patch @@ -0,0 +1,128 @@ +From 844a5fe219cf472060315971e15cbf97674a3324 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Tue, 8 Mar 2016 12:13:39 +0100 +Subject: KVM: MMU: fix ept=0/pte.u=1/pte.w=0/CR0.WP=0/CR4.SMEP=1/EFER.NX=0 combo + +From: Paolo Bonzini + +commit 844a5fe219cf472060315971e15cbf97674a3324 upstream. + +Yes, all of these are needed. :) This is admittedly a bit odd, but +kvm-unit-tests access.flat tests this if you run it with "-cpu host" +and of course ept=0. + +KVM runs the guest with CR0.WP=1, so it must handle supervisor writes +specially when pte.u=1/pte.w=0/CR0.WP=0. Such writes cause a fault +when U=1 and W=0 in the SPTE, but they must succeed because CR0.WP=0. +When KVM gets the fault, it sets U=0 and W=1 in the shadow PTE and +restarts execution. This will still cause a user write to fault, while +supervisor writes will succeed. User reads will fault spuriously now, +and KVM will then flip U and W again in the SPTE (U=1, W=0). User reads +will be enabled and supervisor writes disabled, going back to the +originary situation where supervisor writes fault spuriously. + +When SMEP is in effect, however, U=0 will enable kernel execution of +this page. To avoid this, KVM also sets NX=1 in the shadow PTE together +with U=0. If the guest has not enabled NX, the result is a continuous +stream of page faults due to the NX bit being reserved. + +The fix is to force EFER.NX=1 even if the CPU is taking care of the EFER +switch. (All machines with SMEP have the CPU_LOAD_IA32_EFER vm-entry +control, so they do not use user-return notifiers for EFER---if they did, +EFER.NX would be forced to the same value as the host). + +There is another bug in the reserved bit check, which I've split to a +separate patch for easier application to stable kernels. + +Cc: Andy Lutomirski +Reviewed-by: Xiao Guangrong +Fixes: f6577a5fa15d82217ca73c74cd2dcbc0f6c781dd +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + Documentation/virtual/kvm/mmu.txt | 3 ++- + arch/x86/kvm/vmx.c | 36 +++++++++++++++++++++++------------- + 2 files changed, 25 insertions(+), 14 deletions(-) + +--- a/Documentation/virtual/kvm/mmu.txt ++++ b/Documentation/virtual/kvm/mmu.txt +@@ -358,7 +358,8 @@ In the first case there are two addition + - if CR4.SMEP is enabled: since we've turned the page into a kernel page, + the kernel may now execute it. We handle this by also setting spte.nx. + If we get a user fetch or read fault, we'll change spte.u=1 and +- spte.nx=gpte.nx back. ++ spte.nx=gpte.nx back. For this to work, KVM forces EFER.NX to 1 when ++ shadow paging is in use. + - if CR4.SMAP is disabled: since the page has been changed to a kernel + page, it can not be reused when CR4.SMAP is enabled. We set + CR4.SMAP && !CR0.WP into shadow page's role to avoid this case. Note, +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -1792,26 +1792,31 @@ static void reload_tss(void) + + static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset) + { +- u64 guest_efer; +- u64 ignore_bits; ++ u64 guest_efer = vmx->vcpu.arch.efer; ++ u64 ignore_bits = 0; + +- guest_efer = vmx->vcpu.arch.efer; ++ if (!enable_ept) { ++ /* ++ * NX is needed to handle CR0.WP=1, CR4.SMEP=1. Testing ++ * host CPUID is more efficient than testing guest CPUID ++ * or CR4. Host SMEP is anyway a requirement for guest SMEP. ++ */ ++ if (boot_cpu_has(X86_FEATURE_SMEP)) ++ guest_efer |= EFER_NX; ++ else if (!(guest_efer & EFER_NX)) ++ ignore_bits |= EFER_NX; ++ } + + /* +- * NX is emulated; LMA and LME handled by hardware; SCE meaningless +- * outside long mode ++ * LMA and LME handled by hardware; SCE meaningless outside long mode. + */ +- ignore_bits = EFER_NX | EFER_SCE; ++ ignore_bits |= EFER_SCE; + #ifdef CONFIG_X86_64 + ignore_bits |= EFER_LMA | EFER_LME; + /* SCE is meaningful only in long mode on Intel */ + if (guest_efer & EFER_LMA) + ignore_bits &= ~(u64)EFER_SCE; + #endif +- guest_efer &= ~ignore_bits; +- guest_efer |= host_efer & ignore_bits; +- vmx->guest_msrs[efer_offset].data = guest_efer; +- vmx->guest_msrs[efer_offset].mask = ~ignore_bits; + + clear_atomic_switch_msr(vmx, MSR_EFER); + +@@ -1822,16 +1827,21 @@ static bool update_transition_efer(struc + */ + if (cpu_has_load_ia32_efer || + (enable_ept && ((vmx->vcpu.arch.efer ^ host_efer) & EFER_NX))) { +- guest_efer = vmx->vcpu.arch.efer; + if (!(guest_efer & EFER_LMA)) + guest_efer &= ~EFER_LME; + if (guest_efer != host_efer) + add_atomic_switch_msr(vmx, MSR_EFER, + guest_efer, host_efer); + return false; +- } ++ } else { ++ guest_efer &= ~ignore_bits; ++ guest_efer |= host_efer & ignore_bits; + +- return true; ++ vmx->guest_msrs[efer_offset].data = guest_efer; ++ vmx->guest_msrs[efer_offset].mask = ~ignore_bits; ++ ++ return true; ++ } + } + + static unsigned long segment_base(u16 selector) diff --git a/queue-4.4/kvm-mmu-fix-reserved-bit-check-for-ept-0-cr0.wp-0-cr4.smep-1-efer.nx-0.patch b/queue-4.4/kvm-mmu-fix-reserved-bit-check-for-ept-0-cr0.wp-0-cr4.smep-1-efer.nx-0.patch new file mode 100644 index 00000000000..c1a11a6d009 --- /dev/null +++ b/queue-4.4/kvm-mmu-fix-reserved-bit-check-for-ept-0-cr0.wp-0-cr4.smep-1-efer.nx-0.patch @@ -0,0 +1,49 @@ +From 5f0b819995e172f48fdcd91335a2126ba7d9deae Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Wed, 9 Mar 2016 14:28:02 +0100 +Subject: KVM: MMU: fix reserved bit check for ept=0/CR0.WP=0/CR4.SMEP=1/EFER.NX=0 + +From: Paolo Bonzini + +commit 5f0b819995e172f48fdcd91335a2126ba7d9deae upstream. + +KVM has special logic to handle pages with pte.u=1 and pte.w=0 when +CR0.WP=1. These pages' SPTEs flip continuously between two states: +U=1/W=0 (user and supervisor reads allowed, supervisor writes not allowed) +and U=0/W=1 (supervisor reads and writes allowed, user writes not allowed). + +When SMEP is in effect, however, U=0 will enable kernel execution of +this page. To avoid this, KVM also sets NX=1 in the shadow PTE together +with U=0, making the two states U=1/W=0/NX=gpte.NX and U=0/W=1/NX=1. +When guest EFER has the NX bit cleared, the reserved bit check thinks +that the latter state is invalid; teach it that the smep_andnot_wp case +will also use the NX bit of SPTEs. + +Reviewed-by: Xiao Guangrong +Fixes: c258b62b264fdc469b6d3610a907708068145e3b +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/mmu.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/arch/x86/kvm/mmu.c ++++ b/arch/x86/kvm/mmu.c +@@ -3754,13 +3754,15 @@ static void reset_rsvds_bits_mask_ept(st + void + reset_shadow_zero_bits_mask(struct kvm_vcpu *vcpu, struct kvm_mmu *context) + { ++ bool uses_nx = context->nx || context->base_role.smep_andnot_wp; ++ + /* + * Passing "true" to the last argument is okay; it adds a check + * on bit 8 of the SPTEs which KVM doesn't use anyway. + */ + __reset_rsvds_bits_mask(vcpu, &context->shadow_zero_check, + boot_cpu_data.x86_phys_bits, +- context->shadow_root_level, context->nx, ++ context->shadow_root_level, uses_nx, + guest_cpuid_has_gbpages(vcpu), is_pse(vcpu), + true); + } diff --git a/queue-4.4/kvm-ppc-book3s-hv-sanitize-special-purpose-register-values-on-guest-exit.patch b/queue-4.4/kvm-ppc-book3s-hv-sanitize-special-purpose-register-values-on-guest-exit.patch new file mode 100644 index 00000000000..d4a8aca18e7 --- /dev/null +++ b/queue-4.4/kvm-ppc-book3s-hv-sanitize-special-purpose-register-values-on-guest-exit.patch @@ -0,0 +1,53 @@ +From ccec44563b18a0ce90e2d4f332784b3cb25c8e9c Mon Sep 17 00:00:00 2001 +From: Paul Mackerras +Date: Sat, 5 Mar 2016 19:34:39 +1100 +Subject: KVM: PPC: Book3S HV: Sanitize special-purpose register values on guest exit + +From: Paul Mackerras + +commit ccec44563b18a0ce90e2d4f332784b3cb25c8e9c upstream. + +Thomas Huth discovered that a guest could cause a hard hang of a +host CPU by setting the Instruction Authority Mask Register (IAMR) +to a suitable value. It turns out that this is because when the +code was added to context-switch the new special-purpose registers +(SPRs) that were added in POWER8, we forgot to add code to ensure +that they were restored to a sane value on guest exit. + +This adds code to set those registers where a bad value could +compromise the execution of the host kernel to a suitable neutral +value on guest exit. + +Fixes: b005255e12a3 +Reported-by: Thomas Huth +Reviewed-by: David Gibson +Signed-off-by: Paul Mackerras +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kvm/book3s_hv_rmhandlers.S | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S ++++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S +@@ -1370,6 +1370,20 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) + std r6, VCPU_ACOP(r9) + stw r7, VCPU_GUEST_PID(r9) + std r8, VCPU_WORT(r9) ++ /* ++ * Restore various registers to 0, where non-zero values ++ * set by the guest could disrupt the host. ++ */ ++ li r0, 0 ++ mtspr SPRN_IAMR, r0 ++ mtspr SPRN_CIABR, r0 ++ mtspr SPRN_DAWRX, r0 ++ mtspr SPRN_TCSCR, r0 ++ mtspr SPRN_WORT, r0 ++ /* Set MMCRS to 1<<31 to freeze and disable the SPMC counters */ ++ li r0, 1 ++ sldi r0, r0, 31 ++ mtspr SPRN_MMCRS, r0 + 8: + + /* Save and reset AMR and UAMOR before turning on the MMU */ diff --git a/queue-4.4/kvm-s390-correct-fprs-on-sigp-stop-and-store-status.patch b/queue-4.4/kvm-s390-correct-fprs-on-sigp-stop-and-store-status.patch new file mode 100644 index 00000000000..399701afc42 --- /dev/null +++ b/queue-4.4/kvm-s390-correct-fprs-on-sigp-stop-and-store-status.patch @@ -0,0 +1,44 @@ +From 9522b37f5a8c7bfabe46eecadf2e130f1103f337 Mon Sep 17 00:00:00 2001 +From: David Hildenbrand +Date: Tue, 8 Mar 2016 12:24:30 +0100 +Subject: KVM: s390: correct fprs on SIGP (STOP AND) STORE STATUS + +From: David Hildenbrand + +commit 9522b37f5a8c7bfabe46eecadf2e130f1103f337 upstream. + +With MACHINE_HAS_VX, we convert the floating point registers from the +vector registeres when storing the status. For other VCPUs, these are +stored to vcpu->run->s.regs.vrs, but we are using current->thread.fpu.vxrs, +which resolves to the currently loaded VCPU. + +So kvm_s390_store_status_unloaded() currently writes the wrong floating +point registers (converted from the vector registers) when called from +another VCPU on a z13. + +This is only the case for old user space not handling SIGP STORE STATUS and +SIGP STOP AND STORE STATUS, but relying on the kernel implementation. All +other calls come from the loaded VCPU via kvm_s390_store_status(). + +Fixes: 9abc2a08a7d6 (KVM: s390: fix memory overwrites when vx is disabled) +Reviewed-by: Christian Borntraeger +Signed-off-by: David Hildenbrand +Signed-off-by: Christian Borntraeger +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/kvm/kvm-s390.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/s390/kvm/kvm-s390.c ++++ b/arch/s390/kvm/kvm-s390.c +@@ -2249,7 +2249,7 @@ int kvm_s390_store_status_unloaded(struc + + /* manually convert vector registers if necessary */ + if (MACHINE_HAS_VX) { +- convert_vx_to_fp(fprs, current->thread.fpu.vxrs); ++ convert_vx_to_fp(fprs, (__vector128 *) vcpu->run->s.regs.vrs); + rc = write_guest_abs(vcpu, gpa + __LC_FPREGS_SAVE_AREA, + fprs, 128); + } else { diff --git a/queue-4.4/kvm-vmx-disable-pebs-before-a-guest-entry.patch b/queue-4.4/kvm-vmx-disable-pebs-before-a-guest-entry.patch new file mode 100644 index 00000000000..5699cbd226d --- /dev/null +++ b/queue-4.4/kvm-vmx-disable-pebs-before-a-guest-entry.patch @@ -0,0 +1,76 @@ +From 7099e2e1f4d9051f31bbfa5803adf954bb5d76ef Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= +Date: Fri, 4 Mar 2016 15:08:42 +0100 +Subject: KVM: VMX: disable PEBS before a guest entry +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Radim Krčmář + +commit 7099e2e1f4d9051f31bbfa5803adf954bb5d76ef upstream. + +Linux guests on Haswell (and also SandyBridge and Broadwell, at least) +would crash if you decided to run a host command that uses PEBS, like + perf record -e 'cpu/mem-stores/pp' -a + +This happens because KVM is using VMX MSR switching to disable PEBS, but +SDM [2015-12] 18.4.4.4 Re-configuring PEBS Facilities explains why it +isn't safe: + When software needs to reconfigure PEBS facilities, it should allow a + quiescent period between stopping the prior event counting and setting + up a new PEBS event. The quiescent period is to allow any latent + residual PEBS records to complete its capture at their previously + specified buffer address (provided by IA32_DS_AREA). + +There might not be a quiescent period after the MSR switch, so a CPU +ends up using host's MSR_IA32_DS_AREA to access an area in guest's +memory. (Or MSR switching is just buggy on some models.) + +The guest can learn something about the host this way: +If the guest doesn't map address pointed by MSR_IA32_DS_AREA, it results +in #PF where we leak host's MSR_IA32_DS_AREA through CR2. + +After that, a malicious guest can map and configure memory where +MSR_IA32_DS_AREA is pointing and can therefore get an output from +host's tracing. + +This is not a critical leak as the host must initiate with PEBS tracing +and I have not been able to get a record from more than one instruction +before vmentry in vmx_vcpu_run() (that place has most registers already +overwritten with guest's). + +We could disable PEBS just few instructions before vmentry, but +disabling it earlier shouldn't affect host tracing too much. +We also don't need to switch MSR_IA32_PEBS_ENABLE on VMENTRY, but that +optimization isn't worth its code, IMO. + +(If you are implementing PEBS for guests, be sure to handle the case + where both host and guest enable PEBS, because this patch doesn't.) + +Fixes: 26a4f3c08de4 ("perf/x86: disable PEBS on a guest entry.") +Reported-by: Jiří OlÅ¡a +Signed-off-by: Radim Krčmář +Signed-off-by: Paolo Bonzini +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/vmx.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -1748,6 +1748,13 @@ static void add_atomic_switch_msr(struct + return; + } + break; ++ case MSR_IA32_PEBS_ENABLE: ++ /* PEBS needs a quiescent period after being disabled (to write ++ * a record). Disabling PEBS through VMX MSR swapping doesn't ++ * provide that period, so a CPU could write host's record into ++ * guest's memory. ++ */ ++ wrmsrl(MSR_IA32_PEBS_ENABLE, 0); + } + + for (i = 0; i < m->nr; ++i) diff --git a/queue-4.4/mac80211-check-pn-correctly-for-gcmp-encrypted-fragmented-mpdus.patch b/queue-4.4/mac80211-check-pn-correctly-for-gcmp-encrypted-fragmented-mpdus.patch new file mode 100644 index 00000000000..568f6dfa952 --- /dev/null +++ b/queue-4.4/mac80211-check-pn-correctly-for-gcmp-encrypted-fragmented-mpdus.patch @@ -0,0 +1,108 @@ +From 9acc54beb474c81148e2946603d141cf8716b19f Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Fri, 26 Feb 2016 22:13:40 +0100 +Subject: mac80211: check PN correctly for GCMP-encrypted fragmented MPDUs + +From: Johannes Berg + +commit 9acc54beb474c81148e2946603d141cf8716b19f upstream. + +Just like for CCMP we need to check that for GCMP the fragments +have PNs that increment by one; the spec was updated to fix this +security issue and now has the following text: + + The receiver shall discard MSDUs and MMPDUs whose constituent + MPDU PN values are not incrementing in steps of 1. + +Adapt the code for CCMP to work for GCMP as well, luckily the +relevant fields already alias each other so no code duplication +is needed (just check the aliasing with BUILD_BUG_ON.) + +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/ieee80211_i.h | 2 +- + net/mac80211/rx.c | 36 +++++++++++++++++++++++++++--------- + 2 files changed, 28 insertions(+), 10 deletions(-) + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -92,7 +92,7 @@ struct ieee80211_fragment_entry { + u16 extra_len; + u16 last_frag; + u8 rx_queue; +- bool ccmp; /* Whether fragments were encrypted with CCMP */ ++ bool check_sequential_pn; /* needed for CCMP/GCMP */ + u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ + }; + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1754,7 +1754,7 @@ ieee80211_reassemble_add(struct ieee8021 + entry->seq = seq; + entry->rx_queue = rx_queue; + entry->last_frag = frag; +- entry->ccmp = 0; ++ entry->check_sequential_pn = false; + entry->extra_len = 0; + + return entry; +@@ -1850,15 +1850,27 @@ ieee80211_rx_h_defragment(struct ieee802 + rx->seqno_idx, &(rx->skb)); + if (rx->key && + (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP || +- rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256) && ++ rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 || ++ rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP || ++ rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) && + ieee80211_has_protected(fc)) { + int queue = rx->security_idx; +- /* Store CCMP PN so that we can verify that the next +- * fragment has a sequential PN value. */ +- entry->ccmp = 1; ++ ++ /* Store CCMP/GCMP PN so that we can verify that the ++ * next fragment has a sequential PN value. ++ */ ++ entry->check_sequential_pn = true; + memcpy(entry->last_pn, + rx->key->u.ccmp.rx_pn[queue], + IEEE80211_CCMP_PN_LEN); ++ BUILD_BUG_ON(offsetof(struct ieee80211_key, ++ u.ccmp.rx_pn) != ++ offsetof(struct ieee80211_key, ++ u.gcmp.rx_pn)); ++ BUILD_BUG_ON(sizeof(rx->key->u.ccmp.rx_pn[queue]) != ++ sizeof(rx->key->u.gcmp.rx_pn[queue])); ++ BUILD_BUG_ON(IEEE80211_CCMP_PN_LEN != ++ IEEE80211_GCMP_PN_LEN); + } + return RX_QUEUED; + } +@@ -1873,15 +1885,21 @@ ieee80211_rx_h_defragment(struct ieee802 + return RX_DROP_MONITOR; + } + +- /* Verify that MPDUs within one MSDU have sequential PN values. +- * (IEEE 802.11i, 8.3.3.4.5) */ +- if (entry->ccmp) { ++ /* "The receiver shall discard MSDUs and MMPDUs whose constituent ++ * MPDU PN values are not incrementing in steps of 1." ++ * see IEEE P802.11-REVmc/D5.0, 12.5.3.4.4, item d (for CCMP) ++ * and IEEE P802.11-REVmc/D5.0, 12.5.5.4.4, item d (for GCMP) ++ */ ++ if (entry->check_sequential_pn) { + int i; + u8 pn[IEEE80211_CCMP_PN_LEN], *rpn; + int queue; ++ + if (!rx->key || + (rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP && +- rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256)) ++ rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256 && ++ rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP && ++ rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP_256)) + return RX_DROP_UNUSABLE; + memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN); + for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) { diff --git a/queue-4.4/mac80211-fix-public-action-frame-rx-in-ap-mode.patch b/queue-4.4/mac80211-fix-public-action-frame-rx-in-ap-mode.patch new file mode 100644 index 00000000000..55e62ee97c9 --- /dev/null +++ b/queue-4.4/mac80211-fix-public-action-frame-rx-in-ap-mode.patch @@ -0,0 +1,43 @@ +From 1ec7bae8bec9b72e347e01330c745ab5cdd66f0e Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Tue, 1 Mar 2016 00:29:00 +0200 +Subject: mac80211: Fix Public Action frame RX in AP mode + +From: Jouni Malinen + +commit 1ec7bae8bec9b72e347e01330c745ab5cdd66f0e upstream. + +Public Action frames use special rules for how the BSSID field (Address +3) is set. A wildcard BSSID is used in cases where the transmitter and +recipient are not members of the same BSS. As such, we need to accept +Public Action frames with wildcard BSSID. + +Commit db8e17324553 ("mac80211: ignore frames between TDLS peers when +operating as AP") added a rule that drops Action frames to TDLS-peers +based on an Action frame having different DA (Address 1) and BSSID +(Address 3) values. This is not correct since it misses the possibility +of BSSID being a wildcard BSSID in which case the Address 1 would not +necessarily match. + +Fix this by allowing mac80211 to accept wildcard BSSID in an Action +frame when in AP mode. + +Fixes: db8e17324553 ("mac80211: ignore frames between TDLS peers when operating as AP") +Signed-off-by: Jouni Malinen +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/rx.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -3385,6 +3385,7 @@ static bool ieee80211_accept_frame(struc + return false; + /* ignore action frames to TDLS-peers */ + if (ieee80211_is_action(hdr->frame_control) && ++ !is_broadcast_ether_addr(bssid) && + !ether_addr_equal(bssid, hdr->addr1)) + return false; + } diff --git a/queue-4.4/mac80211-fix-use-of-uninitialised-values-in-rx-aggregation.patch b/queue-4.4/mac80211-fix-use-of-uninitialised-values-in-rx-aggregation.patch new file mode 100644 index 00000000000..ac19d296249 --- /dev/null +++ b/queue-4.4/mac80211-fix-use-of-uninitialised-values-in-rx-aggregation.patch @@ -0,0 +1,52 @@ +From f39ea2690bd61efec97622c48323f40ed6e16317 Mon Sep 17 00:00:00 2001 +From: Chris Bainbridge +Date: Wed, 27 Jan 2016 15:46:18 +0000 +Subject: mac80211: fix use of uninitialised values in RX aggregation + +From: Chris Bainbridge + +commit f39ea2690bd61efec97622c48323f40ed6e16317 upstream. + +Use kzalloc instead of kmalloc for struct tid_ampdu_rx to +initialize the "removed" field (all others are initialized +manually). That fixes: + +UBSAN: Undefined behaviour in net/mac80211/rx.c:932:29 +load of value 2 is not a valid value for type '_Bool' +CPU: 3 PID: 1134 Comm: kworker/u16:7 Not tainted 4.5.0-rc1+ #265 +Workqueue: phy0 rt2x00usb_work_rxdone + 0000000000000004 ffff880254a7ba50 ffffffff8181d866 0000000000000007 + ffff880254a7ba78 ffff880254a7ba68 ffffffff8188422d ffffffff8379b500 + ffff880254a7bab8 ffffffff81884747 0000000000000202 0000000348620032 +Call Trace: + [] dump_stack+0x45/0x5f + [] ubsan_epilogue+0xd/0x40 + [] __ubsan_handle_load_invalid_value+0x67/0x70 + [] ieee80211_sta_reorder_release.isra.16+0x5ed/0x730 + [] ieee80211_prepare_and_rx_handle+0xd04/0x1c00 + [] __ieee80211_rx_handle_packet+0x1f3/0x750 + [] ieee80211_rx_napi+0x447/0x990 + +While at it, convert to use sizeof(*tid_agg_rx) instead. + +Fixes: 788211d81bfdf ("mac80211: fix RX A-MPDU session reorder timer deletion") +Signed-off-by: Chris Bainbridge +[reword commit message, use sizeof(*tid_agg_rx)] +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/agg-rx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/mac80211/agg-rx.c ++++ b/net/mac80211/agg-rx.c +@@ -291,7 +291,7 @@ void __ieee80211_start_rx_ba_session(str + } + + /* prepare A-MPDU MLME for Rx aggregation */ +- tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL); ++ tid_agg_rx = kzalloc(sizeof(*tid_agg_rx), GFP_KERNEL); + if (!tid_agg_rx) + goto end; + diff --git a/queue-4.4/mac80211-minstrel-change-expected-throughput-unit-back-to-kbps.patch b/queue-4.4/mac80211-minstrel-change-expected-throughput-unit-back-to-kbps.patch new file mode 100644 index 00000000000..cafe307a855 --- /dev/null +++ b/queue-4.4/mac80211-minstrel-change-expected-throughput-unit-back-to-kbps.patch @@ -0,0 +1,59 @@ +From 212c5a5e6ba61678be6b5fee576e38bccb50b613 Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Tue, 2 Feb 2016 08:12:26 +0100 +Subject: mac80211: minstrel: Change expected throughput unit back to Kbps + +From: Sven Eckelmann + +commit 212c5a5e6ba61678be6b5fee576e38bccb50b613 upstream. + +The change from cur_tp to the function +minstrel_get_tp_avg/minstrel_ht_get_tp_avg changed the unit used for the +current throughput. For example in minstrel_ht the correct +conversion between them would be: + + mrs->cur_tp / 10 == minstrel_ht_get_tp_avg(..). + +This factor 10 must also be included in the calculation of +minstrel_get_expected_throughput and minstrel_ht_get_expected_throughput to +return values with the unit [Kbps] instead of [10Kbps]. Otherwise routing +algorithms like B.A.T.M.A.N. V will make incorrect decision based on these +values. Its kernel based implementation expects expected_throughput always +to have the unit [Kbps] and not sometimes [10Kbps] and sometimes [Kbps]. + +The same requirement has iw or olsrdv2's nl80211 based statistics module +which retrieve the same data via NL80211_STA_INFO_TX_BITRATE. + +Fixes: 6a27b2c40b48 ("mac80211: restructure per-rate throughput calculation into function") +Signed-off-by: Sven Eckelmann +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/rc80211_minstrel.c | 2 +- + net/mac80211/rc80211_minstrel_ht.c | 3 ++- + 2 files changed, 3 insertions(+), 2 deletions(-) + +--- a/net/mac80211/rc80211_minstrel.c ++++ b/net/mac80211/rc80211_minstrel.c +@@ -711,7 +711,7 @@ static u32 minstrel_get_expected_through + * computing cur_tp + */ + tmp_mrs = &mi->r[idx].stats; +- tmp_cur_tp = minstrel_get_tp_avg(&mi->r[idx], tmp_mrs->prob_ewma); ++ tmp_cur_tp = minstrel_get_tp_avg(&mi->r[idx], tmp_mrs->prob_ewma) * 10; + tmp_cur_tp = tmp_cur_tp * 1200 * 8 / 1024; + + return tmp_cur_tp; +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1334,7 +1334,8 @@ static u32 minstrel_ht_get_expected_thro + prob = mi->groups[i].rates[j].prob_ewma; + + /* convert tp_avg from pkt per second in kbps */ +- tp_avg = minstrel_ht_get_tp_avg(mi, i, j, prob) * AVG_PKT_SIZE * 8 / 1024; ++ tp_avg = minstrel_ht_get_tp_avg(mi, i, j, prob) * 10; ++ tp_avg = tp_avg * AVG_PKT_SIZE * 8 / 1024; + + return tp_avg; + } diff --git a/queue-4.4/mac80211-minstrel_ht-fix-a-logic-error-in-rts-cts-handling.patch b/queue-4.4/mac80211-minstrel_ht-fix-a-logic-error-in-rts-cts-handling.patch new file mode 100644 index 00000000000..a1c0f5419b4 --- /dev/null +++ b/queue-4.4/mac80211-minstrel_ht-fix-a-logic-error-in-rts-cts-handling.patch @@ -0,0 +1,36 @@ +From c36dd3eaf1a674a45b58b922258d6eaa8932e292 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Wed, 24 Feb 2016 12:07:17 +0100 +Subject: mac80211: minstrel_ht: fix a logic error in RTS/CTS handling +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Felix Fietkau + +commit c36dd3eaf1a674a45b58b922258d6eaa8932e292 upstream. + +RTS/CTS needs to be enabled if the rate is a fallback rate *or* if it's +a dual-stream rate and the sta is in dynamic SMPS mode. + +Fixes: a3ebb4e1b763 ("mac80211: minstrel_ht: handle peers in dynamic SMPS") +Reported-by: Matías Richart +Signed-off-by: Felix Fietkau +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/rc80211_minstrel_ht.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -871,7 +871,7 @@ minstrel_ht_set_rate(struct minstrel_pri + * - if station is in dynamic SMPS (and streams > 1) + * - for fallback rates, to increase chances of getting through + */ +- if (offset > 0 && ++ if (offset > 0 || + (mi->sta->smps_mode == IEEE80211_SMPS_DYNAMIC && + group->streams > 1)) { + ratetbl->rate[offset].count = ratetbl->rate[offset].count_rts; diff --git a/queue-4.4/mac80211-minstrel_ht-set-default-tx-aggregation-timeout-to-0.patch b/queue-4.4/mac80211-minstrel_ht-set-default-tx-aggregation-timeout-to-0.patch new file mode 100644 index 00000000000..f03ac944b67 --- /dev/null +++ b/queue-4.4/mac80211-minstrel_ht-set-default-tx-aggregation-timeout-to-0.patch @@ -0,0 +1,40 @@ +From 7a36b930e6ed4702c866dc74a5ad07318a57c688 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Thu, 18 Feb 2016 19:49:18 +0100 +Subject: mac80211: minstrel_ht: set default tx aggregation timeout to 0 + +From: Felix Fietkau + +commit 7a36b930e6ed4702c866dc74a5ad07318a57c688 upstream. + +The value 5000 was put here with the addition of the timeout field to +ieee80211_start_tx_ba_session. It was originally added in mac80211 to +save resources for drivers like iwlwifi, which only supports a limited +number of concurrent aggregation sessions. + +Since iwlwifi does not use minstrel_ht and other drivers don't need +this, 0 is a better default - especially since there have been +recent reports of aggregation setup related issues reproduced with +ath9k. This should improve stability without causing any adverse +effects. + +Acked-by: Avery Pennarun +Signed-off-by: Felix Fietkau +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/rc80211_minstrel_ht.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -691,7 +691,7 @@ minstrel_aggr_check(struct ieee80211_sta + if (likely(sta->ampdu_mlme.tid_tx[tid])) + return; + +- ieee80211_start_tx_ba_session(pubsta, tid, 5000); ++ ieee80211_start_tx_ba_session(pubsta, tid, 0); + } + + static void diff --git a/queue-4.4/ncpfs-fix-a-braino-in-oom-handling-in-ncp_fill_cache.patch b/queue-4.4/ncpfs-fix-a-braino-in-oom-handling-in-ncp_fill_cache.patch new file mode 100644 index 00000000000..471e024e9a2 --- /dev/null +++ b/queue-4.4/ncpfs-fix-a-braino-in-oom-handling-in-ncp_fill_cache.patch @@ -0,0 +1,34 @@ +From 803c00123a8012b3a283c0530910653973ef6d8f Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Mon, 7 Mar 2016 22:17:07 -0500 +Subject: ncpfs: fix a braino in OOM handling in ncp_fill_cache() + +From: Al Viro + +commit 803c00123a8012b3a283c0530910653973ef6d8f upstream. + +Failing to allocate an inode for child means that cache for *parent* is +incompletely populated. So it's parent directory inode ('dir') that +needs NCPI_DIR_CACHE flag removed, *not* the child inode ('inode', which +is what we'd failed to allocate in the first place). + +Fucked-up-in: commit 5e993e25 ("ncpfs: get rid of d_validate() nonsense") +Fucked-up-by: Al Viro +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ncpfs/dir.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ncpfs/dir.c ++++ b/fs/ncpfs/dir.c +@@ -633,7 +633,7 @@ ncp_fill_cache(struct file *file, struct + d_rehash(newdent); + } else { + spin_lock(&dentry->d_lock); +- NCP_FINFO(inode)->flags &= ~NCPI_DIR_CACHE; ++ NCP_FINFO(dir)->flags &= ~NCPI_DIR_CACHE; + spin_unlock(&dentry->d_lock); + } + } else { diff --git a/queue-4.4/ovl-fix-working-on-distributed-fs-as-lower-layer.patch b/queue-4.4/ovl-fix-working-on-distributed-fs-as-lower-layer.patch new file mode 100644 index 00000000000..e08c890a2a0 --- /dev/null +++ b/queue-4.4/ovl-fix-working-on-distributed-fs-as-lower-layer.patch @@ -0,0 +1,33 @@ +From b5891cfab08fe3144a616e8e734df7749fb3b7d0 Mon Sep 17 00:00:00 2001 +From: Konstantin Khlebnikov +Date: Sun, 31 Jan 2016 16:22:16 +0300 +Subject: ovl: fix working on distributed fs as lower layer + +From: Konstantin Khlebnikov + +commit b5891cfab08fe3144a616e8e734df7749fb3b7d0 upstream. + +This adds missing .d_select_inode into alternative dentry_operations. + +Signed-off-by: Konstantin Khlebnikov +Fixes: 7c03b5d45b8e ("ovl: allow distributed fs as lower layer") +Fixes: 4bacc9c9234c ("overlayfs: Make f_path always point to the overlay and f_inode to the underlay") +Reviewed-by: Nikolay Borisov +Tested-by: Nikolay Borisov +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + fs/overlayfs/super.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/overlayfs/super.c ++++ b/fs/overlayfs/super.c +@@ -324,6 +324,7 @@ static const struct dentry_operations ov + + static const struct dentry_operations ovl_reval_dentry_operations = { + .d_release = ovl_dentry_release, ++ .d_select_inode = ovl_d_select_inode, + .d_revalidate = ovl_dentry_revalidate, + .d_weak_revalidate = ovl_dentry_weak_revalidate, + }; diff --git a/queue-4.4/ovl-ignore-lower-entries-when-checking-purity-of-non-directory-entries.patch b/queue-4.4/ovl-ignore-lower-entries-when-checking-purity-of-non-directory-entries.patch new file mode 100644 index 00000000000..c87d097be97 --- /dev/null +++ b/queue-4.4/ovl-ignore-lower-entries-when-checking-purity-of-non-directory-entries.patch @@ -0,0 +1,103 @@ +From 45d11738969633ec07ca35d75d486bf2d8918df6 Mon Sep 17 00:00:00 2001 +From: Konstantin Khlebnikov +Date: Sun, 31 Jan 2016 16:17:53 +0300 +Subject: ovl: ignore lower entries when checking purity of non-directory entries + +From: Konstantin Khlebnikov + +commit 45d11738969633ec07ca35d75d486bf2d8918df6 upstream. + +After rename file dentry still holds reference to lower dentry from +previous location. This doesn't matter for data access because data comes +from upper dentry. But this stale lower dentry taints dentry at new +location and turns it into non-pure upper. Such file leaves visible +whiteout entry after remove in directory which shouldn't have whiteouts at +all. + +Overlayfs already tracks pureness of file location in oe->opaque. This +patch just uses that for detecting actual path type. + +Comment from Vivek Goyal's patch: + +Here are the details of the problem. Do following. + +$ mkdir upper lower work merged upper/dir/ +$ touch lower/test +$ sudo mount -t overlay overlay -olowerdir=lower,upperdir=upper,workdir= +work merged +$ mv merged/test merged/dir/ +$ rm merged/dir/test +$ ls -l merged/dir/ +/usr/bin/ls: cannot access merged/dir/test: No such file or directory +total 0 +c????????? ? ? ? ? ? test + +Basic problem seems to be that once a file has been unlinked, a whiteout +has been left behind which was not needed and hence it becomes visible. + +Whiteout is visible because parent dir is of not type MERGE, hence +od->is_real is set during ovl_dir_open(). And that means ovl_iterate() +passes on iterate handling directly to underlying fs. Underlying fs does +not know/filter whiteouts so it becomes visible to user. + +Why did we leave a whiteout to begin with when we should not have. +ovl_do_remove() checks for OVL_TYPE_PURE_UPPER() and does not leave +whiteout if file is pure upper. In this case file is not found to be pure +upper hence whiteout is left. + +So why file was not PURE_UPPER in this case? I think because dentry is +still carrying some leftover state which was valid before rename. For +example, od->numlower was set to 1 as it was a lower file. After rename, +this state is not valid anymore as there is no such file in lower. + +Signed-off-by: Konstantin Khlebnikov +Reported-by: Viktor Stanchev +Suggested-by: Vivek Goyal +Link: https://bugzilla.kernel.org/show_bug.cgi?id=109611 +Acked-by: Vivek Goyal +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + fs/overlayfs/dir.c | 7 +++++++ + fs/overlayfs/super.c | 12 +++++++----- + 2 files changed, 14 insertions(+), 5 deletions(-) + +--- a/fs/overlayfs/dir.c ++++ b/fs/overlayfs/dir.c +@@ -903,6 +903,13 @@ static int ovl_rename2(struct inode *old + if (!overwrite && new_is_dir && !old_opaque && new_opaque) + ovl_remove_opaque(newdentry); + ++ /* ++ * Old dentry now lives in different location. Dentries in ++ * lowerstack are stale. We cannot drop them here because ++ * access to them is lockless. This could be only pure upper ++ * or opaque directory - numlower is zero. Or upper non-dir ++ * entry - its pureness is tracked by flag opaque. ++ */ + if (old_opaque != new_opaque) { + ovl_dentry_set_opaque(old, new_opaque); + if (!overwrite) +--- a/fs/overlayfs/super.c ++++ b/fs/overlayfs/super.c +@@ -76,12 +76,14 @@ enum ovl_path_type ovl_path_type(struct + if (oe->__upperdentry) { + type = __OVL_PATH_UPPER; + +- if (oe->numlower) { +- if (S_ISDIR(dentry->d_inode->i_mode)) +- type |= __OVL_PATH_MERGE; +- } else if (!oe->opaque) { ++ /* ++ * Non-dir dentry can hold lower dentry from previous ++ * location. Its purity depends only on opaque flag. ++ */ ++ if (oe->numlower && S_ISDIR(dentry->d_inode->i_mode)) ++ type |= __OVL_PATH_MERGE; ++ else if (!oe->opaque) + type |= __OVL_PATH_PURE; +- } + } else { + if (oe->numlower > 1) + type |= __OVL_PATH_MERGE; diff --git a/queue-4.4/pci-allow-a-null-parent-pointer-in-pci_bus_assign_domain_nr.patch b/queue-4.4/pci-allow-a-null-parent-pointer-in-pci_bus_assign_domain_nr.patch new file mode 100644 index 00000000000..8a6cfad6501 --- /dev/null +++ b/queue-4.4/pci-allow-a-null-parent-pointer-in-pci_bus_assign_domain_nr.patch @@ -0,0 +1,64 @@ +From 54c6e2dd00c313d0add58e5befe62fe6f286d03b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Krzysztof=20=3D=3Futf-8=3FQ=3FHa=3DC5=3D82asa=3F=3D?= + +Date: Tue, 1 Mar 2016 07:07:18 +0100 +Subject: PCI: Allow a NULL "parent" pointer in pci_bus_assign_domain_nr() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Krzysztof =?utf-8?Q?Ha=C5=82asa?= + +commit 54c6e2dd00c313d0add58e5befe62fe6f286d03b upstream. + +pci_create_root_bus() passes a "parent" pointer to +pci_bus_assign_domain_nr(). When CONFIG_PCI_DOMAINS_GENERIC is defined, +pci_bus_assign_domain_nr() dereferences that pointer. Many callers of +pci_create_root_bus() supply a NULL "parent" pointer, which leads to a NULL +pointer dereference error. + +7c674700098c ("PCI: Move domain assignment from arm64 to generic code") +moved the "parent" dereference from arm64 to generic code. Only arm64 used +that code (because only arm64 defined CONFIG_PCI_DOMAINS_GENERIC), and it +always supplied a valid "parent" pointer. Other arches supplied NULL +"parent" pointers but didn't defined CONFIG_PCI_DOMAINS_GENERIC, so they +used a no-op version of pci_bus_assign_domain_nr(). + +8c7d14746abc ("ARM/PCI: Move to generic PCI domains") defined +CONFIG_PCI_DOMAINS_GENERIC on ARM, and many ARM platforms use +pci_common_init(), which supplies a NULL "parent" pointer. +These platforms (cns3xxx, dove, footbridge, iop13xx, etc.) crash +with a NULL pointer dereference like this while probing PCI: + + Unable to handle kernel NULL pointer dereference at virtual address 000000a4 + PC is at pci_bus_assign_domain_nr+0x10/0x84 + LR is at pci_create_root_bus+0x48/0x2e4 + Kernel panic - not syncing: Attempted to kill init! + +[bhelgaas: changelog, add "Reported:" and "Fixes:" tags] +Reported: http://forum.doozan.com/read.php?2,17868,22070,quote=1 +Fixes: 8c7d14746abc ("ARM/PCI: Move to generic PCI domains") +Fixes: 7c674700098c ("PCI: Move domain assignment from arm64 to generic code") +Signed-off-by: Krzysztof Hałasa +Signed-off-by: Bjorn Helgaas +Acked-by: Lorenzo Pieralisi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/pci/pci.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -4772,8 +4772,10 @@ int pci_get_new_domain_nr(void) + void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent) + { + static int use_dt_domains = -1; +- int domain = of_get_pci_domain_nr(parent->of_node); ++ int domain = -1; + ++ if (parent) ++ domain = of_get_pci_domain_nr(parent->of_node); + /* + * Check DT domain and use_dt_domains values. + * diff --git a/queue-4.4/powerpc-fix-dedotify-for-binutils-2.26.patch b/queue-4.4/powerpc-fix-dedotify-for-binutils-2.26.patch new file mode 100644 index 00000000000..73839daad75 --- /dev/null +++ b/queue-4.4/powerpc-fix-dedotify-for-binutils-2.26.patch @@ -0,0 +1,37 @@ +From f15838e9cac8f78f0cc506529bb9d3b9fa589c1f Mon Sep 17 00:00:00 2001 +From: Andreas Schwab +Date: Fri, 5 Feb 2016 19:50:03 +0100 +Subject: powerpc: Fix dedotify for binutils >= 2.26 + +From: Andreas Schwab + +commit f15838e9cac8f78f0cc506529bb9d3b9fa589c1f upstream. + +Since binutils 2.26 BFD is doing suffix merging on STRTAB sections. But +dedotify modifies the symbol names in place, which can also modify +unrelated symbols with a name that matches a suffix of a dotted name. To +remove the leading dot of a symbol name we can just increment the pointer +into the STRTAB section instead. + +Backport to all stables to avoid breakage when people update their +binutils - mpe. + +Signed-off-by: Andreas Schwab +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/kernel/module_64.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/powerpc/kernel/module_64.c ++++ b/arch/powerpc/kernel/module_64.c +@@ -335,7 +335,7 @@ static void dedotify(Elf64_Sym *syms, un + if (syms[i].st_shndx == SHN_UNDEF) { + char *name = strtab + syms[i].st_name; + if (name[0] == '.') +- memmove(name, name+1, strlen(name)); ++ syms[i].st_name++; + } + } + } diff --git a/queue-4.4/powerpc-powernv-add-a-kmsg_dumper-that-flushes-console-output-on-panic.patch b/queue-4.4/powerpc-powernv-add-a-kmsg_dumper-that-flushes-console-output-on-panic.patch new file mode 100644 index 00000000000..e9ceb0f4991 --- /dev/null +++ b/queue-4.4/powerpc-powernv-add-a-kmsg_dumper-that-flushes-console-output-on-panic.patch @@ -0,0 +1,187 @@ +From affddff69c55eb68969448f35f59054a370bc7c1 Mon Sep 17 00:00:00 2001 +From: Russell Currey +Date: Fri, 27 Nov 2015 17:23:07 +1100 +Subject: powerpc/powernv: Add a kmsg_dumper that flushes console output on panic + +From: Russell Currey + +commit affddff69c55eb68969448f35f59054a370bc7c1 upstream. + +On BMC machines, console output is controlled by the OPAL firmware and is +only flushed when its pollers are called. When the kernel is in a panic +state, it no longer calls these pollers and thus console output does not +completely flush, causing some output from the panic to be lost. + +Output is only actually lost when the kernel is configured to not power off +or reboot after panic (i.e. CONFIG_PANIC_TIMEOUT is set to 0) since OPAL +flushes the console buffer as part of its power down routines. Before this +patch, however, only partial output would be printed during the timeout wait. + +This patch adds a new kmsg_dumper which gets called at panic time to ensure +panic output is not lost. It accomplishes this by calling OPAL_CONSOLE_FLUSH +in the OPAL API, and if that is not available, the pollers are called enough +times to (hopefully) completely flush the buffer. + +The flushing mechanism will only affect output printed at and before the +kmsg_dump call in kernel/panic.c:panic(). As such, the "end Kernel panic" +message may still be truncated as follows: + +>Call Trace: +>[c000000f1f603b00] [c0000000008e9458] dump_stack+0x90/0xbc (unreliable) +>[c000000f1f603b30] [c0000000008e7e78] panic+0xf8/0x2c4 +>[c000000f1f603bc0] [c000000000be4860] mount_block_root+0x288/0x33c +>[c000000f1f603c80] [c000000000be4d14] prepare_namespace+0x1f4/0x254 +>[c000000f1f603d00] [c000000000be43e8] kernel_init_freeable+0x318/0x350 +>[c000000f1f603dc0] [c00000000000bd74] kernel_init+0x24/0x130 +>[c000000f1f603e30] [c0000000000095b0] ret_from_kernel_thread+0x5c/0xac +>---[ end Kernel panic - not + +This functionality is implemented as a kmsg_dumper as it seems to be the +most sensible way to introduce platform-specific functionality to the +panic function. + +Signed-off-by: Russell Currey +Reviewed-by: Andrew Donnellan +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/include/asm/opal-api.h | 3 - + arch/powerpc/include/asm/opal.h | 3 + + arch/powerpc/platforms/powernv/Makefile | 1 + arch/powerpc/platforms/powernv/opal-kmsg.c | 68 +++++++++++++++++++++++++ + arch/powerpc/platforms/powernv/opal-wrappers.S | 1 + arch/powerpc/platforms/powernv/opal.c | 3 + + 6 files changed, 78 insertions(+), 1 deletion(-) + +--- a/arch/powerpc/include/asm/opal-api.h ++++ b/arch/powerpc/include/asm/opal-api.h +@@ -157,7 +157,8 @@ + #define OPAL_LEDS_GET_INDICATOR 114 + #define OPAL_LEDS_SET_INDICATOR 115 + #define OPAL_CEC_REBOOT2 116 +-#define OPAL_LAST 116 ++#define OPAL_CONSOLE_FLUSH 117 ++#define OPAL_LAST 117 + + /* Device tree flags */ + +--- a/arch/powerpc/include/asm/opal.h ++++ b/arch/powerpc/include/asm/opal.h +@@ -35,6 +35,7 @@ int64_t opal_console_read(int64_t term_n + uint8_t *buffer); + int64_t opal_console_write_buffer_space(int64_t term_number, + __be64 *length); ++void opal_console_flush(void); + int64_t opal_rtc_read(__be32 *year_month_day, + __be64 *hour_minute_second_millisecond); + int64_t opal_rtc_write(uint32_t year_month_day, +@@ -262,6 +263,8 @@ extern int opal_resync_timebase(void); + + extern void opal_lpc_init(void); + ++extern void opal_kmsg_init(void); ++ + extern int opal_event_request(unsigned int opal_event_nr); + + struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr, +--- a/arch/powerpc/platforms/powernv/Makefile ++++ b/arch/powerpc/platforms/powernv/Makefile +@@ -2,6 +2,7 @@ obj-y += setup.o opal-wrappers.o opal. + obj-y += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o + obj-y += rng.o opal-elog.o opal-dump.o opal-sysparam.o opal-sensor.o + obj-y += opal-msglog.o opal-hmi.o opal-power.o opal-irqchip.o ++obj-y += opal-kmsg.o + + obj-$(CONFIG_SMP) += smp.o subcore.o subcore-asm.o + obj-$(CONFIG_PCI) += pci.o pci-p5ioc2.o pci-ioda.o +--- /dev/null ++++ b/arch/powerpc/platforms/powernv/opal-kmsg.c +@@ -0,0 +1,68 @@ ++/* ++ * kmsg dumper that ensures the OPAL console fully flushes panic messages ++ * ++ * Author: Russell Currey ++ * ++ * Copyright 2015 IBM Corporation. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++#include ++ ++#include ++#include ++ ++/* ++ * Console output is controlled by OPAL firmware. The kernel regularly calls ++ * OPAL_POLL_EVENTS, which flushes some console output. In a panic state, ++ * however, the kernel no longer calls OPAL_POLL_EVENTS and the panic message ++ * may not be completely printed. This function does not actually dump the ++ * message, it just ensures that OPAL completely flushes the console buffer. ++ */ ++static void force_opal_console_flush(struct kmsg_dumper *dumper, ++ enum kmsg_dump_reason reason) ++{ ++ int i; ++ ++ /* ++ * Outside of a panic context the pollers will continue to run, ++ * so we don't need to do any special flushing. ++ */ ++ if (reason != KMSG_DUMP_PANIC) ++ return; ++ ++ if (opal_check_token(OPAL_CONSOLE_FLUSH)) { ++ opal_console_flush(); ++ } else { ++ /* ++ * If OPAL_CONSOLE_FLUSH is not implemented in the firmware, ++ * the console can still be flushed by calling the polling ++ * function enough times to flush the buffer. We don't know ++ * how much output still needs to be flushed, but we can be ++ * generous since the kernel is in panic and doesn't need ++ * to do much else. ++ */ ++ printk(KERN_NOTICE "opal: OPAL_CONSOLE_FLUSH missing.\n"); ++ for (i = 0; i < 1024; i++) { ++ opal_poll_events(NULL); ++ } ++ } ++} ++ ++static struct kmsg_dumper opal_kmsg_dumper = { ++ .dump = force_opal_console_flush ++}; ++ ++void __init opal_kmsg_init(void) ++{ ++ int rc; ++ ++ /* Add our dumper to the list */ ++ rc = kmsg_dump_register(&opal_kmsg_dumper); ++ if (rc != 0) ++ pr_err("opal: kmsg_dump_register failed; returned %d\n", rc); ++} +--- a/arch/powerpc/platforms/powernv/opal-wrappers.S ++++ b/arch/powerpc/platforms/powernv/opal-wrappers.S +@@ -301,3 +301,4 @@ OPAL_CALL(opal_flash_erase, OPAL_FLASH + OPAL_CALL(opal_prd_msg, OPAL_PRD_MSG); + OPAL_CALL(opal_leds_get_ind, OPAL_LEDS_GET_INDICATOR); + OPAL_CALL(opal_leds_set_ind, OPAL_LEDS_SET_INDICATOR); ++OPAL_CALL(opal_console_flush, OPAL_CONSOLE_FLUSH); +--- a/arch/powerpc/platforms/powernv/opal.c ++++ b/arch/powerpc/platforms/powernv/opal.c +@@ -758,6 +758,9 @@ static int __init opal_init(void) + opal_pdev_init(opal_node, "ibm,opal-flash"); + opal_pdev_init(opal_node, "ibm,opal-prd"); + ++ /* Initialise OPAL kmsg dumper for flushing console on panic */ ++ opal_kmsg_init(); ++ + return 0; + } + machine_subsys_initcall(powernv, opal_init); diff --git a/queue-4.4/powerpc-powernv-fix-opal_console_flush-prototype-and-usages.patch b/queue-4.4/powerpc-powernv-fix-opal_console_flush-prototype-and-usages.patch new file mode 100644 index 00000000000..e4b6b3ee0ea --- /dev/null +++ b/queue-4.4/powerpc-powernv-fix-opal_console_flush-prototype-and-usages.patch @@ -0,0 +1,62 @@ +From c88c5d43732a0356f99e5e4d1ad62ab1ea516b81 Mon Sep 17 00:00:00 2001 +From: Russell Currey +Date: Wed, 13 Jan 2016 12:04:32 +1100 +Subject: powerpc/powernv: Fix OPAL_CONSOLE_FLUSH prototype and usages + +From: Russell Currey + +commit c88c5d43732a0356f99e5e4d1ad62ab1ea516b81 upstream. + +The recently added OPAL API call, OPAL_CONSOLE_FLUSH, originally took no +parameters and returned nothing. The call was updated to accept the +terminal number to flush, and returned various values depending on the +state of the output buffer. + +The prototype has been updated and its usage in the OPAL kmsg dumper has +been modified to support its new behaviour as an incremental flush. + +Signed-off-by: Russell Currey +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/include/asm/opal.h | 2 +- + arch/powerpc/platforms/powernv/opal-kmsg.c | 9 ++++++++- + 2 files changed, 9 insertions(+), 2 deletions(-) + +--- a/arch/powerpc/include/asm/opal.h ++++ b/arch/powerpc/include/asm/opal.h +@@ -35,7 +35,7 @@ int64_t opal_console_read(int64_t term_n + uint8_t *buffer); + int64_t opal_console_write_buffer_space(int64_t term_number, + __be64 *length); +-void opal_console_flush(void); ++int64_t opal_console_flush(int64_t term_number); + int64_t opal_rtc_read(__be32 *year_month_day, + __be64 *hour_minute_second_millisecond); + int64_t opal_rtc_write(uint32_t year_month_day, +--- a/arch/powerpc/platforms/powernv/opal-kmsg.c ++++ b/arch/powerpc/platforms/powernv/opal-kmsg.c +@@ -27,6 +27,7 @@ static void force_opal_console_flush(str + enum kmsg_dump_reason reason) + { + int i; ++ int64_t ret; + + /* + * Outside of a panic context the pollers will continue to run, +@@ -36,7 +37,13 @@ static void force_opal_console_flush(str + return; + + if (opal_check_token(OPAL_CONSOLE_FLUSH)) { +- opal_console_flush(); ++ ret = opal_console_flush(0); ++ ++ if (ret == OPAL_UNSUPPORTED || ret == OPAL_PARAMETER) ++ return; ++ ++ /* Incrementally flush until there's nothing left */ ++ while (opal_console_flush(0) != OPAL_SUCCESS); + } else { + /* + * If OPAL_CONSOLE_FLUSH is not implemented in the firmware, diff --git a/queue-4.4/revert-drm-radeon-call-hpd_irq_event-on-resume.patch b/queue-4.4/revert-drm-radeon-call-hpd_irq_event-on-resume.patch new file mode 100644 index 00000000000..d818817e45c --- /dev/null +++ b/queue-4.4/revert-drm-radeon-call-hpd_irq_event-on-resume.patch @@ -0,0 +1,49 @@ +From 256faedcfd646161477d47a1a78c32a562d2e845 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Mon, 7 Mar 2016 13:15:09 -0800 +Subject: Revert "drm/radeon: call hpd_irq_event on resume" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Linus Torvalds + +commit 256faedcfd646161477d47a1a78c32a562d2e845 upstream. + +This reverts commit dbb17a21c131eca94eb31136eee9a7fe5aff00d9. + +It turns out that commit can cause problems for systems with multiple +GPUs, and causes X to hang on at least a HP Pavilion dv7 with hybrid +graphics. + +This got noticed originally in 4.4.4, where this patch had already +gotten back-ported, but 4.5-rc7 was verified to have the same problem. + +Alexander Deucher says: + "It looks like you have a muxed system so I suspect what's happening is + that one of the display is being reported as connected for both the + IGP and the dGPU and then the desktop environment gets confused or + there some sort problem in the detect functions since the mux is not + switched to the dGPU. I don't see an easy fix unless Dave has any + ideas. I'd say just revert for now" + +Reported-by: Jörg-Volker Peetz +Acked-by: Alexander Deucher +Cc: Dave Airlie +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_device.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/gpu/drm/radeon/radeon_device.c ++++ b/drivers/gpu/drm/radeon/radeon_device.c +@@ -1744,7 +1744,6 @@ int radeon_resume_kms(struct drm_device + } + + drm_kms_helper_poll_enable(dev); +- drm_helper_hpd_irq_event(dev); + + /* set the power state here in case we are a PX system or headless */ + if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) diff --git a/queue-4.4/revert-drm-radeon-pm-adjust-display-configuration-after-powerstate.patch b/queue-4.4/revert-drm-radeon-pm-adjust-display-configuration-after-powerstate.patch new file mode 100644 index 00000000000..b7148df304e --- /dev/null +++ b/queue-4.4/revert-drm-radeon-pm-adjust-display-configuration-after-powerstate.patch @@ -0,0 +1,44 @@ +From d74e766e1916d0e09b86e4b5b9d0f819628fd546 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 8 Mar 2016 11:31:00 -0500 +Subject: Revert "drm/radeon/pm: adjust display configuration after powerstate" + +From: Alex Deucher + +commit d74e766e1916d0e09b86e4b5b9d0f819628fd546 upstream. + +This reverts commit 39d4275058baf53e89203407bf3841ff2c74fa32. + +This caused a regression on some older hardware. + +bug: +https://bugzilla.kernel.org/show_bug.cgi?id=113891 + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_pm.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_pm.c ++++ b/drivers/gpu/drm/radeon/radeon_pm.c +@@ -1075,6 +1075,8 @@ force: + + /* update display watermarks based on new power state */ + radeon_bandwidth_update(rdev); ++ /* update displays */ ++ radeon_dpm_display_configuration_changed(rdev); + + /* wait for the rings to drain */ + for (i = 0; i < RADEON_NUM_RINGS; i++) { +@@ -1091,9 +1093,6 @@ force: + + radeon_dpm_post_set_power_state(rdev); + +- /* update displays */ +- radeon_dpm_display_configuration_changed(rdev); +- + rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs; + rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count; + rdev->pm.dpm.single_display = single_display; diff --git a/queue-4.4/s390-dasd-fix-diag-0x250-inline-assembly.patch b/queue-4.4/s390-dasd-fix-diag-0x250-inline-assembly.patch new file mode 100644 index 00000000000..bd41b36aab5 --- /dev/null +++ b/queue-4.4/s390-dasd-fix-diag-0x250-inline-assembly.patch @@ -0,0 +1,63 @@ +From ce0c12b633846a47e103842149a5bac2e5d261ec Mon Sep 17 00:00:00 2001 +From: Heiko Carstens +Date: Tue, 1 Mar 2016 12:58:06 +0100 +Subject: s390/dasd: fix diag 0x250 inline assembly + +From: Heiko Carstens + +commit ce0c12b633846a47e103842149a5bac2e5d261ec upstream. + +git commit 1ec2772e0c3c ("s390/diag: add a statistic for diagnose +calls") added function calls to gather diagnose statistics. + +In case of the dasd diag driver the function call was added between a +register asm statement which initialized register r2 and the inline +assembly itself. The function call clobbers the contents of register +r2 and therefore the diag 0x250 call behaves in a more or less random +way. + +Fix this by extracting the function call into a separate function like +we do everywhere else. + +Fixes: 1ec2772e0c3c ("s390/diag: add a statistic for diagnose calls") +Reported-and-tested-by: Stefan Haberland +Signed-off-by: Heiko Carstens +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/s390/block/dasd_diag.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/s390/block/dasd_diag.c ++++ b/drivers/s390/block/dasd_diag.c +@@ -67,7 +67,7 @@ static const u8 DASD_DIAG_CMS1[] = { 0xc + * and function code cmd. + * In case of an exception return 3. Otherwise return result of bitwise OR of + * resulting condition code and DIAG return code. */ +-static inline int dia250(void *iob, int cmd) ++static inline int __dia250(void *iob, int cmd) + { + register unsigned long reg2 asm ("2") = (unsigned long) iob; + typedef union { +@@ -77,7 +77,6 @@ static inline int dia250(void *iob, int + int rc; + + rc = 3; +- diag_stat_inc(DIAG_STAT_X250); + asm volatile( + " diag 2,%2,0x250\n" + "0: ipm %0\n" +@@ -91,6 +90,12 @@ static inline int dia250(void *iob, int + return rc; + } + ++static inline int dia250(void *iob, int cmd) ++{ ++ diag_stat_inc(DIAG_STAT_X250); ++ return __dia250(iob, cmd); ++} ++ + /* Initialize block I/O to DIAG device using the specified blocksize and + * block offset. On success, return zero and set end_block to contain the + * number of blocks on the device minus the specified offset. Return non-zero diff --git a/queue-4.4/s390-mm-four-page-table-levels-vs.-fork.patch b/queue-4.4/s390-mm-four-page-table-levels-vs.-fork.patch new file mode 100644 index 00000000000..db7692f324f --- /dev/null +++ b/queue-4.4/s390-mm-four-page-table-levels-vs.-fork.patch @@ -0,0 +1,121 @@ +From 3446c13b268af86391d06611327006b059b8bab1 Mon Sep 17 00:00:00 2001 +From: Martin Schwidefsky +Date: Mon, 15 Feb 2016 14:46:49 +0100 +Subject: s390/mm: four page table levels vs. fork +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Martin Schwidefsky + +commit 3446c13b268af86391d06611327006b059b8bab1 upstream. + +The fork of a process with four page table levels is broken since +git commit 6252d702c5311ce9 "[S390] dynamic page tables." + +All new mm contexts are created with three page table levels and +an asce limit of 4TB. If the parent has four levels dup_mmap will +add vmas to the new context which are outside of the asce limit. +The subsequent call to copy_page_range will walk the three level +page table structure of the new process with non-zero pgd and pud +indexes. This leads to memory clobbers as the pgd_index *and* the +pud_index is added to the mm->pgd pointer without a pgd_deref +in between. + +The init_new_context() function is selecting the number of page +table levels for a new context. The function is used by mm_init() +which in turn is called by dup_mm() and mm_alloc(). These two are +used by fork() and exec(). The init_new_context() function can +distinguish the two cases by looking at mm->context.asce_limit, +for fork() the mm struct has been copied and the number of page +table levels may not change. For exec() the mm_alloc() function +set the new mm structure to zero, in this case a three-level page +table is created as the temporary stack space is located at +STACK_TOP_MAX = 4TB. + +This fixes CVE-2016-2143. + +Reported-by: Marcin Kościelnicki +Reviewed-by: Heiko Carstens +Signed-off-by: Martin Schwidefsky +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/include/asm/mmu_context.h | 16 +++++++++++----- + arch/s390/include/asm/pgalloc.h | 24 +++++++++++++++++++----- + 2 files changed, 30 insertions(+), 10 deletions(-) + +--- a/arch/s390/include/asm/mmu_context.h ++++ b/arch/s390/include/asm/mmu_context.h +@@ -15,17 +15,25 @@ + static inline int init_new_context(struct task_struct *tsk, + struct mm_struct *mm) + { ++ spin_lock_init(&mm->context.list_lock); ++ INIT_LIST_HEAD(&mm->context.pgtable_list); ++ INIT_LIST_HEAD(&mm->context.gmap_list); + cpumask_clear(&mm->context.cpu_attach_mask); + atomic_set(&mm->context.attach_count, 0); + mm->context.flush_mm = 0; +- mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS; +- mm->context.asce_bits |= _ASCE_TYPE_REGION3; + #ifdef CONFIG_PGSTE + mm->context.alloc_pgste = page_table_allocate_pgste; + mm->context.has_pgste = 0; + mm->context.use_skey = 0; + #endif +- mm->context.asce_limit = STACK_TOP_MAX; ++ if (mm->context.asce_limit == 0) { ++ /* context created by exec, set asce limit to 4TB */ ++ mm->context.asce_bits = _ASCE_TABLE_LENGTH | ++ _ASCE_USER_BITS | _ASCE_TYPE_REGION3; ++ mm->context.asce_limit = STACK_TOP_MAX; ++ } else if (mm->context.asce_limit == (1UL << 31)) { ++ mm_inc_nr_pmds(mm); ++ } + crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm)); + return 0; + } +@@ -111,8 +119,6 @@ static inline void activate_mm(struct mm + static inline void arch_dup_mmap(struct mm_struct *oldmm, + struct mm_struct *mm) + { +- if (oldmm->context.asce_limit < mm->context.asce_limit) +- crst_table_downgrade(mm, oldmm->context.asce_limit); + } + + static inline void arch_exit_mmap(struct mm_struct *mm) +--- a/arch/s390/include/asm/pgalloc.h ++++ b/arch/s390/include/asm/pgalloc.h +@@ -100,12 +100,26 @@ static inline void pud_populate(struct m + + static inline pgd_t *pgd_alloc(struct mm_struct *mm) + { +- spin_lock_init(&mm->context.list_lock); +- INIT_LIST_HEAD(&mm->context.pgtable_list); +- INIT_LIST_HEAD(&mm->context.gmap_list); +- return (pgd_t *) crst_table_alloc(mm); ++ unsigned long *table = crst_table_alloc(mm); ++ ++ if (!table) ++ return NULL; ++ if (mm->context.asce_limit == (1UL << 31)) { ++ /* Forking a compat process with 2 page table levels */ ++ if (!pgtable_pmd_page_ctor(virt_to_page(table))) { ++ crst_table_free(mm, table); ++ return NULL; ++ } ++ } ++ return (pgd_t *) table; ++} ++ ++static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) ++{ ++ if (mm->context.asce_limit == (1UL << 31)) ++ pgtable_pmd_page_dtor(virt_to_page(pgd)); ++ crst_table_free(mm, (unsigned long *) pgd); + } +-#define pgd_free(mm, pgd) crst_table_free(mm, (unsigned long *) pgd) + + static inline void pmd_populate(struct mm_struct *mm, + pmd_t *pmd, pgtable_t pte) diff --git a/queue-4.4/tracing-fix-check-for-cpu-online-when-event-is-disabled.patch b/queue-4.4/tracing-fix-check-for-cpu-online-when-event-is-disabled.patch new file mode 100644 index 00000000000..c5923786860 --- /dev/null +++ b/queue-4.4/tracing-fix-check-for-cpu-online-when-event-is-disabled.patch @@ -0,0 +1,72 @@ +From dc17147de328a74bbdee67c1bf37d2f1992de756 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (Red Hat)" +Date: Wed, 9 Mar 2016 11:58:41 -0500 +Subject: tracing: Fix check for cpu online when event is disabled + +From: Steven Rostedt (Red Hat) + +commit dc17147de328a74bbdee67c1bf37d2f1992de756 upstream. + +Commit f37755490fe9b ("tracepoints: Do not trace when cpu is offline") added +a check to make sure that tracepoints only get called when the cpu is +online, as it uses rcu_read_lock_sched() for protection. + +Commit 3a630178fd5f3 ("tracing: generate RCU warnings even when tracepoints +are disabled") added lockdep checks (including rcu checks) for events that +are not enabled to catch possible RCU issues that would only be triggered if +a trace event was enabled. Commit f37755490fe9b only stopped the warnings +when the trace event was enabled but did not prevent warnings if the trace +event was called when disabled. + +To fix this, the cpu online check is moved to where the condition is added +to the trace event. This will place the cpu online check in all places that +it may be used now and in the future. + +Fixes: f37755490fe9b ("tracepoints: Do not trace when cpu is offline") +Fixes: 3a630178fd5f3 ("tracing: generate RCU warnings even when tracepoints are disabled") +Reported-by: Sudeep Holla +Tested-by: Sudeep Holla +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/tracepoint.h | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +--- a/include/linux/tracepoint.h ++++ b/include/linux/tracepoint.h +@@ -148,9 +148,6 @@ extern void syscall_unregfunc(void); + void *it_func; \ + void *__data; \ + \ +- if (!cpu_online(raw_smp_processor_id())) \ +- return; \ +- \ + if (!(cond)) \ + return; \ + prercu; \ +@@ -357,15 +354,19 @@ extern void syscall_unregfunc(void); + * "void *__data, proto" as the callback prototype. + */ + #define DECLARE_TRACE_NOARGS(name) \ +- __DECLARE_TRACE(name, void, , 1, void *__data, __data) ++ __DECLARE_TRACE(name, void, , \ ++ cpu_online(raw_smp_processor_id()), \ ++ void *__data, __data) + + #define DECLARE_TRACE(name, proto, args) \ +- __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), 1, \ +- PARAMS(void *__data, proto), \ +- PARAMS(__data, args)) ++ __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \ ++ cpu_online(raw_smp_processor_id()), \ ++ PARAMS(void *__data, proto), \ ++ PARAMS(__data, args)) + + #define DECLARE_TRACE_CONDITION(name, proto, args, cond) \ +- __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), PARAMS(cond), \ ++ __DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \ ++ cpu_online(raw_smp_processor_id()) && (PARAMS(cond)), \ + PARAMS(void *__data, proto), \ + PARAMS(__data, args)) + diff --git a/queue-4.4/wext-fix-message-delay-ordering.patch b/queue-4.4/wext-fix-message-delay-ordering.patch new file mode 100644 index 00000000000..a683e9919f7 --- /dev/null +++ b/queue-4.4/wext-fix-message-delay-ordering.patch @@ -0,0 +1,122 @@ +From 8bf862739a7786ae72409220914df960a0aa80d8 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Wed, 27 Jan 2016 12:37:52 +0100 +Subject: wext: fix message delay/ordering + +From: Johannes Berg + +commit 8bf862739a7786ae72409220914df960a0aa80d8 upstream. + +Beniamino reported that he was getting an RTM_NEWLINK message for a +given interface, after the RTM_DELLINK for it. It turns out that the +message is a wireless extensions message, which was sent because the +interface had been connected and disconnection while it was deleted +caused a wext message. + +For its netlink messages, wext uses RTM_NEWLINK, but the message is +without all the regular rtnetlink attributes, so "ip monitor link" +prints just rudimentary information: + +5: wlan1: mtu 1500 qdisc mq state DOWN group default + link/ether 02:00:00:00:01:00 brd ff:ff:ff:ff:ff:ff +Deleted 5: wlan1: mtu 1500 qdisc noop state DOWN group default + link/ether 02:00:00:00:01:00 brd ff:ff:ff:ff:ff:ff +5: wlan1: + link/ether +(from my hwsim reproduction) + +This can cause userspace to get confused since it doesn't expect an +RTM_NEWLINK message after RTM_DELLINK. + +The reason for this is that wext schedules a worker to send out the +messages, and the scheduling delay can cause the messages to get out +to userspace in different order. + +To fix this, have wext register a netdevice notifier and flush out +any pending messages when netdevice state changes. This fixes any +ordering whenever the original message wasn't sent by a notifier +itself. + +Reported-by: Beniamino Galvani +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/wireless/wext-core.c | 51 ++++++++++++++++++++++++++++++++++++----------- + 1 file changed, 40 insertions(+), 11 deletions(-) + +--- a/net/wireless/wext-core.c ++++ b/net/wireless/wext-core.c +@@ -342,6 +342,39 @@ static const int compat_event_type_size[ + + /* IW event code */ + ++static void wireless_nlevent_flush(void) ++{ ++ struct sk_buff *skb; ++ struct net *net; ++ ++ ASSERT_RTNL(); ++ ++ for_each_net(net) { ++ while ((skb = skb_dequeue(&net->wext_nlevents))) ++ rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, ++ GFP_KERNEL); ++ } ++} ++ ++static int wext_netdev_notifier_call(struct notifier_block *nb, ++ unsigned long state, void *ptr) ++{ ++ /* ++ * When a netdev changes state in any way, flush all pending messages ++ * to avoid them going out in a strange order, e.g. RTM_NEWLINK after ++ * RTM_DELLINK, or with IFF_UP after without IFF_UP during dev_close() ++ * or similar - all of which could otherwise happen due to delays from ++ * schedule_work(). ++ */ ++ wireless_nlevent_flush(); ++ ++ return NOTIFY_OK; ++} ++ ++static struct notifier_block wext_netdev_notifier = { ++ .notifier_call = wext_netdev_notifier_call, ++}; ++ + static int __net_init wext_pernet_init(struct net *net) + { + skb_queue_head_init(&net->wext_nlevents); +@@ -360,7 +393,12 @@ static struct pernet_operations wext_per + + static int __init wireless_nlevent_init(void) + { +- return register_pernet_subsys(&wext_pernet_ops); ++ int err = register_pernet_subsys(&wext_pernet_ops); ++ ++ if (err) ++ return err; ++ ++ return register_netdevice_notifier(&wext_netdev_notifier); + } + + subsys_initcall(wireless_nlevent_init); +@@ -368,17 +406,8 @@ subsys_initcall(wireless_nlevent_init); + /* Process events generated by the wireless layer or the driver. */ + static void wireless_nlevent_process(struct work_struct *work) + { +- struct sk_buff *skb; +- struct net *net; +- + rtnl_lock(); +- +- for_each_net(net) { +- while ((skb = skb_dequeue(&net->wext_nlevents))) +- rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, +- GFP_KERNEL); +- } +- ++ wireless_nlevent_flush(); + rtnl_unlock(); + } + diff --git a/queue-4.4/x86-mm-fix-slow_virt_to_phys-for-x86_pae-again.patch b/queue-4.4/x86-mm-fix-slow_virt_to_phys-for-x86_pae-again.patch new file mode 100644 index 00000000000..9e1ccfcfa46 --- /dev/null +++ b/queue-4.4/x86-mm-fix-slow_virt_to_phys-for-x86_pae-again.patch @@ -0,0 +1,74 @@ +From bf70e5513dfea29c3682e7eb3dbb45f0723bac09 Mon Sep 17 00:00:00 2001 +From: Dexuan Cui +Date: Thu, 25 Feb 2016 01:58:12 -0800 +Subject: x86/mm: Fix slow_virt_to_phys() for X86_PAE again + +From: Dexuan Cui + +commit bf70e5513dfea29c3682e7eb3dbb45f0723bac09 upstream. + +"d1cd12108346: x86, pageattr: Prevent overflow in slow_virt_to_phys() for +X86_PAE" was unintentionally removed by the recent "34437e67a672: x86/mm: Fix +slow_virt_to_phys() to handle large PAT bit". + +And, the variable 'phys_addr' was defined as "unsigned long" by mistake -- it should +be "phys_addr_t". + +As a result, Hyper-V network driver in 32-PAE Linux guest can't work again. + +Fixes: commit 34437e67a672: "x86/mm: Fix slow_virt_to_phys() to handle large PAT bit" +Signed-off-by: Dexuan Cui +Reviewed-by: Toshi Kani +Cc: olaf@aepfle.de +Cc: jasowang@redhat.com +Cc: driverdev-devel@linuxdriverproject.org +Cc: linux-mm@kvack.org +Cc: apw@canonical.com +Cc: Andrew Morton +Cc: K. Y. Srinivasan +Cc: Haiyang Zhang +Link: http://lkml.kernel.org/r/1456394292-9030-1-git-send-email-decui@microsoft.com +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/mm/pageattr.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/arch/x86/mm/pageattr.c ++++ b/arch/x86/mm/pageattr.c +@@ -414,24 +414,30 @@ pmd_t *lookup_pmd_address(unsigned long + phys_addr_t slow_virt_to_phys(void *__virt_addr) + { + unsigned long virt_addr = (unsigned long)__virt_addr; +- unsigned long phys_addr, offset; ++ phys_addr_t phys_addr; ++ unsigned long offset; + enum pg_level level; + pte_t *pte; + + pte = lookup_address(virt_addr, &level); + BUG_ON(!pte); + ++ /* ++ * pXX_pfn() returns unsigned long, which must be cast to phys_addr_t ++ * before being left-shifted PAGE_SHIFT bits -- this trick is to ++ * make 32-PAE kernel work correctly. ++ */ + switch (level) { + case PG_LEVEL_1G: +- phys_addr = pud_pfn(*(pud_t *)pte) << PAGE_SHIFT; ++ phys_addr = (phys_addr_t)pud_pfn(*(pud_t *)pte) << PAGE_SHIFT; + offset = virt_addr & ~PUD_PAGE_MASK; + break; + case PG_LEVEL_2M: +- phys_addr = pmd_pfn(*(pmd_t *)pte) << PAGE_SHIFT; ++ phys_addr = (phys_addr_t)pmd_pfn(*(pmd_t *)pte) << PAGE_SHIFT; + offset = virt_addr & ~PMD_PAGE_MASK; + break; + default: +- phys_addr = pte_pfn(*pte) << PAGE_SHIFT; ++ phys_addr = (phys_addr_t)pte_pfn(*pte) << PAGE_SHIFT; + offset = virt_addr & ~PAGE_MASK; + } +