| From: Harald Freudenberger <freude@linux.ibm.com> |
| Date: Mon, 27 May 2019 15:24:20 +0200 |
| Subject: s390/crypto: fix possible sleep during spinlock aquired |
| |
| commit 1c2c7029c008922d4d48902cc386250502e73d51 upstream. |
| |
| This patch fixes a complain about possible sleep during |
| spinlock aquired |
| "BUG: sleeping function called from invalid context at |
| include/crypto/algapi.h:426" |
| for the ctr(aes) and ctr(des) s390 specific ciphers. |
| |
| Instead of using a spinlock this patch introduces a mutex |
| which is save to be held in sleeping context. Please note |
| a deadlock is not possible as mutex_trylock() is used. |
| |
| Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> |
| Reported-by: Julian Wiedmann <jwi@linux.ibm.com> |
| Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> |
| [bwh: Backported to 3.16: |
| - Replace spin_unlock() on all exit paths |
| - Adjust context] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| --- a/arch/s390/crypto/aes_s390.c |
| +++ b/arch/s390/crypto/aes_s390.c |
| @@ -25,7 +25,7 @@ |
| #include <linux/err.h> |
| #include <linux/module.h> |
| #include <linux/init.h> |
| -#include <linux/spinlock.h> |
| +#include <linux/mutex.h> |
| #include "crypt_s390.h" |
| |
| #define AES_KEYLEN_128 1 |
| @@ -33,7 +33,7 @@ |
| #define AES_KEYLEN_256 4 |
| |
| static u8 *ctrblk; |
| -static DEFINE_SPINLOCK(ctrblk_lock); |
| +static DEFINE_MUTEX(ctrblk_lock); |
| static char keylen_flag; |
| |
| struct s390_aes_ctx { |
| @@ -785,7 +785,7 @@ static int ctr_aes_crypt(struct blkciphe |
| if (!walk->nbytes) |
| return ret; |
| |
| - if (spin_trylock(&ctrblk_lock)) |
| + if (mutex_trylock(&ctrblk_lock)) |
| ctrptr = ctrblk; |
| |
| memcpy(ctrptr, walk->iv, AES_BLOCK_SIZE); |
| @@ -801,7 +801,7 @@ static int ctr_aes_crypt(struct blkciphe |
| n, ctrptr); |
| if (ret < 0 || ret != n) { |
| if (ctrptr == ctrblk) |
| - spin_unlock(&ctrblk_lock); |
| + mutex_unlock(&ctrblk_lock); |
| return -EIO; |
| } |
| if (n > AES_BLOCK_SIZE) |
| @@ -819,7 +819,7 @@ static int ctr_aes_crypt(struct blkciphe |
| memcpy(ctrbuf, ctrptr, AES_BLOCK_SIZE); |
| else |
| memcpy(walk->iv, ctrptr, AES_BLOCK_SIZE); |
| - spin_unlock(&ctrblk_lock); |
| + mutex_unlock(&ctrblk_lock); |
| } else { |
| if (!nbytes) |
| memcpy(walk->iv, ctrptr, AES_BLOCK_SIZE); |
| --- a/arch/s390/crypto/des_s390.c |
| +++ b/arch/s390/crypto/des_s390.c |
| @@ -17,6 +17,7 @@ |
| #include <linux/init.h> |
| #include <linux/module.h> |
| #include <linux/crypto.h> |
| +#include <linux/mutex.h> |
| #include <crypto/algapi.h> |
| #include <crypto/des.h> |
| |
| @@ -25,7 +26,7 @@ |
| #define DES3_KEY_SIZE (3 * DES_KEY_SIZE) |
| |
| static u8 *ctrblk; |
| -static DEFINE_SPINLOCK(ctrblk_lock); |
| +static DEFINE_MUTEX(ctrblk_lock); |
| |
| struct s390_des_ctx { |
| u8 iv[DES_BLOCK_SIZE]; |
| @@ -394,7 +395,7 @@ static int ctr_desall_crypt(struct blkci |
| if (!walk->nbytes) |
| return ret; |
| |
| - if (spin_trylock(&ctrblk_lock)) |
| + if (mutex_trylock(&ctrblk_lock)) |
| ctrptr = ctrblk; |
| |
| memcpy(ctrptr, walk->iv, DES_BLOCK_SIZE); |
| @@ -410,7 +411,7 @@ static int ctr_desall_crypt(struct blkci |
| n, ctrptr); |
| if (ret < 0 || ret != n) { |
| if (ctrptr == ctrblk) |
| - spin_unlock(&ctrblk_lock); |
| + mutex_unlock(&ctrblk_lock); |
| return -EIO; |
| } |
| if (n > DES_BLOCK_SIZE) |
| @@ -428,7 +429,7 @@ static int ctr_desall_crypt(struct blkci |
| memcpy(ctrbuf, ctrptr, DES_BLOCK_SIZE); |
| else |
| memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE); |
| - spin_unlock(&ctrblk_lock); |
| + mutex_unlock(&ctrblk_lock); |
| } else { |
| if (!nbytes) |
| memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE); |