crypto: aesni - Fix cryptd reordering problem on gcm
authorHerbert Xu <herbert@gondor.apana.org.au>
Tue, 21 Jun 2016 08:55:14 +0000 (16:55 +0800)
committerHerbert Xu <herbert@gondor.apana.org.au>
Thu, 23 Jun 2016 10:29:52 +0000 (18:29 +0800)
This patch fixes an old bug where gcm requests can be reordered
because some are processed by cryptd while others are processed
directly in softirq context.

The fix is to always postpone to cryptd if there are currently
requests outstanding from the same tfm.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
arch/x86/crypto/aesni-intel_glue.c

index 5b7fa14710073bdc6902de2775d27c3f3ed53bb3..9e15572ef06d6e3f72b26ef862d65aba6320318d 100644 (file)
@@ -1098,9 +1098,12 @@ static int rfc4106_encrypt(struct aead_request *req)
        struct cryptd_aead **ctx = crypto_aead_ctx(tfm);
        struct cryptd_aead *cryptd_tfm = *ctx;
 
-       aead_request_set_tfm(req, irq_fpu_usable() ?
-                                 cryptd_aead_child(cryptd_tfm) :
-                                 &cryptd_tfm->base);
+       tfm = &cryptd_tfm->base;
+       if (irq_fpu_usable() && (!in_atomic() ||
+                                !cryptd_aead_queued(cryptd_tfm)))
+               tfm = cryptd_aead_child(cryptd_tfm);
+
+       aead_request_set_tfm(req, tfm);
 
        return crypto_aead_encrypt(req);
 }
@@ -1111,9 +1114,12 @@ static int rfc4106_decrypt(struct aead_request *req)
        struct cryptd_aead **ctx = crypto_aead_ctx(tfm);
        struct cryptd_aead *cryptd_tfm = *ctx;
 
-       aead_request_set_tfm(req, irq_fpu_usable() ?
-                                 cryptd_aead_child(cryptd_tfm) :
-                                 &cryptd_tfm->base);
+       tfm = &cryptd_tfm->base;
+       if (irq_fpu_usable() && (!in_atomic() ||
+                                !cryptd_aead_queued(cryptd_tfm)))
+               tfm = cryptd_aead_child(cryptd_tfm);
+
+       aead_request_set_tfm(req, tfm);
 
        return crypto_aead_decrypt(req);
 }