--- /dev/null
+From d41519a69b35b10af7fda867fb9100df24fdf403 Mon Sep 17 00:00:00 2001
+From: David Miller <davem@davemloft.net>
+Date: Fri, 2 Jun 2017 11:28:54 -0400
+Subject: crypto: Work around deallocated stack frame reference gcc bug on sparc.
+
+From: David Miller <davem@davemloft.net>
+
+commit d41519a69b35b10af7fda867fb9100df24fdf403 upstream.
+
+On sparc, if we have an alloca() like situation, as is the case with
+SHASH_DESC_ON_STACK(), we can end up referencing deallocated stack
+memory. The result can be that the value is clobbered if a trap
+or interrupt arrives at just the right instruction.
+
+It only occurs if the function ends returning a value from that
+alloca() area and that value can be placed into the return value
+register using a single instruction.
+
+For example, in lib/libcrc32c.c:crc32c() we end up with a return
+sequence like:
+
+ return %i7+8
+ lduw [%o5+16], %o0 ! MEM[(u32 *)__shash_desc.1_10 + 16B],
+
+%o5 holds the base of the on-stack area allocated for the shash
+descriptor. But the return released the stack frame and the
+register window.
+
+So if an intererupt arrives between 'return' and 'lduw', then
+the value read at %o5+16 can be corrupted.
+
+Add a data compiler barrier to work around this problem. This is
+exactly what the gcc fix will end up doing as well, and it absolutely
+should not change the code generated for other cpus (unless gcc
+on them has the same bug :-)
+
+With crucial insight from Eric Sandeen.
+
+Reported-by: Anatoly Pugachev <matorola@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ fs/btrfs/hash.c | 5 ++++-
+ fs/f2fs/f2fs.h | 5 ++++-
+ lib/libcrc32c.c | 6 ++++--
+ 3 files changed, 12 insertions(+), 4 deletions(-)
+
+--- a/fs/btrfs/hash.c
++++ b/fs/btrfs/hash.c
+@@ -38,6 +38,7 @@ u32 btrfs_crc32c(u32 crc, const void *ad
+ {
+ SHASH_DESC_ON_STACK(shash, tfm);
+ u32 *ctx = (u32 *)shash_desc_ctx(shash);
++ u32 retval;
+ int err;
+
+ shash->tfm = tfm;
+@@ -47,5 +48,7 @@ u32 btrfs_crc32c(u32 crc, const void *ad
+ err = crypto_shash_update(shash, address, length);
+ BUG_ON(err);
+
+- return *ctx;
++ retval = *ctx;
++ barrier_data(ctx);
++ return retval;
+ }
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -948,6 +948,7 @@ static inline u32 f2fs_crc32(struct f2fs
+ {
+ SHASH_DESC_ON_STACK(shash, sbi->s_chksum_driver);
+ u32 *ctx = (u32 *)shash_desc_ctx(shash);
++ u32 retval;
+ int err;
+
+ shash->tfm = sbi->s_chksum_driver;
+@@ -957,7 +958,9 @@ static inline u32 f2fs_crc32(struct f2fs
+ err = crypto_shash_update(shash, address, length);
+ BUG_ON(err);
+
+- return *ctx;
++ retval = *ctx;
++ barrier_data(ctx);
++ return retval;
+ }
+
+ static inline bool f2fs_crc_valid(struct f2fs_sb_info *sbi, __u32 blk_crc,
+--- a/lib/libcrc32c.c
++++ b/lib/libcrc32c.c
+@@ -43,7 +43,7 @@ static struct crypto_shash *tfm;
+ u32 crc32c(u32 crc, const void *address, unsigned int length)
+ {
+ SHASH_DESC_ON_STACK(shash, tfm);
+- u32 *ctx = (u32 *)shash_desc_ctx(shash);
++ u32 ret, *ctx = (u32 *)shash_desc_ctx(shash);
+ int err;
+
+ shash->tfm = tfm;
+@@ -53,7 +53,9 @@ u32 crc32c(u32 crc, const void *address,
+ err = crypto_shash_update(shash, address, length);
+ BUG_ON(err);
+
+- return *ctx;
++ ret = *ctx;
++ barrier_data(ctx);
++ return ret;
+ }
+
+ EXPORT_SYMBOL(crc32c);