--- /dev/null
+From 5044bad43ee573d0b6d90e3ccb7a40c2c7d25eb4 Mon Sep 17 00:00:00 2001
+From: Vinayak Kale <vkale@apm.com>
+Date: Wed, 5 Feb 2014 09:34:36 +0000
+Subject: arm64: add DSB after icache flush in __flush_icache_all()
+
+From: Vinayak Kale <vkale@apm.com>
+
+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 <vkale@apm.com>
+Acked-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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) \
--- /dev/null
+From 8e86f0b409a44193f1587e87b69c5dcf8f65be67 Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Tue, 4 Feb 2014 12:29:12 +0000
+Subject: arm64: atomics: fix use of acquire + release for full barrier semantics
+
+From: Will Deacon <will.deacon@arm.com>
+
+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
+
+ <Access [A]>
+
+ // atomic_op (B)
+1: ldaxr x0, [B] // Exclusive load with acquire
+ <op(B)>
+ stlxr w1, x0, [B] // Exclusive store with release
+ cbnz w1, 1b
+
+ <Access [C]>
+
+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:
+
+ <Access [A]>
+
+ // atomic_op (B)
+ dmb ish // Full barrier
+1: ldxr x0, [B] // Exclusive load
+ <op(B)>
+ stxr w1, x0, [B] // Exclusive store
+ cbnz w1, 1b
+ dmb ish // Full barrier
+
+ <Access [C]>
+
+but this has the undesirable effect of introducing *two* full barrier
+instructions. A better approach is actually the following, non-intuitive
+sequence:
+
+ <Access [A]>
+
+ // atomic_op (B)
+1: ldxr x0, [B] // Exclusive load
+ <op(B)>
+ stlxr w1, x0, [B] // Exclusive store with release
+ cbnz w1, 1b
+ dmb ish // Full barrier
+
+ <Access [C]>
+
+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 <peterz@infradead.org>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 )
--- /dev/null
+From a55f9929a9b257f84b6cc7b2397379cabd744a22 Mon Sep 17 00:00:00 2001
+From: Catalin Marinas <catalin.marinas@arm.com>
+Date: Tue, 4 Feb 2014 16:01:31 +0000
+Subject: arm64: Invalidate the TLB when replacing pmd entries during boot
+
+From: Catalin Marinas <catalin.marinas@arm.com>
+
+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 <msalter@redhat.com>
+Tested-by: Mark Salter <msalter@redhat.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
+ }
--- /dev/null
+From 069b918623e1510e58dacf178905a72c3baa3ae4 Mon Sep 17 00:00:00 2001
+From: Nathan Lynch <nathan_lynch@mentor.com>
+Date: Wed, 5 Feb 2014 05:53:04 +0000
+Subject: arm64: vdso: fix coarse clock handling
+
+From: Nathan Lynch <nathan_lynch@mentor.com>
+
+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 <nathan_lynch@mentor.com>
+Acked-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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. */
--- /dev/null
+From 40507403485fcb56b83d6ddfc954e9b08305054c Mon Sep 17 00:00:00 2001
+From: Will Deacon <will.deacon@arm.com>
+Date: Tue, 4 Feb 2014 14:41:26 +0000
+Subject: arm64: vdso: prevent ld from aligning PT_LOAD segments to 64k
+
+From: Will Deacon <will.deacon@arm.com>
+
+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 <kyle@redhat.com>
+Acked-by: Kyle McMartin <kyle@redhat.com>
+Signed-off-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 $@ $<
+
--- /dev/null
+From d4022a335271a48cce49df35d825897914fbffe3 Mon Sep 17 00:00:00 2001
+From: Nathan Lynch <nathan_lynch@mentor.com>
+Date: Mon, 3 Feb 2014 19:48:52 +0000
+Subject: arm64: vdso: update wtm fields for CLOCK_MONOTONIC_COARSE
+
+From: Nathan Lynch <nathan_lynch@mentor.com>
+
+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 <nathan_lynch@mentor.com>
+Acked-by: Will Deacon <will.deacon@arm.com>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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();
--- /dev/null
+From 8101c8dbf6243ba517aab58d69bf1bc37d8b7b9c Mon Sep 17 00:00:00 2001
+From: Josef Bacik <jbacik@fb.com>
+Date: Wed, 29 Jan 2014 16:05:30 -0500
+Subject: Btrfs: disable snapshot aware defrag for now
+
+From: Josef Bacik <jbacik@fb.com>
+
+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 <jbacik@fb.com>
+Signed-off-by: Chris Mason <clm@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
+
--- /dev/null
+From 0519e9ad89e5cd6e6b08398f57c6a71d9580564c Mon Sep 17 00:00:00 2001
+From: Harald Freudenberger <freude@linux.vnet.ibm.com>
+Date: Thu, 16 Jan 2014 16:01:11 +0100
+Subject: crypto: s390 - fix concurrency issue in aes-ctr mode
+
+From: Harald Freudenberger <freude@linux.vnet.ibm.com>
+
+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 <freude@linux.vnet.ibm.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 <linux/err.h>
+ #include <linux/module.h>
+ #include <linux/init.h>
++#include <linux/spinlock.h>
+ #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;
+ }
+
--- /dev/null
+From adc3fcf1552b6e406d172fd9690bbd1395053d13 Mon Sep 17 00:00:00 2001
+From: Harald Freudenberger <freude@linux.vnet.ibm.com>
+Date: Wed, 22 Jan 2014 13:00:04 +0100
+Subject: crypto: s390 - fix des and des3_ede cbc concurrency issue
+
+From: Harald Freudenberger <freude@linux.vnet.ibm.com>
+
+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 <freude@linux.vnet.ibm.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 = {
--- /dev/null
+From ee97dc7db4cbda33e4241c2d85b42d1835bc8a35 Mon Sep 17 00:00:00 2001
+From: Harald Freudenberger <freude@linux.vnet.ibm.com>
+Date: Wed, 22 Jan 2014 13:01:33 +0100
+Subject: crypto: s390 - fix des and des3_ede ctr concurrency issue
+
+From: Harald Freudenberger <freude@linux.vnet.ibm.com>
+
+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 <freude@linux.vnet.ibm.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }
+
--- /dev/null
+From a6f089e95b1e08cdea9633d50ad20aa5d44ba64d Mon Sep 17 00:00:00 2001
+From: Lior Amsalem <alior@marvell.com>
+Date: Mon, 25 Nov 2013 17:26:44 +0100
+Subject: irqchip: armada-370-xp: fix IPI race condition
+
+From: Lior Amsalem <alior@marvell.com>
+
+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 <alior@marvell.com>
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Fixes: 344e873e5657e8dc0 'arm: mvebu: Add IPI support via doorbells'
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Jason Cooper <jason@lakedaemon.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 */
--- /dev/null
+From c7f7bd4a136e4b02dd2a66bf95aec545bd93e8db Mon Sep 17 00:00:00 2001
+From: Lior Amsalem <alior@marvell.com>
+Date: Mon, 25 Nov 2013 17:26:45 +0100
+Subject: irqchip: armada-370-xp: fix MSI race condition
+
+From: Lior Amsalem <alior@marvell.com>
+
+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 <alior@marvell.com>
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Signed-off-by: Jason Cooper <jason@lakedaemon.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
--- /dev/null
+From 17ead6c85c3d0ef57a14d1373f1f1cee2ce60ea8 Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Sat, 1 Feb 2014 14:53:23 -0500
+Subject: NFSv4: Fix memory corruption in nfs4_proc_open_confirm
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+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 <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ };
--- /dev/null
+From 20b9a9024540a775395d5d1f41eec0ec6ec41f9b Mon Sep 17 00:00:00 2001
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+Date: Sat, 1 Feb 2014 13:47:06 -0500
+Subject: NFSv4.1: nfs4_destroy_session must call rpc_destroy_waitqueue
+
+From: Trond Myklebust <trond.myklebust@primarydata.com>
+
+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 <trond.myklebust@primarydata.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From 317b5684d52269b75b4ec6480f9dac056d0d4ba8 Mon Sep 17 00:00:00 2001
+From: Mark Brown <broonie@linaro.org>
+Date: Mon, 27 Jan 2014 17:34:07 +0000
+Subject: regulator: core: Correct default return value for full constraints
+
+From: Mark Brown <broonie@linaro.org>
+
+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 <broonie@linaro.org>
+Tested-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
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