--- /dev/null
+From fe09786178f9df713a4b2dd6b93c0a722346bf5e Mon Sep 17 00:00:00 2001
+From: "Wang, Rui Y" <rui.y.wang@intel.com>
+Date: Wed, 27 Jan 2016 17:08:37 +0800
+Subject: crypto: algif_hash - wait for crypto_ahash_init() to complete
+
+From: Wang, Rui Y <rui.y.wang@intel.com>
+
+commit fe09786178f9df713a4b2dd6b93c0a722346bf5e upstream.
+
+hash_sendmsg/sendpage() need to wait for the completion
+of crypto_ahash_init() otherwise it can cause panic.
+
+Signed-off-by: Rui Wang <rui.y.wang@intel.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/algif_hash.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/crypto/algif_hash.c
++++ b/crypto/algif_hash.c
+@@ -54,7 +54,8 @@ static int hash_sendmsg(struct socket *s
+
+ lock_sock(sk);
+ if (!ctx->more) {
+- err = crypto_ahash_init(&ctx->req);
++ err = af_alg_wait_for_completion(crypto_ahash_init(&ctx->req),
++ &ctx->completion);
+ if (err)
+ goto unlock;
+ }
+@@ -125,6 +126,7 @@ static ssize_t hash_sendpage(struct sock
+ } else {
+ if (!ctx->more) {
+ err = crypto_ahash_init(&ctx->req);
++ err = af_alg_wait_for_completion(err, &ctx->completion);
+ if (err)
+ goto unlock;
+ }
--- /dev/null
+From ec69bbfb9902c32a5c1492f2b1b8ad032a66d724 Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Wed, 3 Feb 2016 21:39:24 +0800
+Subject: crypto: algif_skcipher - Do not assume that req is unchanged
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+commit ec69bbfb9902c32a5c1492f2b1b8ad032a66d724 upstream.
+
+The async path in algif_skcipher assumes that the crypto completion
+function will be called with the original request. This is not
+necessarily the case. In fact there is no need for this anyway
+since we already embed information into the request with struct
+skcipher_async_req.
+
+This patch adds a pointer to that struct and then passes it as
+the data to the callback function.
+
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Tested-by: Tadeusz Struk <tadeusz.struk@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/algif_skcipher.c | 60 ++++++++++++++++++++++--------------------------
+ 1 file changed, 28 insertions(+), 32 deletions(-)
+
+--- a/crypto/algif_skcipher.c
++++ b/crypto/algif_skcipher.c
+@@ -65,18 +65,10 @@ struct skcipher_async_req {
+ struct skcipher_async_rsgl first_sgl;
+ struct list_head list;
+ struct scatterlist *tsg;
+- char iv[];
++ atomic_t *inflight;
++ struct skcipher_request req;
+ };
+
+-#define GET_SREQ(areq, ctx) (struct skcipher_async_req *)((char *)areq + \
+- crypto_skcipher_reqsize(crypto_skcipher_reqtfm(&ctx->req)))
+-
+-#define GET_REQ_SIZE(ctx) \
+- crypto_skcipher_reqsize(crypto_skcipher_reqtfm(&ctx->req))
+-
+-#define GET_IV_SIZE(ctx) \
+- crypto_skcipher_ivsize(crypto_skcipher_reqtfm(&ctx->req))
+-
+ #define MAX_SGL_ENTS ((4096 - sizeof(struct skcipher_sg_list)) / \
+ sizeof(struct scatterlist) - 1)
+
+@@ -102,15 +94,12 @@ static void skcipher_free_async_sgls(str
+
+ static void skcipher_async_cb(struct crypto_async_request *req, int err)
+ {
+- struct sock *sk = req->data;
+- struct alg_sock *ask = alg_sk(sk);
+- struct skcipher_ctx *ctx = ask->private;
+- struct skcipher_async_req *sreq = GET_SREQ(req, ctx);
++ struct skcipher_async_req *sreq = req->data;
+ struct kiocb *iocb = sreq->iocb;
+
+- atomic_dec(&ctx->inflight);
++ atomic_dec(sreq->inflight);
+ skcipher_free_async_sgls(sreq);
+- kfree(req);
++ kzfree(sreq);
+ iocb->ki_complete(iocb, err, err);
+ }
+
+@@ -509,37 +498,42 @@ static int skcipher_recvmsg_async(struct
+ {
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
++ struct sock *psk = ask->parent;
++ struct alg_sock *pask = alg_sk(psk);
+ struct skcipher_ctx *ctx = ask->private;
++ struct skcipher_tfm *skc = pask->private;
++ struct crypto_skcipher *tfm = skc->skcipher;
+ struct skcipher_sg_list *sgl;
+ struct scatterlist *sg;
+ struct skcipher_async_req *sreq;
+ struct skcipher_request *req;
+ struct skcipher_async_rsgl *last_rsgl = NULL;
+ unsigned int txbufs = 0, len = 0, tx_nents = skcipher_all_sg_nents(ctx);
+- unsigned int reqlen = sizeof(struct skcipher_async_req) +
+- GET_REQ_SIZE(ctx) + GET_IV_SIZE(ctx);
++ unsigned int reqsize = crypto_skcipher_reqsize(tfm);
++ unsigned int ivsize = crypto_skcipher_ivsize(tfm);
+ int err = -ENOMEM;
+ bool mark = false;
++ char *iv;
+
+- lock_sock(sk);
+- req = kmalloc(reqlen, GFP_KERNEL);
+- if (unlikely(!req))
+- goto unlock;
++ sreq = kzalloc(sizeof(*sreq) + reqsize + ivsize, GFP_KERNEL);
++ if (unlikely(!sreq))
++ goto out;
+
+- sreq = GET_SREQ(req, ctx);
++ req = &sreq->req;
++ iv = (char *)(req + 1) + reqsize;
+ sreq->iocb = msg->msg_iocb;
+- memset(&sreq->first_sgl, '\0', sizeof(struct skcipher_async_rsgl));
+ INIT_LIST_HEAD(&sreq->list);
++ sreq->inflight = &ctx->inflight;
++
++ lock_sock(sk);
+ sreq->tsg = kcalloc(tx_nents, sizeof(*sg), GFP_KERNEL);
+- if (unlikely(!sreq->tsg)) {
+- kfree(req);
++ if (unlikely(!sreq->tsg))
+ goto unlock;
+- }
+ sg_init_table(sreq->tsg, tx_nents);
+- memcpy(sreq->iv, ctx->iv, GET_IV_SIZE(ctx));
+- skcipher_request_set_tfm(req, crypto_skcipher_reqtfm(&ctx->req));
++ memcpy(iv, ctx->iv, ivsize);
++ skcipher_request_set_tfm(req, tfm);
+ skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+- skcipher_async_cb, sk);
++ skcipher_async_cb, sreq);
+
+ while (iov_iter_count(&msg->msg_iter)) {
+ struct skcipher_async_rsgl *rsgl;
+@@ -615,20 +609,22 @@ static int skcipher_recvmsg_async(struct
+ sg_mark_end(sreq->tsg + txbufs - 1);
+
+ skcipher_request_set_crypt(req, sreq->tsg, sreq->first_sgl.sgl.sg,
+- len, sreq->iv);
++ len, iv);
+ err = ctx->enc ? crypto_skcipher_encrypt(req) :
+ crypto_skcipher_decrypt(req);
+ if (err == -EINPROGRESS) {
+ atomic_inc(&ctx->inflight);
+ err = -EIOCBQUEUED;
++ sreq = NULL;
+ goto unlock;
+ }
+ free:
+ skcipher_free_async_sgls(sreq);
+- kfree(req);
+ unlock:
+ skcipher_wmem_wakeup(sk);
+ release_sock(sk);
++ kzfree(sreq);
++out:
+ return err;
+ }
+
--- /dev/null
+From 6454c2b83f719057069777132b13949e4c6b6350 Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Wed, 3 Feb 2016 21:39:26 +0800
+Subject: crypto: algif_skcipher - Do not dereference ctx without socket lock
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+commit 6454c2b83f719057069777132b13949e4c6b6350 upstream.
+
+Any access to non-constant bits of the private context must be
+done under the socket lock, in particular, this includes ctx->req.
+
+This patch moves such accesses under the lock, and fetches the
+tfm from the parent socket which is guaranteed to be constant,
+rather than from ctx->req.
+
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/algif_skcipher.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/crypto/algif_skcipher.c
++++ b/crypto/algif_skcipher.c
+@@ -295,8 +295,11 @@ static int skcipher_sendmsg(struct socke
+ {
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
++ struct sock *psk = ask->parent;
++ struct alg_sock *pask = alg_sk(psk);
+ struct skcipher_ctx *ctx = ask->private;
+- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(&ctx->req);
++ struct skcipher_tfm *skc = pask->private;
++ struct crypto_skcipher *tfm = skc->skcipher;
+ unsigned ivsize = crypto_skcipher_ivsize(tfm);
+ struct skcipher_sg_list *sgl;
+ struct af_alg_control con = {};
+@@ -508,7 +511,7 @@ static int skcipher_recvmsg_async(struct
+ struct skcipher_async_req *sreq;
+ struct skcipher_request *req;
+ struct skcipher_async_rsgl *last_rsgl = NULL;
+- unsigned int txbufs = 0, len = 0, tx_nents = skcipher_all_sg_nents(ctx);
++ unsigned int txbufs = 0, len = 0, tx_nents;
+ unsigned int reqsize = crypto_skcipher_reqsize(tfm);
+ unsigned int ivsize = crypto_skcipher_ivsize(tfm);
+ int err = -ENOMEM;
+@@ -526,6 +529,7 @@ static int skcipher_recvmsg_async(struct
+ sreq->inflight = &ctx->inflight;
+
+ lock_sock(sk);
++ tx_nents = skcipher_all_sg_nents(ctx);
+ sreq->tsg = kcalloc(tx_nents, sizeof(*sg), GFP_KERNEL);
+ if (unlikely(!sreq->tsg))
+ goto unlock;
+@@ -633,9 +637,12 @@ static int skcipher_recvmsg_sync(struct
+ {
+ struct sock *sk = sock->sk;
+ struct alg_sock *ask = alg_sk(sk);
++ struct sock *psk = ask->parent;
++ struct alg_sock *pask = alg_sk(psk);
+ struct skcipher_ctx *ctx = ask->private;
+- unsigned bs = crypto_skcipher_blocksize(crypto_skcipher_reqtfm(
+- &ctx->req));
++ struct skcipher_tfm *skc = pask->private;
++ struct crypto_skcipher *tfm = skc->skcipher;
++ unsigned bs = crypto_skcipher_blocksize(tfm);
+ struct skcipher_sg_list *sgl;
+ struct scatterlist *sg;
+ int err = -EAGAIN;
--- /dev/null
+From dad41997063723eaf5f77bc2015606a5a9bce320 Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Wed, 3 Feb 2016 21:39:27 +0800
+Subject: crypto: algif_skcipher - Do not set MAY_BACKLOG on the async path
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+commit dad41997063723eaf5f77bc2015606a5a9bce320 upstream.
+
+The async path cannot use MAY_BACKLOG because it is not meant to
+block, which is what MAY_BACKLOG does. On the other hand, both
+the sync and async paths can make use of MAY_SLEEP.
+
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/algif_skcipher.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/crypto/algif_skcipher.c
++++ b/crypto/algif_skcipher.c
+@@ -536,7 +536,7 @@ static int skcipher_recvmsg_async(struct
+ sg_init_table(sreq->tsg, tx_nents);
+ memcpy(iv, ctx->iv, ivsize);
+ skcipher_request_set_tfm(req, tfm);
+- skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
++ skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP,
+ skcipher_async_cb, sreq);
+
+ while (iov_iter_count(&msg->msg_iter)) {
+@@ -950,7 +950,8 @@ static int skcipher_accept_parent_nokey(
+ ask->private = ctx;
+
+ skcipher_request_set_tfm(&ctx->req, skcipher);
+- skcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
++ skcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_SLEEP |
++ CRYPTO_TFM_REQ_MAY_BACKLOG,
+ af_alg_complete, &ctx->completion);
+
+ sk->sk_destruct = skcipher_sock_destruct;
--- /dev/null
+From d961436c11482e974b702c8324426208f00cd7c4 Mon Sep 17 00:00:00 2001
+From: Cyrille Pitchen <cyrille.pitchen@atmel.com>
+Date: Fri, 5 Feb 2016 13:45:12 +0100
+Subject: crypto: atmel-sha - fix atmel_sha_remove()
+
+From: Cyrille Pitchen <cyrille.pitchen@atmel.com>
+
+commit d961436c11482e974b702c8324426208f00cd7c4 upstream.
+
+Since atmel_sha_probe() uses devm_xxx functions to allocate resources,
+atmel_sha_remove() should no longer explicitly release them.
+
+Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
+Fixes: b0e8b3417a62 ("crypto: atmel - use devm_xxx() managed function")
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/crypto/atmel-sha.c | 7 -------
+ 1 file changed, 7 deletions(-)
+
+--- a/drivers/crypto/atmel-sha.c
++++ b/drivers/crypto/atmel-sha.c
+@@ -1484,13 +1484,6 @@ static int atmel_sha_remove(struct platf
+ if (sha_dd->caps.has_dma)
+ atmel_sha_dma_cleanup(sha_dd);
+
+- iounmap(sha_dd->io_base);
+-
+- clk_put(sha_dd->iclk);
+-
+- if (sha_dd->irq >= 0)
+- free_irq(sha_dd->irq, sha_dd);
+-
+ return 0;
+ }
+
--- /dev/null
+From c033042aa8f69894df37dabcaa0231594834a4e4 Mon Sep 17 00:00:00 2001
+From: Cyrille Pitchen <cyrille.pitchen@atmel.com>
+Date: Fri, 5 Feb 2016 13:45:13 +0100
+Subject: crypto: atmel-sha - remove calls of clk_prepare() from atomic contexts
+
+From: Cyrille Pitchen <cyrille.pitchen@atmel.com>
+
+commit c033042aa8f69894df37dabcaa0231594834a4e4 upstream.
+
+clk_prepare()/clk_unprepare() must not be called within atomic context.
+
+This patch calls clk_prepare() once for all from atmel_sha_probe() and
+clk_unprepare() from atmel_sha_remove().
+
+Then calls of clk_prepare_enable()/clk_disable_unprepare() were replaced
+by calls of clk_enable()/clk_disable().
+
+Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
+Reported-by: Matthias Mayr <matthias.mayr@student.kit.edu>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/crypto/atmel-sha.c | 18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+--- a/drivers/crypto/atmel-sha.c
++++ b/drivers/crypto/atmel-sha.c
+@@ -783,7 +783,7 @@ static void atmel_sha_finish_req(struct
+ dd->flags &= ~(SHA_FLAGS_BUSY | SHA_FLAGS_FINAL | SHA_FLAGS_CPU |
+ SHA_FLAGS_DMA_READY | SHA_FLAGS_OUTPUT_READY);
+
+- clk_disable_unprepare(dd->iclk);
++ clk_disable(dd->iclk);
+
+ if (req->base.complete)
+ req->base.complete(&req->base, err);
+@@ -796,7 +796,7 @@ static int atmel_sha_hw_init(struct atme
+ {
+ int err;
+
+- err = clk_prepare_enable(dd->iclk);
++ err = clk_enable(dd->iclk);
+ if (err)
+ return err;
+
+@@ -823,7 +823,7 @@ static void atmel_sha_hw_version_init(st
+ dev_info(dd->dev,
+ "version: 0x%x\n", dd->hw_version);
+
+- clk_disable_unprepare(dd->iclk);
++ clk_disable(dd->iclk);
+ }
+
+ static int atmel_sha_handle_queue(struct atmel_sha_dev *dd,
+@@ -1411,6 +1411,10 @@ static int atmel_sha_probe(struct platfo
+ goto res_err;
+ }
+
++ err = clk_prepare(sha_dd->iclk);
++ if (err)
++ goto res_err;
++
+ atmel_sha_hw_version_init(sha_dd);
+
+ atmel_sha_get_cap(sha_dd);
+@@ -1422,12 +1426,12 @@ static int atmel_sha_probe(struct platfo
+ if (IS_ERR(pdata)) {
+ dev_err(&pdev->dev, "platform data not available\n");
+ err = PTR_ERR(pdata);
+- goto res_err;
++ goto iclk_unprepare;
+ }
+ }
+ if (!pdata->dma_slave) {
+ err = -ENXIO;
+- goto res_err;
++ goto iclk_unprepare;
+ }
+ err = atmel_sha_dma_init(sha_dd, pdata);
+ if (err)
+@@ -1458,6 +1462,8 @@ err_algs:
+ if (sha_dd->caps.has_dma)
+ atmel_sha_dma_cleanup(sha_dd);
+ err_sha_dma:
++iclk_unprepare:
++ clk_unprepare(sha_dd->iclk);
+ res_err:
+ tasklet_kill(&sha_dd->done_task);
+ sha_dd_err:
+@@ -1484,6 +1490,8 @@ static int atmel_sha_remove(struct platf
+ if (sha_dd->caps.has_dma)
+ atmel_sha_dma_cleanup(sha_dd);
+
++ clk_unprepare(sha_dd->iclk);
++
+ return 0;
+ }
+
--- /dev/null
+From 8a3978ad55fb4c0564d285fb2f6cdee2313fce01 Mon Sep 17 00:00:00 2001
+From: Boris BREZILLON <boris.brezillon@free-electrons.com>
+Date: Fri, 5 Feb 2016 17:45:48 +0100
+Subject: crypto: marvell/cesa - fix test in mv_cesa_dev_dma_init()
+
+From: Boris BREZILLON <boris.brezillon@free-electrons.com>
+
+commit 8a3978ad55fb4c0564d285fb2f6cdee2313fce01 upstream.
+
+We are checking twice if dma->cache_pool is not NULL but are never testing
+dma->padding_pool value.
+
+Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/crypto/marvell/cesa.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/crypto/marvell/cesa.c
++++ b/drivers/crypto/marvell/cesa.c
+@@ -306,7 +306,7 @@ static int mv_cesa_dev_dma_init(struct m
+ return -ENOMEM;
+
+ dma->padding_pool = dmam_pool_create("cesa_padding", dev, 72, 1, 0);
+- if (!dma->cache_pool)
++ if (!dma->padding_pool)
+ return -ENOMEM;
+
+ cesa->dma = dma;
--- /dev/null
+From 63e41ebc6630f39422d87f8a4bade1e793f37a01 Mon Sep 17 00:00:00 2001
+From: Mathias Krause <minipli@googlemail.com>
+Date: Mon, 1 Feb 2016 14:27:30 +0100
+Subject: crypto: user - lock crypto_alg_list on alg dump
+
+From: Mathias Krause <minipli@googlemail.com>
+
+commit 63e41ebc6630f39422d87f8a4bade1e793f37a01 upstream.
+
+We miss to take the crypto_alg_sem semaphore when traversing the
+crypto_alg_list for CRYPTO_MSG_GETALG dumps. This allows a race with
+crypto_unregister_alg() removing algorithms from the list while we're
+still traversing it, thereby leading to a use-after-free as show below:
+
+[ 3482.071639] general protection fault: 0000 [#1] SMP
+[ 3482.075639] Modules linked in: aes_x86_64 glue_helper lrw ablk_helper cryptd gf128mul ipv6 pcspkr serio_raw virtio_net microcode virtio_pci virtio_ring virtio sr_mod cdrom [last unloaded: aesni_intel]
+[ 3482.075639] CPU: 1 PID: 11065 Comm: crconf Not tainted 4.3.4-grsec+ #126
+[ 3482.075639] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014
+[ 3482.075639] task: ffff88001cd41a40 ti: ffff88001cd422c8 task.ti: ffff88001cd422c8
+[ 3482.075639] RIP: 0010:[<ffffffff93722bd3>] [<ffffffff93722bd3>] strncpy+0x13/0x30
+[ 3482.075639] RSP: 0018:ffff88001f713b60 EFLAGS: 00010202
+[ 3482.075639] RAX: ffff88001f6c4430 RBX: ffff88001f6c43a0 RCX: ffff88001f6c4430
+[ 3482.075639] RDX: 0000000000000040 RSI: fefefefefefeff16 RDI: ffff88001f6c4430
+[ 3482.075639] RBP: ffff88001f713b60 R08: ffff88001f6c4470 R09: ffff88001f6c4480
+[ 3482.075639] R10: 0000000000000002 R11: 0000000000000246 R12: ffff88001ce2aa28
+[ 3482.075639] R13: ffff880000093700 R14: ffff88001f5e4bf8 R15: 0000000000003b20
+[ 3482.075639] FS: 0000033826fa2700(0000) GS:ffff88001e900000(0000) knlGS:0000000000000000
+[ 3482.075639] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 3482.075639] CR2: ffffffffff600400 CR3: 00000000139ec000 CR4: 00000000001606f0
+[ 3482.075639] Stack:
+[ 3482.075639] ffff88001f713bd8 ffffffff936ccd00 ffff88001e5c4200 ffff880000093700
+[ 3482.075639] ffff88001f713bd0 ffffffff938ef4bf 0000000000000000 0000000000003b20
+[ 3482.075639] ffff88001f5e4bf8 ffff88001f5e4848 0000000000000000 0000000000003b20
+[ 3482.075639] Call Trace:
+[ 3482.075639] [<ffffffff936ccd00>] crypto_report_alg+0xc0/0x3e0
+[ 3482.075639] [<ffffffff938ef4bf>] ? __alloc_skb+0x16f/0x300
+[ 3482.075639] [<ffffffff936cd08a>] crypto_dump_report+0x6a/0x90
+[ 3482.075639] [<ffffffff93935707>] netlink_dump+0x147/0x2e0
+[ 3482.075639] [<ffffffff93935f99>] __netlink_dump_start+0x159/0x190
+[ 3482.075639] [<ffffffff936ccb13>] crypto_user_rcv_msg+0xc3/0x130
+[ 3482.075639] [<ffffffff936cd020>] ? crypto_report_alg+0x3e0/0x3e0
+[ 3482.075639] [<ffffffff936cc4b0>] ? alg_test_crc32c+0x120/0x120
+[ 3482.075639] [<ffffffff93933145>] ? __netlink_lookup+0xd5/0x120
+[ 3482.075639] [<ffffffff936cca50>] ? crypto_add_alg+0x1d0/0x1d0
+[ 3482.075639] [<ffffffff93938141>] netlink_rcv_skb+0xe1/0x130
+[ 3482.075639] [<ffffffff936cc4f8>] crypto_netlink_rcv+0x28/0x40
+[ 3482.075639] [<ffffffff939375a8>] netlink_unicast+0x108/0x180
+[ 3482.075639] [<ffffffff93937c21>] netlink_sendmsg+0x541/0x770
+[ 3482.075639] [<ffffffff938e31e1>] sock_sendmsg+0x21/0x40
+[ 3482.075639] [<ffffffff938e4763>] SyS_sendto+0xf3/0x130
+[ 3482.075639] [<ffffffff93444203>] ? bad_area_nosemaphore+0x13/0x20
+[ 3482.075639] [<ffffffff93444470>] ? __do_page_fault+0x80/0x3a0
+[ 3482.075639] [<ffffffff939d80cb>] entry_SYSCALL_64_fastpath+0x12/0x6e
+[ 3482.075639] Code: 88 4a ff 75 ed 5d 48 0f ba 2c 24 3f c3 66 66 2e 0f 1f 84 00 00 00 00 00 55 48 85 d2 48 89 f8 48 89 f9 4c 8d 04 17 48 89 e5 74 15 <0f> b6 16 80 fa 01 88 11 48 83 de ff 48 83 c1 01 4c 39 c1 75 eb
+[ 3482.075639] RIP [<ffffffff93722bd3>] strncpy+0x13/0x30
+
+To trigger the race run the following loops simultaneously for a while:
+ $ while : ; do modprobe aesni-intel; rmmod aesni-intel; done
+ $ while : ; do crconf show all > /dev/null; done
+
+Fix the race by taking the crypto_alg_sem read lock, thereby preventing
+crypto_unregister_alg() from modifying the algorithm list during the
+dump.
+
+This bug has been detected by the PaX memory sanitize feature.
+
+Signed-off-by: Mathias Krause <minipli@googlemail.com>
+Cc: Steffen Klassert <steffen.klassert@secunet.com>
+Cc: PaX Team <pageexec@freemail.hu>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ crypto/crypto_user.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/crypto/crypto_user.c
++++ b/crypto/crypto_user.c
+@@ -499,6 +499,7 @@ static int crypto_user_rcv_msg(struct sk
+ if (link->dump == NULL)
+ return -EINVAL;
+
++ down_read(&crypto_alg_sem);
+ list_for_each_entry(alg, &crypto_alg_list, cra_list)
+ dump_alloc += CRYPTO_REPORT_MAXSIZE;
+
+@@ -508,8 +509,11 @@ static int crypto_user_rcv_msg(struct sk
+ .done = link->done,
+ .min_dump_alloc = dump_alloc,
+ };
+- return netlink_dump_start(crypto_nlsk, skb, nlh, &c);
++ err = netlink_dump_start(crypto_nlsk, skb, nlh, &c);
+ }
++ up_read(&crypto_alg_sem);
++
++ return err;
+ }
+
+ err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX,
--- /dev/null
+From 613317bd212c585c20796c10afe5daaa95d4b0a1 Mon Sep 17 00:00:00 2001
+From: Ryan Ware <ware@linux.intel.com>
+Date: Thu, 11 Feb 2016 15:58:44 -0800
+Subject: EVM: Use crypto_memneq() for digest comparisons
+
+From: Ryan Ware <ware@linux.intel.com>
+
+commit 613317bd212c585c20796c10afe5daaa95d4b0a1 upstream.
+
+This patch fixes vulnerability CVE-2016-2085. The problem exists
+because the vm_verify_hmac() function includes a use of memcmp().
+Unfortunately, this allows timing side channel attacks; specifically
+a MAC forgery complexity drop from 2^128 to 2^12. This patch changes
+the memcmp() to the cryptographically safe crypto_memneq().
+
+Reported-by: Xiaofei Rex Guo <xiaofei.rex.guo@intel.com>
+Signed-off-by: Ryan Ware <ware@linux.intel.com>
+Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
+Signed-off-by: James Morris <james.l.morris@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/integrity/evm/evm_main.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/security/integrity/evm/evm_main.c
++++ b/security/integrity/evm/evm_main.c
+@@ -23,6 +23,7 @@
+ #include <linux/integrity.h>
+ #include <linux/evm.h>
+ #include <crypto/hash.h>
++#include <crypto/algapi.h>
+ #include "evm.h"
+
+ int evm_initialized;
+@@ -148,7 +149,7 @@ static enum integrity_status evm_verify_
+ xattr_value_len, calc.digest);
+ if (rc)
+ break;
+- rc = memcmp(xattr_data->digest, calc.digest,
++ rc = crypto_memneq(xattr_data->digest, calc.digest,
+ sizeof(calc.digest));
+ if (rc)
+ rc = -EINVAL;
--- /dev/null
+From c72fc9093718a3f8597249863a1bac345ba00859 Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Wed, 20 Jan 2016 21:58:39 -0600
+Subject: rtlwifi: rtl8821ae: Fix 5G failure when EEPROM is incorrectly encoded
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit c72fc9093718a3f8597249863a1bac345ba00859 upstream.
+
+Recently, it has been reported that D-Link DWA-582 cards, which use an
+RTL8812AE chip are not able to scan for 5G networks. The problems started
+with kernel 4.2, which is the first version that had commit d10101a60372
+("rtlwifi: rtl8821ae: Fix problem with regulatory information"). With this
+patch, the driver went from setting a default channel plan to using
+the value derived from EEPROM.
+
+Bug reports at https://bugzilla.kernel.org/show_bug.cgi?id=111031 and
+https://bugzilla.redhat.com/show_bug.cgi?id=1279653 are examples of this
+problem.
+
+The problem was solved once I learned that the internal country code was
+resulting in a regulatory set with only 2.4 GHz channels. With the RTL8821AE
+chips available to me, the country code was such that both 2.4 and 5 GHz
+channels are allowed. The fix is to allow both bands even when the EEPROM
+is incorrectly encoded.
+
+Fixes: d10101a60372 ("rtlwifi: rtl8821ae: Fix problem with regulatory information")
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Cc: littlesmartguy@gmail.com
+Cc: gabe@codehaus.org
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/realtek/rtlwifi/regd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/realtek/rtlwifi/regd.c
++++ b/drivers/net/wireless/realtek/rtlwifi/regd.c
+@@ -351,7 +351,6 @@ static const struct ieee80211_regdomain
+ case COUNTRY_CODE_SPAIN:
+ case COUNTRY_CODE_FRANCE:
+ case COUNTRY_CODE_ISRAEL:
+- case COUNTRY_CODE_WORLD_WIDE_13:
+ return &rtl_regdom_12_13;
+ case COUNTRY_CODE_MKK:
+ case COUNTRY_CODE_MKK1:
+@@ -360,6 +359,7 @@ static const struct ieee80211_regdomain
+ return &rtl_regdom_14_60_64;
+ case COUNTRY_CODE_GLOBAL_DOMAIN:
+ return &rtl_regdom_14;
++ case COUNTRY_CODE_WORLD_WIDE_13:
+ case COUNTRY_CODE_WORLD_WIDE_13_5G_ALL:
+ return &rtl_regdom_12_13_5g_all;
+ default:
--- /dev/null
+From 78bae1de422a7f6f2b4b61f6a5c379e3d7f96f44 Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Mon, 14 Dec 2015 16:34:33 -0600
+Subject: rtlwifi: rtl8821ae: Fix errors in parameter initialization
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit 78bae1de422a7f6f2b4b61f6a5c379e3d7f96f44 upstream.
+
+This driver failed to copy parameters sw_crypto and disable_watchdog into
+the locations actually used by the driver. In addition, msi_support was
+initialized three times and one of them used the wrong variable. The
+initialization of parameter int_clear was moved so that it is near that
+of the rest of the parameters.
+
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c
+@@ -95,8 +95,6 @@ int rtl8821ae_init_sw_vars(struct ieee80
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+ rtl8821ae_bt_reg_init(hw);
+- rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
+- rtlpci->int_clear = rtlpriv->cfg->mod_params->int_clear;
+ rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer();
+
+ rtlpriv->dm.dm_initialgain_enable = 1;
+@@ -168,12 +166,15 @@ int rtl8821ae_init_sw_vars(struct ieee80
+ rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
+ rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
+ rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
+- rtlpci->msi_support = rtlpriv->cfg->mod_params->int_clear;
++ rtlpci->int_clear = rtlpriv->cfg->mod_params->int_clear;
++ rtlpriv->cfg->mod_params->sw_crypto =
++ rtlpriv->cfg->mod_params->sw_crypto;
++ rtlpriv->cfg->mod_params->disable_watchdog =
++ rtlpriv->cfg->mod_params->disable_watchdog;
+ if (rtlpriv->cfg->mod_params->disable_watchdog)
+ pr_info("watchdog disabled\n");
+ rtlpriv->psc.reg_fwctrl_lps = 3;
+ rtlpriv->psc.reg_max_lps_awakeintvl = 5;
+- rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
+
+ /* for ASPM, you can close aspm through
+ * set const_support_pciaspm = 0
crypto-caam-make-write-transactions-bufferable-on-ppc-platforms.patch
crypto-chacha20-ssse3-align-stack-pointer-to-64-bytes.patch
crypto-shash-fix-has_key-setting.patch
+crypto-algif_hash-wait-for-crypto_ahash_init-to-complete.patch
+evm-use-crypto_memneq-for-digest-comparisons.patch
+crypto-user-lock-crypto_alg_list-on-alg-dump.patch
+crypto-algif_skcipher-do-not-assume-that-req-is-unchanged.patch
+crypto-algif_skcipher-do-not-dereference-ctx-without-socket-lock.patch
+crypto-algif_skcipher-do-not-set-may_backlog-on-the-async-path.patch
+crypto-atmel-sha-fix-atmel_sha_remove.patch
+crypto-atmel-sha-remove-calls-of-clk_prepare-from-atomic-contexts.patch
+crypto-marvell-cesa-fix-test-in-mv_cesa_dev_dma_init.patch
+rtlwifi-rtl8821ae-fix-errors-in-parameter-initialization.patch
+rtlwifi-rtl8821ae-fix-5g-failure-when-eeprom-is-incorrectly-encoded.patch
+zram-zcomp-use-gfp_noio-to-allocate-streams.patch
+zram-try-vmalloc-after-kmalloc.patch
+zram-don-t-call-idr_remove-from-zram_remove.patch
+zsmalloc-fix-migrate_zspage-zs_free-race-condition.patch
--- /dev/null
+From 17ec4cd985780a7e30aa45bb8f272237c12502a4 Mon Sep 17 00:00:00 2001
+From: Jerome Marchand <jmarchan@redhat.com>
+Date: Fri, 15 Jan 2016 16:54:48 -0800
+Subject: zram: don't call idr_remove() from zram_remove()
+
+From: Jerome Marchand <jmarchan@redhat.com>
+
+commit 17ec4cd985780a7e30aa45bb8f272237c12502a4 upstream.
+
+The use of idr_remove() is forbidden in the callback functions of
+idr_for_each(). It is therefore unsafe to call idr_remove in
+zram_remove().
+
+This patch moves the call to idr_remove() from zram_remove() to
+hot_remove_store(). In the detroy_devices() path, idrs are removed by
+idr_destroy(). This solves an use-after-free detected by KASan.
+
+[akpm@linux-foundation.org: fix coding stype, per Sergey]
+Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
+Acked-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Cc: Minchan Kim <minchan@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/zram/zram_drv.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/block/zram/zram_drv.c
++++ b/drivers/block/zram/zram_drv.c
+@@ -1325,7 +1325,6 @@ static int zram_remove(struct zram *zram
+
+ pr_info("Removed device: %s\n", zram->disk->disk_name);
+
+- idr_remove(&zram_index_idr, zram->disk->first_minor);
+ blk_cleanup_queue(zram->disk->queue);
+ del_gendisk(zram->disk);
+ put_disk(zram->disk);
+@@ -1367,10 +1366,12 @@ static ssize_t hot_remove_store(struct c
+ mutex_lock(&zram_index_mutex);
+
+ zram = idr_find(&zram_index_idr, dev_id);
+- if (zram)
++ if (zram) {
+ ret = zram_remove(zram);
+- else
++ idr_remove(&zram_index_idr, dev_id);
++ } else {
+ ret = -ENODEV;
++ }
+
+ mutex_unlock(&zram_index_mutex);
+ return ret ? ret : count;
--- /dev/null
+From d913897abace843bba20249f3190167f7895e9c3 Mon Sep 17 00:00:00 2001
+From: Kyeongdon Kim <kyeongdon.kim@lge.com>
+Date: Thu, 14 Jan 2016 15:22:29 -0800
+Subject: zram: try vmalloc() after kmalloc()
+
+From: Kyeongdon Kim <kyeongdon.kim@lge.com>
+
+commit d913897abace843bba20249f3190167f7895e9c3 upstream.
+
+When we're using LZ4 multi compression streams for zram swap, we found
+out page allocation failure message in system running test. That was
+not only once, but a few(2 - 5 times per test). Also, some failure
+cases were continually occurring to try allocation order 3.
+
+In order to make parallel compression private data, we should call
+kzalloc() with order 2/3 in runtime(lzo/lz4). But if there is no order
+2/3 size memory to allocate in that time, page allocation fails. This
+patch makes to use vmalloc() as fallback of kmalloc(), this prevents
+page alloc failure warning.
+
+After using this, we never found warning message in running test, also
+It could reduce process startup latency about 60-120ms in each case.
+
+For reference a call trace :
+
+ Binder_1: page allocation failure: order:3, mode:0x10c0d0
+ CPU: 0 PID: 424 Comm: Binder_1 Tainted: GW 3.10.49-perf-g991d02b-dirty #20
+ Call trace:
+ dump_backtrace+0x0/0x270
+ show_stack+0x10/0x1c
+ dump_stack+0x1c/0x28
+ warn_alloc_failed+0xfc/0x11c
+ __alloc_pages_nodemask+0x724/0x7f0
+ __get_free_pages+0x14/0x5c
+ kmalloc_order_trace+0x38/0xd8
+ zcomp_lz4_create+0x2c/0x38
+ zcomp_strm_alloc+0x34/0x78
+ zcomp_strm_multi_find+0x124/0x1ec
+ zcomp_strm_find+0xc/0x18
+ zram_bvec_rw+0x2fc/0x780
+ zram_make_request+0x25c/0x2d4
+ generic_make_request+0x80/0xbc
+ submit_bio+0xa4/0x15c
+ __swap_writepage+0x218/0x230
+ swap_writepage+0x3c/0x4c
+ shrink_page_list+0x51c/0x8d0
+ shrink_inactive_list+0x3f8/0x60c
+ shrink_lruvec+0x33c/0x4cc
+ shrink_zone+0x3c/0x100
+ try_to_free_pages+0x2b8/0x54c
+ __alloc_pages_nodemask+0x514/0x7f0
+ __get_free_pages+0x14/0x5c
+ proc_info_read+0x50/0xe4
+ vfs_read+0xa0/0x12c
+ SyS_read+0x44/0x74
+ DMA: 3397*4kB (MC) 26*8kB (RC) 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB
+ 0*512kB 0*1024kB 0*2048kB 0*4096kB = 13796kB
+
+[minchan@kernel.org: change vmalloc gfp and adding comment about gfp]
+[sergey.senozhatsky@gmail.com: tweak comments and styles]
+Signed-off-by: Kyeongdon Kim <kyeongdon.kim@lge.com>
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+Acked-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/zram/zcomp_lz4.c | 23 +++++++++++++++++++++--
+ drivers/block/zram/zcomp_lzo.c | 23 +++++++++++++++++++++--
+ 2 files changed, 42 insertions(+), 4 deletions(-)
+
+--- a/drivers/block/zram/zcomp_lz4.c
++++ b/drivers/block/zram/zcomp_lz4.c
+@@ -10,17 +10,36 @@
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+ #include <linux/lz4.h>
++#include <linux/vmalloc.h>
++#include <linux/mm.h>
+
+ #include "zcomp_lz4.h"
+
+ static void *zcomp_lz4_create(void)
+ {
+- return kzalloc(LZ4_MEM_COMPRESS, GFP_NOIO);
++ void *ret;
++
++ /*
++ * This function can be called in swapout/fs write path
++ * so we can't use GFP_FS|IO. And it assumes we already
++ * have at least one stream in zram initialization so we
++ * don't do best effort to allocate more stream in here.
++ * A default stream will work well without further multiple
++ * streams. That's why we use NORETRY | NOWARN.
++ */
++ ret = kzalloc(LZ4_MEM_COMPRESS, GFP_NOIO | __GFP_NORETRY |
++ __GFP_NOWARN);
++ if (!ret)
++ ret = __vmalloc(LZ4_MEM_COMPRESS,
++ GFP_NOIO | __GFP_NORETRY | __GFP_NOWARN |
++ __GFP_ZERO | __GFP_HIGHMEM,
++ PAGE_KERNEL);
++ return ret;
+ }
+
+ static void zcomp_lz4_destroy(void *private)
+ {
+- kfree(private);
++ kvfree(private);
+ }
+
+ static int zcomp_lz4_compress(const unsigned char *src, unsigned char *dst,
+--- a/drivers/block/zram/zcomp_lzo.c
++++ b/drivers/block/zram/zcomp_lzo.c
+@@ -10,17 +10,36 @@
+ #include <linux/kernel.h>
+ #include <linux/slab.h>
+ #include <linux/lzo.h>
++#include <linux/vmalloc.h>
++#include <linux/mm.h>
+
+ #include "zcomp_lzo.h"
+
+ static void *lzo_create(void)
+ {
+- return kzalloc(LZO1X_MEM_COMPRESS, GFP_NOIO);
++ void *ret;
++
++ /*
++ * This function can be called in swapout/fs write path
++ * so we can't use GFP_FS|IO. And it assumes we already
++ * have at least one stream in zram initialization so we
++ * don't do best effort to allocate more stream in here.
++ * A default stream will work well without further multiple
++ * streams. That's why we use NORETRY | NOWARN.
++ */
++ ret = kzalloc(LZO1X_MEM_COMPRESS, GFP_NOIO | __GFP_NORETRY |
++ __GFP_NOWARN);
++ if (!ret)
++ ret = __vmalloc(LZO1X_MEM_COMPRESS,
++ GFP_NOIO | __GFP_NORETRY | __GFP_NOWARN |
++ __GFP_ZERO | __GFP_HIGHMEM,
++ PAGE_KERNEL);
++ return ret;
+ }
+
+ static void lzo_destroy(void *private)
+ {
+- kfree(private);
++ kvfree(private);
+ }
+
+ static int lzo_compress(const unsigned char *src, unsigned char *dst,
--- /dev/null
+From 3d5fe03a3ea013060ebba2a811aeb0f23f56aefa Mon Sep 17 00:00:00 2001
+From: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Date: Thu, 14 Jan 2016 15:22:26 -0800
+Subject: zram/zcomp: use GFP_NOIO to allocate streams
+
+From: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+
+commit 3d5fe03a3ea013060ebba2a811aeb0f23f56aefa upstream.
+
+We can end up allocating a new compression stream with GFP_KERNEL from
+within the IO path, which may result is nested (recursive) IO
+operations. That can introduce problems if the IO path in question is a
+reclaimer, holding some locks that will deadlock nested IOs.
+
+Allocate streams and working memory using GFP_NOIO flag, forbidding
+recursive IO and FS operations.
+
+An example:
+
+ inconsistent {IN-RECLAIM_FS-W} -> {RECLAIM_FS-ON-W} usage.
+ git/20158 [HC0[0]:SC0[0]:HE1:SE1] takes:
+ (jbd2_handle){+.+.?.}, at: start_this_handle+0x4ca/0x555
+ {IN-RECLAIM_FS-W} state was registered at:
+ __lock_acquire+0x8da/0x117b
+ lock_acquire+0x10c/0x1a7
+ start_this_handle+0x52d/0x555
+ jbd2__journal_start+0xb4/0x237
+ __ext4_journal_start_sb+0x108/0x17e
+ ext4_dirty_inode+0x32/0x61
+ __mark_inode_dirty+0x16b/0x60c
+ iput+0x11e/0x274
+ __dentry_kill+0x148/0x1b8
+ shrink_dentry_list+0x274/0x44a
+ prune_dcache_sb+0x4a/0x55
+ super_cache_scan+0xfc/0x176
+ shrink_slab.part.14.constprop.25+0x2a2/0x4d3
+ shrink_zone+0x74/0x140
+ kswapd+0x6b7/0x930
+ kthread+0x107/0x10f
+ ret_from_fork+0x3f/0x70
+ irq event stamp: 138297
+ hardirqs last enabled at (138297): debug_check_no_locks_freed+0x113/0x12f
+ hardirqs last disabled at (138296): debug_check_no_locks_freed+0x33/0x12f
+ softirqs last enabled at (137818): __do_softirq+0x2d3/0x3e9
+ softirqs last disabled at (137813): irq_exit+0x41/0x95
+
+ other info that might help us debug this:
+ Possible unsafe locking scenario:
+ CPU0
+ ----
+ lock(jbd2_handle);
+ <Interrupt>
+ lock(jbd2_handle);
+
+ *** DEADLOCK ***
+ 5 locks held by git/20158:
+ #0: (sb_writers#7){.+.+.+}, at: [<ffffffff81155411>] mnt_want_write+0x24/0x4b
+ #1: (&type->i_mutex_dir_key#2/1){+.+.+.}, at: [<ffffffff81145087>] lock_rename+0xd9/0xe3
+ #2: (&sb->s_type->i_mutex_key#11){+.+.+.}, at: [<ffffffff8114f8e2>] lock_two_nondirectories+0x3f/0x6b
+ #3: (&sb->s_type->i_mutex_key#11/4){+.+.+.}, at: [<ffffffff8114f909>] lock_two_nondirectories+0x66/0x6b
+ #4: (jbd2_handle){+.+.?.}, at: [<ffffffff811e31db>] start_this_handle+0x4ca/0x555
+
+ stack backtrace:
+ CPU: 2 PID: 20158 Comm: git Not tainted 4.1.0-rc7-next-20150615-dbg-00016-g8bdf555-dirty #211
+ Call Trace:
+ dump_stack+0x4c/0x6e
+ mark_lock+0x384/0x56d
+ mark_held_locks+0x5f/0x76
+ lockdep_trace_alloc+0xb2/0xb5
+ kmem_cache_alloc_trace+0x32/0x1e2
+ zcomp_strm_alloc+0x25/0x73 [zram]
+ zcomp_strm_multi_find+0xe7/0x173 [zram]
+ zcomp_strm_find+0xc/0xe [zram]
+ zram_bvec_rw+0x2ca/0x7e0 [zram]
+ zram_make_request+0x1fa/0x301 [zram]
+ generic_make_request+0x9c/0xdb
+ submit_bio+0xf7/0x120
+ ext4_io_submit+0x2e/0x43
+ ext4_bio_write_page+0x1b7/0x300
+ mpage_submit_page+0x60/0x77
+ mpage_map_and_submit_buffers+0x10f/0x21d
+ ext4_writepages+0xc8c/0xe1b
+ do_writepages+0x23/0x2c
+ __filemap_fdatawrite_range+0x84/0x8b
+ filemap_flush+0x1c/0x1e
+ ext4_alloc_da_blocks+0xb8/0x117
+ ext4_rename+0x132/0x6dc
+ ? mark_held_locks+0x5f/0x76
+ ext4_rename2+0x29/0x2b
+ vfs_rename+0x540/0x636
+ SyS_renameat2+0x359/0x44d
+ SyS_rename+0x1e/0x20
+ entry_SYSCALL_64_fastpath+0x12/0x6f
+
+[minchan@kernel.org: add stable mark]
+Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Acked-by: Minchan Kim <minchan@kernel.org>
+Cc: Kyeongdon Kim <kyeongdon.kim@lge.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/zram/zcomp.c | 4 ++--
+ drivers/block/zram/zcomp_lz4.c | 2 +-
+ drivers/block/zram/zcomp_lzo.c | 2 +-
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/block/zram/zcomp.c
++++ b/drivers/block/zram/zcomp.c
+@@ -76,7 +76,7 @@ static void zcomp_strm_free(struct zcomp
+ */
+ static struct zcomp_strm *zcomp_strm_alloc(struct zcomp *comp)
+ {
+- struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), GFP_KERNEL);
++ struct zcomp_strm *zstrm = kmalloc(sizeof(*zstrm), GFP_NOIO);
+ if (!zstrm)
+ return NULL;
+
+@@ -85,7 +85,7 @@ static struct zcomp_strm *zcomp_strm_all
+ * allocate 2 pages. 1 for compressed data, plus 1 extra for the
+ * case when compressed size is larger than the original one
+ */
+- zstrm->buffer = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, 1);
++ zstrm->buffer = (void *)__get_free_pages(GFP_NOIO | __GFP_ZERO, 1);
+ if (!zstrm->private || !zstrm->buffer) {
+ zcomp_strm_free(comp, zstrm);
+ zstrm = NULL;
+--- a/drivers/block/zram/zcomp_lz4.c
++++ b/drivers/block/zram/zcomp_lz4.c
+@@ -15,7 +15,7 @@
+
+ static void *zcomp_lz4_create(void)
+ {
+- return kzalloc(LZ4_MEM_COMPRESS, GFP_KERNEL);
++ return kzalloc(LZ4_MEM_COMPRESS, GFP_NOIO);
+ }
+
+ static void zcomp_lz4_destroy(void *private)
+--- a/drivers/block/zram/zcomp_lzo.c
++++ b/drivers/block/zram/zcomp_lzo.c
+@@ -15,7 +15,7 @@
+
+ static void *lzo_create(void)
+ {
+- return kzalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
++ return kzalloc(LZO1X_MEM_COMPRESS, GFP_NOIO);
+ }
+
+ static void lzo_destroy(void *private)
--- /dev/null
+From c102f07ca0b04f2cb49cfc161c83f6239d17f491 Mon Sep 17 00:00:00 2001
+From: Junil Lee <junil0814.lee@lge.com>
+Date: Wed, 20 Jan 2016 14:58:18 -0800
+Subject: zsmalloc: fix migrate_zspage-zs_free race condition
+
+From: Junil Lee <junil0814.lee@lge.com>
+
+commit c102f07ca0b04f2cb49cfc161c83f6239d17f491 upstream.
+
+record_obj() in migrate_zspage() does not preserve handle's
+HANDLE_PIN_BIT, set by find_aloced_obj()->trypin_tag(), and implicitly
+(accidentally) un-pins the handle, while migrate_zspage() still performs
+an explicit unpin_tag() on the that handle. This additional explicit
+unpin_tag() introduces a race condition with zs_free(), which can pin
+that handle by this time, so the handle becomes un-pinned.
+
+Schematically, it goes like this:
+
+ CPU0 CPU1
+ migrate_zspage
+ find_alloced_obj
+ trypin_tag
+ set HANDLE_PIN_BIT zs_free()
+ pin_tag()
+ obj_malloc() -- new object, no tag
+ record_obj() -- remove HANDLE_PIN_BIT set HANDLE_PIN_BIT
+ unpin_tag() -- remove zs_free's HANDLE_PIN_BIT
+
+The race condition may result in a NULL pointer dereference:
+
+ Unable to handle kernel NULL pointer dereference at virtual address 00000000
+ CPU: 0 PID: 19001 Comm: CookieMonsterCl Tainted:
+ PC is at get_zspage_mapping+0x0/0x24
+ LR is at obj_free.isra.22+0x64/0x128
+ Call trace:
+ get_zspage_mapping+0x0/0x24
+ zs_free+0x88/0x114
+ zram_free_page+0x64/0xcc
+ zram_slot_free_notify+0x90/0x108
+ swap_entry_free+0x278/0x294
+ free_swap_and_cache+0x38/0x11c
+ unmap_single_vma+0x480/0x5c8
+ unmap_vmas+0x44/0x60
+ exit_mmap+0x50/0x110
+ mmput+0x58/0xe0
+ do_exit+0x320/0x8dc
+ do_group_exit+0x44/0xa8
+ get_signal+0x538/0x580
+ do_signal+0x98/0x4b8
+ do_notify_resume+0x14/0x5c
+
+This patch keeps the lock bit in migration path and update value
+atomically.
+
+Signed-off-by: Junil Lee <junil0814.lee@lge.com>
+Signed-off-by: Minchan Kim <minchan@kernel.org>
+Acked-by: Vlastimil Babka <vbabka@suse.cz>
+Cc: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/zsmalloc.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+--- a/mm/zsmalloc.c
++++ b/mm/zsmalloc.c
+@@ -309,7 +309,12 @@ static void free_handle(struct zs_pool *
+
+ static void record_obj(unsigned long handle, unsigned long obj)
+ {
+- *(unsigned long *)handle = obj;
++ /*
++ * lsb of @obj represents handle lock while other bits
++ * represent object value the handle is pointing so
++ * updating shouldn't do store tearing.
++ */
++ WRITE_ONCE(*(unsigned long *)handle, obj);
+ }
+
+ /* zpool driver */
+@@ -1635,6 +1640,13 @@ static int migrate_zspage(struct zs_pool
+ free_obj = obj_malloc(d_page, class, handle);
+ zs_object_copy(free_obj, used_obj, class);
+ index++;
++ /*
++ * record_obj updates handle's value to free_obj and it will
++ * invalidate lock bit(ie, HANDLE_PIN_BIT) of handle, which
++ * breaks synchronization using pin_tag(e,g, zs_free) so
++ * let's keep the lock bit.
++ */
++ free_obj |= BIT(HANDLE_PIN_BIT);
+ record_obj(handle, free_obj);
+ unpin_tag(handle);
+ obj_free(pool, class, used_obj);