aboutsummaryrefslogtreecommitdiff
path: root/arch/s390
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/crypto/aes_s390.c60
-rw-r--r--arch/s390/crypto/des_s390.c360
-rw-r--r--arch/s390/crypto/sha256_s390.c29
-rw-r--r--arch/s390/kernel/process.c14
-rw-r--r--arch/s390/kernel/setup.c11
-rw-r--r--arch/s390/kernel/time.c2
-rw-r--r--arch/s390/kernel/vtime.c27
-rw-r--r--arch/s390/lib/Makefile3
-rw-r--r--arch/s390/lib/spinlock.c7
9 files changed, 385 insertions, 128 deletions
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c
index 7a1033d8e00..c5ca2dc5d42 100644
--- a/arch/s390/crypto/aes_s390.c
+++ b/arch/s390/crypto/aes_s390.c
@@ -114,80 +114,108 @@ static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
const u8 *in, unsigned int nbytes)
{
struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(AES_BLOCK_SIZE - 1);
switch (sctx->key_len) {
case 16:
- crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, nbytes);
+ ret = crypt_s390_km(KM_AES_128_ENCRYPT, &sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
case 24:
- crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in, nbytes);
+ ret = crypt_s390_km(KM_AES_192_ENCRYPT, &sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
case 32:
- crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in, nbytes);
+ ret = crypt_s390_km(KM_AES_256_ENCRYPT, &sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
}
- return nbytes & ~(AES_BLOCK_SIZE - 1);
+ return nbytes;
}
static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out,
const u8 *in, unsigned int nbytes)
{
struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(AES_BLOCK_SIZE - 1);
switch (sctx->key_len) {
case 16:
- crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, nbytes);
+ ret = crypt_s390_km(KM_AES_128_DECRYPT, &sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
case 24:
- crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, nbytes);
+ ret = crypt_s390_km(KM_AES_192_DECRYPT, &sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
case 32:
- crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, nbytes);
+ ret = crypt_s390_km(KM_AES_256_DECRYPT, &sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
}
- return nbytes & ~(AES_BLOCK_SIZE - 1);
+ return nbytes;
}
static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out,
const u8 *in, unsigned int nbytes)
{
struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(AES_BLOCK_SIZE - 1);
memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE);
switch (sctx->key_len) {
case 16:
- crypt_s390_kmc(KMC_AES_128_ENCRYPT, &sctx->iv, out, in, nbytes);
+ ret = crypt_s390_kmc(KMC_AES_128_ENCRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
case 24:
- crypt_s390_kmc(KMC_AES_192_ENCRYPT, &sctx->iv, out, in, nbytes);
+ ret = crypt_s390_kmc(KMC_AES_192_ENCRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
case 32:
- crypt_s390_kmc(KMC_AES_256_ENCRYPT, &sctx->iv, out, in, nbytes);
+ ret = crypt_s390_kmc(KMC_AES_256_ENCRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
}
memcpy(desc->info, &sctx->iv, AES_BLOCK_SIZE);
- return nbytes & ~(AES_BLOCK_SIZE - 1);
+ return nbytes;
}
static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out,
const u8 *in, unsigned int nbytes)
{
struct s390_aes_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(AES_BLOCK_SIZE - 1);
memcpy(&sctx->iv, desc->info, AES_BLOCK_SIZE);
switch (sctx->key_len) {
case 16:
- crypt_s390_kmc(KMC_AES_128_DECRYPT, &sctx->iv, out, in, nbytes);
+ ret = crypt_s390_kmc(KMC_AES_128_DECRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
case 24:
- crypt_s390_kmc(KMC_AES_192_DECRYPT, &sctx->iv, out, in, nbytes);
+ ret = crypt_s390_kmc(KMC_AES_192_DECRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
case 32:
- crypt_s390_kmc(KMC_AES_256_DECRYPT, &sctx->iv, out, in, nbytes);
+ ret = crypt_s390_kmc(KMC_AES_256_DECRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
break;
}
- return nbytes & ~(AES_BLOCK_SIZE - 1);
+ return nbytes;
}
diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c
index a38bb2a3eef..e3c37aa0a19 100644
--- a/arch/s390/crypto/des_s390.c
+++ b/arch/s390/crypto/des_s390.c
@@ -15,10 +15,8 @@
*/
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/errno.h>
-#include <asm/scatterlist.h>
#include <linux/crypto.h>
+
#include "crypt_s390.h"
#include "crypto_des.h"
@@ -46,38 +44,92 @@ struct crypt_s390_des3_192_ctx {
u8 key[DES3_192_KEY_SIZE];
};
-static int
-des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
+static int des_setkey(void *ctx, const u8 *key, unsigned int keylen,
+ u32 *flags)
{
- struct crypt_s390_des_ctx *dctx;
+ struct crypt_s390_des_ctx *dctx = ctx;
int ret;
- dctx = ctx;
- //test if key is valid (not a weak key)
+ /* test if key is valid (not a weak key) */
ret = crypto_des_check_key(key, keylen, flags);
- if (ret == 0){
+ if (ret == 0)
memcpy(dctx->key, key, keylen);
- }
return ret;
}
+static void des_encrypt(void *ctx, u8 *out, const u8 *in)
+{
+ struct crypt_s390_des_ctx *dctx = ctx;
+
+ crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, out, in, DES_BLOCK_SIZE);
+}
+
+static void des_decrypt(void *ctx, u8 *out, const u8 *in)
+{
+ struct crypt_s390_des_ctx *dctx = ctx;
+
+ crypt_s390_km(KM_DEA_DECRYPT, dctx->key, out, in, DES_BLOCK_SIZE);
+}
+
+static unsigned int des_encrypt_ecb(const struct cipher_desc *desc, u8 *out,
+ const u8 *in, unsigned int nbytes)
+{
+ struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES_BLOCK_SIZE - 1);
+ ret = crypt_s390_km(KM_DEA_ENCRYPT, sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ return nbytes;
+}
-static void
-des_encrypt(void *ctx, u8 *dst, const u8 *src)
+static unsigned int des_decrypt_ecb(const struct cipher_desc *desc, u8 *out,
+ const u8 *in, unsigned int nbytes)
{
- struct crypt_s390_des_ctx *dctx;
+ struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES_BLOCK_SIZE - 1);
+ ret = crypt_s390_km(KM_DEA_DECRYPT, sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
- dctx = ctx;
- crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, dst, src, DES_BLOCK_SIZE);
+ return nbytes;
}
-static void
-des_decrypt(void *ctx, u8 *dst, const u8 *src)
+static unsigned int des_encrypt_cbc(const struct cipher_desc *desc, u8 *out,
+ const u8 *in, unsigned int nbytes)
{
- struct crypt_s390_des_ctx *dctx;
+ struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
- dctx = ctx;
- crypt_s390_km(KM_DEA_DECRYPT, dctx->key, dst, src, DES_BLOCK_SIZE);
+ /* only use complete blocks */
+ nbytes &= ~(DES_BLOCK_SIZE - 1);
+
+ memcpy(sctx->iv, desc->info, DES_BLOCK_SIZE);
+ ret = crypt_s390_kmc(KMC_DEA_ENCRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ memcpy(desc->info, sctx->iv, DES_BLOCK_SIZE);
+ return nbytes;
+}
+
+static unsigned int des_decrypt_cbc(const struct cipher_desc *desc, u8 *out,
+ const u8 *in, unsigned int nbytes)
+{
+ struct crypt_s390_des_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES_BLOCK_SIZE - 1);
+
+ memcpy(&sctx->iv, desc->info, DES_BLOCK_SIZE);
+ ret = crypt_s390_kmc(KMC_DEA_DECRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ return nbytes;
}
static struct crypto_alg des_alg = {
@@ -87,12 +139,19 @@ static struct crypto_alg des_alg = {
.cra_ctxsize = sizeof(struct crypt_s390_des_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(des_alg.cra_list),
- .cra_u = { .cipher = {
- .cia_min_keysize = DES_KEY_SIZE,
- .cia_max_keysize = DES_KEY_SIZE,
- .cia_setkey = des_setkey,
- .cia_encrypt = des_encrypt,
- .cia_decrypt = des_decrypt } }
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = DES_KEY_SIZE,
+ .cia_max_keysize = DES_KEY_SIZE,
+ .cia_setkey = des_setkey,
+ .cia_encrypt = des_encrypt,
+ .cia_decrypt = des_decrypt,
+ .cia_encrypt_ecb = des_encrypt_ecb,
+ .cia_decrypt_ecb = des_decrypt_ecb,
+ .cia_encrypt_cbc = des_encrypt_cbc,
+ .cia_decrypt_cbc = des_decrypt_cbc,
+ }
+ }
};
/*
@@ -107,20 +166,18 @@ static struct crypto_alg des_alg = {
* Implementers MUST reject keys that exhibit this property.
*
*/
-static int
-des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
+static int des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen,
+ u32 *flags)
{
int i, ret;
- struct crypt_s390_des3_128_ctx *dctx;
+ struct crypt_s390_des3_128_ctx *dctx = ctx;
const u8* temp_key = key;
- dctx = ctx;
if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) {
-
*flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
return -EINVAL;
}
- for (i = 0; i < 2; i++, temp_key += DES_KEY_SIZE) {
+ for (i = 0; i < 2; i++, temp_key += DES_KEY_SIZE) {
ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags);
if (ret < 0)
return ret;
@@ -129,24 +186,85 @@ des3_128_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
return 0;
}
-static void
-des3_128_encrypt(void *ctx, u8 *dst, const u8 *src)
+static void des3_128_encrypt(void *ctx, u8 *dst, const u8 *src)
{
- struct crypt_s390_des3_128_ctx *dctx;
+ struct crypt_s390_des3_128_ctx *dctx = ctx;
- dctx = ctx;
crypt_s390_km(KM_TDEA_128_ENCRYPT, dctx->key, dst, (void*)src,
- DES3_128_BLOCK_SIZE);
+ DES3_128_BLOCK_SIZE);
}
-static void
-des3_128_decrypt(void *ctx, u8 *dst, const u8 *src)
+static void des3_128_decrypt(void *ctx, u8 *dst, const u8 *src)
{
- struct crypt_s390_des3_128_ctx *dctx;
+ struct crypt_s390_des3_128_ctx *dctx = ctx;
- dctx = ctx;
crypt_s390_km(KM_TDEA_128_DECRYPT, dctx->key, dst, (void*)src,
- DES3_128_BLOCK_SIZE);
+ DES3_128_BLOCK_SIZE);
+}
+
+static unsigned int des3_128_encrypt_ecb(const struct cipher_desc *desc,
+ u8 *out, const u8 *in,
+ unsigned int nbytes)
+{
+ struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
+ ret = crypt_s390_km(KM_TDEA_128_ENCRYPT, sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ return nbytes;
+}
+
+static unsigned int des3_128_decrypt_ecb(const struct cipher_desc *desc,
+ u8 *out, const u8 *in,
+ unsigned int nbytes)
+{
+ struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
+ ret = crypt_s390_km(KM_TDEA_128_DECRYPT, sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ return nbytes;
+}
+
+static unsigned int des3_128_encrypt_cbc(const struct cipher_desc *desc,
+ u8 *out, const u8 *in,
+ unsigned int nbytes)
+{
+ struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
+
+ memcpy(sctx->iv, desc->info, DES3_128_BLOCK_SIZE);
+ ret = crypt_s390_kmc(KMC_TDEA_128_ENCRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ memcpy(desc->info, sctx->iv, DES3_128_BLOCK_SIZE);
+ return nbytes;
+}
+
+static unsigned int des3_128_decrypt_cbc(const struct cipher_desc *desc,
+ u8 *out, const u8 *in,
+ unsigned int nbytes)
+{
+ struct crypt_s390_des3_128_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES3_128_BLOCK_SIZE - 1);
+
+ memcpy(&sctx->iv, desc->info, DES3_128_BLOCK_SIZE);
+ ret = crypt_s390_kmc(KMC_TDEA_128_DECRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ return nbytes;
}
static struct crypto_alg des3_128_alg = {
@@ -156,12 +274,19 @@ static struct crypto_alg des3_128_alg = {
.cra_ctxsize = sizeof(struct crypt_s390_des3_128_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(des3_128_alg.cra_list),
- .cra_u = { .cipher = {
- .cia_min_keysize = DES3_128_KEY_SIZE,
- .cia_max_keysize = DES3_128_KEY_SIZE,
- .cia_setkey = des3_128_setkey,
- .cia_encrypt = des3_128_encrypt,
- .cia_decrypt = des3_128_decrypt } }
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = DES3_128_KEY_SIZE,
+ .cia_max_keysize = DES3_128_KEY_SIZE,
+ .cia_setkey = des3_128_setkey,
+ .cia_encrypt = des3_128_encrypt,
+ .cia_decrypt = des3_128_decrypt,
+ .cia_encrypt_ecb = des3_128_encrypt_ecb,
+ .cia_decrypt_ecb = des3_128_decrypt_ecb,
+ .cia_encrypt_cbc = des3_128_encrypt_cbc,
+ .cia_decrypt_cbc = des3_128_decrypt_cbc,
+ }
+ }
};
/*
@@ -177,50 +302,108 @@ static struct crypto_alg des3_128_alg = {
* property.
*
*/
-static int
-des3_192_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags)
+static int des3_192_setkey(void *ctx, const u8 *key, unsigned int keylen,
+ u32 *flags)
{
int i, ret;
- struct crypt_s390_des3_192_ctx *dctx;
- const u8* temp_key;
+ struct crypt_s390_des3_192_ctx *dctx = ctx;
+ const u8* temp_key = key;
- dctx = ctx;
- temp_key = key;
if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2],
- DES_KEY_SIZE))) {
+ DES_KEY_SIZE))) {
*flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED;
return -EINVAL;
}
for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) {
ret = crypto_des_check_key(temp_key, DES_KEY_SIZE, flags);
- if (ret < 0){
+ if (ret < 0)
return ret;
- }
}
memcpy(dctx->key, key, keylen);
return 0;
}
-static void
-des3_192_encrypt(void *ctx, u8 *dst, const u8 *src)
+static void des3_192_encrypt(void *ctx, u8 *dst, const u8 *src)
{
- struct crypt_s390_des3_192_ctx *dctx;
+ struct crypt_s390_des3_192_ctx *dctx = ctx;
- dctx = ctx;
crypt_s390_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src,
- DES3_192_BLOCK_SIZE);
+ DES3_192_BLOCK_SIZE);
}
-static void
-des3_192_decrypt(void *ctx, u8 *dst, const u8 *src)
+static void des3_192_decrypt(void *ctx, u8 *dst, const u8 *src)
{
- struct crypt_s390_des3_192_ctx *dctx;
+ struct crypt_s390_des3_192_ctx *dctx = ctx;
- dctx = ctx;
crypt_s390_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src,
- DES3_192_BLOCK_SIZE);
+ DES3_192_BLOCK_SIZE);
+}
+
+static unsigned int des3_192_encrypt_ecb(const struct cipher_desc *desc,
+ u8 *out, const u8 *in,
+ unsigned int nbytes)
+{
+ struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
+ ret = crypt_s390_km(KM_TDEA_192_ENCRYPT, sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ return nbytes;
+}
+
+static unsigned int des3_192_decrypt_ecb(const struct cipher_desc *desc,
+ u8 *out, const u8 *in,
+ unsigned int nbytes)
+{
+ struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
+ ret = crypt_s390_km(KM_TDEA_192_DECRYPT, sctx->key, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ return nbytes;
+}
+
+static unsigned int des3_192_encrypt_cbc(const struct cipher_desc *desc,
+ u8 *out, const u8 *in,
+ unsigned int nbytes)
+{
+ struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
+
+ memcpy(sctx->iv, desc->info, DES3_192_BLOCK_SIZE);
+ ret = crypt_s390_kmc(KMC_TDEA_192_ENCRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ memcpy(desc->info, sctx->iv, DES3_192_BLOCK_SIZE);
+ return nbytes;
+}
+
+static unsigned int des3_192_decrypt_cbc(const struct cipher_desc *desc,
+ u8 *out, const u8 *in,
+ unsigned int nbytes)
+{
+ struct crypt_s390_des3_192_ctx *sctx = crypto_tfm_ctx(desc->tfm);
+ int ret;
+
+ /* only use complete blocks */
+ nbytes &= ~(DES3_192_BLOCK_SIZE - 1);
+
+ memcpy(&sctx->iv, desc->info, DES3_192_BLOCK_SIZE);
+ ret = crypt_s390_kmc(KMC_TDEA_192_DECRYPT, &sctx->iv, out, in, nbytes);
+ BUG_ON((ret < 0) || (ret != nbytes));
+
+ return nbytes;
}
static struct crypto_alg des3_192_alg = {
@@ -230,44 +413,43 @@ static struct crypto_alg des3_192_alg = {
.cra_ctxsize = sizeof(struct crypt_s390_des3_192_ctx),
.cra_module = THIS_MODULE,
.cra_list = LIST_HEAD_INIT(des3_192_alg.cra_list),
- .cra_u = { .cipher = {
- .cia_min_keysize = DES3_192_KEY_SIZE,
- .cia_max_keysize = DES3_192_KEY_SIZE,
- .cia_setkey = des3_192_setkey,
- .cia_encrypt = des3_192_encrypt,
- .cia_decrypt = des3_192_decrypt } }
+ .cra_u = {
+ .cipher = {
+ .cia_min_keysize = DES3_192_KEY_SIZE,
+ .cia_max_keysize = DES3_192_KEY_SIZE,
+ .cia_setkey = des3_192_setkey,
+ .cia_encrypt = des3_192_encrypt,
+ .cia_decrypt = des3_192_decrypt,
+ .cia_encrypt_ecb = des3_192_encrypt_ecb,
+ .cia_decrypt_ecb = des3_192_decrypt_ecb,
+ .cia_encrypt_cbc = des3_192_encrypt_cbc,
+ .cia_decrypt_cbc = des3_192_decrypt_cbc,
+ }
+ }
};
-
-
-static int
-init(void)
+static int init(void)
{
- int ret;
+ int ret = 0;
if (!crypt_s390_func_available(KM_DEA_ENCRYPT) ||
!crypt_s390_func_available(KM_TDEA_128_ENCRYPT) ||
- !crypt_s390_func_available(KM_TDEA_192_ENCRYPT)){
+ !crypt_s390_func_available(KM_TDEA_192_ENCRYPT))
return -ENOSYS;
- }
- ret = 0;
- ret |= (crypto_register_alg(&des_alg) == 0)? 0:1;
- ret |= (crypto_register_alg(&des3_128_alg) == 0)? 0:2;
- ret |= (crypto_register_alg(&des3_192_alg) == 0)? 0:4;
- if (ret){
+ ret |= (crypto_register_alg(&des_alg) == 0) ? 0:1;
+ ret |= (crypto_register_alg(&des3_128_alg) == 0) ? 0:2;
+ ret |= (crypto_register_alg(&des3_192_alg) == 0) ? 0:4;
+ if (ret) {
crypto_unregister_alg(&des3_192_alg);
crypto_unregister_alg(&des3_128_alg);
crypto_unregister_alg(&des_alg);
return -EEXIST;
}
-
- printk(KERN_INFO "crypt_s390: des_s390 loaded.\n");
return 0;
}
-static void __exit
-fini(void)
+static void __exit fini(void)
{
crypto_unregister_alg(&des3_192_alg);
crypto_unregister_alg(&des3_128_alg);
diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c
index b75bdbd476c..1ec5e92b345 100644
--- a/arch/s390/crypto/sha256_s390.c
+++ b/arch/s390/crypto/sha256_s390.c
@@ -51,6 +51,7 @@ static void sha256_update(void *ctx, const u8 *data, unsigned int len)
{
struct s390_sha256_ctx *sctx = ctx;
unsigned int index;
+ int ret;
/* how much is already in the buffer? */
index = sctx->count / 8 & 0x3f;
@@ -58,15 +59,29 @@ static void sha256_update(void *ctx, const u8 *data, unsigned int len)
/* update message bit length */
sctx->count += len * 8;
- /* process one block */
- if ((index + len) >= SHA256_BLOCK_SIZE) {
+ if ((index + len) < SHA256_BLOCK_SIZE)
+ goto store;
+
+ /* process one stored block */
+ if (index) {
memcpy(sctx->buf + index, data, SHA256_BLOCK_SIZE - index);
- crypt_s390_kimd(KIMD_SHA_256, sctx->state, sctx->buf,
- SHA256_BLOCK_SIZE);
+ ret = crypt_s390_kimd(KIMD_SHA_256, sctx->state, sctx->buf,
+ SHA256_BLOCK_SIZE);
+ BUG_ON(ret != SHA256_BLOCK_SIZE);
data += SHA256_BLOCK_SIZE - index;
len -= SHA256_BLOCK_SIZE - index;
}
+ /* process as many blocks as possible */
+ if (len >= SHA256_BLOCK_SIZE) {
+ ret = crypt_s390_kimd(KIMD_SHA_256, sctx->state, data,
+ len & ~(SHA256_BLOCK_SIZE - 1));
+ BUG_ON(ret != (len & ~(SHA256_BLOCK_SIZE - 1)));
+ data += ret;
+ len -= ret;
+ }
+
+store:
/* anything left? */
if (len)
memcpy(sctx->buf + index , data, len);
@@ -119,9 +134,9 @@ static struct crypto_alg alg = {
.cra_list = LIST_HEAD_INIT(alg.cra_list),
.cra_u = { .digest = {
.dia_digestsize = SHA256_DIGEST_SIZE,
- .dia_init = sha256_init,
- .dia_update = sha256_update,
- .dia_final = sha256_final } }
+ .dia_init = sha256_init,
+ .dia_update = sha256_update,
+ .dia_final = sha256_final } }
};
static int init(void)
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 2ff90a1a105..008c74526fd 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -58,10 +58,18 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
*/
unsigned long thread_saved_pc(struct task_struct *tsk)
{
- struct stack_frame *sf;
+ struct stack_frame *sf, *low, *high;
- sf = (struct stack_frame *) tsk->thread.ksp;
- sf = (struct stack_frame *) sf->back_chain;
+ if (!tsk || !task_stack_page(tsk))
+ return 0;
+ low = task_stack_page(tsk);
+ high = (struct stack_frame *) task_pt_regs(tsk);
+ sf = (struct stack_frame *) (tsk->thread.ksp & PSW_ADDR_INSN);
+ if (sf <= low || sf > high)
+ return 0;
+ sf = (struct stack_frame *) (sf->back_chain & PSW_ADDR_INSN);
+ if (sf <= low || sf > high)
+ return 0;
return sf->gprs[8];
}
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index b03847d100d..de878426747 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -268,7 +268,7 @@ static void do_machine_restart_nonsmp(char * __unused)
reipl_diag();
if (MACHINE_IS_VM)
- cpcmd ("IPL", NULL, 0);
+ cpcmd ("IPL", NULL, 0, NULL);
else
reipl (0x10000 | S390_lowcore.ipl_device);
}
@@ -276,14 +276,14 @@ static void do_machine_restart_nonsmp(char * __unused)
static void do_machine_halt_nonsmp(void)
{
if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0)
- cpcmd(vmhalt_cmd, NULL, 0);
+ cpcmd(vmhalt_cmd, NULL, 0, NULL);
signal_processor(smp_processor_id(), sigp_stop_and_store_status);
}
static void do_machine_power_off_nonsmp(void)
{
if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
- cpcmd(vmpoff_cmd, NULL, 0);
+ cpcmd(vmpoff_cmd, NULL, 0, NULL);
signal_processor(smp_processor_id(), sigp_stop_and_store_status);
}
@@ -315,6 +315,11 @@ void machine_power_off(void)
_machine_power_off();
}
+/*
+ * Dummy power off function.
+ */
+void (*pm_power_off)(void) = machine_power_off;
+
static void __init
add_memory_hole(unsigned long start, unsigned long end)
{
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index b0d8ca8e5ee..7c0fe152a11 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -214,7 +214,7 @@ void account_ticks(struct pt_regs *regs)
#endif
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
- account_user_vtime(current);
+ account_tick_vtime(current);
#else
while (ticks--)
update_process_times(user_mode(regs));
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 22a895ecb7a..dfe6f085661 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -32,7 +32,7 @@ DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
* Update process times based on virtual cpu times stored by entry.S
* to the lowcore fields user_timer, system_timer & steal_clock.
*/
-void account_user_vtime(struct task_struct *tsk)
+void account_tick_vtime(struct task_struct *tsk)
{
cputime_t cputime;
__u64 timer, clock;
@@ -76,6 +76,31 @@ void account_user_vtime(struct task_struct *tsk)
* Update process times based on virtual cpu times stored by entry.S
* to the lowcore fields user_timer, system_timer & steal_clock.
*/
+void account_vtime(struct task_struct *tsk)
+{
+ cputime_t cputime;
+ __u64 timer;
+
+ timer = S390_lowcore.last_update_timer;
+ asm volatile (" STPT %0" /* Store current cpu timer value */
+ : "=m" (S390_lowcore.last_update_timer) );
+ S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer;
+
+ cputime = S390_lowcore.user_timer >> 12;
+ S390_lowcore.user_timer -= cputime << 12;
+ S390_lowcore.steal_clock -= cputime << 12;
+ account_user_time(tsk, cputime);
+
+ cputime = S390_lowcore.system_timer >> 12;
+ S390_lowcore.system_timer -= cputime << 12;
+ S390_lowcore.steal_clock -= cputime << 12;
+ account_system_time(tsk, 0, cputime);
+}
+
+/*
+ * Update process times based on virtual cpu times stored by entry.S
+ * to the lowcore fields user_timer, system_timer & steal_clock.
+ */
void account_system_vtime(struct task_struct *tsk)
{
cputime_t cputime;
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index d9b97b3c597..f20b51ff1d8 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -4,5 +4,6 @@
EXTRA_AFLAGS := -traditional
-lib-y += delay.o string.o spinlock.o
+lib-y += delay.o string.o
lib-y += $(if $(CONFIG_64BIT),uaccess64.o,uaccess.o)
+lib-$(CONFIG_SMP) += spinlock.o \ No newline at end of file
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c
index 68d79c50208..60f80a4eed4 100644
--- a/arch/s390/lib/spinlock.c
+++ b/arch/s390/lib/spinlock.c
@@ -13,7 +13,6 @@
#include <linux/init.h>
#include <asm/io.h>
-atomic_t spin_retry_counter;
int spin_retry = 1000;
/**
@@ -45,7 +44,6 @@ _raw_spin_lock_wait(raw_spinlock_t *lp, unsigned int pc)
_diag44();
count = spin_retry;
}
- atomic_inc(&spin_retry_counter);
if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0)
return;
}
@@ -58,7 +56,6 @@ _raw_spin_trylock_retry(raw_spinlock_t *lp, unsigned int pc)
int count = spin_retry;
while (count-- > 0) {
- atomic_inc(&spin_retry_counter);
if (_raw_compare_and_swap(&lp->lock, 0, pc) == 0)
return 1;
}
@@ -77,7 +74,6 @@ _raw_read_lock_wait(raw_rwlock_t *rw)
_diag44();
count = spin_retry;
}
- atomic_inc(&spin_retry_counter);
old = rw->lock & 0x7fffffffU;
if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old)
return;
@@ -92,7 +88,6 @@ _raw_read_trylock_retry(raw_rwlock_t *rw)
int count = spin_retry;
while (count-- > 0) {
- atomic_inc(&spin_retry_counter);
old = rw->lock & 0x7fffffffU;
if (_raw_compare_and_swap(&rw->lock, old, old + 1) == old)
return 1;
@@ -111,7 +106,6 @@ _raw_write_lock_wait(raw_rwlock_t *rw)
_diag44();
count = spin_retry;
}
- atomic_inc(&spin_retry_counter);
if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)
return;
}
@@ -124,7 +118,6 @@ _raw_write_trylock_retry(raw_rwlock_t *rw)
int count = spin_retry;
while (count-- > 0) {
- atomic_inc(&spin_retry_counter);
if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)
return 1;
}