diff options
Diffstat (limited to 'arch/s390')
59 files changed, 1772 insertions, 836 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 2ae5d72f47ed..1c866efd217d 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
| @@ -84,7 +84,7 @@ config S390 | |||
| 84 | select HAVE_FUNCTION_TRACER | 84 | select HAVE_FUNCTION_TRACER |
| 85 | select HAVE_FUNCTION_TRACE_MCOUNT_TEST | 85 | select HAVE_FUNCTION_TRACE_MCOUNT_TEST |
| 86 | select HAVE_FTRACE_MCOUNT_RECORD | 86 | select HAVE_FTRACE_MCOUNT_RECORD |
| 87 | select HAVE_FTRACE_SYSCALLS | 87 | select HAVE_SYSCALL_TRACEPOINTS |
| 88 | select HAVE_DYNAMIC_FTRACE | 88 | select HAVE_DYNAMIC_FTRACE |
| 89 | select HAVE_FUNCTION_GRAPH_TRACER | 89 | select HAVE_FUNCTION_GRAPH_TRACER |
| 90 | select HAVE_DEFAULT_NO_SPIN_MUTEXES | 90 | select HAVE_DEFAULT_NO_SPIN_MUTEXES |
| @@ -95,7 +95,6 @@ config S390 | |||
| 95 | select HAVE_ARCH_TRACEHOOK | 95 | select HAVE_ARCH_TRACEHOOK |
| 96 | select INIT_ALL_POSSIBLE | 96 | select INIT_ALL_POSSIBLE |
| 97 | select HAVE_PERF_COUNTERS | 97 | select HAVE_PERF_COUNTERS |
| 98 | select GENERIC_ATOMIC64 if !64BIT | ||
| 99 | 98 | ||
| 100 | config SCHED_OMIT_FRAME_POINTER | 99 | config SCHED_OMIT_FRAME_POINTER |
| 101 | bool | 100 | bool |
| @@ -481,13 +480,6 @@ config CMM_IUCV | |||
| 481 | Select this option to enable the special message interface to | 480 | Select this option to enable the special message interface to |
| 482 | the cooperative memory management. | 481 | the cooperative memory management. |
| 483 | 482 | ||
| 484 | config PAGE_STATES | ||
| 485 | bool "Unused page notification" | ||
| 486 | help | ||
| 487 | This enables the notification of unused pages to the | ||
| 488 | hypervisor. The ESSA instruction is used to do the states | ||
| 489 | changes between a page that has content and the unused state. | ||
| 490 | |||
| 491 | config APPLDATA_BASE | 483 | config APPLDATA_BASE |
| 492 | bool "Linux - VM Monitor Stream, base infrastructure" | 484 | bool "Linux - VM Monitor Stream, base infrastructure" |
| 493 | depends on PROC_FS | 485 | depends on PROC_FS |
diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 0ff387cebf88..fc8fb20e7fc0 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile | |||
| @@ -88,8 +88,7 @@ LDFLAGS_vmlinux := -e start | |||
| 88 | head-y := arch/s390/kernel/head.o arch/s390/kernel/init_task.o | 88 | head-y := arch/s390/kernel/head.o arch/s390/kernel/init_task.o |
| 89 | 89 | ||
| 90 | core-y += arch/s390/mm/ arch/s390/kernel/ arch/s390/crypto/ \ | 90 | core-y += arch/s390/mm/ arch/s390/kernel/ arch/s390/crypto/ \ |
| 91 | arch/s390/appldata/ arch/s390/hypfs/ arch/s390/kvm/ \ | 91 | arch/s390/appldata/ arch/s390/hypfs/ arch/s390/kvm/ |
| 92 | arch/s390/power/ | ||
| 93 | 92 | ||
| 94 | libs-y += arch/s390/lib/ | 93 | libs-y += arch/s390/lib/ |
| 95 | drivers-y += drivers/s390/ | 94 | drivers-y += drivers/s390/ |
diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c index 4aba83b31596..2bc479ab3a66 100644 --- a/arch/s390/crypto/des_s390.c +++ b/arch/s390/crypto/des_s390.c | |||
| @@ -250,8 +250,9 @@ static int des3_128_setkey(struct crypto_tfm *tfm, const u8 *key, | |||
| 250 | const u8 *temp_key = key; | 250 | const u8 *temp_key = key; |
| 251 | u32 *flags = &tfm->crt_flags; | 251 | u32 *flags = &tfm->crt_flags; |
| 252 | 252 | ||
| 253 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE))) { | 253 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE)) && |
| 254 | *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; | 254 | (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) { |
| 255 | *flags |= CRYPTO_TFM_RES_WEAK_KEY; | ||
| 255 | return -EINVAL; | 256 | return -EINVAL; |
| 256 | } | 257 | } |
| 257 | for (i = 0; i < 2; i++, temp_key += DES_KEY_SIZE) { | 258 | for (i = 0; i < 2; i++, temp_key += DES_KEY_SIZE) { |
| @@ -411,9 +412,9 @@ static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key, | |||
| 411 | 412 | ||
| 412 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && | 413 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && |
| 413 | memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], | 414 | memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], |
| 414 | DES_KEY_SIZE))) { | 415 | DES_KEY_SIZE)) && |
| 415 | 416 | (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) { | |
| 416 | *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; | 417 | *flags |= CRYPTO_TFM_RES_WEAK_KEY; |
| 417 | return -EINVAL; | 418 | return -EINVAL; |
| 418 | } | 419 | } |
| 419 | for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) { | 420 | for (i = 0; i < 3; i++, temp_key += DES_KEY_SIZE) { |
diff --git a/arch/s390/crypto/sha1_s390.c b/arch/s390/crypto/sha1_s390.c index e85ba348722a..f6de7826c979 100644 --- a/arch/s390/crypto/sha1_s390.c +++ b/arch/s390/crypto/sha1_s390.c | |||
| @@ -46,12 +46,38 @@ static int sha1_init(struct shash_desc *desc) | |||
| 46 | return 0; | 46 | return 0; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | static int sha1_export(struct shash_desc *desc, void *out) | ||
| 50 | { | ||
| 51 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
| 52 | struct sha1_state *octx = out; | ||
| 53 | |||
| 54 | octx->count = sctx->count; | ||
| 55 | memcpy(octx->state, sctx->state, sizeof(octx->state)); | ||
| 56 | memcpy(octx->buffer, sctx->buf, sizeof(octx->buffer)); | ||
| 57 | return 0; | ||
| 58 | } | ||
| 59 | |||
| 60 | static int sha1_import(struct shash_desc *desc, const void *in) | ||
| 61 | { | ||
| 62 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
| 63 | const struct sha1_state *ictx = in; | ||
| 64 | |||
| 65 | sctx->count = ictx->count; | ||
| 66 | memcpy(sctx->state, ictx->state, sizeof(ictx->state)); | ||
| 67 | memcpy(sctx->buf, ictx->buffer, sizeof(ictx->buffer)); | ||
| 68 | sctx->func = KIMD_SHA_1; | ||
| 69 | return 0; | ||
| 70 | } | ||
| 71 | |||
| 49 | static struct shash_alg alg = { | 72 | static struct shash_alg alg = { |
| 50 | .digestsize = SHA1_DIGEST_SIZE, | 73 | .digestsize = SHA1_DIGEST_SIZE, |
| 51 | .init = sha1_init, | 74 | .init = sha1_init, |
| 52 | .update = s390_sha_update, | 75 | .update = s390_sha_update, |
| 53 | .final = s390_sha_final, | 76 | .final = s390_sha_final, |
| 77 | .export = sha1_export, | ||
| 78 | .import = sha1_import, | ||
| 54 | .descsize = sizeof(struct s390_sha_ctx), | 79 | .descsize = sizeof(struct s390_sha_ctx), |
| 80 | .statesize = sizeof(struct sha1_state), | ||
| 55 | .base = { | 81 | .base = { |
| 56 | .cra_name = "sha1", | 82 | .cra_name = "sha1", |
| 57 | .cra_driver_name= "sha1-s390", | 83 | .cra_driver_name= "sha1-s390", |
diff --git a/arch/s390/crypto/sha256_s390.c b/arch/s390/crypto/sha256_s390.c index f9fefc569632..61a7db372121 100644 --- a/arch/s390/crypto/sha256_s390.c +++ b/arch/s390/crypto/sha256_s390.c | |||
| @@ -42,12 +42,38 @@ static int sha256_init(struct shash_desc *desc) | |||
| 42 | return 0; | 42 | return 0; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | static int sha256_export(struct shash_desc *desc, void *out) | ||
| 46 | { | ||
| 47 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
| 48 | struct sha256_state *octx = out; | ||
| 49 | |||
| 50 | octx->count = sctx->count; | ||
| 51 | memcpy(octx->state, sctx->state, sizeof(octx->state)); | ||
| 52 | memcpy(octx->buf, sctx->buf, sizeof(octx->buf)); | ||
| 53 | return 0; | ||
| 54 | } | ||
| 55 | |||
| 56 | static int sha256_import(struct shash_desc *desc, const void *in) | ||
| 57 | { | ||
| 58 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
| 59 | const struct sha256_state *ictx = in; | ||
| 60 | |||
| 61 | sctx->count = ictx->count; | ||
| 62 | memcpy(sctx->state, ictx->state, sizeof(ictx->state)); | ||
| 63 | memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf)); | ||
| 64 | sctx->func = KIMD_SHA_256; | ||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | |||
| 45 | static struct shash_alg alg = { | 68 | static struct shash_alg alg = { |
| 46 | .digestsize = SHA256_DIGEST_SIZE, | 69 | .digestsize = SHA256_DIGEST_SIZE, |
| 47 | .init = sha256_init, | 70 | .init = sha256_init, |
| 48 | .update = s390_sha_update, | 71 | .update = s390_sha_update, |
| 49 | .final = s390_sha_final, | 72 | .final = s390_sha_final, |
| 73 | .export = sha256_export, | ||
| 74 | .import = sha256_import, | ||
| 50 | .descsize = sizeof(struct s390_sha_ctx), | 75 | .descsize = sizeof(struct s390_sha_ctx), |
| 76 | .statesize = sizeof(struct sha256_state), | ||
| 51 | .base = { | 77 | .base = { |
| 52 | .cra_name = "sha256", | 78 | .cra_name = "sha256", |
| 53 | .cra_driver_name= "sha256-s390", | 79 | .cra_driver_name= "sha256-s390", |
diff --git a/arch/s390/crypto/sha512_s390.c b/arch/s390/crypto/sha512_s390.c index 83192bfc8048..4bf73d0dc525 100644 --- a/arch/s390/crypto/sha512_s390.c +++ b/arch/s390/crypto/sha512_s390.c | |||
| @@ -13,7 +13,10 @@ | |||
| 13 | * | 13 | * |
| 14 | */ | 14 | */ |
| 15 | #include <crypto/internal/hash.h> | 15 | #include <crypto/internal/hash.h> |
| 16 | #include <crypto/sha.h> | ||
| 17 | #include <linux/errno.h> | ||
| 16 | #include <linux/init.h> | 18 | #include <linux/init.h> |
| 19 | #include <linux/kernel.h> | ||
| 17 | #include <linux/module.h> | 20 | #include <linux/module.h> |
| 18 | 21 | ||
| 19 | #include "sha.h" | 22 | #include "sha.h" |
| @@ -37,12 +40,42 @@ static int sha512_init(struct shash_desc *desc) | |||
| 37 | return 0; | 40 | return 0; |
| 38 | } | 41 | } |
| 39 | 42 | ||
| 43 | static int sha512_export(struct shash_desc *desc, void *out) | ||
| 44 | { | ||
| 45 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
| 46 | struct sha512_state *octx = out; | ||
| 47 | |||
| 48 | octx->count[0] = sctx->count; | ||
| 49 | octx->count[1] = 0; | ||
| 50 | memcpy(octx->state, sctx->state, sizeof(octx->state)); | ||
| 51 | memcpy(octx->buf, sctx->buf, sizeof(octx->buf)); | ||
| 52 | return 0; | ||
| 53 | } | ||
| 54 | |||
| 55 | static int sha512_import(struct shash_desc *desc, const void *in) | ||
| 56 | { | ||
| 57 | struct s390_sha_ctx *sctx = shash_desc_ctx(desc); | ||
| 58 | const struct sha512_state *ictx = in; | ||
| 59 | |||
| 60 | if (unlikely(ictx->count[1])) | ||
| 61 | return -ERANGE; | ||
| 62 | sctx->count = ictx->count[0]; | ||
| 63 | |||
| 64 | memcpy(sctx->state, ictx->state, sizeof(ictx->state)); | ||
| 65 | memcpy(sctx->buf, ictx->buf, sizeof(ictx->buf)); | ||
| 66 | sctx->func = KIMD_SHA_512; | ||
| 67 | return 0; | ||
| 68 | } | ||
| 69 | |||
| 40 | static struct shash_alg sha512_alg = { | 70 | static struct shash_alg sha512_alg = { |
| 41 | .digestsize = SHA512_DIGEST_SIZE, | 71 | .digestsize = SHA512_DIGEST_SIZE, |
| 42 | .init = sha512_init, | 72 | .init = sha512_init, |
| 43 | .update = s390_sha_update, | 73 | .update = s390_sha_update, |
| 44 | .final = s390_sha_final, | 74 | .final = s390_sha_final, |
| 75 | .export = sha512_export, | ||
| 76 | .import = sha512_import, | ||
| 45 | .descsize = sizeof(struct s390_sha_ctx), | 77 | .descsize = sizeof(struct s390_sha_ctx), |
| 78 | .statesize = sizeof(struct sha512_state), | ||
| 46 | .base = { | 79 | .base = { |
| 47 | .cra_name = "sha512", | 80 | .cra_name = "sha512", |
| 48 | .cra_driver_name= "sha512-s390", | 81 | .cra_driver_name= "sha512-s390", |
| @@ -78,7 +111,10 @@ static struct shash_alg sha384_alg = { | |||
| 78 | .init = sha384_init, | 111 | .init = sha384_init, |
| 79 | .update = s390_sha_update, | 112 | .update = s390_sha_update, |
| 80 | .final = s390_sha_final, | 113 | .final = s390_sha_final, |
| 114 | .export = sha512_export, | ||
| 115 | .import = sha512_import, | ||
| 81 | .descsize = sizeof(struct s390_sha_ctx), | 116 | .descsize = sizeof(struct s390_sha_ctx), |
| 117 | .statesize = sizeof(struct sha512_state), | ||
| 82 | .base = { | 118 | .base = { |
| 83 | .cra_name = "sha384", | 119 | .cra_name = "sha384", |
| 84 | .cra_driver_name= "sha384-s390", | 120 | .cra_driver_name= "sha384-s390", |
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index fcba206529f3..4e91a2573cc4 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
| @@ -900,7 +900,7 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y | |||
| 900 | CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y | 900 | CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y |
| 901 | CONFIG_HAVE_DYNAMIC_FTRACE=y | 901 | CONFIG_HAVE_DYNAMIC_FTRACE=y |
| 902 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y | 902 | CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y |
| 903 | CONFIG_HAVE_FTRACE_SYSCALLS=y | 903 | CONFIG_HAVE_SYSCALL_TRACEPOINTS=y |
| 904 | CONFIG_TRACING_SUPPORT=y | 904 | CONFIG_TRACING_SUPPORT=y |
| 905 | CONFIG_FTRACE=y | 905 | CONFIG_FTRACE=y |
| 906 | # CONFIG_FUNCTION_TRACER is not set | 906 | # CONFIG_FUNCTION_TRACER is not set |
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index 5a805df216bb..bd9914b89488 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c | |||
| @@ -355,11 +355,7 @@ static struct dentry *hypfs_create_file(struct super_block *sb, | |||
| 355 | { | 355 | { |
| 356 | struct dentry *dentry; | 356 | struct dentry *dentry; |
| 357 | struct inode *inode; | 357 | struct inode *inode; |
| 358 | struct qstr qname; | ||
| 359 | 358 | ||
| 360 | qname.name = name; | ||
| 361 | qname.len = strlen(name); | ||
| 362 | qname.hash = full_name_hash(name, qname.len); | ||
| 363 | mutex_lock(&parent->d_inode->i_mutex); | 359 | mutex_lock(&parent->d_inode->i_mutex); |
| 364 | dentry = lookup_one_len(name, parent, strlen(name)); | 360 | dentry = lookup_one_len(name, parent, strlen(name)); |
| 365 | if (IS_ERR(dentry)) { | 361 | if (IS_ERR(dentry)) { |
| @@ -426,7 +422,7 @@ struct dentry *hypfs_create_u64(struct super_block *sb, struct dentry *dir, | |||
| 426 | char tmp[TMP_SIZE]; | 422 | char tmp[TMP_SIZE]; |
| 427 | struct dentry *dentry; | 423 | struct dentry *dentry; |
| 428 | 424 | ||
| 429 | snprintf(tmp, TMP_SIZE, "%lld\n", (unsigned long long int)value); | 425 | snprintf(tmp, TMP_SIZE, "%llu\n", (unsigned long long int)value); |
| 430 | buffer = kstrdup(tmp, GFP_KERNEL); | 426 | buffer = kstrdup(tmp, GFP_KERNEL); |
| 431 | if (!buffer) | 427 | if (!buffer) |
| 432 | return ERR_PTR(-ENOMEM); | 428 | return ERR_PTR(-ENOMEM); |
diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h index c7d0abfb0f00..ae7c8f9f94a5 100644 --- a/arch/s390/include/asm/atomic.h +++ b/arch/s390/include/asm/atomic.h | |||
| @@ -1,33 +1,23 @@ | |||
| 1 | #ifndef __ARCH_S390_ATOMIC__ | 1 | #ifndef __ARCH_S390_ATOMIC__ |
| 2 | #define __ARCH_S390_ATOMIC__ | 2 | #define __ARCH_S390_ATOMIC__ |
| 3 | 3 | ||
| 4 | #include <linux/compiler.h> | ||
| 5 | #include <linux/types.h> | ||
| 6 | |||
| 7 | /* | 4 | /* |
| 8 | * include/asm-s390/atomic.h | 5 | * Copyright 1999,2009 IBM Corp. |
| 6 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>, | ||
| 7 | * Denis Joseph Barrow, | ||
| 8 | * Arnd Bergmann <arndb@de.ibm.com>, | ||
| 9 | * | 9 | * |
| 10 | * S390 version | 10 | * Atomic operations that C can't guarantee us. |
| 11 | * Copyright (C) 1999-2005 IBM Deutschland Entwicklung GmbH, IBM Corporation | 11 | * Useful for resource counting etc. |
| 12 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | 12 | * s390 uses 'Compare And Swap' for atomicity in SMP enviroment. |
| 13 | * Denis Joseph Barrow, | ||
| 14 | * Arnd Bergmann (arndb@de.ibm.com) | ||
| 15 | * | ||
| 16 | * Derived from "include/asm-i386/bitops.h" | ||
| 17 | * Copyright (C) 1992, Linus Torvalds | ||
| 18 | * | 13 | * |
| 19 | */ | 14 | */ |
| 20 | 15 | ||
| 21 | /* | 16 | #include <linux/compiler.h> |
| 22 | * Atomic operations that C can't guarantee us. Useful for | 17 | #include <linux/types.h> |
| 23 | * resource counting etc.. | ||
| 24 | * S390 uses 'Compare And Swap' for atomicity in SMP enviroment | ||
| 25 | */ | ||
| 26 | 18 | ||
| 27 | #define ATOMIC_INIT(i) { (i) } | 19 | #define ATOMIC_INIT(i) { (i) } |
| 28 | 20 | ||
| 29 | #ifdef __KERNEL__ | ||
| 30 | |||
| 31 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | 21 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) |
| 32 | 22 | ||
| 33 | #define __CS_LOOP(ptr, op_val, op_string) ({ \ | 23 | #define __CS_LOOP(ptr, op_val, op_string) ({ \ |
| @@ -77,7 +67,7 @@ static inline void atomic_set(atomic_t *v, int i) | |||
| 77 | barrier(); | 67 | barrier(); |
| 78 | } | 68 | } |
| 79 | 69 | ||
| 80 | static __inline__ int atomic_add_return(int i, atomic_t * v) | 70 | static inline int atomic_add_return(int i, atomic_t *v) |
| 81 | { | 71 | { |
| 82 | return __CS_LOOP(v, i, "ar"); | 72 | return __CS_LOOP(v, i, "ar"); |
| 83 | } | 73 | } |
| @@ -87,7 +77,7 @@ static __inline__ int atomic_add_return(int i, atomic_t * v) | |||
| 87 | #define atomic_inc_return(_v) atomic_add_return(1, _v) | 77 | #define atomic_inc_return(_v) atomic_add_return(1, _v) |
| 88 | #define atomic_inc_and_test(_v) (atomic_add_return(1, _v) == 0) | 78 | #define atomic_inc_and_test(_v) (atomic_add_return(1, _v) == 0) |
| 89 | 79 | ||
| 90 | static __inline__ int atomic_sub_return(int i, atomic_t * v) | 80 | static inline int atomic_sub_return(int i, atomic_t *v) |
| 91 | { | 81 | { |
| 92 | return __CS_LOOP(v, i, "sr"); | 82 | return __CS_LOOP(v, i, "sr"); |
| 93 | } | 83 | } |
| @@ -97,19 +87,19 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v) | |||
| 97 | #define atomic_dec_return(_v) atomic_sub_return(1, _v) | 87 | #define atomic_dec_return(_v) atomic_sub_return(1, _v) |
| 98 | #define atomic_dec_and_test(_v) (atomic_sub_return(1, _v) == 0) | 88 | #define atomic_dec_and_test(_v) (atomic_sub_return(1, _v) == 0) |
| 99 | 89 | ||
| 100 | static __inline__ void atomic_clear_mask(unsigned long mask, atomic_t * v) | 90 | static inline void atomic_clear_mask(unsigned long mask, atomic_t *v) |
| 101 | { | 91 | { |
| 102 | __CS_LOOP(v, ~mask, "nr"); | 92 | __CS_LOOP(v, ~mask, "nr"); |
| 103 | } | 93 | } |
| 104 | 94 | ||
| 105 | static __inline__ void atomic_set_mask(unsigned long mask, atomic_t * v) | 95 | static inline void atomic_set_mask(unsigned long mask, atomic_t *v) |
| 106 | { | 96 | { |
| 107 | __CS_LOOP(v, mask, "or"); | 97 | __CS_LOOP(v, mask, "or"); |
| 108 | } | 98 | } |
| 109 | 99 | ||
| 110 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | 100 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) |
| 111 | 101 | ||
| 112 | static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new) | 102 | static inline int atomic_cmpxchg(atomic_t *v, int old, int new) |
| 113 | { | 103 | { |
| 114 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | 104 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) |
| 115 | asm volatile( | 105 | asm volatile( |
| @@ -127,7 +117,7 @@ static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new) | |||
| 127 | return old; | 117 | return old; |
| 128 | } | 118 | } |
| 129 | 119 | ||
| 130 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) | 120 | static inline int atomic_add_unless(atomic_t *v, int a, int u) |
| 131 | { | 121 | { |
| 132 | int c, old; | 122 | int c, old; |
| 133 | c = atomic_read(v); | 123 | c = atomic_read(v); |
| @@ -146,9 +136,10 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) | |||
| 146 | 136 | ||
| 147 | #undef __CS_LOOP | 137 | #undef __CS_LOOP |
| 148 | 138 | ||
| 149 | #ifdef __s390x__ | ||
| 150 | #define ATOMIC64_INIT(i) { (i) } | 139 | #define ATOMIC64_INIT(i) { (i) } |
| 151 | 140 | ||
| 141 | #ifdef CONFIG_64BIT | ||
| 142 | |||
| 152 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | 143 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) |
| 153 | 144 | ||
| 154 | #define __CSG_LOOP(ptr, op_val, op_string) ({ \ | 145 | #define __CSG_LOOP(ptr, op_val, op_string) ({ \ |
| @@ -162,7 +153,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) | |||
| 162 | : "=&d" (old_val), "=&d" (new_val), \ | 153 | : "=&d" (old_val), "=&d" (new_val), \ |
| 163 | "=Q" (((atomic_t *)(ptr))->counter) \ | 154 | "=Q" (((atomic_t *)(ptr))->counter) \ |
| 164 | : "d" (op_val), "Q" (((atomic_t *)(ptr))->counter) \ | 155 | : "d" (op_val), "Q" (((atomic_t *)(ptr))->counter) \ |
| 165 | : "cc", "memory" ); \ | 156 | : "cc", "memory"); \ |
| 166 | new_val; \ | 157 | new_val; \ |
| 167 | }) | 158 | }) |
| 168 | 159 | ||
| @@ -180,7 +171,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) | |||
| 180 | "=m" (((atomic_t *)(ptr))->counter) \ | 171 | "=m" (((atomic_t *)(ptr))->counter) \ |
| 181 | : "a" (ptr), "d" (op_val), \ | 172 | : "a" (ptr), "d" (op_val), \ |
| 182 | "m" (((atomic_t *)(ptr))->counter) \ | 173 | "m" (((atomic_t *)(ptr))->counter) \ |
| 183 | : "cc", "memory" ); \ | 174 | : "cc", "memory"); \ |
| 184 | new_val; \ | 175 | new_val; \ |
| 185 | }) | 176 | }) |
| 186 | 177 | ||
| @@ -198,39 +189,29 @@ static inline void atomic64_set(atomic64_t *v, long long i) | |||
| 198 | barrier(); | 189 | barrier(); |
| 199 | } | 190 | } |
| 200 | 191 | ||
| 201 | static __inline__ long long atomic64_add_return(long long i, atomic64_t * v) | 192 | static inline long long atomic64_add_return(long long i, atomic64_t *v) |
| 202 | { | 193 | { |
| 203 | return __CSG_LOOP(v, i, "agr"); | 194 | return __CSG_LOOP(v, i, "agr"); |
| 204 | } | 195 | } |
| 205 | #define atomic64_add(_i, _v) atomic64_add_return(_i, _v) | ||
| 206 | #define atomic64_add_negative(_i, _v) (atomic64_add_return(_i, _v) < 0) | ||
| 207 | #define atomic64_inc(_v) atomic64_add_return(1, _v) | ||
| 208 | #define atomic64_inc_return(_v) atomic64_add_return(1, _v) | ||
| 209 | #define atomic64_inc_and_test(_v) (atomic64_add_return(1, _v) == 0) | ||
| 210 | 196 | ||
| 211 | static __inline__ long long atomic64_sub_return(long long i, atomic64_t * v) | 197 | static inline long long atomic64_sub_return(long long i, atomic64_t *v) |
| 212 | { | 198 | { |
| 213 | return __CSG_LOOP(v, i, "sgr"); | 199 | return __CSG_LOOP(v, i, "sgr"); |
| 214 | } | 200 | } |
| 215 | #define atomic64_sub(_i, _v) atomic64_sub_return(_i, _v) | ||
| 216 | #define atomic64_sub_and_test(_i, _v) (atomic64_sub_return(_i, _v) == 0) | ||
| 217 | #define atomic64_dec(_v) atomic64_sub_return(1, _v) | ||
| 218 | #define atomic64_dec_return(_v) atomic64_sub_return(1, _v) | ||
| 219 | #define atomic64_dec_and_test(_v) (atomic64_sub_return(1, _v) == 0) | ||
| 220 | 201 | ||
| 221 | static __inline__ void atomic64_clear_mask(unsigned long mask, atomic64_t * v) | 202 | static inline void atomic64_clear_mask(unsigned long mask, atomic64_t *v) |
| 222 | { | 203 | { |
| 223 | __CSG_LOOP(v, ~mask, "ngr"); | 204 | __CSG_LOOP(v, ~mask, "ngr"); |
| 224 | } | 205 | } |
| 225 | 206 | ||
| 226 | static __inline__ void atomic64_set_mask(unsigned long mask, atomic64_t * v) | 207 | static inline void atomic64_set_mask(unsigned long mask, atomic64_t *v) |
| 227 | { | 208 | { |
| 228 | __CSG_LOOP(v, mask, "ogr"); | 209 | __CSG_LOOP(v, mask, "ogr"); |
| 229 | } | 210 | } |
| 230 | 211 | ||
| 231 | #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) | 212 | #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) |
| 232 | 213 | ||
| 233 | static __inline__ long long atomic64_cmpxchg(atomic64_t *v, | 214 | static inline long long atomic64_cmpxchg(atomic64_t *v, |
| 234 | long long old, long long new) | 215 | long long old, long long new) |
| 235 | { | 216 | { |
| 236 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | 217 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) |
| @@ -249,8 +230,112 @@ static __inline__ long long atomic64_cmpxchg(atomic64_t *v, | |||
| 249 | return old; | 230 | return old; |
| 250 | } | 231 | } |
| 251 | 232 | ||
| 252 | static __inline__ int atomic64_add_unless(atomic64_t *v, | 233 | #undef __CSG_LOOP |
| 253 | long long a, long long u) | 234 | |
| 235 | #else /* CONFIG_64BIT */ | ||
| 236 | |||
| 237 | typedef struct { | ||
| 238 | long long counter; | ||
| 239 | } atomic64_t; | ||
| 240 | |||
| 241 | static inline long long atomic64_read(const atomic64_t *v) | ||
| 242 | { | ||
| 243 | register_pair rp; | ||
| 244 | |||
| 245 | asm volatile( | ||
| 246 | " lm %0,%N0,0(%1)" | ||
| 247 | : "=&d" (rp) | ||
| 248 | : "a" (&v->counter), "m" (v->counter) | ||
| 249 | ); | ||
| 250 | return rp.pair; | ||
| 251 | } | ||
| 252 | |||
| 253 | static inline void atomic64_set(atomic64_t *v, long long i) | ||
| 254 | { | ||
| 255 | register_pair rp = {.pair = i}; | ||
| 256 | |||
| 257 | asm volatile( | ||
| 258 | " stm %1,%N1,0(%2)" | ||
| 259 | : "=m" (v->counter) | ||
| 260 | : "d" (rp), "a" (&v->counter) | ||
| 261 | ); | ||
| 262 | } | ||
| 263 | |||
| 264 | static inline long long atomic64_xchg(atomic64_t *v, long long new) | ||
| 265 | { | ||
| 266 | register_pair rp_new = {.pair = new}; | ||
| 267 | register_pair rp_old; | ||
| 268 | |||
| 269 | asm volatile( | ||
| 270 | " lm %0,%N0,0(%2)\n" | ||
| 271 | "0: cds %0,%3,0(%2)\n" | ||
| 272 | " jl 0b\n" | ||
| 273 | : "=&d" (rp_old), "+m" (v->counter) | ||
| 274 | : "a" (&v->counter), "d" (rp_new) | ||
| 275 | : "cc"); | ||
| 276 | return rp_old.pair; | ||
| 277 | } | ||
| 278 | |||
| 279 | static inline long long atomic64_cmpxchg(atomic64_t *v, | ||
| 280 | long long old, long long new) | ||
| 281 | { | ||
| 282 | register_pair rp_old = {.pair = old}; | ||
| 283 | register_pair rp_new = {.pair = new}; | ||
| 284 | |||
| 285 | asm volatile( | ||
| 286 | " cds %0,%3,0(%2)" | ||
| 287 | : "+&d" (rp_old), "+m" (v->counter) | ||
| 288 | : "a" (&v->counter), "d" (rp_new) | ||
| 289 | : "cc"); | ||
| 290 | return rp_old.pair; | ||
| 291 | } | ||
| 292 | |||
| 293 | |||
| 294 | static inline long long atomic64_add_return(long long i, atomic64_t *v) | ||
| 295 | { | ||
| 296 | long long old, new; | ||
| 297 | |||
| 298 | do { | ||
| 299 | old = atomic64_read(v); | ||
| 300 | new = old + i; | ||
| 301 | } while (atomic64_cmpxchg(v, old, new) != old); | ||
| 302 | return new; | ||
| 303 | } | ||
| 304 | |||
| 305 | static inline long long atomic64_sub_return(long long i, atomic64_t *v) | ||
| 306 | { | ||
| 307 | long long old, new; | ||
| 308 | |||
| 309 | do { | ||
| 310 | old = atomic64_read(v); | ||
| 311 | new = old - i; | ||
| 312 | } while (atomic64_cmpxchg(v, old, new) != old); | ||
| 313 | return new; | ||
| 314 | } | ||
| 315 | |||
| 316 | static inline void atomic64_set_mask(unsigned long long mask, atomic64_t *v) | ||
| 317 | { | ||
| 318 | long long old, new; | ||
| 319 | |||
| 320 | do { | ||
| 321 | old = atomic64_read(v); | ||
| 322 | new = old | mask; | ||
| 323 | } while (atomic64_cmpxchg(v, old, new) != old); | ||
| 324 | } | ||
| 325 | |||
| 326 | static inline void atomic64_clear_mask(unsigned long long mask, atomic64_t *v) | ||
| 327 | { | ||
| 328 | long long old, new; | ||
| 329 | |||
| 330 | do { | ||
| 331 | old = atomic64_read(v); | ||
| 332 | new = old & mask; | ||
| 333 | } while (atomic64_cmpxchg(v, old, new) != old); | ||
| 334 | } | ||
| 335 | |||
| 336 | #endif /* CONFIG_64BIT */ | ||
| 337 | |||
| 338 | static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) | ||
| 254 | { | 339 | { |
| 255 | long long c, old; | 340 | long long c, old; |
| 256 | c = atomic64_read(v); | 341 | c = atomic64_read(v); |
| @@ -265,15 +350,17 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, | |||
| 265 | return c != u; | 350 | return c != u; |
| 266 | } | 351 | } |
| 267 | 352 | ||
| 268 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | 353 | #define atomic64_add(_i, _v) atomic64_add_return(_i, _v) |
| 269 | 354 | #define atomic64_add_negative(_i, _v) (atomic64_add_return(_i, _v) < 0) | |
| 270 | #undef __CSG_LOOP | 355 | #define atomic64_inc(_v) atomic64_add_return(1, _v) |
| 271 | 356 | #define atomic64_inc_return(_v) atomic64_add_return(1, _v) | |
| 272 | #else /* __s390x__ */ | 357 | #define atomic64_inc_and_test(_v) (atomic64_add_return(1, _v) == 0) |
| 273 | 358 | #define atomic64_sub(_i, _v) atomic64_sub_return(_i, _v) | |
| 274 | #include <asm-generic/atomic64.h> | 359 | #define atomic64_sub_and_test(_i, _v) (atomic64_sub_return(_i, _v) == 0) |
| 275 | 360 | #define atomic64_dec(_v) atomic64_sub_return(1, _v) | |
| 276 | #endif /* __s390x__ */ | 361 | #define atomic64_dec_return(_v) atomic64_sub_return(1, _v) |
| 362 | #define atomic64_dec_and_test(_v) (atomic64_sub_return(1, _v) == 0) | ||
| 363 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | ||
| 277 | 364 | ||
| 278 | #define smp_mb__before_atomic_dec() smp_mb() | 365 | #define smp_mb__before_atomic_dec() smp_mb() |
| 279 | #define smp_mb__after_atomic_dec() smp_mb() | 366 | #define smp_mb__after_atomic_dec() smp_mb() |
| @@ -281,5 +368,5 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, | |||
| 281 | #define smp_mb__after_atomic_inc() smp_mb() | 368 | #define smp_mb__after_atomic_inc() smp_mb() |
| 282 | 369 | ||
| 283 | #include <asm-generic/atomic-long.h> | 370 | #include <asm-generic/atomic-long.h> |
| 284 | #endif /* __KERNEL__ */ | 371 | |
| 285 | #endif /* __ARCH_S390_ATOMIC__ */ | 372 | #endif /* __ARCH_S390_ATOMIC__ */ |
diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h index d5a8e7c1477c..6c00f6800a34 100644 --- a/arch/s390/include/asm/checksum.h +++ b/arch/s390/include/asm/checksum.h | |||
| @@ -78,28 +78,11 @@ csum_partial_copy_nocheck (const void *src, void *dst, int len, __wsum sum) | |||
| 78 | */ | 78 | */ |
| 79 | static inline __sum16 csum_fold(__wsum sum) | 79 | static inline __sum16 csum_fold(__wsum sum) |
| 80 | { | 80 | { |
| 81 | #ifndef __s390x__ | 81 | u32 csum = (__force u32) sum; |
| 82 | register_pair rp; | ||
| 83 | 82 | ||
| 84 | asm volatile( | 83 | csum += (csum >> 16) + (csum << 16); |
| 85 | " slr %N1,%N1\n" /* %0 = H L */ | 84 | csum >>= 16; |
| 86 | " lr %1,%0\n" /* %0 = H L, %1 = H L 0 0 */ | 85 | return (__force __sum16) ~csum; |
| 87 | " srdl %1,16\n" /* %0 = H L, %1 = 0 H L 0 */ | ||
| 88 | " alr %1,%N1\n" /* %0 = H L, %1 = L H L 0 */ | ||
| 89 | " alr %0,%1\n" /* %0 = H+L+C L+H */ | ||
| 90 | " srl %0,16\n" /* %0 = H+L+C */ | ||
| 91 | : "+&d" (sum), "=d" (rp) : : "cc"); | ||
| 92 | #else /* __s390x__ */ | ||
| 93 | asm volatile( | ||
| 94 | " sr 3,3\n" /* %0 = H*65536 + L */ | ||
| 95 | " lr 2,%0\n" /* %0 = H L, 2/3 = H L / 0 0 */ | ||
| 96 | " srdl 2,16\n" /* %0 = H L, 2/3 = 0 H / L 0 */ | ||
| 97 | " alr 2,3\n" /* %0 = H L, 2/3 = L H / L 0 */ | ||
| 98 | " alr %0,2\n" /* %0 = H+L+C L+H */ | ||
| 99 | " srl %0,16\n" /* %0 = H+L+C */ | ||
| 100 | : "+&d" (sum) : : "cc", "2", "3"); | ||
| 101 | #endif /* __s390x__ */ | ||
| 102 | return (__force __sum16) ~sum; | ||
| 103 | } | 86 | } |
| 104 | 87 | ||
| 105 | /* | 88 | /* |
diff --git a/arch/s390/include/asm/chsc.h b/arch/s390/include/asm/chsc.h index 807997f7414b..4943654ed7fd 100644 --- a/arch/s390/include/asm/chsc.h +++ b/arch/s390/include/asm/chsc.h | |||
| @@ -125,4 +125,32 @@ struct chsc_cpd_info { | |||
| 125 | #define CHSC_INFO_CPD _IOWR(CHSC_IOCTL_MAGIC, 0x87, struct chsc_cpd_info) | 125 | #define CHSC_INFO_CPD _IOWR(CHSC_IOCTL_MAGIC, 0x87, struct chsc_cpd_info) |
| 126 | #define CHSC_INFO_DCAL _IOWR(CHSC_IOCTL_MAGIC, 0x88, struct chsc_dcal) | 126 | #define CHSC_INFO_DCAL _IOWR(CHSC_IOCTL_MAGIC, 0x88, struct chsc_dcal) |
| 127 | 127 | ||
| 128 | #ifdef __KERNEL__ | ||
| 129 | |||
| 130 | struct css_general_char { | ||
| 131 | u64 : 12; | ||
| 132 | u32 dynio : 1; /* bit 12 */ | ||
| 133 | u32 : 28; | ||
| 134 | u32 aif : 1; /* bit 41 */ | ||
| 135 | u32 : 3; | ||
| 136 | u32 mcss : 1; /* bit 45 */ | ||
| 137 | u32 fcs : 1; /* bit 46 */ | ||
| 138 | u32 : 1; | ||
| 139 | u32 ext_mb : 1; /* bit 48 */ | ||
| 140 | u32 : 7; | ||
| 141 | u32 aif_tdd : 1; /* bit 56 */ | ||
| 142 | u32 : 1; | ||
| 143 | u32 qebsm : 1; /* bit 58 */ | ||
| 144 | u32 : 8; | ||
| 145 | u32 aif_osa : 1; /* bit 67 */ | ||
| 146 | u32 : 14; | ||
| 147 | u32 cib : 1; /* bit 82 */ | ||
| 148 | u32 : 5; | ||
| 149 | u32 fcx : 1; /* bit 88 */ | ||
| 150 | u32 : 7; | ||
| 151 | }__attribute__((packed)); | ||
| 152 | |||
| 153 | extern struct css_general_char css_general_characteristics; | ||
| 154 | |||
| 155 | #endif /* __KERNEL__ */ | ||
| 128 | #endif | 156 | #endif |
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h index 619bf94b11f1..e85679af54dd 100644 --- a/arch/s390/include/asm/cio.h +++ b/arch/s390/include/asm/cio.h | |||
| @@ -15,228 +15,7 @@ | |||
| 15 | #define LPM_ANYPATH 0xff | 15 | #define LPM_ANYPATH 0xff |
| 16 | #define __MAX_CSSID 0 | 16 | #define __MAX_CSSID 0 |
| 17 | 17 | ||
| 18 | /** | 18 | #include <asm/scsw.h> |
| 19 | * struct cmd_scsw - command-mode subchannel status word | ||
| 20 | * @key: subchannel key | ||
| 21 | * @sctl: suspend control | ||
| 22 | * @eswf: esw format | ||
| 23 | * @cc: deferred condition code | ||
| 24 | * @fmt: format | ||
| 25 | * @pfch: prefetch | ||
| 26 | * @isic: initial-status interruption control | ||
| 27 | * @alcc: address-limit checking control | ||
| 28 | * @ssi: suppress-suspended interruption | ||
| 29 | * @zcc: zero condition code | ||
| 30 | * @ectl: extended control | ||
| 31 | * @pno: path not operational | ||
| 32 | * @res: reserved | ||
| 33 | * @fctl: function control | ||
| 34 | * @actl: activity control | ||
| 35 | * @stctl: status control | ||
| 36 | * @cpa: channel program address | ||
| 37 | * @dstat: device status | ||
| 38 | * @cstat: subchannel status | ||
| 39 | * @count: residual count | ||
| 40 | */ | ||
| 41 | struct cmd_scsw { | ||
| 42 | __u32 key : 4; | ||
| 43 | __u32 sctl : 1; | ||
| 44 | __u32 eswf : 1; | ||
| 45 | __u32 cc : 2; | ||
| 46 | __u32 fmt : 1; | ||
| 47 | __u32 pfch : 1; | ||
| 48 | __u32 isic : 1; | ||
| 49 | __u32 alcc : 1; | ||
| 50 | __u32 ssi : 1; | ||
| 51 | __u32 zcc : 1; | ||
| 52 | __u32 ectl : 1; | ||
| 53 | __u32 pno : 1; | ||
| 54 | __u32 res : 1; | ||
| 55 | __u32 fctl : 3; | ||
| 56 | __u32 actl : 7; | ||
| 57 | __u32 stctl : 5; | ||
| 58 | __u32 cpa; | ||
| 59 | __u32 dstat : 8; | ||
| 60 | __u32 cstat : 8; | ||
| 61 | __u32 count : 16; | ||
| 62 | } __attribute__ ((packed)); | ||
| 63 | |||
| 64 | /** | ||
| 65 | * struct tm_scsw - transport-mode subchannel status word | ||
| 66 | * @key: subchannel key | ||
| 67 | * @eswf: esw format | ||
| 68 | * @cc: deferred condition code | ||
| 69 | * @fmt: format | ||
| 70 | * @x: IRB-format control | ||
| 71 | * @q: interrogate-complete | ||
| 72 | * @ectl: extended control | ||
| 73 | * @pno: path not operational | ||
| 74 | * @fctl: function control | ||
| 75 | * @actl: activity control | ||
| 76 | * @stctl: status control | ||
| 77 | * @tcw: TCW address | ||
| 78 | * @dstat: device status | ||
| 79 | * @cstat: subchannel status | ||
| 80 | * @fcxs: FCX status | ||
| 81 | * @schxs: subchannel-extended status | ||
| 82 | */ | ||
| 83 | struct tm_scsw { | ||
| 84 | u32 key:4; | ||
| 85 | u32 :1; | ||
| 86 | u32 eswf:1; | ||
| 87 | u32 cc:2; | ||
| 88 | u32 fmt:3; | ||
| 89 | u32 x:1; | ||
| 90 | u32 q:1; | ||
| 91 | u32 :1; | ||
| 92 | u32 ectl:1; | ||
| 93 | u32 pno:1; | ||
| 94 | u32 :1; | ||
| 95 | u32 fctl:3; | ||
| 96 | u32 actl:7; | ||
| 97 | u32 stctl:5; | ||
| 98 | u32 tcw; | ||
| 99 | u32 dstat:8; | ||
| 100 | u32 cstat:8; | ||
| 101 | u32 fcxs:8; | ||
| 102 | u32 schxs:8; | ||
| 103 | } __attribute__ ((packed)); | ||
| 104 | |||
| 105 | /** | ||
| 106 | * union scsw - subchannel status word | ||
| 107 | * @cmd: command-mode SCSW | ||
| 108 | * @tm: transport-mode SCSW | ||
| 109 | */ | ||
| 110 | union scsw { | ||
| 111 | struct cmd_scsw cmd; | ||
| 112 | struct tm_scsw tm; | ||
| 113 | } __attribute__ ((packed)); | ||
| 114 | |||
| 115 | int scsw_is_tm(union scsw *scsw); | ||
| 116 | u32 scsw_key(union scsw *scsw); | ||
| 117 | u32 scsw_eswf(union scsw *scsw); | ||
| 118 | u32 scsw_cc(union scsw *scsw); | ||
| 119 | u32 scsw_ectl(union scsw *scsw); | ||
| 120 | u32 scsw_pno(union scsw *scsw); | ||
| 121 | u32 scsw_fctl(union scsw *scsw); | ||
| 122 | u32 scsw_actl(union scsw *scsw); | ||
| 123 | u32 scsw_stctl(union scsw *scsw); | ||
| 124 | u32 scsw_dstat(union scsw *scsw); | ||
| 125 | u32 scsw_cstat(union scsw *scsw); | ||
| 126 | int scsw_is_solicited(union scsw *scsw); | ||
| 127 | int scsw_is_valid_key(union scsw *scsw); | ||
| 128 | int scsw_is_valid_eswf(union scsw *scsw); | ||
| 129 | int scsw_is_valid_cc(union scsw *scsw); | ||
| 130 | int scsw_is_valid_ectl(union scsw *scsw); | ||
| 131 | int scsw_is_valid_pno(union scsw *scsw); | ||
| 132 | int scsw_is_valid_fctl(union scsw *scsw); | ||
| 133 | int scsw_is_valid_actl(union scsw *scsw); | ||
| 134 | int scsw_is_valid_stctl(union scsw *scsw); | ||
| 135 | int scsw_is_valid_dstat(union scsw *scsw); | ||
| 136 | int scsw_is_valid_cstat(union scsw *scsw); | ||
| 137 | int scsw_cmd_is_valid_key(union scsw *scsw); | ||
| 138 | int scsw_cmd_is_valid_sctl(union scsw *scsw); | ||
| 139 | int scsw_cmd_is_valid_eswf(union scsw *scsw); | ||
| 140 | int scsw_cmd_is_valid_cc(union scsw *scsw); | ||
| 141 | int scsw_cmd_is_valid_fmt(union scsw *scsw); | ||
| 142 | int scsw_cmd_is_valid_pfch(union scsw *scsw); | ||
| 143 | int scsw_cmd_is_valid_isic(union scsw *scsw); | ||
| 144 | int scsw_cmd_is_valid_alcc(union scsw *scsw); | ||
| 145 | int scsw_cmd_is_valid_ssi(union scsw *scsw); | ||
| 146 | int scsw_cmd_is_valid_zcc(union scsw *scsw); | ||
| 147 | int scsw_cmd_is_valid_ectl(union scsw *scsw); | ||
| 148 | int scsw_cmd_is_valid_pno(union scsw *scsw); | ||
| 149 | int scsw_cmd_is_valid_fctl(union scsw *scsw); | ||
| 150 | int scsw_cmd_is_valid_actl(union scsw *scsw); | ||
| 151 | int scsw_cmd_is_valid_stctl(union scsw *scsw); | ||
| 152 | int scsw_cmd_is_valid_dstat(union scsw *scsw); | ||
| 153 | int scsw_cmd_is_valid_cstat(union scsw *scsw); | ||
| 154 | int scsw_cmd_is_solicited(union scsw *scsw); | ||
| 155 | int scsw_tm_is_valid_key(union scsw *scsw); | ||
| 156 | int scsw_tm_is_valid_eswf(union scsw *scsw); | ||
| 157 | int scsw_tm_is_valid_cc(union scsw *scsw); | ||
| 158 | int scsw_tm_is_valid_fmt(union scsw *scsw); | ||
| 159 | int scsw_tm_is_valid_x(union scsw *scsw); | ||
| 160 | int scsw_tm_is_valid_q(union scsw *scsw); | ||
| 161 | int scsw_tm_is_valid_ectl(union scsw *scsw); | ||
| 162 | int scsw_tm_is_valid_pno(union scsw *scsw); | ||
| 163 | int scsw_tm_is_valid_fctl(union scsw *scsw); | ||
| 164 | int scsw_tm_is_valid_actl(union scsw *scsw); | ||
| 165 | int scsw_tm_is_valid_stctl(union scsw *scsw); | ||
| 166 | int scsw_tm_is_valid_dstat(union scsw *scsw); | ||
| 167 | int scsw_tm_is_valid_cstat(union scsw *scsw); | ||
| 168 | int scsw_tm_is_valid_fcxs(union scsw *scsw); | ||
| 169 | int scsw_tm_is_valid_schxs(union scsw *scsw); | ||
| 170 | int scsw_tm_is_solicited(union scsw *scsw); | ||
| 171 | |||
| 172 | #define SCSW_FCTL_CLEAR_FUNC 0x1 | ||
| 173 | #define SCSW_FCTL_HALT_FUNC 0x2 | ||
| 174 | #define SCSW_FCTL_START_FUNC 0x4 | ||
| 175 | |||
| 176 | #define SCSW_ACTL_SUSPENDED 0x1 | ||
| 177 | #define SCSW_ACTL_DEVACT 0x2 | ||
| 178 | #define SCSW_ACTL_SCHACT 0x4 | ||
| 179 | #define SCSW_ACTL_CLEAR_PEND 0x8 | ||
| 180 | #define SCSW_ACTL_HALT_PEND 0x10 | ||
| 181 | #define SCSW_ACTL_START_PEND 0x20 | ||
| 182 | #define SCSW_ACTL_RESUME_PEND 0x40 | ||
| 183 | |||
| 184 | #define SCSW_STCTL_STATUS_PEND 0x1 | ||
| 185 | #define SCSW_STCTL_SEC_STATUS 0x2 | ||
| 186 | #define SCSW_STCTL_PRIM_STATUS 0x4 | ||
| 187 | #define SCSW_STCTL_INTER_STATUS 0x8 | ||
| 188 | #define SCSW_STCTL_ALERT_STATUS 0x10 | ||
| 189 | |||
| 190 | #define DEV_STAT_ATTENTION 0x80 | ||
| 191 | #define DEV_STAT_STAT_MOD 0x40 | ||
| 192 | #define DEV_STAT_CU_END 0x20 | ||
| 193 | #define DEV_STAT_BUSY 0x10 | ||
| 194 | #define DEV_STAT_CHN_END 0x08 | ||
| 195 | #define DEV_STAT_DEV_END 0x04 | ||
| 196 | #define DEV_STAT_UNIT_CHECK 0x02 | ||
| 197 | #define DEV_STAT_UNIT_EXCEP 0x01 | ||
| 198 | |||
| 199 | #define SCHN_STAT_PCI 0x80 | ||
| 200 | #define SCHN_STAT_INCORR_LEN 0x40 | ||
| 201 | #define SCHN_STAT_PROG_CHECK 0x20 | ||
| 202 | #define SCHN_STAT_PROT_CHECK 0x10 | ||
| 203 | #define SCHN_STAT_CHN_DATA_CHK 0x08 | ||
| 204 | #define SCHN_STAT_CHN_CTRL_CHK 0x04 | ||
| 205 | #define SCHN_STAT_INTF_CTRL_CHK 0x02 | ||
| 206 | #define SCHN_STAT_CHAIN_CHECK 0x01 | ||
| 207 | |||
| 208 | /* | ||
| 209 | * architectured values for first sense byte | ||
| 210 | */ | ||
| 211 | #define SNS0_CMD_REJECT 0x80 | ||
| 212 | #define SNS_CMD_REJECT SNS0_CMD_REJEC | ||
| 213 | #define SNS0_INTERVENTION_REQ 0x40 | ||
| 214 | #define SNS0_BUS_OUT_CHECK 0x20 | ||
| 215 | #define SNS0_EQUIPMENT_CHECK 0x10 | ||
| 216 | #define SNS0_DATA_CHECK 0x08 | ||
| 217 | #define SNS0_OVERRUN 0x04 | ||
| 218 | #define SNS0_INCOMPL_DOMAIN 0x01 | ||
| 219 | |||
| 220 | /* | ||
| 221 | * architectured values for second sense byte | ||
| 222 | */ | ||
| 223 | #define SNS1_PERM_ERR 0x80 | ||
| 224 | #define SNS1_INV_TRACK_FORMAT 0x40 | ||
| 225 | #define SNS1_EOC 0x20 | ||
| 226 | #define SNS1_MESSAGE_TO_OPER 0x10 | ||
| 227 | #define SNS1_NO_REC_FOUND 0x08 | ||
| 228 | #define SNS1_FILE_PROTECTED 0x04 | ||
| 229 | #define SNS1_WRITE_INHIBITED 0x02 | ||
| 230 | #define SNS1_INPRECISE_END 0x01 | ||
| 231 | |||
| 232 | /* | ||
| 233 | * architectured values for third sense byte | ||
| 234 | */ | ||
| 235 | #define SNS2_REQ_INH_WRITE 0x80 | ||
| 236 | #define SNS2_CORRECTABLE 0x40 | ||
| 237 | #define SNS2_FIRST_LOG_ERR 0x20 | ||
| 238 | #define SNS2_ENV_DATA_PRESENT 0x10 | ||
| 239 | #define SNS2_INPRECISE_END 0x04 | ||
| 240 | 19 | ||
| 241 | /** | 20 | /** |
| 242 | * struct ccw1 - channel command word | 21 | * struct ccw1 - channel command word |
diff --git a/arch/s390/include/asm/cpu.h b/arch/s390/include/asm/cpu.h new file mode 100644 index 000000000000..471234b90574 --- /dev/null +++ b/arch/s390/include/asm/cpu.h | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | /* | ||
| 2 | * Copyright IBM Corp. 2000,2009 | ||
| 3 | * Author(s): Hartmut Penner <hp@de.ibm.com>, | ||
| 4 | * Martin Schwidefsky <schwidefsky@de.ibm.com>, | ||
| 5 | * Christian Ehrhardt <ehrhardt@de.ibm.com>, | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef _ASM_S390_CPU_H | ||
| 9 | #define _ASM_S390_CPU_H | ||
| 10 | |||
| 11 | #define MAX_CPU_ADDRESS 255 | ||
| 12 | |||
| 13 | #ifndef __ASSEMBLY__ | ||
| 14 | |||
| 15 | #include <linux/types.h> | ||
| 16 | |||
| 17 | struct cpuid | ||
| 18 | { | ||
| 19 | unsigned int version : 8; | ||
| 20 | unsigned int ident : 24; | ||
| 21 | unsigned int machine : 16; | ||
| 22 | unsigned int unused : 16; | ||
| 23 | } __packed; | ||
| 24 | |||
| 25 | #endif /* __ASSEMBLY__ */ | ||
| 26 | #endif /* _ASM_S390_CPU_H */ | ||
diff --git a/arch/s390/include/asm/cpuid.h b/arch/s390/include/asm/cpuid.h deleted file mode 100644 index 07836a2e5222..000000000000 --- a/arch/s390/include/asm/cpuid.h +++ /dev/null | |||
| @@ -1,25 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright IBM Corp. 2000,2009 | ||
| 3 | * Author(s): Hartmut Penner <hp@de.ibm.com>, | ||
| 4 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | ||
| 5 | * Christian Ehrhardt <ehrhardt@de.ibm.com> | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef _ASM_S390_CPUID_H_ | ||
| 9 | #define _ASM_S390_CPUID_H_ | ||
| 10 | |||
| 11 | /* | ||
| 12 | * CPU type and hardware bug flags. Kept separately for each CPU. | ||
| 13 | * Members of this structure are referenced in head.S, so think twice | ||
| 14 | * before touching them. [mj] | ||
| 15 | */ | ||
| 16 | |||
| 17 | typedef struct | ||
| 18 | { | ||
| 19 | unsigned int version : 8; | ||
| 20 | unsigned int ident : 24; | ||
| 21 | unsigned int machine : 16; | ||
| 22 | unsigned int unused : 16; | ||
| 23 | } __attribute__ ((packed)) cpuid_t; | ||
| 24 | |||
| 25 | #endif /* _ASM_S390_CPUID_H_ */ | ||
diff --git a/arch/s390/include/asm/debug.h b/arch/s390/include/asm/debug.h index 31ed5686a968..18124b75a7ab 100644 --- a/arch/s390/include/asm/debug.h +++ b/arch/s390/include/asm/debug.h | |||
| @@ -167,6 +167,10 @@ debug_text_event(debug_info_t* id, int level, const char* txt) | |||
| 167 | return debug_event_common(id,level,txt,strlen(txt)); | 167 | return debug_event_common(id,level,txt,strlen(txt)); |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | /* | ||
| 171 | * IMPORTANT: Use "%s" in sprintf format strings with care! Only pointers are | ||
| 172 | * stored in the s390dbf. See Documentation/s390/s390dbf.txt for more details! | ||
| 173 | */ | ||
| 170 | extern debug_entry_t * | 174 | extern debug_entry_t * |
| 171 | debug_sprintf_event(debug_info_t* id,int level,char *string,...) | 175 | debug_sprintf_event(debug_info_t* id,int level,char *string,...) |
| 172 | __attribute__ ((format(printf, 3, 4))); | 176 | __attribute__ ((format(printf, 3, 4))); |
| @@ -206,7 +210,10 @@ debug_text_exception(debug_info_t* id, int level, const char* txt) | |||
| 206 | return debug_exception_common(id,level,txt,strlen(txt)); | 210 | return debug_exception_common(id,level,txt,strlen(txt)); |
| 207 | } | 211 | } |
| 208 | 212 | ||
| 209 | 213 | /* | |
| 214 | * IMPORTANT: Use "%s" in sprintf format strings with care! Only pointers are | ||
| 215 | * stored in the s390dbf. See Documentation/s390/s390dbf.txt for more details! | ||
| 216 | */ | ||
| 210 | extern debug_entry_t * | 217 | extern debug_entry_t * |
| 211 | debug_sprintf_exception(debug_info_t* id,int level,char *string,...) | 218 | debug_sprintf_exception(debug_info_t* id,int level,char *string,...) |
| 212 | __attribute__ ((format(printf, 3, 4))); | 219 | __attribute__ ((format(printf, 3, 4))); |
diff --git a/arch/s390/include/asm/hardirq.h b/arch/s390/include/asm/hardirq.h index 89ec7056da28..498bc3892385 100644 --- a/arch/s390/include/asm/hardirq.h +++ b/arch/s390/include/asm/hardirq.h | |||
| @@ -18,13 +18,6 @@ | |||
| 18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
| 19 | #include <asm/lowcore.h> | 19 | #include <asm/lowcore.h> |
| 20 | 20 | ||
| 21 | /* irq_cpustat_t is unused currently, but could be converted | ||
| 22 | * into a percpu variable instead of storing softirq_pending | ||
| 23 | * on the lowcore */ | ||
| 24 | typedef struct { | ||
| 25 | unsigned int __softirq_pending; | ||
| 26 | } irq_cpustat_t; | ||
| 27 | |||
| 28 | #define local_softirq_pending() (S390_lowcore.softirq_pending) | 21 | #define local_softirq_pending() (S390_lowcore.softirq_pending) |
| 29 | 22 | ||
| 30 | #define __ARCH_IRQ_STAT | 23 | #define __ARCH_IRQ_STAT |
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index 1171e6d144a3..5e95d95450b3 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h | |||
| @@ -57,6 +57,8 @@ struct ipl_block_fcp { | |||
| 57 | } __attribute__((packed)); | 57 | } __attribute__((packed)); |
| 58 | 58 | ||
| 59 | #define DIAG308_VMPARM_SIZE 64 | 59 | #define DIAG308_VMPARM_SIZE 64 |
| 60 | #define DIAG308_SCPDATA_SIZE (PAGE_SIZE - (sizeof(struct ipl_list_hdr) + \ | ||
| 61 | offsetof(struct ipl_block_fcp, scp_data))) | ||
| 60 | 62 | ||
| 61 | struct ipl_block_ccw { | 63 | struct ipl_block_ccw { |
| 62 | u8 load_parm[8]; | 64 | u8 load_parm[8]; |
| @@ -91,7 +93,8 @@ extern void do_halt(void); | |||
| 91 | extern void do_poff(void); | 93 | extern void do_poff(void); |
| 92 | extern void ipl_save_parameters(void); | 94 | extern void ipl_save_parameters(void); |
| 93 | extern void ipl_update_parameters(void); | 95 | extern void ipl_update_parameters(void); |
| 94 | extern void get_ipl_vmparm(char *); | 96 | extern size_t append_ipl_vmparm(char *, size_t); |
| 97 | extern size_t append_ipl_scpdata(char *, size_t); | ||
| 95 | 98 | ||
| 96 | enum { | 99 | enum { |
| 97 | IPL_DEVNO_VALID = 1, | 100 | IPL_DEVNO_VALID = 1, |
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index 1cd02f6073a0..698988f69403 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
| @@ -17,7 +17,7 @@ | |||
| 17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
| 18 | #include <linux/kvm_host.h> | 18 | #include <linux/kvm_host.h> |
| 19 | #include <asm/debug.h> | 19 | #include <asm/debug.h> |
| 20 | #include <asm/cpuid.h> | 20 | #include <asm/cpu.h> |
| 21 | 21 | ||
| 22 | #define KVM_MAX_VCPUS 64 | 22 | #define KVM_MAX_VCPUS 64 |
| 23 | #define KVM_MEMORY_SLOTS 32 | 23 | #define KVM_MEMORY_SLOTS 32 |
| @@ -217,8 +217,8 @@ struct kvm_vcpu_arch { | |||
| 217 | struct hrtimer ckc_timer; | 217 | struct hrtimer ckc_timer; |
| 218 | struct tasklet_struct tasklet; | 218 | struct tasklet_struct tasklet; |
| 219 | union { | 219 | union { |
| 220 | cpuid_t cpu_id; | 220 | struct cpuid cpu_id; |
| 221 | u64 stidp_data; | 221 | u64 stidp_data; |
| 222 | }; | 222 | }; |
| 223 | }; | 223 | }; |
| 224 | 224 | ||
diff --git a/arch/s390/include/asm/kvm_virtio.h b/arch/s390/include/asm/kvm_virtio.h index 0503936f101f..acdfdff26611 100644 --- a/arch/s390/include/asm/kvm_virtio.h +++ b/arch/s390/include/asm/kvm_virtio.h | |||
| @@ -54,14 +54,4 @@ struct kvm_vqconfig { | |||
| 54 | * This is pagesize for historical reasons. */ | 54 | * This is pagesize for historical reasons. */ |
| 55 | #define KVM_S390_VIRTIO_RING_ALIGN 4096 | 55 | #define KVM_S390_VIRTIO_RING_ALIGN 4096 |
| 56 | 56 | ||
| 57 | #ifdef __KERNEL__ | ||
| 58 | /* early virtio console setup */ | ||
| 59 | #ifdef CONFIG_S390_GUEST | ||
| 60 | extern void s390_virtio_console_init(void); | ||
| 61 | #else | ||
| 62 | static inline void s390_virtio_console_init(void) | ||
| 63 | { | ||
| 64 | } | ||
| 65 | #endif /* CONFIG_VIRTIO_CONSOLE */ | ||
| 66 | #endif /* __KERNEL__ */ | ||
| 67 | #endif | 57 | #endif |
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index 5046ad6b7a63..6bc9426a6fbf 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h | |||
| @@ -132,7 +132,7 @@ | |||
| 132 | 132 | ||
| 133 | #ifndef __ASSEMBLY__ | 133 | #ifndef __ASSEMBLY__ |
| 134 | 134 | ||
| 135 | #include <asm/cpuid.h> | 135 | #include <asm/cpu.h> |
| 136 | #include <asm/ptrace.h> | 136 | #include <asm/ptrace.h> |
| 137 | #include <linux/types.h> | 137 | #include <linux/types.h> |
| 138 | 138 | ||
| @@ -275,7 +275,7 @@ struct _lowcore | |||
| 275 | __u32 user_exec_asce; /* 0x02ac */ | 275 | __u32 user_exec_asce; /* 0x02ac */ |
| 276 | 276 | ||
| 277 | /* SMP info area */ | 277 | /* SMP info area */ |
| 278 | cpuid_t cpu_id; /* 0x02b0 */ | 278 | struct cpuid cpu_id; /* 0x02b0 */ |
| 279 | __u32 cpu_nr; /* 0x02b8 */ | 279 | __u32 cpu_nr; /* 0x02b8 */ |
| 280 | __u32 softirq_pending; /* 0x02bc */ | 280 | __u32 softirq_pending; /* 0x02bc */ |
| 281 | __u32 percpu_offset; /* 0x02c0 */ | 281 | __u32 percpu_offset; /* 0x02c0 */ |
| @@ -380,7 +380,7 @@ struct _lowcore | |||
| 380 | __u64 user_exec_asce; /* 0x0318 */ | 380 | __u64 user_exec_asce; /* 0x0318 */ |
| 381 | 381 | ||
| 382 | /* SMP info area */ | 382 | /* SMP info area */ |
| 383 | cpuid_t cpu_id; /* 0x0320 */ | 383 | struct cpuid cpu_id; /* 0x0320 */ |
| 384 | __u32 cpu_nr; /* 0x0328 */ | 384 | __u32 cpu_nr; /* 0x0328 */ |
| 385 | __u32 softirq_pending; /* 0x032c */ | 385 | __u32 softirq_pending; /* 0x032c */ |
| 386 | __u64 percpu_offset; /* 0x0330 */ | 386 | __u64 percpu_offset; /* 0x0330 */ |
diff --git a/arch/s390/include/asm/mmu.h b/arch/s390/include/asm/mmu.h index 3b59216e6284..03be99919d62 100644 --- a/arch/s390/include/asm/mmu.h +++ b/arch/s390/include/asm/mmu.h | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #define __MMU_H | 2 | #define __MMU_H |
| 3 | 3 | ||
| 4 | typedef struct { | 4 | typedef struct { |
| 5 | spinlock_t list_lock; | ||
| 5 | struct list_head crst_list; | 6 | struct list_head crst_list; |
| 6 | struct list_head pgtable_list; | 7 | struct list_head pgtable_list; |
| 7 | unsigned long asce_bits; | 8 | unsigned long asce_bits; |
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h index 3e3594d01f83..5e9daf5d7f22 100644 --- a/arch/s390/include/asm/page.h +++ b/arch/s390/include/asm/page.h | |||
| @@ -125,8 +125,6 @@ page_get_storage_key(unsigned long addr) | |||
| 125 | return skey; | 125 | return skey; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | #ifdef CONFIG_PAGE_STATES | ||
| 129 | |||
| 130 | struct page; | 128 | struct page; |
| 131 | void arch_free_page(struct page *page, int order); | 129 | void arch_free_page(struct page *page, int order); |
| 132 | void arch_alloc_page(struct page *page, int order); | 130 | void arch_alloc_page(struct page *page, int order); |
| @@ -134,8 +132,6 @@ void arch_alloc_page(struct page *page, int order); | |||
| 134 | #define HAVE_ARCH_FREE_PAGE | 132 | #define HAVE_ARCH_FREE_PAGE |
| 135 | #define HAVE_ARCH_ALLOC_PAGE | 133 | #define HAVE_ARCH_ALLOC_PAGE |
| 136 | 134 | ||
| 137 | #endif | ||
| 138 | |||
| 139 | #endif /* !__ASSEMBLY__ */ | 135 | #endif /* !__ASSEMBLY__ */ |
| 140 | 136 | ||
| 141 | #define __PAGE_OFFSET 0x0UL | 137 | #define __PAGE_OFFSET 0x0UL |
diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h index b2658b9220fe..ddad5903341c 100644 --- a/arch/s390/include/asm/pgalloc.h +++ b/arch/s390/include/asm/pgalloc.h | |||
| @@ -140,6 +140,7 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) | |||
| 140 | 140 | ||
| 141 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) | 141 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) |
| 142 | { | 142 | { |
| 143 | spin_lock_init(&mm->context.list_lock); | ||
| 143 | INIT_LIST_HEAD(&mm->context.crst_list); | 144 | INIT_LIST_HEAD(&mm->context.crst_list); |
| 144 | INIT_LIST_HEAD(&mm->context.pgtable_list); | 145 | INIT_LIST_HEAD(&mm->context.pgtable_list); |
| 145 | return (pgd_t *) crst_table_alloc(mm, s390_noexec); | 146 | return (pgd_t *) crst_table_alloc(mm, s390_noexec); |
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index c139fa7b8e89..cf8eed3fa779 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | #define __ASM_S390_PROCESSOR_H | 14 | #define __ASM_S390_PROCESSOR_H |
| 15 | 15 | ||
| 16 | #include <linux/linkage.h> | 16 | #include <linux/linkage.h> |
| 17 | #include <asm/cpuid.h> | 17 | #include <asm/cpu.h> |
| 18 | #include <asm/page.h> | 18 | #include <asm/page.h> |
| 19 | #include <asm/ptrace.h> | 19 | #include <asm/ptrace.h> |
| 20 | #include <asm/setup.h> | 20 | #include <asm/setup.h> |
| @@ -26,7 +26,7 @@ | |||
| 26 | */ | 26 | */ |
| 27 | #define current_text_addr() ({ void *pc; asm("basr %0,0" : "=a" (pc)); pc; }) | 27 | #define current_text_addr() ({ void *pc; asm("basr %0,0" : "=a" (pc)); pc; }) |
| 28 | 28 | ||
| 29 | static inline void get_cpu_id(cpuid_t *ptr) | 29 | static inline void get_cpu_id(struct cpuid *ptr) |
| 30 | { | 30 | { |
| 31 | asm volatile("stidp 0(%1)" : "=m" (*ptr) : "a" (ptr)); | 31 | asm volatile("stidp 0(%1)" : "=m" (*ptr) : "a" (ptr)); |
| 32 | } | 32 | } |
diff --git a/arch/s390/include/asm/scatterlist.h b/arch/s390/include/asm/scatterlist.h index 29ec8e28c8df..35d786fe93ae 100644 --- a/arch/s390/include/asm/scatterlist.h +++ b/arch/s390/include/asm/scatterlist.h | |||
| @@ -1,19 +1 @@ | |||
| 1 | #ifndef _ASMS390_SCATTERLIST_H | #include <asm-generic/scatterlist.h> | |
| 2 | #define _ASMS390_SCATTERLIST_H | ||
| 3 | |||
| 4 | struct scatterlist { | ||
| 5 | #ifdef CONFIG_DEBUG_SG | ||
| 6 | unsigned long sg_magic; | ||
| 7 | #endif | ||
| 8 | unsigned long page_link; | ||
| 9 | unsigned int offset; | ||
| 10 | unsigned int length; | ||
| 11 | }; | ||
| 12 | |||
| 13 | #ifdef __s390x__ | ||
| 14 | #define ISA_DMA_THRESHOLD (0xffffffffffffffffUL) | ||
| 15 | #else | ||
| 16 | #define ISA_DMA_THRESHOLD (0xffffffffUL) | ||
| 17 | #endif | ||
| 18 | |||
| 19 | #endif /* _ASMS390X_SCATTERLIST_H */ | ||
diff --git a/arch/s390/include/asm/scsw.h b/arch/s390/include/asm/scsw.h new file mode 100644 index 000000000000..de389cb54d28 --- /dev/null +++ b/arch/s390/include/asm/scsw.h | |||
| @@ -0,0 +1,956 @@ | |||
| 1 | /* | ||
| 2 | * Helper functions for scsw access. | ||
| 3 | * | ||
| 4 | * Copyright IBM Corp. 2008,2009 | ||
| 5 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef _ASM_S390_SCSW_H_ | ||
| 9 | #define _ASM_S390_SCSW_H_ | ||
| 10 | |||
| 11 | #include <linux/types.h> | ||
| 12 | #include <asm/chsc.h> | ||
| 13 | #include <asm/cio.h> | ||
| 14 | |||
| 15 | /** | ||
| 16 | * struct cmd_scsw - command-mode subchannel status word | ||
| 17 | * @key: subchannel key | ||
| 18 | * @sctl: suspend control | ||
| 19 | * @eswf: esw format | ||
| 20 | * @cc: deferred condition code | ||
| 21 | * @fmt: format | ||
| 22 | * @pfch: prefetch | ||
| 23 | * @isic: initial-status interruption control | ||
| 24 | * @alcc: address-limit checking control | ||
| 25 | * @ssi: suppress-suspended interruption | ||
| 26 | * @zcc: zero condition code | ||
| 27 | * @ectl: extended control | ||
| 28 | * @pno: path not operational | ||
| 29 | * @res: reserved | ||
| 30 | * @fctl: function control | ||
| 31 | * @actl: activity control | ||
| 32 | * @stctl: status control | ||
| 33 | * @cpa: channel program address | ||
| 34 | * @dstat: device status | ||
| 35 | * @cstat: subchannel status | ||
| 36 | * @count: residual count | ||
| 37 | */ | ||
| 38 | struct cmd_scsw { | ||
| 39 | __u32 key : 4; | ||
| 40 | __u32 sctl : 1; | ||
| 41 | __u32 eswf : 1; | ||
| 42 | __u32 cc : 2; | ||
| 43 | __u32 fmt : 1; | ||
| 44 | __u32 pfch : 1; | ||
| 45 | __u32 isic : 1; | ||
| 46 | __u32 alcc : 1; | ||
| 47 | __u32 ssi : 1; | ||
| 48 | __u32 zcc : 1; | ||
| 49 | __u32 ectl : 1; | ||
| 50 | __u32 pno : 1; | ||
| 51 | __u32 res : 1; | ||
| 52 | __u32 fctl : 3; | ||
| 53 | __u32 actl : 7; | ||
| 54 | __u32 stctl : 5; | ||
| 55 | __u32 cpa; | ||
| 56 | __u32 dstat : 8; | ||
| 57 | __u32 cstat : 8; | ||
| 58 | __u32 count : 16; | ||
| 59 | } __attribute__ ((packed)); | ||
| 60 | |||
| 61 | /** | ||
| 62 | * struct tm_scsw - transport-mode subchannel status word | ||
| 63 | * @key: subchannel key | ||
| 64 | * @eswf: esw format | ||
| 65 | * @cc: deferred condition code | ||
| 66 | * @fmt: format | ||
| 67 | * @x: IRB-format control | ||
| 68 | * @q: interrogate-complete | ||
| 69 | * @ectl: extended control | ||
| 70 | * @pno: path not operational | ||
| 71 | * @fctl: function control | ||
| 72 | * @actl: activity control | ||
| 73 | * @stctl: status control | ||
| 74 | * @tcw: TCW address | ||
| 75 | * @dstat: device status | ||
| 76 | * @cstat: subchannel status | ||
| 77 | * @fcxs: FCX status | ||
| 78 | * @schxs: subchannel-extended status | ||
| 79 | */ | ||
| 80 | struct tm_scsw { | ||
| 81 | u32 key:4; | ||
| 82 | u32 :1; | ||
| 83 | u32 eswf:1; | ||
| 84 | u32 cc:2; | ||
| 85 | u32 fmt:3; | ||
| 86 | u32 x:1; | ||
| 87 | u32 q:1; | ||
| 88 | u32 :1; | ||
| 89 | u32 ectl:1; | ||
| 90 | u32 pno:1; | ||
| 91 | u32 :1; | ||
| 92 | u32 fctl:3; | ||
| 93 | u32 actl:7; | ||
| 94 | u32 stctl:5; | ||
| 95 | u32 tcw; | ||
| 96 | u32 dstat:8; | ||
| 97 | u32 cstat:8; | ||
| 98 | u32 fcxs:8; | ||
| 99 | u32 schxs:8; | ||
| 100 | } __attribute__ ((packed)); | ||
| 101 | |||
| 102 | /** | ||
| 103 | * union scsw - subchannel status word | ||
| 104 | * @cmd: command-mode SCSW | ||
| 105 | * @tm: transport-mode SCSW | ||
| 106 | */ | ||
| 107 | union scsw { | ||
| 108 | struct cmd_scsw cmd; | ||
| 109 | struct tm_scsw tm; | ||
| 110 | } __attribute__ ((packed)); | ||
| 111 | |||
| 112 | #define SCSW_FCTL_CLEAR_FUNC 0x1 | ||
| 113 | #define SCSW_FCTL_HALT_FUNC 0x2 | ||
| 114 | #define SCSW_FCTL_START_FUNC 0x4 | ||
| 115 | |||
| 116 | #define SCSW_ACTL_SUSPENDED 0x1 | ||
| 117 | #define SCSW_ACTL_DEVACT 0x2 | ||
| 118 | #define SCSW_ACTL_SCHACT 0x4 | ||
| 119 | #define SCSW_ACTL_CLEAR_PEND 0x8 | ||
| 120 | #define SCSW_ACTL_HALT_PEND 0x10 | ||
| 121 | #define SCSW_ACTL_START_PEND 0x20 | ||
| 122 | #define SCSW_ACTL_RESUME_PEND 0x40 | ||
| 123 | |||
| 124 | #define SCSW_STCTL_STATUS_PEND 0x1 | ||
| 125 | #define SCSW_STCTL_SEC_STATUS 0x2 | ||
| 126 | #define SCSW_STCTL_PRIM_STATUS 0x4 | ||
| 127 | #define SCSW_STCTL_INTER_STATUS 0x8 | ||
| 128 | #define SCSW_STCTL_ALERT_STATUS 0x10 | ||
| 129 | |||
| 130 | #define DEV_STAT_ATTENTION 0x80 | ||
| 131 | #define DEV_STAT_STAT_MOD 0x40 | ||
| 132 | #define DEV_STAT_CU_END 0x20 | ||
| 133 | #define DEV_STAT_BUSY 0x10 | ||
| 134 | #define DEV_STAT_CHN_END 0x08 | ||
| 135 | #define DEV_STAT_DEV_END 0x04 | ||
| 136 | #define DEV_STAT_UNIT_CHECK 0x02 | ||
| 137 | #define DEV_STAT_UNIT_EXCEP 0x01 | ||
| 138 | |||
| 139 | #define SCHN_STAT_PCI 0x80 | ||
| 140 | #define SCHN_STAT_INCORR_LEN 0x40 | ||
| 141 | #define SCHN_STAT_PROG_CHECK 0x20 | ||
| 142 | #define SCHN_STAT_PROT_CHECK 0x10 | ||
| 143 | #define SCHN_STAT_CHN_DATA_CHK 0x08 | ||
| 144 | #define SCHN_STAT_CHN_CTRL_CHK 0x04 | ||
| 145 | #define SCHN_STAT_INTF_CTRL_CHK 0x02 | ||
| 146 | #define SCHN_STAT_CHAIN_CHECK 0x01 | ||
| 147 | |||
| 148 | /* | ||
| 149 | * architectured values for first sense byte | ||
| 150 | */ | ||
| 151 | #define SNS0_CMD_REJECT 0x80 | ||
| 152 | #define SNS_CMD_REJECT SNS0_CMD_REJEC | ||
| 153 | #define SNS0_INTERVENTION_REQ 0x40 | ||
| 154 | #define SNS0_BUS_OUT_CHECK 0x20 | ||
| 155 | #define SNS0_EQUIPMENT_CHECK 0x10 | ||
| 156 | #define SNS0_DATA_CHECK 0x08 | ||
| 157 | #define SNS0_OVERRUN 0x04 | ||
| 158 | #define SNS0_INCOMPL_DOMAIN 0x01 | ||
| 159 | |||
| 160 | /* | ||
| 161 | * architectured values for second sense byte | ||
| 162 | */ | ||
| 163 | #define SNS1_PERM_ERR 0x80 | ||
| 164 | #define SNS1_INV_TRACK_FORMAT 0x40 | ||
| 165 | #define SNS1_EOC 0x20 | ||
| 166 | #define SNS1_MESSAGE_TO_OPER 0x10 | ||
| 167 | #define SNS1_NO_REC_FOUND 0x08 | ||
| 168 | #define SNS1_FILE_PROTECTED 0x04 | ||
| 169 | #define SNS1_WRITE_INHIBITED 0x02 | ||
| 170 | #define SNS1_INPRECISE_END 0x01 | ||
| 171 | |||
| 172 | /* | ||
| 173 | * architectured values for third sense byte | ||
| 174 | */ | ||
| 175 | #define SNS2_REQ_INH_WRITE 0x80 | ||
| 176 | #define SNS2_CORRECTABLE 0x40 | ||
| 177 | #define SNS2_FIRST_LOG_ERR 0x20 | ||
| 178 | #define SNS2_ENV_DATA_PRESENT 0x10 | ||
| 179 | #define SNS2_INPRECISE_END 0x04 | ||
| 180 | |||
| 181 | /** | ||
| 182 | * scsw_is_tm - check for transport mode scsw | ||
| 183 | * @scsw: pointer to scsw | ||
| 184 | * | ||
| 185 | * Return non-zero if the specified scsw is a transport mode scsw, zero | ||
| 186 | * otherwise. | ||
| 187 | */ | ||
| 188 | static inline int scsw_is_tm(union scsw *scsw) | ||
| 189 | { | ||
| 190 | return css_general_characteristics.fcx && (scsw->tm.x == 1); | ||
| 191 | } | ||
| 192 | |||
| 193 | /** | ||
| 194 | * scsw_key - return scsw key field | ||
| 195 | * @scsw: pointer to scsw | ||
| 196 | * | ||
| 197 | * Return the value of the key field of the specified scsw, regardless of | ||
| 198 | * whether it is a transport mode or command mode scsw. | ||
| 199 | */ | ||
| 200 | static inline u32 scsw_key(union scsw *scsw) | ||
| 201 | { | ||
| 202 | if (scsw_is_tm(scsw)) | ||
| 203 | return scsw->tm.key; | ||
| 204 | else | ||
| 205 | return scsw->cmd.key; | ||
| 206 | } | ||
| 207 | |||
| 208 | /** | ||
| 209 | * scsw_eswf - return scsw eswf field | ||
| 210 | * @scsw: pointer to scsw | ||
| 211 | * | ||
| 212 | * Return the value of the eswf field of the specified scsw, regardless of | ||
| 213 | * whether it is a transport mode or command mode scsw. | ||
| 214 | */ | ||
| 215 | static inline u32 scsw_eswf(union scsw *scsw) | ||
| 216 | { | ||
| 217 | if (scsw_is_tm(scsw)) | ||
| 218 | return scsw->tm.eswf; | ||
| 219 | else | ||
| 220 | return scsw->cmd.eswf; | ||
| 221 | } | ||
| 222 | |||
| 223 | /** | ||
| 224 | * scsw_cc - return scsw cc field | ||
| 225 | * @scsw: pointer to scsw | ||
| 226 | * | ||
| 227 | * Return the value of the cc field of the specified scsw, regardless of | ||
| 228 | * whether it is a transport mode or command mode scsw. | ||
| 229 | */ | ||
| 230 | static inline u32 scsw_cc(union scsw *scsw) | ||
| 231 | { | ||
| 232 | if (scsw_is_tm(scsw)) | ||
| 233 | return scsw->tm.cc; | ||
| 234 | else | ||
| 235 | return scsw->cmd.cc; | ||
| 236 | } | ||
| 237 | |||
| 238 | /** | ||
| 239 | * scsw_ectl - return scsw ectl field | ||
| 240 | * @scsw: pointer to scsw | ||
| 241 | * | ||
| 242 | * Return the value of the ectl field of the specified scsw, regardless of | ||
| 243 | * whether it is a transport mode or command mode scsw. | ||
| 244 | */ | ||
| 245 | static inline u32 scsw_ectl(union scsw *scsw) | ||
| 246 | { | ||
| 247 | if (scsw_is_tm(scsw)) | ||
| 248 | return scsw->tm.ectl; | ||
| 249 | else | ||
| 250 | return scsw->cmd.ectl; | ||
| 251 | } | ||
| 252 | |||
| 253 | /** | ||
| 254 | * scsw_pno - return scsw pno field | ||
| 255 | * @scsw: pointer to scsw | ||
| 256 | * | ||
| 257 | * Return the value of the pno field of the specified scsw, regardless of | ||
| 258 | * whether it is a transport mode or command mode scsw. | ||
| 259 | */ | ||
| 260 | static inline u32 scsw_pno(union scsw *scsw) | ||
| 261 | { | ||
| 262 | if (scsw_is_tm(scsw)) | ||
| 263 | return scsw->tm.pno; | ||
| 264 | else | ||
| 265 | return scsw->cmd.pno; | ||
| 266 | } | ||
| 267 | |||
| 268 | /** | ||
| 269 | * scsw_fctl - return scsw fctl field | ||
| 270 | * @scsw: pointer to scsw | ||
| 271 | * | ||
| 272 | * Return the value of the fctl field of the specified scsw, regardless of | ||
| 273 | * whether it is a transport mode or command mode scsw. | ||
| 274 | */ | ||
| 275 | static inline u32 scsw_fctl(union scsw *scsw) | ||
| 276 | { | ||
| 277 | if (scsw_is_tm(scsw)) | ||
| 278 | return scsw->tm.fctl; | ||
| 279 | else | ||
| 280 | return scsw->cmd.fctl; | ||
| 281 | } | ||
| 282 | |||
| 283 | /** | ||
| 284 | * scsw_actl - return scsw actl field | ||
| 285 | * @scsw: pointer to scsw | ||
| 286 | * | ||
| 287 | * Return the value of the actl field of the specified scsw, regardless of | ||
| 288 | * whether it is a transport mode or command mode scsw. | ||
| 289 | */ | ||
| 290 | static inline u32 scsw_actl(union scsw *scsw) | ||
| 291 | { | ||
| 292 | if (scsw_is_tm(scsw)) | ||
| 293 | return scsw->tm.actl; | ||
| 294 | else | ||
| 295 | return scsw->cmd.actl; | ||
| 296 | } | ||
| 297 | |||
| 298 | /** | ||
| 299 | * scsw_stctl - return scsw stctl field | ||
| 300 | * @scsw: pointer to scsw | ||
| 301 | * | ||
| 302 | * Return the value of the stctl field of the specified scsw, regardless of | ||
| 303 | * whether it is a transport mode or command mode scsw. | ||
| 304 | */ | ||
| 305 | static inline u32 scsw_stctl(union scsw *scsw) | ||
| 306 | { | ||
| 307 | if (scsw_is_tm(scsw)) | ||
| 308 | return scsw->tm.stctl; | ||
| 309 | else | ||
| 310 | return scsw->cmd.stctl; | ||
| 311 | } | ||
| 312 | |||
| 313 | /** | ||
| 314 | * scsw_dstat - return scsw dstat field | ||
| 315 | * @scsw: pointer to scsw | ||
| 316 | * | ||
| 317 | * Return the value of the dstat field of the specified scsw, regardless of | ||
| 318 | * whether it is a transport mode or command mode scsw. | ||
| 319 | */ | ||
| 320 | static inline u32 scsw_dstat(union scsw *scsw) | ||
| 321 | { | ||
| 322 | if (scsw_is_tm(scsw)) | ||
| 323 | return scsw->tm.dstat; | ||
| 324 | else | ||
| 325 | return scsw->cmd.dstat; | ||
| 326 | } | ||
| 327 | |||
| 328 | /** | ||
| 329 | * scsw_cstat - return scsw cstat field | ||
| 330 | * @scsw: pointer to scsw | ||
| 331 | * | ||
| 332 | * Return the value of the cstat field of the specified scsw, regardless of | ||
| 333 | * whether it is a transport mode or command mode scsw. | ||
| 334 | */ | ||
| 335 | static inline u32 scsw_cstat(union scsw *scsw) | ||
| 336 | { | ||
| 337 | if (scsw_is_tm(scsw)) | ||
| 338 | return scsw->tm.cstat; | ||
| 339 | else | ||
| 340 | return scsw->cmd.cstat; | ||
| 341 | } | ||
| 342 | |||
| 343 | /** | ||
| 344 | * scsw_cmd_is_valid_key - check key field validity | ||
| 345 | * @scsw: pointer to scsw | ||
| 346 | * | ||
| 347 | * Return non-zero if the key field of the specified command mode scsw is | ||
| 348 | * valid, zero otherwise. | ||
| 349 | */ | ||
| 350 | static inline int scsw_cmd_is_valid_key(union scsw *scsw) | ||
| 351 | { | ||
| 352 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
| 353 | } | ||
| 354 | |||
| 355 | /** | ||
| 356 | * scsw_cmd_is_valid_sctl - check fctl field validity | ||
| 357 | * @scsw: pointer to scsw | ||
| 358 | * | ||
| 359 | * Return non-zero if the fctl field of the specified command mode scsw is | ||
| 360 | * valid, zero otherwise. | ||
| 361 | */ | ||
| 362 | static inline int scsw_cmd_is_valid_sctl(union scsw *scsw) | ||
| 363 | { | ||
| 364 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
| 365 | } | ||
| 366 | |||
| 367 | /** | ||
| 368 | * scsw_cmd_is_valid_eswf - check eswf field validity | ||
| 369 | * @scsw: pointer to scsw | ||
| 370 | * | ||
| 371 | * Return non-zero if the eswf field of the specified command mode scsw is | ||
| 372 | * valid, zero otherwise. | ||
| 373 | */ | ||
| 374 | static inline int scsw_cmd_is_valid_eswf(union scsw *scsw) | ||
| 375 | { | ||
| 376 | return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND); | ||
| 377 | } | ||
| 378 | |||
| 379 | /** | ||
| 380 | * scsw_cmd_is_valid_cc - check cc field validity | ||
| 381 | * @scsw: pointer to scsw | ||
| 382 | * | ||
| 383 | * Return non-zero if the cc field of the specified command mode scsw is | ||
| 384 | * valid, zero otherwise. | ||
| 385 | */ | ||
| 386 | static inline int scsw_cmd_is_valid_cc(union scsw *scsw) | ||
| 387 | { | ||
| 388 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC) && | ||
| 389 | (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND); | ||
| 390 | } | ||
| 391 | |||
| 392 | /** | ||
| 393 | * scsw_cmd_is_valid_fmt - check fmt field validity | ||
| 394 | * @scsw: pointer to scsw | ||
| 395 | * | ||
| 396 | * Return non-zero if the fmt field of the specified command mode scsw is | ||
| 397 | * valid, zero otherwise. | ||
| 398 | */ | ||
| 399 | static inline int scsw_cmd_is_valid_fmt(union scsw *scsw) | ||
| 400 | { | ||
| 401 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
| 402 | } | ||
| 403 | |||
| 404 | /** | ||
| 405 | * scsw_cmd_is_valid_pfch - check pfch field validity | ||
| 406 | * @scsw: pointer to scsw | ||
| 407 | * | ||
| 408 | * Return non-zero if the pfch field of the specified command mode scsw is | ||
| 409 | * valid, zero otherwise. | ||
| 410 | */ | ||
| 411 | static inline int scsw_cmd_is_valid_pfch(union scsw *scsw) | ||
| 412 | { | ||
| 413 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
| 414 | } | ||
| 415 | |||
| 416 | /** | ||
| 417 | * scsw_cmd_is_valid_isic - check isic field validity | ||
| 418 | * @scsw: pointer to scsw | ||
| 419 | * | ||
| 420 | * Return non-zero if the isic field of the specified command mode scsw is | ||
| 421 | * valid, zero otherwise. | ||
| 422 | */ | ||
| 423 | static inline int scsw_cmd_is_valid_isic(union scsw *scsw) | ||
| 424 | { | ||
| 425 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
| 426 | } | ||
| 427 | |||
| 428 | /** | ||
| 429 | * scsw_cmd_is_valid_alcc - check alcc field validity | ||
| 430 | * @scsw: pointer to scsw | ||
| 431 | * | ||
| 432 | * Return non-zero if the alcc field of the specified command mode scsw is | ||
| 433 | * valid, zero otherwise. | ||
| 434 | */ | ||
| 435 | static inline int scsw_cmd_is_valid_alcc(union scsw *scsw) | ||
| 436 | { | ||
| 437 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
| 438 | } | ||
| 439 | |||
| 440 | /** | ||
| 441 | * scsw_cmd_is_valid_ssi - check ssi field validity | ||
| 442 | * @scsw: pointer to scsw | ||
| 443 | * | ||
| 444 | * Return non-zero if the ssi field of the specified command mode scsw is | ||
| 445 | * valid, zero otherwise. | ||
| 446 | */ | ||
| 447 | static inline int scsw_cmd_is_valid_ssi(union scsw *scsw) | ||
| 448 | { | ||
| 449 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | ||
| 450 | } | ||
| 451 | |||
| 452 | /** | ||
| 453 | * scsw_cmd_is_valid_zcc - check zcc field validity | ||
| 454 | * @scsw: pointer to scsw | ||
| 455 | * | ||
| 456 | * Return non-zero if the zcc field of the specified command mode scsw is | ||
| 457 | * valid, zero otherwise. | ||
| 458 | */ | ||
| 459 | static inline int scsw_cmd_is_valid_zcc(union scsw *scsw) | ||
| 460 | { | ||
| 461 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC) && | ||
| 462 | (scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS); | ||
| 463 | } | ||
| 464 | |||
| 465 | /** | ||
| 466 | * scsw_cmd_is_valid_ectl - check ectl field validity | ||
| 467 | * @scsw: pointer to scsw | ||
| 468 | * | ||
| 469 | * Return non-zero if the ectl field of the specified command mode scsw is | ||
| 470 | * valid, zero otherwise. | ||
| 471 | */ | ||
| 472 | static inline int scsw_cmd_is_valid_ectl(union scsw *scsw) | ||
| 473 | { | ||
| 474 | return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && | ||
| 475 | !(scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) && | ||
| 476 | (scsw->cmd.stctl & SCSW_STCTL_ALERT_STATUS); | ||
| 477 | } | ||
| 478 | |||
| 479 | /** | ||
| 480 | * scsw_cmd_is_valid_pno - check pno field validity | ||
| 481 | * @scsw: pointer to scsw | ||
| 482 | * | ||
| 483 | * Return non-zero if the pno field of the specified command mode scsw is | ||
| 484 | * valid, zero otherwise. | ||
| 485 | */ | ||
| 486 | static inline int scsw_cmd_is_valid_pno(union scsw *scsw) | ||
| 487 | { | ||
| 488 | return (scsw->cmd.fctl != 0) && | ||
| 489 | (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && | ||
| 490 | (!(scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) || | ||
| 491 | ((scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) && | ||
| 492 | (scsw->cmd.actl & SCSW_ACTL_SUSPENDED))); | ||
| 493 | } | ||
| 494 | |||
| 495 | /** | ||
| 496 | * scsw_cmd_is_valid_fctl - check fctl field validity | ||
| 497 | * @scsw: pointer to scsw | ||
| 498 | * | ||
| 499 | * Return non-zero if the fctl field of the specified command mode scsw is | ||
| 500 | * valid, zero otherwise. | ||
| 501 | */ | ||
| 502 | static inline int scsw_cmd_is_valid_fctl(union scsw *scsw) | ||
| 503 | { | ||
| 504 | /* Only valid if pmcw.dnv == 1*/ | ||
| 505 | return 1; | ||
| 506 | } | ||
| 507 | |||
| 508 | /** | ||
| 509 | * scsw_cmd_is_valid_actl - check actl field validity | ||
| 510 | * @scsw: pointer to scsw | ||
| 511 | * | ||
| 512 | * Return non-zero if the actl field of the specified command mode scsw is | ||
| 513 | * valid, zero otherwise. | ||
| 514 | */ | ||
| 515 | static inline int scsw_cmd_is_valid_actl(union scsw *scsw) | ||
| 516 | { | ||
| 517 | /* Only valid if pmcw.dnv == 1*/ | ||
| 518 | return 1; | ||
| 519 | } | ||
| 520 | |||
| 521 | /** | ||
| 522 | * scsw_cmd_is_valid_stctl - check stctl field validity | ||
| 523 | * @scsw: pointer to scsw | ||
| 524 | * | ||
| 525 | * Return non-zero if the stctl field of the specified command mode scsw is | ||
| 526 | * valid, zero otherwise. | ||
| 527 | */ | ||
| 528 | static inline int scsw_cmd_is_valid_stctl(union scsw *scsw) | ||
| 529 | { | ||
| 530 | /* Only valid if pmcw.dnv == 1*/ | ||
| 531 | return 1; | ||
| 532 | } | ||
| 533 | |||
| 534 | /** | ||
| 535 | * scsw_cmd_is_valid_dstat - check dstat field validity | ||
| 536 | * @scsw: pointer to scsw | ||
| 537 | * | ||
| 538 | * Return non-zero if the dstat field of the specified command mode scsw is | ||
| 539 | * valid, zero otherwise. | ||
| 540 | */ | ||
| 541 | static inline int scsw_cmd_is_valid_dstat(union scsw *scsw) | ||
| 542 | { | ||
| 543 | return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && | ||
| 544 | (scsw->cmd.cc != 3); | ||
| 545 | } | ||
| 546 | |||
| 547 | /** | ||
| 548 | * scsw_cmd_is_valid_cstat - check cstat field validity | ||
| 549 | * @scsw: pointer to scsw | ||
| 550 | * | ||
| 551 | * Return non-zero if the cstat field of the specified command mode scsw is | ||
| 552 | * valid, zero otherwise. | ||
| 553 | */ | ||
| 554 | static inline int scsw_cmd_is_valid_cstat(union scsw *scsw) | ||
| 555 | { | ||
| 556 | return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && | ||
| 557 | (scsw->cmd.cc != 3); | ||
| 558 | } | ||
| 559 | |||
| 560 | /** | ||
| 561 | * scsw_tm_is_valid_key - check key field validity | ||
| 562 | * @scsw: pointer to scsw | ||
| 563 | * | ||
| 564 | * Return non-zero if the key field of the specified transport mode scsw is | ||
| 565 | * valid, zero otherwise. | ||
| 566 | */ | ||
| 567 | static inline int scsw_tm_is_valid_key(union scsw *scsw) | ||
| 568 | { | ||
| 569 | return (scsw->tm.fctl & SCSW_FCTL_START_FUNC); | ||
| 570 | } | ||
| 571 | |||
| 572 | /** | ||
| 573 | * scsw_tm_is_valid_eswf - check eswf field validity | ||
| 574 | * @scsw: pointer to scsw | ||
| 575 | * | ||
| 576 | * Return non-zero if the eswf field of the specified transport mode scsw is | ||
| 577 | * valid, zero otherwise. | ||
| 578 | */ | ||
| 579 | static inline int scsw_tm_is_valid_eswf(union scsw *scsw) | ||
| 580 | { | ||
| 581 | return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND); | ||
| 582 | } | ||
| 583 | |||
| 584 | /** | ||
| 585 | * scsw_tm_is_valid_cc - check cc field validity | ||
| 586 | * @scsw: pointer to scsw | ||
| 587 | * | ||
| 588 | * Return non-zero if the cc field of the specified transport mode scsw is | ||
| 589 | * valid, zero otherwise. | ||
| 590 | */ | ||
| 591 | static inline int scsw_tm_is_valid_cc(union scsw *scsw) | ||
| 592 | { | ||
| 593 | return (scsw->tm.fctl & SCSW_FCTL_START_FUNC) && | ||
| 594 | (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND); | ||
| 595 | } | ||
| 596 | |||
| 597 | /** | ||
| 598 | * scsw_tm_is_valid_fmt - check fmt field validity | ||
| 599 | * @scsw: pointer to scsw | ||
| 600 | * | ||
| 601 | * Return non-zero if the fmt field of the specified transport mode scsw is | ||
| 602 | * valid, zero otherwise. | ||
| 603 | */ | ||
| 604 | static inline int scsw_tm_is_valid_fmt(union scsw *scsw) | ||
| 605 | { | ||
| 606 | return 1; | ||
| 607 | } | ||
| 608 | |||
| 609 | /** | ||
| 610 | * scsw_tm_is_valid_x - check x field validity | ||
| 611 | * @scsw: pointer to scsw | ||
| 612 | * | ||
| 613 | * Return non-zero if the x field of the specified transport mode scsw is | ||
| 614 | * valid, zero otherwise. | ||
| 615 | */ | ||
| 616 | static inline int scsw_tm_is_valid_x(union scsw *scsw) | ||
| 617 | { | ||
| 618 | return 1; | ||
| 619 | } | ||
| 620 | |||
| 621 | /** | ||
| 622 | * scsw_tm_is_valid_q - check q field validity | ||
| 623 | * @scsw: pointer to scsw | ||
| 624 | * | ||
| 625 | * Return non-zero if the q field of the specified transport mode scsw is | ||
| 626 | * valid, zero otherwise. | ||
| 627 | */ | ||
| 628 | static inline int scsw_tm_is_valid_q(union scsw *scsw) | ||
| 629 | { | ||
| 630 | return 1; | ||
| 631 | } | ||
| 632 | |||
| 633 | /** | ||
| 634 | * scsw_tm_is_valid_ectl - check ectl field validity | ||
| 635 | * @scsw: pointer to scsw | ||
| 636 | * | ||
| 637 | * Return non-zero if the ectl field of the specified transport mode scsw is | ||
| 638 | * valid, zero otherwise. | ||
| 639 | */ | ||
| 640 | static inline int scsw_tm_is_valid_ectl(union scsw *scsw) | ||
| 641 | { | ||
| 642 | return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && | ||
| 643 | !(scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) && | ||
| 644 | (scsw->tm.stctl & SCSW_STCTL_ALERT_STATUS); | ||
| 645 | } | ||
| 646 | |||
| 647 | /** | ||
| 648 | * scsw_tm_is_valid_pno - check pno field validity | ||
| 649 | * @scsw: pointer to scsw | ||
| 650 | * | ||
| 651 | * Return non-zero if the pno field of the specified transport mode scsw is | ||
| 652 | * valid, zero otherwise. | ||
| 653 | */ | ||
| 654 | static inline int scsw_tm_is_valid_pno(union scsw *scsw) | ||
| 655 | { | ||
| 656 | return (scsw->tm.fctl != 0) && | ||
| 657 | (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && | ||
| 658 | (!(scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) || | ||
| 659 | ((scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) && | ||
| 660 | (scsw->tm.actl & SCSW_ACTL_SUSPENDED))); | ||
| 661 | } | ||
| 662 | |||
| 663 | /** | ||
| 664 | * scsw_tm_is_valid_fctl - check fctl field validity | ||
| 665 | * @scsw: pointer to scsw | ||
| 666 | * | ||
| 667 | * Return non-zero if the fctl field of the specified transport mode scsw is | ||
| 668 | * valid, zero otherwise. | ||
| 669 | */ | ||
| 670 | static inline int scsw_tm_is_valid_fctl(union scsw *scsw) | ||
| 671 | { | ||
| 672 | /* Only valid if pmcw.dnv == 1*/ | ||
| 673 | return 1; | ||
| 674 | } | ||
| 675 | |||
| 676 | /** | ||
| 677 | * scsw_tm_is_valid_actl - check actl field validity | ||
| 678 | * @scsw: pointer to scsw | ||
| 679 | * | ||
| 680 | * Return non-zero if the actl field of the specified transport mode scsw is | ||
| 681 | * valid, zero otherwise. | ||
| 682 | */ | ||
| 683 | static inline int scsw_tm_is_valid_actl(union scsw *scsw) | ||
| 684 | { | ||
| 685 | /* Only valid if pmcw.dnv == 1*/ | ||
| 686 | return 1; | ||
| 687 | } | ||
| 688 | |||
| 689 | /** | ||
| 690 | * scsw_tm_is_valid_stctl - check stctl field validity | ||
| 691 | * @scsw: pointer to scsw | ||
| 692 | * | ||
| 693 | * Return non-zero if the stctl field of the specified transport mode scsw is | ||
| 694 | * valid, zero otherwise. | ||
| 695 | */ | ||
| 696 | static inline int scsw_tm_is_valid_stctl(union scsw *scsw) | ||
| 697 | { | ||
| 698 | /* Only valid if pmcw.dnv == 1*/ | ||
| 699 | return 1; | ||
| 700 | } | ||
| 701 | |||
| 702 | /** | ||
| 703 | * scsw_tm_is_valid_dstat - check dstat field validity | ||
| 704 | * @scsw: pointer to scsw | ||
| 705 | * | ||
| 706 | * Return non-zero if the dstat field of the specified transport mode scsw is | ||
| 707 | * valid, zero otherwise. | ||
| 708 | */ | ||
| 709 | static inline int scsw_tm_is_valid_dstat(union scsw *scsw) | ||
| 710 | { | ||
| 711 | return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && | ||
| 712 | (scsw->tm.cc != 3); | ||
| 713 | } | ||
| 714 | |||
| 715 | /** | ||
| 716 | * scsw_tm_is_valid_cstat - check cstat field validity | ||
| 717 | * @scsw: pointer to scsw | ||
| 718 | * | ||
| 719 | * Return non-zero if the cstat field of the specified transport mode scsw is | ||
| 720 | * valid, zero otherwise. | ||
| 721 | */ | ||
| 722 | static inline int scsw_tm_is_valid_cstat(union scsw *scsw) | ||
| 723 | { | ||
| 724 | return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && | ||
| 725 | (scsw->tm.cc != 3); | ||
| 726 | } | ||
| 727 | |||
| 728 | /** | ||
| 729 | * scsw_tm_is_valid_fcxs - check fcxs field validity | ||
| 730 | * @scsw: pointer to scsw | ||
| 731 | * | ||
| 732 | * Return non-zero if the fcxs field of the specified transport mode scsw is | ||
| 733 | * valid, zero otherwise. | ||
| 734 | */ | ||
| 735 | static inline int scsw_tm_is_valid_fcxs(union scsw *scsw) | ||
| 736 | { | ||
| 737 | return 1; | ||
| 738 | } | ||
| 739 | |||
| 740 | /** | ||
| 741 | * scsw_tm_is_valid_schxs - check schxs field validity | ||
| 742 | * @scsw: pointer to scsw | ||
| 743 | * | ||
| 744 | * Return non-zero if the schxs field of the specified transport mode scsw is | ||
| 745 | * valid, zero otherwise. | ||
| 746 | */ | ||
| 747 | static inline int scsw_tm_is_valid_schxs(union scsw *scsw) | ||
| 748 | { | ||
| 749 | return (scsw->tm.cstat & (SCHN_STAT_PROG_CHECK | | ||
| 750 | SCHN_STAT_INTF_CTRL_CHK | | ||
| 751 | SCHN_STAT_PROT_CHECK | | ||
| 752 | SCHN_STAT_CHN_DATA_CHK)); | ||
| 753 | } | ||
| 754 | |||
| 755 | /** | ||
| 756 | * scsw_is_valid_actl - check actl field validity | ||
| 757 | * @scsw: pointer to scsw | ||
| 758 | * | ||
| 759 | * Return non-zero if the actl field of the specified scsw is valid, | ||
| 760 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 761 | * Return zero if the field does not contain a valid value. | ||
| 762 | */ | ||
| 763 | static inline int scsw_is_valid_actl(union scsw *scsw) | ||
| 764 | { | ||
| 765 | if (scsw_is_tm(scsw)) | ||
| 766 | return scsw_tm_is_valid_actl(scsw); | ||
| 767 | else | ||
| 768 | return scsw_cmd_is_valid_actl(scsw); | ||
| 769 | } | ||
| 770 | |||
| 771 | /** | ||
| 772 | * scsw_is_valid_cc - check cc field validity | ||
| 773 | * @scsw: pointer to scsw | ||
| 774 | * | ||
| 775 | * Return non-zero if the cc field of the specified scsw is valid, | ||
| 776 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 777 | * Return zero if the field does not contain a valid value. | ||
| 778 | */ | ||
| 779 | static inline int scsw_is_valid_cc(union scsw *scsw) | ||
| 780 | { | ||
| 781 | if (scsw_is_tm(scsw)) | ||
| 782 | return scsw_tm_is_valid_cc(scsw); | ||
| 783 | else | ||
| 784 | return scsw_cmd_is_valid_cc(scsw); | ||
| 785 | } | ||
| 786 | |||
| 787 | /** | ||
| 788 | * scsw_is_valid_cstat - check cstat field validity | ||
| 789 | * @scsw: pointer to scsw | ||
| 790 | * | ||
| 791 | * Return non-zero if the cstat field of the specified scsw is valid, | ||
| 792 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 793 | * Return zero if the field does not contain a valid value. | ||
| 794 | */ | ||
| 795 | static inline int scsw_is_valid_cstat(union scsw *scsw) | ||
| 796 | { | ||
| 797 | if (scsw_is_tm(scsw)) | ||
| 798 | return scsw_tm_is_valid_cstat(scsw); | ||
| 799 | else | ||
| 800 | return scsw_cmd_is_valid_cstat(scsw); | ||
| 801 | } | ||
| 802 | |||
| 803 | /** | ||
| 804 | * scsw_is_valid_dstat - check dstat field validity | ||
| 805 | * @scsw: pointer to scsw | ||
| 806 | * | ||
| 807 | * Return non-zero if the dstat field of the specified scsw is valid, | ||
| 808 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 809 | * Return zero if the field does not contain a valid value. | ||
| 810 | */ | ||
| 811 | static inline int scsw_is_valid_dstat(union scsw *scsw) | ||
| 812 | { | ||
| 813 | if (scsw_is_tm(scsw)) | ||
| 814 | return scsw_tm_is_valid_dstat(scsw); | ||
| 815 | else | ||
| 816 | return scsw_cmd_is_valid_dstat(scsw); | ||
| 817 | } | ||
| 818 | |||
| 819 | /** | ||
| 820 | * scsw_is_valid_ectl - check ectl field validity | ||
| 821 | * @scsw: pointer to scsw | ||
| 822 | * | ||
| 823 | * Return non-zero if the ectl field of the specified scsw is valid, | ||
| 824 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 825 | * Return zero if the field does not contain a valid value. | ||
| 826 | */ | ||
| 827 | static inline int scsw_is_valid_ectl(union scsw *scsw) | ||
| 828 | { | ||
| 829 | if (scsw_is_tm(scsw)) | ||
| 830 | return scsw_tm_is_valid_ectl(scsw); | ||
| 831 | else | ||
| 832 | return scsw_cmd_is_valid_ectl(scsw); | ||
| 833 | } | ||
| 834 | |||
| 835 | /** | ||
| 836 | * scsw_is_valid_eswf - check eswf field validity | ||
| 837 | * @scsw: pointer to scsw | ||
| 838 | * | ||
| 839 | * Return non-zero if the eswf field of the specified scsw is valid, | ||
| 840 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 841 | * Return zero if the field does not contain a valid value. | ||
| 842 | */ | ||
| 843 | static inline int scsw_is_valid_eswf(union scsw *scsw) | ||
| 844 | { | ||
| 845 | if (scsw_is_tm(scsw)) | ||
| 846 | return scsw_tm_is_valid_eswf(scsw); | ||
| 847 | else | ||
| 848 | return scsw_cmd_is_valid_eswf(scsw); | ||
| 849 | } | ||
| 850 | |||
| 851 | /** | ||
| 852 | * scsw_is_valid_fctl - check fctl field validity | ||
| 853 | * @scsw: pointer to scsw | ||
| 854 | * | ||
| 855 | * Return non-zero if the fctl field of the specified scsw is valid, | ||
| 856 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 857 | * Return zero if the field does not contain a valid value. | ||
| 858 | */ | ||
| 859 | static inline int scsw_is_valid_fctl(union scsw *scsw) | ||
| 860 | { | ||
| 861 | if (scsw_is_tm(scsw)) | ||
| 862 | return scsw_tm_is_valid_fctl(scsw); | ||
| 863 | else | ||
| 864 | return scsw_cmd_is_valid_fctl(scsw); | ||
| 865 | } | ||
| 866 | |||
| 867 | /** | ||
| 868 | * scsw_is_valid_key - check key field validity | ||
| 869 | * @scsw: pointer to scsw | ||
| 870 | * | ||
| 871 | * Return non-zero if the key field of the specified scsw is valid, | ||
| 872 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 873 | * Return zero if the field does not contain a valid value. | ||
| 874 | */ | ||
| 875 | static inline int scsw_is_valid_key(union scsw *scsw) | ||
| 876 | { | ||
| 877 | if (scsw_is_tm(scsw)) | ||
| 878 | return scsw_tm_is_valid_key(scsw); | ||
| 879 | else | ||
| 880 | return scsw_cmd_is_valid_key(scsw); | ||
| 881 | } | ||
| 882 | |||
| 883 | /** | ||
| 884 | * scsw_is_valid_pno - check pno field validity | ||
| 885 | * @scsw: pointer to scsw | ||
| 886 | * | ||
| 887 | * Return non-zero if the pno field of the specified scsw is valid, | ||
| 888 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 889 | * Return zero if the field does not contain a valid value. | ||
| 890 | */ | ||
| 891 | static inline int scsw_is_valid_pno(union scsw *scsw) | ||
| 892 | { | ||
| 893 | if (scsw_is_tm(scsw)) | ||
| 894 | return scsw_tm_is_valid_pno(scsw); | ||
| 895 | else | ||
| 896 | return scsw_cmd_is_valid_pno(scsw); | ||
| 897 | } | ||
| 898 | |||
| 899 | /** | ||
| 900 | * scsw_is_valid_stctl - check stctl field validity | ||
| 901 | * @scsw: pointer to scsw | ||
| 902 | * | ||
| 903 | * Return non-zero if the stctl field of the specified scsw is valid, | ||
| 904 | * regardless of whether it is a transport mode or command mode scsw. | ||
| 905 | * Return zero if the field does not contain a valid value. | ||
| 906 | */ | ||
| 907 | static inline int scsw_is_valid_stctl(union scsw *scsw) | ||
| 908 | { | ||
| 909 | if (scsw_is_tm(scsw)) | ||
| 910 | return scsw_tm_is_valid_stctl(scsw); | ||
| 911 | else | ||
| 912 | return scsw_cmd_is_valid_stctl(scsw); | ||
| 913 | } | ||
| 914 | |||
| 915 | /** | ||
| 916 | * scsw_cmd_is_solicited - check for solicited scsw | ||
| 917 | * @scsw: pointer to scsw | ||
| 918 | * | ||
| 919 | * Return non-zero if the command mode scsw indicates that the associated | ||
| 920 | * status condition is solicited, zero if it is unsolicited. | ||
| 921 | */ | ||
| 922 | static inline int scsw_cmd_is_solicited(union scsw *scsw) | ||
| 923 | { | ||
| 924 | return (scsw->cmd.cc != 0) || (scsw->cmd.stctl != | ||
| 925 | (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)); | ||
| 926 | } | ||
| 927 | |||
| 928 | /** | ||
| 929 | * scsw_tm_is_solicited - check for solicited scsw | ||
| 930 | * @scsw: pointer to scsw | ||
| 931 | * | ||
| 932 | * Return non-zero if the transport mode scsw indicates that the associated | ||
| 933 | * status condition is solicited, zero if it is unsolicited. | ||
| 934 | */ | ||
| 935 | static inline int scsw_tm_is_solicited(union scsw *scsw) | ||
| 936 | { | ||
| 937 | return (scsw->tm.cc != 0) || (scsw->tm.stctl != | ||
| 938 | (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)); | ||
| 939 | } | ||
| 940 | |||
| 941 | /** | ||
| 942 | * scsw_is_solicited - check for solicited scsw | ||
| 943 | * @scsw: pointer to scsw | ||
| 944 | * | ||
| 945 | * Return non-zero if the transport or command mode scsw indicates that the | ||
| 946 | * associated status condition is solicited, zero if it is unsolicited. | ||
| 947 | */ | ||
| 948 | static inline int scsw_is_solicited(union scsw *scsw) | ||
| 949 | { | ||
| 950 | if (scsw_is_tm(scsw)) | ||
| 951 | return scsw_tm_is_solicited(scsw); | ||
| 952 | else | ||
| 953 | return scsw_cmd_is_solicited(scsw); | ||
| 954 | } | ||
| 955 | |||
| 956 | #endif /* _ASM_S390_SCSW_H_ */ | ||
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 38b0fc221ed7..e37478e87286 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | #ifndef _ASM_S390_SETUP_H | 8 | #ifndef _ASM_S390_SETUP_H |
| 9 | #define _ASM_S390_SETUP_H | 9 | #define _ASM_S390_SETUP_H |
| 10 | 10 | ||
| 11 | #define COMMAND_LINE_SIZE 1024 | 11 | #define COMMAND_LINE_SIZE 4096 |
| 12 | 12 | ||
| 13 | #define ARCH_COMMAND_LINE_SIZE 896 | 13 | #define ARCH_COMMAND_LINE_SIZE 896 |
| 14 | 14 | ||
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index 72137bc907ac..c991fe6473c9 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h | |||
| @@ -51,32 +51,7 @@ extern void machine_power_off_smp(void); | |||
| 51 | #define PROC_CHANGE_PENALTY 20 /* Schedule penalty */ | 51 | #define PROC_CHANGE_PENALTY 20 /* Schedule penalty */ |
| 52 | 52 | ||
| 53 | #define raw_smp_processor_id() (S390_lowcore.cpu_nr) | 53 | #define raw_smp_processor_id() (S390_lowcore.cpu_nr) |
| 54 | 54 | #define cpu_logical_map(cpu) (cpu) | |
| 55 | /* | ||
| 56 | * returns 1 if cpu is in stopped/check stopped state or not operational | ||
| 57 | * returns 0 otherwise | ||
| 58 | */ | ||
| 59 | static inline int | ||
| 60 | smp_cpu_not_running(int cpu) | ||
| 61 | { | ||
| 62 | __u32 status; | ||
| 63 | |||
| 64 | switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) { | ||
| 65 | case sigp_order_code_accepted: | ||
| 66 | case sigp_status_stored: | ||
| 67 | /* Check for stopped and check stop state */ | ||
| 68 | if (status & 0x50) | ||
| 69 | return 1; | ||
| 70 | break; | ||
| 71 | case sigp_not_operational: | ||
| 72 | return 1; | ||
| 73 | default: | ||
| 74 | break; | ||
| 75 | } | ||
| 76 | return 0; | ||
| 77 | } | ||
| 78 | |||
| 79 | #define cpu_logical_map(cpu) (cpu) | ||
| 80 | 55 | ||
| 81 | extern int __cpu_disable (void); | 56 | extern int __cpu_disable (void); |
| 82 | extern void __cpu_die (unsigned int cpu); | 57 | extern void __cpu_die (unsigned int cpu); |
| @@ -91,11 +66,6 @@ extern void arch_send_call_function_ipi(cpumask_t mask); | |||
| 91 | 66 | ||
| 92 | #endif | 67 | #endif |
| 93 | 68 | ||
| 94 | #ifndef CONFIG_SMP | ||
| 95 | #define hard_smp_processor_id() 0 | ||
| 96 | #define smp_cpu_not_running(cpu) 1 | ||
| 97 | #endif | ||
| 98 | |||
| 99 | #ifdef CONFIG_HOTPLUG_CPU | 69 | #ifdef CONFIG_HOTPLUG_CPU |
| 100 | extern int smp_rescan_cpus(void); | 70 | extern int smp_rescan_cpus(void); |
| 101 | #else | 71 | #else |
diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h index c9af0d19c7ab..41ce6861174e 100644 --- a/arch/s390/include/asm/spinlock.h +++ b/arch/s390/include/asm/spinlock.h | |||
| @@ -191,4 +191,33 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw) | |||
| 191 | #define _raw_read_relax(lock) cpu_relax() | 191 | #define _raw_read_relax(lock) cpu_relax() |
| 192 | #define _raw_write_relax(lock) cpu_relax() | 192 | #define _raw_write_relax(lock) cpu_relax() |
| 193 | 193 | ||
| 194 | #define __always_inline__spin_lock | ||
| 195 | #define __always_inline__read_lock | ||
| 196 | #define __always_inline__write_lock | ||
| 197 | #define __always_inline__spin_lock_bh | ||
| 198 | #define __always_inline__read_lock_bh | ||
| 199 | #define __always_inline__write_lock_bh | ||
| 200 | #define __always_inline__spin_lock_irq | ||
| 201 | #define __always_inline__read_lock_irq | ||
| 202 | #define __always_inline__write_lock_irq | ||
| 203 | #define __always_inline__spin_lock_irqsave | ||
| 204 | #define __always_inline__read_lock_irqsave | ||
| 205 | #define __always_inline__write_lock_irqsave | ||
| 206 | #define __always_inline__spin_trylock | ||
| 207 | #define __always_inline__read_trylock | ||
| 208 | #define __always_inline__write_trylock | ||
| 209 | #define __always_inline__spin_trylock_bh | ||
| 210 | #define __always_inline__spin_unlock | ||
| 211 | #define __always_inline__read_unlock | ||
| 212 | #define __always_inline__write_unlock | ||
| 213 | #define __always_inline__spin_unlock_bh | ||
| 214 | #define __always_inline__read_unlock_bh | ||
| 215 | #define __always_inline__write_unlock_bh | ||
| 216 | #define __always_inline__spin_unlock_irq | ||
| 217 | #define __always_inline__read_unlock_irq | ||
| 218 | #define __always_inline__write_unlock_irq | ||
| 219 | #define __always_inline__spin_unlock_irqrestore | ||
| 220 | #define __always_inline__read_unlock_irqrestore | ||
| 221 | #define __always_inline__write_unlock_irqrestore | ||
| 222 | |||
| 194 | #endif /* __ASM_SPINLOCK_H */ | 223 | #endif /* __ASM_SPINLOCK_H */ |
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h index 4fb83c1cdb77..379661d2f81a 100644 --- a/arch/s390/include/asm/system.h +++ b/arch/s390/include/asm/system.h | |||
| @@ -109,11 +109,7 @@ extern void pfault_fini(void); | |||
| 109 | #define pfault_fini() do { } while (0) | 109 | #define pfault_fini() do { } while (0) |
| 110 | #endif /* CONFIG_PFAULT */ | 110 | #endif /* CONFIG_PFAULT */ |
| 111 | 111 | ||
| 112 | #ifdef CONFIG_PAGE_STATES | ||
| 113 | extern void cmma_init(void); | 112 | extern void cmma_init(void); |
| 114 | #else | ||
| 115 | static inline void cmma_init(void) { } | ||
| 116 | #endif | ||
| 117 | 113 | ||
| 118 | #define finish_arch_switch(prev) do { \ | 114 | #define finish_arch_switch(prev) do { \ |
| 119 | set_fs(current->thread.mm_segment); \ | 115 | set_fs(current->thread.mm_segment); \ |
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index ba1cab9fc1f9..07eb61b2fb3a 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h | |||
| @@ -92,7 +92,7 @@ static inline struct thread_info *current_thread_info(void) | |||
| 92 | #define TIF_SYSCALL_TRACE 8 /* syscall trace active */ | 92 | #define TIF_SYSCALL_TRACE 8 /* syscall trace active */ |
| 93 | #define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */ | 93 | #define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */ |
| 94 | #define TIF_SECCOMP 10 /* secure computing */ | 94 | #define TIF_SECCOMP 10 /* secure computing */ |
| 95 | #define TIF_SYSCALL_FTRACE 11 /* ftrace syscall instrumentation */ | 95 | #define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */ |
| 96 | #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ | 96 | #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ |
| 97 | #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling | 97 | #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling |
| 98 | TIF_NEED_RESCHED */ | 98 | TIF_NEED_RESCHED */ |
| @@ -111,7 +111,7 @@ static inline struct thread_info *current_thread_info(void) | |||
| 111 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) | 111 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) |
| 112 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) | 112 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) |
| 113 | #define _TIF_SECCOMP (1<<TIF_SECCOMP) | 113 | #define _TIF_SECCOMP (1<<TIF_SECCOMP) |
| 114 | #define _TIF_SYSCALL_FTRACE (1<<TIF_SYSCALL_FTRACE) | 114 | #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) |
| 115 | #define _TIF_USEDFPU (1<<TIF_USEDFPU) | 115 | #define _TIF_USEDFPU (1<<TIF_USEDFPU) |
| 116 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) | 116 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) |
| 117 | #define _TIF_31BIT (1<<TIF_31BIT) | 117 | #define _TIF_31BIT (1<<TIF_31BIT) |
diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h index cc21e3e20fd7..24aa1cda20ad 100644 --- a/arch/s390/include/asm/timex.h +++ b/arch/s390/include/asm/timex.h | |||
| @@ -90,4 +90,18 @@ unsigned long long monotonic_clock(void); | |||
| 90 | 90 | ||
| 91 | extern u64 sched_clock_base_cc; | 91 | extern u64 sched_clock_base_cc; |
| 92 | 92 | ||
| 93 | /** | ||
| 94 | * get_clock_monotonic - returns current time in clock rate units | ||
| 95 | * | ||
| 96 | * The caller must ensure that preemption is disabled. | ||
| 97 | * The clock and sched_clock_base get changed via stop_machine. | ||
| 98 | * Therefore preemption must be disabled when calling this | ||
| 99 | * function, otherwise the returned value is not guaranteed to | ||
| 100 | * be monotonic. | ||
| 101 | */ | ||
| 102 | static inline unsigned long long get_clock_monotonic(void) | ||
| 103 | { | ||
| 104 | return get_clock_xt() - sched_clock_base_cc; | ||
| 105 | } | ||
| 106 | |||
| 93 | #endif | 107 | #endif |
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index c75ed43b1a18..c7be8e10b87e 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
| @@ -32,7 +32,7 @@ extra-y += head.o init_task.o vmlinux.lds | |||
| 32 | 32 | ||
| 33 | obj-$(CONFIG_MODULES) += s390_ksyms.o module.o | 33 | obj-$(CONFIG_MODULES) += s390_ksyms.o module.o |
| 34 | obj-$(CONFIG_SMP) += smp.o topology.o | 34 | obj-$(CONFIG_SMP) += smp.o topology.o |
| 35 | 35 | obj-$(CONFIG_HIBERNATION) += suspend.o swsusp_asm64.o | |
| 36 | obj-$(CONFIG_AUDIT) += audit.o | 36 | obj-$(CONFIG_AUDIT) += audit.o |
| 37 | compat-obj-$(CONFIG_AUDIT) += compat_audit.o | 37 | compat-obj-$(CONFIG_AUDIT) += compat_audit.o |
| 38 | obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ | 38 | obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ |
| @@ -41,7 +41,7 @@ obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o \ | |||
| 41 | 41 | ||
| 42 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 42 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
| 43 | obj-$(CONFIG_KPROBES) += kprobes.o | 43 | obj-$(CONFIG_KPROBES) += kprobes.o |
| 44 | obj-$(CONFIG_FUNCTION_TRACER) += mcount.o | 44 | obj-$(CONFIG_FUNCTION_TRACER) += $(if $(CONFIG_64BIT),mcount64.o,mcount.o) |
| 45 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o | 45 | obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o |
| 46 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o | 46 | obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o |
| 47 | 47 | ||
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index cae14c499511..bf8b4ae7ff2d 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
| @@ -6,6 +6,9 @@ | |||
| 6 | * Heiko Carstens <heiko.carstens@de.ibm.com> | 6 | * Heiko Carstens <heiko.carstens@de.ibm.com> |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #define KMSG_COMPONENT "setup" | ||
| 10 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
| 11 | |||
| 9 | #include <linux/compiler.h> | 12 | #include <linux/compiler.h> |
| 10 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 11 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
| @@ -16,6 +19,7 @@ | |||
| 16 | #include <linux/module.h> | 19 | #include <linux/module.h> |
| 17 | #include <linux/pfn.h> | 20 | #include <linux/pfn.h> |
| 18 | #include <linux/uaccess.h> | 21 | #include <linux/uaccess.h> |
| 22 | #include <linux/kernel.h> | ||
| 19 | #include <asm/ebcdic.h> | 23 | #include <asm/ebcdic.h> |
| 20 | #include <asm/ipl.h> | 24 | #include <asm/ipl.h> |
| 21 | #include <asm/lowcore.h> | 25 | #include <asm/lowcore.h> |
| @@ -35,8 +39,6 @@ | |||
| 35 | 39 | ||
| 36 | char kernel_nss_name[NSS_NAME_SIZE + 1]; | 40 | char kernel_nss_name[NSS_NAME_SIZE + 1]; |
| 37 | 41 | ||
| 38 | static unsigned long machine_flags; | ||
| 39 | |||
| 40 | static void __init setup_boot_command_line(void); | 42 | static void __init setup_boot_command_line(void); |
| 41 | 43 | ||
| 42 | /* | 44 | /* |
| @@ -81,6 +83,8 @@ asm( | |||
| 81 | " br 14\n" | 83 | " br 14\n" |
| 82 | " .size savesys_ipl_nss, .-savesys_ipl_nss\n"); | 84 | " .size savesys_ipl_nss, .-savesys_ipl_nss\n"); |
| 83 | 85 | ||
| 86 | static __initdata char upper_command_line[COMMAND_LINE_SIZE]; | ||
| 87 | |||
| 84 | static noinline __init void create_kernel_nss(void) | 88 | static noinline __init void create_kernel_nss(void) |
| 85 | { | 89 | { |
| 86 | unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size; | 90 | unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size; |
| @@ -90,7 +94,6 @@ static noinline __init void create_kernel_nss(void) | |||
| 90 | int response; | 94 | int response; |
| 91 | size_t len; | 95 | size_t len; |
| 92 | char *savesys_ptr; | 96 | char *savesys_ptr; |
| 93 | char upper_command_line[COMMAND_LINE_SIZE]; | ||
| 94 | char defsys_cmd[DEFSYS_CMD_SIZE]; | 97 | char defsys_cmd[DEFSYS_CMD_SIZE]; |
| 95 | char savesys_cmd[SAVESYS_CMD_SIZE]; | 98 | char savesys_cmd[SAVESYS_CMD_SIZE]; |
| 96 | 99 | ||
| @@ -141,6 +144,8 @@ static noinline __init void create_kernel_nss(void) | |||
| 141 | __cpcmd(defsys_cmd, NULL, 0, &response); | 144 | __cpcmd(defsys_cmd, NULL, 0, &response); |
| 142 | 145 | ||
| 143 | if (response != 0) { | 146 | if (response != 0) { |
| 147 | pr_err("Defining the Linux kernel NSS failed with rc=%d\n", | ||
| 148 | response); | ||
| 144 | kernel_nss_name[0] = '\0'; | 149 | kernel_nss_name[0] = '\0'; |
| 145 | return; | 150 | return; |
| 146 | } | 151 | } |
| @@ -153,8 +158,11 @@ static noinline __init void create_kernel_nss(void) | |||
| 153 | * max SAVESYS_CMD_SIZE | 158 | * max SAVESYS_CMD_SIZE |
| 154 | * On error: response contains the numeric portion of cp error message. | 159 | * On error: response contains the numeric portion of cp error message. |
| 155 | * for SAVESYS it will be >= 263 | 160 | * for SAVESYS it will be >= 263 |
| 161 | * for missing privilege class, it will be 1 | ||
| 156 | */ | 162 | */ |
| 157 | if (response > SAVESYS_CMD_SIZE) { | 163 | if (response > SAVESYS_CMD_SIZE || response == 1) { |
| 164 | pr_err("Saving the Linux kernel NSS failed with rc=%d\n", | ||
| 165 | response); | ||
| 158 | kernel_nss_name[0] = '\0'; | 166 | kernel_nss_name[0] = '\0'; |
| 159 | return; | 167 | return; |
| 160 | } | 168 | } |
| @@ -205,12 +213,9 @@ static noinline __init void detect_machine_type(void) | |||
| 205 | 213 | ||
| 206 | /* Running under KVM? If not we assume z/VM */ | 214 | /* Running under KVM? If not we assume z/VM */ |
| 207 | if (!memcmp(vmms.vm[0].cpi, "\xd2\xe5\xd4", 3)) | 215 | if (!memcmp(vmms.vm[0].cpi, "\xd2\xe5\xd4", 3)) |
| 208 | machine_flags |= MACHINE_FLAG_KVM; | 216 | S390_lowcore.machine_flags |= MACHINE_FLAG_KVM; |
| 209 | else | 217 | else |
| 210 | machine_flags |= MACHINE_FLAG_VM; | 218 | S390_lowcore.machine_flags |= MACHINE_FLAG_VM; |
| 211 | |||
| 212 | /* Store machine flags for setting up lowcore early */ | ||
| 213 | S390_lowcore.machine_flags = machine_flags; | ||
| 214 | } | 219 | } |
| 215 | 220 | ||
| 216 | static __init void early_pgm_check_handler(void) | 221 | static __init void early_pgm_check_handler(void) |
| @@ -245,7 +250,7 @@ static noinline __init void setup_hpage(void) | |||
| 245 | facilities = stfl(); | 250 | facilities = stfl(); |
| 246 | if (!(facilities & (1UL << 23)) || !(facilities & (1UL << 29))) | 251 | if (!(facilities & (1UL << 23)) || !(facilities & (1UL << 29))) |
| 247 | return; | 252 | return; |
| 248 | machine_flags |= MACHINE_FLAG_HPAGE; | 253 | S390_lowcore.machine_flags |= MACHINE_FLAG_HPAGE; |
| 249 | __ctl_set_bit(0, 23); | 254 | __ctl_set_bit(0, 23); |
| 250 | #endif | 255 | #endif |
| 251 | } | 256 | } |
| @@ -263,7 +268,7 @@ static __init void detect_mvpg(void) | |||
| 263 | EX_TABLE(0b,1b) | 268 | EX_TABLE(0b,1b) |
| 264 | : "=d" (rc) : "0" (-EOPNOTSUPP), "a" (0) : "memory", "cc", "0"); | 269 | : "=d" (rc) : "0" (-EOPNOTSUPP), "a" (0) : "memory", "cc", "0"); |
| 265 | if (!rc) | 270 | if (!rc) |
| 266 | machine_flags |= MACHINE_FLAG_MVPG; | 271 | S390_lowcore.machine_flags |= MACHINE_FLAG_MVPG; |
| 267 | #endif | 272 | #endif |
| 268 | } | 273 | } |
| 269 | 274 | ||
| @@ -279,7 +284,7 @@ static __init void detect_ieee(void) | |||
| 279 | EX_TABLE(0b,1b) | 284 | EX_TABLE(0b,1b) |
| 280 | : "=d" (rc), "=d" (tmp): "0" (-EOPNOTSUPP) : "cc"); | 285 | : "=d" (rc), "=d" (tmp): "0" (-EOPNOTSUPP) : "cc"); |
| 281 | if (!rc) | 286 | if (!rc) |
| 282 | machine_flags |= MACHINE_FLAG_IEEE; | 287 | S390_lowcore.machine_flags |= MACHINE_FLAG_IEEE; |
| 283 | #endif | 288 | #endif |
| 284 | } | 289 | } |
| 285 | 290 | ||
| @@ -298,7 +303,7 @@ static __init void detect_csp(void) | |||
| 298 | EX_TABLE(0b,1b) | 303 | EX_TABLE(0b,1b) |
| 299 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc", "0", "1", "2"); | 304 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc", "0", "1", "2"); |
| 300 | if (!rc) | 305 | if (!rc) |
| 301 | machine_flags |= MACHINE_FLAG_CSP; | 306 | S390_lowcore.machine_flags |= MACHINE_FLAG_CSP; |
| 302 | #endif | 307 | #endif |
| 303 | } | 308 | } |
| 304 | 309 | ||
| @@ -315,7 +320,7 @@ static __init void detect_diag9c(void) | |||
| 315 | EX_TABLE(0b,1b) | 320 | EX_TABLE(0b,1b) |
| 316 | : "=d" (rc) : "0" (-EOPNOTSUPP), "d" (cpu_address) : "cc"); | 321 | : "=d" (rc) : "0" (-EOPNOTSUPP), "d" (cpu_address) : "cc"); |
| 317 | if (!rc) | 322 | if (!rc) |
| 318 | machine_flags |= MACHINE_FLAG_DIAG9C; | 323 | S390_lowcore.machine_flags |= MACHINE_FLAG_DIAG9C; |
| 319 | } | 324 | } |
| 320 | 325 | ||
| 321 | static __init void detect_diag44(void) | 326 | static __init void detect_diag44(void) |
| @@ -330,7 +335,7 @@ static __init void detect_diag44(void) | |||
| 330 | EX_TABLE(0b,1b) | 335 | EX_TABLE(0b,1b) |
| 331 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc"); | 336 | : "=d" (rc) : "0" (-EOPNOTSUPP) : "cc"); |
| 332 | if (!rc) | 337 | if (!rc) |
| 333 | machine_flags |= MACHINE_FLAG_DIAG44; | 338 | S390_lowcore.machine_flags |= MACHINE_FLAG_DIAG44; |
| 334 | #endif | 339 | #endif |
| 335 | } | 340 | } |
| 336 | 341 | ||
| @@ -341,11 +346,11 @@ static __init void detect_machine_facilities(void) | |||
| 341 | 346 | ||
| 342 | facilities = stfl(); | 347 | facilities = stfl(); |
| 343 | if (facilities & (1 << 28)) | 348 | if (facilities & (1 << 28)) |
| 344 | machine_flags |= MACHINE_FLAG_IDTE; | 349 | S390_lowcore.machine_flags |= MACHINE_FLAG_IDTE; |
| 345 | if (facilities & (1 << 23)) | 350 | if (facilities & (1 << 23)) |
| 346 | machine_flags |= MACHINE_FLAG_PFMF; | 351 | S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF; |
| 347 | if (facilities & (1 << 4)) | 352 | if (facilities & (1 << 4)) |
| 348 | machine_flags |= MACHINE_FLAG_MVCOS; | 353 | S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS; |
| 349 | #endif | 354 | #endif |
| 350 | } | 355 | } |
| 351 | 356 | ||
| @@ -367,21 +372,35 @@ static __init void rescue_initrd(void) | |||
| 367 | } | 372 | } |
| 368 | 373 | ||
| 369 | /* Set up boot command line */ | 374 | /* Set up boot command line */ |
| 370 | static void __init setup_boot_command_line(void) | 375 | static void __init append_to_cmdline(size_t (*ipl_data)(char *, size_t)) |
| 371 | { | 376 | { |
| 372 | char *parm = NULL; | 377 | char *parm, *delim; |
| 378 | size_t rc, len; | ||
| 379 | |||
| 380 | len = strlen(boot_command_line); | ||
| 381 | |||
| 382 | delim = boot_command_line + len; /* '\0' character position */ | ||
| 383 | parm = boot_command_line + len + 1; /* append right after '\0' */ | ||
| 373 | 384 | ||
| 385 | rc = ipl_data(parm, COMMAND_LINE_SIZE - len - 1); | ||
| 386 | if (rc) { | ||
| 387 | if (*parm == '=') | ||
| 388 | memmove(boot_command_line, parm + 1, rc); | ||
| 389 | else | ||
| 390 | *delim = ' '; /* replace '\0' with space */ | ||
| 391 | } | ||
| 392 | } | ||
| 393 | |||
| 394 | static void __init setup_boot_command_line(void) | ||
| 395 | { | ||
| 374 | /* copy arch command line */ | 396 | /* copy arch command line */ |
| 375 | strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE); | 397 | strlcpy(boot_command_line, COMMAND_LINE, ARCH_COMMAND_LINE_SIZE); |
| 376 | 398 | ||
| 377 | /* append IPL PARM data to the boot command line */ | 399 | /* append IPL PARM data to the boot command line */ |
| 378 | if (MACHINE_IS_VM) { | 400 | if (MACHINE_IS_VM) |
| 379 | parm = boot_command_line + strlen(boot_command_line); | 401 | append_to_cmdline(append_ipl_vmparm); |
| 380 | *parm++ = ' '; | 402 | |
| 381 | get_ipl_vmparm(parm); | 403 | append_to_cmdline(append_ipl_scpdata); |
| 382 | if (parm[0] == '=') | ||
| 383 | memmove(boot_command_line, parm + 1, strlen(parm)); | ||
| 384 | } | ||
| 385 | } | 404 | } |
| 386 | 405 | ||
| 387 | 406 | ||
| @@ -413,7 +432,6 @@ void __init startup_init(void) | |||
| 413 | setup_hpage(); | 432 | setup_hpage(); |
| 414 | sclp_facilities_detect(); | 433 | sclp_facilities_detect(); |
| 415 | detect_memory_layout(memory_chunk); | 434 | detect_memory_layout(memory_chunk); |
| 416 | S390_lowcore.machine_flags = machine_flags; | ||
| 417 | #ifdef CONFIG_DYNAMIC_FTRACE | 435 | #ifdef CONFIG_DYNAMIC_FTRACE |
| 418 | S390_lowcore.ftrace_func = (unsigned long)ftrace_caller; | 436 | S390_lowcore.ftrace_func = (unsigned long)ftrace_caller; |
| 419 | #endif | 437 | #endif |
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index c4c80a22bc1f..f43d2ee54464 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
| @@ -54,7 +54,7 @@ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ | |||
| 54 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ | 54 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ |
| 55 | _TIF_MCCK_PENDING) | 55 | _TIF_MCCK_PENDING) |
| 56 | _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ | 56 | _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ |
| 57 | _TIF_SECCOMP>>8 | _TIF_SYSCALL_FTRACE>>8) | 57 | _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8) |
| 58 | 58 | ||
| 59 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER | 59 | STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER |
| 60 | STACK_SIZE = 1 << STACK_SHIFT | 60 | STACK_SIZE = 1 << STACK_SHIFT |
| @@ -278,7 +278,8 @@ sysc_return: | |||
| 278 | bnz BASED(sysc_work) # there is work to do (signals etc.) | 278 | bnz BASED(sysc_work) # there is work to do (signals etc.) |
| 279 | sysc_restore: | 279 | sysc_restore: |
| 280 | #ifdef CONFIG_TRACE_IRQFLAGS | 280 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 281 | la %r1,BASED(sysc_restore_trace_psw) | 281 | la %r1,BASED(sysc_restore_trace_psw_addr) |
| 282 | l %r1,0(%r1) | ||
| 282 | lpsw 0(%r1) | 283 | lpsw 0(%r1) |
| 283 | sysc_restore_trace: | 284 | sysc_restore_trace: |
| 284 | TRACE_IRQS_CHECK | 285 | TRACE_IRQS_CHECK |
| @@ -289,10 +290,15 @@ sysc_leave: | |||
| 289 | sysc_done: | 290 | sysc_done: |
| 290 | 291 | ||
| 291 | #ifdef CONFIG_TRACE_IRQFLAGS | 292 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 293 | sysc_restore_trace_psw_addr: | ||
| 294 | .long sysc_restore_trace_psw | ||
| 295 | |||
| 296 | .section .data,"aw",@progbits | ||
| 292 | .align 8 | 297 | .align 8 |
| 293 | .globl sysc_restore_trace_psw | 298 | .globl sysc_restore_trace_psw |
| 294 | sysc_restore_trace_psw: | 299 | sysc_restore_trace_psw: |
| 295 | .long 0, sysc_restore_trace + 0x80000000 | 300 | .long 0, sysc_restore_trace + 0x80000000 |
| 301 | .previous | ||
| 296 | #endif | 302 | #endif |
| 297 | 303 | ||
| 298 | # | 304 | # |
| @@ -606,7 +612,8 @@ io_return: | |||
| 606 | bnz BASED(io_work) # there is work to do (signals etc.) | 612 | bnz BASED(io_work) # there is work to do (signals etc.) |
| 607 | io_restore: | 613 | io_restore: |
| 608 | #ifdef CONFIG_TRACE_IRQFLAGS | 614 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 609 | la %r1,BASED(io_restore_trace_psw) | 615 | la %r1,BASED(io_restore_trace_psw_addr) |
| 616 | l %r1,0(%r1) | ||
| 610 | lpsw 0(%r1) | 617 | lpsw 0(%r1) |
| 611 | io_restore_trace: | 618 | io_restore_trace: |
| 612 | TRACE_IRQS_CHECK | 619 | TRACE_IRQS_CHECK |
| @@ -617,10 +624,15 @@ io_leave: | |||
| 617 | io_done: | 624 | io_done: |
| 618 | 625 | ||
| 619 | #ifdef CONFIG_TRACE_IRQFLAGS | 626 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 627 | io_restore_trace_psw_addr: | ||
| 628 | .long io_restore_trace_psw | ||
| 629 | |||
| 630 | .section .data,"aw",@progbits | ||
| 620 | .align 8 | 631 | .align 8 |
| 621 | .globl io_restore_trace_psw | 632 | .globl io_restore_trace_psw |
| 622 | io_restore_trace_psw: | 633 | io_restore_trace_psw: |
| 623 | .long 0, io_restore_trace + 0x80000000 | 634 | .long 0, io_restore_trace + 0x80000000 |
| 635 | .previous | ||
| 624 | #endif | 636 | #endif |
| 625 | 637 | ||
| 626 | # | 638 | # |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index f6618e9e15ef..a6f7b20df616 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
| @@ -57,7 +57,7 @@ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ | |||
| 57 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ | 57 | _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ |
| 58 | _TIF_MCCK_PENDING) | 58 | _TIF_MCCK_PENDING) |
| 59 | _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ | 59 | _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ |
| 60 | _TIF_SECCOMP>>8 | _TIF_SYSCALL_FTRACE>>8) | 60 | _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8) |
| 61 | 61 | ||
| 62 | #define BASED(name) name-system_call(%r13) | 62 | #define BASED(name) name-system_call(%r13) |
| 63 | 63 | ||
| @@ -284,10 +284,12 @@ sysc_leave: | |||
| 284 | sysc_done: | 284 | sysc_done: |
| 285 | 285 | ||
| 286 | #ifdef CONFIG_TRACE_IRQFLAGS | 286 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 287 | .section .data,"aw",@progbits | ||
| 287 | .align 8 | 288 | .align 8 |
| 288 | .globl sysc_restore_trace_psw | 289 | .globl sysc_restore_trace_psw |
| 289 | sysc_restore_trace_psw: | 290 | sysc_restore_trace_psw: |
| 290 | .quad 0, sysc_restore_trace | 291 | .quad 0, sysc_restore_trace |
| 292 | .previous | ||
| 291 | #endif | 293 | #endif |
| 292 | 294 | ||
| 293 | # | 295 | # |
| @@ -595,10 +597,12 @@ io_leave: | |||
| 595 | io_done: | 597 | io_done: |
| 596 | 598 | ||
| 597 | #ifdef CONFIG_TRACE_IRQFLAGS | 599 | #ifdef CONFIG_TRACE_IRQFLAGS |
| 600 | .section .data,"aw",@progbits | ||
| 598 | .align 8 | 601 | .align 8 |
| 599 | .globl io_restore_trace_psw | 602 | .globl io_restore_trace_psw |
| 600 | io_restore_trace_psw: | 603 | io_restore_trace_psw: |
| 601 | .quad 0, io_restore_trace | 604 | .quad 0, io_restore_trace |
| 605 | .previous | ||
| 602 | #endif | 606 | #endif |
| 603 | 607 | ||
| 604 | # | 608 | # |
diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index 3e298e64f0db..57bdcb1e3cdf 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c | |||
| @@ -220,6 +220,29 @@ struct syscall_metadata *syscall_nr_to_meta(int nr) | |||
| 220 | return syscalls_metadata[nr]; | 220 | return syscalls_metadata[nr]; |
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | int syscall_name_to_nr(char *name) | ||
| 224 | { | ||
| 225 | int i; | ||
| 226 | |||
| 227 | if (!syscalls_metadata) | ||
| 228 | return -1; | ||
| 229 | for (i = 0; i < NR_syscalls; i++) | ||
| 230 | if (syscalls_metadata[i]) | ||
| 231 | if (!strcmp(syscalls_metadata[i]->name, name)) | ||
| 232 | return i; | ||
| 233 | return -1; | ||
| 234 | } | ||
| 235 | |||
| 236 | void set_syscall_enter_id(int num, int id) | ||
| 237 | { | ||
| 238 | syscalls_metadata[num]->enter_id = id; | ||
| 239 | } | ||
| 240 | |||
| 241 | void set_syscall_exit_id(int num, int id) | ||
| 242 | { | ||
| 243 | syscalls_metadata[num]->exit_id = id; | ||
| 244 | } | ||
| 245 | |||
| 223 | static struct syscall_metadata *find_syscall_meta(unsigned long syscall) | 246 | static struct syscall_metadata *find_syscall_meta(unsigned long syscall) |
| 224 | { | 247 | { |
| 225 | struct syscall_metadata *start; | 248 | struct syscall_metadata *start; |
| @@ -237,24 +260,19 @@ static struct syscall_metadata *find_syscall_meta(unsigned long syscall) | |||
| 237 | return NULL; | 260 | return NULL; |
| 238 | } | 261 | } |
| 239 | 262 | ||
| 240 | void arch_init_ftrace_syscalls(void) | 263 | static int __init arch_init_ftrace_syscalls(void) |
| 241 | { | 264 | { |
| 242 | struct syscall_metadata *meta; | 265 | struct syscall_metadata *meta; |
| 243 | int i; | 266 | int i; |
| 244 | static atomic_t refs; | ||
| 245 | |||
| 246 | if (atomic_inc_return(&refs) != 1) | ||
| 247 | goto out; | ||
| 248 | syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * NR_syscalls, | 267 | syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * NR_syscalls, |
| 249 | GFP_KERNEL); | 268 | GFP_KERNEL); |
| 250 | if (!syscalls_metadata) | 269 | if (!syscalls_metadata) |
| 251 | goto out; | 270 | return -ENOMEM; |
| 252 | for (i = 0; i < NR_syscalls; i++) { | 271 | for (i = 0; i < NR_syscalls; i++) { |
| 253 | meta = find_syscall_meta((unsigned long)sys_call_table[i]); | 272 | meta = find_syscall_meta((unsigned long)sys_call_table[i]); |
| 254 | syscalls_metadata[i] = meta; | 273 | syscalls_metadata[i] = meta; |
| 255 | } | 274 | } |
| 256 | return; | 275 | return 0; |
| 257 | out: | ||
| 258 | atomic_dec(&refs); | ||
| 259 | } | 276 | } |
| 277 | arch_initcall(arch_init_ftrace_syscalls); | ||
| 260 | #endif | 278 | #endif |
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index ec6882348520..c52b4f7742fa 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <asm/asm-offsets.h> | 27 | #include <asm/asm-offsets.h> |
| 28 | #include <asm/thread_info.h> | 28 | #include <asm/thread_info.h> |
| 29 | #include <asm/page.h> | 29 | #include <asm/page.h> |
| 30 | #include <asm/cpu.h> | ||
| 30 | 31 | ||
| 31 | #ifdef CONFIG_64BIT | 32 | #ifdef CONFIG_64BIT |
| 32 | #define ARCH_OFFSET 4 | 33 | #define ARCH_OFFSET 4 |
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S index 2ced846065b7..602b508cd4c4 100644 --- a/arch/s390/kernel/head31.S +++ b/arch/s390/kernel/head31.S | |||
| @@ -24,6 +24,7 @@ startup_continue: | |||
| 24 | # Setup stack | 24 | # Setup stack |
| 25 | # | 25 | # |
| 26 | l %r15,.Linittu-.LPG1(%r13) | 26 | l %r15,.Linittu-.LPG1(%r13) |
| 27 | st %r15,__LC_THREAD_INFO # cache thread info in lowcore | ||
| 27 | mvc __LC_CURRENT(4),__TI_task(%r15) | 28 | mvc __LC_CURRENT(4),__TI_task(%r15) |
| 28 | ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE | 29 | ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union+THREAD_SIZE |
| 29 | st %r15,__LC_KERNEL_STACK # set end of kernel stack | 30 | st %r15,__LC_KERNEL_STACK # set end of kernel stack |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 65667b2e65ce..6a250808092b 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
| @@ -62,9 +62,9 @@ startup_continue: | |||
| 62 | clr %r11,%r12 | 62 | clr %r11,%r12 |
| 63 | je 5f # no more space in prefix array | 63 | je 5f # no more space in prefix array |
| 64 | 4: | 64 | 4: |
| 65 | ahi %r8,1 # next cpu (r8 += 1) | 65 | ahi %r8,1 # next cpu (r8 += 1) |
| 66 | cl %r8,.Llast_cpu-.LPG1(%r13) # is last possible cpu ? | 66 | chi %r8,MAX_CPU_ADDRESS # is last possible cpu ? |
| 67 | jl 1b # jump if not last cpu | 67 | jle 1b # jump if not last cpu |
| 68 | 5: | 68 | 5: |
| 69 | lhi %r1,2 # mode 2 = esame (dump) | 69 | lhi %r1,2 # mode 2 = esame (dump) |
| 70 | j 6f | 70 | j 6f |
| @@ -92,6 +92,7 @@ startup_continue: | |||
| 92 | # Setup stack | 92 | # Setup stack |
| 93 | # | 93 | # |
| 94 | larl %r15,init_thread_union | 94 | larl %r15,init_thread_union |
| 95 | stg %r15,__LC_THREAD_INFO # cache thread info in lowcore | ||
| 95 | lg %r14,__TI_task(%r15) # cache current in lowcore | 96 | lg %r14,__TI_task(%r15) # cache current in lowcore |
| 96 | stg %r14,__LC_CURRENT | 97 | stg %r14,__LC_CURRENT |
| 97 | aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE | 98 | aghi %r15,1<<(PAGE_SHIFT+THREAD_ORDER) # init_task_union + THREAD_SIZE |
| @@ -129,8 +130,6 @@ startup_continue: | |||
| 129 | #ifdef CONFIG_ZFCPDUMP | 130 | #ifdef CONFIG_ZFCPDUMP |
| 130 | .Lcurrent_cpu: | 131 | .Lcurrent_cpu: |
| 131 | .long 0x0 | 132 | .long 0x0 |
| 132 | .Llast_cpu: | ||
| 133 | .long 0x0000ffff | ||
| 134 | .Lpref_arr_ptr: | 133 | .Lpref_arr_ptr: |
| 135 | .long zfcpdump_prefix_array | 134 | .long zfcpdump_prefix_array |
| 136 | #endif /* CONFIG_ZFCPDUMP */ | 135 | #endif /* CONFIG_ZFCPDUMP */ |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 371a2d88f4ac..ee57a42e6e93 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
| @@ -272,17 +272,18 @@ static ssize_t ipl_type_show(struct kobject *kobj, struct kobj_attribute *attr, | |||
| 272 | static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); | 272 | static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); |
| 273 | 273 | ||
| 274 | /* VM IPL PARM routines */ | 274 | /* VM IPL PARM routines */ |
| 275 | static void reipl_get_ascii_vmparm(char *dest, | 275 | size_t reipl_get_ascii_vmparm(char *dest, size_t size, |
| 276 | const struct ipl_parameter_block *ipb) | 276 | const struct ipl_parameter_block *ipb) |
| 277 | { | 277 | { |
| 278 | int i; | 278 | int i; |
| 279 | int len = 0; | 279 | size_t len; |
| 280 | char has_lowercase = 0; | 280 | char has_lowercase = 0; |
| 281 | 281 | ||
| 282 | len = 0; | ||
| 282 | if ((ipb->ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID) && | 283 | if ((ipb->ipl_info.ccw.vm_flags & DIAG308_VM_FLAGS_VP_VALID) && |
| 283 | (ipb->ipl_info.ccw.vm_parm_len > 0)) { | 284 | (ipb->ipl_info.ccw.vm_parm_len > 0)) { |
| 284 | 285 | ||
| 285 | len = ipb->ipl_info.ccw.vm_parm_len; | 286 | len = min_t(size_t, size - 1, ipb->ipl_info.ccw.vm_parm_len); |
| 286 | memcpy(dest, ipb->ipl_info.ccw.vm_parm, len); | 287 | memcpy(dest, ipb->ipl_info.ccw.vm_parm, len); |
| 287 | /* If at least one character is lowercase, we assume mixed | 288 | /* If at least one character is lowercase, we assume mixed |
| 288 | * case; otherwise we convert everything to lowercase. | 289 | * case; otherwise we convert everything to lowercase. |
| @@ -299,14 +300,20 @@ static void reipl_get_ascii_vmparm(char *dest, | |||
| 299 | EBCASC(dest, len); | 300 | EBCASC(dest, len); |
| 300 | } | 301 | } |
| 301 | dest[len] = 0; | 302 | dest[len] = 0; |
| 303 | |||
| 304 | return len; | ||
| 302 | } | 305 | } |
| 303 | 306 | ||
| 304 | void get_ipl_vmparm(char *dest) | 307 | size_t append_ipl_vmparm(char *dest, size_t size) |
| 305 | { | 308 | { |
| 309 | size_t rc; | ||
| 310 | |||
| 311 | rc = 0; | ||
| 306 | if (diag308_set_works && (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_CCW)) | 312 | if (diag308_set_works && (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_CCW)) |
| 307 | reipl_get_ascii_vmparm(dest, &ipl_block); | 313 | rc = reipl_get_ascii_vmparm(dest, size, &ipl_block); |
| 308 | else | 314 | else |
| 309 | dest[0] = 0; | 315 | dest[0] = 0; |
| 316 | return rc; | ||
| 310 | } | 317 | } |
| 311 | 318 | ||
| 312 | static ssize_t ipl_vm_parm_show(struct kobject *kobj, | 319 | static ssize_t ipl_vm_parm_show(struct kobject *kobj, |
| @@ -314,10 +321,65 @@ static ssize_t ipl_vm_parm_show(struct kobject *kobj, | |||
| 314 | { | 321 | { |
| 315 | char parm[DIAG308_VMPARM_SIZE + 1] = {}; | 322 | char parm[DIAG308_VMPARM_SIZE + 1] = {}; |
| 316 | 323 | ||
| 317 | get_ipl_vmparm(parm); | 324 | append_ipl_vmparm(parm, sizeof(parm)); |
| 318 | return sprintf(page, "%s\n", parm); | 325 | return sprintf(page, "%s\n", parm); |
| 319 | } | 326 | } |
| 320 | 327 | ||
| 328 | static size_t scpdata_length(const char* buf, size_t count) | ||
| 329 | { | ||
| 330 | while (count) { | ||
| 331 | if (buf[count - 1] != '\0' && buf[count - 1] != ' ') | ||
| 332 | break; | ||
| 333 | count--; | ||
| 334 | } | ||
| 335 | return count; | ||
| 336 | } | ||
| 337 | |||
| 338 | size_t reipl_append_ascii_scpdata(char *dest, size_t size, | ||
| 339 | const struct ipl_parameter_block *ipb) | ||
| 340 | { | ||
| 341 | size_t count; | ||
| 342 | size_t i; | ||
| 343 | int has_lowercase; | ||
| 344 | |||
| 345 | count = min(size - 1, scpdata_length(ipb->ipl_info.fcp.scp_data, | ||
| 346 | ipb->ipl_info.fcp.scp_data_len)); | ||
| 347 | if (!count) | ||
| 348 | goto out; | ||
| 349 | |||
| 350 | has_lowercase = 0; | ||
| 351 | for (i = 0; i < count; i++) { | ||
| 352 | if (!isascii(ipb->ipl_info.fcp.scp_data[i])) { | ||
| 353 | count = 0; | ||
| 354 | goto out; | ||
| 355 | } | ||
| 356 | if (!has_lowercase && islower(ipb->ipl_info.fcp.scp_data[i])) | ||
| 357 | has_lowercase = 1; | ||
| 358 | } | ||
| 359 | |||
| 360 | if (has_lowercase) | ||
| 361 | memcpy(dest, ipb->ipl_info.fcp.scp_data, count); | ||
| 362 | else | ||
| 363 | for (i = 0; i < count; i++) | ||
| 364 | dest[i] = tolower(ipb->ipl_info.fcp.scp_data[i]); | ||
| 365 | out: | ||
| 366 | dest[count] = '\0'; | ||
| 367 | return count; | ||
| 368 | } | ||
| 369 | |||
| 370 | size_t append_ipl_scpdata(char *dest, size_t len) | ||
| 371 | { | ||
| 372 | size_t rc; | ||
| 373 | |||
| 374 | rc = 0; | ||
| 375 | if (ipl_block.hdr.pbt == DIAG308_IPL_TYPE_FCP) | ||
| 376 | rc = reipl_append_ascii_scpdata(dest, len, &ipl_block); | ||
| 377 | else | ||
| 378 | dest[0] = 0; | ||
| 379 | return rc; | ||
| 380 | } | ||
| 381 | |||
| 382 | |||
| 321 | static struct kobj_attribute sys_ipl_vm_parm_attr = | 383 | static struct kobj_attribute sys_ipl_vm_parm_attr = |
| 322 | __ATTR(parm, S_IRUGO, ipl_vm_parm_show, NULL); | 384 | __ATTR(parm, S_IRUGO, ipl_vm_parm_show, NULL); |
| 323 | 385 | ||
| @@ -553,7 +615,7 @@ static ssize_t reipl_generic_vmparm_show(struct ipl_parameter_block *ipb, | |||
| 553 | { | 615 | { |
| 554 | char vmparm[DIAG308_VMPARM_SIZE + 1] = {}; | 616 | char vmparm[DIAG308_VMPARM_SIZE + 1] = {}; |
| 555 | 617 | ||
| 556 | reipl_get_ascii_vmparm(vmparm, ipb); | 618 | reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb); |
| 557 | return sprintf(page, "%s\n", vmparm); | 619 | return sprintf(page, "%s\n", vmparm); |
| 558 | } | 620 | } |
| 559 | 621 | ||
| @@ -626,6 +688,59 @@ static struct kobj_attribute sys_reipl_ccw_vmparm_attr = | |||
| 626 | 688 | ||
| 627 | /* FCP reipl device attributes */ | 689 | /* FCP reipl device attributes */ |
| 628 | 690 | ||
| 691 | static ssize_t reipl_fcp_scpdata_read(struct kobject *kobj, | ||
| 692 | struct bin_attribute *attr, | ||
| 693 | char *buf, loff_t off, size_t count) | ||
| 694 | { | ||
| 695 | size_t size = reipl_block_fcp->ipl_info.fcp.scp_data_len; | ||
| 696 | void *scp_data = reipl_block_fcp->ipl_info.fcp.scp_data; | ||
| 697 | |||
| 698 | return memory_read_from_buffer(buf, count, &off, scp_data, size); | ||
| 699 | } | ||
| 700 | |||
| 701 | static ssize_t reipl_fcp_scpdata_write(struct kobject *kobj, | ||
| 702 | struct bin_attribute *attr, | ||
| 703 | char *buf, loff_t off, size_t count) | ||
| 704 | { | ||
| 705 | size_t padding; | ||
| 706 | size_t scpdata_len; | ||
| 707 | |||
| 708 | if (off < 0) | ||
| 709 | return -EINVAL; | ||
| 710 | |||
| 711 | if (off >= DIAG308_SCPDATA_SIZE) | ||
| 712 | return -ENOSPC; | ||
| 713 | |||
| 714 | if (count > DIAG308_SCPDATA_SIZE - off) | ||
| 715 | count = DIAG308_SCPDATA_SIZE - off; | ||
| 716 | |||
| 717 | memcpy(reipl_block_fcp->ipl_info.fcp.scp_data, buf + off, count); | ||
| 718 | scpdata_len = off + count; | ||
| 719 | |||
| 720 | if (scpdata_len % 8) { | ||
| 721 | padding = 8 - (scpdata_len % 8); | ||
| 722 | memset(reipl_block_fcp->ipl_info.fcp.scp_data + scpdata_len, | ||
| 723 | 0, padding); | ||
| 724 | scpdata_len += padding; | ||
| 725 | } | ||
| 726 | |||
| 727 | reipl_block_fcp->ipl_info.fcp.scp_data_len = scpdata_len; | ||
| 728 | reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN + scpdata_len; | ||
| 729 | reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN + scpdata_len; | ||
| 730 | |||
| 731 | return count; | ||
| 732 | } | ||
| 733 | |||
| 734 | static struct bin_attribute sys_reipl_fcp_scp_data_attr = { | ||
| 735 | .attr = { | ||
| 736 | .name = "scp_data", | ||
| 737 | .mode = S_IRUGO | S_IWUSR, | ||
| 738 | }, | ||
| 739 | .size = PAGE_SIZE, | ||
| 740 | .read = reipl_fcp_scpdata_read, | ||
| 741 | .write = reipl_fcp_scpdata_write, | ||
| 742 | }; | ||
| 743 | |||
| 629 | DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n", | 744 | DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%016llx\n", |
| 630 | reipl_block_fcp->ipl_info.fcp.wwpn); | 745 | reipl_block_fcp->ipl_info.fcp.wwpn); |
| 631 | DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n", | 746 | DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%016llx\n", |
| @@ -647,7 +762,6 @@ static struct attribute *reipl_fcp_attrs[] = { | |||
| 647 | }; | 762 | }; |
| 648 | 763 | ||
| 649 | static struct attribute_group reipl_fcp_attr_group = { | 764 | static struct attribute_group reipl_fcp_attr_group = { |
| 650 | .name = IPL_FCP_STR, | ||
| 651 | .attrs = reipl_fcp_attrs, | 765 | .attrs = reipl_fcp_attrs, |
| 652 | }; | 766 | }; |
| 653 | 767 | ||
| @@ -895,6 +1009,7 @@ static struct kobj_attribute reipl_type_attr = | |||
| 895 | __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store); | 1009 | __ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store); |
| 896 | 1010 | ||
| 897 | static struct kset *reipl_kset; | 1011 | static struct kset *reipl_kset; |
| 1012 | static struct kset *reipl_fcp_kset; | ||
| 898 | 1013 | ||
| 899 | static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb, | 1014 | static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb, |
| 900 | const enum ipl_method m) | 1015 | const enum ipl_method m) |
| @@ -906,7 +1021,7 @@ static void get_ipl_string(char *dst, struct ipl_parameter_block *ipb, | |||
| 906 | 1021 | ||
| 907 | reipl_get_ascii_loadparm(loadparm, ipb); | 1022 | reipl_get_ascii_loadparm(loadparm, ipb); |
| 908 | reipl_get_ascii_nss_name(nss_name, ipb); | 1023 | reipl_get_ascii_nss_name(nss_name, ipb); |
| 909 | reipl_get_ascii_vmparm(vmparm, ipb); | 1024 | reipl_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb); |
| 910 | 1025 | ||
| 911 | switch (m) { | 1026 | switch (m) { |
| 912 | case REIPL_METHOD_CCW_VM: | 1027 | case REIPL_METHOD_CCW_VM: |
| @@ -1076,23 +1191,44 @@ static int __init reipl_fcp_init(void) | |||
| 1076 | int rc; | 1191 | int rc; |
| 1077 | 1192 | ||
| 1078 | if (!diag308_set_works) { | 1193 | if (!diag308_set_works) { |
| 1079 | if (ipl_info.type == IPL_TYPE_FCP) | 1194 | if (ipl_info.type == IPL_TYPE_FCP) { |
| 1080 | make_attrs_ro(reipl_fcp_attrs); | 1195 | make_attrs_ro(reipl_fcp_attrs); |
| 1081 | else | 1196 | sys_reipl_fcp_scp_data_attr.attr.mode = S_IRUGO; |
| 1197 | } else | ||
| 1082 | return 0; | 1198 | return 0; |
| 1083 | } | 1199 | } |
| 1084 | 1200 | ||
| 1085 | reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); | 1201 | reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL); |
| 1086 | if (!reipl_block_fcp) | 1202 | if (!reipl_block_fcp) |
| 1087 | return -ENOMEM; | 1203 | return -ENOMEM; |
| 1088 | rc = sysfs_create_group(&reipl_kset->kobj, &reipl_fcp_attr_group); | 1204 | |
| 1205 | /* sysfs: create fcp kset for mixing attr group and bin attrs */ | ||
| 1206 | reipl_fcp_kset = kset_create_and_add(IPL_FCP_STR, NULL, | ||
| 1207 | &reipl_kset->kobj); | ||
| 1208 | if (!reipl_kset) { | ||
| 1209 | free_page((unsigned long) reipl_block_fcp); | ||
| 1210 | return -ENOMEM; | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | rc = sysfs_create_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group); | ||
| 1214 | if (rc) { | ||
| 1215 | kset_unregister(reipl_fcp_kset); | ||
| 1216 | free_page((unsigned long) reipl_block_fcp); | ||
| 1217 | return rc; | ||
| 1218 | } | ||
| 1219 | |||
| 1220 | rc = sysfs_create_bin_file(&reipl_fcp_kset->kobj, | ||
| 1221 | &sys_reipl_fcp_scp_data_attr); | ||
| 1089 | if (rc) { | 1222 | if (rc) { |
| 1090 | free_page((unsigned long)reipl_block_fcp); | 1223 | sysfs_remove_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group); |
| 1224 | kset_unregister(reipl_fcp_kset); | ||
| 1225 | free_page((unsigned long) reipl_block_fcp); | ||
| 1091 | return rc; | 1226 | return rc; |
| 1092 | } | 1227 | } |
| 1093 | if (ipl_info.type == IPL_TYPE_FCP) { | 1228 | |
| 1229 | if (ipl_info.type == IPL_TYPE_FCP) | ||
| 1094 | memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE); | 1230 | memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE); |
| 1095 | } else { | 1231 | else { |
| 1096 | reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN; | 1232 | reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN; |
| 1097 | reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION; | 1233 | reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION; |
| 1098 | reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN; | 1234 | reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN; |
diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S index 2a0a5e97ba8c..dfe015d7398c 100644 --- a/arch/s390/kernel/mcount.S +++ b/arch/s390/kernel/mcount.S | |||
| @@ -11,111 +11,27 @@ | |||
| 11 | ftrace_stub: | 11 | ftrace_stub: |
| 12 | br %r14 | 12 | br %r14 |
| 13 | 13 | ||
| 14 | #ifdef CONFIG_64BIT | ||
| 15 | |||
| 16 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
| 17 | |||
| 18 | .globl _mcount | 14 | .globl _mcount |
| 19 | _mcount: | 15 | _mcount: |
| 20 | br %r14 | 16 | #ifdef CONFIG_DYNAMIC_FTRACE |
| 21 | |||
| 22 | .globl ftrace_caller | ||
| 23 | ftrace_caller: | ||
| 24 | larl %r1,function_trace_stop | ||
| 25 | icm %r1,0xf,0(%r1) | ||
| 26 | bnzr %r14 | ||
| 27 | stmg %r2,%r5,32(%r15) | ||
| 28 | stg %r14,112(%r15) | ||
| 29 | lgr %r1,%r15 | ||
| 30 | aghi %r15,-160 | ||
| 31 | stg %r1,__SF_BACKCHAIN(%r15) | ||
| 32 | lgr %r2,%r14 | ||
| 33 | lg %r3,168(%r15) | ||
| 34 | larl %r14,ftrace_dyn_func | ||
| 35 | lg %r14,0(%r14) | ||
| 36 | basr %r14,%r14 | ||
| 37 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
| 38 | .globl ftrace_graph_caller | ||
| 39 | ftrace_graph_caller: | ||
| 40 | # This unconditional branch gets runtime patched. Change only if | ||
| 41 | # you know what you are doing. See ftrace_enable_graph_caller(). | ||
| 42 | j 0f | ||
| 43 | lg %r2,272(%r15) | ||
| 44 | lg %r3,168(%r15) | ||
| 45 | brasl %r14,prepare_ftrace_return | ||
| 46 | stg %r2,168(%r15) | ||
| 47 | 0: | ||
| 48 | #endif | ||
| 49 | aghi %r15,160 | ||
| 50 | lmg %r2,%r5,32(%r15) | ||
| 51 | lg %r14,112(%r15) | ||
| 52 | br %r14 | 17 | br %r14 |
| 53 | 18 | ||
| 54 | .data | 19 | .data |
| 55 | .globl ftrace_dyn_func | 20 | .globl ftrace_dyn_func |
| 56 | ftrace_dyn_func: | 21 | ftrace_dyn_func: |
| 57 | .quad ftrace_stub | 22 | .long ftrace_stub |
| 58 | .previous | 23 | .previous |
| 59 | 24 | ||
| 60 | #else /* CONFIG_DYNAMIC_FTRACE */ | ||
| 61 | |||
| 62 | .globl _mcount | ||
| 63 | _mcount: | ||
| 64 | larl %r1,function_trace_stop | ||
| 65 | icm %r1,0xf,0(%r1) | ||
| 66 | bnzr %r14 | ||
| 67 | stmg %r2,%r5,32(%r15) | ||
| 68 | stg %r14,112(%r15) | ||
| 69 | lgr %r1,%r15 | ||
| 70 | aghi %r15,-160 | ||
| 71 | stg %r1,__SF_BACKCHAIN(%r15) | ||
| 72 | lgr %r2,%r14 | ||
| 73 | lg %r3,168(%r15) | ||
| 74 | larl %r14,ftrace_trace_function | ||
| 75 | lg %r14,0(%r14) | ||
| 76 | basr %r14,%r14 | ||
| 77 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
| 78 | lg %r2,272(%r15) | ||
| 79 | lg %r3,168(%r15) | ||
| 80 | brasl %r14,prepare_ftrace_return | ||
| 81 | stg %r2,168(%r15) | ||
| 82 | #endif | ||
| 83 | aghi %r15,160 | ||
| 84 | lmg %r2,%r5,32(%r15) | ||
| 85 | lg %r14,112(%r15) | ||
| 86 | br %r14 | ||
| 87 | |||
| 88 | #endif /* CONFIG_DYNAMIC_FTRACE */ | ||
| 89 | |||
| 90 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
| 91 | |||
| 92 | .globl return_to_handler | ||
| 93 | return_to_handler: | ||
| 94 | stmg %r2,%r5,32(%r15) | ||
| 95 | lgr %r1,%r15 | ||
| 96 | aghi %r15,-160 | ||
| 97 | stg %r1,__SF_BACKCHAIN(%r15) | ||
| 98 | brasl %r14,ftrace_return_to_handler | ||
| 99 | aghi %r15,160 | ||
| 100 | lgr %r14,%r2 | ||
| 101 | lmg %r2,%r5,32(%r15) | ||
| 102 | br %r14 | ||
| 103 | |||
| 104 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | ||
| 105 | |||
| 106 | #else /* CONFIG_64BIT */ | ||
| 107 | |||
| 108 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
| 109 | |||
| 110 | .globl _mcount | ||
| 111 | _mcount: | ||
| 112 | br %r14 | ||
| 113 | |||
| 114 | .globl ftrace_caller | 25 | .globl ftrace_caller |
| 115 | ftrace_caller: | 26 | ftrace_caller: |
| 27 | #endif | ||
| 116 | stm %r2,%r5,16(%r15) | 28 | stm %r2,%r5,16(%r15) |
| 117 | bras %r1,2f | 29 | bras %r1,2f |
| 30 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
| 31 | 0: .long ftrace_dyn_func | ||
| 32 | #else | ||
| 118 | 0: .long ftrace_trace_function | 33 | 0: .long ftrace_trace_function |
| 34 | #endif | ||
| 119 | 1: .long function_trace_stop | 35 | 1: .long function_trace_stop |
| 120 | 2: l %r2,1b-0b(%r1) | 36 | 2: l %r2,1b-0b(%r1) |
| 121 | icm %r2,0xf,0(%r2) | 37 | icm %r2,0xf,0(%r2) |
| @@ -131,53 +47,13 @@ ftrace_caller: | |||
| 131 | l %r14,0(%r14) | 47 | l %r14,0(%r14) |
| 132 | basr %r14,%r14 | 48 | basr %r14,%r14 |
| 133 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 49 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 50 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
| 134 | .globl ftrace_graph_caller | 51 | .globl ftrace_graph_caller |
| 135 | ftrace_graph_caller: | 52 | ftrace_graph_caller: |
| 136 | # This unconditional branch gets runtime patched. Change only if | 53 | # This unconditional branch gets runtime patched. Change only if |
| 137 | # you know what you are doing. See ftrace_enable_graph_caller(). | 54 | # you know what you are doing. See ftrace_enable_graph_caller(). |
| 138 | j 1f | 55 | j 1f |
| 139 | bras %r1,0f | ||
| 140 | .long prepare_ftrace_return | ||
| 141 | 0: l %r2,152(%r15) | ||
| 142 | l %r4,0(%r1) | ||
| 143 | l %r3,100(%r15) | ||
| 144 | basr %r14,%r4 | ||
| 145 | st %r2,100(%r15) | ||
| 146 | 1: | ||
| 147 | #endif | 56 | #endif |
| 148 | ahi %r15,96 | ||
| 149 | l %r14,56(%r15) | ||
| 150 | 3: lm %r2,%r5,16(%r15) | ||
| 151 | br %r14 | ||
| 152 | |||
| 153 | .data | ||
| 154 | .globl ftrace_dyn_func | ||
| 155 | ftrace_dyn_func: | ||
| 156 | .long ftrace_stub | ||
| 157 | .previous | ||
| 158 | |||
| 159 | #else /* CONFIG_DYNAMIC_FTRACE */ | ||
| 160 | |||
| 161 | .globl _mcount | ||
| 162 | _mcount: | ||
| 163 | stm %r2,%r5,16(%r15) | ||
| 164 | bras %r1,2f | ||
| 165 | 0: .long ftrace_trace_function | ||
| 166 | 1: .long function_trace_stop | ||
| 167 | 2: l %r2,1b-0b(%r1) | ||
| 168 | icm %r2,0xf,0(%r2) | ||
| 169 | jnz 3f | ||
| 170 | st %r14,56(%r15) | ||
| 171 | lr %r0,%r15 | ||
| 172 | ahi %r15,-96 | ||
| 173 | l %r3,100(%r15) | ||
| 174 | la %r2,0(%r14) | ||
| 175 | st %r0,__SF_BACKCHAIN(%r15) | ||
| 176 | la %r3,0(%r3) | ||
| 177 | l %r14,0b-0b(%r1) | ||
| 178 | l %r14,0(%r14) | ||
| 179 | basr %r14,%r14 | ||
| 180 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
| 181 | bras %r1,0f | 57 | bras %r1,0f |
| 182 | .long prepare_ftrace_return | 58 | .long prepare_ftrace_return |
| 183 | 0: l %r2,152(%r15) | 59 | 0: l %r2,152(%r15) |
| @@ -185,14 +61,13 @@ _mcount: | |||
| 185 | l %r3,100(%r15) | 61 | l %r3,100(%r15) |
| 186 | basr %r14,%r4 | 62 | basr %r14,%r4 |
| 187 | st %r2,100(%r15) | 63 | st %r2,100(%r15) |
| 64 | 1: | ||
| 188 | #endif | 65 | #endif |
| 189 | ahi %r15,96 | 66 | ahi %r15,96 |
| 190 | l %r14,56(%r15) | 67 | l %r14,56(%r15) |
| 191 | 3: lm %r2,%r5,16(%r15) | 68 | 3: lm %r2,%r5,16(%r15) |
| 192 | br %r14 | 69 | br %r14 |
| 193 | 70 | ||
| 194 | #endif /* CONFIG_DYNAMIC_FTRACE */ | ||
| 195 | |||
| 196 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | 71 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 197 | 72 | ||
| 198 | .globl return_to_handler | 73 | .globl return_to_handler |
| @@ -211,6 +86,4 @@ return_to_handler: | |||
| 211 | lm %r2,%r5,16(%r15) | 86 | lm %r2,%r5,16(%r15) |
| 212 | br %r14 | 87 | br %r14 |
| 213 | 88 | ||
| 214 | #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ | 89 | #endif |
| 215 | |||
| 216 | #endif /* CONFIG_64BIT */ | ||
diff --git a/arch/s390/kernel/mcount64.S b/arch/s390/kernel/mcount64.S new file mode 100644 index 000000000000..c37211c6092b --- /dev/null +++ b/arch/s390/kernel/mcount64.S | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | /* | ||
| 2 | * Copyright IBM Corp. 2008,2009 | ||
| 3 | * | ||
| 4 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>, | ||
| 5 | * | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <asm/asm-offsets.h> | ||
| 9 | |||
| 10 | .globl ftrace_stub | ||
| 11 | ftrace_stub: | ||
| 12 | br %r14 | ||
| 13 | |||
| 14 | .globl _mcount | ||
| 15 | _mcount: | ||
| 16 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
| 17 | br %r14 | ||
| 18 | |||
| 19 | .data | ||
| 20 | .globl ftrace_dyn_func | ||
| 21 | ftrace_dyn_func: | ||
| 22 | .quad ftrace_stub | ||
| 23 | .previous | ||
| 24 | |||
| 25 | .globl ftrace_caller | ||
| 26 | ftrace_caller: | ||
| 27 | #endif | ||
| 28 | larl %r1,function_trace_stop | ||
| 29 | icm %r1,0xf,0(%r1) | ||
| 30 | bnzr %r14 | ||
| 31 | stmg %r2,%r5,32(%r15) | ||
| 32 | stg %r14,112(%r15) | ||
| 33 | lgr %r1,%r15 | ||
| 34 | aghi %r15,-160 | ||
| 35 | stg %r1,__SF_BACKCHAIN(%r15) | ||
| 36 | lgr %r2,%r14 | ||
| 37 | lg %r3,168(%r15) | ||
| 38 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
| 39 | larl %r14,ftrace_dyn_func | ||
| 40 | #else | ||
| 41 | larl %r14,ftrace_trace_function | ||
| 42 | #endif | ||
| 43 | lg %r14,0(%r14) | ||
| 44 | basr %r14,%r14 | ||
| 45 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
| 46 | #ifdef CONFIG_DYNAMIC_FTRACE | ||
| 47 | .globl ftrace_graph_caller | ||
| 48 | ftrace_graph_caller: | ||
| 49 | # This unconditional branch gets runtime patched. Change only if | ||
| 50 | # you know what you are doing. See ftrace_enable_graph_caller(). | ||
| 51 | j 0f | ||
| 52 | #endif | ||
| 53 | lg %r2,272(%r15) | ||
| 54 | lg %r3,168(%r15) | ||
| 55 | brasl %r14,prepare_ftrace_return | ||
| 56 | stg %r2,168(%r15) | ||
| 57 | 0: | ||
| 58 | #endif | ||
| 59 | aghi %r15,160 | ||
| 60 | lmg %r2,%r5,32(%r15) | ||
| 61 | lg %r14,112(%r15) | ||
| 62 | br %r14 | ||
| 63 | |||
| 64 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
| 65 | |||
| 66 | .globl return_to_handler | ||
| 67 | return_to_handler: | ||
| 68 | stmg %r2,%r5,32(%r15) | ||
| 69 | lgr %r1,%r15 | ||
| 70 | aghi %r15,-160 | ||
| 71 | stg %r1,__SF_BACKCHAIN(%r15) | ||
| 72 | brasl %r14,ftrace_return_to_handler | ||
| 73 | aghi %r15,160 | ||
| 74 | lgr %r14,%r2 | ||
| 75 | lmg %r2,%r5,32(%r15) | ||
| 76 | br %r14 | ||
| 77 | |||
| 78 | #endif | ||
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 43acd73105b7..f3ddd7ac06c5 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
| @@ -51,6 +51,9 @@ | |||
| 51 | #include "compat_ptrace.h" | 51 | #include "compat_ptrace.h" |
| 52 | #endif | 52 | #endif |
| 53 | 53 | ||
| 54 | #define CREATE_TRACE_POINTS | ||
| 55 | #include <trace/events/syscalls.h> | ||
| 56 | |||
| 54 | enum s390_regset { | 57 | enum s390_regset { |
| 55 | REGSET_GENERAL, | 58 | REGSET_GENERAL, |
| 56 | REGSET_FP, | 59 | REGSET_FP, |
| @@ -661,8 +664,8 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) | |||
| 661 | ret = -1; | 664 | ret = -1; |
| 662 | } | 665 | } |
| 663 | 666 | ||
| 664 | if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) | 667 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) |
| 665 | ftrace_syscall_enter(regs); | 668 | trace_sys_enter(regs, regs->gprs[2]); |
| 666 | 669 | ||
| 667 | if (unlikely(current->audit_context)) | 670 | if (unlikely(current->audit_context)) |
| 668 | audit_syscall_entry(is_compat_task() ? | 671 | audit_syscall_entry(is_compat_task() ? |
| @@ -679,8 +682,8 @@ asmlinkage void do_syscall_trace_exit(struct pt_regs *regs) | |||
| 679 | audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), | 682 | audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), |
| 680 | regs->gprs[2]); | 683 | regs->gprs[2]); |
| 681 | 684 | ||
| 682 | if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) | 685 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) |
| 683 | ftrace_syscall_exit(regs); | 686 | trace_sys_exit(regs, regs->gprs[2]); |
| 684 | 687 | ||
| 685 | if (test_thread_flag(TIF_SYSCALL_TRACE)) | 688 | if (test_thread_flag(TIF_SYSCALL_TRACE)) |
| 686 | tracehook_report_syscall_exit(regs, 0); | 689 | tracehook_report_syscall_exit(regs, 0); |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index cbb897bc50bd..9ed13a1ed376 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
| @@ -156,15 +156,11 @@ __setup("condev=", condev_setup); | |||
| 156 | 156 | ||
| 157 | static void __init set_preferred_console(void) | 157 | static void __init set_preferred_console(void) |
| 158 | { | 158 | { |
| 159 | if (MACHINE_IS_KVM) { | 159 | if (MACHINE_IS_KVM) |
| 160 | add_preferred_console("hvc", 0, NULL); | 160 | add_preferred_console("hvc", 0, NULL); |
| 161 | s390_virtio_console_init(); | 161 | else if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP) |
| 162 | return; | ||
| 163 | } | ||
| 164 | |||
| 165 | if (CONSOLE_IS_3215 || CONSOLE_IS_SCLP) | ||
| 166 | add_preferred_console("ttyS", 0, NULL); | 162 | add_preferred_console("ttyS", 0, NULL); |
| 167 | if (CONSOLE_IS_3270) | 163 | else if (CONSOLE_IS_3270) |
| 168 | add_preferred_console("tty3270", 0, NULL); | 164 | add_preferred_console("tty3270", 0, NULL); |
| 169 | } | 165 | } |
| 170 | 166 | ||
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 062bd64e65fa..6b4fef877f9d 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c | |||
| @@ -536,4 +536,6 @@ void do_notify_resume(struct pt_regs *regs) | |||
| 536 | { | 536 | { |
| 537 | clear_thread_flag(TIF_NOTIFY_RESUME); | 537 | clear_thread_flag(TIF_NOTIFY_RESUME); |
| 538 | tracehook_notify_resume(regs); | 538 | tracehook_notify_resume(regs); |
| 539 | if (current->replacement_session_keyring) | ||
| 540 | key_replace_session_keyring(); | ||
| 539 | } | 541 | } |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index be2cae083406..56c16876b919 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
| @@ -49,6 +49,7 @@ | |||
| 49 | #include <asm/sclp.h> | 49 | #include <asm/sclp.h> |
| 50 | #include <asm/cputime.h> | 50 | #include <asm/cputime.h> |
| 51 | #include <asm/vdso.h> | 51 | #include <asm/vdso.h> |
| 52 | #include <asm/cpu.h> | ||
| 52 | #include "entry.h" | 53 | #include "entry.h" |
| 53 | 54 | ||
| 54 | static struct task_struct *current_set[NR_CPUS]; | 55 | static struct task_struct *current_set[NR_CPUS]; |
| @@ -70,6 +71,23 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices); | |||
| 70 | 71 | ||
| 71 | static void smp_ext_bitcall(int, ec_bit_sig); | 72 | static void smp_ext_bitcall(int, ec_bit_sig); |
| 72 | 73 | ||
| 74 | static int cpu_stopped(int cpu) | ||
| 75 | { | ||
| 76 | __u32 status; | ||
| 77 | |||
| 78 | switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) { | ||
| 79 | case sigp_order_code_accepted: | ||
| 80 | case sigp_status_stored: | ||
| 81 | /* Check for stopped and check stop state */ | ||
| 82 | if (status & 0x50) | ||
| 83 | return 1; | ||
| 84 | break; | ||
| 85 | default: | ||
| 86 | break; | ||
| 87 | } | ||
| 88 | return 0; | ||
| 89 | } | ||
| 90 | |||
| 73 | void smp_send_stop(void) | 91 | void smp_send_stop(void) |
| 74 | { | 92 | { |
| 75 | int cpu, rc; | 93 | int cpu, rc; |
| @@ -86,7 +104,7 @@ void smp_send_stop(void) | |||
| 86 | rc = signal_processor(cpu, sigp_stop); | 104 | rc = signal_processor(cpu, sigp_stop); |
| 87 | } while (rc == sigp_busy); | 105 | } while (rc == sigp_busy); |
| 88 | 106 | ||
| 89 | while (!smp_cpu_not_running(cpu)) | 107 | while (!cpu_stopped(cpu)) |
| 90 | cpu_relax(); | 108 | cpu_relax(); |
| 91 | } | 109 | } |
| 92 | } | 110 | } |
| @@ -269,19 +287,6 @@ static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { } | |||
| 269 | 287 | ||
| 270 | #endif /* CONFIG_ZFCPDUMP */ | 288 | #endif /* CONFIG_ZFCPDUMP */ |
| 271 | 289 | ||
| 272 | static int cpu_stopped(int cpu) | ||
| 273 | { | ||
| 274 | __u32 status; | ||
| 275 | |||
| 276 | /* Check for stopped state */ | ||
| 277 | if (signal_processor_ps(&status, 0, cpu, sigp_sense) == | ||
| 278 | sigp_status_stored) { | ||
| 279 | if (status & 0x40) | ||
| 280 | return 1; | ||
| 281 | } | ||
| 282 | return 0; | ||
| 283 | } | ||
| 284 | |||
| 285 | static int cpu_known(int cpu_id) | 290 | static int cpu_known(int cpu_id) |
| 286 | { | 291 | { |
| 287 | int cpu; | 292 | int cpu; |
| @@ -300,7 +305,7 @@ static int smp_rescan_cpus_sigp(cpumask_t avail) | |||
| 300 | logical_cpu = cpumask_first(&avail); | 305 | logical_cpu = cpumask_first(&avail); |
| 301 | if (logical_cpu >= nr_cpu_ids) | 306 | if (logical_cpu >= nr_cpu_ids) |
| 302 | return 0; | 307 | return 0; |
| 303 | for (cpu_id = 0; cpu_id <= 65535; cpu_id++) { | 308 | for (cpu_id = 0; cpu_id <= MAX_CPU_ADDRESS; cpu_id++) { |
| 304 | if (cpu_known(cpu_id)) | 309 | if (cpu_known(cpu_id)) |
| 305 | continue; | 310 | continue; |
| 306 | __cpu_logical_map[logical_cpu] = cpu_id; | 311 | __cpu_logical_map[logical_cpu] = cpu_id; |
| @@ -379,7 +384,7 @@ static void __init smp_detect_cpus(void) | |||
| 379 | /* Use sigp detection algorithm if sclp doesn't work. */ | 384 | /* Use sigp detection algorithm if sclp doesn't work. */ |
| 380 | if (sclp_get_cpu_info(info)) { | 385 | if (sclp_get_cpu_info(info)) { |
| 381 | smp_use_sigp_detection = 1; | 386 | smp_use_sigp_detection = 1; |
| 382 | for (cpu = 0; cpu <= 65535; cpu++) { | 387 | for (cpu = 0; cpu <= MAX_CPU_ADDRESS; cpu++) { |
| 383 | if (cpu == boot_cpu_addr) | 388 | if (cpu == boot_cpu_addr) |
| 384 | continue; | 389 | continue; |
| 385 | __cpu_logical_map[CPU_INIT_NO] = cpu; | 390 | __cpu_logical_map[CPU_INIT_NO] = cpu; |
| @@ -635,7 +640,7 @@ int __cpu_disable(void) | |||
| 635 | void __cpu_die(unsigned int cpu) | 640 | void __cpu_die(unsigned int cpu) |
| 636 | { | 641 | { |
| 637 | /* Wait until target cpu is down */ | 642 | /* Wait until target cpu is down */ |
| 638 | while (!smp_cpu_not_running(cpu)) | 643 | while (!cpu_stopped(cpu)) |
| 639 | cpu_relax(); | 644 | cpu_relax(); |
| 640 | smp_free_lowcore(cpu); | 645 | smp_free_lowcore(cpu); |
| 641 | pr_info("Processor %d stopped\n", cpu); | 646 | pr_info("Processor %d stopped\n", cpu); |
diff --git a/arch/s390/power/swsusp.c b/arch/s390/kernel/suspend.c index bd1f5c6b0b8c..086bee970cae 100644 --- a/arch/s390/power/swsusp.c +++ b/arch/s390/kernel/suspend.c | |||
| @@ -1,13 +1,44 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Support for suspend and resume on s390 | 2 | * Suspend support specific for s390. |
| 3 | * | 3 | * |
| 4 | * Copyright IBM Corp. 2009 | 4 | * Copyright IBM Corp. 2009 |
| 5 | * | 5 | * |
| 6 | * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> | 6 | * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> |
| 7 | * | ||
| 8 | */ | 7 | */ |
| 9 | 8 | ||
| 9 | #include <linux/suspend.h> | ||
| 10 | #include <linux/reboot.h> | ||
| 11 | #include <linux/pfn.h> | ||
| 12 | #include <linux/mm.h> | ||
| 13 | #include <asm/sections.h> | ||
| 10 | #include <asm/system.h> | 14 | #include <asm/system.h> |
| 15 | #include <asm/ipl.h> | ||
| 16 | |||
| 17 | /* | ||
| 18 | * References to section boundaries | ||
| 19 | */ | ||
| 20 | extern const void __nosave_begin, __nosave_end; | ||
| 21 | |||
| 22 | /* | ||
| 23 | * check if given pfn is in the 'nosave' or in the read only NSS section | ||
| 24 | */ | ||
| 25 | int pfn_is_nosave(unsigned long pfn) | ||
| 26 | { | ||
| 27 | unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT; | ||
| 28 | unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) | ||
| 29 | >> PAGE_SHIFT; | ||
| 30 | unsigned long eshared_pfn = PFN_DOWN(__pa(&_eshared)) - 1; | ||
| 31 | unsigned long stext_pfn = PFN_DOWN(__pa(&_stext)); | ||
| 32 | |||
| 33 | if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn) | ||
| 34 | return 1; | ||
| 35 | if (pfn >= stext_pfn && pfn <= eshared_pfn) { | ||
| 36 | if (ipl_info.type == IPL_TYPE_NSS) | ||
| 37 | return 1; | ||
| 38 | } else if ((tprot(pfn * PAGE_SIZE) && pfn > 0)) | ||
| 39 | return 1; | ||
| 40 | return 0; | ||
| 41 | } | ||
| 11 | 42 | ||
| 12 | void save_processor_state(void) | 43 | void save_processor_state(void) |
| 13 | { | 44 | { |
diff --git a/arch/s390/power/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S index b26df5c5933e..7cd6b096f0d1 100644 --- a/arch/s390/power/swsusp_asm64.S +++ b/arch/s390/kernel/swsusp_asm64.S | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | * This function runs with disabled interrupts. | 21 | * This function runs with disabled interrupts. |
| 22 | */ | 22 | */ |
| 23 | .section .text | 23 | .section .text |
| 24 | .align 2 | 24 | .align 4 |
| 25 | .globl swsusp_arch_suspend | 25 | .globl swsusp_arch_suspend |
| 26 | swsusp_arch_suspend: | 26 | swsusp_arch_suspend: |
| 27 | stmg %r6,%r15,__SF_GPRS(%r15) | 27 | stmg %r6,%r15,__SF_GPRS(%r15) |
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index d4c8e9c47c81..54e327e9af04 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
| @@ -60,6 +60,7 @@ | |||
| 60 | #define TICK_SIZE tick | 60 | #define TICK_SIZE tick |
| 61 | 61 | ||
| 62 | u64 sched_clock_base_cc = -1; /* Force to data section. */ | 62 | u64 sched_clock_base_cc = -1; /* Force to data section. */ |
| 63 | EXPORT_SYMBOL_GPL(sched_clock_base_cc); | ||
| 63 | 64 | ||
| 64 | static DEFINE_PER_CPU(struct clock_event_device, comparators); | 65 | static DEFINE_PER_CPU(struct clock_event_device, comparators); |
| 65 | 66 | ||
| @@ -68,7 +69,7 @@ static DEFINE_PER_CPU(struct clock_event_device, comparators); | |||
| 68 | */ | 69 | */ |
| 69 | unsigned long long notrace sched_clock(void) | 70 | unsigned long long notrace sched_clock(void) |
| 70 | { | 71 | { |
| 71 | return ((get_clock_xt() - sched_clock_base_cc) * 125) >> 9; | 72 | return (get_clock_monotonic() * 125) >> 9; |
| 72 | } | 73 | } |
| 73 | 74 | ||
| 74 | /* | 75 | /* |
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index a53db23ee092..7315f9e67e1d 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S | |||
| @@ -52,55 +52,18 @@ SECTIONS | |||
| 52 | . = ALIGN(PAGE_SIZE); | 52 | . = ALIGN(PAGE_SIZE); |
| 53 | _eshared = .; /* End of shareable data */ | 53 | _eshared = .; /* End of shareable data */ |
| 54 | 54 | ||
| 55 | . = ALIGN(16); /* Exception table */ | 55 | EXCEPTION_TABLE(16) :data |
| 56 | __ex_table : { | ||
| 57 | __start___ex_table = .; | ||
| 58 | *(__ex_table) | ||
| 59 | __stop___ex_table = .; | ||
| 60 | } :data | ||
| 61 | |||
| 62 | .data : { /* Data */ | ||
| 63 | DATA_DATA | ||
| 64 | CONSTRUCTORS | ||
| 65 | } | ||
| 66 | |||
| 67 | . = ALIGN(PAGE_SIZE); | ||
| 68 | .data_nosave : { | ||
| 69 | __nosave_begin = .; | ||
| 70 | *(.data.nosave) | ||
| 71 | } | ||
| 72 | . = ALIGN(PAGE_SIZE); | ||
| 73 | __nosave_end = .; | ||
| 74 | |||
| 75 | . = ALIGN(PAGE_SIZE); | ||
| 76 | .data.page_aligned : { | ||
| 77 | *(.data.idt) | ||
| 78 | } | ||
| 79 | 56 | ||
| 80 | . = ALIGN(0x100); | 57 | RW_DATA_SECTION(0x100, PAGE_SIZE, THREAD_SIZE) |
| 81 | .data.cacheline_aligned : { | ||
| 82 | *(.data.cacheline_aligned) | ||
| 83 | } | ||
| 84 | 58 | ||
| 85 | . = ALIGN(0x100); | ||
| 86 | .data.read_mostly : { | ||
| 87 | *(.data.read_mostly) | ||
| 88 | } | ||
| 89 | _edata = .; /* End of data section */ | 59 | _edata = .; /* End of data section */ |
| 90 | 60 | ||
| 91 | . = ALIGN(THREAD_SIZE); /* init_task */ | ||
| 92 | .data.init_task : { | ||
| 93 | *(.data.init_task) | ||
| 94 | } | ||
| 95 | |||
| 96 | /* will be freed after init */ | 61 | /* will be freed after init */ |
| 97 | . = ALIGN(PAGE_SIZE); /* Init code and data */ | 62 | . = ALIGN(PAGE_SIZE); /* Init code and data */ |
| 98 | __init_begin = .; | 63 | __init_begin = .; |
| 99 | .init.text : { | 64 | |
| 100 | _sinittext = .; | 65 | INIT_TEXT_SECTION(PAGE_SIZE) |
| 101 | INIT_TEXT | 66 | |
| 102 | _einittext = .; | ||
| 103 | } | ||
| 104 | /* | 67 | /* |
| 105 | * .exit.text is discarded at runtime, not link time, | 68 | * .exit.text is discarded at runtime, not link time, |
| 106 | * to deal with references from __bug_table | 69 | * to deal with references from __bug_table |
| @@ -111,49 +74,13 @@ SECTIONS | |||
| 111 | 74 | ||
| 112 | /* early.c uses stsi, which requires page aligned data. */ | 75 | /* early.c uses stsi, which requires page aligned data. */ |
| 113 | . = ALIGN(PAGE_SIZE); | 76 | . = ALIGN(PAGE_SIZE); |
| 114 | .init.data : { | 77 | INIT_DATA_SECTION(0x100) |
| 115 | INIT_DATA | ||
| 116 | } | ||
| 117 | . = ALIGN(0x100); | ||
| 118 | .init.setup : { | ||
| 119 | __setup_start = .; | ||
| 120 | *(.init.setup) | ||
| 121 | __setup_end = .; | ||
| 122 | } | ||
| 123 | .initcall.init : { | ||
| 124 | __initcall_start = .; | ||
| 125 | INITCALLS | ||
| 126 | __initcall_end = .; | ||
| 127 | } | ||
| 128 | |||
| 129 | .con_initcall.init : { | ||
| 130 | __con_initcall_start = .; | ||
| 131 | *(.con_initcall.init) | ||
| 132 | __con_initcall_end = .; | ||
| 133 | } | ||
| 134 | SECURITY_INIT | ||
| 135 | |||
| 136 | #ifdef CONFIG_BLK_DEV_INITRD | ||
| 137 | . = ALIGN(0x100); | ||
| 138 | .init.ramfs : { | ||
| 139 | __initramfs_start = .; | ||
| 140 | *(.init.ramfs) | ||
| 141 | . = ALIGN(2); | ||
| 142 | __initramfs_end = .; | ||
| 143 | } | ||
| 144 | #endif | ||
| 145 | 78 | ||
| 146 | PERCPU(PAGE_SIZE) | 79 | PERCPU(PAGE_SIZE) |
| 147 | . = ALIGN(PAGE_SIZE); | 80 | . = ALIGN(PAGE_SIZE); |
| 148 | __init_end = .; /* freed after init ends here */ | 81 | __init_end = .; /* freed after init ends here */ |
| 149 | 82 | ||
| 150 | /* BSS */ | 83 | BSS_SECTION(0, 2, 0) |
| 151 | .bss : { | ||
| 152 | __bss_start = .; | ||
| 153 | *(.bss) | ||
| 154 | . = ALIGN(2); | ||
| 155 | __bss_stop = .; | ||
| 156 | } | ||
| 157 | 84 | ||
| 158 | _end = . ; | 85 | _end = . ; |
| 159 | 86 | ||
diff --git a/arch/s390/mm/Makefile b/arch/s390/mm/Makefile index db05661ac895..eec054484419 100644 --- a/arch/s390/mm/Makefile +++ b/arch/s390/mm/Makefile | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | # Makefile for the linux s390-specific parts of the memory manager. | 2 | # Makefile for the linux s390-specific parts of the memory manager. |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o | 5 | obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o \ |
| 6 | page-states.o | ||
| 6 | obj-$(CONFIG_CMM) += cmm.o | 7 | obj-$(CONFIG_CMM) += cmm.o |
| 7 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o | 8 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o |
| 8 | obj-$(CONFIG_PAGE_STATES) += page-states.o | ||
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index e5e119fe03b2..1abbadd497e1 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | * Copyright (C) 1995 Linus Torvalds | 10 | * Copyright (C) 1995 Linus Torvalds |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/perf_counter.h> | ||
| 13 | #include <linux/signal.h> | 14 | #include <linux/signal.h> |
| 14 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
| 15 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| @@ -305,7 +306,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int write) | |||
| 305 | * interrupts again and then search the VMAs | 306 | * interrupts again and then search the VMAs |
| 306 | */ | 307 | */ |
| 307 | local_irq_enable(); | 308 | local_irq_enable(); |
| 308 | 309 | perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address); | |
| 309 | down_read(&mm->mmap_sem); | 310 | down_read(&mm->mmap_sem); |
| 310 | 311 | ||
| 311 | si_code = SEGV_MAPERR; | 312 | si_code = SEGV_MAPERR; |
| @@ -363,11 +364,15 @@ good_area: | |||
| 363 | } | 364 | } |
| 364 | BUG(); | 365 | BUG(); |
| 365 | } | 366 | } |
| 366 | if (fault & VM_FAULT_MAJOR) | 367 | if (fault & VM_FAULT_MAJOR) { |
| 367 | tsk->maj_flt++; | 368 | tsk->maj_flt++; |
| 368 | else | 369 | perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0, |
| 370 | regs, address); | ||
| 371 | } else { | ||
| 369 | tsk->min_flt++; | 372 | tsk->min_flt++; |
| 370 | 373 | perf_swcounter_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0, | |
| 374 | regs, address); | ||
| 375 | } | ||
| 371 | up_read(&mm->mmap_sem); | 376 | up_read(&mm->mmap_sem); |
| 372 | /* | 377 | /* |
| 373 | * The instruction that caused the program check will | 378 | * The instruction that caused the program check will |
diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c index fc0ad73ffd90..f92ec203ad92 100644 --- a/arch/s390/mm/page-states.c +++ b/arch/s390/mm/page-states.c | |||
| @@ -1,6 +1,4 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * arch/s390/mm/page-states.c | ||
| 3 | * | ||
| 4 | * Copyright IBM Corp. 2008 | 2 | * Copyright IBM Corp. 2008 |
| 5 | * | 3 | * |
| 6 | * Guest page hinting for unused pages. | 4 | * Guest page hinting for unused pages. |
| @@ -17,11 +15,12 @@ | |||
| 17 | #define ESSA_SET_STABLE 1 | 15 | #define ESSA_SET_STABLE 1 |
| 18 | #define ESSA_SET_UNUSED 2 | 16 | #define ESSA_SET_UNUSED 2 |
| 19 | 17 | ||
| 20 | static int cmma_flag; | 18 | static int cmma_flag = 1; |
| 21 | 19 | ||
| 22 | static int __init cmma(char *str) | 20 | static int __init cmma(char *str) |
| 23 | { | 21 | { |
| 24 | char *parm; | 22 | char *parm; |
| 23 | |||
| 25 | parm = strstrip(str); | 24 | parm = strstrip(str); |
| 26 | if (strcmp(parm, "yes") == 0 || strcmp(parm, "on") == 0) { | 25 | if (strcmp(parm, "yes") == 0 || strcmp(parm, "on") == 0) { |
| 27 | cmma_flag = 1; | 26 | cmma_flag = 1; |
| @@ -32,7 +31,6 @@ static int __init cmma(char *str) | |||
| 32 | return 1; | 31 | return 1; |
| 33 | return 0; | 32 | return 0; |
| 34 | } | 33 | } |
| 35 | |||
| 36 | __setup("cmma=", cmma); | 34 | __setup("cmma=", cmma); |
| 37 | 35 | ||
| 38 | void __init cmma_init(void) | 36 | void __init cmma_init(void) |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 565667207985..c70215247071 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
| @@ -78,9 +78,9 @@ unsigned long *crst_table_alloc(struct mm_struct *mm, int noexec) | |||
| 78 | } | 78 | } |
| 79 | page->index = page_to_phys(shadow); | 79 | page->index = page_to_phys(shadow); |
| 80 | } | 80 | } |
| 81 | spin_lock(&mm->page_table_lock); | 81 | spin_lock(&mm->context.list_lock); |
| 82 | list_add(&page->lru, &mm->context.crst_list); | 82 | list_add(&page->lru, &mm->context.crst_list); |
| 83 | spin_unlock(&mm->page_table_lock); | 83 | spin_unlock(&mm->context.list_lock); |
| 84 | return (unsigned long *) page_to_phys(page); | 84 | return (unsigned long *) page_to_phys(page); |
| 85 | } | 85 | } |
| 86 | 86 | ||
| @@ -89,9 +89,9 @@ void crst_table_free(struct mm_struct *mm, unsigned long *table) | |||
| 89 | unsigned long *shadow = get_shadow_table(table); | 89 | unsigned long *shadow = get_shadow_table(table); |
| 90 | struct page *page = virt_to_page(table); | 90 | struct page *page = virt_to_page(table); |
| 91 | 91 | ||
| 92 | spin_lock(&mm->page_table_lock); | 92 | spin_lock(&mm->context.list_lock); |
| 93 | list_del(&page->lru); | 93 | list_del(&page->lru); |
| 94 | spin_unlock(&mm->page_table_lock); | 94 | spin_unlock(&mm->context.list_lock); |
| 95 | if (shadow) | 95 | if (shadow) |
| 96 | free_pages((unsigned long) shadow, ALLOC_ORDER); | 96 | free_pages((unsigned long) shadow, ALLOC_ORDER); |
| 97 | free_pages((unsigned long) table, ALLOC_ORDER); | 97 | free_pages((unsigned long) table, ALLOC_ORDER); |
| @@ -182,7 +182,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) | |||
| 182 | unsigned long bits; | 182 | unsigned long bits; |
| 183 | 183 | ||
| 184 | bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL; | 184 | bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL; |
| 185 | spin_lock(&mm->page_table_lock); | 185 | spin_lock(&mm->context.list_lock); |
| 186 | page = NULL; | 186 | page = NULL; |
| 187 | if (!list_empty(&mm->context.pgtable_list)) { | 187 | if (!list_empty(&mm->context.pgtable_list)) { |
| 188 | page = list_first_entry(&mm->context.pgtable_list, | 188 | page = list_first_entry(&mm->context.pgtable_list, |
| @@ -191,7 +191,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) | |||
| 191 | page = NULL; | 191 | page = NULL; |
| 192 | } | 192 | } |
| 193 | if (!page) { | 193 | if (!page) { |
| 194 | spin_unlock(&mm->page_table_lock); | 194 | spin_unlock(&mm->context.list_lock); |
| 195 | page = alloc_page(GFP_KERNEL|__GFP_REPEAT); | 195 | page = alloc_page(GFP_KERNEL|__GFP_REPEAT); |
| 196 | if (!page) | 196 | if (!page) |
| 197 | return NULL; | 197 | return NULL; |
| @@ -202,7 +202,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) | |||
| 202 | clear_table_pgstes(table); | 202 | clear_table_pgstes(table); |
| 203 | else | 203 | else |
| 204 | clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE); | 204 | clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE); |
| 205 | spin_lock(&mm->page_table_lock); | 205 | spin_lock(&mm->context.list_lock); |
| 206 | list_add(&page->lru, &mm->context.pgtable_list); | 206 | list_add(&page->lru, &mm->context.pgtable_list); |
| 207 | } | 207 | } |
| 208 | table = (unsigned long *) page_to_phys(page); | 208 | table = (unsigned long *) page_to_phys(page); |
| @@ -213,7 +213,7 @@ unsigned long *page_table_alloc(struct mm_struct *mm) | |||
| 213 | page->flags |= bits; | 213 | page->flags |= bits; |
| 214 | if ((page->flags & FRAG_MASK) == ((1UL << TABLES_PER_PAGE) - 1)) | 214 | if ((page->flags & FRAG_MASK) == ((1UL << TABLES_PER_PAGE) - 1)) |
| 215 | list_move_tail(&page->lru, &mm->context.pgtable_list); | 215 | list_move_tail(&page->lru, &mm->context.pgtable_list); |
| 216 | spin_unlock(&mm->page_table_lock); | 216 | spin_unlock(&mm->context.list_lock); |
| 217 | return table; | 217 | return table; |
| 218 | } | 218 | } |
| 219 | 219 | ||
| @@ -225,7 +225,7 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) | |||
| 225 | bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL; | 225 | bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL; |
| 226 | bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long); | 226 | bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long); |
| 227 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); | 227 | page = pfn_to_page(__pa(table) >> PAGE_SHIFT); |
| 228 | spin_lock(&mm->page_table_lock); | 228 | spin_lock(&mm->context.list_lock); |
| 229 | page->flags ^= bits; | 229 | page->flags ^= bits; |
| 230 | if (page->flags & FRAG_MASK) { | 230 | if (page->flags & FRAG_MASK) { |
| 231 | /* Page now has some free pgtable fragments. */ | 231 | /* Page now has some free pgtable fragments. */ |
| @@ -234,7 +234,7 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) | |||
| 234 | } else | 234 | } else |
| 235 | /* All fragments of the 4K page have been freed. */ | 235 | /* All fragments of the 4K page have been freed. */ |
| 236 | list_del(&page->lru); | 236 | list_del(&page->lru); |
| 237 | spin_unlock(&mm->page_table_lock); | 237 | spin_unlock(&mm->context.list_lock); |
| 238 | if (page) { | 238 | if (page) { |
| 239 | pgtable_page_dtor(page); | 239 | pgtable_page_dtor(page); |
| 240 | __free_page(page); | 240 | __free_page(page); |
| @@ -245,7 +245,7 @@ void disable_noexec(struct mm_struct *mm, struct task_struct *tsk) | |||
| 245 | { | 245 | { |
| 246 | struct page *page; | 246 | struct page *page; |
| 247 | 247 | ||
| 248 | spin_lock(&mm->page_table_lock); | 248 | spin_lock(&mm->context.list_lock); |
| 249 | /* Free shadow region and segment tables. */ | 249 | /* Free shadow region and segment tables. */ |
| 250 | list_for_each_entry(page, &mm->context.crst_list, lru) | 250 | list_for_each_entry(page, &mm->context.crst_list, lru) |
| 251 | if (page->index) { | 251 | if (page->index) { |
| @@ -255,7 +255,7 @@ void disable_noexec(struct mm_struct *mm, struct task_struct *tsk) | |||
| 255 | /* "Free" second halves of page tables. */ | 255 | /* "Free" second halves of page tables. */ |
| 256 | list_for_each_entry(page, &mm->context.pgtable_list, lru) | 256 | list_for_each_entry(page, &mm->context.pgtable_list, lru) |
| 257 | page->flags &= ~SECOND_HALVES; | 257 | page->flags &= ~SECOND_HALVES; |
| 258 | spin_unlock(&mm->page_table_lock); | 258 | spin_unlock(&mm->context.list_lock); |
| 259 | mm->context.noexec = 0; | 259 | mm->context.noexec = 0; |
| 260 | update_mm(mm, tsk); | 260 | update_mm(mm, tsk); |
| 261 | } | 261 | } |
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index e4868bfc672f..5f91a38d7592 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c | |||
| @@ -331,6 +331,7 @@ void __init vmem_map_init(void) | |||
| 331 | unsigned long start, end; | 331 | unsigned long start, end; |
| 332 | int i; | 332 | int i; |
| 333 | 333 | ||
| 334 | spin_lock_init(&init_mm.context.list_lock); | ||
| 334 | INIT_LIST_HEAD(&init_mm.context.crst_list); | 335 | INIT_LIST_HEAD(&init_mm.context.crst_list); |
| 335 | INIT_LIST_HEAD(&init_mm.context.pgtable_list); | 336 | INIT_LIST_HEAD(&init_mm.context.pgtable_list); |
| 336 | init_mm.context.noexec = 0; | 337 | init_mm.context.noexec = 0; |
diff --git a/arch/s390/power/Makefile b/arch/s390/power/Makefile deleted file mode 100644 index 973bb45a8fec..000000000000 --- a/arch/s390/power/Makefile +++ /dev/null | |||
| @@ -1,8 +0,0 @@ | |||
| 1 | # | ||
| 2 | # Makefile for s390 PM support | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-$(CONFIG_HIBERNATION) += suspend.o | ||
| 6 | obj-$(CONFIG_HIBERNATION) += swsusp.o | ||
| 7 | obj-$(CONFIG_HIBERNATION) += swsusp_64.o | ||
| 8 | obj-$(CONFIG_HIBERNATION) += swsusp_asm64.o | ||
diff --git a/arch/s390/power/suspend.c b/arch/s390/power/suspend.c deleted file mode 100644 index b3351eceebbe..000000000000 --- a/arch/s390/power/suspend.c +++ /dev/null | |||
| @@ -1,40 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Suspend support specific for s390. | ||
| 3 | * | ||
| 4 | * Copyright IBM Corp. 2009 | ||
| 5 | * | ||
| 6 | * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/mm.h> | ||
| 10 | #include <linux/suspend.h> | ||
| 11 | #include <linux/reboot.h> | ||
| 12 | #include <linux/pfn.h> | ||
| 13 | #include <asm/sections.h> | ||
| 14 | #include <asm/ipl.h> | ||
| 15 | |||
| 16 | /* | ||
| 17 | * References to section boundaries | ||
| 18 | */ | ||
| 19 | extern const void __nosave_begin, __nosave_end; | ||
| 20 | |||
| 21 | /* | ||
| 22 | * check if given pfn is in the 'nosave' or in the read only NSS section | ||
| 23 | */ | ||
| 24 | int pfn_is_nosave(unsigned long pfn) | ||
| 25 | { | ||
| 26 | unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT; | ||
| 27 | unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) | ||
| 28 | >> PAGE_SHIFT; | ||
| 29 | unsigned long eshared_pfn = PFN_DOWN(__pa(&_eshared)) - 1; | ||
| 30 | unsigned long stext_pfn = PFN_DOWN(__pa(&_stext)); | ||
| 31 | |||
| 32 | if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn) | ||
| 33 | return 1; | ||
| 34 | if (pfn >= stext_pfn && pfn <= eshared_pfn) { | ||
| 35 | if (ipl_info.type == IPL_TYPE_NSS) | ||
| 36 | return 1; | ||
| 37 | } else if ((tprot(pfn * PAGE_SIZE) && pfn > 0)) | ||
| 38 | return 1; | ||
| 39 | return 0; | ||
| 40 | } | ||
diff --git a/arch/s390/power/swsusp_64.c b/arch/s390/power/swsusp_64.c deleted file mode 100644 index 9516a517d72f..000000000000 --- a/arch/s390/power/swsusp_64.c +++ /dev/null | |||
| @@ -1,17 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Support for suspend and resume on s390 | ||
| 3 | * | ||
| 4 | * Copyright IBM Corp. 2009 | ||
| 5 | * | ||
| 6 | * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> | ||
| 7 | * | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <asm/system.h> | ||
| 11 | #include <linux/interrupt.h> | ||
| 12 | |||
| 13 | void do_after_copyback(void) | ||
| 14 | { | ||
| 15 | mb(); | ||
| 16 | } | ||
| 17 | |||
