Re: crypto: NULL deref in sha512_mb_mgr_get_comp_job_avx2

From: Tim Chen
Date: Thu Feb 02 2017 - 11:00:47 EST


On Thu, 2017-02-02 at 11:58 +0100, Dmitry Vyukov wrote:
> On Wed, Feb 1, 2017 at 7:45 PM, Tim Chen <tim.c.chen@xxxxxxxxxxxxxxx> wrote:
> >
> > On Tue, Jan 31, 2017 at 02:16:31PM +0100, Dmitry Vyukov wrote:
> > >
> > > Hello,
> > >
> > > I am getting the following reports with low frequency while running
> > > syzkaller fuzzer. Unfortunately they are not reproducible and happen
> > > in a background thread, so it is difficult to extract any context on
> > > my side. I see only few such crashes per week, so most likely it is
> > > some hard to trigger data race. The following reports are from mmotm
> > > tree, commits 00e20cfc2bf04a0cbe1f5405f61c8426f43eee84 and
> > > fff7e71eac7788904753136f09bcad7471f7799e. Any ideas as to how this can
> > > happen?
> > >
> > > BUG: unable to handle kernel NULL pointer dereference at 0000000000000060
> > > IP: [<ffffffff813fc09e>] sha512_mb_mgr_get_comp_job_avx2+0x6e/0xee
> > > arch/x86/crypto/sha512-mb/sha512_mb_mgr_flush_avx2.S:251
> > > PGD 1d2395067 [ÂÂ220.874864] PUD 1d2860067
> > > Oops: 0002 [#1] SMP KASAN
> > > Dumping ftrace buffer:
> > > ÂÂÂ(ftrace buffer empty)
> > > Modules linked in:
> > > CPU: 0 PID: 516 Comm: kworker/0:1 Not tainted 4.9.0 #4
> > > Hardware name: Google Google Compute Engine/Google Compute Engine,
> > > BIOS Google 01/01/2011
> > > Workqueue: crypto mcryptd_queue_worker
> > > task: ffff8801d9f346c0 task.stack: ffff8801d9f08000
> > > RIP: 0010:[<ffffffff813fc09e>]ÂÂ[<ffffffff813fc09e>]
> > > sha512_mb_mgr_get_comp_job_avx2+0x6e/0xee
> > > arch/x86/crypto/sha512-mb/sha512_mb_mgr_flush_avx2.S:251
> > > RSP: 0018:ffff8801d9f0eef8ÂÂEFLAGS: 00010202
> > > RAX: 0000000000000000 RBX: ffff8801d7db1190 RCX: 0000000000000006
> > > RDX: 0000000000000001 RSI: ffff8801d9f34ee8 RDI: ffff8801d7db1040
> > > RBP: ffff8801d9f0f258 R08: 0000000100000000 R09: 0000000000000001
> > > R10: 0000000000000002 R11: 0000000000000003 R12: ffff8801d9f0f230
> > > R13: ffff8801c8bbc4e0 R14: ffff8801c8bbc530 R15: ffff8801d9f0ef70
> > > FS:ÂÂ0000000000000000(0000) GS:ffff8801dc000000(0000) knlGS:0000000000000000
> > > CS:ÂÂ0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > > CR2: 0000000000000060 CR3: 00000001cc15a000 CR4: 00000000001406f0
> > > DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> > > DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
> > > Stack:
> > > Âffff8801d7db1040 ffffffff813fa207 dffffc0000000000 ffffe8ffffc0f238
> > > Â0000000000000002 1ffff1003b3e1dea ffffe8ffffc0f218 ffff8801d9f0f190
> > > Â0000000000000282 ffffe8ffffc0f140 ffffe8ffffc0f220 0000000041b58ab3
> > > Call Trace:
> > > Â[<ffffffff813fb407>] sha512_mb_update+0x2f7/0x4e0
> > > arch/x86/crypto/sha512-mb/sha512_mb.c:588
> > > Â[<ffffffff8219d4ad>] crypto_ahash_update include/crypto/hash.h:512 [inline]
> > > Â[<ffffffff8219d4ad>] ahash_mcryptd_update crypto/mcryptd.c:627 [inline]
> > > Â[<ffffffff8219d4ad>] mcryptd_hash_update+0xcd/0x1c0 crypto/mcryptd.c:373
> > > Â[<ffffffff8219c99f>] mcryptd_queue_worker+0xff/0x6a0 crypto/mcryptd.c:181
> > > Â[<ffffffff81492960>] process_one_work+0xbd0/0x1c10 kernel/workqueue.c:2096
> > > Â[<ffffffff81493bc3>] worker_thread+0x223/0x1990 kernel/workqueue.c:2230
> > > Â[<ffffffff814abb33>] kthread+0x323/0x3e0 kernel/kthread.c:209
> > > Â[<ffffffff8436fbaa>] ret_from_fork+0x2a/0x40 arch/x86/entry/entry_64.S:433
> > > Code: 49 0f 42 d3 48 f7 c2 f0 ff ff ff 0f 85 9a 00 00 00 48 83 e2 0f
> > > 48 6b da 08 48 8d 9c 1f 48 01 00 00 48 8b 03 48 c7 03 00 00 00 00 <c7>
> > > 40 60 02 00 00 00 48 8b 9f 40 01 00 00 48 c1 e3 08 48 09 d3
> > > RIPÂÂ[<ffffffff813fc09e>] sha512_mb_mgr_get_comp_job_avx2+0x6e/0xee
> > > arch/x86/crypto/sha512-mb/sha512_mb_mgr_flush_avx2.S:251
> > > ÂRSP <ffff8801d9f0eef8>
> > > CR2: 0000000000000060
> > > ---[ end trace 139fd4cda5dfe2c4 ]---
> > >
> > Dmitry,
> >
> > One theory that Mehga and I have is that perhaps the flusher
> > and regular computaion updates are stepping on each other.
> > Can you try this patch and see if it helps?
>
> No, for this one I can't. Sorry.
> It happens with very low frequency and only one fuzzer that tests
> mmotm tree. If/when this is committed, I can keep an eye on these
> reports and notify if I still see them.
> If you have a hypothesis as to how it happens, perhaps you could write
> a test that provokes the crash and maybe add some sleeps to kernel
> code or alter timeouts to increase probability.
>

If this patch is merged, it will most likely go into Herbert's crypto-dev
tree and not Andrew's mm tree for testing. ÂWe will try to do the best
on our side for testing to replicate the crash scenario. Â

Will it be possible to have one of your fuzzer run the crypto-dev treeÂ
once the patch got merged there? Â

Thanks.

Tim

>
>
> >
> > --->8---
> >
> > From: Tim Chen <tim.c.chen@xxxxxxxxxxxxxxx>
> > Subject: [PATCH] crypto/sha512-mb: Protect sha512 mb ctx mgr access
> > To: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>, Dmitry Vyukov <dvyukov@xxxxxxxxxx>
> > Cc: Tim Chen <tim.c.chen@xxxxxxxxxxxxxxx>, David Miller <davem@xxxxxxxxxxxxx>, linux-crypto@xxxxxxxxxxxxxxx, LKML <linux-kernel@xxxxxxxxxxxxxxx>, megha.dey@xxxxxxxxxxxxxxx, fenghua.yu@xxxxxxxxx
> >
> > The flusher and regular multi-buffer computation via mcryptd may race with another.
> > Add here a lock and turn off interrupt to to access multi-buffer
> > computation state cstate->mgr before a round of computation. This should
> > prevent the flusher code jumping in.
> >
> > Signed-off-by: Tim Chen <tim.c.chen@xxxxxxxxxxxxxxx>
> > ---
> > Âarch/x86/crypto/sha512-mb/sha512_mb.c | 64 +++++++++++++++++++++++------------
> > Â1 file changed, 42 insertions(+), 22 deletions(-)
> >
> > diff --git a/arch/x86/crypto/sha512-mb/sha512_mb.c b/arch/x86/crypto/sha512-mb/sha512_mb.c
> > index d210174..f3c1c21 100644
> > --- a/arch/x86/crypto/sha512-mb/sha512_mb.c
> > +++ b/arch/x86/crypto/sha512-mb/sha512_mb.c
> > @@ -221,7 +221,7 @@ static struct sha512_hash_ctx *sha512_ctx_mgr_resubmit
> > Â}
> >
> > Âstatic struct sha512_hash_ctx
> > -ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ*sha512_ctx_mgr_get_comp_ctx(struct sha512_ctx_mgr *mgr)
> > +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ*sha512_ctx_mgr_get_comp_ctx(struct mcryptd_alg_cstate *cstate)
> > Â{
> > ÂÂÂÂÂÂÂÂ/*
> > ÂÂÂÂÂÂÂÂÂ* If get_comp_job returns NULL, there are no jobs complete.
> > @@ -233,11 +233,17 @@ static struct sha512_hash_ctx
> > ÂÂÂÂÂÂÂÂÂ* Otherwise, all jobs currently being managed by the hash_ctx_mgr
> > ÂÂÂÂÂÂÂÂÂ* still need processing.
> > ÂÂÂÂÂÂÂÂÂ*/
> > +ÂÂÂÂÂÂÂstruct sha512_ctx_mgr *mgr;
> > ÂÂÂÂÂÂÂÂstruct sha512_hash_ctx *ctx;
> > +ÂÂÂÂÂÂÂunsigned long flags;
> >
> > +ÂÂÂÂÂÂÂmgr = cstate->mgr;
> > +ÂÂÂÂÂÂÂspin_lock_irqsave(&cstate->work_lock, flags);
> > ÂÂÂÂÂÂÂÂctx = (struct sha512_hash_ctx *)
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂsha512_job_mgr_get_comp_job(&mgr->mgr);
> > -ÂÂÂÂÂÂÂreturn sha512_ctx_mgr_resubmit(mgr, ctx);
> > +ÂÂÂÂÂÂÂctx = sha512_ctx_mgr_resubmit(mgr, ctx);
> > +ÂÂÂÂÂÂÂspin_unlock_irqrestore(&cstate->work_lock, flags);
> > +ÂÂÂÂÂÂÂreturn ctx;
> > Â}
> >
> > Âstatic void sha512_ctx_mgr_init(struct sha512_ctx_mgr *mgr)
> > @@ -246,12 +252,17 @@ static void sha512_ctx_mgr_init(struct sha512_ctx_mgr *mgr)
> > Â}
> >
> > Âstatic struct sha512_hash_ctx
> > -ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ*sha512_ctx_mgr_submit(struct sha512_ctx_mgr *mgr,
> > +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ*sha512_ctx_mgr_submit(struct mcryptd_alg_cstate *cstate,
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂstruct sha512_hash_ctx *ctx,
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂconst void *buffer,
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂuint32_t len,
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂint flags)
> > Â{
> > +ÂÂÂÂÂÂÂstruct sha512_ctx_mgr *mgr;
> > +ÂÂÂÂÂÂÂunsigned long irqflags;
> > +
> > +ÂÂÂÂÂÂÂmgr = cstate->mgr;
> > +ÂÂÂÂÂÂÂspin_lock_irqsave(&cstate->work_lock, irqflags);
> > ÂÂÂÂÂÂÂÂif (flags & (~HASH_ENTIRE)) {
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ/*
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ* User should not pass anything other than FIRST, UPDATE, or
> > @@ -351,20 +362,26 @@ static struct sha512_hash_ctx
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ}
> > ÂÂÂÂÂÂÂÂ}
> >
> > -ÂÂÂÂÂÂÂreturn sha512_ctx_mgr_resubmit(mgr, ctx);
> > +ÂÂÂÂÂÂÂctx = sha512_ctx_mgr_resubmit(mgr, ctx);
> > +ÂÂÂÂÂÂÂspin_unlock_irqrestore(&cstate->work_lock, irqflags);
> > +ÂÂÂÂÂÂÂreturn ctx;
> > Â}
> >
> > -static struct sha512_hash_ctx *sha512_ctx_mgr_flush(struct sha512_ctx_mgr *mgr)
> > +static struct sha512_hash_ctx *sha512_ctx_mgr_flush(struct mcryptd_alg_cstate *cstate)
> > Â{
> > +ÂÂÂÂÂÂÂstruct sha512_ctx_mgr *mgr;
> > ÂÂÂÂÂÂÂÂstruct sha512_hash_ctx *ctx;
> > +ÂÂÂÂÂÂÂunsigned long flags;
> >
> > +ÂÂÂÂÂÂÂmgr = cstate->mgr;
> > +ÂÂÂÂÂÂÂspin_lock_irqsave(&cstate->work_lock, flags);
> > ÂÂÂÂÂÂÂÂwhile (1) {
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂctx = (struct sha512_hash_ctx *)
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂsha512_job_mgr_flush(&mgr->mgr);
> >
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ/* If flush returned 0, there are no more jobs in flight. */
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂif (!ctx)
> > -ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂreturn NULL;
> > +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂbreak;
> >
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ/*
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ* If flush returned a job, resubmit the job to finish
> > @@ -378,8 +395,10 @@ static struct sha512_hash_ctx *sha512_ctx_mgr_flush(struct sha512_ctx_mgr *mgr)
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ* the sha512_ctx_mgr still need processing. Loop.
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ*/
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂif (ctx)
> > -ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂreturn ctx;
> > +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂbreak;
> > ÂÂÂÂÂÂÂÂ}
> > +ÂÂÂÂÂÂÂspin_unlock_irqrestore(&cstate->work_lock, flags);
> > +ÂÂÂÂÂÂÂreturn ctx;
> > Â}
> >
> > Âstatic int sha512_mb_init(struct ahash_request *areq)
> > @@ -439,11 +458,11 @@ static int sha_finish_walk(struct mcryptd_hash_request_ctx **ret_rctx,
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂsha_ctx = (struct sha512_hash_ctx *)
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂahash_request_ctx(&rctx->areq);
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂkernel_fpu_begin();
> > -ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂsha_ctx = sha512_ctx_mgr_submit(cstate->mgr, sha_ctx,
> > +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂsha_ctx = sha512_ctx_mgr_submit(cstate, sha_ctx,
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂrctx->walk.data, nbytes, flag);
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂif (!sha_ctx) {
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂif (flush)
> > -ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂsha_ctx = sha512_ctx_mgr_flush(cstate->mgr);
> > +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂsha_ctx = sha512_ctx_mgr_flush(cstate);
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ}
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂkernel_fpu_end();
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂif (sha_ctx)
> > @@ -471,11 +490,12 @@ static int sha_complete_job(struct mcryptd_hash_request_ctx *rctx,
> > ÂÂÂÂÂÂÂÂstruct sha512_hash_ctx *sha_ctx;
> > ÂÂÂÂÂÂÂÂstruct mcryptd_hash_request_ctx *req_ctx;
> > ÂÂÂÂÂÂÂÂint ret;
> > +ÂÂÂÂÂÂÂunsigned long flags;
> >
> > ÂÂÂÂÂÂÂÂ/* remove from work list */
> > -ÂÂÂÂÂÂÂspin_lock(&cstate->work_lock);
> > +ÂÂÂÂÂÂÂspin_lock_irqsave(&cstate->work_lock, flags);
> > ÂÂÂÂÂÂÂÂlist_del(&rctx->waiter);
> > -ÂÂÂÂÂÂÂspin_unlock(&cstate->work_lock);
> > +ÂÂÂÂÂÂÂspin_unlock_irqrestore(&cstate->work_lock, flags);
> >
> > ÂÂÂÂÂÂÂÂif (irqs_disabled())
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂrctx->complete(&req->base, err);
> > @@ -486,14 +506,14 @@ static int sha_complete_job(struct mcryptd_hash_request_ctx *rctx,
> > ÂÂÂÂÂÂÂÂ}
> >
> > ÂÂÂÂÂÂÂÂ/* check to see if there are other jobs that are done */
> > -ÂÂÂÂÂÂÂsha_ctx = sha512_ctx_mgr_get_comp_ctx(cstate->mgr);
> > +ÂÂÂÂÂÂÂsha_ctx = sha512_ctx_mgr_get_comp_ctx(cstate);
> > ÂÂÂÂÂÂÂÂwhile (sha_ctx) {
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂreq_ctx = cast_hash_to_mcryptd_ctx(sha_ctx);
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂret = sha_finish_walk(&req_ctx, cstate, false);
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂif (req_ctx) {
> > -ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂspin_lock(&cstate->work_lock);
> > +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂspin_lock_irqsave(&cstate->work_lock, flags);
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂlist_del(&req_ctx->waiter);
> > -ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂspin_unlock(&cstate->work_lock);
> > +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂspin_unlock_irqrestore(&cstate->work_lock, flags);
> >
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂreq = cast_mcryptd_ctx_to_req(req_ctx);
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂif (irqs_disabled())
> > @@ -504,7 +524,7 @@ static int sha_complete_job(struct mcryptd_hash_request_ctx *rctx,
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂlocal_bh_enable();
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ}
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ}
> > -ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂsha_ctx = sha512_ctx_mgr_get_comp_ctx(cstate->mgr);
> > +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂsha_ctx = sha512_ctx_mgr_get_comp_ctx(cstate);
> > ÂÂÂÂÂÂÂÂ}
> >
> > ÂÂÂÂÂÂÂÂreturn 0;
> > @@ -515,6 +535,7 @@ static void sha512_mb_add_list(struct mcryptd_hash_request_ctx *rctx,
> > Â{
> > ÂÂÂÂÂÂÂÂunsigned long next_flush;
> > ÂÂÂÂÂÂÂÂunsigned long delay = usecs_to_jiffies(FLUSH_INTERVAL);
> > +ÂÂÂÂÂÂÂunsigned long flags;
> >
> > ÂÂÂÂÂÂÂÂ/* initialize tag */
> > ÂÂÂÂÂÂÂÂrctx->tag.arrival = jiffies;ÂÂÂÂ/* tag the arrival time */
> > @@ -522,9 +543,9 @@ static void sha512_mb_add_list(struct mcryptd_hash_request_ctx *rctx,
> > ÂÂÂÂÂÂÂÂnext_flush = rctx->tag.arrival + delay;
> > ÂÂÂÂÂÂÂÂrctx->tag.expire = next_flush;
> >
> > -ÂÂÂÂÂÂÂspin_lock(&cstate->work_lock);
> > +ÂÂÂÂÂÂÂspin_lock_irqsave(&cstate->work_lock, flags);
> > ÂÂÂÂÂÂÂÂlist_add_tail(&rctx->waiter, &cstate->work_list);
> > -ÂÂÂÂÂÂÂspin_unlock(&cstate->work_lock);
> > +ÂÂÂÂÂÂÂspin_unlock_irqrestore(&cstate->work_lock, flags);
> >
> > ÂÂÂÂÂÂÂÂmcryptd_arm_flusher(cstate, delay);
> > Â}
> > @@ -565,7 +586,7 @@ static int sha512_mb_update(struct ahash_request *areq)
> > ÂÂÂÂÂÂÂÂsha_ctx = (struct sha512_hash_ctx *) ahash_request_ctx(areq);
> > ÂÂÂÂÂÂÂÂsha512_mb_add_list(rctx, cstate);
> > ÂÂÂÂÂÂÂÂkernel_fpu_begin();
> > -ÂÂÂÂÂÂÂsha_ctx = sha512_ctx_mgr_submit(cstate->mgr, sha_ctx, rctx->walk.data,
> > +ÂÂÂÂÂÂÂsha_ctx = sha512_ctx_mgr_submit(cstate, sha_ctx, rctx->walk.data,
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂnbytes, HASH_UPDATE);
> > ÂÂÂÂÂÂÂÂkernel_fpu_end();
> >
> > @@ -628,7 +649,7 @@ static int sha512_mb_finup(struct ahash_request *areq)
> > ÂÂÂÂÂÂÂÂsha512_mb_add_list(rctx, cstate);
> >
> > ÂÂÂÂÂÂÂÂkernel_fpu_begin();
> > -ÂÂÂÂÂÂÂsha_ctx = sha512_ctx_mgr_submit(cstate->mgr, sha_ctx, rctx->walk.data,
> > +ÂÂÂÂÂÂÂsha_ctx = sha512_ctx_mgr_submit(cstate, sha_ctx, rctx->walk.data,
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂnbytes, flag);
> > ÂÂÂÂÂÂÂÂkernel_fpu_end();
> >
> > @@ -677,8 +698,7 @@ static int sha512_mb_final(struct ahash_request *areq)
> > ÂÂÂÂÂÂÂÂ/* flag HASH_FINAL and 0 data size */
> > ÂÂÂÂÂÂÂÂsha512_mb_add_list(rctx, cstate);
> > ÂÂÂÂÂÂÂÂkernel_fpu_begin();
> > -ÂÂÂÂÂÂÂsha_ctx = sha512_ctx_mgr_submit(cstate->mgr, sha_ctx, &data, 0,
> > -ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂHASH_LAST);
> > +ÂÂÂÂÂÂÂsha_ctx = sha512_ctx_mgr_submit(cstate, sha_ctx, &data, 0, HASH_LAST);
> > ÂÂÂÂÂÂÂÂkernel_fpu_end();
> >
> > ÂÂÂÂÂÂÂÂ/* check if anything is returned */
> > @@ -940,7 +960,7 @@ static unsigned long sha512_mb_flusher(struct mcryptd_alg_cstate *cstate)
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂbreak;
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂkernel_fpu_begin();
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂsha_ctx = (struct sha512_hash_ctx *)
> > -ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂsha512_ctx_mgr_flush(cstate->mgr);
> > +ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂsha512_ctx_mgr_flush(cstate);
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂkernel_fpu_end();
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂif (!sha_ctx) {
> > ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂpr_err("sha512_mb error: nothing got flushed for"
> > --
> > 2.5.5
> >