diff options
author | Jiri Kosina <jkosina@suse.cz> | 2014-02-20 08:54:28 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2014-02-20 08:54:28 -0500 |
commit | d4263348f796f29546f90802177865dd4379dd0a (patch) | |
tree | adcbdaebae584eee2f32fab95e826e8e49eef385 /arch/s390 | |
parent | be873ac782f5ff5ee6675f83929f4fe6737eead2 (diff) | |
parent | 6d0abeca3242a88cab8232e4acd7e2bf088f3bc2 (diff) |
Merge branch 'master' into for-next
Diffstat (limited to 'arch/s390')
61 files changed, 3215 insertions, 373 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 1e1a03d2d19f..65a07750f4f9 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -135,7 +135,6 @@ config S390 | |||
135 | select HAVE_SYSCALL_TRACEPOINTS | 135 | select HAVE_SYSCALL_TRACEPOINTS |
136 | select HAVE_UID16 if 32BIT | 136 | select HAVE_UID16 if 32BIT |
137 | select HAVE_VIRT_CPU_ACCOUNTING | 137 | select HAVE_VIRT_CPU_ACCOUNTING |
138 | select INIT_ALL_POSSIBLE | ||
139 | select KTIME_SCALAR if 32BIT | 138 | select KTIME_SCALAR if 32BIT |
140 | select MODULES_USE_ELF_RELA | 139 | select MODULES_USE_ELF_RELA |
141 | select OLD_SIGACTION | 140 | select OLD_SIGACTION |
@@ -335,10 +334,10 @@ config SMP | |||
335 | a system with only one CPU, like most personal computers, say N. If | 334 | a system with only one CPU, like most personal computers, say N. If |
336 | you have a system with more than one CPU, say Y. | 335 | you have a system with more than one CPU, say Y. |
337 | 336 | ||
338 | If you say N here, the kernel will run on single and multiprocessor | 337 | If you say N here, the kernel will run on uni- and multiprocessor |
339 | machines, but will use only one CPU of a multiprocessor machine. If | 338 | machines, but will use only one CPU of a multiprocessor machine. If |
340 | you say Y here, the kernel will run on many, but not all, | 339 | you say Y here, the kernel will run on many, but not all, |
341 | singleprocessor machines. On a singleprocessor machine, the kernel | 340 | uniprocessor machines. On a uniprocessor machine, the kernel |
342 | will run faster if you say N here. | 341 | will run faster if you say N here. |
343 | 342 | ||
344 | See also the SMP-HOWTO available at | 343 | See also the SMP-HOWTO available at |
@@ -597,7 +596,7 @@ config CRASH_DUMP | |||
597 | config ZFCPDUMP | 596 | config ZFCPDUMP |
598 | def_bool n | 597 | def_bool n |
599 | prompt "zfcpdump support" | 598 | prompt "zfcpdump support" |
600 | depends on SMP | 599 | depends on 64BIT && SMP |
601 | help | 600 | help |
602 | Select this option if you want to build an zfcpdump enabled kernel. | 601 | Select this option if you want to build an zfcpdump enabled kernel. |
603 | Refer to <file:Documentation/s390/zfcpdump.txt> for more details on this. | 602 | Refer to <file:Documentation/s390/zfcpdump.txt> for more details on this. |
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 4c4a1cef5208..47c8630c93cd 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c | |||
@@ -529,6 +529,7 @@ static int __init appldata_init(void) | |||
529 | { | 529 | { |
530 | int rc; | 530 | int rc; |
531 | 531 | ||
532 | init_virt_timer(&appldata_timer); | ||
532 | appldata_timer.function = appldata_timer_function; | 533 | appldata_timer.function = appldata_timer_function; |
533 | appldata_timer.data = (unsigned long) &appldata_work; | 534 | appldata_timer.data = (unsigned long) &appldata_work; |
534 | 535 | ||
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index b3feabd39f31..cf3c0089bef2 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/err.h> | 25 | #include <linux/err.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
28 | #include <linux/spinlock.h> | ||
28 | #include "crypt_s390.h" | 29 | #include "crypt_s390.h" |
29 | 30 | ||
30 | #define AES_KEYLEN_128 1 | 31 | #define AES_KEYLEN_128 1 |
@@ -32,6 +33,7 @@ | |||
32 | #define AES_KEYLEN_256 4 | 33 | #define AES_KEYLEN_256 4 |
33 | 34 | ||
34 | static u8 *ctrblk; | 35 | static u8 *ctrblk; |
36 | static DEFINE_SPINLOCK(ctrblk_lock); | ||
35 | static char keylen_flag; | 37 | static char keylen_flag; |
36 | 38 | ||
37 | struct s390_aes_ctx { | 39 | struct s390_aes_ctx { |
@@ -758,43 +760,67 @@ static int ctr_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, | |||
758 | return aes_set_key(tfm, in_key, key_len); | 760 | return aes_set_key(tfm, in_key, key_len); |
759 | } | 761 | } |
760 | 762 | ||
763 | static unsigned int __ctrblk_init(u8 *ctrptr, unsigned int nbytes) | ||
764 | { | ||
765 | unsigned int i, n; | ||
766 | |||
767 | /* only use complete blocks, max. PAGE_SIZE */ | ||
768 | n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : nbytes & ~(AES_BLOCK_SIZE - 1); | ||
769 | for (i = AES_BLOCK_SIZE; i < n; i += AES_BLOCK_SIZE) { | ||
770 | memcpy(ctrptr + i, ctrptr + i - AES_BLOCK_SIZE, | ||
771 | AES_BLOCK_SIZE); | ||
772 | crypto_inc(ctrptr + i, AES_BLOCK_SIZE); | ||
773 | } | ||
774 | return n; | ||
775 | } | ||
776 | |||
761 | static int ctr_aes_crypt(struct blkcipher_desc *desc, long func, | 777 | static int ctr_aes_crypt(struct blkcipher_desc *desc, long func, |
762 | struct s390_aes_ctx *sctx, struct blkcipher_walk *walk) | 778 | struct s390_aes_ctx *sctx, struct blkcipher_walk *walk) |
763 | { | 779 | { |
764 | int ret = blkcipher_walk_virt_block(desc, walk, AES_BLOCK_SIZE); | 780 | int ret = blkcipher_walk_virt_block(desc, walk, AES_BLOCK_SIZE); |
765 | unsigned int i, n, nbytes; | 781 | unsigned int n, nbytes; |
766 | u8 buf[AES_BLOCK_SIZE]; | 782 | u8 buf[AES_BLOCK_SIZE], ctrbuf[AES_BLOCK_SIZE]; |
767 | u8 *out, *in; | 783 | u8 *out, *in, *ctrptr = ctrbuf; |
768 | 784 | ||
769 | if (!walk->nbytes) | 785 | if (!walk->nbytes) |
770 | return ret; | 786 | return ret; |
771 | 787 | ||
772 | memcpy(ctrblk, walk->iv, AES_BLOCK_SIZE); | 788 | if (spin_trylock(&ctrblk_lock)) |
789 | ctrptr = ctrblk; | ||
790 | |||
791 | memcpy(ctrptr, walk->iv, AES_BLOCK_SIZE); | ||
773 | while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) { | 792 | while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) { |
774 | out = walk->dst.virt.addr; | 793 | out = walk->dst.virt.addr; |
775 | in = walk->src.virt.addr; | 794 | in = walk->src.virt.addr; |
776 | while (nbytes >= AES_BLOCK_SIZE) { | 795 | while (nbytes >= AES_BLOCK_SIZE) { |
777 | /* only use complete blocks, max. PAGE_SIZE */ | 796 | if (ctrptr == ctrblk) |
778 | n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : | 797 | n = __ctrblk_init(ctrptr, nbytes); |
779 | nbytes & ~(AES_BLOCK_SIZE - 1); | 798 | else |
780 | for (i = AES_BLOCK_SIZE; i < n; i += AES_BLOCK_SIZE) { | 799 | n = AES_BLOCK_SIZE; |
781 | memcpy(ctrblk + i, ctrblk + i - AES_BLOCK_SIZE, | 800 | ret = crypt_s390_kmctr(func, sctx->key, out, in, |
782 | AES_BLOCK_SIZE); | 801 | n, ctrptr); |
783 | crypto_inc(ctrblk + i, AES_BLOCK_SIZE); | 802 | if (ret < 0 || ret != n) { |
784 | } | 803 | if (ctrptr == ctrblk) |
785 | ret = crypt_s390_kmctr(func, sctx->key, out, in, n, ctrblk); | 804 | spin_unlock(&ctrblk_lock); |
786 | if (ret < 0 || ret != n) | ||
787 | return -EIO; | 805 | return -EIO; |
806 | } | ||
788 | if (n > AES_BLOCK_SIZE) | 807 | if (n > AES_BLOCK_SIZE) |
789 | memcpy(ctrblk, ctrblk + n - AES_BLOCK_SIZE, | 808 | memcpy(ctrptr, ctrptr + n - AES_BLOCK_SIZE, |
790 | AES_BLOCK_SIZE); | 809 | AES_BLOCK_SIZE); |
791 | crypto_inc(ctrblk, AES_BLOCK_SIZE); | 810 | crypto_inc(ctrptr, AES_BLOCK_SIZE); |
792 | out += n; | 811 | out += n; |
793 | in += n; | 812 | in += n; |
794 | nbytes -= n; | 813 | nbytes -= n; |
795 | } | 814 | } |
796 | ret = blkcipher_walk_done(desc, walk, nbytes); | 815 | ret = blkcipher_walk_done(desc, walk, nbytes); |
797 | } | 816 | } |
817 | if (ctrptr == ctrblk) { | ||
818 | if (nbytes) | ||
819 | memcpy(ctrbuf, ctrptr, AES_BLOCK_SIZE); | ||
820 | else | ||
821 | memcpy(walk->iv, ctrptr, AES_BLOCK_SIZE); | ||
822 | spin_unlock(&ctrblk_lock); | ||
823 | } | ||
798 | /* | 824 | /* |
799 | * final block may be < AES_BLOCK_SIZE, copy only nbytes | 825 | * final block may be < AES_BLOCK_SIZE, copy only nbytes |
800 | */ | 826 | */ |
@@ -802,14 +828,15 @@ static int ctr_aes_crypt(struct blkcipher_desc *desc, long func, | |||
802 | out = walk->dst.virt.addr; | 828 | out = walk->dst.virt.addr; |
803 | in = walk->src.virt.addr; | 829 | in = walk->src.virt.addr; |
804 | ret = crypt_s390_kmctr(func, sctx->key, buf, in, | 830 | ret = crypt_s390_kmctr(func, sctx->key, buf, in, |
805 | AES_BLOCK_SIZE, ctrblk); | 831 | AES_BLOCK_SIZE, ctrbuf); |
806 | if (ret < 0 || ret != AES_BLOCK_SIZE) | 832 | if (ret < 0 || ret != AES_BLOCK_SIZE) |
807 | return -EIO; | 833 | return -EIO; |
808 | memcpy(out, buf, nbytes); | 834 | memcpy(out, buf, nbytes); |
809 | crypto_inc(ctrblk, AES_BLOCK_SIZE); | 835 | crypto_inc(ctrbuf, AES_BLOCK_SIZE); |
810 | ret = blkcipher_walk_done(desc, walk, 0); | 836 | ret = blkcipher_walk_done(desc, walk, 0); |
837 | memcpy(walk->iv, ctrbuf, AES_BLOCK_SIZE); | ||
811 | } | 838 | } |
812 | memcpy(walk->iv, ctrblk, AES_BLOCK_SIZE); | 839 | |
813 | return ret; | 840 | return ret; |
814 | } | 841 | } |
815 | 842 | ||
diff --git a/arch/s390/crypto/des_s390.c b/arch/s390/crypto/des_s390.c index bcca01c9989d..0a5aac8a9412 100644 --- a/arch/s390/crypto/des_s390.c +++ b/arch/s390/crypto/des_s390.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #define DES3_KEY_SIZE (3 * DES_KEY_SIZE) | 25 | #define DES3_KEY_SIZE (3 * DES_KEY_SIZE) |
26 | 26 | ||
27 | static u8 *ctrblk; | 27 | static u8 *ctrblk; |
28 | static DEFINE_SPINLOCK(ctrblk_lock); | ||
28 | 29 | ||
29 | struct s390_des_ctx { | 30 | struct s390_des_ctx { |
30 | u8 iv[DES_BLOCK_SIZE]; | 31 | u8 iv[DES_BLOCK_SIZE]; |
@@ -105,29 +106,35 @@ static int ecb_desall_crypt(struct blkcipher_desc *desc, long func, | |||
105 | } | 106 | } |
106 | 107 | ||
107 | static int cbc_desall_crypt(struct blkcipher_desc *desc, long func, | 108 | static int cbc_desall_crypt(struct blkcipher_desc *desc, long func, |
108 | u8 *iv, struct blkcipher_walk *walk) | 109 | struct blkcipher_walk *walk) |
109 | { | 110 | { |
111 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
110 | int ret = blkcipher_walk_virt(desc, walk); | 112 | int ret = blkcipher_walk_virt(desc, walk); |
111 | unsigned int nbytes = walk->nbytes; | 113 | unsigned int nbytes = walk->nbytes; |
114 | struct { | ||
115 | u8 iv[DES_BLOCK_SIZE]; | ||
116 | u8 key[DES3_KEY_SIZE]; | ||
117 | } param; | ||
112 | 118 | ||
113 | if (!nbytes) | 119 | if (!nbytes) |
114 | goto out; | 120 | goto out; |
115 | 121 | ||
116 | memcpy(iv, walk->iv, DES_BLOCK_SIZE); | 122 | memcpy(param.iv, walk->iv, DES_BLOCK_SIZE); |
123 | memcpy(param.key, ctx->key, DES3_KEY_SIZE); | ||
117 | do { | 124 | do { |
118 | /* only use complete blocks */ | 125 | /* only use complete blocks */ |
119 | unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1); | 126 | unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1); |
120 | u8 *out = walk->dst.virt.addr; | 127 | u8 *out = walk->dst.virt.addr; |
121 | u8 *in = walk->src.virt.addr; | 128 | u8 *in = walk->src.virt.addr; |
122 | 129 | ||
123 | ret = crypt_s390_kmc(func, iv, out, in, n); | 130 | ret = crypt_s390_kmc(func, ¶m, out, in, n); |
124 | if (ret < 0 || ret != n) | 131 | if (ret < 0 || ret != n) |
125 | return -EIO; | 132 | return -EIO; |
126 | 133 | ||
127 | nbytes &= DES_BLOCK_SIZE - 1; | 134 | nbytes &= DES_BLOCK_SIZE - 1; |
128 | ret = blkcipher_walk_done(desc, walk, nbytes); | 135 | ret = blkcipher_walk_done(desc, walk, nbytes); |
129 | } while ((nbytes = walk->nbytes)); | 136 | } while ((nbytes = walk->nbytes)); |
130 | memcpy(walk->iv, iv, DES_BLOCK_SIZE); | 137 | memcpy(walk->iv, param.iv, DES_BLOCK_SIZE); |
131 | 138 | ||
132 | out: | 139 | out: |
133 | return ret; | 140 | return ret; |
@@ -179,22 +186,20 @@ static int cbc_des_encrypt(struct blkcipher_desc *desc, | |||
179 | struct scatterlist *dst, struct scatterlist *src, | 186 | struct scatterlist *dst, struct scatterlist *src, |
180 | unsigned int nbytes) | 187 | unsigned int nbytes) |
181 | { | 188 | { |
182 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
183 | struct blkcipher_walk walk; | 189 | struct blkcipher_walk walk; |
184 | 190 | ||
185 | blkcipher_walk_init(&walk, dst, src, nbytes); | 191 | blkcipher_walk_init(&walk, dst, src, nbytes); |
186 | return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, ctx->iv, &walk); | 192 | return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, &walk); |
187 | } | 193 | } |
188 | 194 | ||
189 | static int cbc_des_decrypt(struct blkcipher_desc *desc, | 195 | static int cbc_des_decrypt(struct blkcipher_desc *desc, |
190 | struct scatterlist *dst, struct scatterlist *src, | 196 | struct scatterlist *dst, struct scatterlist *src, |
191 | unsigned int nbytes) | 197 | unsigned int nbytes) |
192 | { | 198 | { |
193 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
194 | struct blkcipher_walk walk; | 199 | struct blkcipher_walk walk; |
195 | 200 | ||
196 | blkcipher_walk_init(&walk, dst, src, nbytes); | 201 | blkcipher_walk_init(&walk, dst, src, nbytes); |
197 | return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, ctx->iv, &walk); | 202 | return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, &walk); |
198 | } | 203 | } |
199 | 204 | ||
200 | static struct crypto_alg cbc_des_alg = { | 205 | static struct crypto_alg cbc_des_alg = { |
@@ -237,9 +242,9 @@ static int des3_setkey(struct crypto_tfm *tfm, const u8 *key, | |||
237 | struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); | 242 | struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm); |
238 | u32 *flags = &tfm->crt_flags; | 243 | u32 *flags = &tfm->crt_flags; |
239 | 244 | ||
240 | if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && | 245 | if (!(crypto_memneq(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && |
241 | memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], | 246 | crypto_memneq(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], |
242 | DES_KEY_SIZE)) && | 247 | DES_KEY_SIZE)) && |
243 | (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) { | 248 | (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) { |
244 | *flags |= CRYPTO_TFM_RES_WEAK_KEY; | 249 | *flags |= CRYPTO_TFM_RES_WEAK_KEY; |
245 | return -EINVAL; | 250 | return -EINVAL; |
@@ -327,22 +332,20 @@ static int cbc_des3_encrypt(struct blkcipher_desc *desc, | |||
327 | struct scatterlist *dst, struct scatterlist *src, | 332 | struct scatterlist *dst, struct scatterlist *src, |
328 | unsigned int nbytes) | 333 | unsigned int nbytes) |
329 | { | 334 | { |
330 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
331 | struct blkcipher_walk walk; | 335 | struct blkcipher_walk walk; |
332 | 336 | ||
333 | blkcipher_walk_init(&walk, dst, src, nbytes); | 337 | blkcipher_walk_init(&walk, dst, src, nbytes); |
334 | return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, ctx->iv, &walk); | 338 | return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, &walk); |
335 | } | 339 | } |
336 | 340 | ||
337 | static int cbc_des3_decrypt(struct blkcipher_desc *desc, | 341 | static int cbc_des3_decrypt(struct blkcipher_desc *desc, |
338 | struct scatterlist *dst, struct scatterlist *src, | 342 | struct scatterlist *dst, struct scatterlist *src, |
339 | unsigned int nbytes) | 343 | unsigned int nbytes) |
340 | { | 344 | { |
341 | struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
342 | struct blkcipher_walk walk; | 345 | struct blkcipher_walk walk; |
343 | 346 | ||
344 | blkcipher_walk_init(&walk, dst, src, nbytes); | 347 | blkcipher_walk_init(&walk, dst, src, nbytes); |
345 | return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, ctx->iv, &walk); | 348 | return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, &walk); |
346 | } | 349 | } |
347 | 350 | ||
348 | static struct crypto_alg cbc_des3_alg = { | 351 | static struct crypto_alg cbc_des3_alg = { |
@@ -366,54 +369,80 @@ static struct crypto_alg cbc_des3_alg = { | |||
366 | } | 369 | } |
367 | }; | 370 | }; |
368 | 371 | ||
372 | static unsigned int __ctrblk_init(u8 *ctrptr, unsigned int nbytes) | ||
373 | { | ||
374 | unsigned int i, n; | ||
375 | |||
376 | /* align to block size, max. PAGE_SIZE */ | ||
377 | n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : nbytes & ~(DES_BLOCK_SIZE - 1); | ||
378 | for (i = DES_BLOCK_SIZE; i < n; i += DES_BLOCK_SIZE) { | ||
379 | memcpy(ctrptr + i, ctrptr + i - DES_BLOCK_SIZE, DES_BLOCK_SIZE); | ||
380 | crypto_inc(ctrptr + i, DES_BLOCK_SIZE); | ||
381 | } | ||
382 | return n; | ||
383 | } | ||
384 | |||
369 | static int ctr_desall_crypt(struct blkcipher_desc *desc, long func, | 385 | static int ctr_desall_crypt(struct blkcipher_desc *desc, long func, |
370 | struct s390_des_ctx *ctx, struct blkcipher_walk *walk) | 386 | struct s390_des_ctx *ctx, |
387 | struct blkcipher_walk *walk) | ||
371 | { | 388 | { |
372 | int ret = blkcipher_walk_virt_block(desc, walk, DES_BLOCK_SIZE); | 389 | int ret = blkcipher_walk_virt_block(desc, walk, DES_BLOCK_SIZE); |
373 | unsigned int i, n, nbytes; | 390 | unsigned int n, nbytes; |
374 | u8 buf[DES_BLOCK_SIZE]; | 391 | u8 buf[DES_BLOCK_SIZE], ctrbuf[DES_BLOCK_SIZE]; |
375 | u8 *out, *in; | 392 | u8 *out, *in, *ctrptr = ctrbuf; |
393 | |||
394 | if (!walk->nbytes) | ||
395 | return ret; | ||
376 | 396 | ||
377 | memcpy(ctrblk, walk->iv, DES_BLOCK_SIZE); | 397 | if (spin_trylock(&ctrblk_lock)) |
398 | ctrptr = ctrblk; | ||
399 | |||
400 | memcpy(ctrptr, walk->iv, DES_BLOCK_SIZE); | ||
378 | while ((nbytes = walk->nbytes) >= DES_BLOCK_SIZE) { | 401 | while ((nbytes = walk->nbytes) >= DES_BLOCK_SIZE) { |
379 | out = walk->dst.virt.addr; | 402 | out = walk->dst.virt.addr; |
380 | in = walk->src.virt.addr; | 403 | in = walk->src.virt.addr; |
381 | while (nbytes >= DES_BLOCK_SIZE) { | 404 | while (nbytes >= DES_BLOCK_SIZE) { |
382 | /* align to block size, max. PAGE_SIZE */ | 405 | if (ctrptr == ctrblk) |
383 | n = (nbytes > PAGE_SIZE) ? PAGE_SIZE : | 406 | n = __ctrblk_init(ctrptr, nbytes); |
384 | nbytes & ~(DES_BLOCK_SIZE - 1); | 407 | else |
385 | for (i = DES_BLOCK_SIZE; i < n; i += DES_BLOCK_SIZE) { | 408 | n = DES_BLOCK_SIZE; |
386 | memcpy(ctrblk + i, ctrblk + i - DES_BLOCK_SIZE, | 409 | ret = crypt_s390_kmctr(func, ctx->key, out, in, |
387 | DES_BLOCK_SIZE); | 410 | n, ctrptr); |
388 | crypto_inc(ctrblk + i, DES_BLOCK_SIZE); | 411 | if (ret < 0 || ret != n) { |
389 | } | 412 | if (ctrptr == ctrblk) |
390 | ret = crypt_s390_kmctr(func, ctx->key, out, in, n, ctrblk); | 413 | spin_unlock(&ctrblk_lock); |
391 | if (ret < 0 || ret != n) | ||
392 | return -EIO; | 414 | return -EIO; |
415 | } | ||
393 | if (n > DES_BLOCK_SIZE) | 416 | if (n > DES_BLOCK_SIZE) |
394 | memcpy(ctrblk, ctrblk + n - DES_BLOCK_SIZE, | 417 | memcpy(ctrptr, ctrptr + n - DES_BLOCK_SIZE, |
395 | DES_BLOCK_SIZE); | 418 | DES_BLOCK_SIZE); |
396 | crypto_inc(ctrblk, DES_BLOCK_SIZE); | 419 | crypto_inc(ctrptr, DES_BLOCK_SIZE); |
397 | out += n; | 420 | out += n; |
398 | in += n; | 421 | in += n; |
399 | nbytes -= n; | 422 | nbytes -= n; |
400 | } | 423 | } |
401 | ret = blkcipher_walk_done(desc, walk, nbytes); | 424 | ret = blkcipher_walk_done(desc, walk, nbytes); |
402 | } | 425 | } |
403 | 426 | if (ctrptr == ctrblk) { | |
427 | if (nbytes) | ||
428 | memcpy(ctrbuf, ctrptr, DES_BLOCK_SIZE); | ||
429 | else | ||
430 | memcpy(walk->iv, ctrptr, DES_BLOCK_SIZE); | ||
431 | spin_unlock(&ctrblk_lock); | ||
432 | } | ||
404 | /* final block may be < DES_BLOCK_SIZE, copy only nbytes */ | 433 | /* final block may be < DES_BLOCK_SIZE, copy only nbytes */ |
405 | if (nbytes) { | 434 | if (nbytes) { |
406 | out = walk->dst.virt.addr; | 435 | out = walk->dst.virt.addr; |
407 | in = walk->src.virt.addr; | 436 | in = walk->src.virt.addr; |
408 | ret = crypt_s390_kmctr(func, ctx->key, buf, in, | 437 | ret = crypt_s390_kmctr(func, ctx->key, buf, in, |
409 | DES_BLOCK_SIZE, ctrblk); | 438 | DES_BLOCK_SIZE, ctrbuf); |
410 | if (ret < 0 || ret != DES_BLOCK_SIZE) | 439 | if (ret < 0 || ret != DES_BLOCK_SIZE) |
411 | return -EIO; | 440 | return -EIO; |
412 | memcpy(out, buf, nbytes); | 441 | memcpy(out, buf, nbytes); |
413 | crypto_inc(ctrblk, DES_BLOCK_SIZE); | 442 | crypto_inc(ctrbuf, DES_BLOCK_SIZE); |
414 | ret = blkcipher_walk_done(desc, walk, 0); | 443 | ret = blkcipher_walk_done(desc, walk, 0); |
444 | memcpy(walk->iv, ctrbuf, DES_BLOCK_SIZE); | ||
415 | } | 445 | } |
416 | memcpy(walk->iv, ctrblk, DES_BLOCK_SIZE); | ||
417 | return ret; | 446 | return ret; |
418 | } | 447 | } |
419 | 448 | ||
diff --git a/arch/s390/hypfs/Makefile b/arch/s390/hypfs/Makefile index 2e671d5004ca..06f8d95a16cd 100644 --- a/arch/s390/hypfs/Makefile +++ b/arch/s390/hypfs/Makefile | |||
@@ -4,4 +4,4 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_S390_HYPFS_FS) += s390_hypfs.o | 5 | obj-$(CONFIG_S390_HYPFS_FS) += s390_hypfs.o |
6 | 6 | ||
7 | s390_hypfs-objs := inode.o hypfs_diag.o hypfs_vm.o hypfs_dbfs.o | 7 | s390_hypfs-objs := inode.o hypfs_diag.o hypfs_vm.o hypfs_dbfs.o hypfs_sprp.o |
diff --git a/arch/s390/hypfs/hypfs.h b/arch/s390/hypfs/hypfs.h index 79f2ac55253f..b34b5ab90a31 100644 --- a/arch/s390/hypfs/hypfs.h +++ b/arch/s390/hypfs/hypfs.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/debugfs.h> | 13 | #include <linux/debugfs.h> |
14 | #include <linux/workqueue.h> | 14 | #include <linux/workqueue.h> |
15 | #include <linux/kref.h> | 15 | #include <linux/kref.h> |
16 | #include <asm/hypfs.h> | ||
16 | 17 | ||
17 | #define REG_FILE_MODE 0440 | 18 | #define REG_FILE_MODE 0440 |
18 | #define UPDATE_FILE_MODE 0220 | 19 | #define UPDATE_FILE_MODE 0220 |
@@ -36,6 +37,10 @@ extern int hypfs_vm_init(void); | |||
36 | extern void hypfs_vm_exit(void); | 37 | extern void hypfs_vm_exit(void); |
37 | extern int hypfs_vm_create_files(struct dentry *root); | 38 | extern int hypfs_vm_create_files(struct dentry *root); |
38 | 39 | ||
40 | /* Set Partition-Resource Parameter */ | ||
41 | int hypfs_sprp_init(void); | ||
42 | void hypfs_sprp_exit(void); | ||
43 | |||
39 | /* debugfs interface */ | 44 | /* debugfs interface */ |
40 | struct hypfs_dbfs_file; | 45 | struct hypfs_dbfs_file; |
41 | 46 | ||
@@ -52,6 +57,8 @@ struct hypfs_dbfs_file { | |||
52 | int (*data_create)(void **data, void **data_free_ptr, | 57 | int (*data_create)(void **data, void **data_free_ptr, |
53 | size_t *size); | 58 | size_t *size); |
54 | void (*data_free)(const void *buf_free_ptr); | 59 | void (*data_free)(const void *buf_free_ptr); |
60 | long (*unlocked_ioctl) (struct file *, unsigned int, | ||
61 | unsigned long); | ||
55 | 62 | ||
56 | /* Private data for hypfs_dbfs.c */ | 63 | /* Private data for hypfs_dbfs.c */ |
57 | struct hypfs_dbfs_data *data; | 64 | struct hypfs_dbfs_data *data; |
diff --git a/arch/s390/hypfs/hypfs_dbfs.c b/arch/s390/hypfs/hypfs_dbfs.c index 17ab8b7b53cc..2badf2bf9cd7 100644 --- a/arch/s390/hypfs/hypfs_dbfs.c +++ b/arch/s390/hypfs/hypfs_dbfs.c | |||
@@ -81,9 +81,25 @@ static ssize_t dbfs_read(struct file *file, char __user *buf, | |||
81 | return rc; | 81 | return rc; |
82 | } | 82 | } |
83 | 83 | ||
84 | static long dbfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
85 | { | ||
86 | struct hypfs_dbfs_file *df; | ||
87 | long rc; | ||
88 | |||
89 | df = file->f_path.dentry->d_inode->i_private; | ||
90 | mutex_lock(&df->lock); | ||
91 | if (df->unlocked_ioctl) | ||
92 | rc = df->unlocked_ioctl(file, cmd, arg); | ||
93 | else | ||
94 | rc = -ENOTTY; | ||
95 | mutex_unlock(&df->lock); | ||
96 | return rc; | ||
97 | } | ||
98 | |||
84 | static const struct file_operations dbfs_ops = { | 99 | static const struct file_operations dbfs_ops = { |
85 | .read = dbfs_read, | 100 | .read = dbfs_read, |
86 | .llseek = no_llseek, | 101 | .llseek = no_llseek, |
102 | .unlocked_ioctl = dbfs_ioctl, | ||
87 | }; | 103 | }; |
88 | 104 | ||
89 | int hypfs_dbfs_create_file(struct hypfs_dbfs_file *df) | 105 | int hypfs_dbfs_create_file(struct hypfs_dbfs_file *df) |
diff --git a/arch/s390/hypfs/hypfs_sprp.c b/arch/s390/hypfs/hypfs_sprp.c new file mode 100644 index 000000000000..f043c3c7e73c --- /dev/null +++ b/arch/s390/hypfs/hypfs_sprp.c | |||
@@ -0,0 +1,141 @@ | |||
1 | /* | ||
2 | * Hypervisor filesystem for Linux on s390. | ||
3 | * Set Partition-Resource Parameter interface. | ||
4 | * | ||
5 | * Copyright IBM Corp. 2013 | ||
6 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> | ||
7 | */ | ||
8 | |||
9 | #include <linux/compat.h> | ||
10 | #include <linux/errno.h> | ||
11 | #include <linux/gfp.h> | ||
12 | #include <linux/string.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/uaccess.h> | ||
15 | #include <asm/compat.h> | ||
16 | #include <asm/sclp.h> | ||
17 | #include "hypfs.h" | ||
18 | |||
19 | #define DIAG304_SET_WEIGHTS 0 | ||
20 | #define DIAG304_QUERY_PRP 1 | ||
21 | #define DIAG304_SET_CAPPING 2 | ||
22 | |||
23 | #define DIAG304_CMD_MAX 2 | ||
24 | |||
25 | static unsigned long hypfs_sprp_diag304(void *data, unsigned long cmd) | ||
26 | { | ||
27 | register unsigned long _data asm("2") = (unsigned long) data; | ||
28 | register unsigned long _rc asm("3"); | ||
29 | register unsigned long _cmd asm("4") = cmd; | ||
30 | |||
31 | asm volatile("diag %1,%2,0x304\n" | ||
32 | : "=d" (_rc) : "d" (_data), "d" (_cmd) : "memory"); | ||
33 | |||
34 | return _rc; | ||
35 | } | ||
36 | |||
37 | static void hypfs_sprp_free(const void *data) | ||
38 | { | ||
39 | free_page((unsigned long) data); | ||
40 | } | ||
41 | |||
42 | static int hypfs_sprp_create(void **data_ptr, void **free_ptr, size_t *size) | ||
43 | { | ||
44 | unsigned long rc; | ||
45 | void *data; | ||
46 | |||
47 | data = (void *) get_zeroed_page(GFP_KERNEL); | ||
48 | if (!data) | ||
49 | return -ENOMEM; | ||
50 | rc = hypfs_sprp_diag304(data, DIAG304_QUERY_PRP); | ||
51 | if (rc != 1) { | ||
52 | *data_ptr = *free_ptr = NULL; | ||
53 | *size = 0; | ||
54 | free_page((unsigned long) data); | ||
55 | return -EIO; | ||
56 | } | ||
57 | *data_ptr = *free_ptr = data; | ||
58 | *size = PAGE_SIZE; | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | static int __hypfs_sprp_ioctl(void __user *user_area) | ||
63 | { | ||
64 | struct hypfs_diag304 diag304; | ||
65 | unsigned long cmd; | ||
66 | void __user *udata; | ||
67 | void *data; | ||
68 | int rc; | ||
69 | |||
70 | if (copy_from_user(&diag304, user_area, sizeof(diag304))) | ||
71 | return -EFAULT; | ||
72 | if ((diag304.args[0] >> 8) != 0 || diag304.args[1] > DIAG304_CMD_MAX) | ||
73 | return -EINVAL; | ||
74 | |||
75 | data = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | ||
76 | if (!data) | ||
77 | return -ENOMEM; | ||
78 | |||
79 | udata = (void __user *)(unsigned long) diag304.data; | ||
80 | if (diag304.args[1] == DIAG304_SET_WEIGHTS || | ||
81 | diag304.args[1] == DIAG304_SET_CAPPING) | ||
82 | if (copy_from_user(data, udata, PAGE_SIZE)) { | ||
83 | rc = -EFAULT; | ||
84 | goto out; | ||
85 | } | ||
86 | |||
87 | cmd = *(unsigned long *) &diag304.args[0]; | ||
88 | diag304.rc = hypfs_sprp_diag304(data, cmd); | ||
89 | |||
90 | if (diag304.args[1] == DIAG304_QUERY_PRP) | ||
91 | if (copy_to_user(udata, data, PAGE_SIZE)) { | ||
92 | rc = -EFAULT; | ||
93 | goto out; | ||
94 | } | ||
95 | |||
96 | rc = copy_to_user(user_area, &diag304, sizeof(diag304)) ? -EFAULT : 0; | ||
97 | out: | ||
98 | free_page((unsigned long) data); | ||
99 | return rc; | ||
100 | } | ||
101 | |||
102 | static long hypfs_sprp_ioctl(struct file *file, unsigned int cmd, | ||
103 | unsigned long arg) | ||
104 | { | ||
105 | void __user *argp; | ||
106 | |||
107 | if (!capable(CAP_SYS_ADMIN)) | ||
108 | return -EACCES; | ||
109 | if (is_compat_task()) | ||
110 | argp = compat_ptr(arg); | ||
111 | else | ||
112 | argp = (void __user *) arg; | ||
113 | switch (cmd) { | ||
114 | case HYPFS_DIAG304: | ||
115 | return __hypfs_sprp_ioctl(argp); | ||
116 | default: /* unknown ioctl number */ | ||
117 | return -ENOTTY; | ||
118 | } | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | static struct hypfs_dbfs_file hypfs_sprp_file = { | ||
123 | .name = "diag_304", | ||
124 | .data_create = hypfs_sprp_create, | ||
125 | .data_free = hypfs_sprp_free, | ||
126 | .unlocked_ioctl = hypfs_sprp_ioctl, | ||
127 | }; | ||
128 | |||
129 | int hypfs_sprp_init(void) | ||
130 | { | ||
131 | if (!sclp_has_sprp()) | ||
132 | return 0; | ||
133 | return hypfs_dbfs_create_file(&hypfs_sprp_file); | ||
134 | } | ||
135 | |||
136 | void hypfs_sprp_exit(void) | ||
137 | { | ||
138 | if (!sclp_has_sprp()) | ||
139 | return; | ||
140 | hypfs_dbfs_remove_file(&hypfs_sprp_file); | ||
141 | } | ||
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index ddfe09b45134..c952b981e4f2 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c | |||
@@ -478,10 +478,14 @@ static int __init hypfs_init(void) | |||
478 | rc = -ENODATA; | 478 | rc = -ENODATA; |
479 | goto fail_hypfs_diag_exit; | 479 | goto fail_hypfs_diag_exit; |
480 | } | 480 | } |
481 | if (hypfs_sprp_init()) { | ||
482 | rc = -ENODATA; | ||
483 | goto fail_hypfs_vm_exit; | ||
484 | } | ||
481 | s390_kobj = kobject_create_and_add("s390", hypervisor_kobj); | 485 | s390_kobj = kobject_create_and_add("s390", hypervisor_kobj); |
482 | if (!s390_kobj) { | 486 | if (!s390_kobj) { |
483 | rc = -ENOMEM; | 487 | rc = -ENOMEM; |
484 | goto fail_hypfs_vm_exit; | 488 | goto fail_hypfs_sprp_exit; |
485 | } | 489 | } |
486 | rc = register_filesystem(&hypfs_type); | 490 | rc = register_filesystem(&hypfs_type); |
487 | if (rc) | 491 | if (rc) |
@@ -490,6 +494,8 @@ static int __init hypfs_init(void) | |||
490 | 494 | ||
491 | fail_filesystem: | 495 | fail_filesystem: |
492 | kobject_put(s390_kobj); | 496 | kobject_put(s390_kobj); |
497 | fail_hypfs_sprp_exit: | ||
498 | hypfs_sprp_exit(); | ||
493 | fail_hypfs_vm_exit: | 499 | fail_hypfs_vm_exit: |
494 | hypfs_vm_exit(); | 500 | hypfs_vm_exit(); |
495 | fail_hypfs_diag_exit: | 501 | fail_hypfs_diag_exit: |
@@ -502,11 +508,12 @@ fail_dbfs_exit: | |||
502 | 508 | ||
503 | static void __exit hypfs_exit(void) | 509 | static void __exit hypfs_exit(void) |
504 | { | 510 | { |
505 | hypfs_diag_exit(); | ||
506 | hypfs_vm_exit(); | ||
507 | hypfs_dbfs_exit(); | ||
508 | unregister_filesystem(&hypfs_type); | 511 | unregister_filesystem(&hypfs_type); |
509 | kobject_put(s390_kobj); | 512 | kobject_put(s390_kobj); |
513 | hypfs_sprp_exit(); | ||
514 | hypfs_vm_exit(); | ||
515 | hypfs_diag_exit(); | ||
516 | hypfs_dbfs_exit(); | ||
510 | } | 517 | } |
511 | 518 | ||
512 | module_init(hypfs_init) | 519 | module_init(hypfs_init) |
diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild index 7a5288f3479a..8386a4a1f19a 100644 --- a/arch/s390/include/asm/Kbuild +++ b/arch/s390/include/asm/Kbuild | |||
@@ -3,3 +3,4 @@ | |||
3 | generic-y += clkdev.h | 3 | generic-y += clkdev.h |
4 | generic-y += trace_clock.h | 4 | generic-y += trace_clock.h |
5 | generic-y += preempt.h | 5 | generic-y += preempt.h |
6 | generic-y += hash.h | ||
diff --git a/arch/s390/include/asm/barrier.h b/arch/s390/include/asm/barrier.h index 16760eeb79b0..578680f6207a 100644 --- a/arch/s390/include/asm/barrier.h +++ b/arch/s390/include/asm/barrier.h | |||
@@ -32,4 +32,19 @@ | |||
32 | 32 | ||
33 | #define set_mb(var, value) do { var = value; mb(); } while (0) | 33 | #define set_mb(var, value) do { var = value; mb(); } while (0) |
34 | 34 | ||
35 | #define smp_store_release(p, v) \ | ||
36 | do { \ | ||
37 | compiletime_assert_atomic_type(*p); \ | ||
38 | barrier(); \ | ||
39 | ACCESS_ONCE(*p) = (v); \ | ||
40 | } while (0) | ||
41 | |||
42 | #define smp_load_acquire(p) \ | ||
43 | ({ \ | ||
44 | typeof(*p) ___p1 = ACCESS_ONCE(*p); \ | ||
45 | compiletime_assert_atomic_type(*p); \ | ||
46 | barrier(); \ | ||
47 | ___p1; \ | ||
48 | }) | ||
49 | |||
35 | #endif /* __ASM_BARRIER_H */ | 50 | #endif /* __ASM_BARRIER_H */ |
diff --git a/arch/s390/include/asm/cmpxchg.h b/arch/s390/include/asm/cmpxchg.h index 0f636cbdf342..4236408070e5 100644 --- a/arch/s390/include/asm/cmpxchg.h +++ b/arch/s390/include/asm/cmpxchg.h | |||
@@ -185,11 +185,12 @@ static inline unsigned long long __cmpxchg64(void *ptr, | |||
185 | { | 185 | { |
186 | register_pair rp_old = {.pair = old}; | 186 | register_pair rp_old = {.pair = old}; |
187 | register_pair rp_new = {.pair = new}; | 187 | register_pair rp_new = {.pair = new}; |
188 | unsigned long long *ullptr = ptr; | ||
188 | 189 | ||
189 | asm volatile( | 190 | asm volatile( |
190 | " cds %0,%2,%1" | 191 | " cds %0,%2,%1" |
191 | : "+&d" (rp_old), "=Q" (ptr) | 192 | : "+d" (rp_old), "+Q" (*ullptr) |
192 | : "d" (rp_new), "Q" (ptr) | 193 | : "d" (rp_new) |
193 | : "memory", "cc"); | 194 | : "memory", "cc"); |
194 | return rp_old.pair; | 195 | return rp_old.pair; |
195 | } | 196 | } |
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index 4bf9da03591e..5d7e8cf83bd6 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h | |||
@@ -38,7 +38,8 @@ | |||
38 | 38 | ||
39 | #define PSW32_USER_BITS (PSW32_MASK_DAT | PSW32_MASK_IO | PSW32_MASK_EXT | \ | 39 | #define PSW32_USER_BITS (PSW32_MASK_DAT | PSW32_MASK_IO | PSW32_MASK_EXT | \ |
40 | PSW32_DEFAULT_KEY | PSW32_MASK_BASE | \ | 40 | PSW32_DEFAULT_KEY | PSW32_MASK_BASE | \ |
41 | PSW32_MASK_MCHECK | PSW32_MASK_PSTATE | PSW32_ASC_HOME) | 41 | PSW32_MASK_MCHECK | PSW32_MASK_PSTATE | \ |
42 | PSW32_ASC_PRIMARY) | ||
42 | 43 | ||
43 | #define COMPAT_USER_HZ 100 | 44 | #define COMPAT_USER_HZ 100 |
44 | #define COMPAT_UTS_MACHINE "s390\0\0\0\0" | 45 | #define COMPAT_UTS_MACHINE "s390\0\0\0\0" |
diff --git a/arch/s390/include/asm/cpu_mf.h b/arch/s390/include/asm/cpu_mf.h index c879fad404c8..cb700d54bd83 100644 --- a/arch/s390/include/asm/cpu_mf.h +++ b/arch/s390/include/asm/cpu_mf.h | |||
@@ -56,6 +56,96 @@ struct cpumf_ctr_info { | |||
56 | u32 reserved2[12]; | 56 | u32 reserved2[12]; |
57 | } __packed; | 57 | } __packed; |
58 | 58 | ||
59 | /* QUERY SAMPLING INFORMATION block */ | ||
60 | struct hws_qsi_info_block { /* Bit(s) */ | ||
61 | unsigned int b0_13:14; /* 0-13: zeros */ | ||
62 | unsigned int as:1; /* 14: basic-sampling authorization */ | ||
63 | unsigned int ad:1; /* 15: diag-sampling authorization */ | ||
64 | unsigned int b16_21:6; /* 16-21: zeros */ | ||
65 | unsigned int es:1; /* 22: basic-sampling enable control */ | ||
66 | unsigned int ed:1; /* 23: diag-sampling enable control */ | ||
67 | unsigned int b24_29:6; /* 24-29: zeros */ | ||
68 | unsigned int cs:1; /* 30: basic-sampling activation control */ | ||
69 | unsigned int cd:1; /* 31: diag-sampling activation control */ | ||
70 | unsigned int bsdes:16; /* 4-5: size of basic sampling entry */ | ||
71 | unsigned int dsdes:16; /* 6-7: size of diagnostic sampling entry */ | ||
72 | unsigned long min_sampl_rate; /* 8-15: minimum sampling interval */ | ||
73 | unsigned long max_sampl_rate; /* 16-23: maximum sampling interval*/ | ||
74 | unsigned long tear; /* 24-31: TEAR contents */ | ||
75 | unsigned long dear; /* 32-39: DEAR contents */ | ||
76 | unsigned int rsvrd0; /* 40-43: reserved */ | ||
77 | unsigned int cpu_speed; /* 44-47: CPU speed */ | ||
78 | unsigned long long rsvrd1; /* 48-55: reserved */ | ||
79 | unsigned long long rsvrd2; /* 56-63: reserved */ | ||
80 | } __packed; | ||
81 | |||
82 | /* SET SAMPLING CONTROLS request block */ | ||
83 | struct hws_lsctl_request_block { | ||
84 | unsigned int s:1; /* 0: maximum buffer indicator */ | ||
85 | unsigned int h:1; /* 1: part. level reserved for VM use*/ | ||
86 | unsigned long long b2_53:52;/* 2-53: zeros */ | ||
87 | unsigned int es:1; /* 54: basic-sampling enable control */ | ||
88 | unsigned int ed:1; /* 55: diag-sampling enable control */ | ||
89 | unsigned int b56_61:6; /* 56-61: - zeros */ | ||
90 | unsigned int cs:1; /* 62: basic-sampling activation control */ | ||
91 | unsigned int cd:1; /* 63: diag-sampling activation control */ | ||
92 | unsigned long interval; /* 8-15: sampling interval */ | ||
93 | unsigned long tear; /* 16-23: TEAR contents */ | ||
94 | unsigned long dear; /* 24-31: DEAR contents */ | ||
95 | /* 32-63: */ | ||
96 | unsigned long rsvrd1; /* reserved */ | ||
97 | unsigned long rsvrd2; /* reserved */ | ||
98 | unsigned long rsvrd3; /* reserved */ | ||
99 | unsigned long rsvrd4; /* reserved */ | ||
100 | } __packed; | ||
101 | |||
102 | struct hws_basic_entry { | ||
103 | unsigned int def:16; /* 0-15 Data Entry Format */ | ||
104 | unsigned int R:4; /* 16-19 reserved */ | ||
105 | unsigned int U:4; /* 20-23 Number of unique instruct. */ | ||
106 | unsigned int z:2; /* zeros */ | ||
107 | unsigned int T:1; /* 26 PSW DAT mode */ | ||
108 | unsigned int W:1; /* 27 PSW wait state */ | ||
109 | unsigned int P:1; /* 28 PSW Problem state */ | ||
110 | unsigned int AS:2; /* 29-30 PSW address-space control */ | ||
111 | unsigned int I:1; /* 31 entry valid or invalid */ | ||
112 | unsigned int:16; | ||
113 | unsigned int prim_asn:16; /* primary ASN */ | ||
114 | unsigned long long ia; /* Instruction Address */ | ||
115 | unsigned long long gpp; /* Guest Program Parameter */ | ||
116 | unsigned long long hpp; /* Host Program Parameter */ | ||
117 | } __packed; | ||
118 | |||
119 | struct hws_diag_entry { | ||
120 | unsigned int def:16; /* 0-15 Data Entry Format */ | ||
121 | unsigned int R:14; /* 16-19 and 20-30 reserved */ | ||
122 | unsigned int I:1; /* 31 entry valid or invalid */ | ||
123 | u8 data[]; /* Machine-dependent sample data */ | ||
124 | } __packed; | ||
125 | |||
126 | struct hws_combined_entry { | ||
127 | struct hws_basic_entry basic; /* Basic-sampling data entry */ | ||
128 | struct hws_diag_entry diag; /* Diagnostic-sampling data entry */ | ||
129 | } __packed; | ||
130 | |||
131 | struct hws_trailer_entry { | ||
132 | union { | ||
133 | struct { | ||
134 | unsigned int f:1; /* 0 - Block Full Indicator */ | ||
135 | unsigned int a:1; /* 1 - Alert request control */ | ||
136 | unsigned int t:1; /* 2 - Timestamp format */ | ||
137 | unsigned long long:61; /* 3 - 63: Reserved */ | ||
138 | }; | ||
139 | unsigned long long flags; /* 0 - 63: All indicators */ | ||
140 | }; | ||
141 | unsigned long long overflow; /* 64 - sample Overflow count */ | ||
142 | unsigned char timestamp[16]; /* 16 - 31 timestamp */ | ||
143 | unsigned long long reserved1; /* 32 -Reserved */ | ||
144 | unsigned long long reserved2; /* */ | ||
145 | unsigned long long progusage1; /* 48 - reserved for programming use */ | ||
146 | unsigned long long progusage2; /* */ | ||
147 | } __packed; | ||
148 | |||
59 | /* Query counter information */ | 149 | /* Query counter information */ |
60 | static inline int qctri(struct cpumf_ctr_info *info) | 150 | static inline int qctri(struct cpumf_ctr_info *info) |
61 | { | 151 | { |
@@ -99,4 +189,95 @@ static inline int ecctr(u64 ctr, u64 *val) | |||
99 | return cc; | 189 | return cc; |
100 | } | 190 | } |
101 | 191 | ||
192 | /* Query sampling information */ | ||
193 | static inline int qsi(struct hws_qsi_info_block *info) | ||
194 | { | ||
195 | int cc; | ||
196 | cc = 1; | ||
197 | |||
198 | asm volatile( | ||
199 | "0: .insn s,0xb2860000,0(%1)\n" | ||
200 | "1: lhi %0,0\n" | ||
201 | "2:\n" | ||
202 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) | ||
203 | : "=d" (cc), "+a" (info) | ||
204 | : "m" (*info) | ||
205 | : "cc", "memory"); | ||
206 | |||
207 | return cc ? -EINVAL : 0; | ||
208 | } | ||
209 | |||
210 | /* Load sampling controls */ | ||
211 | static inline int lsctl(struct hws_lsctl_request_block *req) | ||
212 | { | ||
213 | int cc; | ||
214 | |||
215 | cc = 1; | ||
216 | asm volatile( | ||
217 | "0: .insn s,0xb2870000,0(%1)\n" | ||
218 | "1: ipm %0\n" | ||
219 | " srl %0,28\n" | ||
220 | "2:\n" | ||
221 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) | ||
222 | : "+d" (cc), "+a" (req) | ||
223 | : "m" (*req) | ||
224 | : "cc", "memory"); | ||
225 | |||
226 | return cc ? -EINVAL : 0; | ||
227 | } | ||
228 | |||
229 | /* Sampling control helper functions */ | ||
230 | |||
231 | #include <linux/time.h> | ||
232 | |||
233 | static inline unsigned long freq_to_sample_rate(struct hws_qsi_info_block *qsi, | ||
234 | unsigned long freq) | ||
235 | { | ||
236 | return (USEC_PER_SEC / freq) * qsi->cpu_speed; | ||
237 | } | ||
238 | |||
239 | static inline unsigned long sample_rate_to_freq(struct hws_qsi_info_block *qsi, | ||
240 | unsigned long rate) | ||
241 | { | ||
242 | return USEC_PER_SEC * qsi->cpu_speed / rate; | ||
243 | } | ||
244 | |||
245 | #define SDB_TE_ALERT_REQ_MASK 0x4000000000000000UL | ||
246 | #define SDB_TE_BUFFER_FULL_MASK 0x8000000000000000UL | ||
247 | |||
248 | /* Return TOD timestamp contained in an trailer entry */ | ||
249 | static inline unsigned long long trailer_timestamp(struct hws_trailer_entry *te) | ||
250 | { | ||
251 | /* TOD in STCKE format */ | ||
252 | if (te->t) | ||
253 | return *((unsigned long long *) &te->timestamp[1]); | ||
254 | |||
255 | /* TOD in STCK format */ | ||
256 | return *((unsigned long long *) &te->timestamp[0]); | ||
257 | } | ||
258 | |||
259 | /* Return pointer to trailer entry of an sample data block */ | ||
260 | static inline unsigned long *trailer_entry_ptr(unsigned long v) | ||
261 | { | ||
262 | void *ret; | ||
263 | |||
264 | ret = (void *) v; | ||
265 | ret += PAGE_SIZE; | ||
266 | ret -= sizeof(struct hws_trailer_entry); | ||
267 | |||
268 | return (unsigned long *) ret; | ||
269 | } | ||
270 | |||
271 | /* Return if the entry in the sample data block table (sdbt) | ||
272 | * is a link to the next sdbt */ | ||
273 | static inline int is_link_entry(unsigned long *s) | ||
274 | { | ||
275 | return *s & 0x1ul ? 1 : 0; | ||
276 | } | ||
277 | |||
278 | /* Return pointer to the linked sdbt */ | ||
279 | static inline unsigned long *get_next_sdbt(unsigned long *s) | ||
280 | { | ||
281 | return (unsigned long *) (*s & ~0x1ul); | ||
282 | } | ||
102 | #endif /* _ASM_S390_CPU_MF_H */ | 283 | #endif /* _ASM_S390_CPU_MF_H */ |
diff --git a/arch/s390/include/asm/css_chars.h b/arch/s390/include/asm/css_chars.h index 7e1c917bbba2..09d1dd46bd57 100644 --- a/arch/s390/include/asm/css_chars.h +++ b/arch/s390/include/asm/css_chars.h | |||
@@ -29,6 +29,8 @@ struct css_general_char { | |||
29 | u32 fcx : 1; /* bit 88 */ | 29 | u32 fcx : 1; /* bit 88 */ |
30 | u32 : 19; | 30 | u32 : 19; |
31 | u32 alt_ssi : 1; /* bit 108 */ | 31 | u32 alt_ssi : 1; /* bit 108 */ |
32 | u32:1; | ||
33 | u32 narf:1; /* bit 110 */ | ||
32 | } __packed; | 34 | } __packed; |
33 | 35 | ||
34 | extern struct css_general_char css_general_characteristics; | 36 | extern struct css_general_char css_general_characteristics; |
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index d5bc3750616e..eef3dd3fd9a9 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
@@ -106,9 +106,22 @@ struct kvm_s390_sie_block { | |||
106 | __u64 gbea; /* 0x0180 */ | 106 | __u64 gbea; /* 0x0180 */ |
107 | __u8 reserved188[24]; /* 0x0188 */ | 107 | __u8 reserved188[24]; /* 0x0188 */ |
108 | __u32 fac; /* 0x01a0 */ | 108 | __u32 fac; /* 0x01a0 */ |
109 | __u8 reserved1a4[92]; /* 0x01a4 */ | 109 | __u8 reserved1a4[68]; /* 0x01a4 */ |
110 | __u64 itdba; /* 0x01e8 */ | ||
111 | __u8 reserved1f0[16]; /* 0x01f0 */ | ||
110 | } __attribute__((packed)); | 112 | } __attribute__((packed)); |
111 | 113 | ||
114 | struct kvm_s390_itdb { | ||
115 | __u8 data[256]; | ||
116 | } __packed; | ||
117 | |||
118 | struct sie_page { | ||
119 | struct kvm_s390_sie_block sie_block; | ||
120 | __u8 reserved200[1024]; /* 0x0200 */ | ||
121 | struct kvm_s390_itdb itdb; /* 0x0600 */ | ||
122 | __u8 reserved700[2304]; /* 0x0700 */ | ||
123 | } __packed; | ||
124 | |||
112 | struct kvm_vcpu_stat { | 125 | struct kvm_vcpu_stat { |
113 | u32 exit_userspace; | 126 | u32 exit_userspace; |
114 | u32 exit_null; | 127 | u32 exit_null; |
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h index c129ab2ac731..2583466f576b 100644 --- a/arch/s390/include/asm/pci.h +++ b/arch/s390/include/asm/pci.h | |||
@@ -144,6 +144,7 @@ int clp_disable_fh(struct zpci_dev *); | |||
144 | void zpci_event_error(void *); | 144 | void zpci_event_error(void *); |
145 | void zpci_event_availability(void *); | 145 | void zpci_event_availability(void *); |
146 | void zpci_rescan(void); | 146 | void zpci_rescan(void); |
147 | bool zpci_is_enabled(void); | ||
147 | #else /* CONFIG_PCI */ | 148 | #else /* CONFIG_PCI */ |
148 | static inline void zpci_event_error(void *e) {} | 149 | static inline void zpci_event_error(void *e) {} |
149 | static inline void zpci_event_availability(void *e) {} | 150 | static inline void zpci_event_availability(void *e) {} |
diff --git a/arch/s390/include/asm/perf_event.h b/arch/s390/include/asm/perf_event.h index 1141fb3e7b21..159a8ec6da9a 100644 --- a/arch/s390/include/asm/perf_event.h +++ b/arch/s390/include/asm/perf_event.h | |||
@@ -1,21 +1,40 @@ | |||
1 | /* | 1 | /* |
2 | * Performance event support - s390 specific definitions. | 2 | * Performance event support - s390 specific definitions. |
3 | * | 3 | * |
4 | * Copyright IBM Corp. 2009, 2012 | 4 | * Copyright IBM Corp. 2009, 2013 |
5 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> | 5 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> |
6 | * Hendrik Brueckner <brueckner@linux.vnet.ibm.com> | 6 | * Hendrik Brueckner <brueckner@linux.vnet.ibm.com> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <asm/cpu_mf.h> | 9 | #ifndef _ASM_S390_PERF_EVENT_H |
10 | #define _ASM_S390_PERF_EVENT_H | ||
10 | 11 | ||
11 | /* CPU-measurement counter facility */ | 12 | #ifdef CONFIG_64BIT |
12 | #define PERF_CPUM_CF_MAX_CTR 256 | 13 | |
14 | #include <linux/perf_event.h> | ||
15 | #include <linux/device.h> | ||
16 | #include <asm/cpu_mf.h> | ||
13 | 17 | ||
14 | /* Per-CPU flags for PMU states */ | 18 | /* Per-CPU flags for PMU states */ |
15 | #define PMU_F_RESERVED 0x1000 | 19 | #define PMU_F_RESERVED 0x1000 |
16 | #define PMU_F_ENABLED 0x2000 | 20 | #define PMU_F_ENABLED 0x2000 |
21 | #define PMU_F_IN_USE 0x4000 | ||
22 | #define PMU_F_ERR_IBE 0x0100 | ||
23 | #define PMU_F_ERR_LSDA 0x0200 | ||
24 | #define PMU_F_ERR_MASK (PMU_F_ERR_IBE|PMU_F_ERR_LSDA) | ||
25 | |||
26 | /* Perf defintions for PMU event attributes in sysfs */ | ||
27 | extern __init const struct attribute_group **cpumf_cf_event_group(void); | ||
28 | extern ssize_t cpumf_events_sysfs_show(struct device *dev, | ||
29 | struct device_attribute *attr, | ||
30 | char *page); | ||
31 | #define EVENT_VAR(_cat, _name) event_attr_##_cat##_##_name | ||
32 | #define EVENT_PTR(_cat, _name) (&EVENT_VAR(_cat, _name).attr.attr) | ||
33 | |||
34 | #define CPUMF_EVENT_ATTR(cat, name, id) \ | ||
35 | PMU_EVENT_ATTR(name, EVENT_VAR(cat, name), id, cpumf_events_sysfs_show) | ||
36 | #define CPUMF_EVENT_PTR(cat, name) EVENT_PTR(cat, name) | ||
17 | 37 | ||
18 | #ifdef CONFIG_64BIT | ||
19 | 38 | ||
20 | /* Perf callbacks */ | 39 | /* Perf callbacks */ |
21 | struct pt_regs; | 40 | struct pt_regs; |
@@ -23,4 +42,55 @@ extern unsigned long perf_instruction_pointer(struct pt_regs *regs); | |||
23 | extern unsigned long perf_misc_flags(struct pt_regs *regs); | 42 | extern unsigned long perf_misc_flags(struct pt_regs *regs); |
24 | #define perf_misc_flags(regs) perf_misc_flags(regs) | 43 | #define perf_misc_flags(regs) perf_misc_flags(regs) |
25 | 44 | ||
45 | /* Perf pt_regs extension for sample-data-entry indicators */ | ||
46 | struct perf_sf_sde_regs { | ||
47 | unsigned char in_guest:1; /* guest sample */ | ||
48 | unsigned long reserved:63; /* reserved */ | ||
49 | }; | ||
50 | |||
51 | /* Perf PMU definitions for the counter facility */ | ||
52 | #define PERF_CPUM_CF_MAX_CTR 256 | ||
53 | |||
54 | /* Perf PMU definitions for the sampling facility */ | ||
55 | #define PERF_CPUM_SF_MAX_CTR 2 | ||
56 | #define PERF_EVENT_CPUM_SF 0xB0000UL /* Event: Basic-sampling */ | ||
57 | #define PERF_EVENT_CPUM_SF_DIAG 0xBD000UL /* Event: Combined-sampling */ | ||
58 | #define PERF_CPUM_SF_BASIC_MODE 0x0001 /* Basic-sampling flag */ | ||
59 | #define PERF_CPUM_SF_DIAG_MODE 0x0002 /* Diagnostic-sampling flag */ | ||
60 | #define PERF_CPUM_SF_MODE_MASK (PERF_CPUM_SF_BASIC_MODE| \ | ||
61 | PERF_CPUM_SF_DIAG_MODE) | ||
62 | #define PERF_CPUM_SF_FULL_BLOCKS 0x0004 /* Process full SDBs only */ | ||
63 | |||
64 | #define REG_NONE 0 | ||
65 | #define REG_OVERFLOW 1 | ||
66 | #define OVERFLOW_REG(hwc) ((hwc)->extra_reg.config) | ||
67 | #define SFB_ALLOC_REG(hwc) ((hwc)->extra_reg.alloc) | ||
68 | #define RAWSAMPLE_REG(hwc) ((hwc)->config) | ||
69 | #define TEAR_REG(hwc) ((hwc)->last_tag) | ||
70 | #define SAMPL_RATE(hwc) ((hwc)->event_base) | ||
71 | #define SAMPL_FLAGS(hwc) ((hwc)->config_base) | ||
72 | #define SAMPL_DIAG_MODE(hwc) (SAMPL_FLAGS(hwc) & PERF_CPUM_SF_DIAG_MODE) | ||
73 | #define SDB_FULL_BLOCKS(hwc) (SAMPL_FLAGS(hwc) & PERF_CPUM_SF_FULL_BLOCKS) | ||
74 | |||
75 | /* Structure for sampling data entries to be passed as perf raw sample data | ||
76 | * to user space. Note that raw sample data must be aligned and, thus, might | ||
77 | * be padded with zeros. | ||
78 | */ | ||
79 | struct sf_raw_sample { | ||
80 | #define SF_RAW_SAMPLE_BASIC PERF_CPUM_SF_BASIC_MODE | ||
81 | #define SF_RAW_SAMPLE_DIAG PERF_CPUM_SF_DIAG_MODE | ||
82 | u64 format; | ||
83 | u32 size; /* Size of sf_raw_sample */ | ||
84 | u16 bsdes; /* Basic-sampling data entry size */ | ||
85 | u16 dsdes; /* Diagnostic-sampling data entry size */ | ||
86 | struct hws_basic_entry basic; /* Basic-sampling data entry */ | ||
87 | struct hws_diag_entry diag; /* Diagnostic-sampling data entry */ | ||
88 | u8 padding[]; /* Padding to next multiple of 8 */ | ||
89 | } __packed; | ||
90 | |||
91 | /* Perf hardware reserve and release functions */ | ||
92 | int perf_reserve_sampling(void); | ||
93 | void perf_release_sampling(void); | ||
94 | |||
26 | #endif /* CONFIG_64BIT */ | 95 | #endif /* CONFIG_64BIT */ |
96 | #endif /* _ASM_S390_PERF_EVENT_H */ | ||
diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h index 57d0d7e794b1..d786c634e052 100644 --- a/arch/s390/include/asm/qdio.h +++ b/arch/s390/include/asm/qdio.h | |||
@@ -336,7 +336,7 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int, | |||
336 | #define QDIO_FLAG_CLEANUP_USING_HALT 0x02 | 336 | #define QDIO_FLAG_CLEANUP_USING_HALT 0x02 |
337 | 337 | ||
338 | /** | 338 | /** |
339 | * struct qdio_initialize - qdio initalization data | 339 | * struct qdio_initialize - qdio initialization data |
340 | * @cdev: associated ccw device | 340 | * @cdev: associated ccw device |
341 | * @q_format: queue format | 341 | * @q_format: queue format |
342 | * @adapter_name: name for the adapter | 342 | * @adapter_name: name for the adapter |
@@ -378,6 +378,34 @@ struct qdio_initialize { | |||
378 | struct qdio_outbuf_state *output_sbal_state_array; | 378 | struct qdio_outbuf_state *output_sbal_state_array; |
379 | }; | 379 | }; |
380 | 380 | ||
381 | /** | ||
382 | * enum qdio_brinfo_entry_type - type of address entry for qdio_brinfo_desc() | ||
383 | * @l3_ipv6_addr: entry contains IPv6 address | ||
384 | * @l3_ipv4_addr: entry contains IPv4 address | ||
385 | * @l2_addr_lnid: entry contains MAC address and VLAN ID | ||
386 | */ | ||
387 | enum qdio_brinfo_entry_type {l3_ipv6_addr, l3_ipv4_addr, l2_addr_lnid}; | ||
388 | |||
389 | /** | ||
390 | * struct qdio_brinfo_entry_XXX - Address entry for qdio_brinfo_desc() | ||
391 | * @nit: Network interface token | ||
392 | * @addr: Address of one of the three types | ||
393 | * | ||
394 | * The struct is passed to the callback function by qdio_brinfo_desc() | ||
395 | */ | ||
396 | struct qdio_brinfo_entry_l3_ipv6 { | ||
397 | u64 nit; | ||
398 | struct { unsigned char _s6_addr[16]; } addr; | ||
399 | } __packed; | ||
400 | struct qdio_brinfo_entry_l3_ipv4 { | ||
401 | u64 nit; | ||
402 | struct { uint32_t _s_addr; } addr; | ||
403 | } __packed; | ||
404 | struct qdio_brinfo_entry_l2 { | ||
405 | u64 nit; | ||
406 | struct { u8 mac[6]; u16 lnid; } addr_lnid; | ||
407 | } __packed; | ||
408 | |||
381 | #define QDIO_STATE_INACTIVE 0x00000002 /* after qdio_cleanup */ | 409 | #define QDIO_STATE_INACTIVE 0x00000002 /* after qdio_cleanup */ |
382 | #define QDIO_STATE_ESTABLISHED 0x00000004 /* after qdio_establish */ | 410 | #define QDIO_STATE_ESTABLISHED 0x00000004 /* after qdio_establish */ |
383 | #define QDIO_STATE_ACTIVE 0x00000008 /* after qdio_activate */ | 411 | #define QDIO_STATE_ACTIVE 0x00000008 /* after qdio_activate */ |
@@ -399,5 +427,10 @@ extern int qdio_get_next_buffers(struct ccw_device *, int, int *, int *); | |||
399 | extern int qdio_shutdown(struct ccw_device *, int); | 427 | extern int qdio_shutdown(struct ccw_device *, int); |
400 | extern int qdio_free(struct ccw_device *); | 428 | extern int qdio_free(struct ccw_device *); |
401 | extern int qdio_get_ssqd_desc(struct ccw_device *, struct qdio_ssqd_desc *); | 429 | extern int qdio_get_ssqd_desc(struct ccw_device *, struct qdio_ssqd_desc *); |
430 | extern int qdio_pnso_brinfo(struct subchannel_id schid, | ||
431 | int cnc, u16 *response, | ||
432 | void (*cb)(void *priv, enum qdio_brinfo_entry_type type, | ||
433 | void *entry), | ||
434 | void *priv); | ||
402 | 435 | ||
403 | #endif /* __QDIO_H__ */ | 436 | #endif /* __QDIO_H__ */ |
diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index 2f390956c7c1..abaca2275c7a 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h | |||
@@ -52,8 +52,9 @@ int sclp_chp_configure(struct chp_id chpid); | |||
52 | int sclp_chp_deconfigure(struct chp_id chpid); | 52 | int sclp_chp_deconfigure(struct chp_id chpid); |
53 | int sclp_chp_read_info(struct sclp_chp_info *info); | 53 | int sclp_chp_read_info(struct sclp_chp_info *info); |
54 | void sclp_get_ipl_info(struct sclp_ipl_info *info); | 54 | void sclp_get_ipl_info(struct sclp_ipl_info *info); |
55 | bool sclp_has_linemode(void); | 55 | bool __init sclp_has_linemode(void); |
56 | bool sclp_has_vt220(void); | 56 | bool __init sclp_has_vt220(void); |
57 | bool sclp_has_sprp(void); | ||
57 | int sclp_pci_configure(u32 fid); | 58 | int sclp_pci_configure(u32 fid); |
58 | int sclp_pci_deconfigure(u32 fid); | 59 | int sclp_pci_deconfigure(u32 fid); |
59 | int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode); | 60 | int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode); |
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h index 5a87d16d3e7c..d091aa1aaf11 100644 --- a/arch/s390/include/asm/sigp.h +++ b/arch/s390/include/asm/sigp.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #define SIGP_SENSE 1 | 5 | #define SIGP_SENSE 1 |
6 | #define SIGP_EXTERNAL_CALL 2 | 6 | #define SIGP_EXTERNAL_CALL 2 |
7 | #define SIGP_EMERGENCY_SIGNAL 3 | 7 | #define SIGP_EMERGENCY_SIGNAL 3 |
8 | #define SIGP_START 4 | ||
8 | #define SIGP_STOP 5 | 9 | #define SIGP_STOP 5 |
9 | #define SIGP_RESTART 6 | 10 | #define SIGP_RESTART 6 |
10 | #define SIGP_STOP_AND_STORE_STATUS 9 | 11 | #define SIGP_STOP_AND_STORE_STATUS 9 |
@@ -12,6 +13,7 @@ | |||
12 | #define SIGP_SET_PREFIX 13 | 13 | #define SIGP_SET_PREFIX 13 |
13 | #define SIGP_STORE_STATUS_AT_ADDRESS 14 | 14 | #define SIGP_STORE_STATUS_AT_ADDRESS 14 |
14 | #define SIGP_SET_ARCHITECTURE 18 | 15 | #define SIGP_SET_ARCHITECTURE 18 |
16 | #define SIGP_COND_EMERGENCY_SIGNAL 19 | ||
15 | #define SIGP_SENSE_RUNNING 21 | 17 | #define SIGP_SENSE_RUNNING 21 |
16 | 18 | ||
17 | /* SIGP condition codes */ | 19 | /* SIGP condition codes */ |
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index ac9bed8e103f..160779394096 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h | |||
@@ -31,6 +31,7 @@ extern void smp_yield(void); | |||
31 | extern void smp_stop_cpu(void); | 31 | extern void smp_stop_cpu(void); |
32 | extern void smp_cpu_set_polarization(int cpu, int val); | 32 | extern void smp_cpu_set_polarization(int cpu, int val); |
33 | extern int smp_cpu_get_polarization(int cpu); | 33 | extern int smp_cpu_get_polarization(int cpu); |
34 | extern void smp_fill_possible_mask(void); | ||
34 | 35 | ||
35 | #else /* CONFIG_SMP */ | 36 | #else /* CONFIG_SMP */ |
36 | 37 | ||
@@ -50,6 +51,7 @@ static inline int smp_vcpu_scheduled(int cpu) { return 1; } | |||
50 | static inline void smp_yield_cpu(int cpu) { } | 51 | static inline void smp_yield_cpu(int cpu) { } |
51 | static inline void smp_yield(void) { } | 52 | static inline void smp_yield(void) { } |
52 | static inline void smp_stop_cpu(void) { } | 53 | static inline void smp_stop_cpu(void) { } |
54 | static inline void smp_fill_possible_mask(void) { } | ||
53 | 55 | ||
54 | #endif /* CONFIG_SMP */ | 56 | #endif /* CONFIG_SMP */ |
55 | 57 | ||
diff --git a/arch/s390/include/uapi/asm/hypfs.h b/arch/s390/include/uapi/asm/hypfs.h new file mode 100644 index 000000000000..37998b449531 --- /dev/null +++ b/arch/s390/include/uapi/asm/hypfs.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * IOCTL interface for hypfs | ||
3 | * | ||
4 | * Copyright IBM Corp. 2013 | ||
5 | * | ||
6 | * Author: Martin Schwidefsky <schwidefsky@de.ibm.com> | ||
7 | */ | ||
8 | |||
9 | #ifndef _ASM_HYPFS_CTL_H | ||
10 | #define _ASM_HYPFS_CTL_H | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | |||
14 | struct hypfs_diag304 { | ||
15 | __u32 args[2]; | ||
16 | __u64 data; | ||
17 | __u64 rc; | ||
18 | } __attribute__((packed)); | ||
19 | |||
20 | #define HYPFS_IOCTL_MAGIC 0x10 | ||
21 | |||
22 | #define HYPFS_DIAG304 \ | ||
23 | _IOWR(HYPFS_IOCTL_MAGIC, 0x20, struct hypfs_diag304) | ||
24 | |||
25 | #endif | ||
diff --git a/arch/s390/include/uapi/asm/socket.h b/arch/s390/include/uapi/asm/socket.h index c286c2e868f0..e031332096d7 100644 --- a/arch/s390/include/uapi/asm/socket.h +++ b/arch/s390/include/uapi/asm/socket.h | |||
@@ -84,4 +84,6 @@ | |||
84 | 84 | ||
85 | #define SO_MAX_PACING_RATE 47 | 85 | #define SO_MAX_PACING_RATE 47 |
86 | 86 | ||
87 | #define SO_BPF_EXTENSIONS 48 | ||
88 | |||
87 | #endif /* _ASM_SOCKET_H */ | 89 | #endif /* _ASM_SOCKET_H */ |
diff --git a/arch/s390/include/uapi/asm/statfs.h b/arch/s390/include/uapi/asm/statfs.h index a61d538756f2..471eb09184d4 100644 --- a/arch/s390/include/uapi/asm/statfs.h +++ b/arch/s390/include/uapi/asm/statfs.h | |||
@@ -35,11 +35,11 @@ struct statfs { | |||
35 | struct statfs64 { | 35 | struct statfs64 { |
36 | unsigned int f_type; | 36 | unsigned int f_type; |
37 | unsigned int f_bsize; | 37 | unsigned int f_bsize; |
38 | unsigned long f_blocks; | 38 | unsigned long long f_blocks; |
39 | unsigned long f_bfree; | 39 | unsigned long long f_bfree; |
40 | unsigned long f_bavail; | 40 | unsigned long long f_bavail; |
41 | unsigned long f_files; | 41 | unsigned long long f_files; |
42 | unsigned long f_ffree; | 42 | unsigned long long f_ffree; |
43 | __kernel_fsid_t f_fsid; | 43 | __kernel_fsid_t f_fsid; |
44 | unsigned int f_namelen; | 44 | unsigned int f_namelen; |
45 | unsigned int f_frsize; | 45 | unsigned int f_frsize; |
diff --git a/arch/s390/include/uapi/asm/unistd.h b/arch/s390/include/uapi/asm/unistd.h index 864f693c237f..5eb5c9ddb120 100644 --- a/arch/s390/include/uapi/asm/unistd.h +++ b/arch/s390/include/uapi/asm/unistd.h | |||
@@ -280,6 +280,8 @@ | |||
280 | #define __NR_s390_runtime_instr 342 | 280 | #define __NR_s390_runtime_instr 342 |
281 | #define __NR_kcmp 343 | 281 | #define __NR_kcmp 343 |
282 | #define __NR_finit_module 344 | 282 | #define __NR_finit_module 344 |
283 | #define __NR_sched_setattr 345 | ||
284 | #define __NR_sched_getattr 346 | ||
283 | #define NR_syscalls 345 | 285 | #define NR_syscalls 345 |
284 | 286 | ||
285 | /* | 287 | /* |
diff --git a/arch/s390/include/uapi/asm/zcrypt.h b/arch/s390/include/uapi/asm/zcrypt.h index e83fc116f5bf..f2b18eacaca8 100644 --- a/arch/s390/include/uapi/asm/zcrypt.h +++ b/arch/s390/include/uapi/asm/zcrypt.h | |||
@@ -154,6 +154,67 @@ struct ica_xcRB { | |||
154 | unsigned short priority_window; | 154 | unsigned short priority_window; |
155 | unsigned int status; | 155 | unsigned int status; |
156 | } __attribute__((packed)); | 156 | } __attribute__((packed)); |
157 | |||
158 | /** | ||
159 | * struct ep11_cprb - EP11 connectivity programming request block | ||
160 | * @cprb_len: CPRB header length [0x0020] | ||
161 | * @cprb_ver_id: CPRB version id. [0x04] | ||
162 | * @pad_000: Alignment pad bytes | ||
163 | * @flags: Admin cmd [0x80] or functional cmd [0x00] | ||
164 | * @func_id: Function id / subtype [0x5434] | ||
165 | * @source_id: Source id [originator id] | ||
166 | * @target_id: Target id [usage/ctrl domain id] | ||
167 | * @ret_code: Return code | ||
168 | * @reserved1: Reserved | ||
169 | * @reserved2: Reserved | ||
170 | * @payload_len: Payload length | ||
171 | */ | ||
172 | struct ep11_cprb { | ||
173 | uint16_t cprb_len; | ||
174 | unsigned char cprb_ver_id; | ||
175 | unsigned char pad_000[2]; | ||
176 | unsigned char flags; | ||
177 | unsigned char func_id[2]; | ||
178 | uint32_t source_id; | ||
179 | uint32_t target_id; | ||
180 | uint32_t ret_code; | ||
181 | uint32_t reserved1; | ||
182 | uint32_t reserved2; | ||
183 | uint32_t payload_len; | ||
184 | } __attribute__((packed)); | ||
185 | |||
186 | /** | ||
187 | * struct ep11_target_dev - EP11 target device list | ||
188 | * @ap_id: AP device id | ||
189 | * @dom_id: Usage domain id | ||
190 | */ | ||
191 | struct ep11_target_dev { | ||
192 | uint16_t ap_id; | ||
193 | uint16_t dom_id; | ||
194 | }; | ||
195 | |||
196 | /** | ||
197 | * struct ep11_urb - EP11 user request block | ||
198 | * @targets_num: Number of target adapters | ||
199 | * @targets: Addr to target adapter list | ||
200 | * @weight: Level of request priority | ||
201 | * @req_no: Request id/number | ||
202 | * @req_len: Request length | ||
203 | * @req: Addr to request block | ||
204 | * @resp_len: Response length | ||
205 | * @resp: Addr to response block | ||
206 | */ | ||
207 | struct ep11_urb { | ||
208 | uint16_t targets_num; | ||
209 | uint64_t targets; | ||
210 | uint64_t weight; | ||
211 | uint64_t req_no; | ||
212 | uint64_t req_len; | ||
213 | uint64_t req; | ||
214 | uint64_t resp_len; | ||
215 | uint64_t resp; | ||
216 | } __attribute__((packed)); | ||
217 | |||
157 | #define AUTOSELECT ((unsigned int)0xFFFFFFFF) | 218 | #define AUTOSELECT ((unsigned int)0xFFFFFFFF) |
158 | 219 | ||
159 | #define ZCRYPT_IOCTL_MAGIC 'z' | 220 | #define ZCRYPT_IOCTL_MAGIC 'z' |
@@ -183,6 +244,9 @@ struct ica_xcRB { | |||
183 | * ZSECSENDCPRB | 244 | * ZSECSENDCPRB |
184 | * Send an arbitrary CPRB to a crypto card. | 245 | * Send an arbitrary CPRB to a crypto card. |
185 | * | 246 | * |
247 | * ZSENDEP11CPRB | ||
248 | * Send an arbitrary EP11 CPRB to an EP11 coprocessor crypto card. | ||
249 | * | ||
186 | * Z90STAT_STATUS_MASK | 250 | * Z90STAT_STATUS_MASK |
187 | * Return an 64 element array of unsigned chars for the status of | 251 | * Return an 64 element array of unsigned chars for the status of |
188 | * all devices. | 252 | * all devices. |
@@ -256,6 +320,7 @@ struct ica_xcRB { | |||
256 | #define ICARSAMODEXPO _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x05, 0) | 320 | #define ICARSAMODEXPO _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x05, 0) |
257 | #define ICARSACRT _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x06, 0) | 321 | #define ICARSACRT _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x06, 0) |
258 | #define ZSECSENDCPRB _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x81, 0) | 322 | #define ZSECSENDCPRB _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x81, 0) |
323 | #define ZSENDEP11CPRB _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x04, 0) | ||
259 | 324 | ||
260 | /* New status calls */ | 325 | /* New status calls */ |
261 | #define Z90STAT_TOTALCOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x40, int) | 326 | #define Z90STAT_TOTALCOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x40, int) |
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 2403303cfed7..1b3ac09c11b6 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
@@ -60,7 +60,8 @@ obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o | |||
60 | obj-$(CONFIG_CRASH_DUMP) += crash_dump.o | 60 | obj-$(CONFIG_CRASH_DUMP) += crash_dump.o |
61 | 61 | ||
62 | ifdef CONFIG_64BIT | 62 | ifdef CONFIG_64BIT |
63 | obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_cpum_cf.o | 63 | obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_cpum_cf.o perf_cpum_sf.o \ |
64 | perf_cpum_cf_events.o | ||
64 | obj-y += runtime_instr.o cache.o | 65 | obj-y += runtime_instr.o cache.o |
65 | endif | 66 | endif |
66 | 67 | ||
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index e030d2bdec1b..db02052bd137 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c | |||
@@ -286,8 +286,8 @@ asmlinkage long sys32_getegid16(void) | |||
286 | } | 286 | } |
287 | 287 | ||
288 | #ifdef CONFIG_SYSVIPC | 288 | #ifdef CONFIG_SYSVIPC |
289 | COMPAT_SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second, | 289 | COMPAT_SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, compat_ulong_t, second, |
290 | unsigned long, third, compat_uptr_t, ptr) | 290 | compat_ulong_t, third, compat_uptr_t, ptr) |
291 | { | 291 | { |
292 | if (call >> 16) /* hack for backward compatibility */ | 292 | if (call >> 16) /* hack for backward compatibility */ |
293 | return -EINVAL; | 293 | return -EINVAL; |
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index 95e7ba0fbb7e..8b84bc373e94 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c | |||
@@ -412,8 +412,9 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
412 | regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE; | 412 | regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE; |
413 | } else { | 413 | } else { |
414 | regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE; | 414 | regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE; |
415 | err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, | 415 | if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, |
416 | (u16 __force __user *)(frame->retcode)); | 416 | (u16 __force __user *)(frame->retcode))) |
417 | goto give_sigsegv; | ||
417 | } | 418 | } |
418 | 419 | ||
419 | /* Set up backchain. */ | 420 | /* Set up backchain. */ |
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 9cb1b975b353..59c8efce1b99 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S | |||
@@ -1412,3 +1412,14 @@ ENTRY(sys_finit_module_wrapper) | |||
1412 | llgtr %r3,%r3 # const char __user * | 1412 | llgtr %r3,%r3 # const char __user * |
1413 | lgfr %r4,%r4 # int | 1413 | lgfr %r4,%r4 # int |
1414 | jg sys_finit_module | 1414 | jg sys_finit_module |
1415 | |||
1416 | ENTRY(sys_sched_setattr_wrapper) | ||
1417 | lgfr %r2,%r2 # pid_t | ||
1418 | llgtr %r3,%r3 # struct sched_attr __user * | ||
1419 | jg sys_sched_setattr | ||
1420 | |||
1421 | ENTRY(sys_sched_getattr_wrapper) | ||
1422 | lgfr %r2,%r2 # pid_t | ||
1423 | llgtr %r3,%r3 # const char __user * | ||
1424 | llgfr %r3,%r3 # unsigned int | ||
1425 | jg sys_sched_getattr | ||
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index e5b43c97a834..384e609b4711 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -74,7 +74,7 @@ _TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \ | |||
74 | .endm | 74 | .endm |
75 | 75 | ||
76 | .macro LPP newpp | 76 | .macro LPP newpp |
77 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) | 77 | #if IS_ENABLED(CONFIG_KVM) |
78 | tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_LPP | 78 | tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_LPP |
79 | jz .+8 | 79 | jz .+8 |
80 | .insn s,0xb2800000,\newpp | 80 | .insn s,0xb2800000,\newpp |
@@ -82,7 +82,7 @@ _TIF_TRACE = (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | \ | |||
82 | .endm | 82 | .endm |
83 | 83 | ||
84 | .macro HANDLE_SIE_INTERCEPT scratch,reason | 84 | .macro HANDLE_SIE_INTERCEPT scratch,reason |
85 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) | 85 | #if IS_ENABLED(CONFIG_KVM) |
86 | tmhh %r8,0x0001 # interrupting from user ? | 86 | tmhh %r8,0x0001 # interrupting from user ? |
87 | jnz .+62 | 87 | jnz .+62 |
88 | lgr \scratch,%r9 | 88 | lgr \scratch,%r9 |
@@ -946,7 +946,7 @@ cleanup_idle_insn: | |||
946 | .quad __critical_end - __critical_start | 946 | .quad __critical_end - __critical_start |
947 | 947 | ||
948 | 948 | ||
949 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) | 949 | #if IS_ENABLED(CONFIG_KVM) |
950 | /* | 950 | /* |
951 | * sie64a calling convention: | 951 | * sie64a calling convention: |
952 | * %r2 pointer to sie control block | 952 | * %r2 pointer to sie control block |
@@ -975,7 +975,7 @@ sie_done: | |||
975 | lctlg %c1,%c1,__LC_USER_ASCE # load primary asce | 975 | lctlg %c1,%c1,__LC_USER_ASCE # load primary asce |
976 | # some program checks are suppressing. C code (e.g. do_protection_exception) | 976 | # some program checks are suppressing. C code (e.g. do_protection_exception) |
977 | # will rewind the PSW by the ILC, which is 4 bytes in case of SIE. Other | 977 | # will rewind the PSW by the ILC, which is 4 bytes in case of SIE. Other |
978 | # instructions beween sie64a and sie_done should not cause program | 978 | # instructions between sie64a and sie_done should not cause program |
979 | # interrupts. So lets use a nop (47 00 00 00) as a landing pad. | 979 | # interrupts. So lets use a nop (47 00 00 00) as a landing pad. |
980 | # See also HANDLE_SIE_INTERCEPT | 980 | # See also HANDLE_SIE_INTERCEPT |
981 | rewind_pad: | 981 | rewind_pad: |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index b9e25ae2579c..d7c00507568a 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
@@ -59,7 +59,7 @@ ENTRY(startup_continue) | |||
59 | .quad 0 # cr12: tracing off | 59 | .quad 0 # cr12: tracing off |
60 | .quad 0 # cr13: home space segment table | 60 | .quad 0 # cr13: home space segment table |
61 | .quad 0xc0000000 # cr14: machine check handling off | 61 | .quad 0xc0000000 # cr14: machine check handling off |
62 | .quad 0 # cr15: linkage stack operations | 62 | .quad .Llinkage_stack # cr15: linkage stack operations |
63 | .Lpcmsk:.quad 0x0000000180000000 | 63 | .Lpcmsk:.quad 0x0000000180000000 |
64 | .L4malign:.quad 0xffffffffffc00000 | 64 | .L4malign:.quad 0xffffffffffc00000 |
65 | .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 | 65 | .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 |
@@ -67,12 +67,15 @@ ENTRY(startup_continue) | |||
67 | .Lparmaddr: | 67 | .Lparmaddr: |
68 | .quad PARMAREA | 68 | .quad PARMAREA |
69 | .align 64 | 69 | .align 64 |
70 | .Lduct: .long 0,0,0,0,.Lduald,0,0,0 | 70 | .Lduct: .long 0,.Laste,.Laste,0,.Lduald,0,0,0 |
71 | .long 0,0,0,0,0,0,0,0 | 71 | .long 0,0,0,0,0,0,0,0 |
72 | .Laste: .quad 0,0xffffffffffffffff,0,0,0,0,0,0 | ||
72 | .align 128 | 73 | .align 128 |
73 | .Lduald:.rept 8 | 74 | .Lduald:.rept 8 |
74 | .long 0x80000000,0,0,0 # invalid access-list entries | 75 | .long 0x80000000,0,0,0 # invalid access-list entries |
75 | .endr | 76 | .endr |
77 | .Llinkage_stack: | ||
78 | .long 0,0,0x89000000,0,0,0,0x8a000000,0 | ||
76 | 79 | ||
77 | ENTRY(_ehead) | 80 | ENTRY(_ehead) |
78 | 81 | ||
diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c index 1105502bf6e9..f51214c04858 100644 --- a/arch/s390/kernel/perf_cpum_cf.c +++ b/arch/s390/kernel/perf_cpum_cf.c | |||
@@ -680,6 +680,7 @@ static int __init cpumf_pmu_init(void) | |||
680 | goto out; | 680 | goto out; |
681 | } | 681 | } |
682 | 682 | ||
683 | cpumf_pmu.attr_groups = cpumf_cf_event_group(); | ||
683 | rc = perf_pmu_register(&cpumf_pmu, "cpum_cf", PERF_TYPE_RAW); | 684 | rc = perf_pmu_register(&cpumf_pmu, "cpum_cf", PERF_TYPE_RAW); |
684 | if (rc) { | 685 | if (rc) { |
685 | pr_err("Registering the cpum_cf PMU failed with rc=%i\n", rc); | 686 | pr_err("Registering the cpum_cf PMU failed with rc=%i\n", rc); |
diff --git a/arch/s390/kernel/perf_cpum_cf_events.c b/arch/s390/kernel/perf_cpum_cf_events.c new file mode 100644 index 000000000000..4554a4bae39e --- /dev/null +++ b/arch/s390/kernel/perf_cpum_cf_events.c | |||
@@ -0,0 +1,322 @@ | |||
1 | /* | ||
2 | * Perf PMU sysfs events attributes for available CPU-measurement counters | ||
3 | * | ||
4 | */ | ||
5 | |||
6 | #include <linux/slab.h> | ||
7 | #include <linux/perf_event.h> | ||
8 | |||
9 | |||
10 | /* BEGIN: CPUM_CF COUNTER DEFINITIONS =================================== */ | ||
11 | |||
12 | CPUMF_EVENT_ATTR(cf, CPU_CYCLES, 0x0000); | ||
13 | CPUMF_EVENT_ATTR(cf, INSTRUCTIONS, 0x0001); | ||
14 | CPUMF_EVENT_ATTR(cf, L1I_DIR_WRITES, 0x0002); | ||
15 | CPUMF_EVENT_ATTR(cf, L1I_PENALTY_CYCLES, 0x0003); | ||
16 | CPUMF_EVENT_ATTR(cf, PROBLEM_STATE_CPU_CYCLES, 0x0020); | ||
17 | CPUMF_EVENT_ATTR(cf, PROBLEM_STATE_INSTRUCTIONS, 0x0021); | ||
18 | CPUMF_EVENT_ATTR(cf, PROBLEM_STATE_L1I_DIR_WRITES, 0x0022); | ||
19 | CPUMF_EVENT_ATTR(cf, PROBLEM_STATE_L1I_PENALTY_CYCLES, 0x0023); | ||
20 | CPUMF_EVENT_ATTR(cf, PROBLEM_STATE_L1D_DIR_WRITES, 0x0024); | ||
21 | CPUMF_EVENT_ATTR(cf, PROBLEM_STATE_L1D_PENALTY_CYCLES, 0x0025); | ||
22 | CPUMF_EVENT_ATTR(cf, L1D_DIR_WRITES, 0x0004); | ||
23 | CPUMF_EVENT_ATTR(cf, L1D_PENALTY_CYCLES, 0x0005); | ||
24 | CPUMF_EVENT_ATTR(cf, PRNG_FUNCTIONS, 0x0040); | ||
25 | CPUMF_EVENT_ATTR(cf, PRNG_CYCLES, 0x0041); | ||
26 | CPUMF_EVENT_ATTR(cf, PRNG_BLOCKED_FUNCTIONS, 0x0042); | ||
27 | CPUMF_EVENT_ATTR(cf, PRNG_BLOCKED_CYCLES, 0x0043); | ||
28 | CPUMF_EVENT_ATTR(cf, SHA_FUNCTIONS, 0x0044); | ||
29 | CPUMF_EVENT_ATTR(cf, SHA_CYCLES, 0x0045); | ||
30 | CPUMF_EVENT_ATTR(cf, SHA_BLOCKED_FUNCTIONS, 0x0046); | ||
31 | CPUMF_EVENT_ATTR(cf, SHA_BLOCKED_CYCLES, 0x0047); | ||
32 | CPUMF_EVENT_ATTR(cf, DEA_FUNCTIONS, 0x0048); | ||
33 | CPUMF_EVENT_ATTR(cf, DEA_CYCLES, 0x0049); | ||
34 | CPUMF_EVENT_ATTR(cf, DEA_BLOCKED_FUNCTIONS, 0x004a); | ||
35 | CPUMF_EVENT_ATTR(cf, DEA_BLOCKED_CYCLES, 0x004b); | ||
36 | CPUMF_EVENT_ATTR(cf, AES_FUNCTIONS, 0x004c); | ||
37 | CPUMF_EVENT_ATTR(cf, AES_CYCLES, 0x004d); | ||
38 | CPUMF_EVENT_ATTR(cf, AES_BLOCKED_FUNCTIONS, 0x004e); | ||
39 | CPUMF_EVENT_ATTR(cf, AES_BLOCKED_CYCLES, 0x004f); | ||
40 | CPUMF_EVENT_ATTR(cf_z10, L1I_L2_SOURCED_WRITES, 0x0080); | ||
41 | CPUMF_EVENT_ATTR(cf_z10, L1D_L2_SOURCED_WRITES, 0x0081); | ||
42 | CPUMF_EVENT_ATTR(cf_z10, L1I_L3_LOCAL_WRITES, 0x0082); | ||
43 | CPUMF_EVENT_ATTR(cf_z10, L1D_L3_LOCAL_WRITES, 0x0083); | ||
44 | CPUMF_EVENT_ATTR(cf_z10, L1I_L3_REMOTE_WRITES, 0x0084); | ||
45 | CPUMF_EVENT_ATTR(cf_z10, L1D_L3_REMOTE_WRITES, 0x0085); | ||
46 | CPUMF_EVENT_ATTR(cf_z10, L1D_LMEM_SOURCED_WRITES, 0x0086); | ||
47 | CPUMF_EVENT_ATTR(cf_z10, L1I_LMEM_SOURCED_WRITES, 0x0087); | ||
48 | CPUMF_EVENT_ATTR(cf_z10, L1D_RO_EXCL_WRITES, 0x0088); | ||
49 | CPUMF_EVENT_ATTR(cf_z10, L1I_CACHELINE_INVALIDATES, 0x0089); | ||
50 | CPUMF_EVENT_ATTR(cf_z10, ITLB1_WRITES, 0x008a); | ||
51 | CPUMF_EVENT_ATTR(cf_z10, DTLB1_WRITES, 0x008b); | ||
52 | CPUMF_EVENT_ATTR(cf_z10, TLB2_PTE_WRITES, 0x008c); | ||
53 | CPUMF_EVENT_ATTR(cf_z10, TLB2_CRSTE_WRITES, 0x008d); | ||
54 | CPUMF_EVENT_ATTR(cf_z10, TLB2_CRSTE_HPAGE_WRITES, 0x008e); | ||
55 | CPUMF_EVENT_ATTR(cf_z10, ITLB1_MISSES, 0x0091); | ||
56 | CPUMF_EVENT_ATTR(cf_z10, DTLB1_MISSES, 0x0092); | ||
57 | CPUMF_EVENT_ATTR(cf_z10, L2C_STORES_SENT, 0x0093); | ||
58 | CPUMF_EVENT_ATTR(cf_z196, L1D_L2_SOURCED_WRITES, 0x0080); | ||
59 | CPUMF_EVENT_ATTR(cf_z196, L1I_L2_SOURCED_WRITES, 0x0081); | ||
60 | CPUMF_EVENT_ATTR(cf_z196, DTLB1_MISSES, 0x0082); | ||
61 | CPUMF_EVENT_ATTR(cf_z196, ITLB1_MISSES, 0x0083); | ||
62 | CPUMF_EVENT_ATTR(cf_z196, L2C_STORES_SENT, 0x0085); | ||
63 | CPUMF_EVENT_ATTR(cf_z196, L1D_OFFBOOK_L3_SOURCED_WRITES, 0x0086); | ||
64 | CPUMF_EVENT_ATTR(cf_z196, L1D_ONBOOK_L4_SOURCED_WRITES, 0x0087); | ||
65 | CPUMF_EVENT_ATTR(cf_z196, L1I_ONBOOK_L4_SOURCED_WRITES, 0x0088); | ||
66 | CPUMF_EVENT_ATTR(cf_z196, L1D_RO_EXCL_WRITES, 0x0089); | ||
67 | CPUMF_EVENT_ATTR(cf_z196, L1D_OFFBOOK_L4_SOURCED_WRITES, 0x008a); | ||
68 | CPUMF_EVENT_ATTR(cf_z196, L1I_OFFBOOK_L4_SOURCED_WRITES, 0x008b); | ||
69 | CPUMF_EVENT_ATTR(cf_z196, DTLB1_HPAGE_WRITES, 0x008c); | ||
70 | CPUMF_EVENT_ATTR(cf_z196, L1D_LMEM_SOURCED_WRITES, 0x008d); | ||
71 | CPUMF_EVENT_ATTR(cf_z196, L1I_LMEM_SOURCED_WRITES, 0x008e); | ||
72 | CPUMF_EVENT_ATTR(cf_z196, L1I_OFFBOOK_L3_SOURCED_WRITES, 0x008f); | ||
73 | CPUMF_EVENT_ATTR(cf_z196, DTLB1_WRITES, 0x0090); | ||
74 | CPUMF_EVENT_ATTR(cf_z196, ITLB1_WRITES, 0x0091); | ||
75 | CPUMF_EVENT_ATTR(cf_z196, TLB2_PTE_WRITES, 0x0092); | ||
76 | CPUMF_EVENT_ATTR(cf_z196, TLB2_CRSTE_HPAGE_WRITES, 0x0093); | ||
77 | CPUMF_EVENT_ATTR(cf_z196, TLB2_CRSTE_WRITES, 0x0094); | ||
78 | CPUMF_EVENT_ATTR(cf_z196, L1D_ONCHIP_L3_SOURCED_WRITES, 0x0096); | ||
79 | CPUMF_EVENT_ATTR(cf_z196, L1D_OFFCHIP_L3_SOURCED_WRITES, 0x0098); | ||
80 | CPUMF_EVENT_ATTR(cf_z196, L1I_ONCHIP_L3_SOURCED_WRITES, 0x0099); | ||
81 | CPUMF_EVENT_ATTR(cf_z196, L1I_OFFCHIP_L3_SOURCED_WRITES, 0x009b); | ||
82 | CPUMF_EVENT_ATTR(cf_zec12, DTLB1_MISSES, 0x0080); | ||
83 | CPUMF_EVENT_ATTR(cf_zec12, ITLB1_MISSES, 0x0081); | ||
84 | CPUMF_EVENT_ATTR(cf_zec12, L1D_L2I_SOURCED_WRITES, 0x0082); | ||
85 | CPUMF_EVENT_ATTR(cf_zec12, L1I_L2I_SOURCED_WRITES, 0x0083); | ||
86 | CPUMF_EVENT_ATTR(cf_zec12, L1D_L2D_SOURCED_WRITES, 0x0084); | ||
87 | CPUMF_EVENT_ATTR(cf_zec12, DTLB1_WRITES, 0x0085); | ||
88 | CPUMF_EVENT_ATTR(cf_zec12, L1D_LMEM_SOURCED_WRITES, 0x0087); | ||
89 | CPUMF_EVENT_ATTR(cf_zec12, L1I_LMEM_SOURCED_WRITES, 0x0089); | ||
90 | CPUMF_EVENT_ATTR(cf_zec12, L1D_RO_EXCL_WRITES, 0x008a); | ||
91 | CPUMF_EVENT_ATTR(cf_zec12, DTLB1_HPAGE_WRITES, 0x008b); | ||
92 | CPUMF_EVENT_ATTR(cf_zec12, ITLB1_WRITES, 0x008c); | ||
93 | CPUMF_EVENT_ATTR(cf_zec12, TLB2_PTE_WRITES, 0x008d); | ||
94 | CPUMF_EVENT_ATTR(cf_zec12, TLB2_CRSTE_HPAGE_WRITES, 0x008e); | ||
95 | CPUMF_EVENT_ATTR(cf_zec12, TLB2_CRSTE_WRITES, 0x008f); | ||
96 | CPUMF_EVENT_ATTR(cf_zec12, L1D_ONCHIP_L3_SOURCED_WRITES, 0x0090); | ||
97 | CPUMF_EVENT_ATTR(cf_zec12, L1D_OFFCHIP_L3_SOURCED_WRITES, 0x0091); | ||
98 | CPUMF_EVENT_ATTR(cf_zec12, L1D_OFFBOOK_L3_SOURCED_WRITES, 0x0092); | ||
99 | CPUMF_EVENT_ATTR(cf_zec12, L1D_ONBOOK_L4_SOURCED_WRITES, 0x0093); | ||
100 | CPUMF_EVENT_ATTR(cf_zec12, L1D_OFFBOOK_L4_SOURCED_WRITES, 0x0094); | ||
101 | CPUMF_EVENT_ATTR(cf_zec12, TX_NC_TEND, 0x0095); | ||
102 | CPUMF_EVENT_ATTR(cf_zec12, L1D_ONCHIP_L3_SOURCED_WRITES_IV, 0x0096); | ||
103 | CPUMF_EVENT_ATTR(cf_zec12, L1D_OFFCHIP_L3_SOURCED_WRITES_IV, 0x0097); | ||
104 | CPUMF_EVENT_ATTR(cf_zec12, L1D_OFFBOOK_L3_SOURCED_WRITES_IV, 0x0098); | ||
105 | CPUMF_EVENT_ATTR(cf_zec12, L1I_ONCHIP_L3_SOURCED_WRITES, 0x0099); | ||
106 | CPUMF_EVENT_ATTR(cf_zec12, L1I_OFFCHIP_L3_SOURCED_WRITES, 0x009a); | ||
107 | CPUMF_EVENT_ATTR(cf_zec12, L1I_OFFBOOK_L3_SOURCED_WRITES, 0x009b); | ||
108 | CPUMF_EVENT_ATTR(cf_zec12, L1I_ONBOOK_L4_SOURCED_WRITES, 0x009c); | ||
109 | CPUMF_EVENT_ATTR(cf_zec12, L1I_OFFBOOK_L4_SOURCED_WRITES, 0x009d); | ||
110 | CPUMF_EVENT_ATTR(cf_zec12, TX_C_TEND, 0x009e); | ||
111 | CPUMF_EVENT_ATTR(cf_zec12, L1I_ONCHIP_L3_SOURCED_WRITES_IV, 0x009f); | ||
112 | CPUMF_EVENT_ATTR(cf_zec12, L1I_OFFCHIP_L3_SOURCED_WRITES_IV, 0x00a0); | ||
113 | CPUMF_EVENT_ATTR(cf_zec12, L1I_OFFBOOK_L3_SOURCED_WRITES_IV, 0x00a1); | ||
114 | CPUMF_EVENT_ATTR(cf_zec12, TX_NC_TABORT, 0x00b1); | ||
115 | CPUMF_EVENT_ATTR(cf_zec12, TX_C_TABORT_NO_SPECIAL, 0x00b2); | ||
116 | CPUMF_EVENT_ATTR(cf_zec12, TX_C_TABORT_SPECIAL, 0x00b3); | ||
117 | |||
118 | static struct attribute *cpumcf_pmu_event_attr[] = { | ||
119 | CPUMF_EVENT_PTR(cf, CPU_CYCLES), | ||
120 | CPUMF_EVENT_PTR(cf, INSTRUCTIONS), | ||
121 | CPUMF_EVENT_PTR(cf, L1I_DIR_WRITES), | ||
122 | CPUMF_EVENT_PTR(cf, L1I_PENALTY_CYCLES), | ||
123 | CPUMF_EVENT_PTR(cf, PROBLEM_STATE_CPU_CYCLES), | ||
124 | CPUMF_EVENT_PTR(cf, PROBLEM_STATE_INSTRUCTIONS), | ||
125 | CPUMF_EVENT_PTR(cf, PROBLEM_STATE_L1I_DIR_WRITES), | ||
126 | CPUMF_EVENT_PTR(cf, PROBLEM_STATE_L1I_PENALTY_CYCLES), | ||
127 | CPUMF_EVENT_PTR(cf, PROBLEM_STATE_L1D_DIR_WRITES), | ||
128 | CPUMF_EVENT_PTR(cf, PROBLEM_STATE_L1D_PENALTY_CYCLES), | ||
129 | CPUMF_EVENT_PTR(cf, L1D_DIR_WRITES), | ||
130 | CPUMF_EVENT_PTR(cf, L1D_PENALTY_CYCLES), | ||
131 | CPUMF_EVENT_PTR(cf, PRNG_FUNCTIONS), | ||
132 | CPUMF_EVENT_PTR(cf, PRNG_CYCLES), | ||
133 | CPUMF_EVENT_PTR(cf, PRNG_BLOCKED_FUNCTIONS), | ||
134 | CPUMF_EVENT_PTR(cf, PRNG_BLOCKED_CYCLES), | ||
135 | CPUMF_EVENT_PTR(cf, SHA_FUNCTIONS), | ||
136 | CPUMF_EVENT_PTR(cf, SHA_CYCLES), | ||
137 | CPUMF_EVENT_PTR(cf, SHA_BLOCKED_FUNCTIONS), | ||
138 | CPUMF_EVENT_PTR(cf, SHA_BLOCKED_CYCLES), | ||
139 | CPUMF_EVENT_PTR(cf, DEA_FUNCTIONS), | ||
140 | CPUMF_EVENT_PTR(cf, DEA_CYCLES), | ||
141 | CPUMF_EVENT_PTR(cf, DEA_BLOCKED_FUNCTIONS), | ||
142 | CPUMF_EVENT_PTR(cf, DEA_BLOCKED_CYCLES), | ||
143 | CPUMF_EVENT_PTR(cf, AES_FUNCTIONS), | ||
144 | CPUMF_EVENT_PTR(cf, AES_CYCLES), | ||
145 | CPUMF_EVENT_PTR(cf, AES_BLOCKED_FUNCTIONS), | ||
146 | CPUMF_EVENT_PTR(cf, AES_BLOCKED_CYCLES), | ||
147 | NULL, | ||
148 | }; | ||
149 | |||
150 | static struct attribute *cpumcf_z10_pmu_event_attr[] __initdata = { | ||
151 | CPUMF_EVENT_PTR(cf_z10, L1I_L2_SOURCED_WRITES), | ||
152 | CPUMF_EVENT_PTR(cf_z10, L1D_L2_SOURCED_WRITES), | ||
153 | CPUMF_EVENT_PTR(cf_z10, L1I_L3_LOCAL_WRITES), | ||
154 | CPUMF_EVENT_PTR(cf_z10, L1D_L3_LOCAL_WRITES), | ||
155 | CPUMF_EVENT_PTR(cf_z10, L1I_L3_REMOTE_WRITES), | ||
156 | CPUMF_EVENT_PTR(cf_z10, L1D_L3_REMOTE_WRITES), | ||
157 | CPUMF_EVENT_PTR(cf_z10, L1D_LMEM_SOURCED_WRITES), | ||
158 | CPUMF_EVENT_PTR(cf_z10, L1I_LMEM_SOURCED_WRITES), | ||
159 | CPUMF_EVENT_PTR(cf_z10, L1D_RO_EXCL_WRITES), | ||
160 | CPUMF_EVENT_PTR(cf_z10, L1I_CACHELINE_INVALIDATES), | ||
161 | CPUMF_EVENT_PTR(cf_z10, ITLB1_WRITES), | ||
162 | CPUMF_EVENT_PTR(cf_z10, DTLB1_WRITES), | ||
163 | CPUMF_EVENT_PTR(cf_z10, TLB2_PTE_WRITES), | ||
164 | CPUMF_EVENT_PTR(cf_z10, TLB2_CRSTE_WRITES), | ||
165 | CPUMF_EVENT_PTR(cf_z10, TLB2_CRSTE_HPAGE_WRITES), | ||
166 | CPUMF_EVENT_PTR(cf_z10, ITLB1_MISSES), | ||
167 | CPUMF_EVENT_PTR(cf_z10, DTLB1_MISSES), | ||
168 | CPUMF_EVENT_PTR(cf_z10, L2C_STORES_SENT), | ||
169 | NULL, | ||
170 | }; | ||
171 | |||
172 | static struct attribute *cpumcf_z196_pmu_event_attr[] __initdata = { | ||
173 | CPUMF_EVENT_PTR(cf_z196, L1D_L2_SOURCED_WRITES), | ||
174 | CPUMF_EVENT_PTR(cf_z196, L1I_L2_SOURCED_WRITES), | ||
175 | CPUMF_EVENT_PTR(cf_z196, DTLB1_MISSES), | ||
176 | CPUMF_EVENT_PTR(cf_z196, ITLB1_MISSES), | ||
177 | CPUMF_EVENT_PTR(cf_z196, L2C_STORES_SENT), | ||
178 | CPUMF_EVENT_PTR(cf_z196, L1D_OFFBOOK_L3_SOURCED_WRITES), | ||
179 | CPUMF_EVENT_PTR(cf_z196, L1D_ONBOOK_L4_SOURCED_WRITES), | ||
180 | CPUMF_EVENT_PTR(cf_z196, L1I_ONBOOK_L4_SOURCED_WRITES), | ||
181 | CPUMF_EVENT_PTR(cf_z196, L1D_RO_EXCL_WRITES), | ||
182 | CPUMF_EVENT_PTR(cf_z196, L1D_OFFBOOK_L4_SOURCED_WRITES), | ||
183 | CPUMF_EVENT_PTR(cf_z196, L1I_OFFBOOK_L4_SOURCED_WRITES), | ||
184 | CPUMF_EVENT_PTR(cf_z196, DTLB1_HPAGE_WRITES), | ||
185 | CPUMF_EVENT_PTR(cf_z196, L1D_LMEM_SOURCED_WRITES), | ||
186 | CPUMF_EVENT_PTR(cf_z196, L1I_LMEM_SOURCED_WRITES), | ||
187 | CPUMF_EVENT_PTR(cf_z196, L1I_OFFBOOK_L3_SOURCED_WRITES), | ||
188 | CPUMF_EVENT_PTR(cf_z196, DTLB1_WRITES), | ||
189 | CPUMF_EVENT_PTR(cf_z196, ITLB1_WRITES), | ||
190 | CPUMF_EVENT_PTR(cf_z196, TLB2_PTE_WRITES), | ||
191 | CPUMF_EVENT_PTR(cf_z196, TLB2_CRSTE_HPAGE_WRITES), | ||
192 | CPUMF_EVENT_PTR(cf_z196, TLB2_CRSTE_WRITES), | ||
193 | CPUMF_EVENT_PTR(cf_z196, L1D_ONCHIP_L3_SOURCED_WRITES), | ||
194 | CPUMF_EVENT_PTR(cf_z196, L1D_OFFCHIP_L3_SOURCED_WRITES), | ||
195 | CPUMF_EVENT_PTR(cf_z196, L1I_ONCHIP_L3_SOURCED_WRITES), | ||
196 | CPUMF_EVENT_PTR(cf_z196, L1I_OFFCHIP_L3_SOURCED_WRITES), | ||
197 | NULL, | ||
198 | }; | ||
199 | |||
200 | static struct attribute *cpumcf_zec12_pmu_event_attr[] __initdata = { | ||
201 | CPUMF_EVENT_PTR(cf_zec12, DTLB1_MISSES), | ||
202 | CPUMF_EVENT_PTR(cf_zec12, ITLB1_MISSES), | ||
203 | CPUMF_EVENT_PTR(cf_zec12, L1D_L2I_SOURCED_WRITES), | ||
204 | CPUMF_EVENT_PTR(cf_zec12, L1I_L2I_SOURCED_WRITES), | ||
205 | CPUMF_EVENT_PTR(cf_zec12, L1D_L2D_SOURCED_WRITES), | ||
206 | CPUMF_EVENT_PTR(cf_zec12, DTLB1_WRITES), | ||
207 | CPUMF_EVENT_PTR(cf_zec12, L1D_LMEM_SOURCED_WRITES), | ||
208 | CPUMF_EVENT_PTR(cf_zec12, L1I_LMEM_SOURCED_WRITES), | ||
209 | CPUMF_EVENT_PTR(cf_zec12, L1D_RO_EXCL_WRITES), | ||
210 | CPUMF_EVENT_PTR(cf_zec12, DTLB1_HPAGE_WRITES), | ||
211 | CPUMF_EVENT_PTR(cf_zec12, ITLB1_WRITES), | ||
212 | CPUMF_EVENT_PTR(cf_zec12, TLB2_PTE_WRITES), | ||
213 | CPUMF_EVENT_PTR(cf_zec12, TLB2_CRSTE_HPAGE_WRITES), | ||
214 | CPUMF_EVENT_PTR(cf_zec12, TLB2_CRSTE_WRITES), | ||
215 | CPUMF_EVENT_PTR(cf_zec12, L1D_ONCHIP_L3_SOURCED_WRITES), | ||
216 | CPUMF_EVENT_PTR(cf_zec12, L1D_OFFCHIP_L3_SOURCED_WRITES), | ||
217 | CPUMF_EVENT_PTR(cf_zec12, L1D_OFFBOOK_L3_SOURCED_WRITES), | ||
218 | CPUMF_EVENT_PTR(cf_zec12, L1D_ONBOOK_L4_SOURCED_WRITES), | ||
219 | CPUMF_EVENT_PTR(cf_zec12, L1D_OFFBOOK_L4_SOURCED_WRITES), | ||
220 | CPUMF_EVENT_PTR(cf_zec12, TX_NC_TEND), | ||
221 | CPUMF_EVENT_PTR(cf_zec12, L1D_ONCHIP_L3_SOURCED_WRITES_IV), | ||
222 | CPUMF_EVENT_PTR(cf_zec12, L1D_OFFCHIP_L3_SOURCED_WRITES_IV), | ||
223 | CPUMF_EVENT_PTR(cf_zec12, L1D_OFFBOOK_L3_SOURCED_WRITES_IV), | ||
224 | CPUMF_EVENT_PTR(cf_zec12, L1I_ONCHIP_L3_SOURCED_WRITES), | ||
225 | CPUMF_EVENT_PTR(cf_zec12, L1I_OFFCHIP_L3_SOURCED_WRITES), | ||
226 | CPUMF_EVENT_PTR(cf_zec12, L1I_OFFBOOK_L3_SOURCED_WRITES), | ||
227 | CPUMF_EVENT_PTR(cf_zec12, L1I_ONBOOK_L4_SOURCED_WRITES), | ||
228 | CPUMF_EVENT_PTR(cf_zec12, L1I_OFFBOOK_L4_SOURCED_WRITES), | ||
229 | CPUMF_EVENT_PTR(cf_zec12, TX_C_TEND), | ||
230 | CPUMF_EVENT_PTR(cf_zec12, L1I_ONCHIP_L3_SOURCED_WRITES_IV), | ||
231 | CPUMF_EVENT_PTR(cf_zec12, L1I_OFFCHIP_L3_SOURCED_WRITES_IV), | ||
232 | CPUMF_EVENT_PTR(cf_zec12, L1I_OFFBOOK_L3_SOURCED_WRITES_IV), | ||
233 | CPUMF_EVENT_PTR(cf_zec12, TX_NC_TABORT), | ||
234 | CPUMF_EVENT_PTR(cf_zec12, TX_C_TABORT_NO_SPECIAL), | ||
235 | CPUMF_EVENT_PTR(cf_zec12, TX_C_TABORT_SPECIAL), | ||
236 | NULL, | ||
237 | }; | ||
238 | |||
239 | /* END: CPUM_CF COUNTER DEFINITIONS ===================================== */ | ||
240 | |||
241 | static struct attribute_group cpumsf_pmu_events_group = { | ||
242 | .name = "events", | ||
243 | .attrs = cpumcf_pmu_event_attr, | ||
244 | }; | ||
245 | |||
246 | PMU_FORMAT_ATTR(event, "config:0-63"); | ||
247 | |||
248 | static struct attribute *cpumsf_pmu_format_attr[] = { | ||
249 | &format_attr_event.attr, | ||
250 | NULL, | ||
251 | }; | ||
252 | |||
253 | static struct attribute_group cpumsf_pmu_format_group = { | ||
254 | .name = "format", | ||
255 | .attrs = cpumsf_pmu_format_attr, | ||
256 | }; | ||
257 | |||
258 | static const struct attribute_group *cpumsf_pmu_attr_groups[] = { | ||
259 | &cpumsf_pmu_events_group, | ||
260 | &cpumsf_pmu_format_group, | ||
261 | NULL, | ||
262 | }; | ||
263 | |||
264 | |||
265 | static __init struct attribute **merge_attr(struct attribute **a, | ||
266 | struct attribute **b) | ||
267 | { | ||
268 | struct attribute **new; | ||
269 | int j, i; | ||
270 | |||
271 | for (j = 0; a[j]; j++) | ||
272 | ; | ||
273 | for (i = 0; b[i]; i++) | ||
274 | j++; | ||
275 | j++; | ||
276 | |||
277 | new = kmalloc(sizeof(struct attribute *) * j, GFP_KERNEL); | ||
278 | if (!new) | ||
279 | return NULL; | ||
280 | j = 0; | ||
281 | for (i = 0; a[i]; i++) | ||
282 | new[j++] = a[i]; | ||
283 | for (i = 0; b[i]; i++) | ||
284 | new[j++] = b[i]; | ||
285 | new[j] = NULL; | ||
286 | |||
287 | return new; | ||
288 | } | ||
289 | |||
290 | __init const struct attribute_group **cpumf_cf_event_group(void) | ||
291 | { | ||
292 | struct attribute **combined, **model; | ||
293 | struct cpuid cpu_id; | ||
294 | |||
295 | get_cpu_id(&cpu_id); | ||
296 | switch (cpu_id.machine) { | ||
297 | case 0x2097: | ||
298 | case 0x2098: | ||
299 | model = cpumcf_z10_pmu_event_attr; | ||
300 | break; | ||
301 | case 0x2817: | ||
302 | case 0x2818: | ||
303 | model = cpumcf_z196_pmu_event_attr; | ||
304 | break; | ||
305 | case 0x2827: | ||
306 | case 0x2828: | ||
307 | model = cpumcf_zec12_pmu_event_attr; | ||
308 | break; | ||
309 | default: | ||
310 | model = NULL; | ||
311 | break; | ||
312 | }; | ||
313 | |||
314 | if (!model) | ||
315 | goto out; | ||
316 | |||
317 | combined = merge_attr(cpumcf_pmu_event_attr, model); | ||
318 | if (combined) | ||
319 | cpumsf_pmu_events_group.attrs = combined; | ||
320 | out: | ||
321 | return cpumsf_pmu_attr_groups; | ||
322 | } | ||
diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c new file mode 100644 index 000000000000..6c0d29827cb6 --- /dev/null +++ b/arch/s390/kernel/perf_cpum_sf.c | |||
@@ -0,0 +1,1641 @@ | |||
1 | /* | ||
2 | * Performance event support for the System z CPU-measurement Sampling Facility | ||
3 | * | ||
4 | * Copyright IBM Corp. 2013 | ||
5 | * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License (version 2 only) | ||
9 | * as published by the Free Software Foundation. | ||
10 | */ | ||
11 | #define KMSG_COMPONENT "cpum_sf" | ||
12 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/kernel_stat.h> | ||
16 | #include <linux/perf_event.h> | ||
17 | #include <linux/percpu.h> | ||
18 | #include <linux/notifier.h> | ||
19 | #include <linux/export.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/mm.h> | ||
22 | #include <linux/moduleparam.h> | ||
23 | #include <asm/cpu_mf.h> | ||
24 | #include <asm/irq.h> | ||
25 | #include <asm/debug.h> | ||
26 | #include <asm/timex.h> | ||
27 | |||
28 | /* Minimum number of sample-data-block-tables: | ||
29 | * At least one table is required for the sampling buffer structure. | ||
30 | * A single table contains up to 511 pointers to sample-data-blocks. | ||
31 | */ | ||
32 | #define CPUM_SF_MIN_SDBT 1 | ||
33 | |||
34 | /* Number of sample-data-blocks per sample-data-block-table (SDBT): | ||
35 | * A table contains SDB pointers (8 bytes) and one table-link entry | ||
36 | * that points to the origin of the next SDBT. | ||
37 | */ | ||
38 | #define CPUM_SF_SDB_PER_TABLE ((PAGE_SIZE - 8) / 8) | ||
39 | |||
40 | /* Maximum page offset for an SDBT table-link entry: | ||
41 | * If this page offset is reached, a table-link entry to the next SDBT | ||
42 | * must be added. | ||
43 | */ | ||
44 | #define CPUM_SF_SDBT_TL_OFFSET (CPUM_SF_SDB_PER_TABLE * 8) | ||
45 | static inline int require_table_link(const void *sdbt) | ||
46 | { | ||
47 | return ((unsigned long) sdbt & ~PAGE_MASK) == CPUM_SF_SDBT_TL_OFFSET; | ||
48 | } | ||
49 | |||
50 | /* Minimum and maximum sampling buffer sizes: | ||
51 | * | ||
52 | * This number represents the maximum size of the sampling buffer taking | ||
53 | * the number of sample-data-block-tables into account. Note that these | ||
54 | * numbers apply to the basic-sampling function only. | ||
55 | * The maximum number of SDBs is increased by CPUM_SF_SDB_DIAG_FACTOR if | ||
56 | * the diagnostic-sampling function is active. | ||
57 | * | ||
58 | * Sampling buffer size Buffer characteristics | ||
59 | * --------------------------------------------------- | ||
60 | * 64KB == 16 pages (4KB per page) | ||
61 | * 1 page for SDB-tables | ||
62 | * 15 pages for SDBs | ||
63 | * | ||
64 | * 32MB == 8192 pages (4KB per page) | ||
65 | * 16 pages for SDB-tables | ||
66 | * 8176 pages for SDBs | ||
67 | */ | ||
68 | static unsigned long __read_mostly CPUM_SF_MIN_SDB = 15; | ||
69 | static unsigned long __read_mostly CPUM_SF_MAX_SDB = 8176; | ||
70 | static unsigned long __read_mostly CPUM_SF_SDB_DIAG_FACTOR = 1; | ||
71 | |||
72 | struct sf_buffer { | ||
73 | unsigned long *sdbt; /* Sample-data-block-table origin */ | ||
74 | /* buffer characteristics (required for buffer increments) */ | ||
75 | unsigned long num_sdb; /* Number of sample-data-blocks */ | ||
76 | unsigned long num_sdbt; /* Number of sample-data-block-tables */ | ||
77 | unsigned long *tail; /* last sample-data-block-table */ | ||
78 | }; | ||
79 | |||
80 | struct cpu_hw_sf { | ||
81 | /* CPU-measurement sampling information block */ | ||
82 | struct hws_qsi_info_block qsi; | ||
83 | /* CPU-measurement sampling control block */ | ||
84 | struct hws_lsctl_request_block lsctl; | ||
85 | struct sf_buffer sfb; /* Sampling buffer */ | ||
86 | unsigned int flags; /* Status flags */ | ||
87 | struct perf_event *event; /* Scheduled perf event */ | ||
88 | }; | ||
89 | static DEFINE_PER_CPU(struct cpu_hw_sf, cpu_hw_sf); | ||
90 | |||
91 | /* Debug feature */ | ||
92 | static debug_info_t *sfdbg; | ||
93 | |||
94 | /* | ||
95 | * sf_disable() - Switch off sampling facility | ||
96 | */ | ||
97 | static int sf_disable(void) | ||
98 | { | ||
99 | struct hws_lsctl_request_block sreq; | ||
100 | |||
101 | memset(&sreq, 0, sizeof(sreq)); | ||
102 | return lsctl(&sreq); | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * sf_buffer_available() - Check for an allocated sampling buffer | ||
107 | */ | ||
108 | static int sf_buffer_available(struct cpu_hw_sf *cpuhw) | ||
109 | { | ||
110 | return !!cpuhw->sfb.sdbt; | ||
111 | } | ||
112 | |||
113 | /* | ||
114 | * deallocate sampling facility buffer | ||
115 | */ | ||
116 | static void free_sampling_buffer(struct sf_buffer *sfb) | ||
117 | { | ||
118 | unsigned long *sdbt, *curr; | ||
119 | |||
120 | if (!sfb->sdbt) | ||
121 | return; | ||
122 | |||
123 | sdbt = sfb->sdbt; | ||
124 | curr = sdbt; | ||
125 | |||
126 | /* Free the SDBT after all SDBs are processed... */ | ||
127 | while (1) { | ||
128 | if (!*curr || !sdbt) | ||
129 | break; | ||
130 | |||
131 | /* Process table-link entries */ | ||
132 | if (is_link_entry(curr)) { | ||
133 | curr = get_next_sdbt(curr); | ||
134 | if (sdbt) | ||
135 | free_page((unsigned long) sdbt); | ||
136 | |||
137 | /* If the origin is reached, sampling buffer is freed */ | ||
138 | if (curr == sfb->sdbt) | ||
139 | break; | ||
140 | else | ||
141 | sdbt = curr; | ||
142 | } else { | ||
143 | /* Process SDB pointer */ | ||
144 | if (*curr) { | ||
145 | free_page(*curr); | ||
146 | curr++; | ||
147 | } | ||
148 | } | ||
149 | } | ||
150 | |||
151 | debug_sprintf_event(sfdbg, 5, | ||
152 | "free_sampling_buffer: freed sdbt=%p\n", sfb->sdbt); | ||
153 | memset(sfb, 0, sizeof(*sfb)); | ||
154 | } | ||
155 | |||
156 | static int alloc_sample_data_block(unsigned long *sdbt, gfp_t gfp_flags) | ||
157 | { | ||
158 | unsigned long sdb, *trailer; | ||
159 | |||
160 | /* Allocate and initialize sample-data-block */ | ||
161 | sdb = get_zeroed_page(gfp_flags); | ||
162 | if (!sdb) | ||
163 | return -ENOMEM; | ||
164 | trailer = trailer_entry_ptr(sdb); | ||
165 | *trailer = SDB_TE_ALERT_REQ_MASK; | ||
166 | |||
167 | /* Link SDB into the sample-data-block-table */ | ||
168 | *sdbt = sdb; | ||
169 | |||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | /* | ||
174 | * realloc_sampling_buffer() - extend sampler memory | ||
175 | * | ||
176 | * Allocates new sample-data-blocks and adds them to the specified sampling | ||
177 | * buffer memory. | ||
178 | * | ||
179 | * Important: This modifies the sampling buffer and must be called when the | ||
180 | * sampling facility is disabled. | ||
181 | * | ||
182 | * Returns zero on success, non-zero otherwise. | ||
183 | */ | ||
184 | static int realloc_sampling_buffer(struct sf_buffer *sfb, | ||
185 | unsigned long num_sdb, gfp_t gfp_flags) | ||
186 | { | ||
187 | int i, rc; | ||
188 | unsigned long *new, *tail; | ||
189 | |||
190 | if (!sfb->sdbt || !sfb->tail) | ||
191 | return -EINVAL; | ||
192 | |||
193 | if (!is_link_entry(sfb->tail)) | ||
194 | return -EINVAL; | ||
195 | |||
196 | /* Append to the existing sampling buffer, overwriting the table-link | ||
197 | * register. | ||
198 | * The tail variables always points to the "tail" (last and table-link) | ||
199 | * entry in an SDB-table. | ||
200 | */ | ||
201 | tail = sfb->tail; | ||
202 | |||
203 | /* Do a sanity check whether the table-link entry points to | ||
204 | * the sampling buffer origin. | ||
205 | */ | ||
206 | if (sfb->sdbt != get_next_sdbt(tail)) { | ||
207 | debug_sprintf_event(sfdbg, 3, "realloc_sampling_buffer: " | ||
208 | "sampling buffer is not linked: origin=%p" | ||
209 | "tail=%p\n", | ||
210 | (void *) sfb->sdbt, (void *) tail); | ||
211 | return -EINVAL; | ||
212 | } | ||
213 | |||
214 | /* Allocate remaining SDBs */ | ||
215 | rc = 0; | ||
216 | for (i = 0; i < num_sdb; i++) { | ||
217 | /* Allocate a new SDB-table if it is full. */ | ||
218 | if (require_table_link(tail)) { | ||
219 | new = (unsigned long *) get_zeroed_page(gfp_flags); | ||
220 | if (!new) { | ||
221 | rc = -ENOMEM; | ||
222 | break; | ||
223 | } | ||
224 | sfb->num_sdbt++; | ||
225 | /* Link current page to tail of chain */ | ||
226 | *tail = (unsigned long)(void *) new + 1; | ||
227 | tail = new; | ||
228 | } | ||
229 | |||
230 | /* Allocate a new sample-data-block. | ||
231 | * If there is not enough memory, stop the realloc process | ||
232 | * and simply use what was allocated. If this is a temporary | ||
233 | * issue, a new realloc call (if required) might succeed. | ||
234 | */ | ||
235 | rc = alloc_sample_data_block(tail, gfp_flags); | ||
236 | if (rc) | ||
237 | break; | ||
238 | sfb->num_sdb++; | ||
239 | tail++; | ||
240 | } | ||
241 | |||
242 | /* Link sampling buffer to its origin */ | ||
243 | *tail = (unsigned long) sfb->sdbt + 1; | ||
244 | sfb->tail = tail; | ||
245 | |||
246 | debug_sprintf_event(sfdbg, 4, "realloc_sampling_buffer: new buffer" | ||
247 | " settings: sdbt=%lu sdb=%lu\n", | ||
248 | sfb->num_sdbt, sfb->num_sdb); | ||
249 | return rc; | ||
250 | } | ||
251 | |||
252 | /* | ||
253 | * allocate_sampling_buffer() - allocate sampler memory | ||
254 | * | ||
255 | * Allocates and initializes a sampling buffer structure using the | ||
256 | * specified number of sample-data-blocks (SDB). For each allocation, | ||
257 | * a 4K page is used. The number of sample-data-block-tables (SDBT) | ||
258 | * are calculated from SDBs. | ||
259 | * Also set the ALERT_REQ mask in each SDBs trailer. | ||
260 | * | ||
261 | * Returns zero on success, non-zero otherwise. | ||
262 | */ | ||
263 | static int alloc_sampling_buffer(struct sf_buffer *sfb, unsigned long num_sdb) | ||
264 | { | ||
265 | int rc; | ||
266 | |||
267 | if (sfb->sdbt) | ||
268 | return -EINVAL; | ||
269 | |||
270 | /* Allocate the sample-data-block-table origin */ | ||
271 | sfb->sdbt = (unsigned long *) get_zeroed_page(GFP_KERNEL); | ||
272 | if (!sfb->sdbt) | ||
273 | return -ENOMEM; | ||
274 | sfb->num_sdb = 0; | ||
275 | sfb->num_sdbt = 1; | ||
276 | |||
277 | /* Link the table origin to point to itself to prepare for | ||
278 | * realloc_sampling_buffer() invocation. | ||
279 | */ | ||
280 | sfb->tail = sfb->sdbt; | ||
281 | *sfb->tail = (unsigned long)(void *) sfb->sdbt + 1; | ||
282 | |||
283 | /* Allocate requested number of sample-data-blocks */ | ||
284 | rc = realloc_sampling_buffer(sfb, num_sdb, GFP_KERNEL); | ||
285 | if (rc) { | ||
286 | free_sampling_buffer(sfb); | ||
287 | debug_sprintf_event(sfdbg, 4, "alloc_sampling_buffer: " | ||
288 | "realloc_sampling_buffer failed with rc=%i\n", rc); | ||
289 | } else | ||
290 | debug_sprintf_event(sfdbg, 4, | ||
291 | "alloc_sampling_buffer: tear=%p dear=%p\n", | ||
292 | sfb->sdbt, (void *) *sfb->sdbt); | ||
293 | return rc; | ||
294 | } | ||
295 | |||
296 | static void sfb_set_limits(unsigned long min, unsigned long max) | ||
297 | { | ||
298 | struct hws_qsi_info_block si; | ||
299 | |||
300 | CPUM_SF_MIN_SDB = min; | ||
301 | CPUM_SF_MAX_SDB = max; | ||
302 | |||
303 | memset(&si, 0, sizeof(si)); | ||
304 | if (!qsi(&si)) | ||
305 | CPUM_SF_SDB_DIAG_FACTOR = DIV_ROUND_UP(si.dsdes, si.bsdes); | ||
306 | } | ||
307 | |||
308 | static unsigned long sfb_max_limit(struct hw_perf_event *hwc) | ||
309 | { | ||
310 | return SAMPL_DIAG_MODE(hwc) ? CPUM_SF_MAX_SDB * CPUM_SF_SDB_DIAG_FACTOR | ||
311 | : CPUM_SF_MAX_SDB; | ||
312 | } | ||
313 | |||
314 | static unsigned long sfb_pending_allocs(struct sf_buffer *sfb, | ||
315 | struct hw_perf_event *hwc) | ||
316 | { | ||
317 | if (!sfb->sdbt) | ||
318 | return SFB_ALLOC_REG(hwc); | ||
319 | if (SFB_ALLOC_REG(hwc) > sfb->num_sdb) | ||
320 | return SFB_ALLOC_REG(hwc) - sfb->num_sdb; | ||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | static int sfb_has_pending_allocs(struct sf_buffer *sfb, | ||
325 | struct hw_perf_event *hwc) | ||
326 | { | ||
327 | return sfb_pending_allocs(sfb, hwc) > 0; | ||
328 | } | ||
329 | |||
330 | static void sfb_account_allocs(unsigned long num, struct hw_perf_event *hwc) | ||
331 | { | ||
332 | /* Limit the number of SDBs to not exceed the maximum */ | ||
333 | num = min_t(unsigned long, num, sfb_max_limit(hwc) - SFB_ALLOC_REG(hwc)); | ||
334 | if (num) | ||
335 | SFB_ALLOC_REG(hwc) += num; | ||
336 | } | ||
337 | |||
338 | static void sfb_init_allocs(unsigned long num, struct hw_perf_event *hwc) | ||
339 | { | ||
340 | SFB_ALLOC_REG(hwc) = 0; | ||
341 | sfb_account_allocs(num, hwc); | ||
342 | } | ||
343 | |||
344 | static size_t event_sample_size(struct hw_perf_event *hwc) | ||
345 | { | ||
346 | struct sf_raw_sample *sfr = (struct sf_raw_sample *) RAWSAMPLE_REG(hwc); | ||
347 | size_t sample_size; | ||
348 | |||
349 | /* The sample size depends on the sampling function: The basic-sampling | ||
350 | * function must be always enabled, diagnostic-sampling function is | ||
351 | * optional. | ||
352 | */ | ||
353 | sample_size = sfr->bsdes; | ||
354 | if (SAMPL_DIAG_MODE(hwc)) | ||
355 | sample_size += sfr->dsdes; | ||
356 | |||
357 | return sample_size; | ||
358 | } | ||
359 | |||
360 | static void deallocate_buffers(struct cpu_hw_sf *cpuhw) | ||
361 | { | ||
362 | if (cpuhw->sfb.sdbt) | ||
363 | free_sampling_buffer(&cpuhw->sfb); | ||
364 | } | ||
365 | |||
366 | static int allocate_buffers(struct cpu_hw_sf *cpuhw, struct hw_perf_event *hwc) | ||
367 | { | ||
368 | unsigned long n_sdb, freq, factor; | ||
369 | size_t sfr_size, sample_size; | ||
370 | struct sf_raw_sample *sfr; | ||
371 | |||
372 | /* Allocate raw sample buffer | ||
373 | * | ||
374 | * The raw sample buffer is used to temporarily store sampling data | ||
375 | * entries for perf raw sample processing. The buffer size mainly | ||
376 | * depends on the size of diagnostic-sampling data entries which is | ||
377 | * machine-specific. The exact size calculation includes: | ||
378 | * 1. The first 4 bytes of diagnostic-sampling data entries are | ||
379 | * already reflected in the sf_raw_sample structure. Subtract | ||
380 | * these bytes. | ||
381 | * 2. The perf raw sample data must be 8-byte aligned (u64) and | ||
382 | * perf's internal data size must be considered too. So add | ||
383 | * an additional u32 for correct alignment and subtract before | ||
384 | * allocating the buffer. | ||
385 | * 3. Store the raw sample buffer pointer in the perf event | ||
386 | * hardware structure. | ||
387 | */ | ||
388 | sfr_size = ALIGN((sizeof(*sfr) - sizeof(sfr->diag) + cpuhw->qsi.dsdes) + | ||
389 | sizeof(u32), sizeof(u64)); | ||
390 | sfr_size -= sizeof(u32); | ||
391 | sfr = kzalloc(sfr_size, GFP_KERNEL); | ||
392 | if (!sfr) | ||
393 | return -ENOMEM; | ||
394 | sfr->size = sfr_size; | ||
395 | sfr->bsdes = cpuhw->qsi.bsdes; | ||
396 | sfr->dsdes = cpuhw->qsi.dsdes; | ||
397 | RAWSAMPLE_REG(hwc) = (unsigned long) sfr; | ||
398 | |||
399 | /* Calculate sampling buffers using 4K pages | ||
400 | * | ||
401 | * 1. Determine the sample data size which depends on the used | ||
402 | * sampling functions, for example, basic-sampling or | ||
403 | * basic-sampling with diagnostic-sampling. | ||
404 | * | ||
405 | * 2. Use the sampling frequency as input. The sampling buffer is | ||
406 | * designed for almost one second. This can be adjusted through | ||
407 | * the "factor" variable. | ||
408 | * In any case, alloc_sampling_buffer() sets the Alert Request | ||
409 | * Control indicator to trigger a measurement-alert to harvest | ||
410 | * sample-data-blocks (sdb). | ||
411 | * | ||
412 | * 3. Compute the number of sample-data-blocks and ensure a minimum | ||
413 | * of CPUM_SF_MIN_SDB. Also ensure the upper limit does not | ||
414 | * exceed a "calculated" maximum. The symbolic maximum is | ||
415 | * designed for basic-sampling only and needs to be increased if | ||
416 | * diagnostic-sampling is active. | ||
417 | * See also the remarks for these symbolic constants. | ||
418 | * | ||
419 | * 4. Compute the number of sample-data-block-tables (SDBT) and | ||
420 | * ensure a minimum of CPUM_SF_MIN_SDBT (one table can manage up | ||
421 | * to 511 SDBs). | ||
422 | */ | ||
423 | sample_size = event_sample_size(hwc); | ||
424 | freq = sample_rate_to_freq(&cpuhw->qsi, SAMPL_RATE(hwc)); | ||
425 | factor = 1; | ||
426 | n_sdb = DIV_ROUND_UP(freq, factor * ((PAGE_SIZE-64) / sample_size)); | ||
427 | if (n_sdb < CPUM_SF_MIN_SDB) | ||
428 | n_sdb = CPUM_SF_MIN_SDB; | ||
429 | |||
430 | /* If there is already a sampling buffer allocated, it is very likely | ||
431 | * that the sampling facility is enabled too. If the event to be | ||
432 | * initialized requires a greater sampling buffer, the allocation must | ||
433 | * be postponed. Changing the sampling buffer requires the sampling | ||
434 | * facility to be in the disabled state. So, account the number of | ||
435 | * required SDBs and let cpumsf_pmu_enable() resize the buffer just | ||
436 | * before the event is started. | ||
437 | */ | ||
438 | sfb_init_allocs(n_sdb, hwc); | ||
439 | if (sf_buffer_available(cpuhw)) | ||
440 | return 0; | ||
441 | |||
442 | debug_sprintf_event(sfdbg, 3, | ||
443 | "allocate_buffers: rate=%lu f=%lu sdb=%lu/%lu" | ||
444 | " sample_size=%lu cpuhw=%p\n", | ||
445 | SAMPL_RATE(hwc), freq, n_sdb, sfb_max_limit(hwc), | ||
446 | sample_size, cpuhw); | ||
447 | |||
448 | return alloc_sampling_buffer(&cpuhw->sfb, | ||
449 | sfb_pending_allocs(&cpuhw->sfb, hwc)); | ||
450 | } | ||
451 | |||
452 | static unsigned long min_percent(unsigned int percent, unsigned long base, | ||
453 | unsigned long min) | ||
454 | { | ||
455 | return min_t(unsigned long, min, DIV_ROUND_UP(percent * base, 100)); | ||
456 | } | ||
457 | |||
458 | static unsigned long compute_sfb_extent(unsigned long ratio, unsigned long base) | ||
459 | { | ||
460 | /* Use a percentage-based approach to extend the sampling facility | ||
461 | * buffer. Accept up to 5% sample data loss. | ||
462 | * Vary the extents between 1% to 5% of the current number of | ||
463 | * sample-data-blocks. | ||
464 | */ | ||
465 | if (ratio <= 5) | ||
466 | return 0; | ||
467 | if (ratio <= 25) | ||
468 | return min_percent(1, base, 1); | ||
469 | if (ratio <= 50) | ||
470 | return min_percent(1, base, 1); | ||
471 | if (ratio <= 75) | ||
472 | return min_percent(2, base, 2); | ||
473 | if (ratio <= 100) | ||
474 | return min_percent(3, base, 3); | ||
475 | if (ratio <= 250) | ||
476 | return min_percent(4, base, 4); | ||
477 | |||
478 | return min_percent(5, base, 8); | ||
479 | } | ||
480 | |||
481 | static void sfb_account_overflows(struct cpu_hw_sf *cpuhw, | ||
482 | struct hw_perf_event *hwc) | ||
483 | { | ||
484 | unsigned long ratio, num; | ||
485 | |||
486 | if (!OVERFLOW_REG(hwc)) | ||
487 | return; | ||
488 | |||
489 | /* The sample_overflow contains the average number of sample data | ||
490 | * that has been lost because sample-data-blocks were full. | ||
491 | * | ||
492 | * Calculate the total number of sample data entries that has been | ||
493 | * discarded. Then calculate the ratio of lost samples to total samples | ||
494 | * per second in percent. | ||
495 | */ | ||
496 | ratio = DIV_ROUND_UP(100 * OVERFLOW_REG(hwc) * cpuhw->sfb.num_sdb, | ||
497 | sample_rate_to_freq(&cpuhw->qsi, SAMPL_RATE(hwc))); | ||
498 | |||
499 | /* Compute number of sample-data-blocks */ | ||
500 | num = compute_sfb_extent(ratio, cpuhw->sfb.num_sdb); | ||
501 | if (num) | ||
502 | sfb_account_allocs(num, hwc); | ||
503 | |||
504 | debug_sprintf_event(sfdbg, 5, "sfb: overflow: overflow=%llu ratio=%lu" | ||
505 | " num=%lu\n", OVERFLOW_REG(hwc), ratio, num); | ||
506 | OVERFLOW_REG(hwc) = 0; | ||
507 | } | ||
508 | |||
509 | /* extend_sampling_buffer() - Extend sampling buffer | ||
510 | * @sfb: Sampling buffer structure (for local CPU) | ||
511 | * @hwc: Perf event hardware structure | ||
512 | * | ||
513 | * Use this function to extend the sampling buffer based on the overflow counter | ||
514 | * and postponed allocation extents stored in the specified Perf event hardware. | ||
515 | * | ||
516 | * Important: This function disables the sampling facility in order to safely | ||
517 | * change the sampling buffer structure. Do not call this function | ||
518 | * when the PMU is active. | ||
519 | */ | ||
520 | static void extend_sampling_buffer(struct sf_buffer *sfb, | ||
521 | struct hw_perf_event *hwc) | ||
522 | { | ||
523 | unsigned long num, num_old; | ||
524 | int rc; | ||
525 | |||
526 | num = sfb_pending_allocs(sfb, hwc); | ||
527 | if (!num) | ||
528 | return; | ||
529 | num_old = sfb->num_sdb; | ||
530 | |||
531 | /* Disable the sampling facility to reset any states and also | ||
532 | * clear pending measurement alerts. | ||
533 | */ | ||
534 | sf_disable(); | ||
535 | |||
536 | /* Extend the sampling buffer. | ||
537 | * This memory allocation typically happens in an atomic context when | ||
538 | * called by perf. Because this is a reallocation, it is fine if the | ||
539 | * new SDB-request cannot be satisfied immediately. | ||
540 | */ | ||
541 | rc = realloc_sampling_buffer(sfb, num, GFP_ATOMIC); | ||
542 | if (rc) | ||
543 | debug_sprintf_event(sfdbg, 5, "sfb: extend: realloc " | ||
544 | "failed with rc=%i\n", rc); | ||
545 | |||
546 | if (sfb_has_pending_allocs(sfb, hwc)) | ||
547 | debug_sprintf_event(sfdbg, 5, "sfb: extend: " | ||
548 | "req=%lu alloc=%lu remaining=%lu\n", | ||
549 | num, sfb->num_sdb - num_old, | ||
550 | sfb_pending_allocs(sfb, hwc)); | ||
551 | } | ||
552 | |||
553 | |||
554 | /* Number of perf events counting hardware events */ | ||
555 | static atomic_t num_events; | ||
556 | /* Used to avoid races in calling reserve/release_cpumf_hardware */ | ||
557 | static DEFINE_MUTEX(pmc_reserve_mutex); | ||
558 | |||
559 | #define PMC_INIT 0 | ||
560 | #define PMC_RELEASE 1 | ||
561 | #define PMC_FAILURE 2 | ||
562 | static void setup_pmc_cpu(void *flags) | ||
563 | { | ||
564 | int err; | ||
565 | struct cpu_hw_sf *cpusf = &__get_cpu_var(cpu_hw_sf); | ||
566 | |||
567 | err = 0; | ||
568 | switch (*((int *) flags)) { | ||
569 | case PMC_INIT: | ||
570 | memset(cpusf, 0, sizeof(*cpusf)); | ||
571 | err = qsi(&cpusf->qsi); | ||
572 | if (err) | ||
573 | break; | ||
574 | cpusf->flags |= PMU_F_RESERVED; | ||
575 | err = sf_disable(); | ||
576 | if (err) | ||
577 | pr_err("Switching off the sampling facility failed " | ||
578 | "with rc=%i\n", err); | ||
579 | debug_sprintf_event(sfdbg, 5, | ||
580 | "setup_pmc_cpu: initialized: cpuhw=%p\n", cpusf); | ||
581 | break; | ||
582 | case PMC_RELEASE: | ||
583 | cpusf->flags &= ~PMU_F_RESERVED; | ||
584 | err = sf_disable(); | ||
585 | if (err) { | ||
586 | pr_err("Switching off the sampling facility failed " | ||
587 | "with rc=%i\n", err); | ||
588 | } else | ||
589 | deallocate_buffers(cpusf); | ||
590 | debug_sprintf_event(sfdbg, 5, | ||
591 | "setup_pmc_cpu: released: cpuhw=%p\n", cpusf); | ||
592 | break; | ||
593 | } | ||
594 | if (err) | ||
595 | *((int *) flags) |= PMC_FAILURE; | ||
596 | } | ||
597 | |||
598 | static void release_pmc_hardware(void) | ||
599 | { | ||
600 | int flags = PMC_RELEASE; | ||
601 | |||
602 | irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); | ||
603 | on_each_cpu(setup_pmc_cpu, &flags, 1); | ||
604 | perf_release_sampling(); | ||
605 | } | ||
606 | |||
607 | static int reserve_pmc_hardware(void) | ||
608 | { | ||
609 | int flags = PMC_INIT; | ||
610 | int err; | ||
611 | |||
612 | err = perf_reserve_sampling(); | ||
613 | if (err) | ||
614 | return err; | ||
615 | on_each_cpu(setup_pmc_cpu, &flags, 1); | ||
616 | if (flags & PMC_FAILURE) { | ||
617 | release_pmc_hardware(); | ||
618 | return -ENODEV; | ||
619 | } | ||
620 | irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT); | ||
621 | |||
622 | return 0; | ||
623 | } | ||
624 | |||
625 | static void hw_perf_event_destroy(struct perf_event *event) | ||
626 | { | ||
627 | /* Free raw sample buffer */ | ||
628 | if (RAWSAMPLE_REG(&event->hw)) | ||
629 | kfree((void *) RAWSAMPLE_REG(&event->hw)); | ||
630 | |||
631 | /* Release PMC if this is the last perf event */ | ||
632 | if (!atomic_add_unless(&num_events, -1, 1)) { | ||
633 | mutex_lock(&pmc_reserve_mutex); | ||
634 | if (atomic_dec_return(&num_events) == 0) | ||
635 | release_pmc_hardware(); | ||
636 | mutex_unlock(&pmc_reserve_mutex); | ||
637 | } | ||
638 | } | ||
639 | |||
640 | static void hw_init_period(struct hw_perf_event *hwc, u64 period) | ||
641 | { | ||
642 | hwc->sample_period = period; | ||
643 | hwc->last_period = hwc->sample_period; | ||
644 | local64_set(&hwc->period_left, hwc->sample_period); | ||
645 | } | ||
646 | |||
647 | static void hw_reset_registers(struct hw_perf_event *hwc, | ||
648 | unsigned long *sdbt_origin) | ||
649 | { | ||
650 | struct sf_raw_sample *sfr; | ||
651 | |||
652 | /* (Re)set to first sample-data-block-table */ | ||
653 | TEAR_REG(hwc) = (unsigned long) sdbt_origin; | ||
654 | |||
655 | /* (Re)set raw sampling buffer register */ | ||
656 | sfr = (struct sf_raw_sample *) RAWSAMPLE_REG(hwc); | ||
657 | memset(&sfr->basic, 0, sizeof(sfr->basic)); | ||
658 | memset(&sfr->diag, 0, sfr->dsdes); | ||
659 | } | ||
660 | |||
661 | static unsigned long hw_limit_rate(const struct hws_qsi_info_block *si, | ||
662 | unsigned long rate) | ||
663 | { | ||
664 | return clamp_t(unsigned long, rate, | ||
665 | si->min_sampl_rate, si->max_sampl_rate); | ||
666 | } | ||
667 | |||
668 | static int __hw_perf_event_init(struct perf_event *event) | ||
669 | { | ||
670 | struct cpu_hw_sf *cpuhw; | ||
671 | struct hws_qsi_info_block si; | ||
672 | struct perf_event_attr *attr = &event->attr; | ||
673 | struct hw_perf_event *hwc = &event->hw; | ||
674 | unsigned long rate; | ||
675 | int cpu, err; | ||
676 | |||
677 | /* Reserve CPU-measurement sampling facility */ | ||
678 | err = 0; | ||
679 | if (!atomic_inc_not_zero(&num_events)) { | ||
680 | mutex_lock(&pmc_reserve_mutex); | ||
681 | if (atomic_read(&num_events) == 0 && reserve_pmc_hardware()) | ||
682 | err = -EBUSY; | ||
683 | else | ||
684 | atomic_inc(&num_events); | ||
685 | mutex_unlock(&pmc_reserve_mutex); | ||
686 | } | ||
687 | event->destroy = hw_perf_event_destroy; | ||
688 | |||
689 | if (err) | ||
690 | goto out; | ||
691 | |||
692 | /* Access per-CPU sampling information (query sampling info) */ | ||
693 | /* | ||
694 | * The event->cpu value can be -1 to count on every CPU, for example, | ||
695 | * when attaching to a task. If this is specified, use the query | ||
696 | * sampling info from the current CPU, otherwise use event->cpu to | ||
697 | * retrieve the per-CPU information. | ||
698 | * Later, cpuhw indicates whether to allocate sampling buffers for a | ||
699 | * particular CPU (cpuhw!=NULL) or each online CPU (cpuw==NULL). | ||
700 | */ | ||
701 | memset(&si, 0, sizeof(si)); | ||
702 | cpuhw = NULL; | ||
703 | if (event->cpu == -1) | ||
704 | qsi(&si); | ||
705 | else { | ||
706 | /* Event is pinned to a particular CPU, retrieve the per-CPU | ||
707 | * sampling structure for accessing the CPU-specific QSI. | ||
708 | */ | ||
709 | cpuhw = &per_cpu(cpu_hw_sf, event->cpu); | ||
710 | si = cpuhw->qsi; | ||
711 | } | ||
712 | |||
713 | /* Check sampling facility authorization and, if not authorized, | ||
714 | * fall back to other PMUs. It is safe to check any CPU because | ||
715 | * the authorization is identical for all configured CPUs. | ||
716 | */ | ||
717 | if (!si.as) { | ||
718 | err = -ENOENT; | ||
719 | goto out; | ||
720 | } | ||
721 | |||
722 | /* Always enable basic sampling */ | ||
723 | SAMPL_FLAGS(hwc) = PERF_CPUM_SF_BASIC_MODE; | ||
724 | |||
725 | /* Check if diagnostic sampling is requested. Deny if the required | ||
726 | * sampling authorization is missing. | ||
727 | */ | ||
728 | if (attr->config == PERF_EVENT_CPUM_SF_DIAG) { | ||
729 | if (!si.ad) { | ||
730 | err = -EPERM; | ||
731 | goto out; | ||
732 | } | ||
733 | SAMPL_FLAGS(hwc) |= PERF_CPUM_SF_DIAG_MODE; | ||
734 | } | ||
735 | |||
736 | /* Check and set other sampling flags */ | ||
737 | if (attr->config1 & PERF_CPUM_SF_FULL_BLOCKS) | ||
738 | SAMPL_FLAGS(hwc) |= PERF_CPUM_SF_FULL_BLOCKS; | ||
739 | |||
740 | /* The sampling information (si) contains information about the | ||
741 | * min/max sampling intervals and the CPU speed. So calculate the | ||
742 | * correct sampling interval and avoid the whole period adjust | ||
743 | * feedback loop. | ||
744 | */ | ||
745 | rate = 0; | ||
746 | if (attr->freq) { | ||
747 | rate = freq_to_sample_rate(&si, attr->sample_freq); | ||
748 | rate = hw_limit_rate(&si, rate); | ||
749 | attr->freq = 0; | ||
750 | attr->sample_period = rate; | ||
751 | } else { | ||
752 | /* The min/max sampling rates specifies the valid range | ||
753 | * of sample periods. If the specified sample period is | ||
754 | * out of range, limit the period to the range boundary. | ||
755 | */ | ||
756 | rate = hw_limit_rate(&si, hwc->sample_period); | ||
757 | |||
758 | /* The perf core maintains a maximum sample rate that is | ||
759 | * configurable through the sysctl interface. Ensure the | ||
760 | * sampling rate does not exceed this value. This also helps | ||
761 | * to avoid throttling when pushing samples with | ||
762 | * perf_event_overflow(). | ||
763 | */ | ||
764 | if (sample_rate_to_freq(&si, rate) > | ||
765 | sysctl_perf_event_sample_rate) { | ||
766 | err = -EINVAL; | ||
767 | debug_sprintf_event(sfdbg, 1, "Sampling rate exceeds maximum perf sample rate\n"); | ||
768 | goto out; | ||
769 | } | ||
770 | } | ||
771 | SAMPL_RATE(hwc) = rate; | ||
772 | hw_init_period(hwc, SAMPL_RATE(hwc)); | ||
773 | |||
774 | /* Initialize sample data overflow accounting */ | ||
775 | hwc->extra_reg.reg = REG_OVERFLOW; | ||
776 | OVERFLOW_REG(hwc) = 0; | ||
777 | |||
778 | /* Allocate the per-CPU sampling buffer using the CPU information | ||
779 | * from the event. If the event is not pinned to a particular | ||
780 | * CPU (event->cpu == -1; or cpuhw == NULL), allocate sampling | ||
781 | * buffers for each online CPU. | ||
782 | */ | ||
783 | if (cpuhw) | ||
784 | /* Event is pinned to a particular CPU */ | ||
785 | err = allocate_buffers(cpuhw, hwc); | ||
786 | else { | ||
787 | /* Event is not pinned, allocate sampling buffer on | ||
788 | * each online CPU | ||
789 | */ | ||
790 | for_each_online_cpu(cpu) { | ||
791 | cpuhw = &per_cpu(cpu_hw_sf, cpu); | ||
792 | err = allocate_buffers(cpuhw, hwc); | ||
793 | if (err) | ||
794 | break; | ||
795 | } | ||
796 | } | ||
797 | out: | ||
798 | return err; | ||
799 | } | ||
800 | |||
801 | static int cpumsf_pmu_event_init(struct perf_event *event) | ||
802 | { | ||
803 | int err; | ||
804 | |||
805 | /* No support for taken branch sampling */ | ||
806 | if (has_branch_stack(event)) | ||
807 | return -EOPNOTSUPP; | ||
808 | |||
809 | switch (event->attr.type) { | ||
810 | case PERF_TYPE_RAW: | ||
811 | if ((event->attr.config != PERF_EVENT_CPUM_SF) && | ||
812 | (event->attr.config != PERF_EVENT_CPUM_SF_DIAG)) | ||
813 | return -ENOENT; | ||
814 | break; | ||
815 | case PERF_TYPE_HARDWARE: | ||
816 | /* Support sampling of CPU cycles in addition to the | ||
817 | * counter facility. However, the counter facility | ||
818 | * is more precise and, hence, restrict this PMU to | ||
819 | * sampling events only. | ||
820 | */ | ||
821 | if (event->attr.config != PERF_COUNT_HW_CPU_CYCLES) | ||
822 | return -ENOENT; | ||
823 | if (!is_sampling_event(event)) | ||
824 | return -ENOENT; | ||
825 | break; | ||
826 | default: | ||
827 | return -ENOENT; | ||
828 | } | ||
829 | |||
830 | /* Check online status of the CPU to which the event is pinned */ | ||
831 | if (event->cpu >= nr_cpumask_bits || | ||
832 | (event->cpu >= 0 && !cpu_online(event->cpu))) | ||
833 | return -ENODEV; | ||
834 | |||
835 | /* Force reset of idle/hv excludes regardless of what the | ||
836 | * user requested. | ||
837 | */ | ||
838 | if (event->attr.exclude_hv) | ||
839 | event->attr.exclude_hv = 0; | ||
840 | if (event->attr.exclude_idle) | ||
841 | event->attr.exclude_idle = 0; | ||
842 | |||
843 | err = __hw_perf_event_init(event); | ||
844 | if (unlikely(err)) | ||
845 | if (event->destroy) | ||
846 | event->destroy(event); | ||
847 | return err; | ||
848 | } | ||
849 | |||
850 | static void cpumsf_pmu_enable(struct pmu *pmu) | ||
851 | { | ||
852 | struct cpu_hw_sf *cpuhw = &__get_cpu_var(cpu_hw_sf); | ||
853 | struct hw_perf_event *hwc; | ||
854 | int err; | ||
855 | |||
856 | if (cpuhw->flags & PMU_F_ENABLED) | ||
857 | return; | ||
858 | |||
859 | if (cpuhw->flags & PMU_F_ERR_MASK) | ||
860 | return; | ||
861 | |||
862 | /* Check whether to extent the sampling buffer. | ||
863 | * | ||
864 | * Two conditions trigger an increase of the sampling buffer for a | ||
865 | * perf event: | ||
866 | * 1. Postponed buffer allocations from the event initialization. | ||
867 | * 2. Sampling overflows that contribute to pending allocations. | ||
868 | * | ||
869 | * Note that the extend_sampling_buffer() function disables the sampling | ||
870 | * facility, but it can be fully re-enabled using sampling controls that | ||
871 | * have been saved in cpumsf_pmu_disable(). | ||
872 | */ | ||
873 | if (cpuhw->event) { | ||
874 | hwc = &cpuhw->event->hw; | ||
875 | /* Account number of overflow-designated buffer extents */ | ||
876 | sfb_account_overflows(cpuhw, hwc); | ||
877 | if (sfb_has_pending_allocs(&cpuhw->sfb, hwc)) | ||
878 | extend_sampling_buffer(&cpuhw->sfb, hwc); | ||
879 | } | ||
880 | |||
881 | /* (Re)enable the PMU and sampling facility */ | ||
882 | cpuhw->flags |= PMU_F_ENABLED; | ||
883 | barrier(); | ||
884 | |||
885 | err = lsctl(&cpuhw->lsctl); | ||
886 | if (err) { | ||
887 | cpuhw->flags &= ~PMU_F_ENABLED; | ||
888 | pr_err("Loading sampling controls failed: op=%i err=%i\n", | ||
889 | 1, err); | ||
890 | return; | ||
891 | } | ||
892 | |||
893 | debug_sprintf_event(sfdbg, 6, "pmu_enable: es=%i cs=%i ed=%i cd=%i " | ||
894 | "tear=%p dear=%p\n", cpuhw->lsctl.es, cpuhw->lsctl.cs, | ||
895 | cpuhw->lsctl.ed, cpuhw->lsctl.cd, | ||
896 | (void *) cpuhw->lsctl.tear, (void *) cpuhw->lsctl.dear); | ||
897 | } | ||
898 | |||
899 | static void cpumsf_pmu_disable(struct pmu *pmu) | ||
900 | { | ||
901 | struct cpu_hw_sf *cpuhw = &__get_cpu_var(cpu_hw_sf); | ||
902 | struct hws_lsctl_request_block inactive; | ||
903 | struct hws_qsi_info_block si; | ||
904 | int err; | ||
905 | |||
906 | if (!(cpuhw->flags & PMU_F_ENABLED)) | ||
907 | return; | ||
908 | |||
909 | if (cpuhw->flags & PMU_F_ERR_MASK) | ||
910 | return; | ||
911 | |||
912 | /* Switch off sampling activation control */ | ||
913 | inactive = cpuhw->lsctl; | ||
914 | inactive.cs = 0; | ||
915 | inactive.cd = 0; | ||
916 | |||
917 | err = lsctl(&inactive); | ||
918 | if (err) { | ||
919 | pr_err("Loading sampling controls failed: op=%i err=%i\n", | ||
920 | 2, err); | ||
921 | return; | ||
922 | } | ||
923 | |||
924 | /* Save state of TEAR and DEAR register contents */ | ||
925 | if (!qsi(&si)) { | ||
926 | /* TEAR/DEAR values are valid only if the sampling facility is | ||
927 | * enabled. Note that cpumsf_pmu_disable() might be called even | ||
928 | * for a disabled sampling facility because cpumsf_pmu_enable() | ||
929 | * controls the enable/disable state. | ||
930 | */ | ||
931 | if (si.es) { | ||
932 | cpuhw->lsctl.tear = si.tear; | ||
933 | cpuhw->lsctl.dear = si.dear; | ||
934 | } | ||
935 | } else | ||
936 | debug_sprintf_event(sfdbg, 3, "cpumsf_pmu_disable: " | ||
937 | "qsi() failed with err=%i\n", err); | ||
938 | |||
939 | cpuhw->flags &= ~PMU_F_ENABLED; | ||
940 | } | ||
941 | |||
942 | /* perf_exclude_event() - Filter event | ||
943 | * @event: The perf event | ||
944 | * @regs: pt_regs structure | ||
945 | * @sde_regs: Sample-data-entry (sde) regs structure | ||
946 | * | ||
947 | * Filter perf events according to their exclude specification. | ||
948 | * | ||
949 | * Return non-zero if the event shall be excluded. | ||
950 | */ | ||
951 | static int perf_exclude_event(struct perf_event *event, struct pt_regs *regs, | ||
952 | struct perf_sf_sde_regs *sde_regs) | ||
953 | { | ||
954 | if (event->attr.exclude_user && user_mode(regs)) | ||
955 | return 1; | ||
956 | if (event->attr.exclude_kernel && !user_mode(regs)) | ||
957 | return 1; | ||
958 | if (event->attr.exclude_guest && sde_regs->in_guest) | ||
959 | return 1; | ||
960 | if (event->attr.exclude_host && !sde_regs->in_guest) | ||
961 | return 1; | ||
962 | return 0; | ||
963 | } | ||
964 | |||
965 | /* perf_push_sample() - Push samples to perf | ||
966 | * @event: The perf event | ||
967 | * @sample: Hardware sample data | ||
968 | * | ||
969 | * Use the hardware sample data to create perf event sample. The sample | ||
970 | * is the pushed to the event subsystem and the function checks for | ||
971 | * possible event overflows. If an event overflow occurs, the PMU is | ||
972 | * stopped. | ||
973 | * | ||
974 | * Return non-zero if an event overflow occurred. | ||
975 | */ | ||
976 | static int perf_push_sample(struct perf_event *event, struct sf_raw_sample *sfr) | ||
977 | { | ||
978 | int overflow; | ||
979 | struct pt_regs regs; | ||
980 | struct perf_sf_sde_regs *sde_regs; | ||
981 | struct perf_sample_data data; | ||
982 | struct perf_raw_record raw; | ||
983 | |||
984 | /* Setup perf sample */ | ||
985 | perf_sample_data_init(&data, 0, event->hw.last_period); | ||
986 | raw.size = sfr->size; | ||
987 | raw.data = sfr; | ||
988 | data.raw = &raw; | ||
989 | |||
990 | /* Setup pt_regs to look like an CPU-measurement external interrupt | ||
991 | * using the Program Request Alert code. The regs.int_parm_long | ||
992 | * field which is unused contains additional sample-data-entry related | ||
993 | * indicators. | ||
994 | */ | ||
995 | memset(®s, 0, sizeof(regs)); | ||
996 | regs.int_code = 0x1407; | ||
997 | regs.int_parm = CPU_MF_INT_SF_PRA; | ||
998 | sde_regs = (struct perf_sf_sde_regs *) ®s.int_parm_long; | ||
999 | |||
1000 | regs.psw.addr = sfr->basic.ia; | ||
1001 | if (sfr->basic.T) | ||
1002 | regs.psw.mask |= PSW_MASK_DAT; | ||
1003 | if (sfr->basic.W) | ||
1004 | regs.psw.mask |= PSW_MASK_WAIT; | ||
1005 | if (sfr->basic.P) | ||
1006 | regs.psw.mask |= PSW_MASK_PSTATE; | ||
1007 | switch (sfr->basic.AS) { | ||
1008 | case 0x0: | ||
1009 | regs.psw.mask |= PSW_ASC_PRIMARY; | ||
1010 | break; | ||
1011 | case 0x1: | ||
1012 | regs.psw.mask |= PSW_ASC_ACCREG; | ||
1013 | break; | ||
1014 | case 0x2: | ||
1015 | regs.psw.mask |= PSW_ASC_SECONDARY; | ||
1016 | break; | ||
1017 | case 0x3: | ||
1018 | regs.psw.mask |= PSW_ASC_HOME; | ||
1019 | break; | ||
1020 | } | ||
1021 | |||
1022 | /* The host-program-parameter (hpp) contains the sie control | ||
1023 | * block that is set by sie64a() in entry64.S. Check if hpp | ||
1024 | * refers to a valid control block and set sde_regs flags | ||
1025 | * accordingly. This would allow to use hpp values for other | ||
1026 | * purposes too. | ||
1027 | * For now, simply use a non-zero value as guest indicator. | ||
1028 | */ | ||
1029 | if (sfr->basic.hpp) | ||
1030 | sde_regs->in_guest = 1; | ||
1031 | |||
1032 | overflow = 0; | ||
1033 | if (perf_exclude_event(event, ®s, sde_regs)) | ||
1034 | goto out; | ||
1035 | if (perf_event_overflow(event, &data, ®s)) { | ||
1036 | overflow = 1; | ||
1037 | event->pmu->stop(event, 0); | ||
1038 | } | ||
1039 | perf_event_update_userpage(event); | ||
1040 | out: | ||
1041 | return overflow; | ||
1042 | } | ||
1043 | |||
1044 | static void perf_event_count_update(struct perf_event *event, u64 count) | ||
1045 | { | ||
1046 | local64_add(count, &event->count); | ||
1047 | } | ||
1048 | |||
1049 | static int sample_format_is_valid(struct hws_combined_entry *sample, | ||
1050 | unsigned int flags) | ||
1051 | { | ||
1052 | if (likely(flags & PERF_CPUM_SF_BASIC_MODE)) | ||
1053 | /* Only basic-sampling data entries with data-entry-format | ||
1054 | * version of 0x0001 can be processed. | ||
1055 | */ | ||
1056 | if (sample->basic.def != 0x0001) | ||
1057 | return 0; | ||
1058 | if (flags & PERF_CPUM_SF_DIAG_MODE) | ||
1059 | /* The data-entry-format number of diagnostic-sampling data | ||
1060 | * entries can vary. Because diagnostic data is just passed | ||
1061 | * through, do only a sanity check on the DEF. | ||
1062 | */ | ||
1063 | if (sample->diag.def < 0x8001) | ||
1064 | return 0; | ||
1065 | return 1; | ||
1066 | } | ||
1067 | |||
1068 | static int sample_is_consistent(struct hws_combined_entry *sample, | ||
1069 | unsigned long flags) | ||
1070 | { | ||
1071 | /* This check applies only to basic-sampling data entries of potentially | ||
1072 | * combined-sampling data entries. Invalid entries cannot be processed | ||
1073 | * by the PMU and, thus, do not deliver an associated | ||
1074 | * diagnostic-sampling data entry. | ||
1075 | */ | ||
1076 | if (unlikely(!(flags & PERF_CPUM_SF_BASIC_MODE))) | ||
1077 | return 0; | ||
1078 | /* | ||
1079 | * Samples are skipped, if they are invalid or for which the | ||
1080 | * instruction address is not predictable, i.e., the wait-state bit is | ||
1081 | * set. | ||
1082 | */ | ||
1083 | if (sample->basic.I || sample->basic.W) | ||
1084 | return 0; | ||
1085 | return 1; | ||
1086 | } | ||
1087 | |||
1088 | static void reset_sample_slot(struct hws_combined_entry *sample, | ||
1089 | unsigned long flags) | ||
1090 | { | ||
1091 | if (likely(flags & PERF_CPUM_SF_BASIC_MODE)) | ||
1092 | sample->basic.def = 0; | ||
1093 | if (flags & PERF_CPUM_SF_DIAG_MODE) | ||
1094 | sample->diag.def = 0; | ||
1095 | } | ||
1096 | |||
1097 | static void sfr_store_sample(struct sf_raw_sample *sfr, | ||
1098 | struct hws_combined_entry *sample) | ||
1099 | { | ||
1100 | if (likely(sfr->format & PERF_CPUM_SF_BASIC_MODE)) | ||
1101 | sfr->basic = sample->basic; | ||
1102 | if (sfr->format & PERF_CPUM_SF_DIAG_MODE) | ||
1103 | memcpy(&sfr->diag, &sample->diag, sfr->dsdes); | ||
1104 | } | ||
1105 | |||
1106 | static void debug_sample_entry(struct hws_combined_entry *sample, | ||
1107 | struct hws_trailer_entry *te, | ||
1108 | unsigned long flags) | ||
1109 | { | ||
1110 | debug_sprintf_event(sfdbg, 4, "hw_collect_samples: Found unknown " | ||
1111 | "sampling data entry: te->f=%i basic.def=%04x (%p)" | ||
1112 | " diag.def=%04x (%p)\n", te->f, | ||
1113 | sample->basic.def, &sample->basic, | ||
1114 | (flags & PERF_CPUM_SF_DIAG_MODE) | ||
1115 | ? sample->diag.def : 0xFFFF, | ||
1116 | (flags & PERF_CPUM_SF_DIAG_MODE) | ||
1117 | ? &sample->diag : NULL); | ||
1118 | } | ||
1119 | |||
1120 | /* hw_collect_samples() - Walk through a sample-data-block and collect samples | ||
1121 | * @event: The perf event | ||
1122 | * @sdbt: Sample-data-block table | ||
1123 | * @overflow: Event overflow counter | ||
1124 | * | ||
1125 | * Walks through a sample-data-block and collects sampling data entries that are | ||
1126 | * then pushed to the perf event subsystem. Depending on the sampling function, | ||
1127 | * there can be either basic-sampling or combined-sampling data entries. A | ||
1128 | * combined-sampling data entry consists of a basic- and a diagnostic-sampling | ||
1129 | * data entry. The sampling function is determined by the flags in the perf | ||
1130 | * event hardware structure. The function always works with a combined-sampling | ||
1131 | * data entry but ignores the the diagnostic portion if it is not available. | ||
1132 | * | ||
1133 | * Note that the implementation focuses on basic-sampling data entries and, if | ||
1134 | * such an entry is not valid, the entire combined-sampling data entry is | ||
1135 | * ignored. | ||
1136 | * | ||
1137 | * The overflow variables counts the number of samples that has been discarded | ||
1138 | * due to a perf event overflow. | ||
1139 | */ | ||
1140 | static void hw_collect_samples(struct perf_event *event, unsigned long *sdbt, | ||
1141 | unsigned long long *overflow) | ||
1142 | { | ||
1143 | unsigned long flags = SAMPL_FLAGS(&event->hw); | ||
1144 | struct hws_combined_entry *sample; | ||
1145 | struct hws_trailer_entry *te; | ||
1146 | struct sf_raw_sample *sfr; | ||
1147 | size_t sample_size; | ||
1148 | |||
1149 | /* Prepare and initialize raw sample data */ | ||
1150 | sfr = (struct sf_raw_sample *) RAWSAMPLE_REG(&event->hw); | ||
1151 | sfr->format = flags & PERF_CPUM_SF_MODE_MASK; | ||
1152 | |||
1153 | sample_size = event_sample_size(&event->hw); | ||
1154 | te = (struct hws_trailer_entry *) trailer_entry_ptr(*sdbt); | ||
1155 | sample = (struct hws_combined_entry *) *sdbt; | ||
1156 | while ((unsigned long *) sample < (unsigned long *) te) { | ||
1157 | /* Check for an empty sample */ | ||
1158 | if (!sample->basic.def) | ||
1159 | break; | ||
1160 | |||
1161 | /* Update perf event period */ | ||
1162 | perf_event_count_update(event, SAMPL_RATE(&event->hw)); | ||
1163 | |||
1164 | /* Check sampling data entry */ | ||
1165 | if (sample_format_is_valid(sample, flags)) { | ||
1166 | /* If an event overflow occurred, the PMU is stopped to | ||
1167 | * throttle event delivery. Remaining sample data is | ||
1168 | * discarded. | ||
1169 | */ | ||
1170 | if (!*overflow) { | ||
1171 | if (sample_is_consistent(sample, flags)) { | ||
1172 | /* Deliver sample data to perf */ | ||
1173 | sfr_store_sample(sfr, sample); | ||
1174 | *overflow = perf_push_sample(event, sfr); | ||
1175 | } | ||
1176 | } else | ||
1177 | /* Count discarded samples */ | ||
1178 | *overflow += 1; | ||
1179 | } else { | ||
1180 | debug_sample_entry(sample, te, flags); | ||
1181 | /* Sample slot is not yet written or other record. | ||
1182 | * | ||
1183 | * This condition can occur if the buffer was reused | ||
1184 | * from a combined basic- and diagnostic-sampling. | ||
1185 | * If only basic-sampling is then active, entries are | ||
1186 | * written into the larger diagnostic entries. | ||
1187 | * This is typically the case for sample-data-blocks | ||
1188 | * that are not full. Stop processing if the first | ||
1189 | * invalid format was detected. | ||
1190 | */ | ||
1191 | if (!te->f) | ||
1192 | break; | ||
1193 | } | ||
1194 | |||
1195 | /* Reset sample slot and advance to next sample */ | ||
1196 | reset_sample_slot(sample, flags); | ||
1197 | sample += sample_size; | ||
1198 | } | ||
1199 | } | ||
1200 | |||
1201 | /* hw_perf_event_update() - Process sampling buffer | ||
1202 | * @event: The perf event | ||
1203 | * @flush_all: Flag to also flush partially filled sample-data-blocks | ||
1204 | * | ||
1205 | * Processes the sampling buffer and create perf event samples. | ||
1206 | * The sampling buffer position are retrieved and saved in the TEAR_REG | ||
1207 | * register of the specified perf event. | ||
1208 | * | ||
1209 | * Only full sample-data-blocks are processed. Specify the flash_all flag | ||
1210 | * to also walk through partially filled sample-data-blocks. It is ignored | ||
1211 | * if PERF_CPUM_SF_FULL_BLOCKS is set. The PERF_CPUM_SF_FULL_BLOCKS flag | ||
1212 | * enforces the processing of full sample-data-blocks only (trailer entries | ||
1213 | * with the block-full-indicator bit set). | ||
1214 | */ | ||
1215 | static void hw_perf_event_update(struct perf_event *event, int flush_all) | ||
1216 | { | ||
1217 | struct hw_perf_event *hwc = &event->hw; | ||
1218 | struct hws_trailer_entry *te; | ||
1219 | unsigned long *sdbt; | ||
1220 | unsigned long long event_overflow, sampl_overflow, num_sdb, te_flags; | ||
1221 | int done; | ||
1222 | |||
1223 | if (flush_all && SDB_FULL_BLOCKS(hwc)) | ||
1224 | flush_all = 0; | ||
1225 | |||
1226 | sdbt = (unsigned long *) TEAR_REG(hwc); | ||
1227 | done = event_overflow = sampl_overflow = num_sdb = 0; | ||
1228 | while (!done) { | ||
1229 | /* Get the trailer entry of the sample-data-block */ | ||
1230 | te = (struct hws_trailer_entry *) trailer_entry_ptr(*sdbt); | ||
1231 | |||
1232 | /* Leave loop if no more work to do (block full indicator) */ | ||
1233 | if (!te->f) { | ||
1234 | done = 1; | ||
1235 | if (!flush_all) | ||
1236 | break; | ||
1237 | } | ||
1238 | |||
1239 | /* Check the sample overflow count */ | ||
1240 | if (te->overflow) | ||
1241 | /* Account sample overflows and, if a particular limit | ||
1242 | * is reached, extend the sampling buffer. | ||
1243 | * For details, see sfb_account_overflows(). | ||
1244 | */ | ||
1245 | sampl_overflow += te->overflow; | ||
1246 | |||
1247 | /* Timestamps are valid for full sample-data-blocks only */ | ||
1248 | debug_sprintf_event(sfdbg, 6, "hw_perf_event_update: sdbt=%p " | ||
1249 | "overflow=%llu timestamp=0x%llx\n", | ||
1250 | sdbt, te->overflow, | ||
1251 | (te->f) ? trailer_timestamp(te) : 0ULL); | ||
1252 | |||
1253 | /* Collect all samples from a single sample-data-block and | ||
1254 | * flag if an (perf) event overflow happened. If so, the PMU | ||
1255 | * is stopped and remaining samples will be discarded. | ||
1256 | */ | ||
1257 | hw_collect_samples(event, sdbt, &event_overflow); | ||
1258 | num_sdb++; | ||
1259 | |||
1260 | /* Reset trailer (using compare-double-and-swap) */ | ||
1261 | do { | ||
1262 | te_flags = te->flags & ~SDB_TE_BUFFER_FULL_MASK; | ||
1263 | te_flags |= SDB_TE_ALERT_REQ_MASK; | ||
1264 | } while (!cmpxchg_double(&te->flags, &te->overflow, | ||
1265 | te->flags, te->overflow, | ||
1266 | te_flags, 0ULL)); | ||
1267 | |||
1268 | /* Advance to next sample-data-block */ | ||
1269 | sdbt++; | ||
1270 | if (is_link_entry(sdbt)) | ||
1271 | sdbt = get_next_sdbt(sdbt); | ||
1272 | |||
1273 | /* Update event hardware registers */ | ||
1274 | TEAR_REG(hwc) = (unsigned long) sdbt; | ||
1275 | |||
1276 | /* Stop processing sample-data if all samples of the current | ||
1277 | * sample-data-block were flushed even if it was not full. | ||
1278 | */ | ||
1279 | if (flush_all && done) | ||
1280 | break; | ||
1281 | |||
1282 | /* If an event overflow happened, discard samples by | ||
1283 | * processing any remaining sample-data-blocks. | ||
1284 | */ | ||
1285 | if (event_overflow) | ||
1286 | flush_all = 1; | ||
1287 | } | ||
1288 | |||
1289 | /* Account sample overflows in the event hardware structure */ | ||
1290 | if (sampl_overflow) | ||
1291 | OVERFLOW_REG(hwc) = DIV_ROUND_UP(OVERFLOW_REG(hwc) + | ||
1292 | sampl_overflow, 1 + num_sdb); | ||
1293 | if (sampl_overflow || event_overflow) | ||
1294 | debug_sprintf_event(sfdbg, 4, "hw_perf_event_update: " | ||
1295 | "overflow stats: sample=%llu event=%llu\n", | ||
1296 | sampl_overflow, event_overflow); | ||
1297 | } | ||
1298 | |||
1299 | static void cpumsf_pmu_read(struct perf_event *event) | ||
1300 | { | ||
1301 | /* Nothing to do ... updates are interrupt-driven */ | ||
1302 | } | ||
1303 | |||
1304 | /* Activate sampling control. | ||
1305 | * Next call of pmu_enable() starts sampling. | ||
1306 | */ | ||
1307 | static void cpumsf_pmu_start(struct perf_event *event, int flags) | ||
1308 | { | ||
1309 | struct cpu_hw_sf *cpuhw = &__get_cpu_var(cpu_hw_sf); | ||
1310 | |||
1311 | if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) | ||
1312 | return; | ||
1313 | |||
1314 | if (flags & PERF_EF_RELOAD) | ||
1315 | WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE)); | ||
1316 | |||
1317 | perf_pmu_disable(event->pmu); | ||
1318 | event->hw.state = 0; | ||
1319 | cpuhw->lsctl.cs = 1; | ||
1320 | if (SAMPL_DIAG_MODE(&event->hw)) | ||
1321 | cpuhw->lsctl.cd = 1; | ||
1322 | perf_pmu_enable(event->pmu); | ||
1323 | } | ||
1324 | |||
1325 | /* Deactivate sampling control. | ||
1326 | * Next call of pmu_enable() stops sampling. | ||
1327 | */ | ||
1328 | static void cpumsf_pmu_stop(struct perf_event *event, int flags) | ||
1329 | { | ||
1330 | struct cpu_hw_sf *cpuhw = &__get_cpu_var(cpu_hw_sf); | ||
1331 | |||
1332 | if (event->hw.state & PERF_HES_STOPPED) | ||
1333 | return; | ||
1334 | |||
1335 | perf_pmu_disable(event->pmu); | ||
1336 | cpuhw->lsctl.cs = 0; | ||
1337 | cpuhw->lsctl.cd = 0; | ||
1338 | event->hw.state |= PERF_HES_STOPPED; | ||
1339 | |||
1340 | if ((flags & PERF_EF_UPDATE) && !(event->hw.state & PERF_HES_UPTODATE)) { | ||
1341 | hw_perf_event_update(event, 1); | ||
1342 | event->hw.state |= PERF_HES_UPTODATE; | ||
1343 | } | ||
1344 | perf_pmu_enable(event->pmu); | ||
1345 | } | ||
1346 | |||
1347 | static int cpumsf_pmu_add(struct perf_event *event, int flags) | ||
1348 | { | ||
1349 | struct cpu_hw_sf *cpuhw = &__get_cpu_var(cpu_hw_sf); | ||
1350 | int err; | ||
1351 | |||
1352 | if (cpuhw->flags & PMU_F_IN_USE) | ||
1353 | return -EAGAIN; | ||
1354 | |||
1355 | if (!cpuhw->sfb.sdbt) | ||
1356 | return -EINVAL; | ||
1357 | |||
1358 | err = 0; | ||
1359 | perf_pmu_disable(event->pmu); | ||
1360 | |||
1361 | event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED; | ||
1362 | |||
1363 | /* Set up sampling controls. Always program the sampling register | ||
1364 | * using the SDB-table start. Reset TEAR_REG event hardware register | ||
1365 | * that is used by hw_perf_event_update() to store the sampling buffer | ||
1366 | * position after samples have been flushed. | ||
1367 | */ | ||
1368 | cpuhw->lsctl.s = 0; | ||
1369 | cpuhw->lsctl.h = 1; | ||
1370 | cpuhw->lsctl.tear = (unsigned long) cpuhw->sfb.sdbt; | ||
1371 | cpuhw->lsctl.dear = *(unsigned long *) cpuhw->sfb.sdbt; | ||
1372 | cpuhw->lsctl.interval = SAMPL_RATE(&event->hw); | ||
1373 | hw_reset_registers(&event->hw, cpuhw->sfb.sdbt); | ||
1374 | |||
1375 | /* Ensure sampling functions are in the disabled state. If disabled, | ||
1376 | * switch on sampling enable control. */ | ||
1377 | if (WARN_ON_ONCE(cpuhw->lsctl.es == 1 || cpuhw->lsctl.ed == 1)) { | ||
1378 | err = -EAGAIN; | ||
1379 | goto out; | ||
1380 | } | ||
1381 | cpuhw->lsctl.es = 1; | ||
1382 | if (SAMPL_DIAG_MODE(&event->hw)) | ||
1383 | cpuhw->lsctl.ed = 1; | ||
1384 | |||
1385 | /* Set in_use flag and store event */ | ||
1386 | event->hw.idx = 0; /* only one sampling event per CPU supported */ | ||
1387 | cpuhw->event = event; | ||
1388 | cpuhw->flags |= PMU_F_IN_USE; | ||
1389 | |||
1390 | if (flags & PERF_EF_START) | ||
1391 | cpumsf_pmu_start(event, PERF_EF_RELOAD); | ||
1392 | out: | ||
1393 | perf_event_update_userpage(event); | ||
1394 | perf_pmu_enable(event->pmu); | ||
1395 | return err; | ||
1396 | } | ||
1397 | |||
1398 | static void cpumsf_pmu_del(struct perf_event *event, int flags) | ||
1399 | { | ||
1400 | struct cpu_hw_sf *cpuhw = &__get_cpu_var(cpu_hw_sf); | ||
1401 | |||
1402 | perf_pmu_disable(event->pmu); | ||
1403 | cpumsf_pmu_stop(event, PERF_EF_UPDATE); | ||
1404 | |||
1405 | cpuhw->lsctl.es = 0; | ||
1406 | cpuhw->lsctl.ed = 0; | ||
1407 | cpuhw->flags &= ~PMU_F_IN_USE; | ||
1408 | cpuhw->event = NULL; | ||
1409 | |||
1410 | perf_event_update_userpage(event); | ||
1411 | perf_pmu_enable(event->pmu); | ||
1412 | } | ||
1413 | |||
1414 | static int cpumsf_pmu_event_idx(struct perf_event *event) | ||
1415 | { | ||
1416 | return event->hw.idx; | ||
1417 | } | ||
1418 | |||
1419 | CPUMF_EVENT_ATTR(SF, SF_CYCLES_BASIC, PERF_EVENT_CPUM_SF); | ||
1420 | CPUMF_EVENT_ATTR(SF, SF_CYCLES_BASIC_DIAG, PERF_EVENT_CPUM_SF_DIAG); | ||
1421 | |||
1422 | static struct attribute *cpumsf_pmu_events_attr[] = { | ||
1423 | CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC), | ||
1424 | CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC_DIAG), | ||
1425 | NULL, | ||
1426 | }; | ||
1427 | |||
1428 | PMU_FORMAT_ATTR(event, "config:0-63"); | ||
1429 | |||
1430 | static struct attribute *cpumsf_pmu_format_attr[] = { | ||
1431 | &format_attr_event.attr, | ||
1432 | NULL, | ||
1433 | }; | ||
1434 | |||
1435 | static struct attribute_group cpumsf_pmu_events_group = { | ||
1436 | .name = "events", | ||
1437 | .attrs = cpumsf_pmu_events_attr, | ||
1438 | }; | ||
1439 | static struct attribute_group cpumsf_pmu_format_group = { | ||
1440 | .name = "format", | ||
1441 | .attrs = cpumsf_pmu_format_attr, | ||
1442 | }; | ||
1443 | static const struct attribute_group *cpumsf_pmu_attr_groups[] = { | ||
1444 | &cpumsf_pmu_events_group, | ||
1445 | &cpumsf_pmu_format_group, | ||
1446 | NULL, | ||
1447 | }; | ||
1448 | |||
1449 | static struct pmu cpumf_sampling = { | ||
1450 | .pmu_enable = cpumsf_pmu_enable, | ||
1451 | .pmu_disable = cpumsf_pmu_disable, | ||
1452 | |||
1453 | .event_init = cpumsf_pmu_event_init, | ||
1454 | .add = cpumsf_pmu_add, | ||
1455 | .del = cpumsf_pmu_del, | ||
1456 | |||
1457 | .start = cpumsf_pmu_start, | ||
1458 | .stop = cpumsf_pmu_stop, | ||
1459 | .read = cpumsf_pmu_read, | ||
1460 | |||
1461 | .event_idx = cpumsf_pmu_event_idx, | ||
1462 | .attr_groups = cpumsf_pmu_attr_groups, | ||
1463 | }; | ||
1464 | |||
1465 | static void cpumf_measurement_alert(struct ext_code ext_code, | ||
1466 | unsigned int alert, unsigned long unused) | ||
1467 | { | ||
1468 | struct cpu_hw_sf *cpuhw; | ||
1469 | |||
1470 | if (!(alert & CPU_MF_INT_SF_MASK)) | ||
1471 | return; | ||
1472 | inc_irq_stat(IRQEXT_CMS); | ||
1473 | cpuhw = &__get_cpu_var(cpu_hw_sf); | ||
1474 | |||
1475 | /* Measurement alerts are shared and might happen when the PMU | ||
1476 | * is not reserved. Ignore these alerts in this case. */ | ||
1477 | if (!(cpuhw->flags & PMU_F_RESERVED)) | ||
1478 | return; | ||
1479 | |||
1480 | /* The processing below must take care of multiple alert events that | ||
1481 | * might be indicated concurrently. */ | ||
1482 | |||
1483 | /* Program alert request */ | ||
1484 | if (alert & CPU_MF_INT_SF_PRA) { | ||
1485 | if (cpuhw->flags & PMU_F_IN_USE) | ||
1486 | hw_perf_event_update(cpuhw->event, 0); | ||
1487 | else | ||
1488 | WARN_ON_ONCE(!(cpuhw->flags & PMU_F_IN_USE)); | ||
1489 | } | ||
1490 | |||
1491 | /* Report measurement alerts only for non-PRA codes */ | ||
1492 | if (alert != CPU_MF_INT_SF_PRA) | ||
1493 | debug_sprintf_event(sfdbg, 6, "measurement alert: 0x%x\n", alert); | ||
1494 | |||
1495 | /* Sampling authorization change request */ | ||
1496 | if (alert & CPU_MF_INT_SF_SACA) | ||
1497 | qsi(&cpuhw->qsi); | ||
1498 | |||
1499 | /* Loss of sample data due to high-priority machine activities */ | ||
1500 | if (alert & CPU_MF_INT_SF_LSDA) { | ||
1501 | pr_err("Sample data was lost\n"); | ||
1502 | cpuhw->flags |= PMU_F_ERR_LSDA; | ||
1503 | sf_disable(); | ||
1504 | } | ||
1505 | |||
1506 | /* Invalid sampling buffer entry */ | ||
1507 | if (alert & (CPU_MF_INT_SF_IAE|CPU_MF_INT_SF_ISE)) { | ||
1508 | pr_err("A sampling buffer entry is incorrect (alert=0x%x)\n", | ||
1509 | alert); | ||
1510 | cpuhw->flags |= PMU_F_ERR_IBE; | ||
1511 | sf_disable(); | ||
1512 | } | ||
1513 | } | ||
1514 | |||
1515 | static int cpumf_pmu_notifier(struct notifier_block *self, | ||
1516 | unsigned long action, void *hcpu) | ||
1517 | { | ||
1518 | unsigned int cpu = (long) hcpu; | ||
1519 | int flags; | ||
1520 | |||
1521 | /* Ignore the notification if no events are scheduled on the PMU. | ||
1522 | * This might be racy... | ||
1523 | */ | ||
1524 | if (!atomic_read(&num_events)) | ||
1525 | return NOTIFY_OK; | ||
1526 | |||
1527 | switch (action & ~CPU_TASKS_FROZEN) { | ||
1528 | case CPU_ONLINE: | ||
1529 | case CPU_ONLINE_FROZEN: | ||
1530 | flags = PMC_INIT; | ||
1531 | smp_call_function_single(cpu, setup_pmc_cpu, &flags, 1); | ||
1532 | break; | ||
1533 | case CPU_DOWN_PREPARE: | ||
1534 | flags = PMC_RELEASE; | ||
1535 | smp_call_function_single(cpu, setup_pmc_cpu, &flags, 1); | ||
1536 | break; | ||
1537 | default: | ||
1538 | break; | ||
1539 | } | ||
1540 | |||
1541 | return NOTIFY_OK; | ||
1542 | } | ||
1543 | |||
1544 | static int param_get_sfb_size(char *buffer, const struct kernel_param *kp) | ||
1545 | { | ||
1546 | if (!cpum_sf_avail()) | ||
1547 | return -ENODEV; | ||
1548 | return sprintf(buffer, "%lu,%lu", CPUM_SF_MIN_SDB, CPUM_SF_MAX_SDB); | ||
1549 | } | ||
1550 | |||
1551 | static int param_set_sfb_size(const char *val, const struct kernel_param *kp) | ||
1552 | { | ||
1553 | int rc; | ||
1554 | unsigned long min, max; | ||
1555 | |||
1556 | if (!cpum_sf_avail()) | ||
1557 | return -ENODEV; | ||
1558 | if (!val || !strlen(val)) | ||
1559 | return -EINVAL; | ||
1560 | |||
1561 | /* Valid parameter values: "min,max" or "max" */ | ||
1562 | min = CPUM_SF_MIN_SDB; | ||
1563 | max = CPUM_SF_MAX_SDB; | ||
1564 | if (strchr(val, ',')) | ||
1565 | rc = (sscanf(val, "%lu,%lu", &min, &max) == 2) ? 0 : -EINVAL; | ||
1566 | else | ||
1567 | rc = kstrtoul(val, 10, &max); | ||
1568 | |||
1569 | if (min < 2 || min >= max || max > get_num_physpages()) | ||
1570 | rc = -EINVAL; | ||
1571 | if (rc) | ||
1572 | return rc; | ||
1573 | |||
1574 | sfb_set_limits(min, max); | ||
1575 | pr_info("The sampling buffer limits have changed to: " | ||
1576 | "min=%lu max=%lu (diag=x%lu)\n", | ||
1577 | CPUM_SF_MIN_SDB, CPUM_SF_MAX_SDB, CPUM_SF_SDB_DIAG_FACTOR); | ||
1578 | return 0; | ||
1579 | } | ||
1580 | |||
1581 | #define param_check_sfb_size(name, p) __param_check(name, p, void) | ||
1582 | static struct kernel_param_ops param_ops_sfb_size = { | ||
1583 | .set = param_set_sfb_size, | ||
1584 | .get = param_get_sfb_size, | ||
1585 | }; | ||
1586 | |||
1587 | #define RS_INIT_FAILURE_QSI 0x0001 | ||
1588 | #define RS_INIT_FAILURE_BSDES 0x0002 | ||
1589 | #define RS_INIT_FAILURE_ALRT 0x0003 | ||
1590 | #define RS_INIT_FAILURE_PERF 0x0004 | ||
1591 | static void __init pr_cpumsf_err(unsigned int reason) | ||
1592 | { | ||
1593 | pr_err("Sampling facility support for perf is not available: " | ||
1594 | "reason=%04x\n", reason); | ||
1595 | } | ||
1596 | |||
1597 | static int __init init_cpum_sampling_pmu(void) | ||
1598 | { | ||
1599 | struct hws_qsi_info_block si; | ||
1600 | int err; | ||
1601 | |||
1602 | if (!cpum_sf_avail()) | ||
1603 | return -ENODEV; | ||
1604 | |||
1605 | memset(&si, 0, sizeof(si)); | ||
1606 | if (qsi(&si)) { | ||
1607 | pr_cpumsf_err(RS_INIT_FAILURE_QSI); | ||
1608 | return -ENODEV; | ||
1609 | } | ||
1610 | |||
1611 | if (si.bsdes != sizeof(struct hws_basic_entry)) { | ||
1612 | pr_cpumsf_err(RS_INIT_FAILURE_BSDES); | ||
1613 | return -EINVAL; | ||
1614 | } | ||
1615 | |||
1616 | if (si.ad) | ||
1617 | sfb_set_limits(CPUM_SF_MIN_SDB, CPUM_SF_MAX_SDB); | ||
1618 | |||
1619 | sfdbg = debug_register(KMSG_COMPONENT, 2, 1, 80); | ||
1620 | if (!sfdbg) | ||
1621 | pr_err("Registering for s390dbf failed\n"); | ||
1622 | debug_register_view(sfdbg, &debug_sprintf_view); | ||
1623 | |||
1624 | err = register_external_interrupt(0x1407, cpumf_measurement_alert); | ||
1625 | if (err) { | ||
1626 | pr_cpumsf_err(RS_INIT_FAILURE_ALRT); | ||
1627 | goto out; | ||
1628 | } | ||
1629 | |||
1630 | err = perf_pmu_register(&cpumf_sampling, "cpum_sf", PERF_TYPE_RAW); | ||
1631 | if (err) { | ||
1632 | pr_cpumsf_err(RS_INIT_FAILURE_PERF); | ||
1633 | unregister_external_interrupt(0x1407, cpumf_measurement_alert); | ||
1634 | goto out; | ||
1635 | } | ||
1636 | perf_cpu_notifier(cpumf_pmu_notifier); | ||
1637 | out: | ||
1638 | return err; | ||
1639 | } | ||
1640 | arch_initcall(init_cpum_sampling_pmu); | ||
1641 | core_param(cpum_sfb_size, CPUM_SF_MAX_SDB, sfb_size, 0640); | ||
diff --git a/arch/s390/kernel/perf_event.c b/arch/s390/kernel/perf_event.c index 2343c218b8f9..5d2dfa31c4ef 100644 --- a/arch/s390/kernel/perf_event.c +++ b/arch/s390/kernel/perf_event.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Performance event support for s390x | 2 | * Performance event support for s390x |
3 | * | 3 | * |
4 | * Copyright IBM Corp. 2012 | 4 | * Copyright IBM Corp. 2012, 2013 |
5 | * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com> | 5 | * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -16,15 +16,19 @@ | |||
16 | #include <linux/kvm_host.h> | 16 | #include <linux/kvm_host.h> |
17 | #include <linux/percpu.h> | 17 | #include <linux/percpu.h> |
18 | #include <linux/export.h> | 18 | #include <linux/export.h> |
19 | #include <linux/seq_file.h> | ||
20 | #include <linux/spinlock.h> | ||
21 | #include <linux/sysfs.h> | ||
19 | #include <asm/irq.h> | 22 | #include <asm/irq.h> |
20 | #include <asm/cpu_mf.h> | 23 | #include <asm/cpu_mf.h> |
21 | #include <asm/lowcore.h> | 24 | #include <asm/lowcore.h> |
22 | #include <asm/processor.h> | 25 | #include <asm/processor.h> |
26 | #include <asm/sysinfo.h> | ||
23 | 27 | ||
24 | const char *perf_pmu_name(void) | 28 | const char *perf_pmu_name(void) |
25 | { | 29 | { |
26 | if (cpum_cf_avail() || cpum_sf_avail()) | 30 | if (cpum_cf_avail() || cpum_sf_avail()) |
27 | return "CPU-measurement facilities (CPUMF)"; | 31 | return "CPU-Measurement Facilities (CPU-MF)"; |
28 | return "pmu"; | 32 | return "pmu"; |
29 | } | 33 | } |
30 | EXPORT_SYMBOL(perf_pmu_name); | 34 | EXPORT_SYMBOL(perf_pmu_name); |
@@ -35,6 +39,8 @@ int perf_num_counters(void) | |||
35 | 39 | ||
36 | if (cpum_cf_avail()) | 40 | if (cpum_cf_avail()) |
37 | num += PERF_CPUM_CF_MAX_CTR; | 41 | num += PERF_CPUM_CF_MAX_CTR; |
42 | if (cpum_sf_avail()) | ||
43 | num += PERF_CPUM_SF_MAX_CTR; | ||
38 | 44 | ||
39 | return num; | 45 | return num; |
40 | } | 46 | } |
@@ -54,7 +60,7 @@ static bool is_in_guest(struct pt_regs *regs) | |||
54 | { | 60 | { |
55 | if (user_mode(regs)) | 61 | if (user_mode(regs)) |
56 | return false; | 62 | return false; |
57 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) | 63 | #if IS_ENABLED(CONFIG_KVM) |
58 | return instruction_pointer(regs) == (unsigned long) &sie_exit; | 64 | return instruction_pointer(regs) == (unsigned long) &sie_exit; |
59 | #else | 65 | #else |
60 | return false; | 66 | return false; |
@@ -83,8 +89,31 @@ static unsigned long perf_misc_guest_flags(struct pt_regs *regs) | |||
83 | : PERF_RECORD_MISC_GUEST_KERNEL; | 89 | : PERF_RECORD_MISC_GUEST_KERNEL; |
84 | } | 90 | } |
85 | 91 | ||
92 | static unsigned long perf_misc_flags_sf(struct pt_regs *regs) | ||
93 | { | ||
94 | struct perf_sf_sde_regs *sde_regs; | ||
95 | unsigned long flags; | ||
96 | |||
97 | sde_regs = (struct perf_sf_sde_regs *) ®s->int_parm_long; | ||
98 | if (sde_regs->in_guest) | ||
99 | flags = user_mode(regs) ? PERF_RECORD_MISC_GUEST_USER | ||
100 | : PERF_RECORD_MISC_GUEST_KERNEL; | ||
101 | else | ||
102 | flags = user_mode(regs) ? PERF_RECORD_MISC_USER | ||
103 | : PERF_RECORD_MISC_KERNEL; | ||
104 | return flags; | ||
105 | } | ||
106 | |||
86 | unsigned long perf_misc_flags(struct pt_regs *regs) | 107 | unsigned long perf_misc_flags(struct pt_regs *regs) |
87 | { | 108 | { |
109 | /* Check if the cpum_sf PMU has created the pt_regs structure. | ||
110 | * In this case, perf misc flags can be easily extracted. Otherwise, | ||
111 | * do regular checks on the pt_regs content. | ||
112 | */ | ||
113 | if (regs->int_code == 0x1407 && regs->int_parm == CPU_MF_INT_SF_PRA) | ||
114 | if (!regs->gprs[15]) | ||
115 | return perf_misc_flags_sf(regs); | ||
116 | |||
88 | if (is_in_guest(regs)) | 117 | if (is_in_guest(regs)) |
89 | return perf_misc_guest_flags(regs); | 118 | return perf_misc_guest_flags(regs); |
90 | 119 | ||
@@ -92,27 +121,107 @@ unsigned long perf_misc_flags(struct pt_regs *regs) | |||
92 | : PERF_RECORD_MISC_KERNEL; | 121 | : PERF_RECORD_MISC_KERNEL; |
93 | } | 122 | } |
94 | 123 | ||
95 | void perf_event_print_debug(void) | 124 | void print_debug_cf(void) |
96 | { | 125 | { |
97 | struct cpumf_ctr_info cf_info; | 126 | struct cpumf_ctr_info cf_info; |
98 | unsigned long flags; | 127 | int cpu = smp_processor_id(); |
99 | int cpu; | ||
100 | |||
101 | if (!cpum_cf_avail()) | ||
102 | return; | ||
103 | |||
104 | local_irq_save(flags); | ||
105 | 128 | ||
106 | cpu = smp_processor_id(); | ||
107 | memset(&cf_info, 0, sizeof(cf_info)); | 129 | memset(&cf_info, 0, sizeof(cf_info)); |
108 | if (!qctri(&cf_info)) | 130 | if (!qctri(&cf_info)) |
109 | pr_info("CPU[%i] CPUM_CF: ver=%u.%u A=%04x E=%04x C=%04x\n", | 131 | pr_info("CPU[%i] CPUM_CF: ver=%u.%u A=%04x E=%04x C=%04x\n", |
110 | cpu, cf_info.cfvn, cf_info.csvn, | 132 | cpu, cf_info.cfvn, cf_info.csvn, |
111 | cf_info.auth_ctl, cf_info.enable_ctl, cf_info.act_ctl); | 133 | cf_info.auth_ctl, cf_info.enable_ctl, cf_info.act_ctl); |
134 | } | ||
135 | |||
136 | static void print_debug_sf(void) | ||
137 | { | ||
138 | struct hws_qsi_info_block si; | ||
139 | int cpu = smp_processor_id(); | ||
112 | 140 | ||
141 | memset(&si, 0, sizeof(si)); | ||
142 | if (qsi(&si)) | ||
143 | return; | ||
144 | |||
145 | pr_info("CPU[%i] CPUM_SF: basic=%i diag=%i min=%lu max=%lu cpu_speed=%u\n", | ||
146 | cpu, si.as, si.ad, si.min_sampl_rate, si.max_sampl_rate, | ||
147 | si.cpu_speed); | ||
148 | |||
149 | if (si.as) | ||
150 | pr_info("CPU[%i] CPUM_SF: Basic-sampling: a=%i e=%i c=%i" | ||
151 | " bsdes=%i tear=%016lx dear=%016lx\n", cpu, | ||
152 | si.as, si.es, si.cs, si.bsdes, si.tear, si.dear); | ||
153 | if (si.ad) | ||
154 | pr_info("CPU[%i] CPUM_SF: Diagnostic-sampling: a=%i e=%i c=%i" | ||
155 | " dsdes=%i tear=%016lx dear=%016lx\n", cpu, | ||
156 | si.ad, si.ed, si.cd, si.dsdes, si.tear, si.dear); | ||
157 | } | ||
158 | |||
159 | void perf_event_print_debug(void) | ||
160 | { | ||
161 | unsigned long flags; | ||
162 | |||
163 | local_irq_save(flags); | ||
164 | if (cpum_cf_avail()) | ||
165 | print_debug_cf(); | ||
166 | if (cpum_sf_avail()) | ||
167 | print_debug_sf(); | ||
113 | local_irq_restore(flags); | 168 | local_irq_restore(flags); |
114 | } | 169 | } |
115 | 170 | ||
171 | /* Service level infrastructure */ | ||
172 | static void sl_print_counter(struct seq_file *m) | ||
173 | { | ||
174 | struct cpumf_ctr_info ci; | ||
175 | |||
176 | memset(&ci, 0, sizeof(ci)); | ||
177 | if (qctri(&ci)) | ||
178 | return; | ||
179 | |||
180 | seq_printf(m, "CPU-MF: Counter facility: version=%u.%u " | ||
181 | "authorization=%04x\n", ci.cfvn, ci.csvn, ci.auth_ctl); | ||
182 | } | ||
183 | |||
184 | static void sl_print_sampling(struct seq_file *m) | ||
185 | { | ||
186 | struct hws_qsi_info_block si; | ||
187 | |||
188 | memset(&si, 0, sizeof(si)); | ||
189 | if (qsi(&si)) | ||
190 | return; | ||
191 | |||
192 | if (!si.as && !si.ad) | ||
193 | return; | ||
194 | |||
195 | seq_printf(m, "CPU-MF: Sampling facility: min_rate=%lu max_rate=%lu" | ||
196 | " cpu_speed=%u\n", si.min_sampl_rate, si.max_sampl_rate, | ||
197 | si.cpu_speed); | ||
198 | if (si.as) | ||
199 | seq_printf(m, "CPU-MF: Sampling facility: mode=basic" | ||
200 | " sample_size=%u\n", si.bsdes); | ||
201 | if (si.ad) | ||
202 | seq_printf(m, "CPU-MF: Sampling facility: mode=diagnostic" | ||
203 | " sample_size=%u\n", si.dsdes); | ||
204 | } | ||
205 | |||
206 | static void service_level_perf_print(struct seq_file *m, | ||
207 | struct service_level *sl) | ||
208 | { | ||
209 | if (cpum_cf_avail()) | ||
210 | sl_print_counter(m); | ||
211 | if (cpum_sf_avail()) | ||
212 | sl_print_sampling(m); | ||
213 | } | ||
214 | |||
215 | static struct service_level service_level_perf = { | ||
216 | .seq_print = service_level_perf_print, | ||
217 | }; | ||
218 | |||
219 | static int __init service_level_perf_register(void) | ||
220 | { | ||
221 | return register_service_level(&service_level_perf); | ||
222 | } | ||
223 | arch_initcall(service_level_perf_register); | ||
224 | |||
116 | /* See also arch/s390/kernel/traps.c */ | 225 | /* See also arch/s390/kernel/traps.c */ |
117 | static unsigned long __store_trace(struct perf_callchain_entry *entry, | 226 | static unsigned long __store_trace(struct perf_callchain_entry *entry, |
118 | unsigned long sp, | 227 | unsigned long sp, |
@@ -172,3 +281,44 @@ void perf_callchain_kernel(struct perf_callchain_entry *entry, | |||
172 | __store_trace(entry, head, S390_lowcore.thread_info, | 281 | __store_trace(entry, head, S390_lowcore.thread_info, |
173 | S390_lowcore.thread_info + THREAD_SIZE); | 282 | S390_lowcore.thread_info + THREAD_SIZE); |
174 | } | 283 | } |
284 | |||
285 | /* Perf defintions for PMU event attributes in sysfs */ | ||
286 | ssize_t cpumf_events_sysfs_show(struct device *dev, | ||
287 | struct device_attribute *attr, char *page) | ||
288 | { | ||
289 | struct perf_pmu_events_attr *pmu_attr; | ||
290 | |||
291 | pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr); | ||
292 | return sprintf(page, "event=0x%04llx,name=%s\n", | ||
293 | pmu_attr->id, attr->attr.name); | ||
294 | } | ||
295 | |||
296 | /* Reserve/release functions for sharing perf hardware */ | ||
297 | static DEFINE_SPINLOCK(perf_hw_owner_lock); | ||
298 | static void *perf_sampling_owner; | ||
299 | |||
300 | int perf_reserve_sampling(void) | ||
301 | { | ||
302 | int err; | ||
303 | |||
304 | err = 0; | ||
305 | spin_lock(&perf_hw_owner_lock); | ||
306 | if (perf_sampling_owner) { | ||
307 | pr_warn("The sampling facility is already reserved by %p\n", | ||
308 | perf_sampling_owner); | ||
309 | err = -EBUSY; | ||
310 | } else | ||
311 | perf_sampling_owner = __builtin_return_address(0); | ||
312 | spin_unlock(&perf_hw_owner_lock); | ||
313 | return err; | ||
314 | } | ||
315 | EXPORT_SYMBOL(perf_reserve_sampling); | ||
316 | |||
317 | void perf_release_sampling(void) | ||
318 | { | ||
319 | spin_lock(&perf_hw_owner_lock); | ||
320 | WARN_ON(!perf_sampling_owner); | ||
321 | perf_sampling_owner = NULL; | ||
322 | spin_unlock(&perf_hw_owner_lock); | ||
323 | } | ||
324 | EXPORT_SYMBOL(perf_release_sampling); | ||
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 7ed0d4e2a435..dd145321d215 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -261,20 +261,18 @@ static inline unsigned long brk_rnd(void) | |||
261 | 261 | ||
262 | unsigned long arch_randomize_brk(struct mm_struct *mm) | 262 | unsigned long arch_randomize_brk(struct mm_struct *mm) |
263 | { | 263 | { |
264 | unsigned long ret = PAGE_ALIGN(mm->brk + brk_rnd()); | 264 | unsigned long ret; |
265 | 265 | ||
266 | if (ret < mm->brk) | 266 | ret = PAGE_ALIGN(mm->brk + brk_rnd()); |
267 | return mm->brk; | 267 | return (ret > mm->brk) ? ret : mm->brk; |
268 | return ret; | ||
269 | } | 268 | } |
270 | 269 | ||
271 | unsigned long randomize_et_dyn(unsigned long base) | 270 | unsigned long randomize_et_dyn(unsigned long base) |
272 | { | 271 | { |
273 | unsigned long ret = PAGE_ALIGN(base + brk_rnd()); | 272 | unsigned long ret; |
274 | 273 | ||
275 | if (!(current->flags & PF_RANDOMIZE)) | 274 | if (!(current->flags & PF_RANDOMIZE)) |
276 | return base; | 275 | return base; |
277 | if (ret < base) | 276 | ret = PAGE_ALIGN(base + brk_rnd()); |
278 | return base; | 277 | return (ret > base) ? ret : base; |
279 | return ret; | ||
280 | } | 278 | } |
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index e65c91c591e8..f6be6087a0e9 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -56,25 +56,26 @@ void update_cr_regs(struct task_struct *task) | |||
56 | #ifdef CONFIG_64BIT | 56 | #ifdef CONFIG_64BIT |
57 | /* Take care of the enable/disable of transactional execution. */ | 57 | /* Take care of the enable/disable of transactional execution. */ |
58 | if (MACHINE_HAS_TE) { | 58 | if (MACHINE_HAS_TE) { |
59 | unsigned long cr[3], cr_new[3]; | 59 | unsigned long cr, cr_new; |
60 | 60 | ||
61 | __ctl_store(cr, 0, 2); | 61 | __ctl_store(cr, 0, 0); |
62 | cr_new[1] = cr[1]; | ||
63 | /* Set or clear transaction execution TXC bit 8. */ | 62 | /* Set or clear transaction execution TXC bit 8. */ |
63 | cr_new = cr | (1UL << 55); | ||
64 | if (task->thread.per_flags & PER_FLAG_NO_TE) | 64 | if (task->thread.per_flags & PER_FLAG_NO_TE) |
65 | cr_new[0] = cr[0] & ~(1UL << 55); | 65 | cr_new &= ~(1UL << 55); |
66 | else | 66 | if (cr_new != cr) |
67 | cr_new[0] = cr[0] | (1UL << 55); | 67 | __ctl_load(cr, 0, 0); |
68 | /* Set or clear transaction execution TDC bits 62 and 63. */ | 68 | /* Set or clear transaction execution TDC bits 62 and 63. */ |
69 | cr_new[2] = cr[2] & ~3UL; | 69 | __ctl_store(cr, 2, 2); |
70 | cr_new = cr & ~3UL; | ||
70 | if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND) { | 71 | if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND) { |
71 | if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND_TEND) | 72 | if (task->thread.per_flags & PER_FLAG_TE_ABORT_RAND_TEND) |
72 | cr_new[2] |= 1UL; | 73 | cr_new |= 1UL; |
73 | else | 74 | else |
74 | cr_new[2] |= 2UL; | 75 | cr_new |= 2UL; |
75 | } | 76 | } |
76 | if (memcmp(&cr_new, &cr, sizeof(cr))) | 77 | if (cr_new != cr) |
77 | __ctl_load(cr_new, 0, 2); | 78 | __ctl_load(cr_new, 2, 2); |
78 | } | 79 | } |
79 | #endif | 80 | #endif |
80 | /* Copy user specified PER registers */ | 81 | /* Copy user specified PER registers */ |
@@ -107,15 +108,11 @@ void update_cr_regs(struct task_struct *task) | |||
107 | void user_enable_single_step(struct task_struct *task) | 108 | void user_enable_single_step(struct task_struct *task) |
108 | { | 109 | { |
109 | set_tsk_thread_flag(task, TIF_SINGLE_STEP); | 110 | set_tsk_thread_flag(task, TIF_SINGLE_STEP); |
110 | if (task == current) | ||
111 | update_cr_regs(task); | ||
112 | } | 111 | } |
113 | 112 | ||
114 | void user_disable_single_step(struct task_struct *task) | 113 | void user_disable_single_step(struct task_struct *task) |
115 | { | 114 | { |
116 | clear_tsk_thread_flag(task, TIF_SINGLE_STEP); | 115 | clear_tsk_thread_flag(task, TIF_SINGLE_STEP); |
117 | if (task == current) | ||
118 | update_cr_regs(task); | ||
119 | } | 116 | } |
120 | 117 | ||
121 | /* | 118 | /* |
diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c index 3bac589844a7..9f60467938d1 100644 --- a/arch/s390/kernel/s390_ksyms.c +++ b/arch/s390/kernel/s390_ksyms.c | |||
@@ -5,7 +5,7 @@ | |||
5 | #ifdef CONFIG_FUNCTION_TRACER | 5 | #ifdef CONFIG_FUNCTION_TRACER |
6 | EXPORT_SYMBOL(_mcount); | 6 | EXPORT_SYMBOL(_mcount); |
7 | #endif | 7 | #endif |
8 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) | 8 | #if IS_ENABLED(CONFIG_KVM) |
9 | EXPORT_SYMBOL(sie64a); | 9 | EXPORT_SYMBOL(sie64a); |
10 | EXPORT_SYMBOL(sie_exit); | 10 | EXPORT_SYMBOL(sie_exit); |
11 | #endif | 11 | #endif |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 4444875266ee..09e2f468f48b 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -373,7 +373,7 @@ static void __init setup_lowcore(void) | |||
373 | 373 | ||
374 | /* | 374 | /* |
375 | * Set up PSW restart to call ipl.c:do_restart(). Copy the relevant | 375 | * Set up PSW restart to call ipl.c:do_restart(). Copy the relevant |
376 | * restart data to the absolute zero lowcore. This is necesary if | 376 | * restart data to the absolute zero lowcore. This is necessary if |
377 | * PSW restart is done on an offline CPU that has lowcore zero. | 377 | * PSW restart is done on an offline CPU that has lowcore zero. |
378 | */ | 378 | */ |
379 | lc->restart_stack = (unsigned long) restart_stack; | 379 | lc->restart_stack = (unsigned long) restart_stack; |
@@ -1023,6 +1023,7 @@ void __init setup_arch(char **cmdline_p) | |||
1023 | setup_vmcoreinfo(); | 1023 | setup_vmcoreinfo(); |
1024 | setup_lowcore(); | 1024 | setup_lowcore(); |
1025 | 1025 | ||
1026 | smp_fill_possible_mask(); | ||
1026 | cpu_init(); | 1027 | cpu_init(); |
1027 | s390_init_cpu_topology(); | 1028 | s390_init_cpu_topology(); |
1028 | 1029 | ||
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index dc4a53465060..a7125b62a9a6 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -59,7 +59,7 @@ enum { | |||
59 | }; | 59 | }; |
60 | 60 | ||
61 | struct pcpu { | 61 | struct pcpu { |
62 | struct cpu cpu; | 62 | struct cpu *cpu; |
63 | struct _lowcore *lowcore; /* lowcore page(s) for the cpu */ | 63 | struct _lowcore *lowcore; /* lowcore page(s) for the cpu */ |
64 | unsigned long async_stack; /* async stack for the cpu */ | 64 | unsigned long async_stack; /* async stack for the cpu */ |
65 | unsigned long panic_stack; /* panic stack for the cpu */ | 65 | unsigned long panic_stack; /* panic stack for the cpu */ |
@@ -159,9 +159,9 @@ static void pcpu_ec_call(struct pcpu *pcpu, int ec_bit) | |||
159 | { | 159 | { |
160 | int order; | 160 | int order; |
161 | 161 | ||
162 | set_bit(ec_bit, &pcpu->ec_mask); | 162 | if (test_and_set_bit(ec_bit, &pcpu->ec_mask)) |
163 | order = pcpu_running(pcpu) ? | 163 | return; |
164 | SIGP_EXTERNAL_CALL : SIGP_EMERGENCY_SIGNAL; | 164 | order = pcpu_running(pcpu) ? SIGP_EXTERNAL_CALL : SIGP_EMERGENCY_SIGNAL; |
165 | pcpu_sigp_retry(pcpu, order, 0); | 165 | pcpu_sigp_retry(pcpu, order, 0); |
166 | } | 166 | } |
167 | 167 | ||
@@ -721,18 +721,14 @@ int __cpu_up(unsigned int cpu, struct task_struct *tidle) | |||
721 | return 0; | 721 | return 0; |
722 | } | 722 | } |
723 | 723 | ||
724 | static int __init setup_possible_cpus(char *s) | 724 | static unsigned int setup_possible_cpus __initdata; |
725 | { | ||
726 | int max, cpu; | ||
727 | 725 | ||
728 | if (kstrtoint(s, 0, &max) < 0) | 726 | static int __init _setup_possible_cpus(char *s) |
729 | return 0; | 727 | { |
730 | init_cpu_possible(cpumask_of(0)); | 728 | get_option(&s, &setup_possible_cpus); |
731 | for (cpu = 1; cpu < max && cpu < nr_cpu_ids; cpu++) | ||
732 | set_cpu_possible(cpu, true); | ||
733 | return 0; | 729 | return 0; |
734 | } | 730 | } |
735 | early_param("possible_cpus", setup_possible_cpus); | 731 | early_param("possible_cpus", _setup_possible_cpus); |
736 | 732 | ||
737 | #ifdef CONFIG_HOTPLUG_CPU | 733 | #ifdef CONFIG_HOTPLUG_CPU |
738 | 734 | ||
@@ -775,6 +771,17 @@ void __noreturn cpu_die(void) | |||
775 | 771 | ||
776 | #endif /* CONFIG_HOTPLUG_CPU */ | 772 | #endif /* CONFIG_HOTPLUG_CPU */ |
777 | 773 | ||
774 | void __init smp_fill_possible_mask(void) | ||
775 | { | ||
776 | unsigned int possible, cpu; | ||
777 | |||
778 | possible = setup_possible_cpus; | ||
779 | if (!possible) | ||
780 | possible = MACHINE_IS_VM ? 64 : nr_cpu_ids; | ||
781 | for (cpu = 0; cpu < possible && cpu < nr_cpu_ids; cpu++) | ||
782 | set_cpu_possible(cpu, true); | ||
783 | } | ||
784 | |||
778 | void __init smp_prepare_cpus(unsigned int max_cpus) | 785 | void __init smp_prepare_cpus(unsigned int max_cpus) |
779 | { | 786 | { |
780 | /* request the 0x1201 emergency signal external interrupt */ | 787 | /* request the 0x1201 emergency signal external interrupt */ |
@@ -958,7 +965,7 @@ static int smp_cpu_notify(struct notifier_block *self, unsigned long action, | |||
958 | void *hcpu) | 965 | void *hcpu) |
959 | { | 966 | { |
960 | unsigned int cpu = (unsigned int)(long)hcpu; | 967 | unsigned int cpu = (unsigned int)(long)hcpu; |
961 | struct cpu *c = &pcpu_devices[cpu].cpu; | 968 | struct cpu *c = pcpu_devices[cpu].cpu; |
962 | struct device *s = &c->dev; | 969 | struct device *s = &c->dev; |
963 | int err = 0; | 970 | int err = 0; |
964 | 971 | ||
@@ -975,10 +982,15 @@ static int smp_cpu_notify(struct notifier_block *self, unsigned long action, | |||
975 | 982 | ||
976 | static int smp_add_present_cpu(int cpu) | 983 | static int smp_add_present_cpu(int cpu) |
977 | { | 984 | { |
978 | struct cpu *c = &pcpu_devices[cpu].cpu; | 985 | struct device *s; |
979 | struct device *s = &c->dev; | 986 | struct cpu *c; |
980 | int rc; | 987 | int rc; |
981 | 988 | ||
989 | c = kzalloc(sizeof(*c), GFP_KERNEL); | ||
990 | if (!c) | ||
991 | return -ENOMEM; | ||
992 | pcpu_devices[cpu].cpu = c; | ||
993 | s = &c->dev; | ||
982 | c->hotpluggable = 1; | 994 | c->hotpluggable = 1; |
983 | rc = register_cpu(c, cpu); | 995 | rc = register_cpu(c, cpu); |
984 | if (rc) | 996 | if (rc) |
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S index 913410bd74a3..143992152ec9 100644 --- a/arch/s390/kernel/syscalls.S +++ b/arch/s390/kernel/syscalls.S | |||
@@ -353,3 +353,5 @@ SYSCALL(sys_process_vm_writev,sys_process_vm_writev,compat_sys_process_vm_writev | |||
353 | SYSCALL(sys_ni_syscall,sys_s390_runtime_instr,sys_s390_runtime_instr_wrapper) | 353 | SYSCALL(sys_ni_syscall,sys_s390_runtime_instr,sys_s390_runtime_instr_wrapper) |
354 | SYSCALL(sys_kcmp,sys_kcmp,sys_kcmp_wrapper) | 354 | SYSCALL(sys_kcmp,sys_kcmp,sys_kcmp_wrapper) |
355 | SYSCALL(sys_finit_module,sys_finit_module,sys_finit_module_wrapper) | 355 | SYSCALL(sys_finit_module,sys_finit_module,sys_finit_module_wrapper) |
356 | SYSCALL(sys_sched_setattr,sys_sched_setattr,sys_sched_setattr_wrapper) /* 345 */ | ||
357 | SYSCALL(sys_sched_getattr,sys_sched_getattr,sys_sched_getattr_wrapper) | ||
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c index 78d967f180f4..8216c0e0b2e2 100644 --- a/arch/s390/kvm/diag.c +++ b/arch/s390/kvm/diag.c | |||
@@ -121,7 +121,7 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu) | |||
121 | * - gpr 4 contains the index on the bus (optionally) | 121 | * - gpr 4 contains the index on the bus (optionally) |
122 | */ | 122 | */ |
123 | ret = kvm_io_bus_write_cookie(vcpu->kvm, KVM_VIRTIO_CCW_NOTIFY_BUS, | 123 | ret = kvm_io_bus_write_cookie(vcpu->kvm, KVM_VIRTIO_CCW_NOTIFY_BUS, |
124 | vcpu->run->s.regs.gprs[2], | 124 | vcpu->run->s.regs.gprs[2] & 0xffffffff, |
125 | 8, &vcpu->run->s.regs.gprs[3], | 125 | 8, &vcpu->run->s.regs.gprs[3], |
126 | vcpu->run->s.regs.gprs[4]); | 126 | vcpu->run->s.regs.gprs[4]); |
127 | 127 | ||
@@ -137,7 +137,7 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu) | |||
137 | 137 | ||
138 | int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) | 138 | int kvm_s390_handle_diag(struct kvm_vcpu *vcpu) |
139 | { | 139 | { |
140 | int code = (vcpu->arch.sie_block->ipb & 0xfff0000) >> 16; | 140 | int code = kvm_s390_get_base_disp_rs(vcpu) & 0xffff; |
141 | 141 | ||
142 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) | 142 | if (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PSTATE) |
143 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); | 143 | return kvm_s390_inject_program_int(vcpu, PGM_PRIVILEGED_OP); |
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index 5ddbbde6f65c..eeb1ac7d8fa4 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c | |||
@@ -112,6 +112,17 @@ static int handle_instruction(struct kvm_vcpu *vcpu) | |||
112 | static int handle_prog(struct kvm_vcpu *vcpu) | 112 | static int handle_prog(struct kvm_vcpu *vcpu) |
113 | { | 113 | { |
114 | vcpu->stat.exit_program_interruption++; | 114 | vcpu->stat.exit_program_interruption++; |
115 | |||
116 | /* Restore ITDB to Program-Interruption TDB in guest memory */ | ||
117 | if (IS_TE_ENABLED(vcpu) && | ||
118 | !(current->thread.per_flags & PER_FLAG_NO_TE) && | ||
119 | IS_ITDB_VALID(vcpu)) { | ||
120 | copy_to_guest(vcpu, TDB_ADDR, vcpu->arch.sie_block->itdba, | ||
121 | sizeof(struct kvm_s390_itdb)); | ||
122 | memset((void *) vcpu->arch.sie_block->itdba, 0, | ||
123 | sizeof(struct kvm_s390_itdb)); | ||
124 | } | ||
125 | |||
115 | trace_kvm_s390_intercept_prog(vcpu, vcpu->arch.sie_block->iprcc); | 126 | trace_kvm_s390_intercept_prog(vcpu, vcpu->arch.sie_block->iprcc); |
116 | return kvm_s390_inject_program_int(vcpu, vcpu->arch.sie_block->iprcc); | 127 | return kvm_s390_inject_program_int(vcpu, vcpu->arch.sie_block->iprcc); |
117 | } | 128 | } |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 569494e01ec6..e0676f390d57 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -395,6 +395,9 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | |||
395 | CPUSTAT_STOPPED | | 395 | CPUSTAT_STOPPED | |
396 | CPUSTAT_GED); | 396 | CPUSTAT_GED); |
397 | vcpu->arch.sie_block->ecb = 6; | 397 | vcpu->arch.sie_block->ecb = 6; |
398 | if (test_vfacility(50) && test_vfacility(73)) | ||
399 | vcpu->arch.sie_block->ecb |= 0x10; | ||
400 | |||
398 | vcpu->arch.sie_block->ecb2 = 8; | 401 | vcpu->arch.sie_block->ecb2 = 8; |
399 | vcpu->arch.sie_block->eca = 0xC1002001U; | 402 | vcpu->arch.sie_block->eca = 0xC1002001U; |
400 | vcpu->arch.sie_block->fac = (int) (long) vfacilities; | 403 | vcpu->arch.sie_block->fac = (int) (long) vfacilities; |
@@ -411,6 +414,7 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, | |||
411 | unsigned int id) | 414 | unsigned int id) |
412 | { | 415 | { |
413 | struct kvm_vcpu *vcpu; | 416 | struct kvm_vcpu *vcpu; |
417 | struct sie_page *sie_page; | ||
414 | int rc = -EINVAL; | 418 | int rc = -EINVAL; |
415 | 419 | ||
416 | if (id >= KVM_MAX_VCPUS) | 420 | if (id >= KVM_MAX_VCPUS) |
@@ -422,12 +426,13 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, | |||
422 | if (!vcpu) | 426 | if (!vcpu) |
423 | goto out; | 427 | goto out; |
424 | 428 | ||
425 | vcpu->arch.sie_block = (struct kvm_s390_sie_block *) | 429 | sie_page = (struct sie_page *) get_zeroed_page(GFP_KERNEL); |
426 | get_zeroed_page(GFP_KERNEL); | 430 | if (!sie_page) |
427 | |||
428 | if (!vcpu->arch.sie_block) | ||
429 | goto out_free_cpu; | 431 | goto out_free_cpu; |
430 | 432 | ||
433 | vcpu->arch.sie_block = &sie_page->sie_block; | ||
434 | vcpu->arch.sie_block->itdba = (unsigned long) &sie_page->itdb; | ||
435 | |||
431 | vcpu->arch.sie_block->icpua = id; | 436 | vcpu->arch.sie_block->icpua = id; |
432 | if (!kvm_is_ucontrol(kvm)) { | 437 | if (!kvm_is_ucontrol(kvm)) { |
433 | if (!kvm->arch.sca) { | 438 | if (!kvm->arch.sca) { |
@@ -732,14 +737,16 @@ static int vcpu_post_run(struct kvm_vcpu *vcpu, int exit_reason) | |||
732 | 737 | ||
733 | if (exit_reason >= 0) { | 738 | if (exit_reason >= 0) { |
734 | rc = 0; | 739 | rc = 0; |
740 | } else if (kvm_is_ucontrol(vcpu->kvm)) { | ||
741 | vcpu->run->exit_reason = KVM_EXIT_S390_UCONTROL; | ||
742 | vcpu->run->s390_ucontrol.trans_exc_code = | ||
743 | current->thread.gmap_addr; | ||
744 | vcpu->run->s390_ucontrol.pgm_code = 0x10; | ||
745 | rc = -EREMOTE; | ||
735 | } else { | 746 | } else { |
736 | if (kvm_is_ucontrol(vcpu->kvm)) { | 747 | VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction"); |
737 | rc = SIE_INTERCEPT_UCONTROL; | 748 | trace_kvm_s390_sie_fault(vcpu); |
738 | } else { | 749 | rc = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); |
739 | VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction"); | ||
740 | trace_kvm_s390_sie_fault(vcpu); | ||
741 | rc = kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); | ||
742 | } | ||
743 | } | 750 | } |
744 | 751 | ||
745 | memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16); | 752 | memcpy(&vcpu->run->s.regs.gprs[14], &vcpu->arch.sie_block->gg14, 16); |
@@ -833,16 +840,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
833 | rc = -EINTR; | 840 | rc = -EINTR; |
834 | } | 841 | } |
835 | 842 | ||
836 | #ifdef CONFIG_KVM_S390_UCONTROL | ||
837 | if (rc == SIE_INTERCEPT_UCONTROL) { | ||
838 | kvm_run->exit_reason = KVM_EXIT_S390_UCONTROL; | ||
839 | kvm_run->s390_ucontrol.trans_exc_code = | ||
840 | current->thread.gmap_addr; | ||
841 | kvm_run->s390_ucontrol.pgm_code = 0x10; | ||
842 | rc = 0; | ||
843 | } | ||
844 | #endif | ||
845 | |||
846 | if (rc == -EOPNOTSUPP) { | 843 | if (rc == -EOPNOTSUPP) { |
847 | /* intercept cannot be handled in-kernel, prepare kvm-run */ | 844 | /* intercept cannot be handled in-kernel, prepare kvm-run */ |
848 | kvm_run->exit_reason = KVM_EXIT_S390_SIEIC; | 845 | kvm_run->exit_reason = KVM_EXIT_S390_SIEIC; |
@@ -885,10 +882,11 @@ static int __guestcopy(struct kvm_vcpu *vcpu, u64 guestdest, void *from, | |||
885 | * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit | 882 | * KVM_S390_STORE_STATUS_NOADDR: -> 0x1200 on 64 bit |
886 | * KVM_S390_STORE_STATUS_PREFIXED: -> prefix | 883 | * KVM_S390_STORE_STATUS_PREFIXED: -> prefix |
887 | */ | 884 | */ |
888 | int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr) | 885 | int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr) |
889 | { | 886 | { |
890 | unsigned char archmode = 1; | 887 | unsigned char archmode = 1; |
891 | int prefix; | 888 | int prefix; |
889 | u64 clkcomp; | ||
892 | 890 | ||
893 | if (addr == KVM_S390_STORE_STATUS_NOADDR) { | 891 | if (addr == KVM_S390_STORE_STATUS_NOADDR) { |
894 | if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1)) | 892 | if (copy_to_guest_absolute(vcpu, 163ul, &archmode, 1)) |
@@ -903,15 +901,6 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr) | |||
903 | } else | 901 | } else |
904 | prefix = 0; | 902 | prefix = 0; |
905 | 903 | ||
906 | /* | ||
907 | * The guest FPRS and ACRS are in the host FPRS/ACRS due to the lazy | ||
908 | * copying in vcpu load/put. Lets update our copies before we save | ||
909 | * it into the save area | ||
910 | */ | ||
911 | save_fp_ctl(&vcpu->arch.guest_fpregs.fpc); | ||
912 | save_fp_regs(vcpu->arch.guest_fpregs.fprs); | ||
913 | save_access_regs(vcpu->run->s.regs.acrs); | ||
914 | |||
915 | if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs), | 904 | if (__guestcopy(vcpu, addr + offsetof(struct save_area, fp_regs), |
916 | vcpu->arch.guest_fpregs.fprs, 128, prefix)) | 905 | vcpu->arch.guest_fpregs.fprs, 128, prefix)) |
917 | return -EFAULT; | 906 | return -EFAULT; |
@@ -941,8 +930,9 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr) | |||
941 | &vcpu->arch.sie_block->cputm, 8, prefix)) | 930 | &vcpu->arch.sie_block->cputm, 8, prefix)) |
942 | return -EFAULT; | 931 | return -EFAULT; |
943 | 932 | ||
933 | clkcomp = vcpu->arch.sie_block->ckc >> 8; | ||
944 | if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp), | 934 | if (__guestcopy(vcpu, addr + offsetof(struct save_area, clk_cmp), |
945 | &vcpu->arch.sie_block->ckc, 8, prefix)) | 935 | &clkcomp, 8, prefix)) |
946 | return -EFAULT; | 936 | return -EFAULT; |
947 | 937 | ||
948 | if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs), | 938 | if (__guestcopy(vcpu, addr + offsetof(struct save_area, acc_regs), |
@@ -956,6 +946,20 @@ int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr) | |||
956 | return 0; | 946 | return 0; |
957 | } | 947 | } |
958 | 948 | ||
949 | int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr) | ||
950 | { | ||
951 | /* | ||
952 | * The guest FPRS and ACRS are in the host FPRS/ACRS due to the lazy | ||
953 | * copying in vcpu load/put. Lets update our copies before we save | ||
954 | * it into the save area | ||
955 | */ | ||
956 | save_fp_ctl(&vcpu->arch.guest_fpregs.fpc); | ||
957 | save_fp_regs(vcpu->arch.guest_fpregs.fprs); | ||
958 | save_access_regs(vcpu->run->s.regs.acrs); | ||
959 | |||
960 | return kvm_s390_store_status_unloaded(vcpu, addr); | ||
961 | } | ||
962 | |||
959 | static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, | 963 | static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu, |
960 | struct kvm_enable_cap *cap) | 964 | struct kvm_enable_cap *cap) |
961 | { | 965 | { |
@@ -1183,8 +1187,8 @@ static int __init kvm_s390_init(void) | |||
1183 | return -ENOMEM; | 1187 | return -ENOMEM; |
1184 | } | 1188 | } |
1185 | memcpy(vfacilities, S390_lowcore.stfle_fac_list, 16); | 1189 | memcpy(vfacilities, S390_lowcore.stfle_fac_list, 16); |
1186 | vfacilities[0] &= 0xff82fff3f47c0000UL; | 1190 | vfacilities[0] &= 0xff82fff3f4fc2000UL; |
1187 | vfacilities[1] &= 0x001c000000000000UL; | 1191 | vfacilities[1] &= 0x005c000000000000UL; |
1188 | return 0; | 1192 | return 0; |
1189 | } | 1193 | } |
1190 | 1194 | ||
diff --git a/arch/s390/kvm/kvm-s390.h b/arch/s390/kvm/kvm-s390.h index b44912a32949..f9559b0bd620 100644 --- a/arch/s390/kvm/kvm-s390.h +++ b/arch/s390/kvm/kvm-s390.h | |||
@@ -19,18 +19,19 @@ | |||
19 | #include <linux/kvm.h> | 19 | #include <linux/kvm.h> |
20 | #include <linux/kvm_host.h> | 20 | #include <linux/kvm_host.h> |
21 | 21 | ||
22 | /* The current code can have up to 256 pages for virtio */ | ||
23 | #define VIRTIODESCSPACE (256ul * 4096ul) | ||
24 | |||
25 | typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu); | 22 | typedef int (*intercept_handler_t)(struct kvm_vcpu *vcpu); |
26 | 23 | ||
27 | /* declare vfacilities extern */ | 24 | /* declare vfacilities extern */ |
28 | extern unsigned long *vfacilities; | 25 | extern unsigned long *vfacilities; |
29 | 26 | ||
30 | /* negativ values are error codes, positive values for internal conditions */ | ||
31 | #define SIE_INTERCEPT_UCONTROL (1<<0) | ||
32 | int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu); | 27 | int kvm_handle_sie_intercept(struct kvm_vcpu *vcpu); |
33 | 28 | ||
29 | /* Transactional Memory Execution related macros */ | ||
30 | #define IS_TE_ENABLED(vcpu) ((vcpu->arch.sie_block->ecb & 0x10)) | ||
31 | #define TDB_ADDR 0x1800UL | ||
32 | #define TDB_FORMAT1 1 | ||
33 | #define IS_ITDB_VALID(vcpu) ((*(char *)vcpu->arch.sie_block->itdba == TDB_FORMAT1)) | ||
34 | |||
34 | #define VM_EVENT(d_kvm, d_loglevel, d_string, d_args...)\ | 35 | #define VM_EVENT(d_kvm, d_loglevel, d_string, d_args...)\ |
35 | do { \ | 36 | do { \ |
36 | debug_sprintf_event(d_kvm->arch.dbf, d_loglevel, d_string "\n", \ | 37 | debug_sprintf_event(d_kvm->arch.dbf, d_loglevel, d_string "\n", \ |
@@ -133,7 +134,6 @@ int __must_check kvm_s390_inject_vm(struct kvm *kvm, | |||
133 | int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, | 134 | int __must_check kvm_s390_inject_vcpu(struct kvm_vcpu *vcpu, |
134 | struct kvm_s390_interrupt *s390int); | 135 | struct kvm_s390_interrupt *s390int); |
135 | int __must_check kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); | 136 | int __must_check kvm_s390_inject_program_int(struct kvm_vcpu *vcpu, u16 code); |
136 | int __must_check kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action); | ||
137 | struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, | 137 | struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, |
138 | u64 cr6, u64 schid); | 138 | u64 cr6, u64 schid); |
139 | 139 | ||
@@ -150,8 +150,8 @@ int kvm_s390_handle_eb(struct kvm_vcpu *vcpu); | |||
150 | int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu); | 150 | int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu); |
151 | 151 | ||
152 | /* implemented in kvm-s390.c */ | 152 | /* implemented in kvm-s390.c */ |
153 | int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, | 153 | int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long addr); |
154 | unsigned long addr); | 154 | int kvm_s390_vcpu_store_status(struct kvm_vcpu *vcpu, unsigned long addr); |
155 | void s390_vcpu_block(struct kvm_vcpu *vcpu); | 155 | void s390_vcpu_block(struct kvm_vcpu *vcpu); |
156 | void s390_vcpu_unblock(struct kvm_vcpu *vcpu); | 156 | void s390_vcpu_unblock(struct kvm_vcpu *vcpu); |
157 | void exit_sie(struct kvm_vcpu *vcpu); | 157 | void exit_sie(struct kvm_vcpu *vcpu); |
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 2440602e6df1..75beea632a10 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c | |||
@@ -197,7 +197,7 @@ static int handle_tpi(struct kvm_vcpu *vcpu) | |||
197 | if (addr & 3) | 197 | if (addr & 3) |
198 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 198 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
199 | cc = 0; | 199 | cc = 0; |
200 | inti = kvm_s390_get_io_int(vcpu->kvm, vcpu->run->s.regs.crs[6], 0); | 200 | inti = kvm_s390_get_io_int(vcpu->kvm, vcpu->arch.sie_block->gcr[6], 0); |
201 | if (!inti) | 201 | if (!inti) |
202 | goto no_interrupt; | 202 | goto no_interrupt; |
203 | cc = 1; | 203 | cc = 1; |
@@ -275,7 +275,7 @@ static int handle_io_inst(struct kvm_vcpu *vcpu) | |||
275 | return -EOPNOTSUPP; | 275 | return -EOPNOTSUPP; |
276 | } else { | 276 | } else { |
277 | /* | 277 | /* |
278 | * Set condition code 3 to stop the guest from issueing channel | 278 | * Set condition code 3 to stop the guest from issuing channel |
279 | * I/O instructions. | 279 | * I/O instructions. |
280 | */ | 280 | */ |
281 | kvm_s390_set_psw_cc(vcpu, 3); | 281 | kvm_s390_set_psw_cc(vcpu, 3); |
@@ -638,7 +638,6 @@ static int handle_pfmf(struct kvm_vcpu *vcpu) | |||
638 | 638 | ||
639 | static const intercept_handler_t b9_handlers[256] = { | 639 | static const intercept_handler_t b9_handlers[256] = { |
640 | [0x8d] = handle_epsw, | 640 | [0x8d] = handle_epsw, |
641 | [0x9c] = handle_io_inst, | ||
642 | [0xaf] = handle_pfmf, | 641 | [0xaf] = handle_pfmf, |
643 | }; | 642 | }; |
644 | 643 | ||
@@ -731,7 +730,6 @@ static int handle_lctlg(struct kvm_vcpu *vcpu) | |||
731 | 730 | ||
732 | static const intercept_handler_t eb_handlers[256] = { | 731 | static const intercept_handler_t eb_handlers[256] = { |
733 | [0x2f] = handle_lctlg, | 732 | [0x2f] = handle_lctlg, |
734 | [0x8a] = handle_io_inst, | ||
735 | }; | 733 | }; |
736 | 734 | ||
737 | int kvm_s390_handle_eb(struct kvm_vcpu *vcpu) | 735 | int kvm_s390_handle_eb(struct kvm_vcpu *vcpu) |
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c index bec398c57acf..87c2b3a3bd3e 100644 --- a/arch/s390/kvm/sigp.c +++ b/arch/s390/kvm/sigp.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * handling interprocessor communication | 2 | * handling interprocessor communication |
3 | * | 3 | * |
4 | * Copyright IBM Corp. 2008, 2009 | 4 | * Copyright IBM Corp. 2008, 2013 |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License (version 2 only) | 7 | * it under the terms of the GNU General Public License (version 2 only) |
@@ -89,6 +89,37 @@ unlock: | |||
89 | return rc; | 89 | return rc; |
90 | } | 90 | } |
91 | 91 | ||
92 | static int __sigp_conditional_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr, | ||
93 | u16 asn, u64 *reg) | ||
94 | { | ||
95 | struct kvm_vcpu *dst_vcpu = NULL; | ||
96 | const u64 psw_int_mask = PSW_MASK_IO | PSW_MASK_EXT; | ||
97 | u16 p_asn, s_asn; | ||
98 | psw_t *psw; | ||
99 | u32 flags; | ||
100 | |||
101 | if (cpu_addr < KVM_MAX_VCPUS) | ||
102 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
103 | if (!dst_vcpu) | ||
104 | return SIGP_CC_NOT_OPERATIONAL; | ||
105 | flags = atomic_read(&dst_vcpu->arch.sie_block->cpuflags); | ||
106 | psw = &dst_vcpu->arch.sie_block->gpsw; | ||
107 | p_asn = dst_vcpu->arch.sie_block->gcr[4] & 0xffff; /* Primary ASN */ | ||
108 | s_asn = dst_vcpu->arch.sie_block->gcr[3] & 0xffff; /* Secondary ASN */ | ||
109 | |||
110 | /* Deliver the emergency signal? */ | ||
111 | if (!(flags & CPUSTAT_STOPPED) | ||
112 | || (psw->mask & psw_int_mask) != psw_int_mask | ||
113 | || ((flags & CPUSTAT_WAIT) && psw->addr != 0) | ||
114 | || (!(flags & CPUSTAT_WAIT) && (asn == p_asn || asn == s_asn))) { | ||
115 | return __sigp_emergency(vcpu, cpu_addr); | ||
116 | } else { | ||
117 | *reg &= 0xffffffff00000000UL; | ||
118 | *reg |= SIGP_STATUS_INCORRECT_STATE; | ||
119 | return SIGP_CC_STATUS_STORED; | ||
120 | } | ||
121 | } | ||
122 | |||
92 | static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr) | 123 | static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr) |
93 | { | 124 | { |
94 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; | 125 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; |
@@ -130,6 +161,7 @@ unlock: | |||
130 | static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action) | 161 | static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action) |
131 | { | 162 | { |
132 | struct kvm_s390_interrupt_info *inti; | 163 | struct kvm_s390_interrupt_info *inti; |
164 | int rc = SIGP_CC_ORDER_CODE_ACCEPTED; | ||
133 | 165 | ||
134 | inti = kzalloc(sizeof(*inti), GFP_ATOMIC); | 166 | inti = kzalloc(sizeof(*inti), GFP_ATOMIC); |
135 | if (!inti) | 167 | if (!inti) |
@@ -139,6 +171,8 @@ static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action) | |||
139 | spin_lock_bh(&li->lock); | 171 | spin_lock_bh(&li->lock); |
140 | if ((atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) { | 172 | if ((atomic_read(li->cpuflags) & CPUSTAT_STOPPED)) { |
141 | kfree(inti); | 173 | kfree(inti); |
174 | if ((action & ACTION_STORE_ON_STOP) != 0) | ||
175 | rc = -ESHUTDOWN; | ||
142 | goto out; | 176 | goto out; |
143 | } | 177 | } |
144 | list_add_tail(&inti->list, &li->list); | 178 | list_add_tail(&inti->list, &li->list); |
@@ -150,7 +184,7 @@ static int __inject_sigp_stop(struct kvm_s390_local_interrupt *li, int action) | |||
150 | out: | 184 | out: |
151 | spin_unlock_bh(&li->lock); | 185 | spin_unlock_bh(&li->lock); |
152 | 186 | ||
153 | return SIGP_CC_ORDER_CODE_ACCEPTED; | 187 | return rc; |
154 | } | 188 | } |
155 | 189 | ||
156 | static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action) | 190 | static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action) |
@@ -174,13 +208,17 @@ static int __sigp_stop(struct kvm_vcpu *vcpu, u16 cpu_addr, int action) | |||
174 | unlock: | 208 | unlock: |
175 | spin_unlock(&fi->lock); | 209 | spin_unlock(&fi->lock); |
176 | VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", cpu_addr); | 210 | VCPU_EVENT(vcpu, 4, "sent sigp stop to cpu %x", cpu_addr); |
177 | return rc; | ||
178 | } | ||
179 | 211 | ||
180 | int kvm_s390_inject_sigp_stop(struct kvm_vcpu *vcpu, int action) | 212 | if ((action & ACTION_STORE_ON_STOP) != 0 && rc == -ESHUTDOWN) { |
181 | { | 213 | /* If the CPU has already been stopped, we still have |
182 | struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int; | 214 | * to save the status when doing stop-and-store. This |
183 | return __inject_sigp_stop(li, action); | 215 | * has to be done after unlocking all spinlocks. */ |
216 | struct kvm_vcpu *dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr); | ||
217 | rc = kvm_s390_store_status_unloaded(dst_vcpu, | ||
218 | KVM_S390_STORE_STATUS_NOADDR); | ||
219 | } | ||
220 | |||
221 | return rc; | ||
184 | } | 222 | } |
185 | 223 | ||
186 | static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter) | 224 | static int __sigp_set_arch(struct kvm_vcpu *vcpu, u32 parameter) |
@@ -262,6 +300,37 @@ out_fi: | |||
262 | return rc; | 300 | return rc; |
263 | } | 301 | } |
264 | 302 | ||
303 | static int __sigp_store_status_at_addr(struct kvm_vcpu *vcpu, u16 cpu_id, | ||
304 | u32 addr, u64 *reg) | ||
305 | { | ||
306 | struct kvm_vcpu *dst_vcpu = NULL; | ||
307 | int flags; | ||
308 | int rc; | ||
309 | |||
310 | if (cpu_id < KVM_MAX_VCPUS) | ||
311 | dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_id); | ||
312 | if (!dst_vcpu) | ||
313 | return SIGP_CC_NOT_OPERATIONAL; | ||
314 | |||
315 | spin_lock_bh(&dst_vcpu->arch.local_int.lock); | ||
316 | flags = atomic_read(dst_vcpu->arch.local_int.cpuflags); | ||
317 | spin_unlock_bh(&dst_vcpu->arch.local_int.lock); | ||
318 | if (!(flags & CPUSTAT_STOPPED)) { | ||
319 | *reg &= 0xffffffff00000000UL; | ||
320 | *reg |= SIGP_STATUS_INCORRECT_STATE; | ||
321 | return SIGP_CC_STATUS_STORED; | ||
322 | } | ||
323 | |||
324 | addr &= 0x7ffffe00; | ||
325 | rc = kvm_s390_store_status_unloaded(dst_vcpu, addr); | ||
326 | if (rc == -EFAULT) { | ||
327 | *reg &= 0xffffffff00000000UL; | ||
328 | *reg |= SIGP_STATUS_INVALID_PARAMETER; | ||
329 | rc = SIGP_CC_STATUS_STORED; | ||
330 | } | ||
331 | return rc; | ||
332 | } | ||
333 | |||
265 | static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr, | 334 | static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr, |
266 | u64 *reg) | 335 | u64 *reg) |
267 | { | 336 | { |
@@ -294,7 +363,8 @@ static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr, | |||
294 | return rc; | 363 | return rc; |
295 | } | 364 | } |
296 | 365 | ||
297 | static int __sigp_restart(struct kvm_vcpu *vcpu, u16 cpu_addr) | 366 | /* Test whether the destination CPU is available and not busy */ |
367 | static int sigp_check_callable(struct kvm_vcpu *vcpu, u16 cpu_addr) | ||
298 | { | 368 | { |
299 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; | 369 | struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; |
300 | struct kvm_s390_local_interrupt *li; | 370 | struct kvm_s390_local_interrupt *li; |
@@ -313,9 +383,6 @@ static int __sigp_restart(struct kvm_vcpu *vcpu, u16 cpu_addr) | |||
313 | spin_lock_bh(&li->lock); | 383 | spin_lock_bh(&li->lock); |
314 | if (li->action_bits & ACTION_STOP_ON_STOP) | 384 | if (li->action_bits & ACTION_STOP_ON_STOP) |
315 | rc = SIGP_CC_BUSY; | 385 | rc = SIGP_CC_BUSY; |
316 | else | ||
317 | VCPU_EVENT(vcpu, 4, "sigp restart %x to handle userspace", | ||
318 | cpu_addr); | ||
319 | spin_unlock_bh(&li->lock); | 386 | spin_unlock_bh(&li->lock); |
320 | out: | 387 | out: |
321 | spin_unlock(&fi->lock); | 388 | spin_unlock(&fi->lock); |
@@ -366,6 +433,10 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) | |||
366 | rc = __sigp_stop(vcpu, cpu_addr, ACTION_STORE_ON_STOP | | 433 | rc = __sigp_stop(vcpu, cpu_addr, ACTION_STORE_ON_STOP | |
367 | ACTION_STOP_ON_STOP); | 434 | ACTION_STOP_ON_STOP); |
368 | break; | 435 | break; |
436 | case SIGP_STORE_STATUS_AT_ADDRESS: | ||
437 | rc = __sigp_store_status_at_addr(vcpu, cpu_addr, parameter, | ||
438 | &vcpu->run->s.regs.gprs[r1]); | ||
439 | break; | ||
369 | case SIGP_SET_ARCHITECTURE: | 440 | case SIGP_SET_ARCHITECTURE: |
370 | vcpu->stat.instruction_sigp_arch++; | 441 | vcpu->stat.instruction_sigp_arch++; |
371 | rc = __sigp_set_arch(vcpu, parameter); | 442 | rc = __sigp_set_arch(vcpu, parameter); |
@@ -375,17 +446,31 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) | |||
375 | rc = __sigp_set_prefix(vcpu, cpu_addr, parameter, | 446 | rc = __sigp_set_prefix(vcpu, cpu_addr, parameter, |
376 | &vcpu->run->s.regs.gprs[r1]); | 447 | &vcpu->run->s.regs.gprs[r1]); |
377 | break; | 448 | break; |
449 | case SIGP_COND_EMERGENCY_SIGNAL: | ||
450 | rc = __sigp_conditional_emergency(vcpu, cpu_addr, parameter, | ||
451 | &vcpu->run->s.regs.gprs[r1]); | ||
452 | break; | ||
378 | case SIGP_SENSE_RUNNING: | 453 | case SIGP_SENSE_RUNNING: |
379 | vcpu->stat.instruction_sigp_sense_running++; | 454 | vcpu->stat.instruction_sigp_sense_running++; |
380 | rc = __sigp_sense_running(vcpu, cpu_addr, | 455 | rc = __sigp_sense_running(vcpu, cpu_addr, |
381 | &vcpu->run->s.regs.gprs[r1]); | 456 | &vcpu->run->s.regs.gprs[r1]); |
382 | break; | 457 | break; |
458 | case SIGP_START: | ||
459 | rc = sigp_check_callable(vcpu, cpu_addr); | ||
460 | if (rc == SIGP_CC_ORDER_CODE_ACCEPTED) | ||
461 | rc = -EOPNOTSUPP; /* Handle START in user space */ | ||
462 | break; | ||
383 | case SIGP_RESTART: | 463 | case SIGP_RESTART: |
384 | vcpu->stat.instruction_sigp_restart++; | 464 | vcpu->stat.instruction_sigp_restart++; |
385 | rc = __sigp_restart(vcpu, cpu_addr); | 465 | rc = sigp_check_callable(vcpu, cpu_addr); |
386 | if (rc == SIGP_CC_BUSY) | 466 | if (rc == SIGP_CC_ORDER_CODE_ACCEPTED) { |
387 | break; | 467 | VCPU_EVENT(vcpu, 4, |
388 | /* user space must know about restart */ | 468 | "sigp restart %x to handle userspace", |
469 | cpu_addr); | ||
470 | /* user space must know about restart */ | ||
471 | rc = -EOPNOTSUPP; | ||
472 | } | ||
473 | break; | ||
389 | default: | 474 | default: |
390 | return -EOPNOTSUPP; | 475 | return -EOPNOTSUPP; |
391 | } | 476 | } |
@@ -393,7 +478,6 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu) | |||
393 | if (rc < 0) | 478 | if (rc < 0) |
394 | return rc; | 479 | return rc; |
395 | 480 | ||
396 | vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44); | 481 | kvm_s390_set_psw_cc(vcpu, rc); |
397 | vcpu->arch.sie_block->gpsw.mask |= (rc & 3ul) << 44; | ||
398 | return 0; | 482 | return 0; |
399 | } | 483 | } |
diff --git a/arch/s390/kvm/trace.h b/arch/s390/kvm/trace.h index 0c991c6748ab..3db76b2daed7 100644 --- a/arch/s390/kvm/trace.h +++ b/arch/s390/kvm/trace.h | |||
@@ -175,6 +175,7 @@ TRACE_EVENT(kvm_s390_intercept_validity, | |||
175 | {SIGP_STOP_AND_STORE_STATUS, "stop and store status"}, \ | 175 | {SIGP_STOP_AND_STORE_STATUS, "stop and store status"}, \ |
176 | {SIGP_SET_ARCHITECTURE, "set architecture"}, \ | 176 | {SIGP_SET_ARCHITECTURE, "set architecture"}, \ |
177 | {SIGP_SET_PREFIX, "set prefix"}, \ | 177 | {SIGP_SET_PREFIX, "set prefix"}, \ |
178 | {SIGP_STORE_STATUS_AT_ADDRESS, "store status at addr"}, \ | ||
178 | {SIGP_SENSE_RUNNING, "sense running"}, \ | 179 | {SIGP_SENSE_RUNNING, "sense running"}, \ |
179 | {SIGP_RESTART, "restart"} | 180 | {SIGP_RESTART, "restart"} |
180 | 181 | ||
diff --git a/arch/s390/lib/uaccess.h b/arch/s390/lib/uaccess.h index 315dbe09983e..b1a22173d027 100644 --- a/arch/s390/lib/uaccess.h +++ b/arch/s390/lib/uaccess.h | |||
@@ -6,15 +6,6 @@ | |||
6 | #ifndef __ARCH_S390_LIB_UACCESS_H | 6 | #ifndef __ARCH_S390_LIB_UACCESS_H |
7 | #define __ARCH_S390_LIB_UACCESS_H | 7 | #define __ARCH_S390_LIB_UACCESS_H |
8 | 8 | ||
9 | extern size_t copy_from_user_std(size_t, const void __user *, void *); | ||
10 | extern size_t copy_to_user_std(size_t, void __user *, const void *); | ||
11 | extern size_t strnlen_user_std(size_t, const char __user *); | ||
12 | extern size_t strncpy_from_user_std(size_t, const char __user *, char *); | ||
13 | extern int futex_atomic_cmpxchg_std(u32 *, u32 __user *, u32, u32); | ||
14 | extern int futex_atomic_op_std(int, u32 __user *, int, int *); | ||
15 | |||
16 | extern size_t copy_from_user_pt(size_t, const void __user *, void *); | ||
17 | extern size_t copy_to_user_pt(size_t, void __user *, const void *); | ||
18 | extern int futex_atomic_op_pt(int, u32 __user *, int, int *); | 9 | extern int futex_atomic_op_pt(int, u32 __user *, int, int *); |
19 | extern int futex_atomic_cmpxchg_pt(u32 *, u32 __user *, u32, u32); | 10 | extern int futex_atomic_cmpxchg_pt(u32 *, u32 __user *, u32, u32); |
20 | 11 | ||
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c index dbdab3e7a1a6..61ebcc9ccb34 100644 --- a/arch/s390/lib/uaccess_pt.c +++ b/arch/s390/lib/uaccess_pt.c | |||
@@ -74,8 +74,8 @@ static size_t copy_in_kernel(size_t count, void __user *to, | |||
74 | 74 | ||
75 | /* | 75 | /* |
76 | * Returns kernel address for user virtual address. If the returned address is | 76 | * Returns kernel address for user virtual address. If the returned address is |
77 | * >= -4095 (IS_ERR_VALUE(x) returns true), a fault has occured and the address | 77 | * >= -4095 (IS_ERR_VALUE(x) returns true), a fault has occurred and the |
78 | * contains the (negative) exception code. | 78 | * address contains the (negative) exception code. |
79 | */ | 79 | */ |
80 | #ifdef CONFIG_64BIT | 80 | #ifdef CONFIG_64BIT |
81 | 81 | ||
@@ -153,6 +153,8 @@ static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr, | |||
153 | unsigned long offset, done, size, kaddr; | 153 | unsigned long offset, done, size, kaddr; |
154 | void *from, *to; | 154 | void *from, *to; |
155 | 155 | ||
156 | if (!mm) | ||
157 | return n; | ||
156 | done = 0; | 158 | done = 0; |
157 | retry: | 159 | retry: |
158 | spin_lock(&mm->page_table_lock); | 160 | spin_lock(&mm->page_table_lock); |
@@ -209,7 +211,7 @@ fault: | |||
209 | return 0; | 211 | return 0; |
210 | } | 212 | } |
211 | 213 | ||
212 | size_t copy_from_user_pt(size_t n, const void __user *from, void *to) | 214 | static size_t copy_from_user_pt(size_t n, const void __user *from, void *to) |
213 | { | 215 | { |
214 | size_t rc; | 216 | size_t rc; |
215 | 217 | ||
@@ -221,7 +223,7 @@ size_t copy_from_user_pt(size_t n, const void __user *from, void *to) | |||
221 | return rc; | 223 | return rc; |
222 | } | 224 | } |
223 | 225 | ||
224 | size_t copy_to_user_pt(size_t n, void __user *to, const void *from) | 226 | static size_t copy_to_user_pt(size_t n, void __user *to, const void *from) |
225 | { | 227 | { |
226 | if (segment_eq(get_fs(), KERNEL_DS)) | 228 | if (segment_eq(get_fs(), KERNEL_DS)) |
227 | return copy_in_kernel(n, to, (void __user *) from); | 229 | return copy_in_kernel(n, to, (void __user *) from); |
@@ -262,6 +264,8 @@ static size_t strnlen_user_pt(size_t count, const char __user *src) | |||
262 | return 0; | 264 | return 0; |
263 | if (segment_eq(get_fs(), KERNEL_DS)) | 265 | if (segment_eq(get_fs(), KERNEL_DS)) |
264 | return strnlen_kernel(count, src); | 266 | return strnlen_kernel(count, src); |
267 | if (!mm) | ||
268 | return 0; | ||
265 | done = 0; | 269 | done = 0; |
266 | retry: | 270 | retry: |
267 | spin_lock(&mm->page_table_lock); | 271 | spin_lock(&mm->page_table_lock); |
@@ -323,6 +327,8 @@ static size_t copy_in_user_pt(size_t n, void __user *to, | |||
323 | 327 | ||
324 | if (segment_eq(get_fs(), KERNEL_DS)) | 328 | if (segment_eq(get_fs(), KERNEL_DS)) |
325 | return copy_in_kernel(n, to, from); | 329 | return copy_in_kernel(n, to, from); |
330 | if (!mm) | ||
331 | return n; | ||
326 | done = 0; | 332 | done = 0; |
327 | retry: | 333 | retry: |
328 | spin_lock(&mm->page_table_lock); | 334 | spin_lock(&mm->page_table_lock); |
@@ -411,6 +417,8 @@ int futex_atomic_op_pt(int op, u32 __user *uaddr, int oparg, int *old) | |||
411 | 417 | ||
412 | if (segment_eq(get_fs(), KERNEL_DS)) | 418 | if (segment_eq(get_fs(), KERNEL_DS)) |
413 | return __futex_atomic_op_pt(op, uaddr, oparg, old); | 419 | return __futex_atomic_op_pt(op, uaddr, oparg, old); |
420 | if (unlikely(!current->mm)) | ||
421 | return -EFAULT; | ||
414 | spin_lock(¤t->mm->page_table_lock); | 422 | spin_lock(¤t->mm->page_table_lock); |
415 | uaddr = (u32 __force __user *) | 423 | uaddr = (u32 __force __user *) |
416 | __dat_user_addr((__force unsigned long) uaddr, 1); | 424 | __dat_user_addr((__force unsigned long) uaddr, 1); |
@@ -448,6 +456,8 @@ int futex_atomic_cmpxchg_pt(u32 *uval, u32 __user *uaddr, | |||
448 | 456 | ||
449 | if (segment_eq(get_fs(), KERNEL_DS)) | 457 | if (segment_eq(get_fs(), KERNEL_DS)) |
450 | return __futex_atomic_cmpxchg_pt(uval, uaddr, oldval, newval); | 458 | return __futex_atomic_cmpxchg_pt(uval, uaddr, oldval, newval); |
459 | if (unlikely(!current->mm)) | ||
460 | return -EFAULT; | ||
451 | spin_lock(¤t->mm->page_table_lock); | 461 | spin_lock(¤t->mm->page_table_lock); |
452 | uaddr = (u32 __force __user *) | 462 | uaddr = (u32 __force __user *) |
453 | __dat_user_addr((__force unsigned long) uaddr, 1); | 463 | __dat_user_addr((__force unsigned long) uaddr, 1); |
diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c index a90d45e9dfb0..27c50f4d90cb 100644 --- a/arch/s390/mm/page-states.c +++ b/arch/s390/mm/page-states.c | |||
@@ -12,6 +12,8 @@ | |||
12 | #include <linux/mm.h> | 12 | #include <linux/mm.h> |
13 | #include <linux/gfp.h> | 13 | #include <linux/gfp.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <asm/setup.h> | ||
16 | #include <asm/ipl.h> | ||
15 | 17 | ||
16 | #define ESSA_SET_STABLE 1 | 18 | #define ESSA_SET_STABLE 1 |
17 | #define ESSA_SET_UNUSED 2 | 19 | #define ESSA_SET_UNUSED 2 |
@@ -41,6 +43,14 @@ void __init cmma_init(void) | |||
41 | 43 | ||
42 | if (!cmma_flag) | 44 | if (!cmma_flag) |
43 | return; | 45 | return; |
46 | /* | ||
47 | * Disable CMM for dump, otherwise the tprot based memory | ||
48 | * detection can fail because of unstable pages. | ||
49 | */ | ||
50 | if (OLDMEM_BASE || ipl_info.type == IPL_TYPE_FCP_DUMP) { | ||
51 | cmma_flag = 0; | ||
52 | return; | ||
53 | } | ||
44 | asm volatile( | 54 | asm volatile( |
45 | " .insn rrf,0xb9ab0000,%1,%1,0,0\n" | 55 | " .insn rrf,0xb9ab0000,%1,%1,0,0\n" |
46 | "0: la %0,0\n" | 56 | "0: la %0,0\n" |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index e794c88f699a..3584ed9b20a1 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
@@ -293,7 +293,7 @@ static int gmap_alloc_table(struct gmap *gmap, | |||
293 | * @addr: address in the guest address space | 293 | * @addr: address in the guest address space |
294 | * @len: length of the memory area to unmap | 294 | * @len: length of the memory area to unmap |
295 | * | 295 | * |
296 | * Returns 0 if the unmap succeded, -EINVAL if not. | 296 | * Returns 0 if the unmap succeeded, -EINVAL if not. |
297 | */ | 297 | */ |
298 | int gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len) | 298 | int gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len) |
299 | { | 299 | { |
@@ -344,7 +344,7 @@ EXPORT_SYMBOL_GPL(gmap_unmap_segment); | |||
344 | * @from: source address in the parent address space | 344 | * @from: source address in the parent address space |
345 | * @to: target address in the guest address space | 345 | * @to: target address in the guest address space |
346 | * | 346 | * |
347 | * Returns 0 if the mmap succeded, -EINVAL or -ENOMEM if not. | 347 | * Returns 0 if the mmap succeeded, -EINVAL or -ENOMEM if not. |
348 | */ | 348 | */ |
349 | int gmap_map_segment(struct gmap *gmap, unsigned long from, | 349 | int gmap_map_segment(struct gmap *gmap, unsigned long from, |
350 | unsigned long to, unsigned long len) | 350 | unsigned long to, unsigned long len) |
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 16871da37371..708d60e40066 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c | |||
@@ -368,14 +368,16 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter, | |||
368 | EMIT4_PCREL(0xa7840000, (jit->ret0_ip - jit->prg)); | 368 | EMIT4_PCREL(0xa7840000, (jit->ret0_ip - jit->prg)); |
369 | /* lhi %r4,0 */ | 369 | /* lhi %r4,0 */ |
370 | EMIT4(0xa7480000); | 370 | EMIT4(0xa7480000); |
371 | /* dr %r4,%r12 */ | 371 | /* dlr %r4,%r12 */ |
372 | EMIT2(0x1d4c); | 372 | EMIT4(0xb997004c); |
373 | break; | 373 | break; |
374 | case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K) */ | 374 | case BPF_S_ALU_DIV_K: /* A /= K */ |
375 | /* m %r4,<d(K)>(%r13) */ | 375 | if (K == 1) |
376 | EMIT4_DISP(0x5c40d000, EMIT_CONST(K)); | 376 | break; |
377 | /* lr %r5,%r4 */ | 377 | /* lhi %r4,0 */ |
378 | EMIT2(0x1854); | 378 | EMIT4(0xa7480000); |
379 | /* dl %r4,<d(K)>(%r13) */ | ||
380 | EMIT6_DISP(0xe340d000, 0x0097, EMIT_CONST(K)); | ||
379 | break; | 381 | break; |
380 | case BPF_S_ALU_MOD_X: /* A %= X */ | 382 | case BPF_S_ALU_MOD_X: /* A %= X */ |
381 | jit->seen |= SEEN_XREG | SEEN_RET0; | 383 | jit->seen |= SEEN_XREG | SEEN_RET0; |
@@ -385,16 +387,21 @@ static int bpf_jit_insn(struct bpf_jit *jit, struct sock_filter *filter, | |||
385 | EMIT4_PCREL(0xa7840000, (jit->ret0_ip - jit->prg)); | 387 | EMIT4_PCREL(0xa7840000, (jit->ret0_ip - jit->prg)); |
386 | /* lhi %r4,0 */ | 388 | /* lhi %r4,0 */ |
387 | EMIT4(0xa7480000); | 389 | EMIT4(0xa7480000); |
388 | /* dr %r4,%r12 */ | 390 | /* dlr %r4,%r12 */ |
389 | EMIT2(0x1d4c); | 391 | EMIT4(0xb997004c); |
390 | /* lr %r5,%r4 */ | 392 | /* lr %r5,%r4 */ |
391 | EMIT2(0x1854); | 393 | EMIT2(0x1854); |
392 | break; | 394 | break; |
393 | case BPF_S_ALU_MOD_K: /* A %= K */ | 395 | case BPF_S_ALU_MOD_K: /* A %= K */ |
396 | if (K == 1) { | ||
397 | /* lhi %r5,0 */ | ||
398 | EMIT4(0xa7580000); | ||
399 | break; | ||
400 | } | ||
394 | /* lhi %r4,0 */ | 401 | /* lhi %r4,0 */ |
395 | EMIT4(0xa7480000); | 402 | EMIT4(0xa7480000); |
396 | /* d %r4,<d(K)>(%r13) */ | 403 | /* dl %r4,<d(K)>(%r13) */ |
397 | EMIT4_DISP(0x5d40d000, EMIT_CONST(K)); | 404 | EMIT6_DISP(0xe340d000, 0x0097, EMIT_CONST(K)); |
398 | /* lr %r5,%r4 */ | 405 | /* lr %r5,%r4 */ |
399 | EMIT2(0x1854); | 406 | EMIT2(0x1854); |
400 | break; | 407 | break; |
diff --git a/arch/s390/oprofile/hwsampler.c b/arch/s390/oprofile/hwsampler.c index 231cecafc2f1..a32c96761eab 100644 --- a/arch/s390/oprofile/hwsampler.c +++ b/arch/s390/oprofile/hwsampler.c | |||
@@ -26,9 +26,6 @@ | |||
26 | #define MAX_NUM_SDB 511 | 26 | #define MAX_NUM_SDB 511 |
27 | #define MIN_NUM_SDB 1 | 27 | #define MIN_NUM_SDB 1 |
28 | 28 | ||
29 | #define ALERT_REQ_MASK 0x4000000000000000ul | ||
30 | #define BUFFER_FULL_MASK 0x8000000000000000ul | ||
31 | |||
32 | DECLARE_PER_CPU(struct hws_cpu_buffer, sampler_cpu_buffer); | 29 | DECLARE_PER_CPU(struct hws_cpu_buffer, sampler_cpu_buffer); |
33 | 30 | ||
34 | struct hws_execute_parms { | 31 | struct hws_execute_parms { |
@@ -44,6 +41,7 @@ static DEFINE_MUTEX(hws_sem_oom); | |||
44 | 41 | ||
45 | static unsigned char hws_flush_all; | 42 | static unsigned char hws_flush_all; |
46 | static unsigned int hws_oom; | 43 | static unsigned int hws_oom; |
44 | static unsigned int hws_alert; | ||
47 | static struct workqueue_struct *hws_wq; | 45 | static struct workqueue_struct *hws_wq; |
48 | 46 | ||
49 | static unsigned int hws_state; | 47 | static unsigned int hws_state; |
@@ -65,43 +63,6 @@ static unsigned long interval; | |||
65 | static unsigned long min_sampler_rate; | 63 | static unsigned long min_sampler_rate; |
66 | static unsigned long max_sampler_rate; | 64 | static unsigned long max_sampler_rate; |
67 | 65 | ||
68 | static int ssctl(void *buffer) | ||
69 | { | ||
70 | int cc; | ||
71 | |||
72 | /* set in order to detect a program check */ | ||
73 | cc = 1; | ||
74 | |||
75 | asm volatile( | ||
76 | "0: .insn s,0xB2870000,0(%1)\n" | ||
77 | "1: ipm %0\n" | ||
78 | " srl %0,28\n" | ||
79 | "2:\n" | ||
80 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) | ||
81 | : "+d" (cc), "+a" (buffer) | ||
82 | : "m" (*((struct hws_ssctl_request_block *)buffer)) | ||
83 | : "cc", "memory"); | ||
84 | |||
85 | return cc ? -EINVAL : 0 ; | ||
86 | } | ||
87 | |||
88 | static int qsi(void *buffer) | ||
89 | { | ||
90 | int cc; | ||
91 | cc = 1; | ||
92 | |||
93 | asm volatile( | ||
94 | "0: .insn s,0xB2860000,0(%1)\n" | ||
95 | "1: lhi %0,0\n" | ||
96 | "2:\n" | ||
97 | EX_TABLE(0b, 2b) EX_TABLE(1b, 2b) | ||
98 | : "=d" (cc), "+a" (buffer) | ||
99 | : "m" (*((struct hws_qsi_info_block *)buffer)) | ||
100 | : "cc", "memory"); | ||
101 | |||
102 | return cc ? -EINVAL : 0; | ||
103 | } | ||
104 | |||
105 | static void execute_qsi(void *parms) | 66 | static void execute_qsi(void *parms) |
106 | { | 67 | { |
107 | struct hws_execute_parms *ep = parms; | 68 | struct hws_execute_parms *ep = parms; |
@@ -113,7 +74,7 @@ static void execute_ssctl(void *parms) | |||
113 | { | 74 | { |
114 | struct hws_execute_parms *ep = parms; | 75 | struct hws_execute_parms *ep = parms; |
115 | 76 | ||
116 | ep->rc = ssctl(ep->buffer); | 77 | ep->rc = lsctl(ep->buffer); |
117 | } | 78 | } |
118 | 79 | ||
119 | static int smp_ctl_ssctl_stop(int cpu) | 80 | static int smp_ctl_ssctl_stop(int cpu) |
@@ -214,17 +175,6 @@ static int smp_ctl_qsi(int cpu) | |||
214 | return ep.rc; | 175 | return ep.rc; |
215 | } | 176 | } |
216 | 177 | ||
217 | static inline unsigned long *trailer_entry_ptr(unsigned long v) | ||
218 | { | ||
219 | void *ret; | ||
220 | |||
221 | ret = (void *)v; | ||
222 | ret += PAGE_SIZE; | ||
223 | ret -= sizeof(struct hws_trailer_entry); | ||
224 | |||
225 | return (unsigned long *) ret; | ||
226 | } | ||
227 | |||
228 | static void hws_ext_handler(struct ext_code ext_code, | 178 | static void hws_ext_handler(struct ext_code ext_code, |
229 | unsigned int param32, unsigned long param64) | 179 | unsigned int param32, unsigned long param64) |
230 | { | 180 | { |
@@ -233,6 +183,9 @@ static void hws_ext_handler(struct ext_code ext_code, | |||
233 | if (!(param32 & CPU_MF_INT_SF_MASK)) | 183 | if (!(param32 & CPU_MF_INT_SF_MASK)) |
234 | return; | 184 | return; |
235 | 185 | ||
186 | if (!hws_alert) | ||
187 | return; | ||
188 | |||
236 | inc_irq_stat(IRQEXT_CMS); | 189 | inc_irq_stat(IRQEXT_CMS); |
237 | atomic_xchg(&cb->ext_params, atomic_read(&cb->ext_params) | param32); | 190 | atomic_xchg(&cb->ext_params, atomic_read(&cb->ext_params) | param32); |
238 | 191 | ||
@@ -256,16 +209,6 @@ static void init_all_cpu_buffers(void) | |||
256 | } | 209 | } |
257 | } | 210 | } |
258 | 211 | ||
259 | static int is_link_entry(unsigned long *s) | ||
260 | { | ||
261 | return *s & 0x1ul ? 1 : 0; | ||
262 | } | ||
263 | |||
264 | static unsigned long *get_next_sdbt(unsigned long *s) | ||
265 | { | ||
266 | return (unsigned long *) (*s & ~0x1ul); | ||
267 | } | ||
268 | |||
269 | static int prepare_cpu_buffers(void) | 212 | static int prepare_cpu_buffers(void) |
270 | { | 213 | { |
271 | int cpu; | 214 | int cpu; |
@@ -353,7 +296,7 @@ static int allocate_sdbt(int cpu) | |||
353 | } | 296 | } |
354 | *sdbt = sdb; | 297 | *sdbt = sdb; |
355 | trailer = trailer_entry_ptr(*sdbt); | 298 | trailer = trailer_entry_ptr(*sdbt); |
356 | *trailer = ALERT_REQ_MASK; | 299 | *trailer = SDB_TE_ALERT_REQ_MASK; |
357 | sdbt++; | 300 | sdbt++; |
358 | mutex_unlock(&hws_sem_oom); | 301 | mutex_unlock(&hws_sem_oom); |
359 | } | 302 | } |
@@ -829,7 +772,7 @@ static void worker_on_interrupt(unsigned int cpu) | |||
829 | 772 | ||
830 | trailer = trailer_entry_ptr(*sdbt); | 773 | trailer = trailer_entry_ptr(*sdbt); |
831 | /* leave loop if no more work to do */ | 774 | /* leave loop if no more work to do */ |
832 | if (!(*trailer & BUFFER_FULL_MASK)) { | 775 | if (!(*trailer & SDB_TE_BUFFER_FULL_MASK)) { |
833 | done = 1; | 776 | done = 1; |
834 | if (!hws_flush_all) | 777 | if (!hws_flush_all) |
835 | continue; | 778 | continue; |
@@ -856,7 +799,7 @@ static void worker_on_interrupt(unsigned int cpu) | |||
856 | static void add_samples_to_oprofile(unsigned int cpu, unsigned long *sdbt, | 799 | static void add_samples_to_oprofile(unsigned int cpu, unsigned long *sdbt, |
857 | unsigned long *dear) | 800 | unsigned long *dear) |
858 | { | 801 | { |
859 | struct hws_data_entry *sample_data_ptr; | 802 | struct hws_basic_entry *sample_data_ptr; |
860 | unsigned long *trailer; | 803 | unsigned long *trailer; |
861 | 804 | ||
862 | trailer = trailer_entry_ptr(*sdbt); | 805 | trailer = trailer_entry_ptr(*sdbt); |
@@ -866,7 +809,7 @@ static void add_samples_to_oprofile(unsigned int cpu, unsigned long *sdbt, | |||
866 | trailer = dear; | 809 | trailer = dear; |
867 | } | 810 | } |
868 | 811 | ||
869 | sample_data_ptr = (struct hws_data_entry *)(*sdbt); | 812 | sample_data_ptr = (struct hws_basic_entry *)(*sdbt); |
870 | 813 | ||
871 | while ((unsigned long *)sample_data_ptr < trailer) { | 814 | while ((unsigned long *)sample_data_ptr < trailer) { |
872 | struct pt_regs *regs = NULL; | 815 | struct pt_regs *regs = NULL; |
@@ -1002,6 +945,7 @@ int hwsampler_deallocate(void) | |||
1002 | goto deallocate_exit; | 945 | goto deallocate_exit; |
1003 | 946 | ||
1004 | irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); | 947 | irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); |
948 | hws_alert = 0; | ||
1005 | deallocate_sdbt(); | 949 | deallocate_sdbt(); |
1006 | 950 | ||
1007 | hws_state = HWS_DEALLOCATED; | 951 | hws_state = HWS_DEALLOCATED; |
@@ -1116,6 +1060,7 @@ int hwsampler_shutdown(void) | |||
1116 | 1060 | ||
1117 | if (hws_state == HWS_STOPPED) { | 1061 | if (hws_state == HWS_STOPPED) { |
1118 | irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); | 1062 | irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); |
1063 | hws_alert = 0; | ||
1119 | deallocate_sdbt(); | 1064 | deallocate_sdbt(); |
1120 | } | 1065 | } |
1121 | if (hws_wq) { | 1066 | if (hws_wq) { |
@@ -1190,6 +1135,7 @@ start_all_exit: | |||
1190 | hws_oom = 1; | 1135 | hws_oom = 1; |
1191 | hws_flush_all = 0; | 1136 | hws_flush_all = 0; |
1192 | /* now let them in, 1407 CPUMF external interrupts */ | 1137 | /* now let them in, 1407 CPUMF external interrupts */ |
1138 | hws_alert = 1; | ||
1193 | irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT); | 1139 | irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT); |
1194 | 1140 | ||
1195 | return 0; | 1141 | return 0; |
diff --git a/arch/s390/oprofile/hwsampler.h b/arch/s390/oprofile/hwsampler.h index 0022e1ebfbde..a483d06f2fa7 100644 --- a/arch/s390/oprofile/hwsampler.h +++ b/arch/s390/oprofile/hwsampler.h | |||
@@ -9,27 +9,7 @@ | |||
9 | #define HWSAMPLER_H_ | 9 | #define HWSAMPLER_H_ |
10 | 10 | ||
11 | #include <linux/workqueue.h> | 11 | #include <linux/workqueue.h> |
12 | 12 | #include <asm/cpu_mf.h> | |
13 | struct hws_qsi_info_block /* QUERY SAMPLING information block */ | ||
14 | { /* Bit(s) */ | ||
15 | unsigned int b0_13:14; /* 0-13: zeros */ | ||
16 | unsigned int as:1; /* 14: sampling authorisation control*/ | ||
17 | unsigned int b15_21:7; /* 15-21: zeros */ | ||
18 | unsigned int es:1; /* 22: sampling enable control */ | ||
19 | unsigned int b23_29:7; /* 23-29: zeros */ | ||
20 | unsigned int cs:1; /* 30: sampling activation control */ | ||
21 | unsigned int:1; /* 31: reserved */ | ||
22 | unsigned int bsdes:16; /* 4-5: size of sampling entry */ | ||
23 | unsigned int:16; /* 6-7: reserved */ | ||
24 | unsigned long min_sampl_rate; /* 8-15: minimum sampling interval */ | ||
25 | unsigned long max_sampl_rate; /* 16-23: maximum sampling interval*/ | ||
26 | unsigned long tear; /* 24-31: TEAR contents */ | ||
27 | unsigned long dear; /* 32-39: DEAR contents */ | ||
28 | unsigned int rsvrd0; /* 40-43: reserved */ | ||
29 | unsigned int cpu_speed; /* 44-47: CPU speed */ | ||
30 | unsigned long long rsvrd1; /* 48-55: reserved */ | ||
31 | unsigned long long rsvrd2; /* 56-63: reserved */ | ||
32 | }; | ||
33 | 13 | ||
34 | struct hws_ssctl_request_block /* SET SAMPLING CONTROLS req block */ | 14 | struct hws_ssctl_request_block /* SET SAMPLING CONTROLS req block */ |
35 | { /* bytes 0 - 7 Bit(s) */ | 15 | { /* bytes 0 - 7 Bit(s) */ |
@@ -68,36 +48,6 @@ struct hws_cpu_buffer { | |||
68 | unsigned int stop_mode:1; | 48 | unsigned int stop_mode:1; |
69 | }; | 49 | }; |
70 | 50 | ||
71 | struct hws_data_entry { | ||
72 | unsigned int def:16; /* 0-15 Data Entry Format */ | ||
73 | unsigned int R:4; /* 16-19 reserved */ | ||
74 | unsigned int U:4; /* 20-23 Number of unique instruct. */ | ||
75 | unsigned int z:2; /* zeros */ | ||
76 | unsigned int T:1; /* 26 PSW DAT mode */ | ||
77 | unsigned int W:1; /* 27 PSW wait state */ | ||
78 | unsigned int P:1; /* 28 PSW Problem state */ | ||
79 | unsigned int AS:2; /* 29-30 PSW address-space control */ | ||
80 | unsigned int I:1; /* 31 entry valid or invalid */ | ||
81 | unsigned int:16; | ||
82 | unsigned int prim_asn:16; /* primary ASN */ | ||
83 | unsigned long long ia; /* Instruction Address */ | ||
84 | unsigned long long gpp; /* Guest Program Parameter */ | ||
85 | unsigned long long hpp; /* Host Program Parameter */ | ||
86 | }; | ||
87 | |||
88 | struct hws_trailer_entry { | ||
89 | unsigned int f:1; /* 0 - Block Full Indicator */ | ||
90 | unsigned int a:1; /* 1 - Alert request control */ | ||
91 | unsigned long:62; /* 2 - 63: Reserved */ | ||
92 | unsigned long overflow; /* 64 - sample Overflow count */ | ||
93 | unsigned long timestamp; /* 16 - time-stamp */ | ||
94 | unsigned long timestamp1; /* */ | ||
95 | unsigned long reserved1; /* 32 -Reserved */ | ||
96 | unsigned long reserved2; /* */ | ||
97 | unsigned long progusage1; /* 48 - reserved for programming use */ | ||
98 | unsigned long progusage2; /* */ | ||
99 | }; | ||
100 | |||
101 | int hwsampler_setup(void); | 51 | int hwsampler_setup(void); |
102 | int hwsampler_shutdown(void); | 52 | int hwsampler_shutdown(void); |
103 | int hwsampler_allocate(unsigned long sdbt, unsigned long sdb); | 53 | int hwsampler_allocate(unsigned long sdbt, unsigned long sdb); |
diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c index 04e1b6a85362..9ffe645d5989 100644 --- a/arch/s390/oprofile/init.c +++ b/arch/s390/oprofile/init.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/oprofile.h> | 12 | #include <linux/oprofile.h> |
13 | #include <linux/perf_event.h> | ||
13 | #include <linux/init.h> | 14 | #include <linux/init.h> |
14 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
15 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
@@ -67,6 +68,21 @@ module_param_call(cpu_type, set_cpu_type, NULL, NULL, 0); | |||
67 | MODULE_PARM_DESC(cpu_type, "Force legacy basic mode sampling" | 68 | MODULE_PARM_DESC(cpu_type, "Force legacy basic mode sampling" |
68 | "(report cpu_type \"timer\""); | 69 | "(report cpu_type \"timer\""); |
69 | 70 | ||
71 | static int __oprofile_hwsampler_start(void) | ||
72 | { | ||
73 | int retval; | ||
74 | |||
75 | retval = hwsampler_allocate(oprofile_sdbt_blocks, oprofile_sdb_blocks); | ||
76 | if (retval) | ||
77 | return retval; | ||
78 | |||
79 | retval = hwsampler_start_all(oprofile_hw_interval); | ||
80 | if (retval) | ||
81 | hwsampler_deallocate(); | ||
82 | |||
83 | return retval; | ||
84 | } | ||
85 | |||
70 | static int oprofile_hwsampler_start(void) | 86 | static int oprofile_hwsampler_start(void) |
71 | { | 87 | { |
72 | int retval; | 88 | int retval; |
@@ -76,13 +92,13 @@ static int oprofile_hwsampler_start(void) | |||
76 | if (!hwsampler_running) | 92 | if (!hwsampler_running) |
77 | return timer_ops.start(); | 93 | return timer_ops.start(); |
78 | 94 | ||
79 | retval = hwsampler_allocate(oprofile_sdbt_blocks, oprofile_sdb_blocks); | 95 | retval = perf_reserve_sampling(); |
80 | if (retval) | 96 | if (retval) |
81 | return retval; | 97 | return retval; |
82 | 98 | ||
83 | retval = hwsampler_start_all(oprofile_hw_interval); | 99 | retval = __oprofile_hwsampler_start(); |
84 | if (retval) | 100 | if (retval) |
85 | hwsampler_deallocate(); | 101 | perf_release_sampling(); |
86 | 102 | ||
87 | return retval; | 103 | return retval; |
88 | } | 104 | } |
@@ -96,6 +112,7 @@ static void oprofile_hwsampler_stop(void) | |||
96 | 112 | ||
97 | hwsampler_stop_all(); | 113 | hwsampler_stop_all(); |
98 | hwsampler_deallocate(); | 114 | hwsampler_deallocate(); |
115 | perf_release_sampling(); | ||
99 | return; | 116 | return; |
100 | } | 117 | } |
101 | 118 | ||
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index bf7c73d71eef..66670ff262a0 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c | |||
@@ -407,8 +407,8 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) | |||
407 | struct msi_msg msg; | 407 | struct msi_msg msg; |
408 | int rc; | 408 | int rc; |
409 | 409 | ||
410 | if (type != PCI_CAP_ID_MSIX && type != PCI_CAP_ID_MSI) | 410 | if (type == PCI_CAP_ID_MSI && nvec > 1) |
411 | return -EINVAL; | 411 | return 1; |
412 | msi_vecs = min(nvec, ZPCI_MSI_VEC_MAX); | 412 | msi_vecs = min(nvec, ZPCI_MSI_VEC_MAX); |
413 | msi_vecs = min_t(unsigned int, msi_vecs, CONFIG_PCI_NR_MSI); | 413 | msi_vecs = min_t(unsigned int, msi_vecs, CONFIG_PCI_NR_MSI); |
414 | 414 | ||
@@ -919,17 +919,23 @@ static void zpci_mem_exit(void) | |||
919 | kmem_cache_destroy(zdev_fmb_cache); | 919 | kmem_cache_destroy(zdev_fmb_cache); |
920 | } | 920 | } |
921 | 921 | ||
922 | static unsigned int s390_pci_probe; | 922 | static unsigned int s390_pci_probe = 1; |
923 | static unsigned int s390_pci_initialized; | ||
923 | 924 | ||
924 | char * __init pcibios_setup(char *str) | 925 | char * __init pcibios_setup(char *str) |
925 | { | 926 | { |
926 | if (!strcmp(str, "on")) { | 927 | if (!strcmp(str, "off")) { |
927 | s390_pci_probe = 1; | 928 | s390_pci_probe = 0; |
928 | return NULL; | 929 | return NULL; |
929 | } | 930 | } |
930 | return str; | 931 | return str; |
931 | } | 932 | } |
932 | 933 | ||
934 | bool zpci_is_enabled(void) | ||
935 | { | ||
936 | return s390_pci_initialized; | ||
937 | } | ||
938 | |||
933 | static int __init pci_base_init(void) | 939 | static int __init pci_base_init(void) |
934 | { | 940 | { |
935 | int rc; | 941 | int rc; |
@@ -961,6 +967,7 @@ static int __init pci_base_init(void) | |||
961 | if (rc) | 967 | if (rc) |
962 | goto out_find; | 968 | goto out_find; |
963 | 969 | ||
970 | s390_pci_initialized = 1; | ||
964 | return 0; | 971 | return 0; |
965 | 972 | ||
966 | out_find: | 973 | out_find: |
@@ -978,5 +985,6 @@ subsys_initcall_sync(pci_base_init); | |||
978 | 985 | ||
979 | void zpci_rescan(void) | 986 | void zpci_rescan(void) |
980 | { | 987 | { |
981 | clp_rescan_pci_devices_simple(); | 988 | if (zpci_is_enabled()) |
989 | clp_rescan_pci_devices_simple(); | ||
982 | } | 990 | } |
diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index 9b83d080902d..60c11a629d96 100644 --- a/arch/s390/pci/pci_dma.c +++ b/arch/s390/pci/pci_dma.c | |||
@@ -285,7 +285,7 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page, | |||
285 | flags |= ZPCI_TABLE_PROTECTED; | 285 | flags |= ZPCI_TABLE_PROTECTED; |
286 | 286 | ||
287 | if (!dma_update_trans(zdev, pa, dma_addr, size, flags)) { | 287 | if (!dma_update_trans(zdev, pa, dma_addr, size, flags)) { |
288 | atomic64_add(nr_pages, (atomic64_t *) &zdev->fmb->mapped_pages); | 288 | atomic64_add(nr_pages, &zdev->fmb->mapped_pages); |
289 | return dma_addr + (offset & ~PAGE_MASK); | 289 | return dma_addr + (offset & ~PAGE_MASK); |
290 | } | 290 | } |
291 | 291 | ||
@@ -313,7 +313,7 @@ static void s390_dma_unmap_pages(struct device *dev, dma_addr_t dma_addr, | |||
313 | zpci_err_hex(&dma_addr, sizeof(dma_addr)); | 313 | zpci_err_hex(&dma_addr, sizeof(dma_addr)); |
314 | } | 314 | } |
315 | 315 | ||
316 | atomic64_add(npages, (atomic64_t *) &zdev->fmb->unmapped_pages); | 316 | atomic64_add(npages, &zdev->fmb->unmapped_pages); |
317 | iommu_page_index = (dma_addr - zdev->start_dma) >> PAGE_SHIFT; | 317 | iommu_page_index = (dma_addr - zdev->start_dma) >> PAGE_SHIFT; |
318 | dma_free_iommu(zdev, iommu_page_index, npages); | 318 | dma_free_iommu(zdev, iommu_page_index, npages); |
319 | } | 319 | } |
@@ -332,7 +332,6 @@ static void *s390_dma_alloc(struct device *dev, size_t size, | |||
332 | if (!page) | 332 | if (!page) |
333 | return NULL; | 333 | return NULL; |
334 | 334 | ||
335 | atomic64_add(size / PAGE_SIZE, (atomic64_t *) &zdev->fmb->allocated_pages); | ||
336 | pa = page_to_phys(page); | 335 | pa = page_to_phys(page); |
337 | memset((void *) pa, 0, size); | 336 | memset((void *) pa, 0, size); |
338 | 337 | ||
@@ -343,6 +342,7 @@ static void *s390_dma_alloc(struct device *dev, size_t size, | |||
343 | return NULL; | 342 | return NULL; |
344 | } | 343 | } |
345 | 344 | ||
345 | atomic64_add(size / PAGE_SIZE, &zdev->fmb->allocated_pages); | ||
346 | if (dma_handle) | 346 | if (dma_handle) |
347 | *dma_handle = map; | 347 | *dma_handle = map; |
348 | return (void *) pa; | 348 | return (void *) pa; |
@@ -352,8 +352,11 @@ static void s390_dma_free(struct device *dev, size_t size, | |||
352 | void *pa, dma_addr_t dma_handle, | 352 | void *pa, dma_addr_t dma_handle, |
353 | struct dma_attrs *attrs) | 353 | struct dma_attrs *attrs) |
354 | { | 354 | { |
355 | s390_dma_unmap_pages(dev, dma_handle, PAGE_ALIGN(size), | 355 | struct zpci_dev *zdev = get_zdev(to_pci_dev(dev)); |
356 | DMA_BIDIRECTIONAL, NULL); | 356 | |
357 | size = PAGE_ALIGN(size); | ||
358 | atomic64_sub(size / PAGE_SIZE, &zdev->fmb->allocated_pages); | ||
359 | s390_dma_unmap_pages(dev, dma_handle, size, DMA_BIDIRECTIONAL, NULL); | ||
357 | free_pages((unsigned long) pa, get_order(size)); | 360 | free_pages((unsigned long) pa, get_order(size)); |
358 | } | 361 | } |
359 | 362 | ||
diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c index 800f064b0da7..01e251b1da0c 100644 --- a/arch/s390/pci/pci_event.c +++ b/arch/s390/pci/pci_event.c | |||
@@ -43,9 +43,8 @@ struct zpci_ccdf_avail { | |||
43 | u16 pec; /* PCI event code */ | 43 | u16 pec; /* PCI event code */ |
44 | } __packed; | 44 | } __packed; |
45 | 45 | ||
46 | void zpci_event_error(void *data) | 46 | static void __zpci_event_error(struct zpci_ccdf_err *ccdf) |
47 | { | 47 | { |
48 | struct zpci_ccdf_err *ccdf = data; | ||
49 | struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid); | 48 | struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid); |
50 | 49 | ||
51 | zpci_err("error CCDF:\n"); | 50 | zpci_err("error CCDF:\n"); |
@@ -58,9 +57,14 @@ void zpci_event_error(void *data) | |||
58 | pci_name(zdev->pdev), ccdf->pec, ccdf->fid); | 57 | pci_name(zdev->pdev), ccdf->pec, ccdf->fid); |
59 | } | 58 | } |
60 | 59 | ||
61 | void zpci_event_availability(void *data) | 60 | void zpci_event_error(void *data) |
61 | { | ||
62 | if (zpci_is_enabled()) | ||
63 | __zpci_event_error(data); | ||
64 | } | ||
65 | |||
66 | static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf) | ||
62 | { | 67 | { |
63 | struct zpci_ccdf_avail *ccdf = data; | ||
64 | struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid); | 68 | struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid); |
65 | struct pci_dev *pdev = zdev ? zdev->pdev : NULL; | 69 | struct pci_dev *pdev = zdev ? zdev->pdev : NULL; |
66 | int ret; | 70 | int ret; |
@@ -75,6 +79,7 @@ void zpci_event_availability(void *data) | |||
75 | if (!zdev || zdev->state == ZPCI_FN_STATE_CONFIGURED) | 79 | if (!zdev || zdev->state == ZPCI_FN_STATE_CONFIGURED) |
76 | break; | 80 | break; |
77 | zdev->state = ZPCI_FN_STATE_CONFIGURED; | 81 | zdev->state = ZPCI_FN_STATE_CONFIGURED; |
82 | zdev->fh = ccdf->fh; | ||
78 | ret = zpci_enable_device(zdev); | 83 | ret = zpci_enable_device(zdev); |
79 | if (ret) | 84 | if (ret) |
80 | break; | 85 | break; |
@@ -98,9 +103,14 @@ void zpci_event_availability(void *data) | |||
98 | 103 | ||
99 | break; | 104 | break; |
100 | case 0x0304: /* Configured -> Standby */ | 105 | case 0x0304: /* Configured -> Standby */ |
101 | if (pdev) | 106 | if (pdev) { |
107 | /* Give the driver a hint that the function is | ||
108 | * already unusable. */ | ||
109 | pdev->error_state = pci_channel_io_perm_failure; | ||
102 | pci_stop_and_remove_bus_device(pdev); | 110 | pci_stop_and_remove_bus_device(pdev); |
111 | } | ||
103 | 112 | ||
113 | zdev->fh = ccdf->fh; | ||
104 | zpci_disable_device(zdev); | 114 | zpci_disable_device(zdev); |
105 | zdev->state = ZPCI_FN_STATE_STANDBY; | 115 | zdev->state = ZPCI_FN_STATE_STANDBY; |
106 | break; | 116 | break; |
@@ -108,6 +118,8 @@ void zpci_event_availability(void *data) | |||
108 | clp_rescan_pci_devices(); | 118 | clp_rescan_pci_devices(); |
109 | break; | 119 | break; |
110 | case 0x0308: /* Standby -> Reserved */ | 120 | case 0x0308: /* Standby -> Reserved */ |
121 | if (!zdev) | ||
122 | break; | ||
111 | pci_stop_root_bus(zdev->bus); | 123 | pci_stop_root_bus(zdev->bus); |
112 | pci_remove_root_bus(zdev->bus); | 124 | pci_remove_root_bus(zdev->bus); |
113 | break; | 125 | break; |
@@ -115,3 +127,9 @@ void zpci_event_availability(void *data) | |||
115 | break; | 127 | break; |
116 | } | 128 | } |
117 | } | 129 | } |
130 | |||
131 | void zpci_event_availability(void *data) | ||
132 | { | ||
133 | if (zpci_is_enabled()) | ||
134 | __zpci_event_availability(data); | ||
135 | } | ||