From: Greg Kroah-Hartman Date: Sun, 16 Feb 2014 18:46:12 +0000 (-0800) Subject: 3.13-stable patches X-Git-Tag: v3.4.81~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=15505bde2866a7d271397e5f7e53df3740b596b7;p=thirdparty%2Fkernel%2Fstable-queue.git 3.13-stable patches added patches: arm64-add-dsb-after-icache-flush-in-__flush_icache_all.patch arm64-atomics-fix-use-of-acquire-release-for-full-barrier-semantics.patch arm64-invalidate-the-tlb-when-replacing-pmd-entries-during-boot.patch arm64-vdso-fix-coarse-clock-handling.patch arm64-vdso-prevent-ld-from-aligning-pt_load-segments-to-64k.patch arm64-vdso-update-wtm-fields-for-clock_monotonic_coarse.patch btrfs-disable-snapshot-aware-defrag-for-now.patch crypto-s390-fix-concurrency-issue-in-aes-ctr-mode.patch crypto-s390-fix-des-and-des3_ede-cbc-concurrency-issue.patch crypto-s390-fix-des-and-des3_ede-ctr-concurrency-issue.patch irqchip-armada-370-xp-fix-ipi-race-condition.patch irqchip-armada-370-xp-fix-msi-race-condition.patch nfsv4.1-nfs4_destroy_session-must-call-rpc_destroy_waitqueue.patch nfsv4-fix-memory-corruption-in-nfs4_proc_open_confirm.patch regulator-core-correct-default-return-value-for-full-constraints.patch --- diff --git a/queue-3.13/arm64-add-dsb-after-icache-flush-in-__flush_icache_all.patch b/queue-3.13/arm64-add-dsb-after-icache-flush-in-__flush_icache_all.patch new file mode 100644 index 00000000000..a3eea8e8fdb --- /dev/null +++ b/queue-3.13/arm64-add-dsb-after-icache-flush-in-__flush_icache_all.patch @@ -0,0 +1,33 @@ +From 5044bad43ee573d0b6d90e3ccb7a40c2c7d25eb4 Mon Sep 17 00:00:00 2001 +From: Vinayak Kale +Date: Wed, 5 Feb 2014 09:34:36 +0000 +Subject: arm64: add DSB after icache flush in __flush_icache_all() + +From: Vinayak Kale + +commit 5044bad43ee573d0b6d90e3ccb7a40c2c7d25eb4 upstream. + +Add DSB after icache flush to complete the cache maintenance operation. +The function __flush_icache_all() is used only for user space mappings +and an ISB is not required because of an exception return before executing +user instructions. An exception return would behave like an ISB. + +Signed-off-by: Vinayak Kale +Acked-by: Will Deacon +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/include/asm/cacheflush.h | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/arm64/include/asm/cacheflush.h ++++ b/arch/arm64/include/asm/cacheflush.h +@@ -116,6 +116,7 @@ extern void flush_dcache_page(struct pag + static inline void __flush_icache_all(void) + { + asm("ic ialluis"); ++ dsb(); + } + + #define flush_dcache_mmap_lock(mapping) \ diff --git a/queue-3.13/arm64-atomics-fix-use-of-acquire-release-for-full-barrier-semantics.patch b/queue-3.13/arm64-atomics-fix-use-of-acquire-release-for-full-barrier-semantics.patch new file mode 100644 index 00000000000..741d1a3fdcd --- /dev/null +++ b/queue-3.13/arm64-atomics-fix-use-of-acquire-release-for-full-barrier-semantics.patch @@ -0,0 +1,374 @@ +From 8e86f0b409a44193f1587e87b69c5dcf8f65be67 Mon Sep 17 00:00:00 2001 +From: Will Deacon +Date: Tue, 4 Feb 2014 12:29:12 +0000 +Subject: arm64: atomics: fix use of acquire + release for full barrier semantics + +From: Will Deacon + +commit 8e86f0b409a44193f1587e87b69c5dcf8f65be67 upstream. + +Linux requires a number of atomic operations to provide full barrier +semantics, that is no memory accesses after the operation can be +observed before any accesses up to and including the operation in +program order. + +On arm64, these operations have been incorrectly implemented as follows: + + // A, B, C are independent memory locations + + + + // atomic_op (B) +1: ldaxr x0, [B] // Exclusive load with acquire + + stlxr w1, x0, [B] // Exclusive store with release + cbnz w1, 1b + + + +The assumption here being that two half barriers are equivalent to a +full barrier, so the only permitted ordering would be A -> B -> C +(where B is the atomic operation involving both a load and a store). + +Unfortunately, this is not the case by the letter of the architecture +and, in fact, the accesses to A and C are permitted to pass their +nearest half barrier resulting in orderings such as Bl -> A -> C -> Bs +or Bl -> C -> A -> Bs (where Bl is the load-acquire on B and Bs is the +store-release on B). This is a clear violation of the full barrier +requirement. + +The simple way to fix this is to implement the same algorithm as ARMv7 +using explicit barriers: + + + + // atomic_op (B) + dmb ish // Full barrier +1: ldxr x0, [B] // Exclusive load + + stxr w1, x0, [B] // Exclusive store + cbnz w1, 1b + dmb ish // Full barrier + + + +but this has the undesirable effect of introducing *two* full barrier +instructions. A better approach is actually the following, non-intuitive +sequence: + + + + // atomic_op (B) +1: ldxr x0, [B] // Exclusive load + + stlxr w1, x0, [B] // Exclusive store with release + cbnz w1, 1b + dmb ish // Full barrier + + + +The simple observations here are: + + - The dmb ensures that no subsequent accesses (e.g. the access to C) + can enter or pass the atomic sequence. + + - The dmb also ensures that no prior accesses (e.g. the access to A) + can pass the atomic sequence. + + - Therefore, no prior access can pass a subsequent access, or + vice-versa (i.e. A is strictly ordered before C). + + - The stlxr ensures that no prior access can pass the store component + of the atomic operation. + +The only tricky part remaining is the ordering between the ldxr and the +access to A, since the absence of the first dmb means that we're now +permitting re-ordering between the ldxr and any prior accesses. + +From an (arbitrary) observer's point of view, there are two scenarios: + + 1. We have observed the ldxr. This means that if we perform a store to + [B], the ldxr will still return older data. If we can observe the + ldxr, then we can potentially observe the permitted re-ordering + with the access to A, which is clearly an issue when compared to + the dmb variant of the code. Thankfully, the exclusive monitor will + save us here since it will be cleared as a result of the store and + the ldxr will retry. Notice that any use of a later memory + observation to imply observation of the ldxr will also imply + observation of the access to A, since the stlxr/dmb ensure strict + ordering. + + 2. We have not observed the ldxr. This means we can perform a store + and influence the later ldxr. However, that doesn't actually tell + us anything about the access to [A], so we've not lost anything + here either when compared to the dmb variant. + +This patch implements this solution for our barriered atomic operations, +ensuring that we satisfy the full barrier requirements where they are +needed. + +Cc: Peter Zijlstra +Signed-off-by: Will Deacon +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/include/asm/atomic.h | 29 ++++++++++++++++++++--------- + arch/arm64/include/asm/cmpxchg.h | 9 +++++---- + arch/arm64/include/asm/futex.h | 6 ++++-- + arch/arm64/kernel/kuser32.S | 6 ++++-- + arch/arm64/lib/bitops.S | 3 ++- + 5 files changed, 35 insertions(+), 18 deletions(-) + +--- a/arch/arm64/include/asm/atomic.h ++++ b/arch/arm64/include/asm/atomic.h +@@ -64,7 +64,7 @@ static inline int atomic_add_return(int + int result; + + asm volatile("// atomic_add_return\n" +-"1: ldaxr %w0, %2\n" ++"1: ldxr %w0, %2\n" + " add %w0, %w0, %w3\n" + " stlxr %w1, %w0, %2\n" + " cbnz %w1, 1b" +@@ -72,6 +72,7 @@ static inline int atomic_add_return(int + : "Ir" (i) + : "cc", "memory"); + ++ smp_mb(); + return result; + } + +@@ -96,7 +97,7 @@ static inline int atomic_sub_return(int + int result; + + asm volatile("// atomic_sub_return\n" +-"1: ldaxr %w0, %2\n" ++"1: ldxr %w0, %2\n" + " sub %w0, %w0, %w3\n" + " stlxr %w1, %w0, %2\n" + " cbnz %w1, 1b" +@@ -104,6 +105,7 @@ static inline int atomic_sub_return(int + : "Ir" (i) + : "cc", "memory"); + ++ smp_mb(); + return result; + } + +@@ -112,17 +114,20 @@ static inline int atomic_cmpxchg(atomic_ + unsigned long tmp; + int oldval; + ++ smp_mb(); ++ + asm volatile("// atomic_cmpxchg\n" +-"1: ldaxr %w1, %2\n" ++"1: ldxr %w1, %2\n" + " cmp %w1, %w3\n" + " b.ne 2f\n" +-" stlxr %w0, %w4, %2\n" ++" stxr %w0, %w4, %2\n" + " cbnz %w0, 1b\n" + "2:" + : "=&r" (tmp), "=&r" (oldval), "+Q" (ptr->counter) + : "Ir" (old), "r" (new) + : "cc", "memory"); + ++ smp_mb(); + return oldval; + } + +@@ -183,7 +188,7 @@ static inline long atomic64_add_return(l + unsigned long tmp; + + asm volatile("// atomic64_add_return\n" +-"1: ldaxr %0, %2\n" ++"1: ldxr %0, %2\n" + " add %0, %0, %3\n" + " stlxr %w1, %0, %2\n" + " cbnz %w1, 1b" +@@ -191,6 +196,7 @@ static inline long atomic64_add_return(l + : "Ir" (i) + : "cc", "memory"); + ++ smp_mb(); + return result; + } + +@@ -215,7 +221,7 @@ static inline long atomic64_sub_return(l + unsigned long tmp; + + asm volatile("// atomic64_sub_return\n" +-"1: ldaxr %0, %2\n" ++"1: ldxr %0, %2\n" + " sub %0, %0, %3\n" + " stlxr %w1, %0, %2\n" + " cbnz %w1, 1b" +@@ -223,6 +229,7 @@ static inline long atomic64_sub_return(l + : "Ir" (i) + : "cc", "memory"); + ++ smp_mb(); + return result; + } + +@@ -231,17 +238,20 @@ static inline long atomic64_cmpxchg(atom + long oldval; + unsigned long res; + ++ smp_mb(); ++ + asm volatile("// atomic64_cmpxchg\n" +-"1: ldaxr %1, %2\n" ++"1: ldxr %1, %2\n" + " cmp %1, %3\n" + " b.ne 2f\n" +-" stlxr %w0, %4, %2\n" ++" stxr %w0, %4, %2\n" + " cbnz %w0, 1b\n" + "2:" + : "=&r" (res), "=&r" (oldval), "+Q" (ptr->counter) + : "Ir" (old), "r" (new) + : "cc", "memory"); + ++ smp_mb(); + return oldval; + } + +@@ -253,11 +263,12 @@ static inline long atomic64_dec_if_posit + unsigned long tmp; + + asm volatile("// atomic64_dec_if_positive\n" +-"1: ldaxr %0, %2\n" ++"1: ldxr %0, %2\n" + " subs %0, %0, #1\n" + " b.mi 2f\n" + " stlxr %w1, %0, %2\n" + " cbnz %w1, 1b\n" ++" dmb ish\n" + "2:" + : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) + : +--- a/arch/arm64/include/asm/cmpxchg.h ++++ b/arch/arm64/include/asm/cmpxchg.h +@@ -29,7 +29,7 @@ static inline unsigned long __xchg(unsig + switch (size) { + case 1: + asm volatile("// __xchg1\n" +- "1: ldaxrb %w0, %2\n" ++ "1: ldxrb %w0, %2\n" + " stlxrb %w1, %w3, %2\n" + " cbnz %w1, 1b\n" + : "=&r" (ret), "=&r" (tmp), "+Q" (*(u8 *)ptr) +@@ -38,7 +38,7 @@ static inline unsigned long __xchg(unsig + break; + case 2: + asm volatile("// __xchg2\n" +- "1: ldaxrh %w0, %2\n" ++ "1: ldxrh %w0, %2\n" + " stlxrh %w1, %w3, %2\n" + " cbnz %w1, 1b\n" + : "=&r" (ret), "=&r" (tmp), "+Q" (*(u16 *)ptr) +@@ -47,7 +47,7 @@ static inline unsigned long __xchg(unsig + break; + case 4: + asm volatile("// __xchg4\n" +- "1: ldaxr %w0, %2\n" ++ "1: ldxr %w0, %2\n" + " stlxr %w1, %w3, %2\n" + " cbnz %w1, 1b\n" + : "=&r" (ret), "=&r" (tmp), "+Q" (*(u32 *)ptr) +@@ -56,7 +56,7 @@ static inline unsigned long __xchg(unsig + break; + case 8: + asm volatile("// __xchg8\n" +- "1: ldaxr %0, %2\n" ++ "1: ldxr %0, %2\n" + " stlxr %w1, %3, %2\n" + " cbnz %w1, 1b\n" + : "=&r" (ret), "=&r" (tmp), "+Q" (*(u64 *)ptr) +@@ -67,6 +67,7 @@ static inline unsigned long __xchg(unsig + BUILD_BUG(); + } + ++ smp_mb(); + return ret; + } + +--- a/arch/arm64/include/asm/futex.h ++++ b/arch/arm64/include/asm/futex.h +@@ -24,10 +24,11 @@ + + #define __futex_atomic_op(insn, ret, oldval, uaddr, tmp, oparg) \ + asm volatile( \ +-"1: ldaxr %w1, %2\n" \ ++"1: ldxr %w1, %2\n" \ + insn "\n" \ + "2: stlxr %w3, %w0, %2\n" \ + " cbnz %w3, 1b\n" \ ++" dmb ish\n" \ + "3:\n" \ + " .pushsection .fixup,\"ax\"\n" \ + "4: mov %w0, %w5\n" \ +@@ -110,11 +111,12 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, + return -EFAULT; + + asm volatile("// futex_atomic_cmpxchg_inatomic\n" +-"1: ldaxr %w1, %2\n" ++"1: ldxr %w1, %2\n" + " sub %w3, %w1, %w4\n" + " cbnz %w3, 3f\n" + "2: stlxr %w3, %w5, %2\n" + " cbnz %w3, 1b\n" ++" dmb ish\n" + "3:\n" + " .pushsection .fixup,\"ax\"\n" + "4: mov %w0, %w6\n" +--- a/arch/arm64/kernel/kuser32.S ++++ b/arch/arm64/kernel/kuser32.S +@@ -38,12 +38,13 @@ __kuser_cmpxchg64: // 0xffff0f60 + .inst 0xe92d00f0 // push {r4, r5, r6, r7} + .inst 0xe1c040d0 // ldrd r4, r5, [r0] + .inst 0xe1c160d0 // ldrd r6, r7, [r1] +- .inst 0xe1b20e9f // 1: ldaexd r0, r1, [r2] ++ .inst 0xe1b20f9f // 1: ldrexd r0, r1, [r2] + .inst 0xe0303004 // eors r3, r0, r4 + .inst 0x00313005 // eoreqs r3, r1, r5 + .inst 0x01a23e96 // stlexdeq r3, r6, [r2] + .inst 0x03330001 // teqeq r3, #1 + .inst 0x0afffff9 // beq 1b ++ .inst 0xf57ff05b // dmb ish + .inst 0xe2730000 // rsbs r0, r3, #0 + .inst 0xe8bd00f0 // pop {r4, r5, r6, r7} + .inst 0xe12fff1e // bx lr +@@ -55,11 +56,12 @@ __kuser_memory_barrier: // 0xffff0fa0 + + .align 5 + __kuser_cmpxchg: // 0xffff0fc0 +- .inst 0xe1923e9f // 1: ldaex r3, [r2] ++ .inst 0xe1923f9f // 1: ldrex r3, [r2] + .inst 0xe0533000 // subs r3, r3, r0 + .inst 0x01823e91 // stlexeq r3, r1, [r2] + .inst 0x03330001 // teqeq r3, #1 + .inst 0x0afffffa // beq 1b ++ .inst 0xf57ff05b // dmb ish + .inst 0xe2730000 // rsbs r0, r3, #0 + .inst 0xe12fff1e // bx lr + +--- a/arch/arm64/lib/bitops.S ++++ b/arch/arm64/lib/bitops.S +@@ -46,11 +46,12 @@ ENTRY( \name ) + mov x2, #1 + add x1, x1, x0, lsr #3 // Get word offset + lsl x4, x2, x3 // Create mask +-1: ldaxr x2, [x1] ++1: ldxr x2, [x1] + lsr x0, x2, x3 // Save old value of bit + \instr x2, x2, x4 // toggle bit + stlxr w5, x2, [x1] + cbnz w5, 1b ++ dmb ish + and x0, x0, #1 + 3: ret + ENDPROC(\name ) diff --git a/queue-3.13/arm64-invalidate-the-tlb-when-replacing-pmd-entries-during-boot.patch b/queue-3.13/arm64-invalidate-the-tlb-when-replacing-pmd-entries-during-boot.patch new file mode 100644 index 00000000000..f0cf6080392 --- /dev/null +++ b/queue-3.13/arm64-invalidate-the-tlb-when-replacing-pmd-entries-during-boot.patch @@ -0,0 +1,49 @@ +From a55f9929a9b257f84b6cc7b2397379cabd744a22 Mon Sep 17 00:00:00 2001 +From: Catalin Marinas +Date: Tue, 4 Feb 2014 16:01:31 +0000 +Subject: arm64: Invalidate the TLB when replacing pmd entries during boot + +From: Catalin Marinas + +commit a55f9929a9b257f84b6cc7b2397379cabd744a22 upstream. + +With the 64K page size configuration, __create_page_tables in head.S +maps enough memory to get started but using 64K pages rather than 512M +sections with a single pgd/pud/pmd entry pointing to a pte table. +create_mapping() may override the pgd/pud/pmd table entry with a block +(section) one if the RAM size is more than 512MB and aligned correctly. +For the end of this block to be accessible, the old TLB entry must be +invalidated. + +Reported-by: Mark Salter +Tested-by: Mark Salter +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/mm/mmu.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/arch/arm64/mm/mmu.c ++++ b/arch/arm64/mm/mmu.c +@@ -203,10 +203,18 @@ static void __init alloc_init_pmd(pud_t + do { + next = pmd_addr_end(addr, end); + /* try section mapping first */ +- if (((addr | next | phys) & ~SECTION_MASK) == 0) ++ if (((addr | next | phys) & ~SECTION_MASK) == 0) { ++ pmd_t old_pmd =*pmd; + set_pmd(pmd, __pmd(phys | prot_sect_kernel)); +- else ++ /* ++ * Check for previous table entries created during ++ * boot (__create_page_tables) and flush them. ++ */ ++ if (!pmd_none(old_pmd)) ++ flush_tlb_all(); ++ } else { + alloc_init_pte(pmd, addr, next, __phys_to_pfn(phys)); ++ } + phys += next - addr; + } while (pmd++, addr = next, addr != end); + } diff --git a/queue-3.13/arm64-vdso-fix-coarse-clock-handling.patch b/queue-3.13/arm64-vdso-fix-coarse-clock-handling.patch new file mode 100644 index 00000000000..ce50a14162a --- /dev/null +++ b/queue-3.13/arm64-vdso-fix-coarse-clock-handling.patch @@ -0,0 +1,64 @@ +From 069b918623e1510e58dacf178905a72c3baa3ae4 Mon Sep 17 00:00:00 2001 +From: Nathan Lynch +Date: Wed, 5 Feb 2014 05:53:04 +0000 +Subject: arm64: vdso: fix coarse clock handling + +From: Nathan Lynch + +commit 069b918623e1510e58dacf178905a72c3baa3ae4 upstream. + +When __kernel_clock_gettime is called with a CLOCK_MONOTONIC_COARSE or +CLOCK_REALTIME_COARSE clock id, it returns incorrectly to whatever the +caller has placed in x2 ("ret x2" to return from the fast path). Fix +this by saving x30/LR to x2 only in code that will call +__do_get_tspec, restoring x30 afterward, and using a plain "ret" to +return from the routine. + +Also: while the resulting tv_nsec value for CLOCK_REALTIME and +CLOCK_MONOTONIC must be computed using intermediate values that are +left-shifted by cs_shift (x12, set by __do_get_tspec), the results for +coarse clocks should be calculated using unshifted values +(xtime_coarse_nsec is in units of actual nanoseconds). The current +code shifts intermediate values by x12 unconditionally, but x12 is +uninitialized when servicing a coarse clock. Fix this by setting x12 +to 0 once we know we are dealing with a coarse clock id. + +Signed-off-by: Nathan Lynch +Acked-by: Will Deacon +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/kernel/vdso/gettimeofday.S | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/arch/arm64/kernel/vdso/gettimeofday.S ++++ b/arch/arm64/kernel/vdso/gettimeofday.S +@@ -103,6 +103,8 @@ ENTRY(__kernel_clock_gettime) + bl __do_get_tspec + seqcnt_check w9, 1b + ++ mov x30, x2 ++ + cmp w0, #CLOCK_MONOTONIC + b.ne 6f + +@@ -118,6 +120,9 @@ ENTRY(__kernel_clock_gettime) + ccmp w0, #CLOCK_MONOTONIC_COARSE, #0x4, ne + b.ne 8f + ++ /* xtime_coarse_nsec is already right-shifted */ ++ mov x12, #0 ++ + /* Get coarse timespec. */ + adr vdso_data, _vdso_data + 3: seqcnt_acquire +@@ -156,7 +161,7 @@ ENTRY(__kernel_clock_gettime) + lsr x11, x11, x12 + stp x10, x11, [x1, #TSPEC_TV_SEC] + mov x0, xzr +- ret x2 ++ ret + 7: + mov x30, x2 + 8: /* Syscall fallback. */ diff --git a/queue-3.13/arm64-vdso-prevent-ld-from-aligning-pt_load-segments-to-64k.patch b/queue-3.13/arm64-vdso-prevent-ld-from-aligning-pt_load-segments-to-64k.patch new file mode 100644 index 00000000000..cd3988f4130 --- /dev/null +++ b/queue-3.13/arm64-vdso-prevent-ld-from-aligning-pt_load-segments-to-64k.patch @@ -0,0 +1,41 @@ +From 40507403485fcb56b83d6ddfc954e9b08305054c Mon Sep 17 00:00:00 2001 +From: Will Deacon +Date: Tue, 4 Feb 2014 14:41:26 +0000 +Subject: arm64: vdso: prevent ld from aligning PT_LOAD segments to 64k + +From: Will Deacon + +commit 40507403485fcb56b83d6ddfc954e9b08305054c upstream. + +Whilst the text segment for our VDSO is marked as PT_LOAD in the ELF +headers, it is mapped by the kernel and not actually subject to +demand-paging. ld doesn't realise this, and emits a p_align field of 64k +(the maximum supported page size), which conflicts with the load address +picked by the kernel on 4k systems, which will be 4k aligned. This +causes GDB to fail with "Failed to read a valid object file image from +memory" when attempting to load the VDSO. + +This patch passes the -n option to ld, which prevents it from aligning +PT_LOAD segments to the maximum page size. + +Reported-by: Kyle McMartin +Acked-by: Kyle McMartin +Signed-off-by: Will Deacon +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/kernel/vdso/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm64/kernel/vdso/Makefile ++++ b/arch/arm64/kernel/vdso/Makefile +@@ -48,7 +48,7 @@ $(obj-vdso): %.o: %.S + + # Actual build commands + quiet_cmd_vdsold = VDSOL $@ +- cmd_vdsold = $(CC) $(c_flags) -Wl,-T $^ -o $@ ++ cmd_vdsold = $(CC) $(c_flags) -Wl,-n -Wl,-T $^ -o $@ + quiet_cmd_vdsoas = VDSOA $@ + cmd_vdsoas = $(CC) $(a_flags) -c -o $@ $< + diff --git a/queue-3.13/arm64-vdso-update-wtm-fields-for-clock_monotonic_coarse.patch b/queue-3.13/arm64-vdso-update-wtm-fields-for-clock_monotonic_coarse.patch new file mode 100644 index 00000000000..6d9920b9d05 --- /dev/null +++ b/queue-3.13/arm64-vdso-update-wtm-fields-for-clock_monotonic_coarse.patch @@ -0,0 +1,42 @@ +From d4022a335271a48cce49df35d825897914fbffe3 Mon Sep 17 00:00:00 2001 +From: Nathan Lynch +Date: Mon, 3 Feb 2014 19:48:52 +0000 +Subject: arm64: vdso: update wtm fields for CLOCK_MONOTONIC_COARSE + +From: Nathan Lynch + +commit d4022a335271a48cce49df35d825897914fbffe3 upstream. + +Update wall-to-monotonic fields in the VDSO data page +unconditionally. These are used to service CLOCK_MONOTONIC_COARSE, +which is not guarded by use_syscall. + +Signed-off-by: Nathan Lynch +Acked-by: Will Deacon +Signed-off-by: Catalin Marinas +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/kernel/vdso.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm64/kernel/vdso.c ++++ b/arch/arm64/kernel/vdso.c +@@ -238,6 +238,8 @@ void update_vsyscall(struct timekeeper * + vdso_data->use_syscall = use_syscall; + vdso_data->xtime_coarse_sec = xtime_coarse.tv_sec; + vdso_data->xtime_coarse_nsec = xtime_coarse.tv_nsec; ++ vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec; ++ vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec; + + if (!use_syscall) { + vdso_data->cs_cycle_last = tk->clock->cycle_last; +@@ -245,8 +247,6 @@ void update_vsyscall(struct timekeeper * + vdso_data->xtime_clock_nsec = tk->xtime_nsec; + vdso_data->cs_mult = tk->mult; + vdso_data->cs_shift = tk->shift; +- vdso_data->wtm_clock_sec = tk->wall_to_monotonic.tv_sec; +- vdso_data->wtm_clock_nsec = tk->wall_to_monotonic.tv_nsec; + } + + smp_wmb(); diff --git a/queue-3.13/btrfs-disable-snapshot-aware-defrag-for-now.patch b/queue-3.13/btrfs-disable-snapshot-aware-defrag-for-now.patch new file mode 100644 index 00000000000..cb18fb3b80b --- /dev/null +++ b/queue-3.13/btrfs-disable-snapshot-aware-defrag-for-now.patch @@ -0,0 +1,31 @@ +From 8101c8dbf6243ba517aab58d69bf1bc37d8b7b9c Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Wed, 29 Jan 2014 16:05:30 -0500 +Subject: Btrfs: disable snapshot aware defrag for now + +From: Josef Bacik + +commit 8101c8dbf6243ba517aab58d69bf1bc37d8b7b9c upstream. + +It's just broken and it's taking a lot of effort to fix it, so for now just +disable it so people can defrag in peace. Thanks, + +Signed-off-by: Josef Bacik +Signed-off-by: Chris Mason +Signed-off-by: Greg Kroah-Hartman + +--- + fs/btrfs/inode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -2610,7 +2610,7 @@ static int btrfs_finish_ordered_io(struc + EXTENT_DEFRAG, 1, cached_state); + if (ret) { + u64 last_snapshot = btrfs_root_last_snapshot(&root->root_item); +- if (last_snapshot >= BTRFS_I(inode)->generation) ++ if (0 && last_snapshot >= BTRFS_I(inode)->generation) + /* the inode is shared */ + new = record_old_file_extents(inode, ordered_extent); + diff --git a/queue-3.13/crypto-s390-fix-concurrency-issue-in-aes-ctr-mode.patch b/queue-3.13/crypto-s390-fix-concurrency-issue-in-aes-ctr-mode.patch new file mode 100644 index 00000000000..77c7e92ebb2 --- /dev/null +++ b/queue-3.13/crypto-s390-fix-concurrency-issue-in-aes-ctr-mode.patch @@ -0,0 +1,145 @@ +From 0519e9ad89e5cd6e6b08398f57c6a71d9580564c Mon Sep 17 00:00:00 2001 +From: Harald Freudenberger +Date: Thu, 16 Jan 2014 16:01:11 +0100 +Subject: crypto: s390 - fix concurrency issue in aes-ctr mode + +From: Harald Freudenberger + +commit 0519e9ad89e5cd6e6b08398f57c6a71d9580564c upstream. + +The aes-ctr mode uses one preallocated page without any concurrency +protection. When multiple threads run aes-ctr encryption or decryption +this can lead to data corruption. + +The patch introduces locking for the page and a fallback solution with +slower en/decryption performance in concurrency situations. + +Signed-off-by: Harald Freudenberger +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/crypto/aes_s390.c | 65 +++++++++++++++++++++++++++++++------------- + 1 file changed, 46 insertions(+), 19 deletions(-) + +--- a/arch/s390/crypto/aes_s390.c ++++ b/arch/s390/crypto/aes_s390.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include "crypt_s390.h" + + #define AES_KEYLEN_128 1 +@@ -32,6 +33,7 @@ + #define AES_KEYLEN_256 4 + + static u8 *ctrblk; ++static DEFINE_SPINLOCK(ctrblk_lock); + static char keylen_flag; + + struct s390_aes_ctx { +@@ -758,43 +760,67 @@ static int ctr_aes_set_key(struct crypto + return aes_set_key(tfm, in_key, key_len); + } + ++static unsigned int __ctrblk_init(u8 *ctrptr, unsigned int nbytes) ++{ ++ unsigned int i, n; ++ ++ /* only use complete blocks, max. PAGE_SIZE */ ++ n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : nbytes & ~(AES_BLOCK_SIZE - 1); ++ for (i = AES_BLOCK_SIZE; i < n; i += AES_BLOCK_SIZE) { ++ memcpy(ctrptr + i, ctrptr + i - AES_BLOCK_SIZE, ++ AES_BLOCK_SIZE); ++ crypto_inc(ctrptr + i, AES_BLOCK_SIZE); ++ } ++ return n; ++} ++ + static int ctr_aes_crypt(struct blkcipher_desc *desc, long func, + struct s390_aes_ctx *sctx, struct blkcipher_walk *walk) + { + int ret = blkcipher_walk_virt_block(desc, walk, AES_BLOCK_SIZE); +- unsigned int i, n, nbytes; +- u8 buf[AES_BLOCK_SIZE]; +- u8 *out, *in; ++ unsigned int n, nbytes; ++ u8 buf[AES_BLOCK_SIZE], ctrbuf[AES_BLOCK_SIZE]; ++ u8 *out, *in, *ctrptr = ctrbuf; + + if (!walk->nbytes) + return ret; + +- memcpy(ctrblk, walk->iv, AES_BLOCK_SIZE); ++ if (spin_trylock(&ctrblk_lock)) ++ ctrptr = ctrblk; ++ ++ memcpy(ctrptr, walk->iv, AES_BLOCK_SIZE); + while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) { + out = walk->dst.virt.addr; + in = walk->src.virt.addr; + while (nbytes >= AES_BLOCK_SIZE) { +- /* only use complete blocks, max. PAGE_SIZE */ +- n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : +- nbytes & ~(AES_BLOCK_SIZE - 1); +- for (i = AES_BLOCK_SIZE; i < n; i += AES_BLOCK_SIZE) { +- memcpy(ctrblk + i, ctrblk + i - AES_BLOCK_SIZE, +- AES_BLOCK_SIZE); +- crypto_inc(ctrblk + i, AES_BLOCK_SIZE); +- } +- ret = crypt_s390_kmctr(func, sctx->key, out, in, n, ctrblk); +- if (ret < 0 || ret != n) ++ if (ctrptr == ctrblk) ++ n = __ctrblk_init(ctrptr, nbytes); ++ else ++ n = AES_BLOCK_SIZE; ++ ret = crypt_s390_kmctr(func, sctx->key, out, in, ++ n, ctrptr); ++ if (ret < 0 || ret != n) { ++ if (ctrptr == ctrblk) ++ spin_unlock(&ctrblk_lock); + return -EIO; ++ } + if (n > AES_BLOCK_SIZE) +- memcpy(ctrblk, ctrblk + n - AES_BLOCK_SIZE, ++ memcpy(ctrptr, ctrptr + n - AES_BLOCK_SIZE, + AES_BLOCK_SIZE); +- crypto_inc(ctrblk, AES_BLOCK_SIZE); ++ crypto_inc(ctrptr, AES_BLOCK_SIZE); + out += n; + in += n; + nbytes -= n; + } + ret = blkcipher_walk_done(desc, walk, nbytes); + } ++ if (ctrptr == ctrblk) { ++ if (nbytes) ++ memcpy(ctrbuf, ctrptr, AES_BLOCK_SIZE); ++ else ++ memcpy(walk->iv, ctrptr, AES_BLOCK_SIZE); ++ spin_unlock(&ctrblk_lock); ++ } + /* + * final block may be < AES_BLOCK_SIZE, copy only nbytes + */ +@@ -802,14 +828,15 @@ static int ctr_aes_crypt(struct blkciphe + out = walk->dst.virt.addr; + in = walk->src.virt.addr; + ret = crypt_s390_kmctr(func, sctx->key, buf, in, +- AES_BLOCK_SIZE, ctrblk); ++ AES_BLOCK_SIZE, ctrbuf); + if (ret < 0 || ret != AES_BLOCK_SIZE) + return -EIO; + memcpy(out, buf, nbytes); +- crypto_inc(ctrblk, AES_BLOCK_SIZE); ++ crypto_inc(ctrbuf, AES_BLOCK_SIZE); + ret = blkcipher_walk_done(desc, walk, 0); ++ memcpy(walk->iv, ctrbuf, AES_BLOCK_SIZE); + } +- memcpy(walk->iv, ctrblk, AES_BLOCK_SIZE); ++ + return ret; + } + diff --git a/queue-3.13/crypto-s390-fix-des-and-des3_ede-cbc-concurrency-issue.patch b/queue-3.13/crypto-s390-fix-des-and-des3_ede-cbc-concurrency-issue.patch new file mode 100644 index 00000000000..a1b87cde4d4 --- /dev/null +++ b/queue-3.13/crypto-s390-fix-des-and-des3_ede-cbc-concurrency-issue.patch @@ -0,0 +1,115 @@ +From adc3fcf1552b6e406d172fd9690bbd1395053d13 Mon Sep 17 00:00:00 2001 +From: Harald Freudenberger +Date: Wed, 22 Jan 2014 13:00:04 +0100 +Subject: crypto: s390 - fix des and des3_ede cbc concurrency issue + +From: Harald Freudenberger + +commit adc3fcf1552b6e406d172fd9690bbd1395053d13 upstream. + +In s390 des and des3_ede cbc mode the iv value is not protected +against concurrency access and modifications from another running +en/decrypt operation which is using the very same tfm struct +instance. This fix copies the iv to the local stack before +the crypto operation and stores the value back when done. + +Signed-off-by: Harald Freudenberger +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/crypto/des_s390.c | 26 ++++++++++++++------------ + 1 file changed, 14 insertions(+), 12 deletions(-) + +--- a/arch/s390/crypto/des_s390.c ++++ b/arch/s390/crypto/des_s390.c +@@ -105,29 +105,35 @@ static int ecb_desall_crypt(struct blkci + } + + static int cbc_desall_crypt(struct blkcipher_desc *desc, long func, +- u8 *iv, struct blkcipher_walk *walk) ++ struct blkcipher_walk *walk) + { ++ struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + int ret = blkcipher_walk_virt(desc, walk); + unsigned int nbytes = walk->nbytes; ++ struct { ++ u8 iv[DES_BLOCK_SIZE]; ++ u8 key[DES3_KEY_SIZE]; ++ } param; + + if (!nbytes) + goto out; + +- memcpy(iv, walk->iv, DES_BLOCK_SIZE); ++ memcpy(param.iv, walk->iv, DES_BLOCK_SIZE); ++ memcpy(param.key, ctx->key, DES3_KEY_SIZE); + do { + /* only use complete blocks */ + unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1); + u8 *out = walk->dst.virt.addr; + u8 *in = walk->src.virt.addr; + +- ret = crypt_s390_kmc(func, iv, out, in, n); ++ ret = crypt_s390_kmc(func, ¶m, out, in, n); + if (ret < 0 || ret != n) + return -EIO; + + nbytes &= DES_BLOCK_SIZE - 1; + ret = blkcipher_walk_done(desc, walk, nbytes); + } while ((nbytes = walk->nbytes)); +- memcpy(walk->iv, iv, DES_BLOCK_SIZE); ++ memcpy(walk->iv, param.iv, DES_BLOCK_SIZE); + + out: + return ret; +@@ -179,22 +185,20 @@ static int cbc_des_encrypt(struct blkcip + struct scatterlist *dst, struct scatterlist *src, + unsigned int nbytes) + { +- struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + struct blkcipher_walk walk; + + blkcipher_walk_init(&walk, dst, src, nbytes); +- return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, ctx->iv, &walk); ++ return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, &walk); + } + + static int cbc_des_decrypt(struct blkcipher_desc *desc, + struct scatterlist *dst, struct scatterlist *src, + unsigned int nbytes) + { +- struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + struct blkcipher_walk walk; + + blkcipher_walk_init(&walk, dst, src, nbytes); +- return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, ctx->iv, &walk); ++ return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, &walk); + } + + static struct crypto_alg cbc_des_alg = { +@@ -327,22 +331,20 @@ static int cbc_des3_encrypt(struct blkci + struct scatterlist *dst, struct scatterlist *src, + unsigned int nbytes) + { +- struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + struct blkcipher_walk walk; + + blkcipher_walk_init(&walk, dst, src, nbytes); +- return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, ctx->iv, &walk); ++ return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, &walk); + } + + static int cbc_des3_decrypt(struct blkcipher_desc *desc, + struct scatterlist *dst, struct scatterlist *src, + unsigned int nbytes) + { +- struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); + struct blkcipher_walk walk; + + blkcipher_walk_init(&walk, dst, src, nbytes); +- return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, ctx->iv, &walk); ++ return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, &walk); + } + + static struct crypto_alg cbc_des3_alg = { diff --git a/queue-3.13/crypto-s390-fix-des-and-des3_ede-ctr-concurrency-issue.patch b/queue-3.13/crypto-s390-fix-des-and-des3_ede-ctr-concurrency-issue.patch new file mode 100644 index 00000000000..6e951464993 --- /dev/null +++ b/queue-3.13/crypto-s390-fix-des-and-des3_ede-ctr-concurrency-issue.patch @@ -0,0 +1,137 @@ +From ee97dc7db4cbda33e4241c2d85b42d1835bc8a35 Mon Sep 17 00:00:00 2001 +From: Harald Freudenberger +Date: Wed, 22 Jan 2014 13:01:33 +0100 +Subject: crypto: s390 - fix des and des3_ede ctr concurrency issue + +From: Harald Freudenberger + +commit ee97dc7db4cbda33e4241c2d85b42d1835bc8a35 upstream. + +In s390 des and 3des ctr mode there is one preallocated page +used to speed up the en/decryption. This page is not protected +against concurrent usage and thus there is a potential of data +corruption with multiple threads. + +The fix introduces locking/unlocking the ctr page and a slower +fallback solution at concurrency situations. + +Signed-off-by: Harald Freudenberger +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + arch/s390/crypto/des_s390.c | 69 ++++++++++++++++++++++++++++++-------------- + 1 file changed, 48 insertions(+), 21 deletions(-) + +--- a/arch/s390/crypto/des_s390.c ++++ b/arch/s390/crypto/des_s390.c +@@ -25,6 +25,7 @@ + #define DES3_KEY_SIZE (3 * DES_KEY_SIZE) + + static u8 *ctrblk; ++static DEFINE_SPINLOCK(ctrblk_lock); + + struct s390_des_ctx { + u8 iv[DES_BLOCK_SIZE]; +@@ -368,54 +369,80 @@ static struct crypto_alg cbc_des3_alg = + } + }; + ++static unsigned int __ctrblk_init(u8 *ctrptr, unsigned int nbytes) ++{ ++ unsigned int i, n; ++ ++ /* align to block size, max. PAGE_SIZE */ ++ n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : nbytes & ~(DES_BLOCK_SIZE - 1); ++ for (i = DES_BLOCK_SIZE; i < n; i += DES_BLOCK_SIZE) { ++ memcpy(ctrptr + i, ctrptr + i - DES_BLOCK_SIZE, DES_BLOCK_SIZE); ++ crypto_inc(ctrptr + i, DES_BLOCK_SIZE); ++ } ++ return n; ++} ++ + static int ctr_desall_crypt(struct blkcipher_desc *desc, long func, +- struct s390_des_ctx *ctx, struct blkcipher_walk *walk) ++ struct s390_des_ctx *ctx, ++ struct blkcipher_walk *walk) + { + int ret = blkcipher_walk_virt_block(desc, walk, DES_BLOCK_SIZE); +- unsigned int i, n, nbytes; +- u8 buf[DES_BLOCK_SIZE]; +- u8 *out, *in; ++ unsigned int n, nbytes; ++ u8 buf[DES_BLOCK_SIZE], ctrbuf[DES_BLOCK_SIZE]; ++ u8 *out, *in, *ctrptr = ctrbuf; ++ ++ if (!walk->nbytes) ++ return ret; + +- memcpy(ctrblk, walk->iv, DES_BLOCK_SIZE); ++ if (spin_trylock(&ctrblk_lock)) ++ ctrptr = ctrblk; ++ ++ memcpy(ctrptr, walk->iv, DES_BLOCK_SIZE); + while ((nbytes = walk->nbytes) >= DES_BLOCK_SIZE) { + out = walk->dst.virt.addr; + in = walk->src.virt.addr; + while (nbytes >= DES_BLOCK_SIZE) { +- /* align to block size, max. PAGE_SIZE */ +- n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : +- nbytes & ~(DES_BLOCK_SIZE - 1); +- for (i = DES_BLOCK_SIZE; i < n; i += DES_BLOCK_SIZE) { +- memcpy(ctrblk + i, ctrblk + i - DES_BLOCK_SIZE, +- DES_BLOCK_SIZE); +- crypto_inc(ctrblk + i, DES_BLOCK_SIZE); +- } +- ret = crypt_s390_kmctr(func, ctx->key, out, in, n, ctrblk); +- if (ret < 0 || ret != n) ++ if (ctrptr == ctrblk) ++ n = __ctrblk_init(ctrptr, nbytes); ++ else ++ n = DES_BLOCK_SIZE; ++ ret = crypt_s390_kmctr(func, ctx->key, out, in, ++ n, ctrptr); ++ if (ret < 0 || ret != n) { ++ if (ctrptr == ctrblk) ++ spin_unlock(&ctrblk_lock); + return -EIO; ++ } + if (n > DES_BLOCK_SIZE) +- memcpy(ctrblk, ctrblk + n - DES_BLOCK_SIZE, ++ memcpy(ctrptr, ctrptr + n - DES_BLOCK_SIZE, + DES_BLOCK_SIZE); +- crypto_inc(ctrblk, DES_BLOCK_SIZE); ++ crypto_inc(ctrptr, DES_BLOCK_SIZE); + out += n; + in += n; + nbytes -= n; + } + ret = blkcipher_walk_done(desc, walk, nbytes); + } +- ++ if (ctrptr == ctrblk) { ++ if (nbytes) ++ memcpy(ctrbuf, ctrptr, DES_BLOCK_SIZE); ++ else ++ memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE); ++ spin_unlock(&ctrblk_lock); ++ } + /* final block may be < DES_BLOCK_SIZE, copy only nbytes */ + if (nbytes) { + out = walk->dst.virt.addr; + in = walk->src.virt.addr; + ret = crypt_s390_kmctr(func, ctx->key, buf, in, +- DES_BLOCK_SIZE, ctrblk); ++ DES_BLOCK_SIZE, ctrbuf); + if (ret < 0 || ret != DES_BLOCK_SIZE) + return -EIO; + memcpy(out, buf, nbytes); +- crypto_inc(ctrblk, DES_BLOCK_SIZE); ++ crypto_inc(ctrbuf, DES_BLOCK_SIZE); + ret = blkcipher_walk_done(desc, walk, 0); ++ memcpy(walk->iv, ctrbuf, DES_BLOCK_SIZE); + } +- memcpy(walk->iv, ctrblk, DES_BLOCK_SIZE); + return ret; + } + diff --git a/queue-3.13/irqchip-armada-370-xp-fix-ipi-race-condition.patch b/queue-3.13/irqchip-armada-370-xp-fix-ipi-race-condition.patch new file mode 100644 index 00000000000..0566897f07e --- /dev/null +++ b/queue-3.13/irqchip-armada-370-xp-fix-ipi-race-condition.patch @@ -0,0 +1,53 @@ +From a6f089e95b1e08cdea9633d50ad20aa5d44ba64d Mon Sep 17 00:00:00 2001 +From: Lior Amsalem +Date: Mon, 25 Nov 2013 17:26:44 +0100 +Subject: irqchip: armada-370-xp: fix IPI race condition + +From: Lior Amsalem + +commit a6f089e95b1e08cdea9633d50ad20aa5d44ba64d upstream. + +In the Armada 370/XP driver, when we receive an IRQ 0, we read the +list of doorbells that caused the interrupt from register +ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS. This gives the list of IPIs that +were generated. However, instead of acknowledging only the IPIs that +were generated, we acknowledge *all* the IPIs, by writing +~IPI_DOORBELL_MASK in the ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS register. + +This creates a race condition: if a new IPI that isn't part of the +ones read into the temporary "ipimask" variable is fired before we +acknowledge all IPIs, then we will simply loose it. This is causing +scheduling hangs on SMP intensive workloads. + +It is important to mention that this ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS +register has the following behavior: "A CPU write of 0 clears the bits +in this field. A CPU write of 1 has no effect". This is what allows us +to simply write ~ipimask to acknoledge the handled IPIs. + +Notice that the same problem is present in the MSI implementation, but +it will be fixed as a separate patch, so that this IPI fix can be +pushed to older stable versions as appropriate (all the way to 3.8), +while the MSI code only appeared in 3.13. + +Signed-off-by: Lior Amsalem +Signed-off-by: Thomas Petazzoni +Fixes: 344e873e5657e8dc0 'arm: mvebu: Add IPI support via doorbells' +Cc: Thomas Gleixner +Signed-off-by: Jason Cooper +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/irqchip/irq-armada-370-xp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/irqchip/irq-armada-370-xp.c ++++ b/drivers/irqchip/irq-armada-370-xp.c +@@ -407,7 +407,7 @@ armada_370_xp_handle_irq(struct pt_regs + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS) + & IPI_DOORBELL_MASK; + +- writel(~IPI_DOORBELL_MASK, per_cpu_int_base + ++ writel(~ipimask, per_cpu_int_base + + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); + + /* Handle all pending doorbells */ diff --git a/queue-3.13/irqchip-armada-370-xp-fix-msi-race-condition.patch b/queue-3.13/irqchip-armada-370-xp-fix-msi-race-condition.patch new file mode 100644 index 00000000000..b91f221e69a --- /dev/null +++ b/queue-3.13/irqchip-armada-370-xp-fix-msi-race-condition.patch @@ -0,0 +1,50 @@ +From c7f7bd4a136e4b02dd2a66bf95aec545bd93e8db Mon Sep 17 00:00:00 2001 +From: Lior Amsalem +Date: Mon, 25 Nov 2013 17:26:45 +0100 +Subject: irqchip: armada-370-xp: fix MSI race condition + +From: Lior Amsalem + +commit c7f7bd4a136e4b02dd2a66bf95aec545bd93e8db upstream. + +In the Armada 370/XP driver, when we receive an IRQ 1, we read the +list of doorbells that caused the interrupt from register +ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS. This gives the list of MSIs that +were generated. However, instead of acknowledging only the MSIs that +were generated, we acknowledge *all* the MSIs, by writing +~MSI_DOORBELL_MASK in the ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS register. + +This creates a race condition: if a new MSI that isn't part of the +ones read into the temporary "msimask" variable is fired before we +acknowledge all MSIs, then we will simply loose it. + +It is important to mention that this ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS +register has the following behavior: "A CPU write of 0 clears the bits +in this field. A CPU write of 1 has no effect". This is what allows us +to simply write ~msimask to acknoledge the handled MSIs. + +Notice that the same problem is present in the IPI implementation, but +it is fixed as a separate patch, so that this IPI fix can be pushed to +older stable versions as appropriate (all the way to 3.8), while the +MSI code only appeared in 3.13. + +Signed-off-by: Lior Amsalem +Signed-off-by: Thomas Petazzoni +Signed-off-by: Jason Cooper +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/irqchip/irq-armada-370-xp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/irqchip/irq-armada-370-xp.c ++++ b/drivers/irqchip/irq-armada-370-xp.c +@@ -381,7 +381,7 @@ armada_370_xp_handle_irq(struct pt_regs + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS) + & PCI_MSI_DOORBELL_MASK; + +- writel(~PCI_MSI_DOORBELL_MASK, per_cpu_int_base + ++ writel(~msimask, per_cpu_int_base + + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); + + for (msinr = PCI_MSI_DOORBELL_START; diff --git a/queue-3.13/nfsv4-fix-memory-corruption-in-nfs4_proc_open_confirm.patch b/queue-3.13/nfsv4-fix-memory-corruption-in-nfs4_proc_open_confirm.patch new file mode 100644 index 00000000000..2f32aa6b490 --- /dev/null +++ b/queue-3.13/nfsv4-fix-memory-corruption-in-nfs4_proc_open_confirm.patch @@ -0,0 +1,70 @@ +From 17ead6c85c3d0ef57a14d1373f1f1cee2ce60ea8 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Sat, 1 Feb 2014 14:53:23 -0500 +Subject: NFSv4: Fix memory corruption in nfs4_proc_open_confirm + +From: Trond Myklebust + +commit 17ead6c85c3d0ef57a14d1373f1f1cee2ce60ea8 upstream. + +nfs41_wake_and_assign_slot() relies on the task->tk_msg.rpc_argp and +task->tk_msg.rpc_resp always pointing to the session sequence arguments. + +nfs4_proc_open_confirm tries to pull a fast one by reusing the open +sequence structure, thus causing corruption of the NFSv4 slot table. + +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4proc.c | 8 ++++---- + include/linux/nfs_xdr.h | 2 ++ + 2 files changed, 6 insertions(+), 4 deletions(-) + +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1622,15 +1622,15 @@ static void nfs4_open_confirm_prepare(st + { + struct nfs4_opendata *data = calldata; + +- nfs40_setup_sequence(data->o_arg.server, &data->o_arg.seq_args, +- &data->o_res.seq_res, task); ++ nfs40_setup_sequence(data->o_arg.server, &data->c_arg.seq_args, ++ &data->c_res.seq_res, task); + } + + static void nfs4_open_confirm_done(struct rpc_task *task, void *calldata) + { + struct nfs4_opendata *data = calldata; + +- nfs40_sequence_done(task, &data->o_res.seq_res); ++ nfs40_sequence_done(task, &data->c_res.seq_res); + + data->rpc_status = task->tk_status; + if (data->rpc_status == 0) { +@@ -1688,7 +1688,7 @@ static int _nfs4_proc_open_confirm(struc + }; + int status; + +- nfs4_init_sequence(&data->o_arg.seq_args, &data->o_res.seq_res, 1); ++ nfs4_init_sequence(&data->c_arg.seq_args, &data->c_res.seq_res, 1); + kref_get(&data->kref); + data->rpc_done = 0; + data->rpc_status = 0; +--- a/include/linux/nfs_xdr.h ++++ b/include/linux/nfs_xdr.h +@@ -379,12 +379,14 @@ struct nfs_openres { + * Arguments to the open_confirm call. + */ + struct nfs_open_confirmargs { ++ struct nfs4_sequence_args seq_args; + const struct nfs_fh * fh; + nfs4_stateid * stateid; + struct nfs_seqid * seqid; + }; + + struct nfs_open_confirmres { ++ struct nfs4_sequence_res seq_res; + nfs4_stateid stateid; + struct nfs_seqid * seqid; + }; diff --git a/queue-3.13/nfsv4.1-nfs4_destroy_session-must-call-rpc_destroy_waitqueue.patch b/queue-3.13/nfsv4.1-nfs4_destroy_session-must-call-rpc_destroy_waitqueue.patch new file mode 100644 index 00000000000..28dd13aaca8 --- /dev/null +++ b/queue-3.13/nfsv4.1-nfs4_destroy_session-must-call-rpc_destroy_waitqueue.patch @@ -0,0 +1,103 @@ +From 20b9a9024540a775395d5d1f41eec0ec6ec41f9b Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Sat, 1 Feb 2014 13:47:06 -0500 +Subject: NFSv4.1: nfs4_destroy_session must call rpc_destroy_waitqueue + +From: Trond Myklebust + +commit 20b9a9024540a775395d5d1f41eec0ec6ec41f9b upstream. + +There may still be timers active on the session waitqueues. Make sure +that we kill them before freeing the memory. + +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4client.c | 2 +- + fs/nfs/nfs4session.c | 25 ++++++++++++++++++++----- + fs/nfs/nfs4session.h | 2 +- + 3 files changed, 22 insertions(+), 7 deletions(-) + +--- a/fs/nfs/nfs4client.c ++++ b/fs/nfs/nfs4client.c +@@ -169,7 +169,7 @@ void nfs41_shutdown_client(struct nfs_cl + void nfs40_shutdown_client(struct nfs_client *clp) + { + if (clp->cl_slot_tbl) { +- nfs4_release_slot_table(clp->cl_slot_tbl); ++ nfs4_shutdown_slot_table(clp->cl_slot_tbl); + kfree(clp->cl_slot_tbl); + } + } +--- a/fs/nfs/nfs4session.c ++++ b/fs/nfs/nfs4session.c +@@ -231,14 +231,23 @@ out: + return ret; + } + ++/* ++ * nfs4_release_slot_table - release all slot table entries ++ */ ++static void nfs4_release_slot_table(struct nfs4_slot_table *tbl) ++{ ++ nfs4_shrink_slot_table(tbl, 0); ++} ++ + /** +- * nfs4_release_slot_table - release resources attached to a slot table ++ * nfs4_shutdown_slot_table - release resources attached to a slot table + * @tbl: slot table to shut down + * + */ +-void nfs4_release_slot_table(struct nfs4_slot_table *tbl) ++void nfs4_shutdown_slot_table(struct nfs4_slot_table *tbl) + { +- nfs4_shrink_slot_table(tbl, 0); ++ nfs4_release_slot_table(tbl); ++ rpc_destroy_wait_queue(&tbl->slot_tbl_waitq); + } + + /** +@@ -422,7 +431,7 @@ void nfs41_update_target_slotid(struct n + spin_unlock(&tbl->slot_tbl_lock); + } + +-static void nfs4_destroy_session_slot_tables(struct nfs4_session *session) ++static void nfs4_release_session_slot_tables(struct nfs4_session *session) + { + nfs4_release_slot_table(&session->fc_slot_table); + nfs4_release_slot_table(&session->bc_slot_table); +@@ -450,7 +459,7 @@ int nfs4_setup_session_slot_tables(struc + if (status && tbl->slots == NULL) + /* Fore and back channel share a connection so get + * both slot tables or neither */ +- nfs4_destroy_session_slot_tables(ses); ++ nfs4_release_session_slot_tables(ses); + return status; + } + +@@ -470,6 +479,12 @@ struct nfs4_session *nfs4_alloc_session( + return session; + } + ++static void nfs4_destroy_session_slot_tables(struct nfs4_session *session) ++{ ++ nfs4_shutdown_slot_table(&session->fc_slot_table); ++ nfs4_shutdown_slot_table(&session->bc_slot_table); ++} ++ + void nfs4_destroy_session(struct nfs4_session *session) + { + struct rpc_xprt *xprt; +--- a/fs/nfs/nfs4session.h ++++ b/fs/nfs/nfs4session.h +@@ -74,7 +74,7 @@ enum nfs4_session_state { + + extern int nfs4_setup_slot_table(struct nfs4_slot_table *tbl, + unsigned int max_reqs, const char *queue); +-extern void nfs4_release_slot_table(struct nfs4_slot_table *tbl); ++extern void nfs4_shutdown_slot_table(struct nfs4_slot_table *tbl); + extern struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl); + extern void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot); + extern void nfs4_slot_tbl_drain_complete(struct nfs4_slot_table *tbl); diff --git a/queue-3.13/regulator-core-correct-default-return-value-for-full-constraints.patch b/queue-3.13/regulator-core-correct-default-return-value-for-full-constraints.patch new file mode 100644 index 00000000000..1f5d26dee43 --- /dev/null +++ b/queue-3.13/regulator-core-correct-default-return-value-for-full-constraints.patch @@ -0,0 +1,61 @@ +From 317b5684d52269b75b4ec6480f9dac056d0d4ba8 Mon Sep 17 00:00:00 2001 +From: Mark Brown +Date: Mon, 27 Jan 2014 17:34:07 +0000 +Subject: regulator: core: Correct default return value for full constraints + +From: Mark Brown + +commit 317b5684d52269b75b4ec6480f9dac056d0d4ba8 upstream. + +Once we have full constraints then all supply mappings should be known to +the regulator API. This means that we should treat failed lookups as fatal +rather than deferring in the hope of further registrations but this was +broken by commit 9b92da1f1205bd25 "regulator: core: Fix default return +value for _get()" which was targeted at DT systems but unintentionally +broke non-DT systems by changing the default return value. + +Fix this by explicitly returning -EPROBE_DEFER from the DT lookup if we +find a property but no corresponding regulator and by having the non-DT +case default to -ENODEV when we have full constraints. + +Fixes: 9b92da1f1205bd25 "regulator: core: Fix default return value for _get()" +Signed-off-by: Mark Brown +Tested-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/regulator/core.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1272,6 +1272,8 @@ static struct regulator_dev *regulator_d + if (r->dev.parent && + node == r->dev.of_node) + return r; ++ *ret = -EPROBE_DEFER; ++ return NULL; + } else { + /* + * If we couldn't even get the node then it's +@@ -1312,7 +1314,7 @@ static struct regulator *_regulator_get( + struct regulator_dev *rdev; + struct regulator *regulator = ERR_PTR(-EPROBE_DEFER); + const char *devname = NULL; +- int ret = -EPROBE_DEFER; ++ int ret; + + if (id == NULL) { + pr_err("get() with no identifier\n"); +@@ -1322,6 +1324,11 @@ static struct regulator *_regulator_get( + if (dev) + devname = dev_name(dev); + ++ if (have_full_constraints()) ++ ret = -ENODEV; ++ else ++ ret = -EPROBE_DEFER; ++ + mutex_lock(®ulator_list_mutex); + + rdev = regulator_dev_lookup(dev, id, &ret); diff --git a/queue-3.13/series b/queue-3.13/series index 28db5b4d597..a691bf3dd82 100644 --- a/queue-3.13/series +++ b/queue-3.13/series @@ -1 +1,16 @@ selinux-fix-kernel-bug-on-empty-security-contexts.patch +btrfs-disable-snapshot-aware-defrag-for-now.patch +crypto-s390-fix-concurrency-issue-in-aes-ctr-mode.patch +crypto-s390-fix-des-and-des3_ede-cbc-concurrency-issue.patch +crypto-s390-fix-des-and-des3_ede-ctr-concurrency-issue.patch +nfsv4.1-nfs4_destroy_session-must-call-rpc_destroy_waitqueue.patch +nfsv4-fix-memory-corruption-in-nfs4_proc_open_confirm.patch +regulator-core-correct-default-return-value-for-full-constraints.patch +irqchip-armada-370-xp-fix-ipi-race-condition.patch +irqchip-armada-370-xp-fix-msi-race-condition.patch +arm64-vdso-update-wtm-fields-for-clock_monotonic_coarse.patch +arm64-atomics-fix-use-of-acquire-release-for-full-barrier-semantics.patch +arm64-vdso-prevent-ld-from-aligning-pt_load-segments-to-64k.patch +arm64-invalidate-the-tlb-when-replacing-pmd-entries-during-boot.patch +arm64-vdso-fix-coarse-clock-handling.patch +arm64-add-dsb-after-icache-flush-in-__flush_icache_all.patch