summaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/Kconfig5
-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/Makefile3
-rw-r--r--arch/s390/kernel/binfmt_elf32.c2
-rw-r--r--arch/s390/kernel/compat_ioctl.c81
-rw-r--r--arch/s390/kernel/compat_linux.c33
-rw-r--r--arch/s390/kernel/compat_wrapper.S2
-rw-r--r--arch/s390/kernel/crash.c2
-rw-r--r--arch/s390/kernel/process.c47
-rw-r--r--arch/s390/kernel/ptrace.c55
-rw-r--r--arch/s390/kernel/s390_ksyms.c1
-rw-r--r--arch/s390/kernel/setup.c11
-rw-r--r--arch/s390/kernel/smp.c2
-rw-r--r--arch/s390/kernel/time.c4
-rw-r--r--arch/s390/kernel/traps.c6
-rw-r--r--arch/s390/kernel/vtime.c27
-rw-r--r--arch/s390/lib/Makefile3
-rw-r--r--arch/s390/lib/spinlock.c7
20 files changed, 418 insertions, 322 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 6fe532d82417..b66602ad7b33 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -27,11 +27,6 @@ config S390
bool
default y
-config UID16
- bool
- default y
- depends on !64BIT
-
source "init/Kconfig"
menu "Base setup"
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c
index 7a1033d8e00f..c5ca2dc5d428 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 a38bb2a3eef6..e3c37aa0a199 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 b75bdbd476c7..1ec5e92b3454 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/Makefile b/arch/s390/kernel/Makefile
index 4865e4b49464..9269b5788fac 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -17,8 +17,7 @@ obj-$(CONFIG_MODULES) += s390_ksyms.o module.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \
- compat_ioctl.o compat_wrapper.o \
- compat_exec_domain.o
+ compat_wrapper.o compat_exec_domain.o
obj-$(CONFIG_BINFMT_ELF32) += binfmt_elf32.o
obj-$(CONFIG_VIRT_TIMER) += vtime.o
diff --git a/arch/s390/kernel/binfmt_elf32.c b/arch/s390/kernel/binfmt_elf32.c
index 03ba5893f17b..1f451c2cb071 100644
--- a/arch/s390/kernel/binfmt_elf32.c
+++ b/arch/s390/kernel/binfmt_elf32.c
@@ -112,7 +112,7 @@ static inline int dump_regs32(struct pt_regs *ptregs, elf_gregset_t *regs)
static inline int dump_task_regs32(struct task_struct *tsk, elf_gregset_t *regs)
{
- struct pt_regs *ptregs = __KSTK_PTREGS(tsk);
+ struct pt_regs *ptregs = task_pt_regs(tsk);
int i;
memcpy(&regs->psw.mask, &ptregs->psw.mask, 4);
diff --git a/arch/s390/kernel/compat_ioctl.c b/arch/s390/kernel/compat_ioctl.c
deleted file mode 100644
index 6504c4e69986..000000000000
--- a/arch/s390/kernel/compat_ioctl.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
- *
- * S390 version
- * Copyright (C) 2000-2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Gerhard Tonn (ton@de.ibm.com)
- * Arnd Bergmann (arndb@de.ibm.com)
- *
- * Original implementation from 32-bit Sparc compat code which is
- * Copyright (C) 2000 Silicon Graphics, Inc.
- * Written by Ulf Carlsson (ulfc@engr.sgi.com)
- */
-
-#include "compat_linux.h"
-#define INCLUDES
-#define CODE
-#include "../../../fs/compat_ioctl.c"
-#include <asm/dasd.h>
-#include <asm/cmb.h>
-#include <asm/tape390.h>
-#include <asm/ccwdev.h>
-#include "../../../drivers/s390/char/raw3270.h"
-
-static int do_ioctl32_pointer(unsigned int fd, unsigned int cmd,
- unsigned long arg, struct file *f)
-{
- return sys_ioctl(fd, cmd, (unsigned long)compat_ptr(arg));
-}
-
-static int do_ioctl32_ulong(unsigned int fd, unsigned int cmd,
- unsigned long arg, struct file *f)
-{
- return sys_ioctl(fd, cmd, arg);
-}
-
-#define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)do_ioctl32_pointer)
-#define ULONG_IOCTL(cmd) HANDLE_IOCTL((cmd),(ioctl_trans_handler_t)do_ioctl32_ulong)
-#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler), NULL },
-
-struct ioctl_trans ioctl_start[] = {
-/* architecture independent ioctls */
-#include <linux/compat_ioctl.h>
-#define DECLARES
-#include "../../../fs/compat_ioctl.c"
-
-/* s390 only ioctls */
-COMPATIBLE_IOCTL(DASDAPIVER)
-COMPATIBLE_IOCTL(BIODASDDISABLE)
-COMPATIBLE_IOCTL(BIODASDENABLE)
-COMPATIBLE_IOCTL(BIODASDRSRV)
-COMPATIBLE_IOCTL(BIODASDRLSE)
-COMPATIBLE_IOCTL(BIODASDSLCK)
-COMPATIBLE_IOCTL(BIODASDINFO)
-COMPATIBLE_IOCTL(BIODASDINFO2)
-COMPATIBLE_IOCTL(BIODASDFMT)
-COMPATIBLE_IOCTL(BIODASDPRRST)
-COMPATIBLE_IOCTL(BIODASDQUIESCE)
-COMPATIBLE_IOCTL(BIODASDRESUME)
-COMPATIBLE_IOCTL(BIODASDPRRD)
-COMPATIBLE_IOCTL(BIODASDPSRD)
-COMPATIBLE_IOCTL(BIODASDGATTR)
-COMPATIBLE_IOCTL(BIODASDSATTR)
-COMPATIBLE_IOCTL(BIODASDCMFENABLE)
-COMPATIBLE_IOCTL(BIODASDCMFDISABLE)
-COMPATIBLE_IOCTL(BIODASDREADALLCMB)
-
-COMPATIBLE_IOCTL(TUBICMD)
-COMPATIBLE_IOCTL(TUBOCMD)
-COMPATIBLE_IOCTL(TUBGETI)
-COMPATIBLE_IOCTL(TUBGETO)
-COMPATIBLE_IOCTL(TUBSETMOD)
-COMPATIBLE_IOCTL(TUBGETMOD)
-
-COMPATIBLE_IOCTL(TAPE390_DISPLAY)
-
-/* s390 doesn't need handlers here */
-COMPATIBLE_IOCTL(TIOCGSERIAL)
-COMPATIBLE_IOCTL(TIOCSSERIAL)
-};
-
-int ioctl_table_size = ARRAY_SIZE(ioctl_start);
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 41b197a3f3a3..bf9a7a361b34 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -55,6 +55,7 @@
#include <linux/syscalls.h>
#include <linux/sysctl.h>
#include <linux/binfmts.h>
+#include <linux/capability.h>
#include <linux/compat.h>
#include <linux/vfs.h>
#include <linux/ptrace.h>
@@ -1014,38 +1015,6 @@ asmlinkage long sys32_clone(struct pt_regs regs)
}
/*
- * Wrapper function for sys_timer_create.
- */
-extern asmlinkage long
-sys_timer_create(clockid_t, struct sigevent *, timer_t *);
-
-asmlinkage long
-sys32_timer_create(clockid_t which_clock, struct compat_sigevent *se32,
- timer_t *timer_id)
-{
- struct sigevent se;
- timer_t ktimer_id;
- mm_segment_t old_fs;
- long ret;
-
- if (se32 == NULL)
- return sys_timer_create(which_clock, NULL, timer_id);
-
- if (get_compat_sigevent(&se, se32))
- return -EFAULT;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- ret = sys_timer_create(which_clock, &se, &ktimer_id);
- set_fs(old_fs);
-
- if (!ret)
- ret = put_user (ktimer_id, timer_id);
-
- return ret;
-}
-
-/*
* 31 bit emulation wrapper functions for sys_fadvise64/fadvise64_64.
* These need to rewrite the advise values for POSIX_FADV_{DONTNEED,NOREUSE}
* because the 31 bit values differ from the 64 bit values.
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 23fe94e58688..cfde1905d07d 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -1289,7 +1289,7 @@ sys32_timer_create_wrapper:
lgfr %r2,%r2 # timer_t (int)
llgtr %r3,%r3 # struct compat_sigevent *
llgtr %r4,%r4 # timer_t *
- jg sys32_timer_create
+ jg compat_sys_timer_create
.globl sys32_timer_settime_wrapper
sys32_timer_settime_wrapper:
diff --git a/arch/s390/kernel/crash.c b/arch/s390/kernel/crash.c
index 7bd169c58b0c..926cceeae0fa 100644
--- a/arch/s390/kernel/crash.c
+++ b/arch/s390/kernel/crash.c
@@ -10,8 +10,6 @@
#include <linux/threads.h>
#include <linux/kexec.h>
-note_buf_t crash_notes[NR_CPUS];
-
void machine_crash_shutdown(struct pt_regs *regs)
{
}
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index a942bf2d58e9..008c74526fd3 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];
}
@@ -153,7 +161,7 @@ void show_regs(struct pt_regs *regs)
{
struct task_struct *tsk = current;
- printk("CPU: %d %s\n", tsk->thread_info->cpu, print_tainted());
+ printk("CPU: %d %s\n", task_thread_info(tsk)->cpu, print_tainted());
printk("Process %s (pid: %d, task: %p, ksp: %p)\n",
current->comm, current->pid, (void *) tsk,
(void *) tsk->thread.ksp);
@@ -217,8 +225,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
struct pt_regs childregs;
} *frame;
- frame = ((struct fake_frame *)
- (THREAD_SIZE + (unsigned long) p->thread_info)) - 1;
+ frame = container_of(task_pt_regs(p), struct fake_frame, childregs);
p->thread.ksp = (unsigned long) frame;
/* Store access registers to kernel stack of new process. */
frame->childregs = *regs;
@@ -352,38 +359,16 @@ int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs)
return 1;
}
-/*
- * fill in the user structure for a core dump..
- */
-void dump_thread(struct pt_regs * regs, struct user * dump)
-{
-
-/* changed the size calculations - should hopefully work better. lbt */
- dump->magic = CMAGIC;
- dump->start_code = 0;
- dump->start_stack = regs->gprs[15] & ~(PAGE_SIZE - 1);
- dump->u_tsize = current->mm->end_code >> PAGE_SHIFT;
- dump->u_dsize = (current->mm->brk + PAGE_SIZE - 1) >> PAGE_SHIFT;
- dump->u_dsize -= dump->u_tsize;
- dump->u_ssize = 0;
- if (dump->start_stack < TASK_SIZE)
- dump->u_ssize = (TASK_SIZE - dump->start_stack) >> PAGE_SHIFT;
- memcpy(&dump->regs, regs, sizeof(s390_regs));
- dump_fpu (regs, &dump->regs.fp_regs);
- dump->regs.per_info = current->thread.per_info;
-}
-
unsigned long get_wchan(struct task_struct *p)
{
struct stack_frame *sf, *low, *high;
unsigned long return_address;
int count;
- if (!p || p == current || p->state == TASK_RUNNING || !p->thread_info)
+ if (!p || p == current || p->state == TASK_RUNNING || !task_stack_page(p))
return 0;
- low = (struct stack_frame *) p->thread_info;
- high = (struct stack_frame *)
- ((unsigned long) p->thread_info + THREAD_SIZE) - 1;
+ low = task_stack_page(p);
+ high = (struct stack_frame *) task_pt_regs(p);
sf = (struct stack_frame *) (p->thread.ksp & PSW_ADDR_INSN);
if (sf <= low || sf > high)
return 0;
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 8ecda6d66de4..37dfe33dab73 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -52,7 +52,7 @@ FixPerRegisters(struct task_struct *task)
struct pt_regs *regs;
per_struct *per_info;
- regs = __KSTK_PTREGS(task);
+ regs = task_pt_regs(task);
per_info = (per_struct *) &task->thread.per_info;
per_info->control_regs.bits.em_instruction_fetch =
per_info->single_step | per_info->instruction_fetch;
@@ -150,7 +150,7 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data)
/*
* psw and gprs are stored on the stack
*/
- tmp = *(addr_t *)((addr_t) &__KSTK_PTREGS(child)->psw + addr);
+ tmp = *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr);
if (addr == (addr_t) &dummy->regs.psw.mask)
/* Remove per bit from user psw. */
tmp &= ~PSW_MASK_PER;
@@ -176,7 +176,7 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data)
/*
* orig_gpr2 is stored on the kernel stack
*/
- tmp = (addr_t) __KSTK_PTREGS(child)->orig_gpr2;
+ tmp = (addr_t) task_pt_regs(child)->orig_gpr2;
} else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
/*
@@ -243,7 +243,7 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
high order bit but older gdb's rely on it */
data |= PSW_ADDR_AMODE;
#endif
- *(addr_t *)((addr_t) &__KSTK_PTREGS(child)->psw + addr) = data;
+ *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data;
} else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) {
/*
@@ -267,7 +267,7 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
/*
* orig_gpr2 is stored on the kernel stack
*/
- __KSTK_PTREGS(child)->orig_gpr2 = data;
+ task_pt_regs(child)->orig_gpr2 = data;
} else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
/*
@@ -393,15 +393,15 @@ peek_user_emu31(struct task_struct *child, addr_t addr, addr_t data)
*/
if (addr == (addr_t) &dummy32->regs.psw.mask) {
/* Fake a 31 bit psw mask. */
- tmp = (__u32)(__KSTK_PTREGS(child)->psw.mask >> 32);
+ tmp = (__u32)(task_pt_regs(child)->psw.mask >> 32);
tmp = PSW32_MASK_MERGE(PSW32_USER_BITS, tmp);
} else if (addr == (addr_t) &dummy32->regs.psw.addr) {
/* Fake a 31 bit psw address. */
- tmp = (__u32) __KSTK_PTREGS(child)->psw.addr |
+ tmp = (__u32) task_pt_regs(child)->psw.addr |
PSW32_ADDR_AMODE31;
} else {
/* gpr 0-15 */
- tmp = *(__u32 *)((addr_t) &__KSTK_PTREGS(child)->psw +
+ tmp = *(__u32 *)((addr_t) &task_pt_regs(child)->psw +
addr*2 + 4);
}
} else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
@@ -415,7 +415,7 @@ peek_user_emu31(struct task_struct *child, addr_t addr, addr_t data)
/*
* orig_gpr2 is stored on the kernel stack
*/
- tmp = *(__u32*)((addr_t) &__KSTK_PTREGS(child)->orig_gpr2 + 4);
+ tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4);
} else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
/*
@@ -472,15 +472,15 @@ poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data)
if (tmp != PSW32_MASK_MERGE(PSW32_USER_BITS, tmp))
/* Invalid psw mask. */
return -EINVAL;
- __KSTK_PTREGS(child)->psw.mask =
+ task_pt_regs(child)->psw.mask =
PSW_MASK_MERGE(PSW_USER32_BITS, (__u64) tmp << 32);
} else if (addr == (addr_t) &dummy32->regs.psw.addr) {
/* Build a 64 bit psw address from 31 bit address. */
- __KSTK_PTREGS(child)->psw.addr =
+ task_pt_regs(child)->psw.addr =
(__u64) tmp & PSW32_ADDR_INSN;
} else {
/* gpr 0-15 */
- *(__u32*)((addr_t) &__KSTK_PTREGS(child)->psw
+ *(__u32*)((addr_t) &task_pt_regs(child)->psw
+ addr*2 + 4) = tmp;
}
} else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) {
@@ -494,7 +494,7 @@ poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data)
/*
* orig_gpr2 is stored on the kernel stack
*/
- *(__u32*)((addr_t) &__KSTK_PTREGS(child)->orig_gpr2 + 4) = tmp;
+ *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp;
} else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
/*
@@ -712,35 +712,18 @@ sys_ptrace(long request, long pid, long addr, long data)
int ret;
lock_kernel();
-
if (request == PTRACE_TRACEME) {
- /* are we already being traced? */
- ret = -EPERM;
- if (current->ptrace & PT_PTRACED)
- goto out;
- ret = security_ptrace(current->parent, current);
- if (ret)
- goto out;
- /* set the ptrace bit in the process flags. */
- current->ptrace |= PT_PTRACED;
- goto out;
+ ret = ptrace_traceme();
+ goto out;
}
- ret = -EPERM;
- if (pid == 1) /* you may not mess with init */
- goto out;
-
- ret = -ESRCH;
- read_lock(&tasklist_lock);
- child = find_task_by_pid(pid);
- if (child)
- get_task_struct(child);
- read_unlock(&tasklist_lock);
- if (!child)
+ child = ptrace_get_task_struct(pid);
+ if (IS_ERR(child)) {
+ ret = PTR_ERR(child);
goto out;
+ }
ret = do_ptrace(child, request, addr, data);
-
put_task_struct(child);
out:
unlock_kernel();
diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c
index bee654abb6d3..4176c77670c4 100644
--- a/arch/s390/kernel/s390_ksyms.c
+++ b/arch/s390/kernel/s390_ksyms.c
@@ -10,7 +10,6 @@
#include <linux/smp.h>
#include <linux/syscalls.h>
#include <linux/interrupt.h>
-#include <linux/ioctl32.h>
#include <asm/checksum.h>
#include <asm/cpcmd.h>
#include <asm/delay.h>
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index b03847d100d9..de8784267473 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/smp.c b/arch/s390/kernel/smp.c
index e10f4ca00499..cbfcfd02a43a 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -657,7 +657,7 @@ __cpu_up(unsigned int cpu)
idle = current_set[cpu];
cpu_lowcore = lowcore_ptr[cpu];
cpu_lowcore->kernel_stack = (unsigned long)
- idle->thread_info + (THREAD_SIZE);
+ task_stack_page(idle) + (THREAD_SIZE);
sf = (struct stack_frame *) (cpu_lowcore->kernel_stack
- sizeof(struct pt_regs)
- sizeof(struct stack_frame));
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index c36353e8c140..7c0fe152a111 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));
@@ -282,7 +282,7 @@ static inline void start_hz_timer(void)
{
if (!cpu_isset(smp_processor_id(), nohz_cpu_mask))
return;
- account_ticks(__KSTK_PTREGS(current));
+ account_ticks(task_pt_regs(current));
cpu_clear(smp_processor_id(), nohz_cpu_mask);
}
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 95d109968619..5d21e9e6e7b4 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -136,8 +136,8 @@ void show_trace(struct task_struct *task, unsigned long * stack)
sp = __show_trace(sp, S390_lowcore.async_stack - ASYNC_SIZE,
S390_lowcore.async_stack);
if (task)
- __show_trace(sp, (unsigned long) task->thread_info,
- (unsigned long) task->thread_info + THREAD_SIZE);
+ __show_trace(sp, (unsigned long) task_stack_page(task),
+ (unsigned long) task_stack_page(task) + THREAD_SIZE);
else
__show_trace(sp, S390_lowcore.thread_info,
S390_lowcore.thread_info + THREAD_SIZE);
@@ -240,7 +240,7 @@ char *task_show_regs(struct task_struct *task, char *buffer)
{
struct pt_regs *regs;
- regs = __KSTK_PTREGS(task);
+ regs = task_pt_regs(task);
buffer += sprintf(buffer, "task: %p, ksp: %p\n",
task, (void *)task->thread.ksp);
buffer += sprintf(buffer, "User PSW : %p %p\n",
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 22a895ecb7a4..dfe6f0856617 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 d9b97b3c597f..f20b51ff1d86 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 68d79c502081..60f80a4eed4e 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;
}
OpenPOWER on IntegriCloud