]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 18 Oct 2015 00:34:30 +0000 (17:34 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 18 Oct 2015 00:34:30 +0000 (17:34 -0700)
added patches:
arm64-efi-fix-boot-crash-by-not-padding-between-efi_memory_runtime-regions.patch
arm64-ftrace-fix-function_graph-tracer-panic.patch
arm64-readahead-fault-retry-breaks-mmap-file-read-random-detection.patch
clk-ti-fix-dual-registration-of-uart4_ick.patch
dm-cache-fix-null-pointer-when-switching-from-cleaner-policy.patch
dm-fix-ab-ba-deadlock-in-__dm_destroy.patch
drivers-tty-require-read-access-for-controlling-terminal.patch
fix-a-braino-in-ovl_d_select_inode.patch
genirq-fix-race-in-register_irq_proc.patch
igb-do-not-re-init-sr-iov-during-probe.patch
m68k-define-asmlinkage_protect.patch
md-bitmap-don-t-pass-1-to-bitmap_storage_alloc.patch
namei-results-of-d_is_negative-should-be-checked-after-dentry-revalidation.patch
net-xen-netfront-only-napi_synchronize-if-running.patch
nfs-filelayout-fix-null-reference-caused-by-double-freeing-of-fh_array.patch
overlay-call-ovl_drop_write-earlier-in-ovl_dentry_open.patch
overlayfs-make-f_path-always-point-to-the-overlay-and-f_inode-to-the-underlay.patch
serial-8250-add-uart_config-entry-for-port_rt2880.patch
staging-speakup-fix-speakup-r-regression.patch
tty-fix-stall-caused-by-missing-memory-barrier-in-drivers-tty-n_tty.c.patch

22 files changed:
queue-4.1/arm64-efi-fix-boot-crash-by-not-padding-between-efi_memory_runtime-regions.patch [new file with mode: 0644]
queue-4.1/arm64-ftrace-fix-function_graph-tracer-panic.patch [new file with mode: 0644]
queue-4.1/arm64-readahead-fault-retry-breaks-mmap-file-read-random-detection.patch [new file with mode: 0644]
queue-4.1/clk-ti-fix-dual-registration-of-uart4_ick.patch [new file with mode: 0644]
queue-4.1/dm-cache-fix-null-pointer-when-switching-from-cleaner-policy.patch [new file with mode: 0644]
queue-4.1/dm-fix-ab-ba-deadlock-in-__dm_destroy.patch [new file with mode: 0644]
queue-4.1/drivers-tty-require-read-access-for-controlling-terminal.patch [new file with mode: 0644]
queue-4.1/fix-a-braino-in-ovl_d_select_inode.patch [new file with mode: 0644]
queue-4.1/genirq-fix-race-in-register_irq_proc.patch [new file with mode: 0644]
queue-4.1/igb-do-not-re-init-sr-iov-during-probe.patch [new file with mode: 0644]
queue-4.1/m68k-define-asmlinkage_protect.patch [new file with mode: 0644]
queue-4.1/md-bitmap-don-t-pass-1-to-bitmap_storage_alloc.patch [new file with mode: 0644]
queue-4.1/namei-results-of-d_is_negative-should-be-checked-after-dentry-revalidation.patch [new file with mode: 0644]
queue-4.1/net-xen-netfront-only-napi_synchronize-if-running.patch [new file with mode: 0644]
queue-4.1/netfilter-ipset-fixing-unnamed-union-init.patch [deleted file]
queue-4.1/nfs-filelayout-fix-null-reference-caused-by-double-freeing-of-fh_array.patch [new file with mode: 0644]
queue-4.1/overlay-call-ovl_drop_write-earlier-in-ovl_dentry_open.patch [new file with mode: 0644]
queue-4.1/overlayfs-make-f_path-always-point-to-the-overlay-and-f_inode-to-the-underlay.patch [new file with mode: 0644]
queue-4.1/serial-8250-add-uart_config-entry-for-port_rt2880.patch [new file with mode: 0644]
queue-4.1/series
queue-4.1/staging-speakup-fix-speakup-r-regression.patch [new file with mode: 0644]
queue-4.1/tty-fix-stall-caused-by-missing-memory-barrier-in-drivers-tty-n_tty.c.patch [new file with mode: 0644]

diff --git a/queue-4.1/arm64-efi-fix-boot-crash-by-not-padding-between-efi_memory_runtime-regions.patch b/queue-4.1/arm64-efi-fix-boot-crash-by-not-padding-between-efi_memory_runtime-regions.patch
new file mode 100644 (file)
index 0000000..c665bd3
--- /dev/null
@@ -0,0 +1,194 @@
+From 0ce3cc008ec04258b6a6314b09f1a6012810881a Mon Sep 17 00:00:00 2001
+From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Date: Fri, 25 Sep 2015 23:02:19 +0100
+Subject: arm64/efi: Fix boot crash by not padding between EFI_MEMORY_RUNTIME regions
+
+From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+
+commit 0ce3cc008ec04258b6a6314b09f1a6012810881a upstream.
+
+The new Properties Table feature introduced in UEFIv2.5 may
+split memory regions that cover PE/COFF memory images into
+separate code and data regions. Since these regions only differ
+in the type (runtime code vs runtime data) and the permission
+bits, but not in the memory type attributes (UC/WC/WT/WB), the
+spec does not require them to be aligned to 64 KB.
+
+Since the relative offset of PE/COFF .text and .data segments
+cannot be changed on the fly, this means that we can no longer
+pad out those regions to be mappable using 64 KB pages.
+Unfortunately, there is no annotation in the UEFI memory map
+that identifies data regions that were split off from a code
+region, so we must apply this logic to all adjacent runtime
+regions whose attributes only differ in the permission bits.
+
+So instead of rounding each memory region to 64 KB alignment at
+both ends, only round down regions that are not directly
+preceded by another runtime region with the same type
+attributes. Since the UEFI spec does not mandate that the memory
+map be sorted, this means we also need to sort it first.
+
+Note that this change will result in all EFI_MEMORY_RUNTIME
+regions whose start addresses are not aligned to the OS page
+size to be mapped with executable permissions (i.e., on kernels
+compiled with 64 KB pages). However, since these mappings are
+only active during the time that UEFI Runtime Services are being
+invoked, the window for abuse is rather small.
+
+Tested-by: Mark Salter <msalter@redhat.com>
+Tested-by: Mark Rutland <mark.rutland@arm.com> [UEFI 2.4 only]
+Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
+Signed-off-by: Matt Fleming <matt.fleming@intel.com>
+Reviewed-by: Mark Salter <msalter@redhat.com>
+Reviewed-by: Mark Rutland <mark.rutland@arm.com>
+Cc: Catalin Marinas <catalin.marinas@arm.com>
+Cc: Leif Lindholm <leif.lindholm@linaro.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Mike Galbraith <efault@gmx.de>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Will Deacon <will.deacon@arm.com>
+Cc: linux-kernel@vger.kernel.org
+Link: http://lkml.kernel.org/r/1443218539-7610-3-git-send-email-matt@codeblueprint.co.uk
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/kernel/efi.c                 |    3 -
+ drivers/firmware/efi/libstub/arm-stub.c |   86 ++++++++++++++++++++++++++------
+ 2 files changed, 74 insertions(+), 15 deletions(-)
+
+--- a/arch/arm64/kernel/efi.c
++++ b/arch/arm64/kernel/efi.c
+@@ -257,7 +257,8 @@ static bool __init efi_virtmap_init(void
+                */
+               if (!is_normal_ram(md))
+                       prot = __pgprot(PROT_DEVICE_nGnRE);
+-              else if (md->type == EFI_RUNTIME_SERVICES_CODE)
++              else if (md->type == EFI_RUNTIME_SERVICES_CODE ||
++                       !PAGE_ALIGNED(md->phys_addr))
+                       prot = PAGE_KERNEL_EXEC;
+               else
+                       prot = PAGE_KERNEL;
+--- a/drivers/firmware/efi/libstub/arm-stub.c
++++ b/drivers/firmware/efi/libstub/arm-stub.c
+@@ -13,6 +13,7 @@
+  */
+ #include <linux/efi.h>
++#include <linux/sort.h>
+ #include <asm/efi.h>
+ #include "efistub.h"
+@@ -305,6 +306,44 @@ fail:
+  */
+ #define EFI_RT_VIRTUAL_BASE   0x40000000
++static int cmp_mem_desc(const void *l, const void *r)
++{
++      const efi_memory_desc_t *left = l, *right = r;
++
++      return (left->phys_addr > right->phys_addr) ? 1 : -1;
++}
++
++/*
++ * Returns whether region @left ends exactly where region @right starts,
++ * or false if either argument is NULL.
++ */
++static bool regions_are_adjacent(efi_memory_desc_t *left,
++                               efi_memory_desc_t *right)
++{
++      u64 left_end;
++
++      if (left == NULL || right == NULL)
++              return false;
++
++      left_end = left->phys_addr + left->num_pages * EFI_PAGE_SIZE;
++
++      return left_end == right->phys_addr;
++}
++
++/*
++ * Returns whether region @left and region @right have compatible memory type
++ * mapping attributes, and are both EFI_MEMORY_RUNTIME regions.
++ */
++static bool regions_have_compatible_memory_type_attrs(efi_memory_desc_t *left,
++                                                    efi_memory_desc_t *right)
++{
++      static const u64 mem_type_mask = EFI_MEMORY_WB | EFI_MEMORY_WT |
++                                       EFI_MEMORY_WC | EFI_MEMORY_UC |
++                                       EFI_MEMORY_RUNTIME;
++
++      return ((left->attribute ^ right->attribute) & mem_type_mask) == 0;
++}
++
+ /*
+  * efi_get_virtmap() - create a virtual mapping for the EFI memory map
+  *
+@@ -317,33 +356,52 @@ void efi_get_virtmap(efi_memory_desc_t *
+                    int *count)
+ {
+       u64 efi_virt_base = EFI_RT_VIRTUAL_BASE;
+-      efi_memory_desc_t *out = runtime_map;
++      efi_memory_desc_t *in, *prev = NULL, *out = runtime_map;
+       int l;
+-      for (l = 0; l < map_size; l += desc_size) {
+-              efi_memory_desc_t *in = (void *)memory_map + l;
++      /*
++       * To work around potential issues with the Properties Table feature
++       * introduced in UEFI 2.5, which may split PE/COFF executable images
++       * in memory into several RuntimeServicesCode and RuntimeServicesData
++       * regions, we need to preserve the relative offsets between adjacent
++       * EFI_MEMORY_RUNTIME regions with the same memory type attributes.
++       * The easiest way to find adjacent regions is to sort the memory map
++       * before traversing it.
++       */
++      sort(memory_map, map_size / desc_size, desc_size, cmp_mem_desc, NULL);
++
++      for (l = 0; l < map_size; l += desc_size, prev = in) {
+               u64 paddr, size;
++              in = (void *)memory_map + l;
+               if (!(in->attribute & EFI_MEMORY_RUNTIME))
+                       continue;
++              paddr = in->phys_addr;
++              size = in->num_pages * EFI_PAGE_SIZE;
++
+               /*
+                * Make the mapping compatible with 64k pages: this allows
+                * a 4k page size kernel to kexec a 64k page size kernel and
+                * vice versa.
+                */
+-              paddr = round_down(in->phys_addr, SZ_64K);
+-              size = round_up(in->num_pages * EFI_PAGE_SIZE +
+-                              in->phys_addr - paddr, SZ_64K);
++              if (!regions_are_adjacent(prev, in) ||
++                  !regions_have_compatible_memory_type_attrs(prev, in)) {
+-              /*
+-               * Avoid wasting memory on PTEs by choosing a virtual base that
+-               * is compatible with section mappings if this region has the
+-               * appropriate size and physical alignment. (Sections are 2 MB
+-               * on 4k granule kernels)
+-               */
+-              if (IS_ALIGNED(in->phys_addr, SZ_2M) && size >= SZ_2M)
+-                      efi_virt_base = round_up(efi_virt_base, SZ_2M);
++                      paddr = round_down(in->phys_addr, SZ_64K);
++                      size += in->phys_addr - paddr;
++
++                      /*
++                       * Avoid wasting memory on PTEs by choosing a virtual
++                       * base that is compatible with section mappings if this
++                       * region has the appropriate size and physical
++                       * alignment. (Sections are 2 MB on 4k granule kernels)
++                       */
++                      if (IS_ALIGNED(in->phys_addr, SZ_2M) && size >= SZ_2M)
++                              efi_virt_base = round_up(efi_virt_base, SZ_2M);
++                      else
++                              efi_virt_base = round_up(efi_virt_base, SZ_64K);
++              }
+               in->virt_addr = efi_virt_base + in->phys_addr - paddr;
+               efi_virt_base += size;
diff --git a/queue-4.1/arm64-ftrace-fix-function_graph-tracer-panic.patch b/queue-4.1/arm64-ftrace-fix-function_graph-tracer-panic.patch
new file mode 100644 (file)
index 0000000..d993586
--- /dev/null
@@ -0,0 +1,112 @@
+From ee556d00cf20012e889344a0adbbf809ab5015a3 Mon Sep 17 00:00:00 2001
+From: Li Bin <huawei.libin@huawei.com>
+Date: Wed, 30 Sep 2015 10:49:55 +0800
+Subject: arm64: ftrace: fix function_graph tracer panic
+
+From: Li Bin <huawei.libin@huawei.com>
+
+commit ee556d00cf20012e889344a0adbbf809ab5015a3 upstream.
+
+When function graph tracer is enabled, the following operation
+will trigger panic:
+
+mount -t debugfs nodev /sys/kernel
+echo next_tgid > /sys/kernel/tracing/set_ftrace_filter
+echo function_graph > /sys/kernel/tracing/current_tracer
+ls /proc/
+
+------------[ cut here ]------------
+[  198.501417] Unable to handle kernel paging request at virtual address cb88537fdc8ba316
+[  198.506126] pgd = ffffffc008f79000
+[  198.509363] [cb88537fdc8ba316] *pgd=00000000488c6003, *pud=00000000488c6003, *pmd=0000000000000000
+[  198.517726] Internal error: Oops: 94000005 [#1] SMP
+[  198.518798] Modules linked in:
+[  198.520582] CPU: 1 PID: 1388 Comm: ls Tainted: G
+[  198.521800] Hardware name: linux,dummy-virt (DT)
+[  198.522852] task: ffffffc0fa9e8000 ti: ffffffc0f9ab0000 task.ti: ffffffc0f9ab0000
+[  198.524306] PC is at next_tgid+0x30/0x100
+[  198.525205] LR is at return_to_handler+0x0/0x20
+[  198.526090] pc : [<ffffffc0002a1070>] lr : [<ffffffc0000907c0>] pstate: 60000145
+[  198.527392] sp : ffffffc0f9ab3d40
+[  198.528084] x29: ffffffc0f9ab3d40 x28: ffffffc0f9ab0000
+[  198.529406] x27: ffffffc000d6a000 x26: ffffffc000b786e8
+[  198.530659] x25: ffffffc0002a1900 x24: ffffffc0faf16c00
+[  198.531942] x23: ffffffc0f9ab3ea0 x22: 0000000000000002
+[  198.533202] x21: ffffffc000d85050 x20: 0000000000000002
+[  198.534446] x19: 0000000000000002 x18: 0000000000000000
+[  198.535719] x17: 000000000049fa08 x16: ffffffc000242efc
+[  198.537030] x15: 0000007fa472b54c x14: ffffffffff000000
+[  198.538347] x13: ffffffc0fada84a0 x12: 0000000000000001
+[  198.539634] x11: ffffffc0f9ab3d70 x10: ffffffc0f9ab3d70
+[  198.540915] x9 : ffffffc0000907c0 x8 : ffffffc0f9ab3d40
+[  198.542215] x7 : 0000002e330f08f0 x6 : 0000000000000015
+[  198.543508] x5 : 0000000000000f08 x4 : ffffffc0f9835ec0
+[  198.544792] x3 : cb88537fdc8ba316 x2 : cb88537fdc8ba306
+[  198.546108] x1 : 0000000000000002 x0 : ffffffc000d85050
+[  198.547432]
+[  198.547920] Process ls (pid: 1388, stack limit = 0xffffffc0f9ab0020)
+[  198.549170] Stack: (0xffffffc0f9ab3d40 to 0xffffffc0f9ab4000)
+[  198.582568] Call trace:
+[  198.583313] [<ffffffc0002a1070>] next_tgid+0x30/0x100
+[  198.584359] [<ffffffc0000907bc>] ftrace_graph_caller+0x6c/0x70
+[  198.585503] [<ffffffc0000907bc>] ftrace_graph_caller+0x6c/0x70
+[  198.586574] [<ffffffc0000907bc>] ftrace_graph_caller+0x6c/0x70
+[  198.587660] [<ffffffc0000907bc>] ftrace_graph_caller+0x6c/0x70
+[  198.588896] Code: aa0003f5 2a0103f4 b4000102 91004043 (885f7c60)
+[  198.591092] ---[ end trace 6a346f8f20949ac8 ]---
+
+This is because when using function graph tracer, if the traced
+function return value is in multi regs ([x0-x7]), return_to_handler
+may corrupt them. So in return_to_handler, the parameter regs should
+be protected properly.
+
+Signed-off-by: Li Bin <huawei.libin@huawei.com>
+Acked-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/kernel/entry-ftrace.S |   22 ++++++++++++++++++++--
+ 1 file changed, 20 insertions(+), 2 deletions(-)
+
+--- a/arch/arm64/kernel/entry-ftrace.S
++++ b/arch/arm64/kernel/entry-ftrace.S
+@@ -178,6 +178,24 @@ ENTRY(ftrace_stub)
+ ENDPROC(ftrace_stub)
+ #ifdef CONFIG_FUNCTION_GRAPH_TRACER
++      /* save return value regs*/
++      .macro save_return_regs
++      sub sp, sp, #64
++      stp x0, x1, [sp]
++      stp x2, x3, [sp, #16]
++      stp x4, x5, [sp, #32]
++      stp x6, x7, [sp, #48]
++      .endm
++
++      /* restore return value regs*/
++      .macro restore_return_regs
++      ldp x0, x1, [sp]
++      ldp x2, x3, [sp, #16]
++      ldp x4, x5, [sp, #32]
++      ldp x6, x7, [sp, #48]
++      add sp, sp, #64
++      .endm
++
+ /*
+  * void ftrace_graph_caller(void)
+  *
+@@ -204,11 +222,11 @@ ENDPROC(ftrace_graph_caller)
+  * only when CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST is enabled.
+  */
+ ENTRY(return_to_handler)
+-      str     x0, [sp, #-16]!
++      save_return_regs
+       mov     x0, x29                 //     parent's fp
+       bl      ftrace_return_to_handler// addr = ftrace_return_to_hander(fp);
+       mov     x30, x0                 // restore the original return address
+-      ldr     x0, [sp], #16
++      restore_return_regs
+       ret
+ END(return_to_handler)
+ #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/queue-4.1/arm64-readahead-fault-retry-breaks-mmap-file-read-random-detection.patch b/queue-4.1/arm64-readahead-fault-retry-breaks-mmap-file-read-random-detection.patch
new file mode 100644 (file)
index 0000000..32ec82d
--- /dev/null
@@ -0,0 +1,48 @@
+From 569ba74a7ba69f46ce2950bf085b37fea2408385 Mon Sep 17 00:00:00 2001
+From: Mark Salyzyn <salyzyn@android.com>
+Date: Mon, 21 Sep 2015 21:39:50 +0100
+Subject: arm64: readahead: fault retry breaks mmap file read random detection
+
+From: Mark Salyzyn <salyzyn@android.com>
+
+commit 569ba74a7ba69f46ce2950bf085b37fea2408385 upstream.
+
+This is the arm64 portion of commit 45cac65b0fcd ("readahead: fault
+retry breaks mmap file read random detection"), which was absent from
+the initial port and has since gone unnoticed. The original commit says:
+
+> .fault now can retry.  The retry can break state machine of .fault.  In
+> filemap_fault, if page is miss, ra->mmap_miss is increased.  In the second
+> try, since the page is in page cache now, ra->mmap_miss is decreased.  And
+> these are done in one fault, so we can't detect random mmap file access.
+>
+> Add a new flag to indicate .fault is tried once.  In the second try, skip
+> ra->mmap_miss decreasing.  The filemap_fault state machine is ok with it.
+
+With this change, Mark reports that:
+
+> Random read improves by 250%, sequential read improves by 40%, and
+> random write by 400% to an eMMC device with dm crypto wrapped around it.
+
+Cc: Shaohua Li <shli@kernel.org>
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Wu Fengguang <fengguang.wu@intel.com>
+Signed-off-by: Mark Salyzyn <salyzyn@android.com>
+Signed-off-by: Riley Andrews <riandrews@android.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm64/mm/fault.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm64/mm/fault.c
++++ b/arch/arm64/mm/fault.c
+@@ -279,6 +279,7 @@ retry:
+                        * starvation.
+                        */
+                       mm_flags &= ~FAULT_FLAG_ALLOW_RETRY;
++                      mm_flags |= FAULT_FLAG_TRIED;
+                       goto retry;
+               }
+       }
diff --git a/queue-4.1/clk-ti-fix-dual-registration-of-uart4_ick.patch b/queue-4.1/clk-ti-fix-dual-registration-of-uart4_ick.patch
new file mode 100644 (file)
index 0000000..53eeb12
--- /dev/null
@@ -0,0 +1,51 @@
+From 19e79687de22f23bcfb5e79cce3daba20af228d1 Mon Sep 17 00:00:00 2001
+From: Ben Dooks <ben.dooks@codethink.co.uk>
+Date: Tue, 29 Sep 2015 15:01:08 +0100
+Subject: clk: ti: fix dual-registration of uart4_ick
+
+From: Ben Dooks <ben.dooks@codethink.co.uk>
+
+commit 19e79687de22f23bcfb5e79cce3daba20af228d1 upstream.
+
+On the OMAP AM3517 platform the uart4_ick gets registered
+twice, causing any power management to /dev/ttyO3 to fail
+when trying to wake the device up.
+
+This solves the following oops:
+
+[] Unhandled fault: external abort on non-linefetch (0x1028) at 0xfa09e008
+[] PC is at serial_omap_pm+0x48/0x15c
+[] LR is at _raw_spin_unlock_irqrestore+0x30/0x5c
+
+Fixes: aafd900cab87 ("CLK: TI: add omap3 clock init file")
+Cc: mturquette@baylibre.com
+Cc: sboyd@codeaurora.org
+Cc: linux-clk@vger.kernel.org
+Cc: linux-omap@vger.kernel.org
+Cc: linux-kernel@lists.codethink.co.uk
+Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
+Signed-off-by: Tero Kristo <t-kristo@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clk/ti/clk-3xxx.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/clk/ti/clk-3xxx.c
++++ b/drivers/clk/ti/clk-3xxx.c
+@@ -163,7 +163,6 @@ static struct ti_dt_clk omap3xxx_clks[]
+       DT_CLK(NULL, "gpio2_ick", "gpio2_ick"),
+       DT_CLK(NULL, "wdt3_ick", "wdt3_ick"),
+       DT_CLK(NULL, "uart3_ick", "uart3_ick"),
+-      DT_CLK(NULL, "uart4_ick", "uart4_ick"),
+       DT_CLK(NULL, "gpt9_ick", "gpt9_ick"),
+       DT_CLK(NULL, "gpt8_ick", "gpt8_ick"),
+       DT_CLK(NULL, "gpt7_ick", "gpt7_ick"),
+@@ -308,6 +307,7 @@ static struct ti_dt_clk am35xx_clks[] =
+ static struct ti_dt_clk omap36xx_clks[] = {
+       DT_CLK(NULL, "omap_192m_alwon_fck", "omap_192m_alwon_fck"),
+       DT_CLK(NULL, "uart4_fck", "uart4_fck"),
++      DT_CLK(NULL, "uart4_ick", "uart4_ick"),
+       { .node_name = NULL },
+ };
diff --git a/queue-4.1/dm-cache-fix-null-pointer-when-switching-from-cleaner-policy.patch b/queue-4.1/dm-cache-fix-null-pointer-when-switching-from-cleaner-policy.patch
new file mode 100644 (file)
index 0000000..c3e7e87
--- /dev/null
@@ -0,0 +1,37 @@
+From 2bffa1503c5c06192eb1459180fac4416575a966 Mon Sep 17 00:00:00 2001
+From: Joe Thornber <ejt@redhat.com>
+Date: Fri, 9 Oct 2015 14:03:38 +0100
+Subject: dm cache: fix NULL pointer when switching from cleaner policy
+
+From: Joe Thornber <ejt@redhat.com>
+
+commit 2bffa1503c5c06192eb1459180fac4416575a966 upstream.
+
+The cleaner policy doesn't make use of the per cache block hint space in
+the metadata (unlike the other policies).  When switching from the
+cleaner policy to mq or smq a NULL pointer crash (in dm_tm_new_block)
+was observed.  The crash was caused by bugs in dm-cache-metadata.c
+when trying to skip creation of the hint btree.
+
+The minimal fix is to change hint size for the cleaner policy to 4 bytes
+(only hint size supported).
+
+Signed-off-by: Joe Thornber <ejt@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-cache-policy-cleaner.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/md/dm-cache-policy-cleaner.c
++++ b/drivers/md/dm-cache-policy-cleaner.c
+@@ -435,7 +435,7 @@ static struct dm_cache_policy *wb_create
+ static struct dm_cache_policy_type wb_policy_type = {
+       .name = "cleaner",
+       .version = {1, 0, 0},
+-      .hint_size = 0,
++      .hint_size = 4,
+       .owner = THIS_MODULE,
+       .create = wb_create
+ };
diff --git a/queue-4.1/dm-fix-ab-ba-deadlock-in-__dm_destroy.patch b/queue-4.1/dm-fix-ab-ba-deadlock-in-__dm_destroy.patch
new file mode 100644 (file)
index 0000000..5082f91
--- /dev/null
@@ -0,0 +1,63 @@
+From 2a708cff93f1845b9239bc7d6310aef54e716c6a Mon Sep 17 00:00:00 2001
+From: Junichi Nomura <j-nomura@ce.jp.nec.com>
+Date: Thu, 1 Oct 2015 08:31:51 +0000
+Subject: dm: fix AB-BA deadlock in __dm_destroy()
+
+From: Junichi Nomura <j-nomura@ce.jp.nec.com>
+
+commit 2a708cff93f1845b9239bc7d6310aef54e716c6a upstream.
+
+__dm_destroy() takes io_barrier SRCU lock (dm_get_live_table) and
+suspend_lock in reverse order.  Doing so can cause AB-BA deadlock:
+
+  __dm_destroy                    dm_swap_table
+  ---------------------------------------------------
+                                  mutex_lock(suspend_lock)
+  dm_get_live_table()
+    srcu_read_lock(io_barrier)
+                                  dm_sync_table()
+                                    synchronize_srcu(io_barrier)
+                                      .. waiting for dm_put_live_table()
+  mutex_lock(suspend_lock)
+    .. waiting for suspend_lock
+
+Fix this by taking the locks in proper order.
+
+Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
+Fixes: ab7c7bb6f4ab ("dm: hold suspend_lock while suspending device during device deletion")
+Acked-by: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -2925,8 +2925,6 @@ static void __dm_destroy(struct mapped_d
+       might_sleep();
+-      map = dm_get_live_table(md, &srcu_idx);
+-
+       spin_lock(&_minor_lock);
+       idr_replace(&_minor_idr, MINOR_ALLOCED, MINOR(disk_devt(dm_disk(md))));
+       set_bit(DMF_FREEING, &md->flags);
+@@ -2940,14 +2938,14 @@ static void __dm_destroy(struct mapped_d
+        * do not race with internal suspend.
+        */
+       mutex_lock(&md->suspend_lock);
++      map = dm_get_live_table(md, &srcu_idx);
+       if (!dm_suspended_md(md)) {
+               dm_table_presuspend_targets(map);
+               dm_table_postsuspend_targets(map);
+       }
+-      mutex_unlock(&md->suspend_lock);
+-
+       /* dm_put_live_table must be before msleep, otherwise deadlock is possible */
+       dm_put_live_table(md, srcu_idx);
++      mutex_unlock(&md->suspend_lock);
+       /*
+        * Rare, but there may be I/O requests still going to complete,
diff --git a/queue-4.1/drivers-tty-require-read-access-for-controlling-terminal.patch b/queue-4.1/drivers-tty-require-read-access-for-controlling-terminal.patch
new file mode 100644 (file)
index 0000000..b3eadb9
--- /dev/null
@@ -0,0 +1,80 @@
+From 0c55627167870255158db1cde0d28366f91c8872 Mon Sep 17 00:00:00 2001
+From: Jann Horn <jann@thejh.net>
+Date: Sun, 4 Oct 2015 19:29:12 +0200
+Subject: drivers/tty: require read access for controlling terminal
+
+From: Jann Horn <jann@thejh.net>
+
+commit 0c55627167870255158db1cde0d28366f91c8872 upstream.
+
+This is mostly a hardening fix, given that write-only access to other
+users' ttys is usually only given through setgid tty executables.
+
+Signed-off-by: Jann Horn <jann@thejh.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/tty_io.c |   31 +++++++++++++++++++++++++++----
+ 1 file changed, 27 insertions(+), 4 deletions(-)
+
+--- a/drivers/tty/tty_io.c
++++ b/drivers/tty/tty_io.c
+@@ -2144,8 +2144,24 @@ retry_open:
+       if (!noctty &&
+           current->signal->leader &&
+           !current->signal->tty &&
+-          tty->session == NULL)
+-              __proc_set_tty(tty);
++          tty->session == NULL) {
++              /*
++               * Don't let a process that only has write access to the tty
++               * obtain the privileges associated with having a tty as
++               * controlling terminal (being able to reopen it with full
++               * access through /dev/tty, being able to perform pushback).
++               * Many distributions set the group of all ttys to "tty" and
++               * grant write-only access to all terminals for setgid tty
++               * binaries, which should not imply full privileges on all ttys.
++               *
++               * This could theoretically break old code that performs open()
++               * on a write-only file descriptor. In that case, it might be
++               * necessary to also permit this if
++               * inode_permission(inode, MAY_READ) == 0.
++               */
++              if (filp->f_mode & FMODE_READ)
++                      __proc_set_tty(tty);
++      }
+       spin_unlock_irq(&current->sighand->siglock);
+       read_unlock(&tasklist_lock);
+       tty_unlock(tty);
+@@ -2434,7 +2450,7 @@ static int fionbio(struct file *file, in
+  *            Takes ->siglock() when updating signal->tty
+  */
+-static int tiocsctty(struct tty_struct *tty, int arg)
++static int tiocsctty(struct tty_struct *tty, struct file *file, int arg)
+ {
+       int ret = 0;
+@@ -2468,6 +2484,13 @@ static int tiocsctty(struct tty_struct *
+                       goto unlock;
+               }
+       }
++
++      /* See the comment in tty_open(). */
++      if ((file->f_mode & FMODE_READ) == 0 && !capable(CAP_SYS_ADMIN)) {
++              ret = -EPERM;
++              goto unlock;
++      }
++
+       proc_set_tty(tty);
+ unlock:
+       read_unlock(&tasklist_lock);
+@@ -2860,7 +2883,7 @@ long tty_ioctl(struct file *file, unsign
+               no_tty();
+               return 0;
+       case TIOCSCTTY:
+-              return tiocsctty(tty, arg);
++              return tiocsctty(tty, file, arg);
+       case TIOCGPGRP:
+               return tiocgpgrp(tty, real_tty, p);
+       case TIOCSPGRP:
diff --git a/queue-4.1/fix-a-braino-in-ovl_d_select_inode.patch b/queue-4.1/fix-a-braino-in-ovl_d_select_inode.patch
new file mode 100644 (file)
index 0000000..7d6efd9
--- /dev/null
@@ -0,0 +1,34 @@
+From 9391dd00d13c853ab4f2a85435288ae2202e0e43 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Sun, 12 Jul 2015 10:39:45 -0400
+Subject: fix a braino in ovl_d_select_inode()
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+commit 9391dd00d13c853ab4f2a85435288ae2202e0e43 upstream.
+
+when opening a directory we want the overlayfs inode, not one from
+the topmost layer.
+
+Reported-By: Andrey Jr. Melnikov <temnota.am@gmail.com>
+Tested-By: Andrey Jr. Melnikov <temnota.am@gmail.com>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Cc: "Kamata, Munehisa" <kamatam@amazon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/inode.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -342,6 +342,9 @@ struct inode *ovl_d_select_inode(struct
+       struct path realpath;
+       enum ovl_path_type type;
++      if (d_is_dir(dentry))
++              return d_backing_inode(dentry);
++
+       type = ovl_path_real(dentry, &realpath);
+       if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) {
+               err = ovl_want_write(dentry);
diff --git a/queue-4.1/genirq-fix-race-in-register_irq_proc.patch b/queue-4.1/genirq-fix-race-in-register_irq_proc.patch
new file mode 100644 (file)
index 0000000..b5b8362
--- /dev/null
@@ -0,0 +1,76 @@
+From 95c2b17534654829db428f11bcf4297c059a2a7e Mon Sep 17 00:00:00 2001
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Sat, 26 Sep 2015 12:23:56 +0100
+Subject: genirq: Fix race in register_irq_proc()
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+commit 95c2b17534654829db428f11bcf4297c059a2a7e upstream.
+
+Per-IRQ directories in procfs are created only when a handler is first
+added to the irqdesc, not when the irqdesc is created.  In the case of
+a shared IRQ, multiple tasks can race to create a directory.  This
+race condition seems to have been present forever, but is easier to
+hit with async probing.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Link: http://lkml.kernel.org/r/1443266636.2004.2.camel@decadent.org.uk
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/irq/proc.c |   19 +++++++++++++++++--
+ 1 file changed, 17 insertions(+), 2 deletions(-)
+
+--- a/kernel/irq/proc.c
++++ b/kernel/irq/proc.c
+@@ -12,6 +12,7 @@
+ #include <linux/seq_file.h>
+ #include <linux/interrupt.h>
+ #include <linux/kernel_stat.h>
++#include <linux/mutex.h>
+ #include "internals.h"
+@@ -323,18 +324,29 @@ void register_handler_proc(unsigned int
+ void register_irq_proc(unsigned int irq, struct irq_desc *desc)
+ {
++      static DEFINE_MUTEX(register_lock);
+       char name [MAX_NAMELEN];
+-      if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip) || desc->dir)
++      if (!root_irq_dir || (desc->irq_data.chip == &no_irq_chip))
+               return;
++      /*
++       * irq directories are registered only when a handler is
++       * added, not when the descriptor is created, so multiple
++       * tasks might try to register at the same time.
++       */
++      mutex_lock(&register_lock);
++
++      if (desc->dir)
++              goto out_unlock;
++
+       memset(name, 0, MAX_NAMELEN);
+       sprintf(name, "%d", irq);
+       /* create /proc/irq/1234 */
+       desc->dir = proc_mkdir(name, root_irq_dir);
+       if (!desc->dir)
+-              return;
++              goto out_unlock;
+ #ifdef CONFIG_SMP
+       /* create /proc/irq/<irq>/smp_affinity */
+@@ -355,6 +367,9 @@ void register_irq_proc(unsigned int irq,
+       proc_create_data("spurious", 0444, desc->dir,
+                        &irq_spurious_proc_fops, (void *)(long)irq);
++
++out_unlock:
++      mutex_unlock(&register_lock);
+ }
+ void unregister_irq_proc(unsigned int irq, struct irq_desc *desc)
diff --git a/queue-4.1/igb-do-not-re-init-sr-iov-during-probe.patch b/queue-4.1/igb-do-not-re-init-sr-iov-during-probe.patch
new file mode 100644 (file)
index 0000000..5cd7bed
--- /dev/null
@@ -0,0 +1,47 @@
+From 6423fc34160939142d72ffeaa2db6408317f54df Mon Sep 17 00:00:00 2001
+From: Stefan Assmann <sassmann@kpanic.de>
+Date: Fri, 10 Jul 2015 15:01:12 +0200
+Subject: igb: do not re-init SR-IOV during probe
+
+From: Stefan Assmann <sassmann@kpanic.de>
+
+commit 6423fc34160939142d72ffeaa2db6408317f54df upstream.
+
+During driver probing the following code path is triggered.
+igb_probe
+->igb_sw_init
+  ->igb_probe_vfs
+    ->igb_pci_enable_sriov
+      ->igb_sriov_reinit
+
+Doing the SR-IOV re-init is not necessary during probing since we're
+starting from scratch. Here we can call igb_enable_sriov() right away.
+
+Running igb_sriov_reinit() during igb_probe() also seems to cause
+occasional packet loss on some onboard 82576 NICs. Reproduced on
+Dell and HP servers with onboard 82576 NICs.
+Example:
+Intel Corporation 82576 Gigabit Network Connection [8086:10c9] (rev 01)
+Subsystem: Dell Device [1028:0481]
+
+Signed-off-by: Stefan Assmann <sassmann@kpanic.de>
+Tested-by: Aaron Brown <aaron.f.brown@intel.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
+Cc: Daniel J Blueman <daniel@numascale.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/intel/igb/igb_main.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/intel/igb/igb_main.c
++++ b/drivers/net/ethernet/intel/igb/igb_main.c
+@@ -2864,7 +2864,7 @@ static void igb_probe_vfs(struct igb_ada
+               return;
+       pci_sriov_set_totalvfs(pdev, 7);
+-      igb_pci_enable_sriov(pdev, max_vfs);
++      igb_enable_sriov(pdev, max_vfs);
+ #endif /* CONFIG_PCI_IOV */
+ }
diff --git a/queue-4.1/m68k-define-asmlinkage_protect.patch b/queue-4.1/m68k-define-asmlinkage_protect.patch
new file mode 100644 (file)
index 0000000..e284c30
--- /dev/null
@@ -0,0 +1,70 @@
+From 8474ba74193d302e8340dddd1e16c85cc4b98caf Mon Sep 17 00:00:00 2001
+From: Andreas Schwab <schwab@linux-m68k.org>
+Date: Wed, 23 Sep 2015 23:12:09 +0200
+Subject: m68k: Define asmlinkage_protect
+
+From: Andreas Schwab <schwab@linux-m68k.org>
+
+commit 8474ba74193d302e8340dddd1e16c85cc4b98caf upstream.
+
+Make sure the compiler does not modify arguments of syscall functions.
+This can happen if the compiler generates a tailcall to another
+function.  For example, without asmlinkage_protect sys_openat is compiled
+into this function:
+
+sys_openat:
+       clr.l %d0
+       move.w 18(%sp),%d0
+       move.l %d0,16(%sp)
+       jbra do_sys_open
+
+Note how the fourth argument is modified in place, modifying the register
+%d4 that gets restored from this stack slot when the function returns to
+user-space.  The caller may expect the register to be unmodified across
+system calls.
+
+Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
+Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/m68k/include/asm/linkage.h |   30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+--- a/arch/m68k/include/asm/linkage.h
++++ b/arch/m68k/include/asm/linkage.h
+@@ -4,4 +4,34 @@
+ #define __ALIGN .align 4
+ #define __ALIGN_STR ".align 4"
++/*
++ * Make sure the compiler doesn't do anything stupid with the
++ * arguments on the stack - they are owned by the *caller*, not
++ * the callee. This just fools gcc into not spilling into them,
++ * and keeps it from doing tailcall recursion and/or using the
++ * stack slots for temporaries, since they are live and "used"
++ * all the way to the end of the function.
++ */
++#define asmlinkage_protect(n, ret, args...) \
++      __asmlinkage_protect##n(ret, ##args)
++#define __asmlinkage_protect_n(ret, args...) \
++      __asm__ __volatile__ ("" : "=r" (ret) : "0" (ret), ##args)
++#define __asmlinkage_protect0(ret) \
++      __asmlinkage_protect_n(ret)
++#define __asmlinkage_protect1(ret, arg1) \
++      __asmlinkage_protect_n(ret, "m" (arg1))
++#define __asmlinkage_protect2(ret, arg1, arg2) \
++      __asmlinkage_protect_n(ret, "m" (arg1), "m" (arg2))
++#define __asmlinkage_protect3(ret, arg1, arg2, arg3) \
++      __asmlinkage_protect_n(ret, "m" (arg1), "m" (arg2), "m" (arg3))
++#define __asmlinkage_protect4(ret, arg1, arg2, arg3, arg4) \
++      __asmlinkage_protect_n(ret, "m" (arg1), "m" (arg2), "m" (arg3), \
++                            "m" (arg4))
++#define __asmlinkage_protect5(ret, arg1, arg2, arg3, arg4, arg5) \
++      __asmlinkage_protect_n(ret, "m" (arg1), "m" (arg2), "m" (arg3), \
++                            "m" (arg4), "m" (arg5))
++#define __asmlinkage_protect6(ret, arg1, arg2, arg3, arg4, arg5, arg6) \
++      __asmlinkage_protect_n(ret, "m" (arg1), "m" (arg2), "m" (arg3), \
++                            "m" (arg4), "m" (arg5), "m" (arg6))
++
+ #endif
diff --git a/queue-4.1/md-bitmap-don-t-pass-1-to-bitmap_storage_alloc.patch b/queue-4.1/md-bitmap-don-t-pass-1-to-bitmap_storage_alloc.patch
new file mode 100644 (file)
index 0000000..738cca9
--- /dev/null
@@ -0,0 +1,34 @@
+From da6fb7a9e5bd6f04f7e15070f630bdf1ea502841 Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Thu, 1 Oct 2015 16:03:38 +1000
+Subject: md/bitmap: don't pass -1 to bitmap_storage_alloc.
+
+From: NeilBrown <neilb@suse.com>
+
+commit da6fb7a9e5bd6f04f7e15070f630bdf1ea502841 upstream.
+
+Passing -1 to bitmap_storage_alloc() causes page->index to be set to
+-1, which is quite problematic.
+
+So only pass ->cluster_slot if mddev_is_clustered().
+
+Fixes: b97e92574c0b ("Use separate bitmaps for each nodes in the cluster")
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/bitmap.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/md/bitmap.c
++++ b/drivers/md/bitmap.c
+@@ -2000,7 +2000,8 @@ int bitmap_resize(struct bitmap *bitmap,
+       if (bitmap->mddev->bitmap_info.offset || bitmap->mddev->bitmap_info.file)
+               ret = bitmap_storage_alloc(&store, chunks,
+                                          !bitmap->mddev->bitmap_info.external,
+-                                         bitmap->cluster_slot);
++                                         mddev_is_clustered(bitmap->mddev)
++                                         ? bitmap->cluster_slot : 0);
+       if (ret)
+               goto err;
diff --git a/queue-4.1/namei-results-of-d_is_negative-should-be-checked-after-dentry-revalidation.patch b/queue-4.1/namei-results-of-d_is_negative-should-be-checked-after-dentry-revalidation.patch
new file mode 100644 (file)
index 0000000..a7c05f3
--- /dev/null
@@ -0,0 +1,74 @@
+From daf3761c9fcde0f4ca64321cbed6c1c86d304193 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Fri, 9 Oct 2015 13:44:34 -0400
+Subject: namei: results of d_is_negative() should be checked after dentry revalidation
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+commit daf3761c9fcde0f4ca64321cbed6c1c86d304193 upstream.
+
+Leandro Awa writes:
+ "After switching to version 4.1.6, our parallelized and distributed
+  workflows now fail consistently with errors of the form:
+
+  T34: ./regex.c:39:22: error: config.h: No such file or directory
+
+  From our 'git bisect' testing, the following commit appears to be the
+  possible cause of the behavior we've been seeing: commit 766c4cbfacd8"
+
+Al Viro says:
+ "What happens is that 766c4cbfacd8 got the things subtly wrong.
+
+  We used to treat d_is_negative() after lookup_fast() as "fall with
+  ENOENT".  That was wrong - checking ->d_flags outside of ->d_seq
+  protection is unreliable and failing with hard error on what should've
+  fallen back to non-RCU pathname resolution is a bug.
+
+  Unfortunately, we'd pulled the test too far up and ran afoul of
+  another kind of staleness.  The dentry might have been absolutely
+  stable from the RCU point of view (and we might be on UP, etc), but
+  stale from the remote fs point of view.  If ->d_revalidate() returns
+  "it's actually stale", dentry gets thrown away and the original code
+  wouldn't even have looked at its ->d_flags.
+
+  What we need is to check ->d_flags where 766c4cbfacd8 does (prior to
+  ->d_seq validation) but only use the result in cases where we do not
+  discard this dentry outright"
+
+Reported-by: Leandro Awa <lawa@nvidia.com>
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=104911
+Fixes: 766c4cbfacd8 ("namei: d_is_negative() should be checked...")
+Tested-by: Leandro Awa <lawa@nvidia.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Acked-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/namei.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -1453,8 +1453,6 @@ static int lookup_fast(struct nameidata
+               negative = d_is_negative(dentry);
+               if (read_seqcount_retry(&dentry->d_seq, seq))
+                       return -ECHILD;
+-              if (negative)
+-                      return -ENOENT;
+               /*
+                * This sequence count validates that the parent had no
+@@ -1475,6 +1473,12 @@ static int lookup_fast(struct nameidata
+                               goto unlazy;
+                       }
+               }
++              /*
++               * Note: do negative dentry check after revalidation in
++               * case that drops it.
++               */
++              if (negative)
++                      return -ENOENT;
+               path->mnt = mnt;
+               path->dentry = dentry;
+               if (likely(__follow_mount_rcu(nd, path, inode)))
diff --git a/queue-4.1/net-xen-netfront-only-napi_synchronize-if-running.patch b/queue-4.1/net-xen-netfront-only-napi_synchronize-if-running.patch
new file mode 100644 (file)
index 0000000..2cdf254
--- /dev/null
@@ -0,0 +1,54 @@
+From 274b045509175db0405c784be85e8cce116e6f7d Mon Sep 17 00:00:00 2001
+From: Chas Williams <3chas3@gmail.com>
+Date: Thu, 27 Aug 2015 12:28:46 -0400
+Subject: net/xen-netfront: only napi_synchronize() if running
+
+From: Chas Williams <3chas3@gmail.com>
+
+commit 274b045509175db0405c784be85e8cce116e6f7d upstream.
+
+If an interface isn't running napi_synchronize() will hang forever.
+
+[  392.248403] rmmod           R  running task        0   359    343 0x00000000
+[  392.257671]  ffff88003760fc88 ffff880037193b40 ffff880037193160 ffff88003760fc88
+[  392.267644]  ffff880037610000 ffff88003760fcd8 0000000100014c22 ffffffff81f75c40
+[  392.277524]  0000000000bc7010 ffff88003760fca8 ffffffff81796927 ffffffff81f75c40
+[  392.287323] Call Trace:
+[  392.291599]  [<ffffffff81796927>] schedule+0x37/0x90
+[  392.298553]  [<ffffffff8179985b>] schedule_timeout+0x14b/0x280
+[  392.306421]  [<ffffffff810f91b9>] ? irq_free_descs+0x69/0x80
+[  392.314006]  [<ffffffff811084d0>] ? internal_add_timer+0xb0/0xb0
+[  392.322125]  [<ffffffff81109d07>] msleep+0x37/0x50
+[  392.329037]  [<ffffffffa00ec79a>] xennet_disconnect_backend.isra.24+0xda/0x390 [xen_netfront]
+[  392.339658]  [<ffffffffa00ecadc>] xennet_remove+0x2c/0x80 [xen_netfront]
+[  392.348516]  [<ffffffff81481c69>] xenbus_dev_remove+0x59/0xc0
+[  392.356257]  [<ffffffff814e7217>] __device_release_driver+0x87/0x120
+[  392.364645]  [<ffffffff814e7cf8>] driver_detach+0xb8/0xc0
+[  392.371989]  [<ffffffff814e6e69>] bus_remove_driver+0x59/0xe0
+[  392.379883]  [<ffffffff814e84f0>] driver_unregister+0x30/0x70
+[  392.387495]  [<ffffffff814814b2>] xenbus_unregister_driver+0x12/0x20
+[  392.395908]  [<ffffffffa00ed89b>] netif_exit+0x10/0x775 [xen_netfront]
+[  392.404877]  [<ffffffff81124e08>] SyS_delete_module+0x1d8/0x230
+[  392.412804]  [<ffffffff8179a8ee>] system_call_fastpath+0x12/0x71
+
+Signed-off-by: Chas Williams <3chas3@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Cc: "Kamata, Munehisa" <kamatam@amazon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/xen-netfront.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/xen-netfront.c
++++ b/drivers/net/xen-netfront.c
+@@ -1353,7 +1353,8 @@ static void xennet_disconnect_backend(st
+               queue->tx_evtchn = queue->rx_evtchn = 0;
+               queue->tx_irq = queue->rx_irq = 0;
+-              napi_synchronize(&queue->napi);
++              if (netif_running(info->netdev))
++                      napi_synchronize(&queue->napi);
+               xennet_release_tx_bufs(queue);
+               xennet_release_rx_bufs(queue);
diff --git a/queue-4.1/netfilter-ipset-fixing-unnamed-union-init.patch b/queue-4.1/netfilter-ipset-fixing-unnamed-union-init.patch
deleted file mode 100644 (file)
index 68c720e..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-From 96be5f2806cd65a2ebced3bfcdf7df0116e6c4a6 Mon Sep 17 00:00:00 2001
-From: Elad Raz <eladr@mellanox.com>
-Date: Sat, 22 Aug 2015 08:44:11 +0300
-Subject: netfilter: ipset: Fixing unnamed union init
-
-From: Elad Raz <eladr@mellanox.com>
-
-commit 96be5f2806cd65a2ebced3bfcdf7df0116e6c4a6 upstream.
-
-In continue to proposed Vinson Lee's post [1], this patch fixes compilation
-issues founded at gcc 4.4.7. The initialization of .cidr field of unnamed
-unions causes compilation error in gcc 4.4.x.
-
-References
-
-Visible links
-[1] https://lkml.org/lkml/2015/7/5/74
-
-Signed-off-by: Elad Raz <eladr@mellanox.com>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-Cc: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
-diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c
-index 3c862c0a76d1..a93dfebffa81 100644
---- a/net/netfilter/ipset/ip_set_hash_netnet.c
-+++ b/net/netfilter/ipset/ip_set_hash_netnet.c
-@@ -131,6 +131,13 @@ hash_netnet4_data_next(struct hash_netnet4_elem *next,
- #define HOST_MASK     32
- #include "ip_set_hash_gen.h"
-+static void
-+hash_netnet4_init(struct hash_netnet4_elem *e)
-+{
-+      e->cidr[0] = HOST_MASK;
-+      e->cidr[1] = HOST_MASK;
-+}
-+
- static int
- hash_netnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
-                 const struct xt_action_param *par,
-@@ -160,7 +167,7 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
- {
-       const struct hash_netnet *h = set->data;
-       ipset_adtfn adtfn = set->variant->adt[adt];
--      struct hash_netnet4_elem e = { .cidr = { HOST_MASK, HOST_MASK, }, };
-+      struct hash_netnet4_elem e = { };
-       struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
-       u32 ip = 0, ip_to = 0, last;
-       u32 ip2 = 0, ip2_from = 0, ip2_to = 0, last2;
-@@ -169,6 +176,7 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
-       if (tb[IPSET_ATTR_LINENO])
-               *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
-+      hash_netnet4_init(&e);
-       if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
-                    !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
-               return -IPSET_ERR_PROTOCOL;
-@@ -357,6 +365,13 @@ hash_netnet6_data_next(struct hash_netnet4_elem *next,
- #define IP_SET_EMIT_CREATE
- #include "ip_set_hash_gen.h"
-+static void
-+hash_netnet6_init(struct hash_netnet6_elem *e)
-+{
-+      e->cidr[0] = HOST_MASK;
-+      e->cidr[1] = HOST_MASK;
-+}
-+
- static int
- hash_netnet6_kadt(struct ip_set *set, const struct sk_buff *skb,
-                 const struct xt_action_param *par,
-@@ -385,13 +400,14 @@ hash_netnet6_uadt(struct ip_set *set, struct nlattr *tb[],
-                 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
- {
-       ipset_adtfn adtfn = set->variant->adt[adt];
--      struct hash_netnet6_elem e = { .cidr = { HOST_MASK, HOST_MASK, }, };
-+      struct hash_netnet6_elem e = { };
-       struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
-       int ret;
-       if (tb[IPSET_ATTR_LINENO])
-               *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
-+      hash_netnet6_init(&e);
-       if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
-                    !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
-               return -IPSET_ERR_PROTOCOL;
-diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c
-index 0c68734f5cc4..9a14c237830f 100644
---- a/net/netfilter/ipset/ip_set_hash_netportnet.c
-+++ b/net/netfilter/ipset/ip_set_hash_netportnet.c
-@@ -142,6 +142,13 @@ hash_netportnet4_data_next(struct hash_netportnet4_elem *next,
- #define HOST_MASK     32
- #include "ip_set_hash_gen.h"
-+static void
-+hash_netportnet4_init(struct hash_netportnet4_elem *e)
-+{
-+      e->cidr[0] = HOST_MASK;
-+      e->cidr[1] = HOST_MASK;
-+}
-+
- static int
- hash_netportnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
-                     const struct xt_action_param *par,
-@@ -175,7 +182,7 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
- {
-       const struct hash_netportnet *h = set->data;
-       ipset_adtfn adtfn = set->variant->adt[adt];
--      struct hash_netportnet4_elem e = { .cidr = { HOST_MASK, HOST_MASK, }, };
-+      struct hash_netportnet4_elem e = { };
-       struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
-       u32 ip = 0, ip_to = 0, ip_last, p = 0, port, port_to;
-       u32 ip2_from = 0, ip2_to = 0, ip2_last, ip2;
-@@ -185,6 +192,7 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
-       if (tb[IPSET_ATTR_LINENO])
-               *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
-+      hash_netportnet4_init(&e);
-       if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
-                    !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
-                    !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
-@@ -412,6 +420,13 @@ hash_netportnet6_data_next(struct hash_netportnet4_elem *next,
- #define IP_SET_EMIT_CREATE
- #include "ip_set_hash_gen.h"
-+static void
-+hash_netportnet6_init(struct hash_netportnet6_elem *e)
-+{
-+      e->cidr[0] = HOST_MASK;
-+      e->cidr[1] = HOST_MASK;
-+}
-+
- static int
- hash_netportnet6_kadt(struct ip_set *set, const struct sk_buff *skb,
-                     const struct xt_action_param *par,
-@@ -445,7 +460,7 @@ hash_netportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
- {
-       const struct hash_netportnet *h = set->data;
-       ipset_adtfn adtfn = set->variant->adt[adt];
--      struct hash_netportnet6_elem e = { .cidr = { HOST_MASK, HOST_MASK, }, };
-+      struct hash_netportnet6_elem e = { };
-       struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
-       u32 port, port_to;
-       bool with_ports = false;
-@@ -454,6 +469,7 @@ hash_netportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
-       if (tb[IPSET_ATTR_LINENO])
-               *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
-+      hash_netportnet6_init(&e);
-       if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
-                    !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
-                    !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
diff --git a/queue-4.1/nfs-filelayout-fix-null-reference-caused-by-double-freeing-of-fh_array.patch b/queue-4.1/nfs-filelayout-fix-null-reference-caused-by-double-freeing-of-fh_array.patch
new file mode 100644 (file)
index 0000000..bcd7a83
--- /dev/null
@@ -0,0 +1,143 @@
+From 3ec0c97959abff33a42db9081c22132bcff5b4f2 Mon Sep 17 00:00:00 2001
+From: Kinglong Mee <kinglongmee@gmail.com>
+Date: Mon, 14 Sep 2015 20:12:21 +0800
+Subject: nfs/filelayout: Fix NULL reference caused by double freeing of fh_array
+
+From: Kinglong Mee <kinglongmee@gmail.com>
+
+commit 3ec0c97959abff33a42db9081c22132bcff5b4f2 upstream.
+
+If filelayout_decode_layout fail, _filelayout_free_lseg will causes
+a double freeing of fh_array.
+
+[ 1179.279800] BUG: unable to handle kernel NULL pointer dereference at           (null)
+[ 1179.280198] IP: [<ffffffffa027222d>] filelayout_free_fh_array.isra.11+0x1d/0x70 [nfs_layout_nfsv41_files]
+[ 1179.281010] PGD 0
+[ 1179.281443] Oops: 0000 [#1]
+[ 1179.281831] Modules linked in: nfs_layout_nfsv41_files(OE) nfsv4(OE) nfs(OE) fscache(E) xfs libcrc32c coretemp nfsd crct10dif_pclmul ppdev crc32_pclmul crc32c_intel auth_rpcgss ghash_clmulni_intel nfs_acl lockd vmw_balloon grace sunrpc parport_pc vmw_vmci parport shpchp i2c_piix4 vmwgfx drm_kms_helper ttm drm serio_raw mptspi scsi_transport_spi mptscsih e1000 mptbase ata_generic pata_acpi [last unloaded: fscache]
+[ 1179.283891] CPU: 0 PID: 13336 Comm: cat Tainted: G           OE   4.3.0-rc1-pnfs+ #244
+[ 1179.284323] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 05/20/2014
+[ 1179.285206] task: ffff8800501d48c0 ti: ffff88003e3c4000 task.ti: ffff88003e3c4000
+[ 1179.285668] RIP: 0010:[<ffffffffa027222d>]  [<ffffffffa027222d>] filelayout_free_fh_array.isra.11+0x1d/0x70 [nfs_layout_nfsv41_files]
+[ 1179.286612] RSP: 0018:ffff88003e3c77f8  EFLAGS: 00010202
+[ 1179.287092] RAX: 0000000000000000 RBX: ffff88001fe78900 RCX: 0000000000000000
+[ 1179.287731] RDX: ffffea0000f40760 RSI: ffff88001fe789c8 RDI: ffff88001fe789c0
+[ 1179.288383] RBP: ffff88003e3c7810 R08: ffffea0000f40760 R09: 0000000000000000
+[ 1179.289170] R10: 0000000000000000 R11: 0000000000000001 R12: ffff88001fe789c8
+[ 1179.289959] R13: ffff88001fe789c0 R14: ffff88004ec05a80 R15: ffff88004f935b88
+[ 1179.290791] FS:  00007f4e66bb5700(0000) GS:ffffffff81c29000(0000) knlGS:0000000000000000
+[ 1179.291580] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 1179.292209] CR2: 0000000000000000 CR3: 00000000203f8000 CR4: 00000000001406f0
+[ 1179.292731] Stack:
+[ 1179.293195]  ffff88001fe78900 00000000000000d0 ffff88001fe78178 ffff88003e3c7868
+[ 1179.293676]  ffffffffa0272737 0000000000000001 0000000000000001 ffff88001fe78800
+[ 1179.294151]  00000000614fffce ffffffff81727671 ffff88001fe78100 ffff88001fe78100
+[ 1179.294623] Call Trace:
+[ 1179.295092]  [<ffffffffa0272737>] filelayout_alloc_lseg+0xa7/0x2d0 [nfs_layout_nfsv41_files]
+[ 1179.295625]  [<ffffffff81727671>] ? out_of_line_wait_on_bit+0x81/0xb0
+[ 1179.296133]  [<ffffffffa040407e>] pnfs_layout_process+0xae/0x320 [nfsv4]
+[ 1179.296632]  [<ffffffffa03e0a01>] nfs4_proc_layoutget+0x2b1/0x360 [nfsv4]
+[ 1179.297134]  [<ffffffffa0402983>] pnfs_update_layout+0x853/0xb30 [nfsv4]
+[ 1179.297632]  [<ffffffffa039db24>] ? nfs_get_lock_context+0x74/0x170 [nfs]
+[ 1179.298158]  [<ffffffffa0271807>] filelayout_pg_init_read+0x37/0x50 [nfs_layout_nfsv41_files]
+[ 1179.298834]  [<ffffffffa03a72d9>] __nfs_pageio_add_request+0x119/0x460 [nfs]
+[ 1179.299385]  [<ffffffffa03a6bd7>] ? nfs_create_request.part.9+0x37/0x2e0 [nfs]
+[ 1179.299872]  [<ffffffffa03a7cc3>] nfs_pageio_add_request+0xa3/0x1b0 [nfs]
+[ 1179.300362]  [<ffffffffa03a8635>] readpage_async_filler+0x85/0x260 [nfs]
+[ 1179.300907]  [<ffffffff81180cb1>] read_cache_pages+0x91/0xd0
+[ 1179.301391]  [<ffffffffa03a85b0>] ? nfs_read_completion+0x220/0x220 [nfs]
+[ 1179.301867]  [<ffffffffa03a8dc8>] nfs_readpages+0x128/0x200 [nfs]
+[ 1179.302330]  [<ffffffff81180ef3>] __do_page_cache_readahead+0x203/0x280
+[ 1179.302784]  [<ffffffff81180dc8>] ? __do_page_cache_readahead+0xd8/0x280
+[ 1179.303413]  [<ffffffff81181116>] ondemand_readahead+0x1a6/0x2f0
+[ 1179.303855]  [<ffffffff81181371>] page_cache_sync_readahead+0x31/0x50
+[ 1179.304286]  [<ffffffff811750a6>] generic_file_read_iter+0x4a6/0x5c0
+[ 1179.304711]  [<ffffffffa03a0316>] ? __nfs_revalidate_mapping+0x1f6/0x240 [nfs]
+[ 1179.305132]  [<ffffffffa039ccf2>] nfs_file_read+0x52/0xa0 [nfs]
+[ 1179.305540]  [<ffffffff811e343c>] __vfs_read+0xcc/0x100
+[ 1179.305936]  [<ffffffff811e3d15>] vfs_read+0x85/0x130
+[ 1179.306326]  [<ffffffff811e4a98>] SyS_read+0x58/0xd0
+[ 1179.306708]  [<ffffffff8172caaf>] entry_SYSCALL_64_fastpath+0x12/0x76
+[ 1179.307094] Code: c4 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 55 48 89 e5 41 55 41 54 53 8b 07 49 89 f4 85 c0 74 47 48 8b 06 49 89 fd <48> 8b 38 48 85 ff 74 22 31 db eb 0c 48 63 d3 48 8b 3c d0 48 85
+[ 1179.308357] RIP  [<ffffffffa027222d>] filelayout_free_fh_array.isra.11+0x1d/0x70 [nfs_layout_nfsv41_files]
+[ 1179.309177]  RSP <ffff88003e3c77f8>
+[ 1179.309582] CR2: 0000000000000000
+
+Signed-off-by: Kinglong Mee <kinglongmee@gmail.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Cc: William Dauchy <william@gandi.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/nfs/filelayout/filelayout.c |   31 ++++++++++++-------------------
+ 1 file changed, 12 insertions(+), 19 deletions(-)
+
+--- a/fs/nfs/filelayout/filelayout.c
++++ b/fs/nfs/filelayout/filelayout.c
+@@ -628,23 +628,18 @@ out_put:
+       goto out;
+ }
+-static void filelayout_free_fh_array(struct nfs4_filelayout_segment *fl)
++static void _filelayout_free_lseg(struct nfs4_filelayout_segment *fl)
+ {
+       int i;
+-      for (i = 0; i < fl->num_fh; i++) {
+-              if (!fl->fh_array[i])
+-                      break;
+-              kfree(fl->fh_array[i]);
++      if (fl->fh_array) {
++              for (i = 0; i < fl->num_fh; i++) {
++                      if (!fl->fh_array[i])
++                              break;
++                      kfree(fl->fh_array[i]);
++              }
++              kfree(fl->fh_array);
+       }
+-      kfree(fl->fh_array);
+-      fl->fh_array = NULL;
+-}
+-
+-static void
+-_filelayout_free_lseg(struct nfs4_filelayout_segment *fl)
+-{
+-      filelayout_free_fh_array(fl);
+       kfree(fl);
+ }
+@@ -715,21 +710,21 @@ filelayout_decode_layout(struct pnfs_lay
+               /* Do we want to use a mempool here? */
+               fl->fh_array[i] = kmalloc(sizeof(struct nfs_fh), gfp_flags);
+               if (!fl->fh_array[i])
+-                      goto out_err_free;
++                      goto out_err;
+               p = xdr_inline_decode(&stream, 4);
+               if (unlikely(!p))
+-                      goto out_err_free;
++                      goto out_err;
+               fl->fh_array[i]->size = be32_to_cpup(p++);
+               if (sizeof(struct nfs_fh) < fl->fh_array[i]->size) {
+                       printk(KERN_ERR "NFS: Too big fh %d received %d\n",
+                              i, fl->fh_array[i]->size);
+-                      goto out_err_free;
++                      goto out_err;
+               }
+               p = xdr_inline_decode(&stream, fl->fh_array[i]->size);
+               if (unlikely(!p))
+-                      goto out_err_free;
++                      goto out_err;
+               memcpy(fl->fh_array[i]->data, p, fl->fh_array[i]->size);
+               dprintk("DEBUG: %s: fh len %d\n", __func__,
+                       fl->fh_array[i]->size);
+@@ -738,8 +733,6 @@ filelayout_decode_layout(struct pnfs_lay
+       __free_page(scratch);
+       return 0;
+-out_err_free:
+-      filelayout_free_fh_array(fl);
+ out_err:
+       __free_page(scratch);
+       return -EIO;
diff --git a/queue-4.1/overlay-call-ovl_drop_write-earlier-in-ovl_dentry_open.patch b/queue-4.1/overlay-call-ovl_drop_write-earlier-in-ovl_dentry_open.patch
new file mode 100644 (file)
index 0000000..773b6c8
--- /dev/null
@@ -0,0 +1,60 @@
+From f25801ee4680ef1db21e15c112e6e5fe3ffe8da5 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Thu, 18 Jun 2015 14:32:23 +0100
+Subject: overlay: Call ovl_drop_write() earlier in ovl_dentry_open()
+
+From: David Howells <dhowells@redhat.com>
+
+commit f25801ee4680ef1db21e15c112e6e5fe3ffe8da5 upstream.
+
+Call ovl_drop_write() earlier in ovl_dentry_open() before we call vfs_open()
+as we've done the copy up for which we needed the freeze-write lock by that
+point.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Cc: "Kamata, Munehisa" <kamatam@amazon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/overlayfs/inode.c |   14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -342,31 +342,25 @@ static int ovl_dentry_open(struct dentry
+       int err;
+       struct path realpath;
+       enum ovl_path_type type;
+-      bool want_write = false;
+       type = ovl_path_real(dentry, &realpath);
+       if (ovl_open_need_copy_up(file->f_flags, type, realpath.dentry)) {
+-              want_write = true;
+               err = ovl_want_write(dentry);
+               if (err)
+-                      goto out;
++                      return err;
+               if (file->f_flags & O_TRUNC)
+                       err = ovl_copy_up_last(dentry, NULL, true);
+               else
+                       err = ovl_copy_up(dentry);
++              ovl_drop_write(dentry);
+               if (err)
+-                      goto out_drop_write;
++                      return err;
+               ovl_path_upper(dentry, &realpath);
+       }
+-      err = vfs_open(&realpath, file, cred);
+-out_drop_write:
+-      if (want_write)
+-              ovl_drop_write(dentry);
+-out:
+-      return err;
++      return vfs_open(&realpath, file, cred);
+ }
+ static const struct inode_operations ovl_file_inode_operations = {
diff --git a/queue-4.1/overlayfs-make-f_path-always-point-to-the-overlay-and-f_inode-to-the-underlay.patch b/queue-4.1/overlayfs-make-f_path-always-point-to-the-overlay-and-f_inode-to-the-underlay.patch
new file mode 100644 (file)
index 0000000..d883afc
--- /dev/null
@@ -0,0 +1,290 @@
+From 4bacc9c9234c7c8eec44f5ed4e960d9f96fa0f01 Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Thu, 18 Jun 2015 14:32:31 +0100
+Subject: overlayfs: Make f_path always point to the overlay and f_inode to the underlay
+
+From: David Howells <dhowells@redhat.com>
+
+commit 4bacc9c9234c7c8eec44f5ed4e960d9f96fa0f01 upstream.
+
+Make file->f_path always point to the overlay dentry so that the path in
+/proc/pid/fd is correct and to ensure that label-based LSMs have access to the
+overlay as well as the underlay (path-based LSMs probably don't need it).
+
+Using my union testsuite to set things up, before the patch I see:
+
+       [root@andromeda union-testsuite]# bash 5</mnt/a/foo107
+       [root@andromeda union-testsuite]# ls -l /proc/$$/fd/
+       ...
+       lr-x------. 1 root root 64 Jun  5 14:38 5 -> /a/foo107
+       [root@andromeda union-testsuite]# stat /mnt/a/foo107
+       ...
+       Device: 23h/35d Inode: 13381       Links: 1
+       ...
+       [root@andromeda union-testsuite]# stat -L /proc/$$/fd/5
+       ...
+       Device: 23h/35d Inode: 13381       Links: 1
+       ...
+
+After the patch:
+
+       [root@andromeda union-testsuite]# bash 5</mnt/a/foo107
+       [root@andromeda union-testsuite]# ls -l /proc/$$/fd/
+       ...
+       lr-x------. 1 root root 64 Jun  5 14:22 5 -> /mnt/a/foo107
+       [root@andromeda union-testsuite]# stat /mnt/a/foo107
+       ...
+       Device: 23h/35d Inode: 40346       Links: 1
+       ...
+       [root@andromeda union-testsuite]# stat -L /proc/$$/fd/5
+       ...
+       Device: 23h/35d Inode: 40346       Links: 1
+       ...
+
+Note the change in where /proc/$$/fd/5 points to in the ls command.  It was
+pointing to /a/foo107 (which doesn't exist) and now points to /mnt/a/foo107
+(which is correct).
+
+The inode accessed, however, is the lower layer.  The union layer is on device
+25h/37d and the upper layer on 24h/36d.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Cc: "Kamata, Munehisa" <kamatam@amazon.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/dcache.c              |    5 +++-
+ fs/internal.h            |    1 
+ fs/open.c                |   49 ++++++++++++++++++++++++-----------------------
+ fs/overlayfs/inode.c     |   14 +++++--------
+ fs/overlayfs/overlayfs.h |    1 
+ fs/overlayfs/super.c     |    1 
+ include/linux/dcache.h   |    2 +
+ include/linux/fs.h       |    2 -
+ 8 files changed, 41 insertions(+), 34 deletions(-)
+
+--- a/fs/dcache.c
++++ b/fs/dcache.c
+@@ -1676,7 +1676,8 @@ void d_set_d_op(struct dentry *dentry, c
+                               DCACHE_OP_COMPARE       |
+                               DCACHE_OP_REVALIDATE    |
+                               DCACHE_OP_WEAK_REVALIDATE       |
+-                              DCACHE_OP_DELETE ));
++                              DCACHE_OP_DELETE        |
++                              DCACHE_OP_SELECT_INODE));
+       dentry->d_op = op;
+       if (!op)
+               return;
+@@ -1692,6 +1693,8 @@ void d_set_d_op(struct dentry *dentry, c
+               dentry->d_flags |= DCACHE_OP_DELETE;
+       if (op->d_prune)
+               dentry->d_flags |= DCACHE_OP_PRUNE;
++      if (op->d_select_inode)
++              dentry->d_flags |= DCACHE_OP_SELECT_INODE;
+ }
+ EXPORT_SYMBOL(d_set_d_op);
+--- a/fs/internal.h
++++ b/fs/internal.h
+@@ -107,6 +107,7 @@ extern struct file *do_file_open_root(st
+ extern long do_handle_open(int mountdirfd,
+                          struct file_handle __user *ufh, int open_flag);
+ extern int open_check_o_direct(struct file *f);
++extern int vfs_open(const struct path *, struct file *, const struct cred *);
+ /*
+  * inode.c
+--- a/fs/open.c
++++ b/fs/open.c
+@@ -678,18 +678,18 @@ int open_check_o_direct(struct file *f)
+ }
+ static int do_dentry_open(struct file *f,
++                        struct inode *inode,
+                         int (*open)(struct inode *, struct file *),
+                         const struct cred *cred)
+ {
+       static const struct file_operations empty_fops = {};
+-      struct inode *inode;
+       int error;
+       f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK |
+                               FMODE_PREAD | FMODE_PWRITE;
+       path_get(&f->f_path);
+-      inode = f->f_inode = f->f_path.dentry->d_inode;
++      f->f_inode = inode;
+       f->f_mapping = inode->i_mapping;
+       if (unlikely(f->f_flags & O_PATH)) {
+@@ -793,7 +793,8 @@ int finish_open(struct file *file, struc
+       BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */
+       file->f_path.dentry = dentry;
+-      error = do_dentry_open(file, open, current_cred());
++      error = do_dentry_open(file, d_backing_inode(dentry), open,
++                             current_cred());
+       if (!error)
+               *opened |= FILE_OPENED;
+@@ -822,6 +823,28 @@ int finish_no_open(struct file *file, st
+ }
+ EXPORT_SYMBOL(finish_no_open);
++/**
++ * vfs_open - open the file at the given path
++ * @path: path to open
++ * @file: newly allocated file with f_flag initialized
++ * @cred: credentials to use
++ */
++int vfs_open(const struct path *path, struct file *file,
++           const struct cred *cred)
++{
++      struct dentry *dentry = path->dentry;
++      struct inode *inode = dentry->d_inode;
++
++      file->f_path = *path;
++      if (dentry->d_flags & DCACHE_OP_SELECT_INODE) {
++              inode = dentry->d_op->d_select_inode(dentry, file->f_flags);
++              if (IS_ERR(inode))
++                      return PTR_ERR(inode);
++      }
++
++      return do_dentry_open(file, inode, NULL, cred);
++}
++
+ struct file *dentry_open(const struct path *path, int flags,
+                        const struct cred *cred)
+ {
+@@ -853,26 +876,6 @@ struct file *dentry_open(const struct pa
+ }
+ EXPORT_SYMBOL(dentry_open);
+-/**
+- * vfs_open - open the file at the given path
+- * @path: path to open
+- * @filp: newly allocated file with f_flag initialized
+- * @cred: credentials to use
+- */
+-int vfs_open(const struct path *path, struct file *filp,
+-           const struct cred *cred)
+-{
+-      struct inode *inode = path->dentry->d_inode;
+-
+-      if (inode->i_op->dentry_open)
+-              return inode->i_op->dentry_open(path->dentry, filp, cred);
+-      else {
+-              filp->f_path = *path;
+-              return do_dentry_open(filp, NULL, cred);
+-      }
+-}
+-EXPORT_SYMBOL(vfs_open);
+-
+ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *op)
+ {
+       int lookup_flags = 0;
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -336,31 +336,30 @@ static bool ovl_open_need_copy_up(int fl
+       return true;
+ }
+-static int ovl_dentry_open(struct dentry *dentry, struct file *file,
+-                  const struct cred *cred)
++struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags)
+ {
+       int err;
+       struct path realpath;
+       enum ovl_path_type type;
+       type = ovl_path_real(dentry, &realpath);
+-      if (ovl_open_need_copy_up(file->f_flags, type, realpath.dentry)) {
++      if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) {
+               err = ovl_want_write(dentry);
+               if (err)
+-                      return err;
++                      return ERR_PTR(err);
+-              if (file->f_flags & O_TRUNC)
++              if (file_flags & O_TRUNC)
+                       err = ovl_copy_up_last(dentry, NULL, true);
+               else
+                       err = ovl_copy_up(dentry);
+               ovl_drop_write(dentry);
+               if (err)
+-                      return err;
++                      return ERR_PTR(err);
+               ovl_path_upper(dentry, &realpath);
+       }
+-      return vfs_open(&realpath, file, cred);
++      return d_backing_inode(realpath.dentry);
+ }
+ static const struct inode_operations ovl_file_inode_operations = {
+@@ -371,7 +370,6 @@ static const struct inode_operations ovl
+       .getxattr       = ovl_getxattr,
+       .listxattr      = ovl_listxattr,
+       .removexattr    = ovl_removexattr,
+-      .dentry_open    = ovl_dentry_open,
+ };
+ static const struct inode_operations ovl_symlink_inode_operations = {
+--- a/fs/overlayfs/overlayfs.h
++++ b/fs/overlayfs/overlayfs.h
+@@ -173,6 +173,7 @@ ssize_t ovl_getxattr(struct dentry *dent
+                    void *value, size_t size);
+ ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size);
+ int ovl_removexattr(struct dentry *dentry, const char *name);
++struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags);
+ struct inode *ovl_new_inode(struct super_block *sb, umode_t mode,
+                           struct ovl_entry *oe);
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -275,6 +275,7 @@ static void ovl_dentry_release(struct de
+ static const struct dentry_operations ovl_dentry_operations = {
+       .d_release = ovl_dentry_release,
++      .d_select_inode = ovl_d_select_inode,
+ };
+ static struct ovl_entry *ovl_alloc_entry(unsigned int numlower)
+--- a/include/linux/dcache.h
++++ b/include/linux/dcache.h
+@@ -160,6 +160,7 @@ struct dentry_operations {
+       char *(*d_dname)(struct dentry *, char *, int);
+       struct vfsmount *(*d_automount)(struct path *);
+       int (*d_manage)(struct dentry *, bool);
++      struct inode *(*d_select_inode)(struct dentry *, unsigned);
+ } ____cacheline_aligned;
+ /*
+@@ -225,6 +226,7 @@ struct dentry_operations {
+ #define DCACHE_MAY_FREE                       0x00800000
+ #define DCACHE_FALLTHRU                       0x01000000 /* Fall through to lower layer */
++#define DCACHE_OP_SELECT_INODE                0x02000000 /* Unioned entry: dcache op selects inode */
+ extern seqlock_t rename_lock;
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1641,7 +1641,6 @@ struct inode_operations {
+       int (*set_acl)(struct inode *, struct posix_acl *, int);
+       /* WARNING: probably going away soon, do not use! */
+-      int (*dentry_open)(struct dentry *, struct file *, const struct cred *);
+ } ____cacheline_aligned;
+ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
+@@ -2193,7 +2192,6 @@ extern struct file *file_open_name(struc
+ extern struct file *filp_open(const char *, int, umode_t);
+ extern struct file *file_open_root(struct dentry *, struct vfsmount *,
+                                  const char *, int);
+-extern int vfs_open(const struct path *, struct file *, const struct cred *);
+ extern struct file * dentry_open(const struct path *, int, const struct cred *);
+ extern int filp_close(struct file *, fl_owner_t id);
diff --git a/queue-4.1/serial-8250-add-uart_config-entry-for-port_rt2880.patch b/queue-4.1/serial-8250-add-uart_config-entry-for-port_rt2880.patch
new file mode 100644 (file)
index 0000000..8e36742
--- /dev/null
@@ -0,0 +1,38 @@
+From 3c5a0357fdb3a9116a48dbdb0abb91fd23fbff80 Mon Sep 17 00:00:00 2001
+From: Mans Rullgard <mans@mansr.com>
+Date: Fri, 2 Oct 2015 17:50:31 +0100
+Subject: serial: 8250: add uart_config entry for PORT_RT2880
+
+From: Mans Rullgard <mans@mansr.com>
+
+commit 3c5a0357fdb3a9116a48dbdb0abb91fd23fbff80 upstream.
+
+This adds an entry to the uart_config table for PORT_RT2880
+enabling rx/tx FIFOs.  The UART is actually a Palmchip BK-3103
+which is found in several devices from Alchemy/RMI, Ralink, and
+Sigma Designs.
+
+Signed-off-by: Mans Rullgard <mans@mansr.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/8250/8250_core.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/tty/serial/8250/8250_core.c
++++ b/drivers/tty/serial/8250/8250_core.c
+@@ -339,6 +339,14 @@ configured less than Maximum supported f
+                                 UART_FCR7_64BYTE,
+               .flags          = UART_CAP_FIFO,
+       },
++      [PORT_RT2880] = {
++              .name           = "Palmchip BK-3103",
++              .fifo_size      = 16,
++              .tx_loadsz      = 16,
++              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
++              .rxtrig_bytes   = {1, 4, 8, 14},
++              .flags          = UART_CAP_FIFO,
++      },
+ };
+ /* Uart divisor latch read */
index 5eb7a1545f588344782f5d3f5f852d7a002e6795..caf13f3dcc6b368d3c587525c2174ce70c817527 100644 (file)
@@ -175,4 +175,23 @@ mmc-sdhci-fix-dma-memory-leak-in-sdhci_pre_req.patch
 mmc-core-don-t-return-an-error-for-cd-wp-gpios-when-gpiolib-is-unset.patch
 dcache-handle-escaped-paths-in-prepend_path.patch
 vfs-test-for-and-handle-paths-that-are-unreachable-from-their-mnt_root.patch
-netfilter-ipset-fixing-unnamed-union-init.patch
+arm64-efi-fix-boot-crash-by-not-padding-between-efi_memory_runtime-regions.patch
+arm64-ftrace-fix-function_graph-tracer-panic.patch
+arm64-readahead-fault-retry-breaks-mmap-file-read-random-detection.patch
+m68k-define-asmlinkage_protect.patch
+net-xen-netfront-only-napi_synchronize-if-running.patch
+igb-do-not-re-init-sr-iov-during-probe.patch
+genirq-fix-race-in-register_irq_proc.patch
+md-bitmap-don-t-pass-1-to-bitmap_storage_alloc.patch
+overlay-call-ovl_drop_write-earlier-in-ovl_dentry_open.patch
+overlayfs-make-f_path-always-point-to-the-overlay-and-f_inode-to-the-underlay.patch
+fix-a-braino-in-ovl_d_select_inode.patch
+nfs-filelayout-fix-null-reference-caused-by-double-freeing-of-fh_array.patch
+clk-ti-fix-dual-registration-of-uart4_ick.patch
+namei-results-of-d_is_negative-should-be-checked-after-dentry-revalidation.patch
+dm-fix-ab-ba-deadlock-in-__dm_destroy.patch
+dm-cache-fix-null-pointer-when-switching-from-cleaner-policy.patch
+staging-speakup-fix-speakup-r-regression.patch
+tty-fix-stall-caused-by-missing-memory-barrier-in-drivers-tty-n_tty.c.patch
+drivers-tty-require-read-access-for-controlling-terminal.patch
+serial-8250-add-uart_config-entry-for-port_rt2880.patch
diff --git a/queue-4.1/staging-speakup-fix-speakup-r-regression.patch b/queue-4.1/staging-speakup-fix-speakup-r-regression.patch
new file mode 100644 (file)
index 0000000..52590cb
--- /dev/null
@@ -0,0 +1,37 @@
+From b1d562acc78f0af46de0dfe447410bc40bdb7ece Mon Sep 17 00:00:00 2001
+From: "covici@ccs.covici.com" <covici@ccs.covici.com>
+Date: Wed, 20 May 2015 05:44:11 -0400
+Subject: staging: speakup: fix speakup-r regression
+
+From: "covici@ccs.covici.com" <covici@ccs.covici.com>
+
+commit b1d562acc78f0af46de0dfe447410bc40bdb7ece upstream.
+
+Here is a patch to make speakup-r work again.
+
+It broke in 3.6 due to commit 4369c64c79a22b98d3b7eff9d089196cd878a10a
+"Input: Send events one packet at a time)
+
+The problem was that the fakekey.c routine to fake a down arrow no
+longer functioned properly and putting the input_sync fixed it.
+
+Fixes: 4369c64c79a22b98d3b7eff9d089196cd878a10a
+Acked-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
+Signed-off-by: John Covici <covici@ccs.covici.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/speakup/fakekey.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/staging/speakup/fakekey.c
++++ b/drivers/staging/speakup/fakekey.c
+@@ -81,6 +81,7 @@ void speakup_fake_down_arrow(void)
+       __this_cpu_write(reporting_keystroke, true);
+       input_report_key(virt_keyboard, KEY_DOWN, PRESSED);
+       input_report_key(virt_keyboard, KEY_DOWN, RELEASED);
++      input_sync(virt_keyboard);
+       __this_cpu_write(reporting_keystroke, false);
+       /* reenable preemption */
diff --git a/queue-4.1/tty-fix-stall-caused-by-missing-memory-barrier-in-drivers-tty-n_tty.c.patch b/queue-4.1/tty-fix-stall-caused-by-missing-memory-barrier-in-drivers-tty-n_tty.c.patch
new file mode 100644 (file)
index 0000000..f31a527
--- /dev/null
@@ -0,0 +1,140 @@
+From e81107d4c6bd098878af9796b24edc8d4a9524fd Mon Sep 17 00:00:00 2001
+From: Kosuke Tatsukawa <tatsu@ab.jp.nec.com>
+Date: Fri, 2 Oct 2015 08:27:05 +0000
+Subject: tty: fix stall caused by missing memory barrier in drivers/tty/n_tty.c
+
+From: Kosuke Tatsukawa <tatsu@ab.jp.nec.com>
+
+commit e81107d4c6bd098878af9796b24edc8d4a9524fd upstream.
+
+My colleague ran into a program stall on a x86_64 server, where
+n_tty_read() was waiting for data even if there was data in the buffer
+in the pty.  kernel stack for the stuck process looks like below.
+ #0 [ffff88303d107b58] __schedule at ffffffff815c4b20
+ #1 [ffff88303d107bd0] schedule at ffffffff815c513e
+ #2 [ffff88303d107bf0] schedule_timeout at ffffffff815c7818
+ #3 [ffff88303d107ca0] wait_woken at ffffffff81096bd2
+ #4 [ffff88303d107ce0] n_tty_read at ffffffff8136fa23
+ #5 [ffff88303d107dd0] tty_read at ffffffff81368013
+ #6 [ffff88303d107e20] __vfs_read at ffffffff811a3704
+ #7 [ffff88303d107ec0] vfs_read at ffffffff811a3a57
+ #8 [ffff88303d107f00] sys_read at ffffffff811a4306
+ #9 [ffff88303d107f50] entry_SYSCALL_64_fastpath at ffffffff815c86d7
+
+There seems to be two problems causing this issue.
+
+First, in drivers/tty/n_tty.c, __receive_buf() stores the data and
+updates ldata->commit_head using smp_store_release() and then checks
+the wait queue using waitqueue_active().  However, since there is no
+memory barrier, __receive_buf() could return without calling
+wake_up_interactive_poll(), and at the same time, n_tty_read() could
+start to wait in wait_woken() as in the following chart.
+
+        __receive_buf()                         n_tty_read()
+------------------------------------------------------------------------
+if (waitqueue_active(&tty->read_wait))
+/* Memory operations issued after the
+   RELEASE may be completed before the
+   RELEASE operation has completed */
+                                        add_wait_queue(&tty->read_wait, &wait);
+                                        ...
+                                        if (!input_available_p(tty, 0)) {
+smp_store_release(&ldata->commit_head,
+                  ldata->read_head);
+                                        ...
+                                        timeout = wait_woken(&wait,
+                                          TASK_INTERRUPTIBLE, timeout);
+------------------------------------------------------------------------
+
+The second problem is that n_tty_read() also lacks a memory barrier
+call and could also cause __receive_buf() to return without calling
+wake_up_interactive_poll(), and n_tty_read() to wait in wait_woken()
+as in the chart below.
+
+        __receive_buf()                         n_tty_read()
+------------------------------------------------------------------------
+                                        spin_lock_irqsave(&q->lock, flags);
+                                        /* from add_wait_queue() */
+                                        ...
+                                        if (!input_available_p(tty, 0)) {
+                                        /* Memory operations issued after the
+                                           RELEASE may be completed before the
+                                           RELEASE operation has completed */
+smp_store_release(&ldata->commit_head,
+                  ldata->read_head);
+if (waitqueue_active(&tty->read_wait))
+                                        __add_wait_queue(q, wait);
+                                        spin_unlock_irqrestore(&q->lock,flags);
+                                        /* from add_wait_queue() */
+                                        ...
+                                        timeout = wait_woken(&wait,
+                                          TASK_INTERRUPTIBLE, timeout);
+------------------------------------------------------------------------
+
+There are also other places in drivers/tty/n_tty.c which have similar
+calls to waitqueue_active(), so instead of adding many memory barrier
+calls, this patch simply removes the call to waitqueue_active(),
+leaving just wake_up*() behind.
+
+This fixes both problems because, even though the memory access before
+or after the spinlocks in both wake_up*() and add_wait_queue() can
+sneak into the critical section, it cannot go past it and the critical
+section assures that they will be serialized (please see "INTER-CPU
+ACQUIRING BARRIER EFFECTS" in Documentation/memory-barriers.txt for a
+better explanation).  Moreover, the resulting code is much simpler.
+
+Latency measurement using a ping-pong test over a pty doesn't show any
+visible performance drop.
+
+Signed-off-by: Kosuke Tatsukawa <tatsu@ab.jp.nec.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/n_tty.c |   15 +++++----------
+ 1 file changed, 5 insertions(+), 10 deletions(-)
+
+--- a/drivers/tty/n_tty.c
++++ b/drivers/tty/n_tty.c
+@@ -343,8 +343,7 @@ static void n_tty_packet_mode_flush(stru
+               spin_lock_irqsave(&tty->ctrl_lock, flags);
+               tty->ctrl_status |= TIOCPKT_FLUSHREAD;
+               spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+-              if (waitqueue_active(&tty->link->read_wait))
+-                      wake_up_interruptible(&tty->link->read_wait);
++              wake_up_interruptible(&tty->link->read_wait);
+       }
+ }
+@@ -1383,8 +1382,7 @@ handle_newline:
+                       put_tty_queue(c, ldata);
+                       smp_store_release(&ldata->canon_head, ldata->read_head);
+                       kill_fasync(&tty->fasync, SIGIO, POLL_IN);
+-                      if (waitqueue_active(&tty->read_wait))
+-                              wake_up_interruptible_poll(&tty->read_wait, POLLIN);
++                      wake_up_interruptible_poll(&tty->read_wait, POLLIN);
+                       return 0;
+               }
+       }
+@@ -1670,8 +1668,7 @@ static void __receive_buf(struct tty_str
+       if ((read_cnt(ldata) >= ldata->minimum_to_wake) || L_EXTPROC(tty)) {
+               kill_fasync(&tty->fasync, SIGIO, POLL_IN);
+-              if (waitqueue_active(&tty->read_wait))
+-                      wake_up_interruptible_poll(&tty->read_wait, POLLIN);
++              wake_up_interruptible_poll(&tty->read_wait, POLLIN);
+       }
+ }
+@@ -1890,10 +1887,8 @@ static void n_tty_set_termios(struct tty
+       }
+       /* The termios change make the tty ready for I/O */
+-      if (waitqueue_active(&tty->write_wait))
+-              wake_up_interruptible(&tty->write_wait);
+-      if (waitqueue_active(&tty->read_wait))
+-              wake_up_interruptible(&tty->read_wait);
++      wake_up_interruptible(&tty->write_wait);
++      wake_up_interruptible(&tty->read_wait);
+ }
+ /**