From: Greg Kroah-Hartman Date: Sun, 18 Oct 2015 00:34:30 +0000 (-0700) Subject: 4.1-stable patches X-Git-Tag: v3.10.91~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fdaccb63bbfc5b60e64dc46bb2b43b18e44d8188;p=thirdparty%2Fkernel%2Fstable-queue.git 4.1-stable patches 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 --- 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 index 00000000000..c665bd337ad --- /dev/null +++ b/queue-4.1/arm64-efi-fix-boot-crash-by-not-padding-between-efi_memory_runtime-regions.patch @@ -0,0 +1,194 @@ +From 0ce3cc008ec04258b6a6314b09f1a6012810881a Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +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 + +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 +Tested-by: Mark Rutland [UEFI 2.4 only] +Signed-off-by: Ard Biesheuvel +Signed-off-by: Matt Fleming +Reviewed-by: Mark Salter +Reviewed-by: Mark Rutland +Cc: Catalin Marinas +Cc: Leif Lindholm +Cc: Linus Torvalds +Cc: Mike Galbraith +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: Will Deacon +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 ++#include + #include + + #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 index 00000000000..d993586f36c --- /dev/null +++ b/queue-4.1/arm64-ftrace-fix-function_graph-tracer-panic.patch @@ -0,0 +1,112 @@ +From ee556d00cf20012e889344a0adbbf809ab5015a3 Mon Sep 17 00:00:00 2001 +From: Li Bin +Date: Wed, 30 Sep 2015 10:49:55 +0800 +Subject: arm64: ftrace: fix function_graph tracer panic + +From: Li Bin + +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 : [] lr : [] 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] [] next_tgid+0x30/0x100 +[ 198.584359] [] ftrace_graph_caller+0x6c/0x70 +[ 198.585503] [] ftrace_graph_caller+0x6c/0x70 +[ 198.586574] [] ftrace_graph_caller+0x6c/0x70 +[ 198.587660] [] 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 +Acked-by: AKASHI Takahiro +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..32ec82de003 --- /dev/null +++ b/queue-4.1/arm64-readahead-fault-retry-breaks-mmap-file-read-random-detection.patch @@ -0,0 +1,48 @@ +From 569ba74a7ba69f46ce2950bf085b37fea2408385 Mon Sep 17 00:00:00 2001 +From: Mark Salyzyn +Date: Mon, 21 Sep 2015 21:39:50 +0100 +Subject: arm64: readahead: fault retry breaks mmap file read random detection + +From: Mark Salyzyn + +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 +Cc: Rik van Riel +Cc: Wu Fengguang +Signed-off-by: Mark Salyzyn +Signed-off-by: Riley Andrews +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..53eeb12417e --- /dev/null +++ b/queue-4.1/clk-ti-fix-dual-registration-of-uart4_ick.patch @@ -0,0 +1,51 @@ +From 19e79687de22f23bcfb5e79cce3daba20af228d1 Mon Sep 17 00:00:00 2001 +From: Ben Dooks +Date: Tue, 29 Sep 2015 15:01:08 +0100 +Subject: clk: ti: fix dual-registration of uart4_ick + +From: Ben Dooks + +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 +Signed-off-by: Tero Kristo +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..c3e7e872e1a --- /dev/null +++ b/queue-4.1/dm-cache-fix-null-pointer-when-switching-from-cleaner-policy.patch @@ -0,0 +1,37 @@ +From 2bffa1503c5c06192eb1459180fac4416575a966 Mon Sep 17 00:00:00 2001 +From: Joe Thornber +Date: Fri, 9 Oct 2015 14:03:38 +0100 +Subject: dm cache: fix NULL pointer when switching from cleaner policy + +From: Joe Thornber + +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 +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..5082f91a941 --- /dev/null +++ b/queue-4.1/dm-fix-ab-ba-deadlock-in-__dm_destroy.patch @@ -0,0 +1,63 @@ +From 2a708cff93f1845b9239bc7d6310aef54e716c6a Mon Sep 17 00:00:00 2001 +From: Junichi Nomura +Date: Thu, 1 Oct 2015 08:31:51 +0000 +Subject: dm: fix AB-BA deadlock in __dm_destroy() + +From: Junichi Nomura + +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 +Fixes: ab7c7bb6f4ab ("dm: hold suspend_lock while suspending device during device deletion") +Acked-by: Mikulas Patocka +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..b3eadb9beb2 --- /dev/null +++ b/queue-4.1/drivers-tty-require-read-access-for-controlling-terminal.patch @@ -0,0 +1,80 @@ +From 0c55627167870255158db1cde0d28366f91c8872 Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Sun, 4 Oct 2015 19:29:12 +0200 +Subject: drivers/tty: require read access for controlling terminal + +From: Jann Horn + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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(¤t->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 index 00000000000..7d6efd90bbf --- /dev/null +++ b/queue-4.1/fix-a-braino-in-ovl_d_select_inode.patch @@ -0,0 +1,34 @@ +From 9391dd00d13c853ab4f2a85435288ae2202e0e43 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Sun, 12 Jul 2015 10:39:45 -0400 +Subject: fix a braino in ovl_d_select_inode() + +From: Al Viro + +commit 9391dd00d13c853ab4f2a85435288ae2202e0e43 upstream. + +when opening a directory we want the overlayfs inode, not one from +the topmost layer. + +Reported-By: Andrey Jr. Melnikov +Tested-By: Andrey Jr. Melnikov +Signed-off-by: Al Viro +Cc: "Kamata, Munehisa" +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..b5b8362347c --- /dev/null +++ b/queue-4.1/genirq-fix-race-in-register_irq_proc.patch @@ -0,0 +1,76 @@ +From 95c2b17534654829db428f11bcf4297c059a2a7e Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Sat, 26 Sep 2015 12:23:56 +0100 +Subject: genirq: Fix race in register_irq_proc() + +From: Ben Hutchings + +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 +Link: http://lkml.kernel.org/r/1443266636.2004.2.camel@decadent.org.uk +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + #include + #include ++#include + + #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(®ister_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//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(®ister_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 index 00000000000..5cd7bed3229 --- /dev/null +++ b/queue-4.1/igb-do-not-re-init-sr-iov-during-probe.patch @@ -0,0 +1,47 @@ +From 6423fc34160939142d72ffeaa2db6408317f54df Mon Sep 17 00:00:00 2001 +From: Stefan Assmann +Date: Fri, 10 Jul 2015 15:01:12 +0200 +Subject: igb: do not re-init SR-IOV during probe + +From: Stefan Assmann + +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 +Tested-by: Aaron Brown +Signed-off-by: Jeff Kirsher +Cc: Daniel J Blueman +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..e284c30de41 --- /dev/null +++ b/queue-4.1/m68k-define-asmlinkage_protect.patch @@ -0,0 +1,70 @@ +From 8474ba74193d302e8340dddd1e16c85cc4b98caf Mon Sep 17 00:00:00 2001 +From: Andreas Schwab +Date: Wed, 23 Sep 2015 23:12:09 +0200 +Subject: m68k: Define asmlinkage_protect + +From: Andreas Schwab + +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 +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..738cca9f877 --- /dev/null +++ b/queue-4.1/md-bitmap-don-t-pass-1-to-bitmap_storage_alloc.patch @@ -0,0 +1,34 @@ +From da6fb7a9e5bd6f04f7e15070f630bdf1ea502841 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Thu, 1 Oct 2015 16:03:38 +1000 +Subject: md/bitmap: don't pass -1 to bitmap_storage_alloc. + +From: NeilBrown + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..a7c05f34ae8 --- /dev/null +++ b/queue-4.1/namei-results-of-d_is_negative-should-be-checked-after-dentry-revalidation.patch @@ -0,0 +1,74 @@ +From daf3761c9fcde0f4ca64321cbed6c1c86d304193 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +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 + +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 +Link: https://bugzilla.kernel.org/show_bug.cgi?id=104911 +Fixes: 766c4cbfacd8 ("namei: d_is_negative() should be checked...") +Tested-by: Leandro Awa +Signed-off-by: Trond Myklebust +Acked-by: Al Viro +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..2cdf2542e0e --- /dev/null +++ b/queue-4.1/net-xen-netfront-only-napi_synchronize-if-running.patch @@ -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] [] schedule+0x37/0x90 +[ 392.298553] [] schedule_timeout+0x14b/0x280 +[ 392.306421] [] ? irq_free_descs+0x69/0x80 +[ 392.314006] [] ? internal_add_timer+0xb0/0xb0 +[ 392.322125] [] msleep+0x37/0x50 +[ 392.329037] [] xennet_disconnect_backend.isra.24+0xda/0x390 [xen_netfront] +[ 392.339658] [] xennet_remove+0x2c/0x80 [xen_netfront] +[ 392.348516] [] xenbus_dev_remove+0x59/0xc0 +[ 392.356257] [] __device_release_driver+0x87/0x120 +[ 392.364645] [] driver_detach+0xb8/0xc0 +[ 392.371989] [] bus_remove_driver+0x59/0xe0 +[ 392.379883] [] driver_unregister+0x30/0x70 +[ 392.387495] [] xenbus_unregister_driver+0x12/0x20 +[ 392.395908] [] netif_exit+0x10/0x775 [xen_netfront] +[ 392.404877] [] SyS_delete_module+0x1d8/0x230 +[ 392.412804] [] system_call_fastpath+0x12/0x71 + +Signed-off-by: Chas Williams <3chas3@gmail.com> +Signed-off-by: David S. Miller +Cc: "Kamata, Munehisa" +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 68c720e2ef7..00000000000 --- a/queue-4.1/netfilter-ipset-fixing-unnamed-union-init.patch +++ /dev/null @@ -1,154 +0,0 @@ -From 96be5f2806cd65a2ebced3bfcdf7df0116e6c4a6 Mon Sep 17 00:00:00 2001 -From: Elad Raz -Date: Sat, 22 Aug 2015 08:44:11 +0300 -Subject: netfilter: ipset: Fixing unnamed union init - -From: Elad Raz - -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 -Signed-off-by: Pablo Neira Ayuso -Cc: Sudip Mukherjee -Signed-off-by: Greg Kroah-Hartman - -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 index 00000000000..bcd7a831fe7 --- /dev/null +++ b/queue-4.1/nfs-filelayout-fix-null-reference-caused-by-double-freeing-of-fh_array.patch @@ -0,0 +1,143 @@ +From 3ec0c97959abff33a42db9081c22132bcff5b4f2 Mon Sep 17 00:00:00 2001 +From: Kinglong Mee +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 + +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: [] 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:[] [] 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] [] filelayout_alloc_lseg+0xa7/0x2d0 [nfs_layout_nfsv41_files] +[ 1179.295625] [] ? out_of_line_wait_on_bit+0x81/0xb0 +[ 1179.296133] [] pnfs_layout_process+0xae/0x320 [nfsv4] +[ 1179.296632] [] nfs4_proc_layoutget+0x2b1/0x360 [nfsv4] +[ 1179.297134] [] pnfs_update_layout+0x853/0xb30 [nfsv4] +[ 1179.297632] [] ? nfs_get_lock_context+0x74/0x170 [nfs] +[ 1179.298158] [] filelayout_pg_init_read+0x37/0x50 [nfs_layout_nfsv41_files] +[ 1179.298834] [] __nfs_pageio_add_request+0x119/0x460 [nfs] +[ 1179.299385] [] ? nfs_create_request.part.9+0x37/0x2e0 [nfs] +[ 1179.299872] [] nfs_pageio_add_request+0xa3/0x1b0 [nfs] +[ 1179.300362] [] readpage_async_filler+0x85/0x260 [nfs] +[ 1179.300907] [] read_cache_pages+0x91/0xd0 +[ 1179.301391] [] ? nfs_read_completion+0x220/0x220 [nfs] +[ 1179.301867] [] nfs_readpages+0x128/0x200 [nfs] +[ 1179.302330] [] __do_page_cache_readahead+0x203/0x280 +[ 1179.302784] [] ? __do_page_cache_readahead+0xd8/0x280 +[ 1179.303413] [] ondemand_readahead+0x1a6/0x2f0 +[ 1179.303855] [] page_cache_sync_readahead+0x31/0x50 +[ 1179.304286] [] generic_file_read_iter+0x4a6/0x5c0 +[ 1179.304711] [] ? __nfs_revalidate_mapping+0x1f6/0x240 [nfs] +[ 1179.305132] [] nfs_file_read+0x52/0xa0 [nfs] +[ 1179.305540] [] __vfs_read+0xcc/0x100 +[ 1179.305936] [] vfs_read+0x85/0x130 +[ 1179.306326] [] SyS_read+0x58/0xd0 +[ 1179.306708] [] 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 [] filelayout_free_fh_array.isra.11+0x1d/0x70 [nfs_layout_nfsv41_files] +[ 1179.309177] RSP +[ 1179.309582] CR2: 0000000000000000 + +Signed-off-by: Kinglong Mee +Signed-off-by: Trond Myklebust +Cc: William Dauchy +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..773b6c861ad --- /dev/null +++ b/queue-4.1/overlay-call-ovl_drop_write-earlier-in-ovl_dentry_open.patch @@ -0,0 +1,60 @@ +From f25801ee4680ef1db21e15c112e6e5fe3ffe8da5 Mon Sep 17 00:00:00 2001 +From: David Howells +Date: Thu, 18 Jun 2015 14:32:23 +0100 +Subject: overlay: Call ovl_drop_write() earlier in ovl_dentry_open() + +From: David Howells + +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 +Signed-off-by: Al Viro +Cc: "Kamata, Munehisa" +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..d883afc65f6 --- /dev/null +++ b/queue-4.1/overlayfs-make-f_path-always-point-to-the-overlay-and-f_inode-to-the-underlay.patch @@ -0,0 +1,290 @@ +From 4bacc9c9234c7c8eec44f5ed4e960d9f96fa0f01 Mon Sep 17 00:00:00 2001 +From: David Howells +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 + +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 /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]# 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 +Signed-off-by: Al Viro +Cc: "Kamata, Munehisa" +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..8e36742b2db --- /dev/null +++ b/queue-4.1/serial-8250-add-uart_config-entry-for-port_rt2880.patch @@ -0,0 +1,38 @@ +From 3c5a0357fdb3a9116a48dbdb0abb91fd23fbff80 Mon Sep 17 00:00:00 2001 +From: Mans Rullgard +Date: Fri, 2 Oct 2015 17:50:31 +0100 +Subject: serial: 8250: add uart_config entry for PORT_RT2880 + +From: Mans Rullgard + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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 */ diff --git a/queue-4.1/series b/queue-4.1/series index 5eb7a1545f5..caf13f3dcc6 100644 --- a/queue-4.1/series +++ b/queue-4.1/series @@ -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 index 00000000000..52590cb859b --- /dev/null +++ b/queue-4.1/staging-speakup-fix-speakup-r-regression.patch @@ -0,0 +1,37 @@ +From b1d562acc78f0af46de0dfe447410bc40bdb7ece Mon Sep 17 00:00:00 2001 +From: "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" + +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 +Signed-off-by: John Covici +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..f31a52759e8 --- /dev/null +++ b/queue-4.1/tty-fix-stall-caused-by-missing-memory-barrier-in-drivers-tty-n_tty.c.patch @@ -0,0 +1,140 @@ +From e81107d4c6bd098878af9796b24edc8d4a9524fd Mon Sep 17 00:00:00 2001 +From: Kosuke Tatsukawa +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 + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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); + } + + /**