Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 update from Martin Schwidefsky:
"Add support to generate code for the latest machine zEC12, MOD and XOR
instruction support for the BPF jit compiler, the dasd safe offline
feature and the big one: the s390 architecture gets PCI support!!
Right before the world ends on the 21st ;-)"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (41 commits)
s390/qdio: rename the misleading PCI flag of qdio devices
s390/pci: remove obsolete email addresses
s390/pci: speed up __iowrite64_copy by using pci store block insn
s390/pci: enable NEED_DMA_MAP_STATE
s390/pci: no msleep in potential IRQ context
s390/pci: fix potential NULL pointer dereference in dma_free_seg_table()
s390/pci: use kmem_cache_zalloc instead of kmem_cache_alloc/memset
s390/bpf,jit: add support for XOR instruction
s390/bpf,jit: add support MOD instruction
s390/cio: fix pgid reserved check
vga: compile fix, disable vga for s390
s390/pci: add PCI Kconfig options
s390/pci: s390 specific PCI sysfs attributes
s390/pci: PCI hotplug support via SCLP
s390/pci: CHSC PCI support for error and availability events
s390/pci: DMA support
s390/pci: PCI adapter interrupts for MSI/MSI-X
s390/bitops: find leftmost bit instruction support
s390/pci: CLP interface
s390/pci: base support
...

+5331 -792
+1
arch/s390/Kbuild
··· 6 6 obj-$(CONFIG_APPLDATA_BASE) += appldata/ 7 7 obj-$(CONFIG_MATHEMU) += math-emu/ 8 8 obj-y += net/ 9 + obj-$(CONFIG_PCI) += pci/
+64 -6
arch/s390/Kconfig
··· 34 34 config GENERIC_BUG_RELATIVE_POINTERS 35 35 def_bool y 36 36 37 - config NO_IOMEM 38 - def_bool y 39 - 40 - config NO_DMA 41 - def_bool y 42 - 43 37 config ARCH_DMA_ADDR_T_64BIT 44 38 def_bool 64BIT 45 39 ··· 51 57 52 58 config AUDIT_ARCH 53 59 def_bool y 60 + 61 + config NO_IOPORT 62 + def_bool y 63 + 64 + config PCI_QUIRKS 65 + def_bool n 54 66 55 67 config S390 56 68 def_bool y ··· 171 171 def_bool n 172 172 select HAVE_MARCH_Z10_FEATURES 173 173 174 + config HAVE_MARCH_ZEC12_FEATURES 175 + def_bool n 176 + select HAVE_MARCH_Z196_FEATURES 177 + 174 178 choice 175 179 prompt "Processor type" 176 180 default MARCH_G5 ··· 225 221 Select this to enable optimizations for IBM zEnterprise 114 and 196 226 222 (2818 and 2817 series). The kernel will be slightly faster but will 227 223 not work on older machines. 224 + 225 + config MARCH_ZEC12 226 + bool "IBM zEC12" 227 + select HAVE_MARCH_ZEC12_FEATURES if 64BIT 228 + help 229 + Select this to enable optimizations for IBM zEC12 (2827 series). The 230 + kernel will be slightly faster but will not work on older machines. 228 231 229 232 endchoice 230 233 ··· 436 425 module will be called qdio. 437 426 438 427 If unsure, say Y. 428 + 429 + menuconfig PCI 430 + bool "PCI support" 431 + default n 432 + depends on 64BIT 433 + select ARCH_SUPPORTS_MSI 434 + select PCI_MSI 435 + help 436 + Enable PCI support. 437 + 438 + if PCI 439 + 440 + config PCI_NR_FUNCTIONS 441 + int "Maximum number of PCI functions (1-4096)" 442 + range 1 4096 443 + default "64" 444 + help 445 + This allows you to specify the maximum number of PCI functions which 446 + this kernel will support. 447 + 448 + source "drivers/pci/Kconfig" 449 + source "drivers/pci/pcie/Kconfig" 450 + source "drivers/pci/hotplug/Kconfig" 451 + 452 + endif # PCI 453 + 454 + config PCI_DOMAINS 455 + def_bool PCI 456 + 457 + config HAS_IOMEM 458 + def_bool PCI 459 + 460 + config IOMMU_HELPER 461 + def_bool PCI 462 + 463 + config HAS_DMA 464 + def_bool PCI 465 + select HAVE_DMA_API_DEBUG 466 + 467 + config NEED_SG_DMA_LENGTH 468 + def_bool PCI 469 + 470 + config HAVE_DMA_ATTRS 471 + def_bool PCI 472 + 473 + config NEED_DMA_MAP_STATE 474 + def_bool PCI 439 475 440 476 config CHSC_SCH 441 477 def_tristate m
+1
arch/s390/Makefile
··· 41 41 cflags-$(CONFIG_MARCH_Z9_109) += $(call cc-option,-march=z9-109) 42 42 cflags-$(CONFIG_MARCH_Z10) += $(call cc-option,-march=z10) 43 43 cflags-$(CONFIG_MARCH_Z196) += $(call cc-option,-march=z196) 44 + cflags-$(CONFIG_MARCH_ZEC12) += $(call cc-option,-march=zEC12) 44 45 45 46 #KBUILD_IMAGE is necessary for make rpm 46 47 KBUILD_IMAGE :=arch/s390/boot/image
+12 -6
arch/s390/crypto/aes_s390.c
··· 325 325 u8 *in = walk->src.virt.addr; 326 326 327 327 ret = crypt_s390_km(func, param, out, in, n); 328 - BUG_ON((ret < 0) || (ret != n)); 328 + if (ret < 0 || ret != n) 329 + return -EIO; 329 330 330 331 nbytes &= AES_BLOCK_SIZE - 1; 331 332 ret = blkcipher_walk_done(desc, walk, nbytes); ··· 458 457 u8 *in = walk->src.virt.addr; 459 458 460 459 ret = crypt_s390_kmc(func, param, out, in, n); 461 - BUG_ON((ret < 0) || (ret != n)); 460 + if (ret < 0 || ret != n) 461 + return -EIO; 462 462 463 463 nbytes &= AES_BLOCK_SIZE - 1; 464 464 ret = blkcipher_walk_done(desc, walk, nbytes); ··· 627 625 memcpy(xts_ctx->pcc.tweak, walk->iv, sizeof(xts_ctx->pcc.tweak)); 628 626 param = xts_ctx->pcc.key + offset; 629 627 ret = crypt_s390_pcc(func, param); 630 - BUG_ON(ret < 0); 628 + if (ret < 0) 629 + return -EIO; 631 630 632 631 memcpy(xts_ctx->xts_param, xts_ctx->pcc.xts, 16); 633 632 param = xts_ctx->key + offset; ··· 639 636 in = walk->src.virt.addr; 640 637 641 638 ret = crypt_s390_km(func, param, out, in, n); 642 - BUG_ON(ret < 0 || ret != n); 639 + if (ret < 0 || ret != n) 640 + return -EIO; 643 641 644 642 nbytes &= AES_BLOCK_SIZE - 1; 645 643 ret = blkcipher_walk_done(desc, walk, nbytes); ··· 773 769 crypto_inc(ctrblk + i, AES_BLOCK_SIZE); 774 770 } 775 771 ret = crypt_s390_kmctr(func, sctx->key, out, in, n, ctrblk); 776 - BUG_ON(ret < 0 || ret != n); 772 + if (ret < 0 || ret != n) 773 + return -EIO; 777 774 if (n > AES_BLOCK_SIZE) 778 775 memcpy(ctrblk, ctrblk + n - AES_BLOCK_SIZE, 779 776 AES_BLOCK_SIZE); ··· 793 788 in = walk->src.virt.addr; 794 789 ret = crypt_s390_kmctr(func, sctx->key, buf, in, 795 790 AES_BLOCK_SIZE, ctrblk); 796 - BUG_ON(ret < 0 || ret != AES_BLOCK_SIZE); 791 + if (ret < 0 || ret != AES_BLOCK_SIZE) 792 + return -EIO; 797 793 memcpy(out, buf, nbytes); 798 794 crypto_inc(ctrblk, AES_BLOCK_SIZE); 799 795 ret = blkcipher_walk_done(desc, walk, 0);
+8 -4
arch/s390/crypto/des_s390.c
··· 94 94 u8 *in = walk->src.virt.addr; 95 95 96 96 ret = crypt_s390_km(func, key, out, in, n); 97 - BUG_ON((ret < 0) || (ret != n)); 97 + if (ret < 0 || ret != n) 98 + return -EIO; 98 99 99 100 nbytes &= DES_BLOCK_SIZE - 1; 100 101 ret = blkcipher_walk_done(desc, walk, nbytes); ··· 121 120 u8 *in = walk->src.virt.addr; 122 121 123 122 ret = crypt_s390_kmc(func, iv, out, in, n); 124 - BUG_ON((ret < 0) || (ret != n)); 123 + if (ret < 0 || ret != n) 124 + return -EIO; 125 125 126 126 nbytes &= DES_BLOCK_SIZE - 1; 127 127 ret = blkcipher_walk_done(desc, walk, nbytes); ··· 388 386 crypto_inc(ctrblk + i, DES_BLOCK_SIZE); 389 387 } 390 388 ret = crypt_s390_kmctr(func, ctx->key, out, in, n, ctrblk); 391 - BUG_ON((ret < 0) || (ret != n)); 389 + if (ret < 0 || ret != n) 390 + return -EIO; 392 391 if (n > DES_BLOCK_SIZE) 393 392 memcpy(ctrblk, ctrblk + n - DES_BLOCK_SIZE, 394 393 DES_BLOCK_SIZE); ··· 407 404 in = walk->src.virt.addr; 408 405 ret = crypt_s390_kmctr(func, ctx->key, buf, in, 409 406 DES_BLOCK_SIZE, ctrblk); 410 - BUG_ON(ret < 0 || ret != DES_BLOCK_SIZE); 407 + if (ret < 0 || ret != DES_BLOCK_SIZE) 408 + return -EIO; 411 409 memcpy(out, buf, nbytes); 412 410 crypto_inc(ctrblk, DES_BLOCK_SIZE); 413 411 ret = blkcipher_walk_done(desc, walk, 0);
+13 -8
arch/s390/crypto/ghash_s390.c
··· 72 72 if (!dctx->bytes) { 73 73 ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, 74 74 GHASH_BLOCK_SIZE); 75 - BUG_ON(ret != GHASH_BLOCK_SIZE); 75 + if (ret != GHASH_BLOCK_SIZE) 76 + return -EIO; 76 77 } 77 78 } 78 79 79 80 n = srclen & ~(GHASH_BLOCK_SIZE - 1); 80 81 if (n) { 81 82 ret = crypt_s390_kimd(KIMD_GHASH, ctx, src, n); 82 - BUG_ON(ret != n); 83 + if (ret != n) 84 + return -EIO; 83 85 src += n; 84 86 srclen -= n; 85 87 } ··· 94 92 return 0; 95 93 } 96 94 97 - static void ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx) 95 + static int ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx) 98 96 { 99 97 u8 *buf = dctx->buffer; 100 98 int ret; ··· 105 103 memset(pos, 0, dctx->bytes); 106 104 107 105 ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, GHASH_BLOCK_SIZE); 108 - BUG_ON(ret != GHASH_BLOCK_SIZE); 106 + if (ret != GHASH_BLOCK_SIZE) 107 + return -EIO; 109 108 } 110 109 111 110 dctx->bytes = 0; 111 + return 0; 112 112 } 113 113 114 114 static int ghash_final(struct shash_desc *desc, u8 *dst) 115 115 { 116 116 struct ghash_desc_ctx *dctx = shash_desc_ctx(desc); 117 117 struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm); 118 + int ret; 118 119 119 - ghash_flush(ctx, dctx); 120 - memcpy(dst, ctx->icv, GHASH_BLOCK_SIZE); 121 - 122 - return 0; 120 + ret = ghash_flush(ctx, dctx); 121 + if (!ret) 122 + memcpy(dst, ctx->icv, GHASH_BLOCK_SIZE); 123 + return ret; 123 124 } 124 125 125 126 static struct shash_alg ghash_alg = {
+6 -3
arch/s390/crypto/sha_common.c
··· 36 36 if (index) { 37 37 memcpy(ctx->buf + index, data, bsize - index); 38 38 ret = crypt_s390_kimd(ctx->func, ctx->state, ctx->buf, bsize); 39 - BUG_ON(ret != bsize); 39 + if (ret != bsize) 40 + return -EIO; 40 41 data += bsize - index; 41 42 len -= bsize - index; 42 43 index = 0; ··· 47 46 if (len >= bsize) { 48 47 ret = crypt_s390_kimd(ctx->func, ctx->state, data, 49 48 len & ~(bsize - 1)); 50 - BUG_ON(ret != (len & ~(bsize - 1))); 49 + if (ret != (len & ~(bsize - 1))) 50 + return -EIO; 51 51 data += ret; 52 52 len -= ret; 53 53 } ··· 90 88 memcpy(ctx->buf + end - 8, &bits, sizeof(bits)); 91 89 92 90 ret = crypt_s390_kimd(ctx->func, ctx->state, ctx->buf, end); 93 - BUG_ON(ret != end); 91 + if (ret != end) 92 + return -EIO; 94 93 95 94 /* copy digest to out */ 96 95 memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm));
+81
arch/s390/include/asm/bitops.h
··· 640 640 } 641 641 #define find_first_bit find_first_bit 642 642 643 + /* 644 + * Big endian variant whichs starts bit counting from left using 645 + * the flogr (find leftmost one) instruction. 646 + */ 647 + static inline unsigned long __flo_word(unsigned long nr, unsigned long val) 648 + { 649 + register unsigned long bit asm("2") = val; 650 + register unsigned long out asm("3"); 651 + 652 + asm volatile ( 653 + " .insn rre,0xb9830000,%[bit],%[bit]\n" 654 + : [bit] "+d" (bit), [out] "=d" (out) : : "cc"); 655 + return nr + bit; 656 + } 657 + 658 + /* 659 + * 64 bit special left bitops format: 660 + * order in memory: 661 + * 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 662 + * 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 663 + * 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 664 + * 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 665 + * after that follows the next long with bit numbers 666 + * 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 667 + * 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 668 + * 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 669 + * 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 670 + * The reason for this bit ordering is the fact that 671 + * the hardware sets bits in a bitmap starting at bit 0 672 + * and we don't want to scan the bitmap from the 'wrong 673 + * end'. 674 + */ 675 + static inline unsigned long find_first_bit_left(const unsigned long *addr, 676 + unsigned long size) 677 + { 678 + unsigned long bytes, bits; 679 + 680 + if (!size) 681 + return 0; 682 + bytes = __ffs_word_loop(addr, size); 683 + bits = __flo_word(bytes * 8, __load_ulong_be(addr, bytes)); 684 + return (bits < size) ? bits : size; 685 + } 686 + 687 + static inline int find_next_bit_left(const unsigned long *addr, 688 + unsigned long size, 689 + unsigned long offset) 690 + { 691 + const unsigned long *p; 692 + unsigned long bit, set; 693 + 694 + if (offset >= size) 695 + return size; 696 + bit = offset & (__BITOPS_WORDSIZE - 1); 697 + offset -= bit; 698 + size -= offset; 699 + p = addr + offset / __BITOPS_WORDSIZE; 700 + if (bit) { 701 + set = __flo_word(0, *p & (~0UL << bit)); 702 + if (set >= size) 703 + return size + offset; 704 + if (set < __BITOPS_WORDSIZE) 705 + return set + offset; 706 + offset += __BITOPS_WORDSIZE; 707 + size -= __BITOPS_WORDSIZE; 708 + p++; 709 + } 710 + return offset + find_first_bit_left(p, size); 711 + } 712 + 713 + #define for_each_set_bit_left(bit, addr, size) \ 714 + for ((bit) = find_first_bit_left((addr), (size)); \ 715 + (bit) < (size); \ 716 + (bit) = find_next_bit_left((addr), (size), (bit) + 1)) 717 + 718 + /* same as for_each_set_bit() but use bit as value to start with */ 719 + #define for_each_set_bit_left_cont(bit, addr, size) \ 720 + for ((bit) = find_next_bit_left((addr), (size), (bit)); \ 721 + (bit) < (size); \ 722 + (bit) = find_next_bit_left((addr), (size), (bit) + 1)) 723 + 643 724 /** 644 725 * find_next_zero_bit - find the first zero bit in a memory region 645 726 * @addr: The address to base the search on
+4 -2
arch/s390/include/asm/ccwdev.h
··· 18 18 struct ccw1; 19 19 struct ccw_dev_id; 20 20 21 + /* from asm/schid.h */ 22 + struct subchannel_id; 23 + 21 24 /* simplified initializers for struct ccw_device: 22 25 * CCW_DEVICE and CCW_DEVICE_DEVTYPE initialize one 23 26 * entry in your MODULE_DEVICE_TABLE and set the match_flag correctly */ ··· 226 223 227 224 int ccw_device_siosl(struct ccw_device *); 228 225 229 - // FIXME: these have to go 230 - extern int _ccw_device_get_subchannel_number(struct ccw_device *); 226 + extern void ccw_device_get_schid(struct ccw_device *, struct subchannel_id *); 231 227 232 228 extern void *ccw_device_get_chp_desc(struct ccw_device *, int); 233 229 #endif /* _S390_CCWDEV_H_ */
+3
arch/s390/include/asm/ccwgroup.h
··· 59 59 int ccwgroup_create_dev(struct device *root, struct ccwgroup_driver *gdrv, 60 60 int num_devices, const char *buf); 61 61 62 + extern int ccwgroup_set_online(struct ccwgroup_device *gdev); 63 + extern int ccwgroup_set_offline(struct ccwgroup_device *gdev); 64 + 62 65 extern int ccwgroup_probe_ccwdev(struct ccw_device *cdev); 63 66 extern void ccwgroup_remove_ccwdev(struct ccw_device *cdev); 64 67
+28
arch/s390/include/asm/clp.h
··· 1 + #ifndef _ASM_S390_CLP_H 2 + #define _ASM_S390_CLP_H 3 + 4 + /* CLP common request & response block size */ 5 + #define CLP_BLK_SIZE (PAGE_SIZE * 2) 6 + 7 + struct clp_req_hdr { 8 + u16 len; 9 + u16 cmd; 10 + } __packed; 11 + 12 + struct clp_rsp_hdr { 13 + u16 len; 14 + u16 rsp; 15 + } __packed; 16 + 17 + /* CLP Response Codes */ 18 + #define CLP_RC_OK 0x0010 /* Command request successfully */ 19 + #define CLP_RC_CMD 0x0020 /* Command code not recognized */ 20 + #define CLP_RC_PERM 0x0030 /* Command not authorized */ 21 + #define CLP_RC_FMT 0x0040 /* Invalid command request format */ 22 + #define CLP_RC_LEN 0x0050 /* Invalid command request length */ 23 + #define CLP_RC_8K 0x0060 /* Command requires 8K LPCB */ 24 + #define CLP_RC_RESNOT0 0x0070 /* Reserved field not zero */ 25 + #define CLP_RC_NODATA 0x0080 /* No data available */ 26 + #define CLP_RC_FC_UNKNOWN 0x0100 /* Function code not recognized */ 27 + 28 + #endif
+76
arch/s390/include/asm/dma-mapping.h
··· 1 + #ifndef _ASM_S390_DMA_MAPPING_H 2 + #define _ASM_S390_DMA_MAPPING_H 3 + 4 + #include <linux/kernel.h> 5 + #include <linux/types.h> 6 + #include <linux/mm.h> 7 + #include <linux/scatterlist.h> 8 + #include <linux/dma-attrs.h> 9 + #include <linux/dma-debug.h> 10 + #include <linux/io.h> 11 + 12 + #define DMA_ERROR_CODE (~(dma_addr_t) 0x0) 13 + 14 + extern struct dma_map_ops s390_dma_ops; 15 + 16 + static inline struct dma_map_ops *get_dma_ops(struct device *dev) 17 + { 18 + return &s390_dma_ops; 19 + } 20 + 21 + extern int dma_set_mask(struct device *dev, u64 mask); 22 + extern int dma_is_consistent(struct device *dev, dma_addr_t dma_handle); 23 + extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, 24 + enum dma_data_direction direction); 25 + 26 + #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) 27 + #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) 28 + 29 + #include <asm-generic/dma-mapping-common.h> 30 + 31 + static inline int dma_supported(struct device *dev, u64 mask) 32 + { 33 + struct dma_map_ops *dma_ops = get_dma_ops(dev); 34 + 35 + if (dma_ops->dma_supported == NULL) 36 + return 1; 37 + return dma_ops->dma_supported(dev, mask); 38 + } 39 + 40 + static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) 41 + { 42 + if (!dev->dma_mask) 43 + return 0; 44 + return addr + size - 1 <= *dev->dma_mask; 45 + } 46 + 47 + static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) 48 + { 49 + struct dma_map_ops *dma_ops = get_dma_ops(dev); 50 + 51 + if (dma_ops->mapping_error) 52 + return dma_ops->mapping_error(dev, dma_addr); 53 + return (dma_addr == 0UL); 54 + } 55 + 56 + static inline void *dma_alloc_coherent(struct device *dev, size_t size, 57 + dma_addr_t *dma_handle, gfp_t flag) 58 + { 59 + struct dma_map_ops *ops = get_dma_ops(dev); 60 + void *ret; 61 + 62 + ret = ops->alloc(dev, size, dma_handle, flag, NULL); 63 + debug_dma_alloc_coherent(dev, size, *dma_handle, ret); 64 + return ret; 65 + } 66 + 67 + static inline void dma_free_coherent(struct device *dev, size_t size, 68 + void *cpu_addr, dma_addr_t dma_handle) 69 + { 70 + struct dma_map_ops *dma_ops = get_dma_ops(dev); 71 + 72 + dma_ops->free(dev, size, cpu_addr, dma_handle, NULL); 73 + debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); 74 + } 75 + 76 + #endif /* _ASM_S390_DMA_MAPPING_H */
+9 -10
arch/s390/include/asm/dma.h
··· 1 + #ifndef _ASM_S390_DMA_H 2 + #define _ASM_S390_DMA_H 3 + 4 + #include <asm/io.h> 5 + 1 6 /* 2 - * S390 version 7 + * MAX_DMA_ADDRESS is ambiguous because on s390 its completely unrelated 8 + * to DMA. It _is_ used for the s390 memory zone split at 2GB caused 9 + * by the 31 bit heritage. 3 10 */ 4 - 5 - #ifndef _ASM_DMA_H 6 - #define _ASM_DMA_H 7 - 8 - #include <asm/io.h> /* need byte IO */ 9 - 10 11 #define MAX_DMA_ADDRESS 0x80000000 11 12 12 - #define free_dma(x) do { } while (0) 13 - 14 - #endif /* _ASM_DMA_H */ 13 + #endif /* _ASM_S390_DMA_H */
+22
arch/s390/include/asm/hw_irq.h
··· 1 + #ifndef _HW_IRQ_H 2 + #define _HW_IRQ_H 3 + 4 + #include <linux/msi.h> 5 + #include <linux/pci.h> 6 + 7 + static inline struct msi_desc *irq_get_msi_desc(unsigned int irq) 8 + { 9 + return __irq_get_msi_desc(irq); 10 + } 11 + 12 + /* Must be called with msi map lock held */ 13 + static inline int irq_set_msi_desc(unsigned int irq, struct msi_desc *msi) 14 + { 15 + if (!msi) 16 + return -EINVAL; 17 + 18 + msi->irq = irq; 19 + return 0; 20 + } 21 + 22 + #endif
+51 -4
arch/s390/include/asm/io.h
··· 9 9 #ifndef _S390_IO_H 10 10 #define _S390_IO_H 11 11 12 + #include <linux/kernel.h> 12 13 #include <asm/page.h> 13 - 14 - #define IO_SPACE_LIMIT 0xffffffff 14 + #include <asm/pci_io.h> 15 15 16 16 /* 17 17 * Change virtual addresses to physical addresses and vv. ··· 24 24 " lra %0,0(%1)\n" 25 25 " jz 0f\n" 26 26 " la %0,0\n" 27 - "0:" 27 + "0:" 28 28 : "=a" (real_address) : "a" (address) : "cc"); 29 - return real_address; 29 + return real_address; 30 30 } 31 + #define virt_to_phys virt_to_phys 31 32 32 33 static inline void * phys_to_virt(unsigned long address) 33 34 { ··· 42 41 * Convert a virtual cached pointer to an uncached pointer 43 42 */ 44 43 #define xlate_dev_kmem_ptr(p) p 44 + 45 + #define IO_SPACE_LIMIT 0 46 + 47 + #ifdef CONFIG_PCI 48 + 49 + #define ioremap_nocache(addr, size) ioremap(addr, size) 50 + #define ioremap_wc ioremap_nocache 51 + 52 + /* TODO: s390 cannot support io_remap_pfn_range... */ 53 + #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ 54 + remap_pfn_range(vma, vaddr, pfn, size, prot) 55 + 56 + static inline void __iomem *ioremap(unsigned long offset, unsigned long size) 57 + { 58 + return (void __iomem *) offset; 59 + } 60 + 61 + static inline void iounmap(volatile void __iomem *addr) 62 + { 63 + } 64 + 65 + /* 66 + * s390 needs a private implementation of pci_iomap since ioremap with its 67 + * offset parameter isn't sufficient. That's because BAR spaces are not 68 + * disjunctive on s390 so we need the bar parameter of pci_iomap to find 69 + * the corresponding device and create the mapping cookie. 70 + */ 71 + #define pci_iomap pci_iomap 72 + #define pci_iounmap pci_iounmap 73 + 74 + #define memcpy_fromio(dst, src, count) zpci_memcpy_fromio(dst, src, count) 75 + #define memcpy_toio(dst, src, count) zpci_memcpy_toio(dst, src, count) 76 + #define memset_io(dst, val, count) zpci_memset_io(dst, val, count) 77 + 78 + #define __raw_readb zpci_read_u8 79 + #define __raw_readw zpci_read_u16 80 + #define __raw_readl zpci_read_u32 81 + #define __raw_readq zpci_read_u64 82 + #define __raw_writeb zpci_write_u8 83 + #define __raw_writew zpci_write_u16 84 + #define __raw_writel zpci_write_u32 85 + #define __raw_writeq zpci_write_u64 86 + 87 + #endif /* CONFIG_PCI */ 88 + 89 + #include <asm-generic/io.h> 45 90 46 91 #endif
+12
arch/s390/include/asm/irq.h
··· 33 33 IOINT_APB, 34 34 IOINT_ADM, 35 35 IOINT_CSC, 36 + IOINT_PCI, 37 + IOINT_MSI, 36 38 NMI_NMI, 37 39 NR_IRQS, 38 40 }; ··· 52 50 void service_subclass_irq_unregister(void); 53 51 void measurement_alert_subclass_register(void); 54 52 void measurement_alert_subclass_unregister(void); 53 + 54 + #ifdef CONFIG_LOCKDEP 55 + # define disable_irq_nosync_lockdep(irq) disable_irq_nosync(irq) 56 + # define disable_irq_nosync_lockdep_irqsave(irq, flags) \ 57 + disable_irq_nosync(irq) 58 + # define disable_irq_lockdep(irq) disable_irq(irq) 59 + # define enable_irq_lockdep(irq) enable_irq(irq) 60 + # define enable_irq_lockdep_irqrestore(irq, flags) \ 61 + enable_irq(irq) 62 + #endif 55 63 56 64 #endif /* _ASM_IRQ_H */
+1
arch/s390/include/asm/isc.h
··· 18 18 #define CHSC_SCH_ISC 7 /* CHSC subchannels */ 19 19 /* Adapter interrupts. */ 20 20 #define QDIO_AIRQ_ISC IO_SCH_ISC /* I/O subchannel in qdio mode */ 21 + #define PCI_ISC 2 /* PCI I/O subchannels */ 21 22 #define AP_ISC 6 /* adjunct processor (crypto) devices */ 22 23 23 24 /* Functions for registration of I/O interruption subclasses */
+2
arch/s390/include/asm/page.h
··· 30 30 #include <asm/setup.h> 31 31 #ifndef __ASSEMBLY__ 32 32 33 + void storage_key_init_range(unsigned long start, unsigned long end); 34 + 33 35 static unsigned long pfmf(unsigned long function, unsigned long address) 34 36 { 35 37 asm volatile(
+152 -4
arch/s390/include/asm/pci.h
··· 1 1 #ifndef __ASM_S390_PCI_H 2 2 #define __ASM_S390_PCI_H 3 3 4 - /* S/390 systems don't have a PCI bus. This file is just here because some stupid .c code 5 - * includes it even if CONFIG_PCI is not set. 6 - */ 4 + /* must be set before including asm-generic/pci.h */ 7 5 #define PCI_DMA_BUS_IS_PHYS (0) 6 + /* must be set before including pci_clp.h */ 7 + #define PCI_BAR_COUNT 6 8 8 9 - #endif /* __ASM_S390_PCI_H */ 9 + #include <asm-generic/pci.h> 10 + #include <asm-generic/pci-dma-compat.h> 11 + #include <asm/pci_clp.h> 10 12 13 + #define PCIBIOS_MIN_IO 0x1000 14 + #define PCIBIOS_MIN_MEM 0x10000000 15 + 16 + #define pcibios_assign_all_busses() (0) 17 + 18 + void __iomem *pci_iomap(struct pci_dev *, int, unsigned long); 19 + void pci_iounmap(struct pci_dev *, void __iomem *); 20 + int pci_domain_nr(struct pci_bus *); 21 + int pci_proc_domain(struct pci_bus *); 22 + 23 + /* MSI arch hooks */ 24 + #define arch_setup_msi_irqs arch_setup_msi_irqs 25 + #define arch_teardown_msi_irqs arch_teardown_msi_irqs 26 + 27 + #define ZPCI_BUS_NR 0 /* default bus number */ 28 + #define ZPCI_DEVFN 0 /* default device number */ 29 + 30 + /* PCI Function Controls */ 31 + #define ZPCI_FC_FN_ENABLED 0x80 32 + #define ZPCI_FC_ERROR 0x40 33 + #define ZPCI_FC_BLOCKED 0x20 34 + #define ZPCI_FC_DMA_ENABLED 0x10 35 + 36 + struct msi_map { 37 + unsigned long irq; 38 + struct msi_desc *msi; 39 + struct hlist_node msi_chain; 40 + }; 41 + 42 + #define ZPCI_NR_MSI_VECS 64 43 + #define ZPCI_MSI_MASK (ZPCI_NR_MSI_VECS - 1) 44 + 45 + enum zpci_state { 46 + ZPCI_FN_STATE_RESERVED, 47 + ZPCI_FN_STATE_STANDBY, 48 + ZPCI_FN_STATE_CONFIGURED, 49 + ZPCI_FN_STATE_ONLINE, 50 + NR_ZPCI_FN_STATES, 51 + }; 52 + 53 + struct zpci_bar_struct { 54 + u32 val; /* bar start & 3 flag bits */ 55 + u8 size; /* order 2 exponent */ 56 + u16 map_idx; /* index into bar mapping array */ 57 + }; 58 + 59 + /* Private data per function */ 60 + struct zpci_dev { 61 + struct pci_dev *pdev; 62 + struct pci_bus *bus; 63 + struct list_head entry; /* list of all zpci_devices, needed for hotplug, etc. */ 64 + 65 + enum zpci_state state; 66 + u32 fid; /* function ID, used by sclp */ 67 + u32 fh; /* function handle, used by insn's */ 68 + u16 pchid; /* physical channel ID */ 69 + u8 pfgid; /* function group ID */ 70 + u16 domain; 71 + 72 + /* IRQ stuff */ 73 + u64 msi_addr; /* MSI address */ 74 + struct zdev_irq_map *irq_map; 75 + struct msi_map *msi_map[ZPCI_NR_MSI_VECS]; 76 + unsigned int aisb; /* number of the summary bit */ 77 + 78 + /* DMA stuff */ 79 + unsigned long *dma_table; 80 + spinlock_t dma_table_lock; 81 + int tlb_refresh; 82 + 83 + spinlock_t iommu_bitmap_lock; 84 + unsigned long *iommu_bitmap; 85 + unsigned long iommu_size; 86 + unsigned long iommu_pages; 87 + unsigned int next_bit; 88 + 89 + struct zpci_bar_struct bars[PCI_BAR_COUNT]; 90 + 91 + u64 start_dma; /* Start of available DMA addresses */ 92 + u64 end_dma; /* End of available DMA addresses */ 93 + u64 dma_mask; /* DMA address space mask */ 94 + 95 + enum pci_bus_speed max_bus_speed; 96 + }; 97 + 98 + struct pci_hp_callback_ops { 99 + int (*create_slot) (struct zpci_dev *zdev); 100 + void (*remove_slot) (struct zpci_dev *zdev); 101 + }; 102 + 103 + static inline bool zdev_enabled(struct zpci_dev *zdev) 104 + { 105 + return (zdev->fh & (1UL << 31)) ? true : false; 106 + } 107 + 108 + /* ----------------------------------------------------------------------------- 109 + Prototypes 110 + ----------------------------------------------------------------------------- */ 111 + /* Base stuff */ 112 + struct zpci_dev *zpci_alloc_device(void); 113 + int zpci_create_device(struct zpci_dev *); 114 + int zpci_enable_device(struct zpci_dev *); 115 + void zpci_stop_device(struct zpci_dev *); 116 + void zpci_free_device(struct zpci_dev *); 117 + int zpci_scan_device(struct zpci_dev *); 118 + int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64); 119 + int zpci_unregister_ioat(struct zpci_dev *, u8); 120 + 121 + /* CLP */ 122 + int clp_find_pci_devices(void); 123 + int clp_add_pci_device(u32, u32, int); 124 + int clp_enable_fh(struct zpci_dev *, u8); 125 + int clp_disable_fh(struct zpci_dev *); 126 + 127 + /* MSI */ 128 + struct msi_desc *__irq_get_msi_desc(unsigned int); 129 + int zpci_msi_set_mask_bits(struct msi_desc *, u32, u32); 130 + int zpci_setup_msi_irq(struct zpci_dev *, struct msi_desc *, unsigned int, int); 131 + void zpci_teardown_msi_irq(struct zpci_dev *, struct msi_desc *); 132 + int zpci_msihash_init(void); 133 + void zpci_msihash_exit(void); 134 + 135 + /* Error handling and recovery */ 136 + void zpci_event_error(void *); 137 + void zpci_event_availability(void *); 138 + 139 + /* Helpers */ 140 + struct zpci_dev *get_zdev(struct pci_dev *); 141 + struct zpci_dev *get_zdev_by_fid(u32); 142 + bool zpci_fid_present(u32); 143 + 144 + /* sysfs */ 145 + int zpci_sysfs_add_device(struct device *); 146 + void zpci_sysfs_remove_device(struct device *); 147 + 148 + /* DMA */ 149 + int zpci_dma_init(void); 150 + void zpci_dma_exit(void); 151 + 152 + /* Hotplug */ 153 + extern struct mutex zpci_list_lock; 154 + extern struct list_head zpci_list; 155 + extern struct pci_hp_callback_ops hotplug_ops; 156 + extern unsigned int pci_probe; 157 + 158 + #endif
+182
arch/s390/include/asm/pci_clp.h
··· 1 + #ifndef _ASM_S390_PCI_CLP_H 2 + #define _ASM_S390_PCI_CLP_H 3 + 4 + #include <asm/clp.h> 5 + 6 + /* 7 + * Call Logical Processor - Command Codes 8 + */ 9 + #define CLP_LIST_PCI 0x0002 10 + #define CLP_QUERY_PCI_FN 0x0003 11 + #define CLP_QUERY_PCI_FNGRP 0x0004 12 + #define CLP_SET_PCI_FN 0x0005 13 + 14 + /* PCI function handle list entry */ 15 + struct clp_fh_list_entry { 16 + u16 device_id; 17 + u16 vendor_id; 18 + u32 config_state : 1; 19 + u32 : 31; 20 + u32 fid; /* PCI function id */ 21 + u32 fh; /* PCI function handle */ 22 + } __packed; 23 + 24 + #define CLP_RC_SETPCIFN_FH 0x0101 /* Invalid PCI fn handle */ 25 + #define CLP_RC_SETPCIFN_FHOP 0x0102 /* Fn handle not valid for op */ 26 + #define CLP_RC_SETPCIFN_DMAAS 0x0103 /* Invalid DMA addr space */ 27 + #define CLP_RC_SETPCIFN_RES 0x0104 /* Insufficient resources */ 28 + #define CLP_RC_SETPCIFN_ALRDY 0x0105 /* Fn already in requested state */ 29 + #define CLP_RC_SETPCIFN_ERR 0x0106 /* Fn in permanent error state */ 30 + #define CLP_RC_SETPCIFN_RECPND 0x0107 /* Error recovery pending */ 31 + #define CLP_RC_SETPCIFN_BUSY 0x0108 /* Fn busy */ 32 + #define CLP_RC_LISTPCI_BADRT 0x010a /* Resume token not recognized */ 33 + #define CLP_RC_QUERYPCIFG_PFGID 0x010b /* Unrecognized PFGID */ 34 + 35 + /* request or response block header length */ 36 + #define LIST_PCI_HDR_LEN 32 37 + 38 + /* Number of function handles fitting in response block */ 39 + #define CLP_FH_LIST_NR_ENTRIES \ 40 + ((CLP_BLK_SIZE - 2 * LIST_PCI_HDR_LEN) \ 41 + / sizeof(struct clp_fh_list_entry)) 42 + 43 + #define CLP_SET_ENABLE_PCI_FN 0 /* Yes, 0 enables it */ 44 + #define CLP_SET_DISABLE_PCI_FN 1 /* Yes, 1 disables it */ 45 + 46 + #define CLP_UTIL_STR_LEN 64 47 + 48 + /* List PCI functions request */ 49 + struct clp_req_list_pci { 50 + struct clp_req_hdr hdr; 51 + u32 fmt : 4; /* cmd request block format */ 52 + u32 : 28; 53 + u64 reserved1; 54 + u64 resume_token; 55 + u64 reserved2; 56 + } __packed; 57 + 58 + /* List PCI functions response */ 59 + struct clp_rsp_list_pci { 60 + struct clp_rsp_hdr hdr; 61 + u32 fmt : 4; /* cmd request block format */ 62 + u32 : 28; 63 + u64 reserved1; 64 + u64 resume_token; 65 + u32 reserved2; 66 + u16 max_fn; 67 + u8 reserved3; 68 + u8 entry_size; 69 + struct clp_fh_list_entry fh_list[CLP_FH_LIST_NR_ENTRIES]; 70 + } __packed; 71 + 72 + /* Query PCI function request */ 73 + struct clp_req_query_pci { 74 + struct clp_req_hdr hdr; 75 + u32 fmt : 4; /* cmd request block format */ 76 + u32 : 28; 77 + u64 reserved1; 78 + u32 fh; /* function handle */ 79 + u32 reserved2; 80 + u64 reserved3; 81 + } __packed; 82 + 83 + /* Query PCI function response */ 84 + struct clp_rsp_query_pci { 85 + struct clp_rsp_hdr hdr; 86 + u32 fmt : 4; /* cmd request block format */ 87 + u32 : 28; 88 + u64 reserved1; 89 + u16 vfn; /* virtual fn number */ 90 + u16 : 7; 91 + u16 util_str_avail : 1; /* utility string available? */ 92 + u16 pfgid : 8; /* pci function group id */ 93 + u32 fid; /* pci function id */ 94 + u8 bar_size[PCI_BAR_COUNT]; 95 + u16 pchid; 96 + u32 bar[PCI_BAR_COUNT]; 97 + u64 reserved2; 98 + u64 sdma; /* start dma as */ 99 + u64 edma; /* end dma as */ 100 + u64 reserved3[6]; 101 + u8 util_str[CLP_UTIL_STR_LEN]; /* utility string */ 102 + } __packed; 103 + 104 + /* Query PCI function group request */ 105 + struct clp_req_query_pci_grp { 106 + struct clp_req_hdr hdr; 107 + u32 fmt : 4; /* cmd request block format */ 108 + u32 : 28; 109 + u64 reserved1; 110 + u32 : 24; 111 + u32 pfgid : 8; /* function group id */ 112 + u32 reserved2; 113 + u64 reserved3; 114 + } __packed; 115 + 116 + /* Query PCI function group response */ 117 + struct clp_rsp_query_pci_grp { 118 + struct clp_rsp_hdr hdr; 119 + u32 fmt : 4; /* cmd request block format */ 120 + u32 : 28; 121 + u64 reserved1; 122 + u16 : 4; 123 + u16 noi : 12; /* number of interrupts */ 124 + u8 version; 125 + u8 : 6; 126 + u8 frame : 1; 127 + u8 refresh : 1; /* TLB refresh mode */ 128 + u16 reserved2; 129 + u16 mui; 130 + u64 reserved3; 131 + u64 dasm; /* dma address space mask */ 132 + u64 msia; /* MSI address */ 133 + u64 reserved4; 134 + u64 reserved5; 135 + } __packed; 136 + 137 + /* Set PCI function request */ 138 + struct clp_req_set_pci { 139 + struct clp_req_hdr hdr; 140 + u32 fmt : 4; /* cmd request block format */ 141 + u32 : 28; 142 + u64 reserved1; 143 + u32 fh; /* function handle */ 144 + u16 reserved2; 145 + u8 oc; /* operation controls */ 146 + u8 ndas; /* number of dma spaces */ 147 + u64 reserved3; 148 + } __packed; 149 + 150 + /* Set PCI function response */ 151 + struct clp_rsp_set_pci { 152 + struct clp_rsp_hdr hdr; 153 + u32 fmt : 4; /* cmd request block format */ 154 + u32 : 28; 155 + u64 reserved1; 156 + u32 fh; /* function handle */ 157 + u32 reserved3; 158 + u64 reserved4; 159 + } __packed; 160 + 161 + /* Combined request/response block structures used by clp insn */ 162 + struct clp_req_rsp_list_pci { 163 + struct clp_req_list_pci request; 164 + struct clp_rsp_list_pci response; 165 + } __packed; 166 + 167 + struct clp_req_rsp_set_pci { 168 + struct clp_req_set_pci request; 169 + struct clp_rsp_set_pci response; 170 + } __packed; 171 + 172 + struct clp_req_rsp_query_pci { 173 + struct clp_req_query_pci request; 174 + struct clp_rsp_query_pci response; 175 + } __packed; 176 + 177 + struct clp_req_rsp_query_pci_grp { 178 + struct clp_req_query_pci_grp request; 179 + struct clp_rsp_query_pci_grp response; 180 + } __packed; 181 + 182 + #endif
+196
arch/s390/include/asm/pci_dma.h
··· 1 + #ifndef _ASM_S390_PCI_DMA_H 2 + #define _ASM_S390_PCI_DMA_H 3 + 4 + /* I/O Translation Anchor (IOTA) */ 5 + enum zpci_ioat_dtype { 6 + ZPCI_IOTA_STO = 0, 7 + ZPCI_IOTA_RTTO = 1, 8 + ZPCI_IOTA_RSTO = 2, 9 + ZPCI_IOTA_RFTO = 3, 10 + ZPCI_IOTA_PFAA = 4, 11 + ZPCI_IOTA_IOPFAA = 5, 12 + ZPCI_IOTA_IOPTO = 7 13 + }; 14 + 15 + #define ZPCI_IOTA_IOT_ENABLED 0x800UL 16 + #define ZPCI_IOTA_DT_ST (ZPCI_IOTA_STO << 2) 17 + #define ZPCI_IOTA_DT_RT (ZPCI_IOTA_RTTO << 2) 18 + #define ZPCI_IOTA_DT_RS (ZPCI_IOTA_RSTO << 2) 19 + #define ZPCI_IOTA_DT_RF (ZPCI_IOTA_RFTO << 2) 20 + #define ZPCI_IOTA_DT_PF (ZPCI_IOTA_PFAA << 2) 21 + #define ZPCI_IOTA_FS_4K 0 22 + #define ZPCI_IOTA_FS_1M 1 23 + #define ZPCI_IOTA_FS_2G 2 24 + #define ZPCI_KEY (PAGE_DEFAULT_KEY << 5) 25 + 26 + #define ZPCI_IOTA_STO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_ST) 27 + #define ZPCI_IOTA_RTTO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RT) 28 + #define ZPCI_IOTA_RSTO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RS) 29 + #define ZPCI_IOTA_RFTO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RF) 30 + #define ZPCI_IOTA_RFAA_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_PF | ZPCI_IOTA_FS_2G) 31 + 32 + /* I/O Region and segment tables */ 33 + #define ZPCI_INDEX_MASK 0x7ffUL 34 + 35 + #define ZPCI_TABLE_TYPE_MASK 0xc 36 + #define ZPCI_TABLE_TYPE_RFX 0xc 37 + #define ZPCI_TABLE_TYPE_RSX 0x8 38 + #define ZPCI_TABLE_TYPE_RTX 0x4 39 + #define ZPCI_TABLE_TYPE_SX 0x0 40 + 41 + #define ZPCI_TABLE_LEN_RFX 0x3 42 + #define ZPCI_TABLE_LEN_RSX 0x3 43 + #define ZPCI_TABLE_LEN_RTX 0x3 44 + 45 + #define ZPCI_TABLE_OFFSET_MASK 0xc0 46 + #define ZPCI_TABLE_SIZE 0x4000 47 + #define ZPCI_TABLE_ALIGN ZPCI_TABLE_SIZE 48 + #define ZPCI_TABLE_ENTRY_SIZE (sizeof(unsigned long)) 49 + #define ZPCI_TABLE_ENTRIES (ZPCI_TABLE_SIZE / ZPCI_TABLE_ENTRY_SIZE) 50 + 51 + #define ZPCI_TABLE_BITS 11 52 + #define ZPCI_PT_BITS 8 53 + #define ZPCI_ST_SHIFT (ZPCI_PT_BITS + PAGE_SHIFT) 54 + #define ZPCI_RT_SHIFT (ZPCI_ST_SHIFT + ZPCI_TABLE_BITS) 55 + 56 + #define ZPCI_RTE_FLAG_MASK 0x3fffUL 57 + #define ZPCI_RTE_ADDR_MASK (~ZPCI_RTE_FLAG_MASK) 58 + #define ZPCI_STE_FLAG_MASK 0x7ffUL 59 + #define ZPCI_STE_ADDR_MASK (~ZPCI_STE_FLAG_MASK) 60 + 61 + /* I/O Page tables */ 62 + #define ZPCI_PTE_VALID_MASK 0x400 63 + #define ZPCI_PTE_INVALID 0x400 64 + #define ZPCI_PTE_VALID 0x000 65 + #define ZPCI_PT_SIZE 0x800 66 + #define ZPCI_PT_ALIGN ZPCI_PT_SIZE 67 + #define ZPCI_PT_ENTRIES (ZPCI_PT_SIZE / ZPCI_TABLE_ENTRY_SIZE) 68 + #define ZPCI_PT_MASK (ZPCI_PT_ENTRIES - 1) 69 + 70 + #define ZPCI_PTE_FLAG_MASK 0xfffUL 71 + #define ZPCI_PTE_ADDR_MASK (~ZPCI_PTE_FLAG_MASK) 72 + 73 + /* Shared bits */ 74 + #define ZPCI_TABLE_VALID 0x00 75 + #define ZPCI_TABLE_INVALID 0x20 76 + #define ZPCI_TABLE_PROTECTED 0x200 77 + #define ZPCI_TABLE_UNPROTECTED 0x000 78 + 79 + #define ZPCI_TABLE_VALID_MASK 0x20 80 + #define ZPCI_TABLE_PROT_MASK 0x200 81 + 82 + static inline unsigned int calc_rtx(dma_addr_t ptr) 83 + { 84 + return ((unsigned long) ptr >> ZPCI_RT_SHIFT) & ZPCI_INDEX_MASK; 85 + } 86 + 87 + static inline unsigned int calc_sx(dma_addr_t ptr) 88 + { 89 + return ((unsigned long) ptr >> ZPCI_ST_SHIFT) & ZPCI_INDEX_MASK; 90 + } 91 + 92 + static inline unsigned int calc_px(dma_addr_t ptr) 93 + { 94 + return ((unsigned long) ptr >> PAGE_SHIFT) & ZPCI_PT_MASK; 95 + } 96 + 97 + static inline void set_pt_pfaa(unsigned long *entry, void *pfaa) 98 + { 99 + *entry &= ZPCI_PTE_FLAG_MASK; 100 + *entry |= ((unsigned long) pfaa & ZPCI_PTE_ADDR_MASK); 101 + } 102 + 103 + static inline void set_rt_sto(unsigned long *entry, void *sto) 104 + { 105 + *entry &= ZPCI_RTE_FLAG_MASK; 106 + *entry |= ((unsigned long) sto & ZPCI_RTE_ADDR_MASK); 107 + *entry |= ZPCI_TABLE_TYPE_RTX; 108 + } 109 + 110 + static inline void set_st_pto(unsigned long *entry, void *pto) 111 + { 112 + *entry &= ZPCI_STE_FLAG_MASK; 113 + *entry |= ((unsigned long) pto & ZPCI_STE_ADDR_MASK); 114 + *entry |= ZPCI_TABLE_TYPE_SX; 115 + } 116 + 117 + static inline void validate_rt_entry(unsigned long *entry) 118 + { 119 + *entry &= ~ZPCI_TABLE_VALID_MASK; 120 + *entry &= ~ZPCI_TABLE_OFFSET_MASK; 121 + *entry |= ZPCI_TABLE_VALID; 122 + *entry |= ZPCI_TABLE_LEN_RTX; 123 + } 124 + 125 + static inline void validate_st_entry(unsigned long *entry) 126 + { 127 + *entry &= ~ZPCI_TABLE_VALID_MASK; 128 + *entry |= ZPCI_TABLE_VALID; 129 + } 130 + 131 + static inline void invalidate_table_entry(unsigned long *entry) 132 + { 133 + *entry &= ~ZPCI_TABLE_VALID_MASK; 134 + *entry |= ZPCI_TABLE_INVALID; 135 + } 136 + 137 + static inline void invalidate_pt_entry(unsigned long *entry) 138 + { 139 + WARN_ON_ONCE((*entry & ZPCI_PTE_VALID_MASK) == ZPCI_PTE_INVALID); 140 + *entry &= ~ZPCI_PTE_VALID_MASK; 141 + *entry |= ZPCI_PTE_INVALID; 142 + } 143 + 144 + static inline void validate_pt_entry(unsigned long *entry) 145 + { 146 + WARN_ON_ONCE((*entry & ZPCI_PTE_VALID_MASK) == ZPCI_PTE_VALID); 147 + *entry &= ~ZPCI_PTE_VALID_MASK; 148 + *entry |= ZPCI_PTE_VALID; 149 + } 150 + 151 + static inline void entry_set_protected(unsigned long *entry) 152 + { 153 + *entry &= ~ZPCI_TABLE_PROT_MASK; 154 + *entry |= ZPCI_TABLE_PROTECTED; 155 + } 156 + 157 + static inline void entry_clr_protected(unsigned long *entry) 158 + { 159 + *entry &= ~ZPCI_TABLE_PROT_MASK; 160 + *entry |= ZPCI_TABLE_UNPROTECTED; 161 + } 162 + 163 + static inline int reg_entry_isvalid(unsigned long entry) 164 + { 165 + return (entry & ZPCI_TABLE_VALID_MASK) == ZPCI_TABLE_VALID; 166 + } 167 + 168 + static inline int pt_entry_isvalid(unsigned long entry) 169 + { 170 + return (entry & ZPCI_PTE_VALID_MASK) == ZPCI_PTE_VALID; 171 + } 172 + 173 + static inline int entry_isprotected(unsigned long entry) 174 + { 175 + return (entry & ZPCI_TABLE_PROT_MASK) == ZPCI_TABLE_PROTECTED; 176 + } 177 + 178 + static inline unsigned long *get_rt_sto(unsigned long entry) 179 + { 180 + return ((entry & ZPCI_TABLE_TYPE_MASK) == ZPCI_TABLE_TYPE_RTX) 181 + ? (unsigned long *) (entry & ZPCI_RTE_ADDR_MASK) 182 + : NULL; 183 + } 184 + 185 + static inline unsigned long *get_st_pto(unsigned long entry) 186 + { 187 + return ((entry & ZPCI_TABLE_TYPE_MASK) == ZPCI_TABLE_TYPE_SX) 188 + ? (unsigned long *) (entry & ZPCI_STE_ADDR_MASK) 189 + : NULL; 190 + } 191 + 192 + /* Prototypes */ 193 + int zpci_dma_init_device(struct zpci_dev *); 194 + void zpci_dma_exit_device(struct zpci_dev *); 195 + 196 + #endif
+280
arch/s390/include/asm/pci_insn.h
··· 1 + #ifndef _ASM_S390_PCI_INSN_H 2 + #define _ASM_S390_PCI_INSN_H 3 + 4 + #include <linux/delay.h> 5 + 6 + #define ZPCI_INSN_BUSY_DELAY 1 /* 1 microsecond */ 7 + 8 + /* Load/Store status codes */ 9 + #define ZPCI_PCI_ST_FUNC_NOT_ENABLED 4 10 + #define ZPCI_PCI_ST_FUNC_IN_ERR 8 11 + #define ZPCI_PCI_ST_BLOCKED 12 12 + #define ZPCI_PCI_ST_INSUF_RES 16 13 + #define ZPCI_PCI_ST_INVAL_AS 20 14 + #define ZPCI_PCI_ST_FUNC_ALREADY_ENABLED 24 15 + #define ZPCI_PCI_ST_DMA_AS_NOT_ENABLED 28 16 + #define ZPCI_PCI_ST_2ND_OP_IN_INV_AS 36 17 + #define ZPCI_PCI_ST_FUNC_NOT_AVAIL 40 18 + #define ZPCI_PCI_ST_ALREADY_IN_RQ_STATE 44 19 + 20 + /* Load/Store return codes */ 21 + #define ZPCI_PCI_LS_OK 0 22 + #define ZPCI_PCI_LS_ERR 1 23 + #define ZPCI_PCI_LS_BUSY 2 24 + #define ZPCI_PCI_LS_INVAL_HANDLE 3 25 + 26 + /* Load/Store address space identifiers */ 27 + #define ZPCI_PCIAS_MEMIO_0 0 28 + #define ZPCI_PCIAS_MEMIO_1 1 29 + #define ZPCI_PCIAS_MEMIO_2 2 30 + #define ZPCI_PCIAS_MEMIO_3 3 31 + #define ZPCI_PCIAS_MEMIO_4 4 32 + #define ZPCI_PCIAS_MEMIO_5 5 33 + #define ZPCI_PCIAS_CFGSPC 15 34 + 35 + /* Modify PCI Function Controls */ 36 + #define ZPCI_MOD_FC_REG_INT 2 37 + #define ZPCI_MOD_FC_DEREG_INT 3 38 + #define ZPCI_MOD_FC_REG_IOAT 4 39 + #define ZPCI_MOD_FC_DEREG_IOAT 5 40 + #define ZPCI_MOD_FC_REREG_IOAT 6 41 + #define ZPCI_MOD_FC_RESET_ERROR 7 42 + #define ZPCI_MOD_FC_RESET_BLOCK 9 43 + #define ZPCI_MOD_FC_SET_MEASURE 10 44 + 45 + /* FIB function controls */ 46 + #define ZPCI_FIB_FC_ENABLED 0x80 47 + #define ZPCI_FIB_FC_ERROR 0x40 48 + #define ZPCI_FIB_FC_LS_BLOCKED 0x20 49 + #define ZPCI_FIB_FC_DMAAS_REG 0x10 50 + 51 + /* FIB function controls */ 52 + #define ZPCI_FIB_FC_ENABLED 0x80 53 + #define ZPCI_FIB_FC_ERROR 0x40 54 + #define ZPCI_FIB_FC_LS_BLOCKED 0x20 55 + #define ZPCI_FIB_FC_DMAAS_REG 0x10 56 + 57 + /* Function Information Block */ 58 + struct zpci_fib { 59 + u32 fmt : 8; /* format */ 60 + u32 : 24; 61 + u32 reserved1; 62 + u8 fc; /* function controls */ 63 + u8 reserved2; 64 + u16 reserved3; 65 + u32 reserved4; 66 + u64 pba; /* PCI base address */ 67 + u64 pal; /* PCI address limit */ 68 + u64 iota; /* I/O Translation Anchor */ 69 + u32 : 1; 70 + u32 isc : 3; /* Interrupt subclass */ 71 + u32 noi : 12; /* Number of interrupts */ 72 + u32 : 2; 73 + u32 aibvo : 6; /* Adapter interrupt bit vector offset */ 74 + u32 sum : 1; /* Adapter int summary bit enabled */ 75 + u32 : 1; 76 + u32 aisbo : 6; /* Adapter int summary bit offset */ 77 + u32 reserved5; 78 + u64 aibv; /* Adapter int bit vector address */ 79 + u64 aisb; /* Adapter int summary bit address */ 80 + u64 fmb_addr; /* Function measurement block address and key */ 81 + u64 reserved6; 82 + u64 reserved7; 83 + } __packed; 84 + 85 + /* Modify PCI Function Controls */ 86 + static inline u8 __mpcifc(u64 req, struct zpci_fib *fib, u8 *status) 87 + { 88 + u8 cc; 89 + 90 + asm volatile ( 91 + " .insn rxy,0xe300000000d0,%[req],%[fib]\n" 92 + " ipm %[cc]\n" 93 + " srl %[cc],28\n" 94 + : [cc] "=d" (cc), [req] "+d" (req), [fib] "+Q" (*fib) 95 + : : "cc"); 96 + *status = req >> 24 & 0xff; 97 + return cc; 98 + } 99 + 100 + static inline int mpcifc_instr(u64 req, struct zpci_fib *fib) 101 + { 102 + u8 cc, status; 103 + 104 + do { 105 + cc = __mpcifc(req, fib, &status); 106 + if (cc == 2) 107 + msleep(ZPCI_INSN_BUSY_DELAY); 108 + } while (cc == 2); 109 + 110 + if (cc) 111 + printk_once(KERN_ERR "%s: error cc: %d status: %d\n", 112 + __func__, cc, status); 113 + return (cc) ? -EIO : 0; 114 + } 115 + 116 + /* Refresh PCI Translations */ 117 + static inline u8 __rpcit(u64 fn, u64 addr, u64 range, u8 *status) 118 + { 119 + register u64 __addr asm("2") = addr; 120 + register u64 __range asm("3") = range; 121 + u8 cc; 122 + 123 + asm volatile ( 124 + " .insn rre,0xb9d30000,%[fn],%[addr]\n" 125 + " ipm %[cc]\n" 126 + " srl %[cc],28\n" 127 + : [cc] "=d" (cc), [fn] "+d" (fn) 128 + : [addr] "d" (__addr), "d" (__range) 129 + : "cc"); 130 + *status = fn >> 24 & 0xff; 131 + return cc; 132 + } 133 + 134 + static inline int rpcit_instr(u64 fn, u64 addr, u64 range) 135 + { 136 + u8 cc, status; 137 + 138 + do { 139 + cc = __rpcit(fn, addr, range, &status); 140 + if (cc == 2) 141 + udelay(ZPCI_INSN_BUSY_DELAY); 142 + } while (cc == 2); 143 + 144 + if (cc) 145 + printk_once(KERN_ERR "%s: error cc: %d status: %d dma_addr: %Lx size: %Lx\n", 146 + __func__, cc, status, addr, range); 147 + return (cc) ? -EIO : 0; 148 + } 149 + 150 + /* Store PCI function controls */ 151 + static inline u8 __stpcifc(u32 handle, u8 space, struct zpci_fib *fib, u8 *status) 152 + { 153 + u64 fn = (u64) handle << 32 | space << 16; 154 + u8 cc; 155 + 156 + asm volatile ( 157 + " .insn rxy,0xe300000000d4,%[fn],%[fib]\n" 158 + " ipm %[cc]\n" 159 + " srl %[cc],28\n" 160 + : [cc] "=d" (cc), [fn] "+d" (fn), [fib] "=m" (*fib) 161 + : : "cc"); 162 + *status = fn >> 24 & 0xff; 163 + return cc; 164 + } 165 + 166 + /* Set Interruption Controls */ 167 + static inline void sic_instr(u16 ctl, char *unused, u8 isc) 168 + { 169 + asm volatile ( 170 + " .insn rsy,0xeb00000000d1,%[ctl],%[isc],%[u]\n" 171 + : : [ctl] "d" (ctl), [isc] "d" (isc << 27), [u] "Q" (*unused)); 172 + } 173 + 174 + /* PCI Load */ 175 + static inline u8 __pcilg(u64 *data, u64 req, u64 offset, u8 *status) 176 + { 177 + register u64 __req asm("2") = req; 178 + register u64 __offset asm("3") = offset; 179 + u64 __data; 180 + u8 cc; 181 + 182 + asm volatile ( 183 + " .insn rre,0xb9d20000,%[data],%[req]\n" 184 + " ipm %[cc]\n" 185 + " srl %[cc],28\n" 186 + : [cc] "=d" (cc), [data] "=d" (__data), [req] "+d" (__req) 187 + : "d" (__offset) 188 + : "cc"); 189 + *status = __req >> 24 & 0xff; 190 + *data = __data; 191 + return cc; 192 + } 193 + 194 + static inline int pcilg_instr(u64 *data, u64 req, u64 offset) 195 + { 196 + u8 cc, status; 197 + 198 + do { 199 + cc = __pcilg(data, req, offset, &status); 200 + if (cc == 2) 201 + udelay(ZPCI_INSN_BUSY_DELAY); 202 + } while (cc == 2); 203 + 204 + if (cc) { 205 + printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", 206 + __func__, cc, status, req, offset); 207 + /* TODO: on IO errors set data to 0xff... 208 + * here or in users of pcilg (le conversion)? 209 + */ 210 + } 211 + return (cc) ? -EIO : 0; 212 + } 213 + 214 + /* PCI Store */ 215 + static inline u8 __pcistg(u64 data, u64 req, u64 offset, u8 *status) 216 + { 217 + register u64 __req asm("2") = req; 218 + register u64 __offset asm("3") = offset; 219 + u8 cc; 220 + 221 + asm volatile ( 222 + " .insn rre,0xb9d00000,%[data],%[req]\n" 223 + " ipm %[cc]\n" 224 + " srl %[cc],28\n" 225 + : [cc] "=d" (cc), [req] "+d" (__req) 226 + : "d" (__offset), [data] "d" (data) 227 + : "cc"); 228 + *status = __req >> 24 & 0xff; 229 + return cc; 230 + } 231 + 232 + static inline int pcistg_instr(u64 data, u64 req, u64 offset) 233 + { 234 + u8 cc, status; 235 + 236 + do { 237 + cc = __pcistg(data, req, offset, &status); 238 + if (cc == 2) 239 + udelay(ZPCI_INSN_BUSY_DELAY); 240 + } while (cc == 2); 241 + 242 + if (cc) 243 + printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", 244 + __func__, cc, status, req, offset); 245 + return (cc) ? -EIO : 0; 246 + } 247 + 248 + /* PCI Store Block */ 249 + static inline u8 __pcistb(const u64 *data, u64 req, u64 offset, u8 *status) 250 + { 251 + u8 cc; 252 + 253 + asm volatile ( 254 + " .insn rsy,0xeb00000000d0,%[req],%[offset],%[data]\n" 255 + " ipm %[cc]\n" 256 + " srl %[cc],28\n" 257 + : [cc] "=d" (cc), [req] "+d" (req) 258 + : [offset] "d" (offset), [data] "Q" (*data) 259 + : "cc"); 260 + *status = req >> 24 & 0xff; 261 + return cc; 262 + } 263 + 264 + static inline int pcistb_instr(const u64 *data, u64 req, u64 offset) 265 + { 266 + u8 cc, status; 267 + 268 + do { 269 + cc = __pcistb(data, req, offset, &status); 270 + if (cc == 2) 271 + udelay(ZPCI_INSN_BUSY_DELAY); 272 + } while (cc == 2); 273 + 274 + if (cc) 275 + printk_once(KERN_ERR "%s: error cc: %d status: %d req: %Lx offset: %Lx\n", 276 + __func__, cc, status, req, offset); 277 + return (cc) ? -EIO : 0; 278 + } 279 + 280 + #endif
+194
arch/s390/include/asm/pci_io.h
··· 1 + #ifndef _ASM_S390_PCI_IO_H 2 + #define _ASM_S390_PCI_IO_H 3 + 4 + #ifdef CONFIG_PCI 5 + 6 + #include <linux/kernel.h> 7 + #include <linux/slab.h> 8 + #include <asm/pci_insn.h> 9 + 10 + /* I/O Map */ 11 + #define ZPCI_IOMAP_MAX_ENTRIES 0x7fff 12 + #define ZPCI_IOMAP_ADDR_BASE 0x8000000000000000ULL 13 + #define ZPCI_IOMAP_ADDR_IDX_MASK 0x7fff000000000000ULL 14 + #define ZPCI_IOMAP_ADDR_OFF_MASK 0x0000ffffffffffffULL 15 + 16 + struct zpci_iomap_entry { 17 + u32 fh; 18 + u8 bar; 19 + }; 20 + 21 + extern struct zpci_iomap_entry *zpci_iomap_start; 22 + 23 + #define ZPCI_IDX(addr) \ 24 + (((__force u64) addr & ZPCI_IOMAP_ADDR_IDX_MASK) >> 48) 25 + #define ZPCI_OFFSET(addr) \ 26 + ((__force u64) addr & ZPCI_IOMAP_ADDR_OFF_MASK) 27 + 28 + #define ZPCI_CREATE_REQ(handle, space, len) \ 29 + ((u64) handle << 32 | space << 16 | len) 30 + 31 + #define zpci_read(LENGTH, RETTYPE) \ 32 + static inline RETTYPE zpci_read_##RETTYPE(const volatile void __iomem *addr) \ 33 + { \ 34 + struct zpci_iomap_entry *entry = &zpci_iomap_start[ZPCI_IDX(addr)]; \ 35 + u64 req = ZPCI_CREATE_REQ(entry->fh, entry->bar, LENGTH); \ 36 + u64 data; \ 37 + int rc; \ 38 + \ 39 + rc = pcilg_instr(&data, req, ZPCI_OFFSET(addr)); \ 40 + if (rc) \ 41 + data = -1ULL; \ 42 + return (RETTYPE) data; \ 43 + } 44 + 45 + #define zpci_write(LENGTH, VALTYPE) \ 46 + static inline void zpci_write_##VALTYPE(VALTYPE val, \ 47 + const volatile void __iomem *addr) \ 48 + { \ 49 + struct zpci_iomap_entry *entry = &zpci_iomap_start[ZPCI_IDX(addr)]; \ 50 + u64 req = ZPCI_CREATE_REQ(entry->fh, entry->bar, LENGTH); \ 51 + u64 data = (VALTYPE) val; \ 52 + \ 53 + pcistg_instr(data, req, ZPCI_OFFSET(addr)); \ 54 + } 55 + 56 + zpci_read(8, u64) 57 + zpci_read(4, u32) 58 + zpci_read(2, u16) 59 + zpci_read(1, u8) 60 + zpci_write(8, u64) 61 + zpci_write(4, u32) 62 + zpci_write(2, u16) 63 + zpci_write(1, u8) 64 + 65 + static inline int zpci_write_single(u64 req, const u64 *data, u64 offset, u8 len) 66 + { 67 + u64 val; 68 + 69 + switch (len) { 70 + case 1: 71 + val = (u64) *((u8 *) data); 72 + break; 73 + case 2: 74 + val = (u64) *((u16 *) data); 75 + break; 76 + case 4: 77 + val = (u64) *((u32 *) data); 78 + break; 79 + case 8: 80 + val = (u64) *((u64 *) data); 81 + break; 82 + default: 83 + val = 0; /* let FW report error */ 84 + break; 85 + } 86 + return pcistg_instr(val, req, offset); 87 + } 88 + 89 + static inline int zpci_read_single(u64 req, u64 *dst, u64 offset, u8 len) 90 + { 91 + u64 data; 92 + u8 cc; 93 + 94 + cc = pcilg_instr(&data, req, offset); 95 + switch (len) { 96 + case 1: 97 + *((u8 *) dst) = (u8) data; 98 + break; 99 + case 2: 100 + *((u16 *) dst) = (u16) data; 101 + break; 102 + case 4: 103 + *((u32 *) dst) = (u32) data; 104 + break; 105 + case 8: 106 + *((u64 *) dst) = (u64) data; 107 + break; 108 + } 109 + return cc; 110 + } 111 + 112 + static inline int zpci_write_block(u64 req, const u64 *data, u64 offset) 113 + { 114 + return pcistb_instr(data, req, offset); 115 + } 116 + 117 + static inline u8 zpci_get_max_write_size(u64 src, u64 dst, int len, int max) 118 + { 119 + int count = len > max ? max : len, size = 1; 120 + 121 + while (!(src & 0x1) && !(dst & 0x1) && ((size << 1) <= count)) { 122 + dst = dst >> 1; 123 + src = src >> 1; 124 + size = size << 1; 125 + } 126 + return size; 127 + } 128 + 129 + static inline int zpci_memcpy_fromio(void *dst, 130 + const volatile void __iomem *src, 131 + unsigned long n) 132 + { 133 + struct zpci_iomap_entry *entry = &zpci_iomap_start[ZPCI_IDX(src)]; 134 + u64 req, offset = ZPCI_OFFSET(src); 135 + int size, rc = 0; 136 + 137 + while (n > 0) { 138 + size = zpci_get_max_write_size((u64) src, (u64) dst, n, 8); 139 + req = ZPCI_CREATE_REQ(entry->fh, entry->bar, size); 140 + rc = zpci_read_single(req, dst, offset, size); 141 + if (rc) 142 + break; 143 + offset += size; 144 + dst += size; 145 + n -= size; 146 + } 147 + return rc; 148 + } 149 + 150 + static inline int zpci_memcpy_toio(volatile void __iomem *dst, 151 + const void *src, unsigned long n) 152 + { 153 + struct zpci_iomap_entry *entry = &zpci_iomap_start[ZPCI_IDX(dst)]; 154 + u64 req, offset = ZPCI_OFFSET(dst); 155 + int size, rc = 0; 156 + 157 + if (!src) 158 + return -EINVAL; 159 + 160 + while (n > 0) { 161 + size = zpci_get_max_write_size((u64) dst, (u64) src, n, 128); 162 + req = ZPCI_CREATE_REQ(entry->fh, entry->bar, size); 163 + 164 + if (size > 8) /* main path */ 165 + rc = zpci_write_block(req, src, offset); 166 + else 167 + rc = zpci_write_single(req, src, offset, size); 168 + if (rc) 169 + break; 170 + offset += size; 171 + src += size; 172 + n -= size; 173 + } 174 + return rc; 175 + } 176 + 177 + static inline int zpci_memset_io(volatile void __iomem *dst, 178 + unsigned char val, size_t count) 179 + { 180 + u8 *src = kmalloc(count, GFP_KERNEL); 181 + int rc; 182 + 183 + if (src == NULL) 184 + return -ENOMEM; 185 + memset(src, val, count); 186 + 187 + rc = zpci_memcpy_toio(dst, src, count); 188 + kfree(src); 189 + return rc; 190 + } 191 + 192 + #endif /* CONFIG_PCI */ 193 + 194 + #endif /* _ASM_S390_PCI_IO_H */
+10 -1
arch/s390/include/asm/pgtable.h
··· 35 35 extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096))); 36 36 extern void paging_init(void); 37 37 extern void vmem_map_init(void); 38 - extern void fault_init(void); 39 38 40 39 /* 41 40 * The S390 doesn't have any external MMU info: the kernel page ··· 335 336 #define _REGION3_ENTRY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_LENGTH) 336 337 #define _REGION3_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INV) 337 338 339 + #define _REGION3_ENTRY_LARGE 0x400 /* RTTE-format control, large page */ 340 + 338 341 /* Bits in the segment table entry */ 339 342 #define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */ 340 343 #define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */ ··· 436 435 437 436 static inline int pud_present(pud_t pud) { return 1; } 438 437 static inline int pud_none(pud_t pud) { return 0; } 438 + static inline int pud_large(pud_t pud) { return 0; } 439 439 static inline int pud_bad(pud_t pud) { return 0; } 440 440 441 441 #else /* CONFIG_64BIT */ ··· 480 478 if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R3) 481 479 return 0; 482 480 return (pud_val(pud) & _REGION_ENTRY_INV) != 0UL; 481 + } 482 + 483 + static inline int pud_large(pud_t pud) 484 + { 485 + if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) != _REGION_ENTRY_TYPE_R3) 486 + return 0; 487 + return !!(pud_val(pud) & _REGION3_ENTRY_LARGE); 483 488 } 484 489 485 490 static inline int pud_bad(pud_t pud)
+2
arch/s390/include/asm/sclp.h
··· 55 55 void sclp_get_ipl_info(struct sclp_ipl_info *info); 56 56 bool sclp_has_linemode(void); 57 57 bool sclp_has_vt220(void); 58 + int sclp_pci_configure(u32 fid); 59 + int sclp_pci_deconfigure(u32 fid); 58 60 59 61 #endif /* _ASM_S390_SCLP_H */
+18 -16
arch/s390/include/asm/topology.h
··· 8 8 9 9 #ifdef CONFIG_SCHED_BOOK 10 10 11 - extern unsigned char cpu_socket_id[NR_CPUS]; 12 - #define topology_physical_package_id(cpu) (cpu_socket_id[cpu]) 11 + struct cpu_topology_s390 { 12 + unsigned short core_id; 13 + unsigned short socket_id; 14 + unsigned short book_id; 15 + cpumask_t core_mask; 16 + cpumask_t book_mask; 17 + }; 13 18 14 - extern unsigned char cpu_core_id[NR_CPUS]; 15 - extern cpumask_t cpu_core_map[NR_CPUS]; 19 + extern struct cpu_topology_s390 cpu_topology[NR_CPUS]; 20 + 21 + #define topology_physical_package_id(cpu) (cpu_topology[cpu].socket_id) 22 + #define topology_core_id(cpu) (cpu_topology[cpu].core_id) 23 + #define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_mask) 24 + #define topology_book_id(cpu) (cpu_topology[cpu].book_id) 25 + #define topology_book_cpumask(cpu) (&cpu_topology[cpu].book_mask) 26 + 27 + #define mc_capable() 1 16 28 17 29 static inline const struct cpumask *cpu_coregroup_mask(int cpu) 18 30 { 19 - return &cpu_core_map[cpu]; 31 + return &cpu_topology[cpu].core_mask; 20 32 } 21 - 22 - #define topology_core_id(cpu) (cpu_core_id[cpu]) 23 - #define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) 24 - #define mc_capable() (1) 25 - 26 - extern unsigned char cpu_book_id[NR_CPUS]; 27 - extern cpumask_t cpu_book_map[NR_CPUS]; 28 33 29 34 static inline const struct cpumask *cpu_book_mask(int cpu) 30 35 { 31 - return &cpu_book_map[cpu]; 36 + return &cpu_topology[cpu].book_mask; 32 37 } 33 - 34 - #define topology_book_id(cpu) (cpu_book_id[cpu]) 35 - #define topology_book_cpumask(cpu) (&cpu_book_map[cpu]) 36 38 37 39 int topology_cpu_init(struct cpu *); 38 40 int topology_set_cpu_management(int fc);
+6
arch/s390/include/asm/vga.h
··· 1 + #ifndef _ASM_S390_VGA_H 2 + #define _ASM_S390_VGA_H 3 + 4 + /* Avoid compile errors due to missing asm/vga.h */ 5 + 6 + #endif /* _ASM_S390_VGA_H */
+1 -1
arch/s390/kernel/Makefile
··· 23 23 obj-y := bitmap.o traps.o time.o process.o base.o early.o setup.o vtime.o \ 24 24 processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o \ 25 25 debug.o irq.o ipl.o dis.o diag.o mem_detect.o sclp.o vdso.o \ 26 - sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o 26 + sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o 27 27 28 28 obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) 29 29 obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
+403 -211
arch/s390/kernel/dis.c
··· 83 83 U4_12, /* 4 bit unsigned value starting at 12 */ 84 84 U4_16, /* 4 bit unsigned value starting at 16 */ 85 85 U4_20, /* 4 bit unsigned value starting at 20 */ 86 + U4_24, /* 4 bit unsigned value starting at 24 */ 87 + U4_28, /* 4 bit unsigned value starting at 28 */ 86 88 U4_32, /* 4 bit unsigned value starting at 32 */ 89 + U4_36, /* 4 bit unsigned value starting at 36 */ 87 90 U8_8, /* 8 bit unsigned value starting at 8 */ 88 91 U8_16, /* 8 bit unsigned value starting at 16 */ 89 92 U8_24, /* 8 bit unsigned value starting at 24 */ 90 93 U8_32, /* 8 bit unsigned value starting at 32 */ 91 94 I8_8, /* 8 bit signed value starting at 8 */ 92 95 I8_32, /* 8 bit signed value starting at 32 */ 96 + J12_12, /* PC relative offset at 12 */ 93 97 I16_16, /* 16 bit signed value starting at 16 */ 94 98 I16_32, /* 32 bit signed value starting at 16 */ 95 99 U16_16, /* 16 bit unsigned value starting at 16 */ 96 100 U16_32, /* 32 bit unsigned value starting at 16 */ 97 101 J16_16, /* PC relative jump offset at 16 */ 102 + J16_32, /* PC relative offset at 16 */ 103 + I24_24, /* 24 bit signed value starting at 24 */ 98 104 J32_16, /* PC relative long offset at 16 */ 99 105 I32_16, /* 32 bit signed value starting at 16 */ 100 106 U32_16, /* 32 bit unsigned value starting at 16 */ 101 107 M_16, /* 4 bit optional mask starting at 16 */ 108 + M_20, /* 4 bit optional mask starting at 20 */ 102 109 RO_28, /* optional GPR starting at position 28 */ 103 110 }; 104 111 ··· 116 109 enum { 117 110 INSTR_INVALID, 118 111 INSTR_E, 112 + INSTR_IE_UU, 113 + INSTR_MII_UPI, 119 114 INSTR_RIE_R0IU, INSTR_RIE_R0UU, INSTR_RIE_RRP, INSTR_RIE_RRPU, 120 115 INSTR_RIE_RRUUU, INSTR_RIE_RUPI, INSTR_RIE_RUPU, INSTR_RIE_RRI0, 121 116 INSTR_RIL_RI, INSTR_RIL_RP, INSTR_RIL_RU, INSTR_RIL_UP, ··· 127 118 INSTR_RRE_FF, INSTR_RRE_FR, INSTR_RRE_R0, INSTR_RRE_RA, INSTR_RRE_RF, 128 119 INSTR_RRE_RR, INSTR_RRE_RR_OPT, 129 120 INSTR_RRF_0UFF, INSTR_RRF_F0FF, INSTR_RRF_F0FF2, INSTR_RRF_F0FR, 130 - INSTR_RRF_FFRU, INSTR_RRF_FUFF, INSTR_RRF_M0RR, INSTR_RRF_R0RR, 131 - INSTR_RRF_R0RR2, INSTR_RRF_RURR, INSTR_RRF_U0FF, INSTR_RRF_U0RF, 132 - INSTR_RRF_U0RR, INSTR_RRF_UUFF, INSTR_RRR_F0FF, INSTR_RRS_RRRDU, 121 + INSTR_RRF_FFRU, INSTR_RRF_FUFF, INSTR_RRF_FUFF2, INSTR_RRF_M0RR, 122 + INSTR_RRF_R0RR, INSTR_RRF_R0RR2, INSTR_RRF_RMRR, INSTR_RRF_RURR, 123 + INSTR_RRF_U0FF, INSTR_RRF_U0RF, INSTR_RRF_U0RR, INSTR_RRF_UUFF, 124 + INSTR_RRF_UUFR, INSTR_RRF_UURF, 125 + INSTR_RRR_F0FF, INSTR_RRS_RRRDU, 133 126 INSTR_RR_FF, INSTR_RR_R0, INSTR_RR_RR, INSTR_RR_U0, INSTR_RR_UR, 134 127 INSTR_RSE_CCRD, INSTR_RSE_RRRD, INSTR_RSE_RURD, 135 128 INSTR_RSI_RRP, 136 - INSTR_RSL_R0RD, 129 + INSTR_RSL_LRDFU, INSTR_RSL_R0RD, 137 130 INSTR_RSY_AARD, INSTR_RSY_CCRD, INSTR_RSY_RRRD, INSTR_RSY_RURD, 138 131 INSTR_RSY_RDRM, 139 132 INSTR_RS_AARD, INSTR_RS_CCRD, INSTR_RS_R0RD, INSTR_RS_RRRD, ··· 147 136 INSTR_SIL_RDI, INSTR_SIL_RDU, 148 137 INSTR_SIY_IRD, INSTR_SIY_URD, 149 138 INSTR_SI_URD, 139 + INSTR_SMI_U0RDP, 150 140 INSTR_SSE_RDRD, 151 141 INSTR_SSF_RRDRD, INSTR_SSF_RRDRD2, 152 142 INSTR_SS_L0RDRD, INSTR_SS_LIRDRD, INSTR_SS_LLRDRD, INSTR_SS_RRRDRD, ··· 203 191 [U4_12] = { 4, 12, 0 }, 204 192 [U4_16] = { 4, 16, 0 }, 205 193 [U4_20] = { 4, 20, 0 }, 194 + [U4_24] = { 4, 24, 0 }, 195 + [U4_28] = { 4, 28, 0 }, 206 196 [U4_32] = { 4, 32, 0 }, 197 + [U4_36] = { 4, 36, 0 }, 207 198 [U8_8] = { 8, 8, 0 }, 208 199 [U8_16] = { 8, 16, 0 }, 209 200 [U8_24] = { 8, 24, 0 }, 210 201 [U8_32] = { 8, 32, 0 }, 202 + [J12_12] = { 12, 12, OPERAND_PCREL }, 211 203 [I16_16] = { 16, 16, OPERAND_SIGNED }, 212 204 [U16_16] = { 16, 16, 0 }, 213 205 [U16_32] = { 16, 32, 0 }, 214 206 [J16_16] = { 16, 16, OPERAND_PCREL }, 207 + [J16_32] = { 16, 32, OPERAND_PCREL }, 215 208 [I16_32] = { 16, 32, OPERAND_SIGNED }, 209 + [I24_24] = { 24, 24, OPERAND_SIGNED }, 216 210 [J32_16] = { 32, 16, OPERAND_PCREL }, 217 211 [I32_16] = { 32, 16, OPERAND_SIGNED }, 218 212 [U32_16] = { 32, 16, 0 }, 219 213 [M_16] = { 4, 16, 0 }, 214 + [M_20] = { 4, 20, 0 }, 220 215 [RO_28] = { 4, 28, OPERAND_GPR } 221 216 }; 222 217 223 218 static const unsigned char formats[][7] = { 224 219 [INSTR_E] = { 0xff, 0,0,0,0,0,0 }, 220 + [INSTR_IE_UU] = { 0xff, U4_24,U4_28,0,0,0,0 }, 221 + [INSTR_MII_UPI] = { 0xff, U4_8,J12_12,I24_24 }, 222 + [INSTR_RIE_R0IU] = { 0xff, R_8,I16_16,U4_32,0,0,0 }, 225 223 [INSTR_RIE_R0UU] = { 0xff, R_8,U16_16,U4_32,0,0,0 }, 224 + [INSTR_RIE_RRI0] = { 0xff, R_8,R_12,I16_16,0,0,0 }, 226 225 [INSTR_RIE_RRPU] = { 0xff, R_8,R_12,U4_32,J16_16,0,0 }, 227 226 [INSTR_RIE_RRP] = { 0xff, R_8,R_12,J16_16,0,0,0 }, 228 227 [INSTR_RIE_RRUUU] = { 0xff, R_8,R_12,U8_16,U8_24,U8_32,0 }, 229 228 [INSTR_RIE_RUPI] = { 0xff, R_8,I8_32,U4_12,J16_16,0,0 }, 230 - [INSTR_RIE_RRI0] = { 0xff, R_8,R_12,I16_16,0,0,0 }, 229 + [INSTR_RIE_RUPU] = { 0xff, R_8,U8_32,U4_12,J16_16,0,0 }, 231 230 [INSTR_RIL_RI] = { 0x0f, R_8,I32_16,0,0,0,0 }, 232 231 [INSTR_RIL_RP] = { 0x0f, R_8,J32_16,0,0,0,0 }, 233 232 [INSTR_RIL_RU] = { 0x0f, R_8,U32_16,0,0,0,0 }, ··· 268 245 [INSTR_RRF_F0FR] = { 0xff, F_24,F_16,R_28,0,0,0 }, 269 246 [INSTR_RRF_FFRU] = { 0xff, F_24,F_16,R_28,U4_20,0,0 }, 270 247 [INSTR_RRF_FUFF] = { 0xff, F_24,F_16,F_28,U4_20,0,0 }, 248 + [INSTR_RRF_FUFF2] = { 0xff, F_24,F_28,F_16,U4_20,0,0 }, 271 249 [INSTR_RRF_M0RR] = { 0xff, R_24,R_28,M_16,0,0,0 }, 272 250 [INSTR_RRF_R0RR] = { 0xff, R_24,R_16,R_28,0,0,0 }, 273 251 [INSTR_RRF_R0RR2] = { 0xff, R_24,R_28,R_16,0,0,0 }, 252 + [INSTR_RRF_RMRR] = { 0xff, R_24,R_16,R_28,M_20,0,0 }, 274 253 [INSTR_RRF_RURR] = { 0xff, R_24,R_28,R_16,U4_20,0,0 }, 275 254 [INSTR_RRF_U0FF] = { 0xff, F_24,U4_16,F_28,0,0,0 }, 276 255 [INSTR_RRF_U0RF] = { 0xff, R_24,U4_16,F_28,0,0,0 }, 277 256 [INSTR_RRF_U0RR] = { 0xff, R_24,R_28,U4_16,0,0,0 }, 278 257 [INSTR_RRF_UUFF] = { 0xff, F_24,U4_16,F_28,U4_20,0,0 }, 258 + [INSTR_RRF_UUFR] = { 0xff, F_24,U4_16,R_28,U4_20,0,0 }, 259 + [INSTR_RRF_UURF] = { 0xff, R_24,U4_16,F_28,U4_20,0,0 }, 279 260 [INSTR_RRR_F0FF] = { 0xff, F_24,F_28,F_16,0,0,0 }, 280 261 [INSTR_RRS_RRRDU] = { 0xff, R_8,R_12,U4_32,D_20,B_16,0 }, 281 262 [INSTR_RR_FF] = { 0xff, F_8,F_12,0,0,0,0 }, ··· 291 264 [INSTR_RSE_RRRD] = { 0xff, R_8,R_12,D_20,B_16,0,0 }, 292 265 [INSTR_RSE_RURD] = { 0xff, R_8,U4_12,D_20,B_16,0,0 }, 293 266 [INSTR_RSI_RRP] = { 0xff, R_8,R_12,J16_16,0,0,0 }, 267 + [INSTR_RSL_LRDFU] = { 0xff, F_32,D_20,L4_8,B_16,U4_36,0 }, 294 268 [INSTR_RSL_R0RD] = { 0xff, D_20,L4_8,B_16,0,0,0 }, 295 269 [INSTR_RSY_AARD] = { 0xff, A_8,A_12,D20_20,B_16,0,0 }, 296 270 [INSTR_RSY_CCRD] = { 0xff, C_8,C_12,D20_20,B_16,0,0 }, 271 + [INSTR_RSY_RDRM] = { 0xff, R_8,D20_20,B_16,U4_12,0,0 }, 297 272 [INSTR_RSY_RRRD] = { 0xff, R_8,R_12,D20_20,B_16,0,0 }, 298 273 [INSTR_RSY_RURD] = { 0xff, R_8,U4_12,D20_20,B_16,0,0 }, 299 - [INSTR_RSY_RDRM] = { 0xff, R_8,D20_20,B_16,U4_12,0,0 }, 300 274 [INSTR_RS_AARD] = { 0xff, A_8,A_12,D_20,B_16,0,0 }, 301 275 [INSTR_RS_CCRD] = { 0xff, C_8,C_12,D_20,B_16,0,0 }, 302 276 [INSTR_RS_R0RD] = { 0xff, R_8,D_20,B_16,0,0,0 }, ··· 317 289 [INSTR_SIY_IRD] = { 0xff, D20_20,B_16,I8_8,0,0,0 }, 318 290 [INSTR_SIY_URD] = { 0xff, D20_20,B_16,U8_8,0,0,0 }, 319 291 [INSTR_SI_URD] = { 0xff, D_20,B_16,U8_8,0,0,0 }, 292 + [INSTR_SMI_U0RDP] = { 0xff, U4_8,J16_32,D_20,B_16,0,0 }, 320 293 [INSTR_SSE_RDRD] = { 0xff, D_20,B_16,D_36,B_32,0,0 }, 321 - [INSTR_SSF_RRDRD] = { 0x00, D_20,B_16,D_36,B_32,R_8,0 }, 322 - [INSTR_SSF_RRDRD2]= { 0x00, R_8,D_20,B_16,D_36,B_32,0 }, 294 + [INSTR_SSF_RRDRD] = { 0x0f, D_20,B_16,D_36,B_32,R_8,0 }, 295 + [INSTR_SSF_RRDRD2]= { 0x0f, R_8,D_20,B_16,D_36,B_32,0 }, 323 296 [INSTR_SS_L0RDRD] = { 0xff, D_20,L8_8,B_16,D_36,B_32,0 }, 324 297 [INSTR_SS_LIRDRD] = { 0xff, D_20,L4_8,B_16,D_36,B_32,U4_12 }, 325 298 [INSTR_SS_LLRDRD] = { 0xff, D_20,L4_8,B_16,D_36,L4_12,B_32 }, ··· 333 304 334 305 enum { 335 306 LONG_INSN_ALGHSIK, 307 + LONG_INSN_ALHHHR, 308 + LONG_INSN_ALHHLR, 336 309 LONG_INSN_ALHSIK, 310 + LONG_INSN_ALSIHN, 311 + LONG_INSN_CDFBRA, 312 + LONG_INSN_CDGBRA, 313 + LONG_INSN_CDGTRA, 314 + LONG_INSN_CDLFBR, 315 + LONG_INSN_CDLFTR, 316 + LONG_INSN_CDLGBR, 317 + LONG_INSN_CDLGTR, 318 + LONG_INSN_CEFBRA, 319 + LONG_INSN_CEGBRA, 320 + LONG_INSN_CELFBR, 321 + LONG_INSN_CELGBR, 322 + LONG_INSN_CFDBRA, 323 + LONG_INSN_CFEBRA, 324 + LONG_INSN_CFXBRA, 325 + LONG_INSN_CGDBRA, 326 + LONG_INSN_CGDTRA, 327 + LONG_INSN_CGEBRA, 328 + LONG_INSN_CGXBRA, 329 + LONG_INSN_CGXTRA, 330 + LONG_INSN_CLFDBR, 331 + LONG_INSN_CLFDTR, 332 + LONG_INSN_CLFEBR, 337 333 LONG_INSN_CLFHSI, 334 + LONG_INSN_CLFXBR, 335 + LONG_INSN_CLFXTR, 336 + LONG_INSN_CLGDBR, 337 + LONG_INSN_CLGDTR, 338 + LONG_INSN_CLGEBR, 338 339 LONG_INSN_CLGFRL, 339 340 LONG_INSN_CLGHRL, 340 341 LONG_INSN_CLGHSI, 342 + LONG_INSN_CLGXBR, 343 + LONG_INSN_CLGXTR, 341 344 LONG_INSN_CLHHSI, 345 + LONG_INSN_CXFBRA, 346 + LONG_INSN_CXGBRA, 347 + LONG_INSN_CXGTRA, 348 + LONG_INSN_CXLFBR, 349 + LONG_INSN_CXLFTR, 350 + LONG_INSN_CXLGBR, 351 + LONG_INSN_CXLGTR, 352 + LONG_INSN_FIDBRA, 353 + LONG_INSN_FIEBRA, 354 + LONG_INSN_FIXBRA, 355 + LONG_INSN_LDXBRA, 356 + LONG_INSN_LEDBRA, 357 + LONG_INSN_LEXBRA, 358 + LONG_INSN_LLGFAT, 342 359 LONG_INSN_LLGFRL, 343 360 LONG_INSN_LLGHRL, 361 + LONG_INSN_LLGTAT, 344 362 LONG_INSN_POPCNT, 363 + LONG_INSN_RIEMIT, 364 + LONG_INSN_RINEXT, 365 + LONG_INSN_RISBGN, 345 366 LONG_INSN_RISBHG, 346 367 LONG_INSN_RISBLG, 347 - LONG_INSN_RINEXT, 348 - LONG_INSN_RIEMIT, 368 + LONG_INSN_SLHHHR, 369 + LONG_INSN_SLHHLR, 349 370 LONG_INSN_TABORT, 350 371 LONG_INSN_TBEGIN, 351 372 LONG_INSN_TBEGINC, 373 + LONG_INSN_PCISTG, 374 + LONG_INSN_MPCIFC, 375 + LONG_INSN_STPCIFC, 376 + LONG_INSN_PCISTB, 352 377 }; 353 378 354 379 static char *long_insn_name[] = { 355 380 [LONG_INSN_ALGHSIK] = "alghsik", 381 + [LONG_INSN_ALHHHR] = "alhhhr", 382 + [LONG_INSN_ALHHLR] = "alhhlr", 356 383 [LONG_INSN_ALHSIK] = "alhsik", 384 + [LONG_INSN_ALSIHN] = "alsihn", 385 + [LONG_INSN_CDFBRA] = "cdfbra", 386 + [LONG_INSN_CDGBRA] = "cdgbra", 387 + [LONG_INSN_CDGTRA] = "cdgtra", 388 + [LONG_INSN_CDLFBR] = "cdlfbr", 389 + [LONG_INSN_CDLFTR] = "cdlftr", 390 + [LONG_INSN_CDLGBR] = "cdlgbr", 391 + [LONG_INSN_CDLGTR] = "cdlgtr", 392 + [LONG_INSN_CEFBRA] = "cefbra", 393 + [LONG_INSN_CEGBRA] = "cegbra", 394 + [LONG_INSN_CELFBR] = "celfbr", 395 + [LONG_INSN_CELGBR] = "celgbr", 396 + [LONG_INSN_CFDBRA] = "cfdbra", 397 + [LONG_INSN_CFEBRA] = "cfebra", 398 + [LONG_INSN_CFXBRA] = "cfxbra", 399 + [LONG_INSN_CGDBRA] = "cgdbra", 400 + [LONG_INSN_CGDTRA] = "cgdtra", 401 + [LONG_INSN_CGEBRA] = "cgebra", 402 + [LONG_INSN_CGXBRA] = "cgxbra", 403 + [LONG_INSN_CGXTRA] = "cgxtra", 404 + [LONG_INSN_CLFDBR] = "clfdbr", 405 + [LONG_INSN_CLFDTR] = "clfdtr", 406 + [LONG_INSN_CLFEBR] = "clfebr", 357 407 [LONG_INSN_CLFHSI] = "clfhsi", 408 + [LONG_INSN_CLFXBR] = "clfxbr", 409 + [LONG_INSN_CLFXTR] = "clfxtr", 410 + [LONG_INSN_CLGDBR] = "clgdbr", 411 + [LONG_INSN_CLGDTR] = "clgdtr", 412 + [LONG_INSN_CLGEBR] = "clgebr", 358 413 [LONG_INSN_CLGFRL] = "clgfrl", 359 414 [LONG_INSN_CLGHRL] = "clghrl", 360 415 [LONG_INSN_CLGHSI] = "clghsi", 416 + [LONG_INSN_CLGXBR] = "clgxbr", 417 + [LONG_INSN_CLGXTR] = "clgxtr", 361 418 [LONG_INSN_CLHHSI] = "clhhsi", 419 + [LONG_INSN_CXFBRA] = "cxfbra", 420 + [LONG_INSN_CXGBRA] = "cxgbra", 421 + [LONG_INSN_CXGTRA] = "cxgtra", 422 + [LONG_INSN_CXLFBR] = "cxlfbr", 423 + [LONG_INSN_CXLFTR] = "cxlftr", 424 + [LONG_INSN_CXLGBR] = "cxlgbr", 425 + [LONG_INSN_CXLGTR] = "cxlgtr", 426 + [LONG_INSN_FIDBRA] = "fidbra", 427 + [LONG_INSN_FIEBRA] = "fiebra", 428 + [LONG_INSN_FIXBRA] = "fixbra", 429 + [LONG_INSN_LDXBRA] = "ldxbra", 430 + [LONG_INSN_LEDBRA] = "ledbra", 431 + [LONG_INSN_LEXBRA] = "lexbra", 432 + [LONG_INSN_LLGFAT] = "llgfat", 362 433 [LONG_INSN_LLGFRL] = "llgfrl", 363 434 [LONG_INSN_LLGHRL] = "llghrl", 435 + [LONG_INSN_LLGTAT] = "llgtat", 364 436 [LONG_INSN_POPCNT] = "popcnt", 437 + [LONG_INSN_RIEMIT] = "riemit", 438 + [LONG_INSN_RINEXT] = "rinext", 439 + [LONG_INSN_RISBGN] = "risbgn", 365 440 [LONG_INSN_RISBHG] = "risbhg", 366 441 [LONG_INSN_RISBLG] = "risblg", 367 - [LONG_INSN_RINEXT] = "rinext", 368 - [LONG_INSN_RIEMIT] = "riemit", 442 + [LONG_INSN_SLHHHR] = "slhhhr", 443 + [LONG_INSN_SLHHLR] = "slhhlr", 369 444 [LONG_INSN_TABORT] = "tabort", 370 445 [LONG_INSN_TBEGIN] = "tbegin", 371 446 [LONG_INSN_TBEGINC] = "tbeginc", 447 + [LONG_INSN_PCISTG] = "pcistg", 448 + [LONG_INSN_MPCIFC] = "mpcifc", 449 + [LONG_INSN_STPCIFC] = "stpcifc", 450 + [LONG_INSN_PCISTB] = "pcistb", 372 451 }; 373 452 374 453 static struct insn opcode[] = { 375 454 #ifdef CONFIG_64BIT 455 + { "bprp", 0xc5, INSTR_MII_UPI }, 456 + { "bpp", 0xc7, INSTR_SMI_U0RDP }, 457 + { "trtr", 0xd0, INSTR_SS_L0RDRD }, 376 458 { "lmd", 0xef, INSTR_SS_RRRDRD3 }, 377 459 #endif 378 460 { "spm", 0x04, INSTR_RR_R0 }, ··· 518 378 { "lcdr", 0x23, INSTR_RR_FF }, 519 379 { "hdr", 0x24, INSTR_RR_FF }, 520 380 { "ldxr", 0x25, INSTR_RR_FF }, 521 - { "lrdr", 0x25, INSTR_RR_FF }, 522 381 { "mxr", 0x26, INSTR_RR_FF }, 523 382 { "mxdr", 0x27, INSTR_RR_FF }, 524 383 { "ldr", 0x28, INSTR_RR_FF }, ··· 534 395 { "lcer", 0x33, INSTR_RR_FF }, 535 396 { "her", 0x34, INSTR_RR_FF }, 536 397 { "ledr", 0x35, INSTR_RR_FF }, 537 - { "lrer", 0x35, INSTR_RR_FF }, 538 398 { "axr", 0x36, INSTR_RR_FF }, 539 399 { "sxr", 0x37, INSTR_RR_FF }, 540 400 { "ler", 0x38, INSTR_RR_FF }, ··· 541 403 { "aer", 0x3a, INSTR_RR_FF }, 542 404 { "ser", 0x3b, INSTR_RR_FF }, 543 405 { "mder", 0x3c, INSTR_RR_FF }, 544 - { "mer", 0x3c, INSTR_RR_FF }, 545 406 { "der", 0x3d, INSTR_RR_FF }, 546 407 { "aur", 0x3e, INSTR_RR_FF }, 547 408 { "sur", 0x3f, INSTR_RR_FF }, ··· 591 454 { "ae", 0x7a, INSTR_RX_FRRD }, 592 455 { "se", 0x7b, INSTR_RX_FRRD }, 593 456 { "mde", 0x7c, INSTR_RX_FRRD }, 594 - { "me", 0x7c, INSTR_RX_FRRD }, 595 457 { "de", 0x7d, INSTR_RX_FRRD }, 596 458 { "au", 0x7e, INSTR_RX_FRRD }, 597 459 { "su", 0x7f, INSTR_RX_FRRD }, ··· 670 534 671 535 static struct insn opcode_01[] = { 672 536 #ifdef CONFIG_64BIT 673 - { "sam64", 0x0e, INSTR_E }, 674 - { "pfpo", 0x0a, INSTR_E }, 675 537 { "ptff", 0x04, INSTR_E }, 538 + { "pfpo", 0x0a, INSTR_E }, 539 + { "sam64", 0x0e, INSTR_E }, 676 540 #endif 677 541 { "pr", 0x01, INSTR_E }, 678 542 { "upt", 0x02, INSTR_E }, ··· 741 605 742 606 static struct insn opcode_b2[] = { 743 607 #ifdef CONFIG_64BIT 744 - { "sske", 0x2b, INSTR_RRF_M0RR }, 745 608 { "stckf", 0x7c, INSTR_S_RD }, 746 - { "cu21", 0xa6, INSTR_RRF_M0RR }, 747 - { "cuutf", 0xa6, INSTR_RRF_M0RR }, 748 - { "cu12", 0xa7, INSTR_RRF_M0RR }, 749 - { "cutfu", 0xa7, INSTR_RRF_M0RR }, 609 + { "lpp", 0x80, INSTR_S_RD }, 610 + { "lcctl", 0x84, INSTR_S_RD }, 611 + { "lpctl", 0x85, INSTR_S_RD }, 612 + { "qsi", 0x86, INSTR_S_RD }, 613 + { "lsctl", 0x87, INSTR_S_RD }, 614 + { "qctri", 0x8e, INSTR_S_RD }, 750 615 { "stfle", 0xb0, INSTR_S_RD }, 751 616 { "lpswe", 0xb2, INSTR_S_RD }, 617 + { "srnmb", 0xb8, INSTR_S_RD }, 752 618 { "srnmt", 0xb9, INSTR_S_RD }, 753 619 { "lfas", 0xbd, INSTR_S_RD }, 754 - { "etndg", 0xec, INSTR_RRE_R0 }, 620 + { "scctr", 0xe0, INSTR_RRE_RR }, 621 + { "spctr", 0xe1, INSTR_RRE_RR }, 622 + { "ecctr", 0xe4, INSTR_RRE_RR }, 623 + { "epctr", 0xe5, INSTR_RRE_RR }, 624 + { "ppa", 0xe8, INSTR_RRF_U0RR }, 625 + { "etnd", 0xec, INSTR_RRE_R0 }, 626 + { "ecpga", 0xed, INSTR_RRE_RR }, 627 + { "tend", 0xf8, INSTR_S_00 }, 628 + { "niai", 0xfa, INSTR_IE_UU }, 755 629 { { 0, LONG_INSN_TABORT }, 0xfc, INSTR_S_RD }, 756 - { "tend", 0xf8, INSTR_S_RD }, 757 630 #endif 758 631 { "stidp", 0x02, INSTR_S_RD }, 759 632 { "sck", 0x04, INSTR_S_RD }, ··· 780 635 { "sie", 0x14, INSTR_S_RD }, 781 636 { "pc", 0x18, INSTR_S_RD }, 782 637 { "sac", 0x19, INSTR_S_RD }, 783 - { "servc", 0x20, INSTR_RRE_RR }, 784 638 { "cfc", 0x1a, INSTR_S_RD }, 639 + { "servc", 0x20, INSTR_RRE_RR }, 785 640 { "ipte", 0x21, INSTR_RRE_RR }, 786 641 { "ipm", 0x22, INSTR_RRE_R0 }, 787 642 { "ivsk", 0x23, INSTR_RRE_RR }, ··· 792 647 { "pt", 0x28, INSTR_RRE_RR }, 793 648 { "iske", 0x29, INSTR_RRE_RR }, 794 649 { "rrbe", 0x2a, INSTR_RRE_RR }, 795 - { "sske", 0x2b, INSTR_RRE_RR }, 650 + { "sske", 0x2b, INSTR_RRF_M0RR }, 796 651 { "tb", 0x2c, INSTR_RRE_0R }, 797 - { "dxr", 0x2d, INSTR_RRE_F0 }, 652 + { "dxr", 0x2d, INSTR_RRE_FF }, 798 653 { "pgin", 0x2e, INSTR_RRE_RR }, 799 654 { "pgout", 0x2f, INSTR_RRE_RR }, 800 655 { "csch", 0x30, INSTR_S_00 }, ··· 812 667 { "schm", 0x3c, INSTR_S_00 }, 813 668 { "bakr", 0x40, INSTR_RRE_RR }, 814 669 { "cksm", 0x41, INSTR_RRE_RR }, 815 - { "sqdr", 0x44, INSTR_RRE_F0 }, 816 - { "sqer", 0x45, INSTR_RRE_F0 }, 670 + { "sqdr", 0x44, INSTR_RRE_FF }, 671 + { "sqer", 0x45, INSTR_RRE_FF }, 817 672 { "stura", 0x46, INSTR_RRE_RR }, 818 673 { "msta", 0x47, INSTR_RRE_R0 }, 819 674 { "palb", 0x48, INSTR_RRE_00 }, ··· 839 694 { "rp", 0x77, INSTR_S_RD }, 840 695 { "stcke", 0x78, INSTR_S_RD }, 841 696 { "sacf", 0x79, INSTR_S_RD }, 842 - { "spp", 0x80, INSTR_S_RD }, 843 697 { "stsi", 0x7d, INSTR_S_RD }, 698 + { "spp", 0x80, INSTR_S_RD }, 844 699 { "srnm", 0x99, INSTR_S_RD }, 845 700 { "stfpc", 0x9c, INSTR_S_RD }, 846 701 { "lfpc", 0x9d, INSTR_S_RD }, 847 702 { "tre", 0xa5, INSTR_RRE_RR }, 848 - { "cuutf", 0xa6, INSTR_RRE_RR }, 849 - { "cutfu", 0xa7, INSTR_RRE_RR }, 703 + { "cuutf", 0xa6, INSTR_RRF_M0RR }, 704 + { "cutfu", 0xa7, INSTR_RRF_M0RR }, 850 705 { "stfl", 0xb1, INSTR_S_RD }, 851 706 { "trap4", 0xff, INSTR_S_RD }, 852 707 { "", 0, INSTR_INVALID } ··· 860 715 { "myr", 0x3b, INSTR_RRF_F0FF }, 861 716 { "mayhr", 0x3c, INSTR_RRF_F0FF }, 862 717 { "myhr", 0x3d, INSTR_RRF_F0FF }, 863 - { "cegbr", 0xa4, INSTR_RRE_RR }, 864 - { "cdgbr", 0xa5, INSTR_RRE_RR }, 865 - { "cxgbr", 0xa6, INSTR_RRE_RR }, 866 - { "cgebr", 0xa8, INSTR_RRF_U0RF }, 867 - { "cgdbr", 0xa9, INSTR_RRF_U0RF }, 868 - { "cgxbr", 0xaa, INSTR_RRF_U0RF }, 869 - { "cfer", 0xb8, INSTR_RRF_U0RF }, 870 - { "cfdr", 0xb9, INSTR_RRF_U0RF }, 871 - { "cfxr", 0xba, INSTR_RRF_U0RF }, 872 - { "cegr", 0xc4, INSTR_RRE_RR }, 873 - { "cdgr", 0xc5, INSTR_RRE_RR }, 874 - { "cxgr", 0xc6, INSTR_RRE_RR }, 875 - { "cger", 0xc8, INSTR_RRF_U0RF }, 876 - { "cgdr", 0xc9, INSTR_RRF_U0RF }, 877 - { "cgxr", 0xca, INSTR_RRF_U0RF }, 878 718 { "lpdfr", 0x70, INSTR_RRE_FF }, 879 719 { "lndfr", 0x71, INSTR_RRE_FF }, 880 720 { "cpsdr", 0x72, INSTR_RRF_F0FF2 }, 881 721 { "lcdfr", 0x73, INSTR_RRE_FF }, 882 - { "ldgr", 0xc1, INSTR_RRE_FR }, 883 - { "lgdr", 0xcd, INSTR_RRE_RF }, 884 - { "adtr", 0xd2, INSTR_RRR_F0FF }, 885 - { "axtr", 0xda, INSTR_RRR_F0FF }, 886 - { "cdtr", 0xe4, INSTR_RRE_FF }, 887 - { "cxtr", 0xec, INSTR_RRE_FF }, 888 - { "kdtr", 0xe0, INSTR_RRE_FF }, 889 - { "kxtr", 0xe8, INSTR_RRE_FF }, 890 - { "cedtr", 0xf4, INSTR_RRE_FF }, 891 - { "cextr", 0xfc, INSTR_RRE_FF }, 892 - { "cdgtr", 0xf1, INSTR_RRE_FR }, 893 - { "cxgtr", 0xf9, INSTR_RRE_FR }, 894 - { "cdstr", 0xf3, INSTR_RRE_FR }, 895 - { "cxstr", 0xfb, INSTR_RRE_FR }, 896 - { "cdutr", 0xf2, INSTR_RRE_FR }, 897 - { "cxutr", 0xfa, INSTR_RRE_FR }, 898 - { "cgdtr", 0xe1, INSTR_RRF_U0RF }, 899 - { "cgxtr", 0xe9, INSTR_RRF_U0RF }, 900 - { "csdtr", 0xe3, INSTR_RRE_RF }, 901 - { "csxtr", 0xeb, INSTR_RRE_RF }, 902 - { "cudtr", 0xe2, INSTR_RRE_RF }, 903 - { "cuxtr", 0xea, INSTR_RRE_RF }, 904 - { "ddtr", 0xd1, INSTR_RRR_F0FF }, 905 - { "dxtr", 0xd9, INSTR_RRR_F0FF }, 906 - { "eedtr", 0xe5, INSTR_RRE_RF }, 907 - { "eextr", 0xed, INSTR_RRE_RF }, 908 - { "esdtr", 0xe7, INSTR_RRE_RF }, 909 - { "esxtr", 0xef, INSTR_RRE_RF }, 910 - { "iedtr", 0xf6, INSTR_RRF_F0FR }, 911 - { "iextr", 0xfe, INSTR_RRF_F0FR }, 912 - { "ltdtr", 0xd6, INSTR_RRE_FF }, 913 - { "ltxtr", 0xde, INSTR_RRE_FF }, 914 - { "fidtr", 0xd7, INSTR_RRF_UUFF }, 915 - { "fixtr", 0xdf, INSTR_RRF_UUFF }, 916 - { "ldetr", 0xd4, INSTR_RRF_0UFF }, 917 - { "lxdtr", 0xdc, INSTR_RRF_0UFF }, 918 - { "ledtr", 0xd5, INSTR_RRF_UUFF }, 919 - { "ldxtr", 0xdd, INSTR_RRF_UUFF }, 920 - { "mdtr", 0xd0, INSTR_RRR_F0FF }, 921 - { "mxtr", 0xd8, INSTR_RRR_F0FF }, 922 - { "qadtr", 0xf5, INSTR_RRF_FUFF }, 923 - { "qaxtr", 0xfd, INSTR_RRF_FUFF }, 924 - { "rrdtr", 0xf7, INSTR_RRF_FFRU }, 925 - { "rrxtr", 0xff, INSTR_RRF_FFRU }, 926 722 { "sfasr", 0x85, INSTR_RRE_R0 }, 927 - { "sdtr", 0xd3, INSTR_RRR_F0FF }, 928 - { "sxtr", 0xdb, INSTR_RRR_F0FF }, 723 + { { 0, LONG_INSN_CELFBR }, 0x90, INSTR_RRF_UUFR }, 724 + { { 0, LONG_INSN_CDLFBR }, 0x91, INSTR_RRF_UUFR }, 725 + { { 0, LONG_INSN_CXLFBR }, 0x92, INSTR_RRF_UURF }, 726 + { { 0, LONG_INSN_CEFBRA }, 0x94, INSTR_RRF_UUFR }, 727 + { { 0, LONG_INSN_CDFBRA }, 0x95, INSTR_RRF_UUFR }, 728 + { { 0, LONG_INSN_CXFBRA }, 0x96, INSTR_RRF_UURF }, 729 + { { 0, LONG_INSN_CFEBRA }, 0x98, INSTR_RRF_UURF }, 730 + { { 0, LONG_INSN_CFDBRA }, 0x99, INSTR_RRF_UURF }, 731 + { { 0, LONG_INSN_CFXBRA }, 0x9a, INSTR_RRF_UUFR }, 732 + { { 0, LONG_INSN_CLFEBR }, 0x9c, INSTR_RRF_UURF }, 733 + { { 0, LONG_INSN_CLFDBR }, 0x9d, INSTR_RRF_UURF }, 734 + { { 0, LONG_INSN_CLFXBR }, 0x9e, INSTR_RRF_UUFR }, 735 + { { 0, LONG_INSN_CELGBR }, 0xa0, INSTR_RRF_UUFR }, 736 + { { 0, LONG_INSN_CDLGBR }, 0xa1, INSTR_RRF_UUFR }, 737 + { { 0, LONG_INSN_CXLGBR }, 0xa2, INSTR_RRF_UURF }, 738 + { { 0, LONG_INSN_CEGBRA }, 0xa4, INSTR_RRF_UUFR }, 739 + { { 0, LONG_INSN_CDGBRA }, 0xa5, INSTR_RRF_UUFR }, 740 + { { 0, LONG_INSN_CXGBRA }, 0xa6, INSTR_RRF_UURF }, 741 + { { 0, LONG_INSN_CGEBRA }, 0xa8, INSTR_RRF_UURF }, 742 + { { 0, LONG_INSN_CGDBRA }, 0xa9, INSTR_RRF_UURF }, 743 + { { 0, LONG_INSN_CGXBRA }, 0xaa, INSTR_RRF_UUFR }, 744 + { { 0, LONG_INSN_CLGEBR }, 0xac, INSTR_RRF_UURF }, 745 + { { 0, LONG_INSN_CLGDBR }, 0xad, INSTR_RRF_UURF }, 746 + { { 0, LONG_INSN_CLGXBR }, 0xae, INSTR_RRF_UUFR }, 747 + { "ldgr", 0xc1, INSTR_RRE_FR }, 748 + { "cegr", 0xc4, INSTR_RRE_FR }, 749 + { "cdgr", 0xc5, INSTR_RRE_FR }, 750 + { "cxgr", 0xc6, INSTR_RRE_FR }, 751 + { "cger", 0xc8, INSTR_RRF_U0RF }, 752 + { "cgdr", 0xc9, INSTR_RRF_U0RF }, 753 + { "cgxr", 0xca, INSTR_RRF_U0RF }, 754 + { "lgdr", 0xcd, INSTR_RRE_RF }, 755 + { "mdtra", 0xd0, INSTR_RRF_FUFF2 }, 756 + { "ddtra", 0xd1, INSTR_RRF_FUFF2 }, 757 + { "adtra", 0xd2, INSTR_RRF_FUFF2 }, 758 + { "sdtra", 0xd3, INSTR_RRF_FUFF2 }, 759 + { "ldetr", 0xd4, INSTR_RRF_0UFF }, 760 + { "ledtr", 0xd5, INSTR_RRF_UUFF }, 761 + { "ltdtr", 0xd6, INSTR_RRE_FF }, 762 + { "fidtr", 0xd7, INSTR_RRF_UUFF }, 763 + { "mxtra", 0xd8, INSTR_RRF_FUFF2 }, 764 + { "dxtra", 0xd9, INSTR_RRF_FUFF2 }, 765 + { "axtra", 0xda, INSTR_RRF_FUFF2 }, 766 + { "sxtra", 0xdb, INSTR_RRF_FUFF2 }, 767 + { "lxdtr", 0xdc, INSTR_RRF_0UFF }, 768 + { "ldxtr", 0xdd, INSTR_RRF_UUFF }, 769 + { "ltxtr", 0xde, INSTR_RRE_FF }, 770 + { "fixtr", 0xdf, INSTR_RRF_UUFF }, 771 + { "kdtr", 0xe0, INSTR_RRE_FF }, 772 + { { 0, LONG_INSN_CGDTRA }, 0xe1, INSTR_RRF_UURF }, 773 + { "cudtr", 0xe2, INSTR_RRE_RF }, 774 + { "csdtr", 0xe3, INSTR_RRE_RF }, 775 + { "cdtr", 0xe4, INSTR_RRE_FF }, 776 + { "eedtr", 0xe5, INSTR_RRE_RF }, 777 + { "esdtr", 0xe7, INSTR_RRE_RF }, 778 + { "kxtr", 0xe8, INSTR_RRE_FF }, 779 + { { 0, LONG_INSN_CGXTRA }, 0xe9, INSTR_RRF_UUFR }, 780 + { "cuxtr", 0xea, INSTR_RRE_RF }, 781 + { "csxtr", 0xeb, INSTR_RRE_RF }, 782 + { "cxtr", 0xec, INSTR_RRE_FF }, 783 + { "eextr", 0xed, INSTR_RRE_RF }, 784 + { "esxtr", 0xef, INSTR_RRE_RF }, 785 + { { 0, LONG_INSN_CDGTRA }, 0xf1, INSTR_RRF_UUFR }, 786 + { "cdutr", 0xf2, INSTR_RRE_FR }, 787 + { "cdstr", 0xf3, INSTR_RRE_FR }, 788 + { "cedtr", 0xf4, INSTR_RRE_FF }, 789 + { "qadtr", 0xf5, INSTR_RRF_FUFF }, 790 + { "iedtr", 0xf6, INSTR_RRF_F0FR }, 791 + { "rrdtr", 0xf7, INSTR_RRF_FFRU }, 792 + { { 0, LONG_INSN_CXGTRA }, 0xf9, INSTR_RRF_UURF }, 793 + { "cxutr", 0xfa, INSTR_RRE_FR }, 794 + { "cxstr", 0xfb, INSTR_RRE_FR }, 795 + { "cextr", 0xfc, INSTR_RRE_FF }, 796 + { "qaxtr", 0xfd, INSTR_RRF_FUFF }, 797 + { "iextr", 0xfe, INSTR_RRF_F0FR }, 798 + { "rrxtr", 0xff, INSTR_RRF_FFRU }, 929 799 #endif 930 800 { "lpebr", 0x00, INSTR_RRE_FF }, 931 801 { "lnebr", 0x01, INSTR_RRE_FF }, ··· 987 827 { "lnxbr", 0x41, INSTR_RRE_FF }, 988 828 { "ltxbr", 0x42, INSTR_RRE_FF }, 989 829 { "lcxbr", 0x43, INSTR_RRE_FF }, 990 - { "ledbr", 0x44, INSTR_RRE_FF }, 991 - { "ldxbr", 0x45, INSTR_RRE_FF }, 992 - { "lexbr", 0x46, INSTR_RRE_FF }, 993 - { "fixbr", 0x47, INSTR_RRF_U0FF }, 830 + { { 0, LONG_INSN_LEDBRA }, 0x44, INSTR_RRF_UUFF }, 831 + { { 0, LONG_INSN_LDXBRA }, 0x45, INSTR_RRF_UUFF }, 832 + { { 0, LONG_INSN_LEXBRA }, 0x46, INSTR_RRF_UUFF }, 833 + { { 0, LONG_INSN_FIXBRA }, 0x47, INSTR_RRF_UUFF }, 994 834 { "kxbr", 0x48, INSTR_RRE_FF }, 995 835 { "cxbr", 0x49, INSTR_RRE_FF }, 996 836 { "axbr", 0x4a, INSTR_RRE_FF }, ··· 1000 840 { "tbedr", 0x50, INSTR_RRF_U0FF }, 1001 841 { "tbdr", 0x51, INSTR_RRF_U0FF }, 1002 842 { "diebr", 0x53, INSTR_RRF_FUFF }, 1003 - { "fiebr", 0x57, INSTR_RRF_U0FF }, 1004 - { "thder", 0x58, INSTR_RRE_RR }, 1005 - { "thdr", 0x59, INSTR_RRE_RR }, 843 + { { 0, LONG_INSN_FIEBRA }, 0x57, INSTR_RRF_UUFF }, 844 + { "thder", 0x58, INSTR_RRE_FF }, 845 + { "thdr", 0x59, INSTR_RRE_FF }, 1006 846 { "didbr", 0x5b, INSTR_RRF_FUFF }, 1007 - { "fidbr", 0x5f, INSTR_RRF_U0FF }, 847 + { { 0, LONG_INSN_FIDBRA }, 0x5f, INSTR_RRF_UUFF }, 1008 848 { "lpxr", 0x60, INSTR_RRE_FF }, 1009 849 { "lnxr", 0x61, INSTR_RRE_FF }, 1010 850 { "ltxr", 0x62, INSTR_RRE_FF }, 1011 851 { "lcxr", 0x63, INSTR_RRE_FF }, 1012 - { "lxr", 0x65, INSTR_RRE_RR }, 852 + { "lxr", 0x65, INSTR_RRE_FF }, 1013 853 { "lexr", 0x66, INSTR_RRE_FF }, 1014 - { "fixr", 0x67, INSTR_RRF_U0FF }, 854 + { "fixr", 0x67, INSTR_RRE_FF }, 1015 855 { "cxr", 0x69, INSTR_RRE_FF }, 1016 - { "lzer", 0x74, INSTR_RRE_R0 }, 1017 - { "lzdr", 0x75, INSTR_RRE_R0 }, 1018 - { "lzxr", 0x76, INSTR_RRE_R0 }, 1019 - { "fier", 0x77, INSTR_RRF_U0FF }, 1020 - { "fidr", 0x7f, INSTR_RRF_U0FF }, 856 + { "lzer", 0x74, INSTR_RRE_F0 }, 857 + { "lzdr", 0x75, INSTR_RRE_F0 }, 858 + { "lzxr", 0x76, INSTR_RRE_F0 }, 859 + { "fier", 0x77, INSTR_RRE_FF }, 860 + { "fidr", 0x7f, INSTR_RRE_FF }, 1021 861 { "sfpc", 0x84, INSTR_RRE_RR_OPT }, 1022 862 { "efpc", 0x8c, INSTR_RRE_RR_OPT }, 1023 863 { "cefbr", 0x94, INSTR_RRE_RF }, ··· 1026 866 { "cfebr", 0x98, INSTR_RRF_U0RF }, 1027 867 { "cfdbr", 0x99, INSTR_RRF_U0RF }, 1028 868 { "cfxbr", 0x9a, INSTR_RRF_U0RF }, 1029 - { "cefr", 0xb4, INSTR_RRE_RF }, 1030 - { "cdfr", 0xb5, INSTR_RRE_RF }, 1031 - { "cxfr", 0xb6, INSTR_RRE_RF }, 869 + { "cefr", 0xb4, INSTR_RRE_FR }, 870 + { "cdfr", 0xb5, INSTR_RRE_FR }, 871 + { "cxfr", 0xb6, INSTR_RRE_FR }, 872 + { "cfer", 0xb8, INSTR_RRF_U0RF }, 873 + { "cfdr", 0xb9, INSTR_RRF_U0RF }, 874 + { "cfxr", 0xba, INSTR_RRF_U0RF }, 1032 875 { "", 0, INSTR_INVALID } 1033 876 }; 1034 877 ··· 1073 910 { "lhr", 0x27, INSTR_RRE_RR }, 1074 911 { "cgfr", 0x30, INSTR_RRE_RR }, 1075 912 { "clgfr", 0x31, INSTR_RRE_RR }, 913 + { "cfdtr", 0x41, INSTR_RRF_UURF }, 914 + { { 0, LONG_INSN_CLGDTR }, 0x42, INSTR_RRF_UURF }, 915 + { { 0, LONG_INSN_CLFDTR }, 0x43, INSTR_RRF_UURF }, 1076 916 { "bctgr", 0x46, INSTR_RRE_RR }, 917 + { "cfxtr", 0x49, INSTR_RRF_UURF }, 918 + { { 0, LONG_INSN_CLGXTR }, 0x4a, INSTR_RRF_UUFR }, 919 + { { 0, LONG_INSN_CLFXTR }, 0x4b, INSTR_RRF_UUFR }, 920 + { "cdftr", 0x51, INSTR_RRF_UUFR }, 921 + { { 0, LONG_INSN_CDLGTR }, 0x52, INSTR_RRF_UUFR }, 922 + { { 0, LONG_INSN_CDLFTR }, 0x53, INSTR_RRF_UUFR }, 923 + { "cxftr", 0x59, INSTR_RRF_UURF }, 924 + { { 0, LONG_INSN_CXLGTR }, 0x5a, INSTR_RRF_UURF }, 925 + { { 0, LONG_INSN_CXLFTR }, 0x5b, INSTR_RRF_UUFR }, 926 + { "cgrt", 0x60, INSTR_RRF_U0RR }, 927 + { "clgrt", 0x61, INSTR_RRF_U0RR }, 928 + { "crt", 0x72, INSTR_RRF_U0RR }, 929 + { "clrt", 0x73, INSTR_RRF_U0RR }, 1077 930 { "ngr", 0x80, INSTR_RRE_RR }, 1078 931 { "ogr", 0x81, INSTR_RRE_RR }, 1079 932 { "xgr", 0x82, INSTR_RRE_RR }, ··· 1102 923 { "slbgr", 0x89, INSTR_RRE_RR }, 1103 924 { "cspg", 0x8a, INSTR_RRE_RR }, 1104 925 { "idte", 0x8e, INSTR_RRF_R0RR }, 926 + { "crdte", 0x8f, INSTR_RRF_RMRR }, 1105 927 { "llcr", 0x94, INSTR_RRE_RR }, 1106 928 { "llhr", 0x95, INSTR_RRE_RR }, 1107 929 { "esea", 0x9d, INSTR_RRE_R0 }, 930 + { "ptf", 0xa2, INSTR_RRE_R0 }, 1108 931 { "lptea", 0xaa, INSTR_RRF_RURR }, 932 + { "rrbm", 0xae, INSTR_RRE_RR }, 933 + { "pfmf", 0xaf, INSTR_RRE_RR }, 1109 934 { "cu14", 0xb0, INSTR_RRF_M0RR }, 1110 935 { "cu24", 0xb1, INSTR_RRF_M0RR }, 1111 - { "cu41", 0xb2, INSTR_RRF_M0RR }, 1112 - { "cu42", 0xb3, INSTR_RRF_M0RR }, 1113 - { "crt", 0x72, INSTR_RRF_U0RR }, 1114 - { "cgrt", 0x60, INSTR_RRF_U0RR }, 1115 - { "clrt", 0x73, INSTR_RRF_U0RR }, 1116 - { "clgrt", 0x61, INSTR_RRF_U0RR }, 1117 - { "ptf", 0xa2, INSTR_RRE_R0 }, 1118 - { "pfmf", 0xaf, INSTR_RRE_RR }, 1119 - { "trte", 0xbf, INSTR_RRF_M0RR }, 936 + { "cu41", 0xb2, INSTR_RRE_RR }, 937 + { "cu42", 0xb3, INSTR_RRE_RR }, 1120 938 { "trtre", 0xbd, INSTR_RRF_M0RR }, 939 + { "srstu", 0xbe, INSTR_RRE_RR }, 940 + { "trte", 0xbf, INSTR_RRF_M0RR }, 1121 941 { "ahhhr", 0xc8, INSTR_RRF_R0RR2 }, 1122 942 { "shhhr", 0xc9, INSTR_RRF_R0RR2 }, 1123 - { "alhhh", 0xca, INSTR_RRF_R0RR2 }, 1124 - { "alhhl", 0xca, INSTR_RRF_R0RR2 }, 1125 - { "slhhh", 0xcb, INSTR_RRF_R0RR2 }, 1126 - { "chhr ", 0xcd, INSTR_RRE_RR }, 943 + { { 0, LONG_INSN_ALHHHR }, 0xca, INSTR_RRF_R0RR2 }, 944 + { { 0, LONG_INSN_SLHHHR }, 0xcb, INSTR_RRF_R0RR2 }, 945 + { "chhr", 0xcd, INSTR_RRE_RR }, 1127 946 { "clhhr", 0xcf, INSTR_RRE_RR }, 947 + { { 0, LONG_INSN_PCISTG }, 0xd0, INSTR_RRE_RR }, 948 + { "pcilg", 0xd2, INSTR_RRE_RR }, 949 + { "rpcit", 0xd3, INSTR_RRE_RR }, 1128 950 { "ahhlr", 0xd8, INSTR_RRF_R0RR2 }, 1129 951 { "shhlr", 0xd9, INSTR_RRF_R0RR2 }, 1130 - { "slhhl", 0xdb, INSTR_RRF_R0RR2 }, 952 + { { 0, LONG_INSN_ALHHLR }, 0xda, INSTR_RRF_R0RR2 }, 953 + { { 0, LONG_INSN_SLHHLR }, 0xdb, INSTR_RRF_R0RR2 }, 1131 954 { "chlr", 0xdd, INSTR_RRE_RR }, 1132 955 { "clhlr", 0xdf, INSTR_RRE_RR }, 1133 956 { { 0, LONG_INSN_POPCNT }, 0xe1, INSTR_RRE_RR }, ··· 1157 976 { "kimd", 0x3e, INSTR_RRE_RR }, 1158 977 { "klmd", 0x3f, INSTR_RRE_RR }, 1159 978 { "epsw", 0x8d, INSTR_RRE_RR }, 1160 - { "trtt", 0x90, INSTR_RRE_RR }, 1161 979 { "trtt", 0x90, INSTR_RRF_M0RR }, 1162 - { "trto", 0x91, INSTR_RRE_RR }, 1163 980 { "trto", 0x91, INSTR_RRF_M0RR }, 1164 - { "trot", 0x92, INSTR_RRE_RR }, 1165 981 { "trot", 0x92, INSTR_RRF_M0RR }, 1166 - { "troo", 0x93, INSTR_RRE_RR }, 1167 982 { "troo", 0x93, INSTR_RRF_M0RR }, 1168 983 { "mlr", 0x96, INSTR_RRE_RR }, 1169 984 { "dlr", 0x97, INSTR_RRE_RR }, ··· 1190 1013 1191 1014 static struct insn opcode_c2[] = { 1192 1015 #ifdef CONFIG_64BIT 1016 + { "msgfi", 0x00, INSTR_RIL_RI }, 1017 + { "msfi", 0x01, INSTR_RIL_RI }, 1193 1018 { "slgfi", 0x04, INSTR_RIL_RU }, 1194 1019 { "slfi", 0x05, INSTR_RIL_RU }, 1195 1020 { "agfi", 0x08, INSTR_RIL_RI }, ··· 1202 1023 { "cfi", 0x0d, INSTR_RIL_RI }, 1203 1024 { "clgfi", 0x0e, INSTR_RIL_RU }, 1204 1025 { "clfi", 0x0f, INSTR_RIL_RU }, 1205 - { "msfi", 0x01, INSTR_RIL_RI }, 1206 - { "msgfi", 0x00, INSTR_RIL_RI }, 1207 1026 #endif 1208 1027 { "", 0, INSTR_INVALID } 1209 1028 }; 1210 1029 1211 1030 static struct insn opcode_c4[] = { 1212 1031 #ifdef CONFIG_64BIT 1213 - { "lrl", 0x0d, INSTR_RIL_RP }, 1214 - { "lgrl", 0x08, INSTR_RIL_RP }, 1215 - { "lgfrl", 0x0c, INSTR_RIL_RP }, 1216 - { "lhrl", 0x05, INSTR_RIL_RP }, 1217 - { "lghrl", 0x04, INSTR_RIL_RP }, 1218 - { { 0, LONG_INSN_LLGFRL }, 0x0e, INSTR_RIL_RP }, 1219 1032 { "llhrl", 0x02, INSTR_RIL_RP }, 1033 + { "lghrl", 0x04, INSTR_RIL_RP }, 1034 + { "lhrl", 0x05, INSTR_RIL_RP }, 1220 1035 { { 0, LONG_INSN_LLGHRL }, 0x06, INSTR_RIL_RP }, 1221 - { "strl", 0x0f, INSTR_RIL_RP }, 1222 - { "stgrl", 0x0b, INSTR_RIL_RP }, 1223 1036 { "sthrl", 0x07, INSTR_RIL_RP }, 1037 + { "lgrl", 0x08, INSTR_RIL_RP }, 1038 + { "stgrl", 0x0b, INSTR_RIL_RP }, 1039 + { "lgfrl", 0x0c, INSTR_RIL_RP }, 1040 + { "lrl", 0x0d, INSTR_RIL_RP }, 1041 + { { 0, LONG_INSN_LLGFRL }, 0x0e, INSTR_RIL_RP }, 1042 + { "strl", 0x0f, INSTR_RIL_RP }, 1224 1043 #endif 1225 1044 { "", 0, INSTR_INVALID } 1226 1045 }; 1227 1046 1228 1047 static struct insn opcode_c6[] = { 1229 1048 #ifdef CONFIG_64BIT 1230 - { "crl", 0x0d, INSTR_RIL_RP }, 1231 - { "cgrl", 0x08, INSTR_RIL_RP }, 1232 - { "cgfrl", 0x0c, INSTR_RIL_RP }, 1233 - { "chrl", 0x05, INSTR_RIL_RP }, 1234 - { "cghrl", 0x04, INSTR_RIL_RP }, 1235 - { "clrl", 0x0f, INSTR_RIL_RP }, 1236 - { "clgrl", 0x0a, INSTR_RIL_RP }, 1237 - { { 0, LONG_INSN_CLGFRL }, 0x0e, INSTR_RIL_RP }, 1238 - { "clhrl", 0x07, INSTR_RIL_RP }, 1239 - { { 0, LONG_INSN_CLGHRL }, 0x06, INSTR_RIL_RP }, 1240 - { "pfdrl", 0x02, INSTR_RIL_UP }, 1241 1049 { "exrl", 0x00, INSTR_RIL_RP }, 1050 + { "pfdrl", 0x02, INSTR_RIL_UP }, 1051 + { "cghrl", 0x04, INSTR_RIL_RP }, 1052 + { "chrl", 0x05, INSTR_RIL_RP }, 1053 + { { 0, LONG_INSN_CLGHRL }, 0x06, INSTR_RIL_RP }, 1054 + { "clhrl", 0x07, INSTR_RIL_RP }, 1055 + { "cgrl", 0x08, INSTR_RIL_RP }, 1056 + { "clgrl", 0x0a, INSTR_RIL_RP }, 1057 + { "cgfrl", 0x0c, INSTR_RIL_RP }, 1058 + { "crl", 0x0d, INSTR_RIL_RP }, 1059 + { { 0, LONG_INSN_CLGFRL }, 0x0e, INSTR_RIL_RP }, 1060 + { "clrl", 0x0f, INSTR_RIL_RP }, 1242 1061 #endif 1243 1062 { "", 0, INSTR_INVALID } 1244 1063 }; ··· 1247 1070 { "ectg", 0x01, INSTR_SSF_RRDRD }, 1248 1071 { "csst", 0x02, INSTR_SSF_RRDRD }, 1249 1072 { "lpd", 0x04, INSTR_SSF_RRDRD2 }, 1250 - { "lpdg ", 0x05, INSTR_SSF_RRDRD2 }, 1073 + { "lpdg", 0x05, INSTR_SSF_RRDRD2 }, 1251 1074 #endif 1252 1075 { "", 0, INSTR_INVALID } 1253 1076 }; ··· 1257 1080 { "brcth", 0x06, INSTR_RIL_RP }, 1258 1081 { "aih", 0x08, INSTR_RIL_RI }, 1259 1082 { "alsih", 0x0a, INSTR_RIL_RI }, 1260 - { "alsih", 0x0b, INSTR_RIL_RI }, 1083 + { { 0, LONG_INSN_ALSIHN }, 0x0b, INSTR_RIL_RI }, 1261 1084 { "cih", 0x0d, INSTR_RIL_RI }, 1262 - { "clih ", 0x0f, INSTR_RIL_RI }, 1085 + { "clih", 0x0f, INSTR_RIL_RI }, 1263 1086 #endif 1264 1087 { "", 0, INSTR_INVALID } 1265 1088 }; ··· 1293 1116 { "cg", 0x20, INSTR_RXY_RRRD }, 1294 1117 { "clg", 0x21, INSTR_RXY_RRRD }, 1295 1118 { "stg", 0x24, INSTR_RXY_RRRD }, 1119 + { "ntstg", 0x25, INSTR_RXY_RRRD }, 1296 1120 { "cvdy", 0x26, INSTR_RXY_RRRD }, 1297 1121 { "cvdg", 0x2e, INSTR_RXY_RRRD }, 1298 1122 { "strvg", 0x2f, INSTR_RXY_RRRD }, 1299 1123 { "cgf", 0x30, INSTR_RXY_RRRD }, 1300 1124 { "clgf", 0x31, INSTR_RXY_RRRD }, 1125 + { "ltgf", 0x32, INSTR_RXY_RRRD }, 1126 + { "cgh", 0x34, INSTR_RXY_RRRD }, 1127 + { "pfd", 0x36, INSTR_RXY_URRD }, 1301 1128 { "strvh", 0x3f, INSTR_RXY_RRRD }, 1302 1129 { "bctg", 0x46, INSTR_RXY_RRRD }, 1303 1130 { "sty", 0x50, INSTR_RXY_RRRD }, ··· 1314 1133 { "cy", 0x59, INSTR_RXY_RRRD }, 1315 1134 { "ay", 0x5a, INSTR_RXY_RRRD }, 1316 1135 { "sy", 0x5b, INSTR_RXY_RRRD }, 1136 + { "mfy", 0x5c, INSTR_RXY_RRRD }, 1317 1137 { "aly", 0x5e, INSTR_RXY_RRRD }, 1318 1138 { "sly", 0x5f, INSTR_RXY_RRRD }, 1319 1139 { "sthy", 0x70, INSTR_RXY_RRRD }, 1320 1140 { "lay", 0x71, INSTR_RXY_RRRD }, 1321 1141 { "stcy", 0x72, INSTR_RXY_RRRD }, 1322 1142 { "icy", 0x73, INSTR_RXY_RRRD }, 1143 + { "laey", 0x75, INSTR_RXY_RRRD }, 1323 1144 { "lb", 0x76, INSTR_RXY_RRRD }, 1324 1145 { "lgb", 0x77, INSTR_RXY_RRRD }, 1325 1146 { "lhy", 0x78, INSTR_RXY_RRRD }, 1326 1147 { "chy", 0x79, INSTR_RXY_RRRD }, 1327 1148 { "ahy", 0x7a, INSTR_RXY_RRRD }, 1328 1149 { "shy", 0x7b, INSTR_RXY_RRRD }, 1150 + { "mhy", 0x7c, INSTR_RXY_RRRD }, 1329 1151 { "ng", 0x80, INSTR_RXY_RRRD }, 1330 1152 { "og", 0x81, INSTR_RXY_RRRD }, 1331 1153 { "xg", 0x82, INSTR_RXY_RRRD }, 1154 + { "lgat", 0x85, INSTR_RXY_RRRD }, 1332 1155 { "mlg", 0x86, INSTR_RXY_RRRD }, 1333 1156 { "dlg", 0x87, INSTR_RXY_RRRD }, 1334 1157 { "alcg", 0x88, INSTR_RXY_RRRD }, ··· 1343 1158 { "llgh", 0x91, INSTR_RXY_RRRD }, 1344 1159 { "llc", 0x94, INSTR_RXY_RRRD }, 1345 1160 { "llh", 0x95, INSTR_RXY_RRRD }, 1346 - { "cgh", 0x34, INSTR_RXY_RRRD }, 1347 - { "laey", 0x75, INSTR_RXY_RRRD }, 1348 - { "ltgf", 0x32, INSTR_RXY_RRRD }, 1349 - { "mfy", 0x5c, INSTR_RXY_RRRD }, 1350 - { "mhy", 0x7c, INSTR_RXY_RRRD }, 1351 - { "pfd", 0x36, INSTR_RXY_URRD }, 1161 + { { 0, LONG_INSN_LLGTAT }, 0x9c, INSTR_RXY_RRRD }, 1162 + { { 0, LONG_INSN_LLGFAT }, 0x9d, INSTR_RXY_RRRD }, 1163 + { "lat", 0x9f, INSTR_RXY_RRRD }, 1352 1164 { "lbh", 0xc0, INSTR_RXY_RRRD }, 1353 1165 { "llch", 0xc2, INSTR_RXY_RRRD }, 1354 1166 { "stch", 0xc3, INSTR_RXY_RRRD }, 1355 1167 { "lhh", 0xc4, INSTR_RXY_RRRD }, 1356 1168 { "llhh", 0xc6, INSTR_RXY_RRRD }, 1357 1169 { "sthh", 0xc7, INSTR_RXY_RRRD }, 1170 + { "lfhat", 0xc8, INSTR_RXY_RRRD }, 1358 1171 { "lfh", 0xca, INSTR_RXY_RRRD }, 1359 1172 { "stfh", 0xcb, INSTR_RXY_RRRD }, 1360 1173 { "chf", 0xcd, INSTR_RXY_RRRD }, 1361 1174 { "clhf", 0xcf, INSTR_RXY_RRRD }, 1362 - { "ntstg", 0x25, INSTR_RXY_RRRD }, 1175 + { { 0, LONG_INSN_MPCIFC }, 0xd0, INSTR_RXY_RRRD }, 1176 + { { 0, LONG_INSN_STPCIFC }, 0xd4, INSTR_RXY_RRRD }, 1363 1177 #endif 1364 1178 { "lrv", 0x1e, INSTR_RXY_RRRD }, 1365 1179 { "lrvh", 0x1f, INSTR_RXY_RRRD }, ··· 1373 1189 static struct insn opcode_e5[] = { 1374 1190 #ifdef CONFIG_64BIT 1375 1191 { "strag", 0x02, INSTR_SSE_RDRD }, 1376 - { "chhsi", 0x54, INSTR_SIL_RDI }, 1377 - { "chsi", 0x5c, INSTR_SIL_RDI }, 1378 - { "cghsi", 0x58, INSTR_SIL_RDI }, 1379 - { { 0, LONG_INSN_CLHHSI }, 0x55, INSTR_SIL_RDU }, 1380 - { { 0, LONG_INSN_CLFHSI }, 0x5d, INSTR_SIL_RDU }, 1381 - { { 0, LONG_INSN_CLGHSI }, 0x59, INSTR_SIL_RDU }, 1382 1192 { "mvhhi", 0x44, INSTR_SIL_RDI }, 1383 - { "mvhi", 0x4c, INSTR_SIL_RDI }, 1384 1193 { "mvghi", 0x48, INSTR_SIL_RDI }, 1194 + { "mvhi", 0x4c, INSTR_SIL_RDI }, 1195 + { "chhsi", 0x54, INSTR_SIL_RDI }, 1196 + { { 0, LONG_INSN_CLHHSI }, 0x55, INSTR_SIL_RDU }, 1197 + { "cghsi", 0x58, INSTR_SIL_RDI }, 1198 + { { 0, LONG_INSN_CLGHSI }, 0x59, INSTR_SIL_RDU }, 1199 + { "chsi", 0x5c, INSTR_SIL_RDI }, 1200 + { { 0, LONG_INSN_CLFHSI }, 0x5d, INSTR_SIL_RDU }, 1385 1201 { { 0, LONG_INSN_TBEGIN }, 0x60, INSTR_SIL_RDU }, 1386 1202 { { 0, LONG_INSN_TBEGINC }, 0x61, INSTR_SIL_RDU }, 1387 1203 #endif ··· 1404 1220 { "rllg", 0x1c, INSTR_RSY_RRRD }, 1405 1221 { "clmh", 0x20, INSTR_RSY_RURD }, 1406 1222 { "clmy", 0x21, INSTR_RSY_RURD }, 1223 + { "clt", 0x23, INSTR_RSY_RURD }, 1407 1224 { "stmg", 0x24, INSTR_RSY_RRRD }, 1408 1225 { "stctg", 0x25, INSTR_RSY_CCRD }, 1409 1226 { "stmh", 0x26, INSTR_RSY_RRRD }, 1227 + { "clgt", 0x2b, INSTR_RSY_RURD }, 1410 1228 { "stcmh", 0x2c, INSTR_RSY_RURD }, 1411 1229 { "stcmy", 0x2d, INSTR_RSY_RURD }, 1412 1230 { "lctlg", 0x2f, INSTR_RSY_CCRD }, ··· 1417 1231 { "cdsg", 0x3e, INSTR_RSY_RRRD }, 1418 1232 { "bxhg", 0x44, INSTR_RSY_RRRD }, 1419 1233 { "bxleg", 0x45, INSTR_RSY_RRRD }, 1234 + { "ecag", 0x4c, INSTR_RSY_RRRD }, 1420 1235 { "tmy", 0x51, INSTR_SIY_URD }, 1421 1236 { "mviy", 0x52, INSTR_SIY_URD }, 1422 1237 { "niy", 0x54, INSTR_SIY_URD }, 1423 1238 { "cliy", 0x55, INSTR_SIY_URD }, 1424 1239 { "oiy", 0x56, INSTR_SIY_URD }, 1425 1240 { "xiy", 0x57, INSTR_SIY_URD }, 1426 - { "lric", 0x60, INSTR_RSY_RDRM }, 1427 - { "stric", 0x61, INSTR_RSY_RDRM }, 1428 - { "mric", 0x62, INSTR_RSY_RDRM }, 1429 - { "icmh", 0x80, INSTR_RSE_RURD }, 1241 + { "asi", 0x6a, INSTR_SIY_IRD }, 1242 + { "alsi", 0x6e, INSTR_SIY_IRD }, 1243 + { "agsi", 0x7a, INSTR_SIY_IRD }, 1244 + { "algsi", 0x7e, INSTR_SIY_IRD }, 1430 1245 { "icmh", 0x80, INSTR_RSY_RURD }, 1431 1246 { "icmy", 0x81, INSTR_RSY_RURD }, 1432 1247 { "clclu", 0x8f, INSTR_RSY_RRRD }, ··· 1436 1249 { "lmy", 0x98, INSTR_RSY_RRRD }, 1437 1250 { "lamy", 0x9a, INSTR_RSY_AARD }, 1438 1251 { "stamy", 0x9b, INSTR_RSY_AARD }, 1439 - { "asi", 0x6a, INSTR_SIY_IRD }, 1440 - { "agsi", 0x7a, INSTR_SIY_IRD }, 1441 - { "alsi", 0x6e, INSTR_SIY_IRD }, 1442 - { "algsi", 0x7e, INSTR_SIY_IRD }, 1443 - { "ecag", 0x4c, INSTR_RSY_RRRD }, 1252 + { { 0, LONG_INSN_PCISTB }, 0xd0, INSTR_RSY_RRRD }, 1253 + { "sic", 0xd1, INSTR_RSY_RRRD }, 1444 1254 { "srak", 0xdc, INSTR_RSY_RRRD }, 1445 1255 { "slak", 0xdd, INSTR_RSY_RRRD }, 1446 1256 { "srlk", 0xde, INSTR_RSY_RRRD }, ··· 1456 1272 { "lax", 0xf7, INSTR_RSY_RRRD }, 1457 1273 { "laa", 0xf8, INSTR_RSY_RRRD }, 1458 1274 { "laal", 0xfa, INSTR_RSY_RRRD }, 1275 + { "lric", 0x60, INSTR_RSY_RDRM }, 1276 + { "stric", 0x61, INSTR_RSY_RDRM }, 1277 + { "mric", 0x62, INSTR_RSY_RDRM }, 1459 1278 #endif 1460 1279 { "rll", 0x1d, INSTR_RSY_RRRD }, 1461 1280 { "mvclu", 0x8e, INSTR_RSY_RRRD }, ··· 1470 1283 #ifdef CONFIG_64BIT 1471 1284 { "brxhg", 0x44, INSTR_RIE_RRP }, 1472 1285 { "brxlg", 0x45, INSTR_RIE_RRP }, 1473 - { "crb", 0xf6, INSTR_RRS_RRRDU }, 1474 - { "cgrb", 0xe4, INSTR_RRS_RRRDU }, 1475 - { "crj", 0x76, INSTR_RIE_RRPU }, 1476 - { "cgrj", 0x64, INSTR_RIE_RRPU }, 1477 - { "cib", 0xfe, INSTR_RIS_RURDI }, 1478 - { "cgib", 0xfc, INSTR_RIS_RURDI }, 1479 - { "cij", 0x7e, INSTR_RIE_RUPI }, 1480 - { "cgij", 0x7c, INSTR_RIE_RUPI }, 1481 - { "cit", 0x72, INSTR_RIE_R0IU }, 1482 - { "cgit", 0x70, INSTR_RIE_R0IU }, 1483 - { "clrb", 0xf7, INSTR_RRS_RRRDU }, 1484 - { "clgrb", 0xe5, INSTR_RRS_RRRDU }, 1485 - { "clrj", 0x77, INSTR_RIE_RRPU }, 1486 - { "clgrj", 0x65, INSTR_RIE_RRPU }, 1487 - { "clib", 0xff, INSTR_RIS_RURDU }, 1488 - { "clgib", 0xfd, INSTR_RIS_RURDU }, 1489 - { "clij", 0x7f, INSTR_RIE_RUPU }, 1490 - { "clgij", 0x7d, INSTR_RIE_RUPU }, 1491 - { "clfit", 0x73, INSTR_RIE_R0UU }, 1492 - { "clgit", 0x71, INSTR_RIE_R0UU }, 1493 - { "rnsbg", 0x54, INSTR_RIE_RRUUU }, 1494 - { "rxsbg", 0x57, INSTR_RIE_RRUUU }, 1495 - { "rosbg", 0x56, INSTR_RIE_RRUUU }, 1496 - { "risbg", 0x55, INSTR_RIE_RRUUU }, 1497 1286 { { 0, LONG_INSN_RISBLG }, 0x51, INSTR_RIE_RRUUU }, 1287 + { "rnsbg", 0x54, INSTR_RIE_RRUUU }, 1288 + { "risbg", 0x55, INSTR_RIE_RRUUU }, 1289 + { "rosbg", 0x56, INSTR_RIE_RRUUU }, 1290 + { "rxsbg", 0x57, INSTR_RIE_RRUUU }, 1291 + { { 0, LONG_INSN_RISBGN }, 0x59, INSTR_RIE_RRUUU }, 1498 1292 { { 0, LONG_INSN_RISBHG }, 0x5D, INSTR_RIE_RRUUU }, 1293 + { "cgrj", 0x64, INSTR_RIE_RRPU }, 1294 + { "clgrj", 0x65, INSTR_RIE_RRPU }, 1295 + { "cgit", 0x70, INSTR_RIE_R0IU }, 1296 + { "clgit", 0x71, INSTR_RIE_R0UU }, 1297 + { "cit", 0x72, INSTR_RIE_R0IU }, 1298 + { "clfit", 0x73, INSTR_RIE_R0UU }, 1299 + { "crj", 0x76, INSTR_RIE_RRPU }, 1300 + { "clrj", 0x77, INSTR_RIE_RRPU }, 1301 + { "cgij", 0x7c, INSTR_RIE_RUPI }, 1302 + { "clgij", 0x7d, INSTR_RIE_RUPU }, 1303 + { "cij", 0x7e, INSTR_RIE_RUPI }, 1304 + { "clij", 0x7f, INSTR_RIE_RUPU }, 1499 1305 { "ahik", 0xd8, INSTR_RIE_RRI0 }, 1500 1306 { "aghik", 0xd9, INSTR_RIE_RRI0 }, 1501 1307 { { 0, LONG_INSN_ALHSIK }, 0xda, INSTR_RIE_RRI0 }, 1502 1308 { { 0, LONG_INSN_ALGHSIK }, 0xdb, INSTR_RIE_RRI0 }, 1309 + { "cgrb", 0xe4, INSTR_RRS_RRRDU }, 1310 + { "clgrb", 0xe5, INSTR_RRS_RRRDU }, 1311 + { "crb", 0xf6, INSTR_RRS_RRRDU }, 1312 + { "clrb", 0xf7, INSTR_RRS_RRRDU }, 1313 + { "cgib", 0xfc, INSTR_RIS_RURDI }, 1314 + { "clgib", 0xfd, INSTR_RIS_RURDU }, 1315 + { "cib", 0xfe, INSTR_RIS_RURDI }, 1316 + { "clib", 0xff, INSTR_RIS_RURDU }, 1503 1317 #endif 1504 1318 { "", 0, INSTR_INVALID } 1505 1319 }; ··· 1513 1325 { "my", 0x3b, INSTR_RXF_FRRDF }, 1514 1326 { "mayh", 0x3c, INSTR_RXF_FRRDF }, 1515 1327 { "myh", 0x3d, INSTR_RXF_FRRDF }, 1328 + { "sldt", 0x40, INSTR_RXF_FRRDF }, 1329 + { "srdt", 0x41, INSTR_RXF_FRRDF }, 1330 + { "slxt", 0x48, INSTR_RXF_FRRDF }, 1331 + { "srxt", 0x49, INSTR_RXF_FRRDF }, 1332 + { "tdcet", 0x50, INSTR_RXE_FRRD }, 1333 + { "tdget", 0x51, INSTR_RXE_FRRD }, 1334 + { "tdcdt", 0x54, INSTR_RXE_FRRD }, 1335 + { "tdgdt", 0x55, INSTR_RXE_FRRD }, 1336 + { "tdcxt", 0x58, INSTR_RXE_FRRD }, 1337 + { "tdgxt", 0x59, INSTR_RXE_FRRD }, 1516 1338 { "ley", 0x64, INSTR_RXY_FRRD }, 1517 1339 { "ldy", 0x65, INSTR_RXY_FRRD }, 1518 1340 { "stey", 0x66, INSTR_RXY_FRRD }, 1519 1341 { "stdy", 0x67, INSTR_RXY_FRRD }, 1520 - { "sldt", 0x40, INSTR_RXF_FRRDF }, 1521 - { "slxt", 0x48, INSTR_RXF_FRRDF }, 1522 - { "srdt", 0x41, INSTR_RXF_FRRDF }, 1523 - { "srxt", 0x49, INSTR_RXF_FRRDF }, 1524 - { "tdcet", 0x50, INSTR_RXE_FRRD }, 1525 - { "tdcdt", 0x54, INSTR_RXE_FRRD }, 1526 - { "tdcxt", 0x58, INSTR_RXE_FRRD }, 1527 - { "tdget", 0x51, INSTR_RXE_FRRD }, 1528 - { "tdgdt", 0x55, INSTR_RXE_FRRD }, 1529 - { "tdgxt", 0x59, INSTR_RXE_FRRD }, 1342 + { "czdt", 0xa8, INSTR_RSL_LRDFU }, 1343 + { "czxt", 0xa9, INSTR_RSL_LRDFU }, 1344 + { "cdzt", 0xaa, INSTR_RSL_LRDFU }, 1345 + { "cxzt", 0xab, INSTR_RSL_LRDFU }, 1530 1346 #endif 1531 1347 { "ldeb", 0x04, INSTR_RXE_FRRD }, 1532 1348 { "lxdb", 0x05, INSTR_RXE_FRRD },
+3 -4
arch/s390/kernel/entry.S
··· 231 231 jo sysc_mcck_pending 232 232 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED 233 233 jo sysc_reschedule 234 + tm __TI_flags+3(%r12),_TIF_PER_TRAP 235 + jo sysc_singlestep 234 236 tm __TI_flags+3(%r12),_TIF_SIGPENDING 235 237 jo sysc_sigpending 236 238 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME 237 239 jo sysc_notify_resume 238 - tm __TI_flags+3(%r12),_TIF_PER_TRAP 239 - jo sysc_singlestep 240 240 j sysc_return # beware of critical section cleanup 241 241 242 242 # ··· 259 259 # _TIF_SIGPENDING is set, call do_signal 260 260 # 261 261 sysc_sigpending: 262 - ni __TI_flags+3(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP 263 262 lr %r2,%r11 # pass pointer to pt_regs 264 263 l %r1,BASED(.Ldo_signal) 265 264 basr %r14,%r1 # call do_signal ··· 285 286 # _TIF_PER_TRAP is set, call do_per_trap 286 287 # 287 288 sysc_singlestep: 288 - ni __TI_flags+3(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP) 289 + ni __TI_flags+3(%r12),255-_TIF_PER_TRAP 289 290 lr %r2,%r11 # pass pointer to pt_regs 290 291 l %r1,BASED(.Ldo_per_trap) 291 292 la %r14,BASED(sysc_return)
+20 -1
arch/s390/kernel/entry.h
··· 6 6 #include <asm/ptrace.h> 7 7 #include <asm/cputime.h> 8 8 9 - extern void (*pgm_check_table[128])(struct pt_regs *); 10 9 extern void *restart_stack; 11 10 12 11 void system_call(void); ··· 23 24 void do_protection_exception(struct pt_regs *regs); 24 25 void do_dat_exception(struct pt_regs *regs); 25 26 void do_asce_exception(struct pt_regs *regs); 27 + 28 + void addressing_exception(struct pt_regs *regs); 29 + void data_exception(struct pt_regs *regs); 30 + void default_trap_handler(struct pt_regs *regs); 31 + void divide_exception(struct pt_regs *regs); 32 + void execute_exception(struct pt_regs *regs); 33 + void hfp_divide_exception(struct pt_regs *regs); 34 + void hfp_overflow_exception(struct pt_regs *regs); 35 + void hfp_significance_exception(struct pt_regs *regs); 36 + void hfp_sqrt_exception(struct pt_regs *regs); 37 + void hfp_underflow_exception(struct pt_regs *regs); 38 + void illegal_op(struct pt_regs *regs); 39 + void operand_exception(struct pt_regs *regs); 40 + void overflow_exception(struct pt_regs *regs); 41 + void privileged_op(struct pt_regs *regs); 42 + void space_switch_exception(struct pt_regs *regs); 43 + void special_op_exception(struct pt_regs *regs); 44 + void specification_exception(struct pt_regs *regs); 45 + void transaction_exception(struct pt_regs *regs); 46 + void translation_exception(struct pt_regs *regs); 26 47 27 48 void do_per_trap(struct pt_regs *regs); 28 49 void syscall_trace(struct pt_regs *regs, int entryexit);
+25 -11
arch/s390/kernel/entry64.S
··· 80 80 #endif 81 81 .endm 82 82 83 - .macro HANDLE_SIE_INTERCEPT scratch 83 + .macro HANDLE_SIE_INTERCEPT scratch,pgmcheck 84 84 #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) 85 85 tmhh %r8,0x0001 # interrupting from user ? 86 86 jnz .+42 87 87 lgr \scratch,%r9 88 88 slg \scratch,BASED(.Lsie_loop) 89 89 clg \scratch,BASED(.Lsie_length) 90 + .if \pgmcheck 91 + # Some program interrupts are suppressing (e.g. protection). 92 + # We must also check the instruction after SIE in that case. 93 + # do_protection_exception will rewind to rewind_pad 94 + jh .+22 95 + .else 90 96 jhe .+22 97 + .endif 91 98 lg %r9,BASED(.Lsie_loop) 92 99 SPP BASED(.Lhost_id) # set host id 93 100 #endif ··· 269 262 jo sysc_mcck_pending 270 263 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED 271 264 jo sysc_reschedule 265 + tm __TI_flags+7(%r12),_TIF_PER_TRAP 266 + jo sysc_singlestep 272 267 tm __TI_flags+7(%r12),_TIF_SIGPENDING 273 268 jo sysc_sigpending 274 269 tm __TI_flags+7(%r12),_TIF_NOTIFY_RESUME 275 270 jo sysc_notify_resume 276 - tm __TI_flags+7(%r12),_TIF_PER_TRAP 277 - jo sysc_singlestep 278 271 j sysc_return # beware of critical section cleanup 279 272 280 273 # ··· 295 288 # _TIF_SIGPENDING is set, call do_signal 296 289 # 297 290 sysc_sigpending: 298 - ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP 299 291 lgr %r2,%r11 # pass pointer to pt_regs 300 292 brasl %r14,do_signal 301 293 tm __TI_flags+7(%r12),_TIF_SYSCALL ··· 319 313 # _TIF_PER_TRAP is set, call do_per_trap 320 314 # 321 315 sysc_singlestep: 322 - ni __TI_flags+7(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP) 316 + ni __TI_flags+7(%r12),255-_TIF_PER_TRAP 323 317 lgr %r2,%r11 # pass pointer to pt_regs 324 318 larl %r14,sysc_return 325 319 jg do_per_trap ··· 381 375 lg %r12,__LC_THREAD_INFO 382 376 larl %r13,system_call 383 377 lmg %r8,%r9,__LC_PGM_OLD_PSW 384 - HANDLE_SIE_INTERCEPT %r14 378 + HANDLE_SIE_INTERCEPT %r14,1 385 379 tmhh %r8,0x0001 # test problem state bit 386 380 jnz 1f # -> fault in user space 387 381 tmhh %r8,0x4000 # PER bit set in old PSW ? ··· 419 413 larl %r1,pgm_check_table 420 414 llgh %r10,__PT_INT_CODE+2(%r11) 421 415 nill %r10,0x007f 422 - sll %r10,3 416 + sll %r10,2 423 417 je sysc_return 424 - lg %r1,0(%r10,%r1) # load address of handler routine 418 + lgf %r1,0(%r10,%r1) # load address of handler routine 425 419 lgr %r2,%r11 # pass pointer to pt_regs 426 420 basr %r14,%r1 # branch to interrupt-handler 427 421 j sysc_return ··· 457 451 lg %r12,__LC_THREAD_INFO 458 452 larl %r13,system_call 459 453 lmg %r8,%r9,__LC_IO_OLD_PSW 460 - HANDLE_SIE_INTERCEPT %r14 454 + HANDLE_SIE_INTERCEPT %r14,0 461 455 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT 462 456 tmhh %r8,0x0001 # interrupting from user? 463 457 jz io_skip ··· 603 597 lg %r12,__LC_THREAD_INFO 604 598 larl %r13,system_call 605 599 lmg %r8,%r9,__LC_EXT_OLD_PSW 606 - HANDLE_SIE_INTERCEPT %r14 600 + HANDLE_SIE_INTERCEPT %r14,0 607 601 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT 608 602 tmhh %r8,0x0001 # interrupting from user ? 609 603 jz ext_skip ··· 651 645 lg %r12,__LC_THREAD_INFO 652 646 larl %r13,system_call 653 647 lmg %r8,%r9,__LC_MCK_OLD_PSW 654 - HANDLE_SIE_INTERCEPT %r14 648 + HANDLE_SIE_INTERCEPT %r14,0 655 649 tm __LC_MCCK_CODE,0x80 # system damage? 656 650 jo mcck_panic # yes -> rest of mcck code invalid 657 651 lghi %r14,__LC_CPU_TIMER_SAVE_AREA ··· 950 944 stg %r3,__SF_EMPTY+8(%r15) # save guest register save area 951 945 xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # host id == 0 952 946 lmg %r0,%r13,0(%r3) # load guest gprs 0-13 947 + # some program checks are suppressing. C code (e.g. do_protection_exception) 948 + # will rewind the PSW by the ILC, which is 4 bytes in case of SIE. Other 949 + # instructions in the sie_loop should not cause program interrupts. So 950 + # lets use a nop (47 00 00 00) as a landing pad. 951 + # See also HANDLE_SIE_INTERCEPT 952 + rewind_pad: 953 + nop 0 953 954 sie_loop: 954 955 lg %r14,__LC_THREAD_INFO # pointer thread_info struct 955 956 tm __TI_flags+7(%r14),_TIF_EXIT_SIE ··· 996 983 .Lhost_id: 997 984 .quad 0 998 985 986 + EX_TABLE(rewind_pad,sie_fault) 999 987 EX_TABLE(sie_loop,sie_fault) 1000 988 #endif 1001 989
+44 -30
arch/s390/kernel/head.S
··· 393 393 xc 0x300(256),0x300 394 394 xc 0xe00(256),0xe00 395 395 stck __LC_LAST_UPDATE_CLOCK 396 - spt 5f-.LPG0(%r13) 397 - mvc __LC_LAST_UPDATE_TIMER(8),5f-.LPG0(%r13) 396 + spt 6f-.LPG0(%r13) 397 + mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13) 398 398 xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST 399 399 #ifndef CONFIG_MARCH_G5 400 400 # check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10} 401 401 .insn s,0xb2b10000,__LC_STFL_FAC_LIST # store facility list 402 402 tm __LC_STFL_FAC_LIST,0x01 # stfle available ? 403 403 jz 0f 404 - la %r0,0 404 + la %r0,1 405 405 .insn s,0xb2b00000,__LC_STFL_FAC_LIST # store facility list extended 406 - 0: l %r0,__LC_STFL_FAC_LIST 407 - n %r0,2f+8-.LPG0(%r13) 408 - cl %r0,2f+8-.LPG0(%r13) 409 - jne 1f 410 - l %r0,__LC_STFL_FAC_LIST+4 411 - n %r0,2f+12-.LPG0(%r13) 412 - cl %r0,2f+12-.LPG0(%r13) 413 - je 3f 414 - 1: l %r15,.Lstack-.LPG0(%r13) 406 + # verify if all required facilities are supported by the machine 407 + 0: la %r1,__LC_STFL_FAC_LIST 408 + la %r2,3f+8-.LPG0(%r13) 409 + l %r3,0(%r2) 410 + 1: l %r0,0(%r1) 411 + n %r0,4(%r2) 412 + cl %r0,4(%r2) 413 + jne 2f 414 + la %r1,4(%r1) 415 + la %r2,4(%r2) 416 + ahi %r3,-1 417 + jnz 1b 418 + j 4f 419 + 2: l %r15,.Lstack-.LPG0(%r13) 415 420 ahi %r15,-96 416 421 la %r2,.Lals_string-.LPG0(%r13) 417 422 l %r3,.Lsclp_print-.LPG0(%r13) 418 423 basr %r14,%r3 419 - lpsw 2f-.LPG0(%r13) # machine type not good enough, crash 424 + lpsw 3f-.LPG0(%r13) # machine type not good enough, crash 420 425 .Lals_string: 421 426 .asciz "The Linux kernel requires more recent processor hardware" 422 427 .Lsclp_print: ··· 429 424 .Lstack: 430 425 .long 0x8000 + (1<<(PAGE_SHIFT+THREAD_ORDER)) 431 426 .align 16 432 - 2: .long 0x000a0000,0x8badcccc 427 + 3: .long 0x000a0000,0x8badcccc 428 + 429 + # List of facilities that are required. If not all facilities are present 430 + # the kernel will crash. Format is number of facility words with bits set, 431 + # followed by the facility words. 432 + 433 433 #if defined(CONFIG_64BIT) 434 - #if defined(CONFIG_MARCH_Z196) 435 - .long 0xc100efe3, 0xf46c0000 434 + #if defined(CONFIG_MARCH_ZEC12) 435 + .long 3, 0xc100efe3, 0xf46ce000, 0x00400000 436 + #elif defined(CONFIG_MARCH_Z196) 437 + .long 2, 0xc100efe3, 0xf46c0000 436 438 #elif defined(CONFIG_MARCH_Z10) 437 - .long 0xc100efe3, 0xf0680000 439 + .long 2, 0xc100efe3, 0xf0680000 438 440 #elif defined(CONFIG_MARCH_Z9_109) 439 - .long 0xc100efc3, 0x00000000 441 + .long 1, 0xc100efc3 440 442 #elif defined(CONFIG_MARCH_Z990) 441 - .long 0xc0002000, 0x00000000 443 + .long 1, 0xc0002000 442 444 #elif defined(CONFIG_MARCH_Z900) 443 - .long 0xc0000000, 0x00000000 445 + .long 1, 0xc0000000 444 446 #endif 445 447 #else 446 - #if defined(CONFIG_MARCH_Z196) 447 - .long 0x8100c880, 0x00000000 448 + #if defined(CONFIG_MARCH_ZEC12) 449 + .long 1, 0x8100c880 450 + #elif defined(CONFIG_MARCH_Z196) 451 + .long 1, 0x8100c880 448 452 #elif defined(CONFIG_MARCH_Z10) 449 - .long 0x8100c880, 0x00000000 453 + .long 1, 0x8100c880 450 454 #elif defined(CONFIG_MARCH_Z9_109) 451 - .long 0x8100c880, 0x00000000 455 + .long 1, 0x8100c880 452 456 #elif defined(CONFIG_MARCH_Z990) 453 - .long 0x80002000, 0x00000000 457 + .long 1, 0x80002000 454 458 #elif defined(CONFIG_MARCH_Z900) 455 - .long 0x80000000, 0x00000000 459 + .long 1, 0x80000000 456 460 #endif 457 461 #endif 458 - 3: 462 + 4: 459 463 #endif 460 464 461 465 #ifdef CONFIG_64BIT ··· 473 459 jg startup_continue 474 460 #else 475 461 /* Continue with 31bit startup code in head31.S */ 476 - l %r13,4f-.LPG0(%r13) 462 + l %r13,5f-.LPG0(%r13) 477 463 b 0(%r13) 478 464 .align 8 479 - 4: .long startup_continue 465 + 5: .long startup_continue 480 466 #endif 481 467 482 468 .align 8 483 - 5: .long 0x7fffffff,0xffffffff 469 + 6: .long 0x7fffffff,0xffffffff 484 470 485 471 #include "head_kdump.S" 486 472
+2
arch/s390/kernel/irq.c
··· 58 58 [IOINT_APB] = {.name = "APB", .desc = "[I/O] AP Bus"}, 59 59 [IOINT_ADM] = {.name = "ADM", .desc = "[I/O] EADM Subchannel"}, 60 60 [IOINT_CSC] = {.name = "CSC", .desc = "[I/O] CHSC Subchannel"}, 61 + [IOINT_PCI] = {.name = "PCI", .desc = "[I/O] PCI Interrupt" }, 62 + [IOINT_MSI] = {.name = "MSI", .desc = "[I/O] MSI Interrupt" }, 61 63 [NMI_NMI] = {.name = "NMI", .desc = "[NMI] Machine Check"}, 62 64 }; 63 65
+152
arch/s390/kernel/pgm_check.S
··· 1 + /* 2 + * Program check table. 3 + * 4 + * Copyright IBM Corp. 2012 5 + */ 6 + 7 + #include <linux/linkage.h> 8 + 9 + #ifdef CONFIG_32BIT 10 + #define PGM_CHECK_64BIT(handler) .long default_trap_handler 11 + #else 12 + #define PGM_CHECK_64BIT(handler) .long handler 13 + #endif 14 + 15 + #define PGM_CHECK(handler) .long handler 16 + #define PGM_CHECK_DEFAULT PGM_CHECK(default_trap_handler) 17 + 18 + /* 19 + * The program check table contains exactly 128 (0x00-0x7f) entries. Each 20 + * line defines the 31 and/or 64 bit function to be called corresponding 21 + * to the program check interruption code. 22 + */ 23 + .section .rodata, "a" 24 + ENTRY(pgm_check_table) 25 + PGM_CHECK_DEFAULT /* 00 */ 26 + PGM_CHECK(illegal_op) /* 01 */ 27 + PGM_CHECK(privileged_op) /* 02 */ 28 + PGM_CHECK(execute_exception) /* 03 */ 29 + PGM_CHECK(do_protection_exception) /* 04 */ 30 + PGM_CHECK(addressing_exception) /* 05 */ 31 + PGM_CHECK(specification_exception) /* 06 */ 32 + PGM_CHECK(data_exception) /* 07 */ 33 + PGM_CHECK(overflow_exception) /* 08 */ 34 + PGM_CHECK(divide_exception) /* 09 */ 35 + PGM_CHECK(overflow_exception) /* 0a */ 36 + PGM_CHECK(divide_exception) /* 0b */ 37 + PGM_CHECK(hfp_overflow_exception) /* 0c */ 38 + PGM_CHECK(hfp_underflow_exception) /* 0d */ 39 + PGM_CHECK(hfp_significance_exception) /* 0e */ 40 + PGM_CHECK(hfp_divide_exception) /* 0f */ 41 + PGM_CHECK(do_dat_exception) /* 10 */ 42 + PGM_CHECK(do_dat_exception) /* 11 */ 43 + PGM_CHECK(translation_exception) /* 12 */ 44 + PGM_CHECK(special_op_exception) /* 13 */ 45 + PGM_CHECK_DEFAULT /* 14 */ 46 + PGM_CHECK(operand_exception) /* 15 */ 47 + PGM_CHECK_DEFAULT /* 16 */ 48 + PGM_CHECK_DEFAULT /* 17 */ 49 + PGM_CHECK_64BIT(transaction_exception) /* 18 */ 50 + PGM_CHECK_DEFAULT /* 19 */ 51 + PGM_CHECK_DEFAULT /* 1a */ 52 + PGM_CHECK_DEFAULT /* 1b */ 53 + PGM_CHECK(space_switch_exception) /* 1c */ 54 + PGM_CHECK(hfp_sqrt_exception) /* 1d */ 55 + PGM_CHECK_DEFAULT /* 1e */ 56 + PGM_CHECK_DEFAULT /* 1f */ 57 + PGM_CHECK_DEFAULT /* 20 */ 58 + PGM_CHECK_DEFAULT /* 21 */ 59 + PGM_CHECK_DEFAULT /* 22 */ 60 + PGM_CHECK_DEFAULT /* 23 */ 61 + PGM_CHECK_DEFAULT /* 24 */ 62 + PGM_CHECK_DEFAULT /* 25 */ 63 + PGM_CHECK_DEFAULT /* 26 */ 64 + PGM_CHECK_DEFAULT /* 27 */ 65 + PGM_CHECK_DEFAULT /* 28 */ 66 + PGM_CHECK_DEFAULT /* 29 */ 67 + PGM_CHECK_DEFAULT /* 2a */ 68 + PGM_CHECK_DEFAULT /* 2b */ 69 + PGM_CHECK_DEFAULT /* 2c */ 70 + PGM_CHECK_DEFAULT /* 2d */ 71 + PGM_CHECK_DEFAULT /* 2e */ 72 + PGM_CHECK_DEFAULT /* 2f */ 73 + PGM_CHECK_DEFAULT /* 30 */ 74 + PGM_CHECK_DEFAULT /* 31 */ 75 + PGM_CHECK_DEFAULT /* 32 */ 76 + PGM_CHECK_DEFAULT /* 33 */ 77 + PGM_CHECK_DEFAULT /* 34 */ 78 + PGM_CHECK_DEFAULT /* 35 */ 79 + PGM_CHECK_DEFAULT /* 36 */ 80 + PGM_CHECK_DEFAULT /* 37 */ 81 + PGM_CHECK_64BIT(do_asce_exception) /* 38 */ 82 + PGM_CHECK_64BIT(do_dat_exception) /* 39 */ 83 + PGM_CHECK_64BIT(do_dat_exception) /* 3a */ 84 + PGM_CHECK_64BIT(do_dat_exception) /* 3b */ 85 + PGM_CHECK_DEFAULT /* 3c */ 86 + PGM_CHECK_DEFAULT /* 3d */ 87 + PGM_CHECK_DEFAULT /* 3e */ 88 + PGM_CHECK_DEFAULT /* 3f */ 89 + PGM_CHECK_DEFAULT /* 40 */ 90 + PGM_CHECK_DEFAULT /* 41 */ 91 + PGM_CHECK_DEFAULT /* 42 */ 92 + PGM_CHECK_DEFAULT /* 43 */ 93 + PGM_CHECK_DEFAULT /* 44 */ 94 + PGM_CHECK_DEFAULT /* 45 */ 95 + PGM_CHECK_DEFAULT /* 46 */ 96 + PGM_CHECK_DEFAULT /* 47 */ 97 + PGM_CHECK_DEFAULT /* 48 */ 98 + PGM_CHECK_DEFAULT /* 49 */ 99 + PGM_CHECK_DEFAULT /* 4a */ 100 + PGM_CHECK_DEFAULT /* 4b */ 101 + PGM_CHECK_DEFAULT /* 4c */ 102 + PGM_CHECK_DEFAULT /* 4d */ 103 + PGM_CHECK_DEFAULT /* 4e */ 104 + PGM_CHECK_DEFAULT /* 4f */ 105 + PGM_CHECK_DEFAULT /* 50 */ 106 + PGM_CHECK_DEFAULT /* 51 */ 107 + PGM_CHECK_DEFAULT /* 52 */ 108 + PGM_CHECK_DEFAULT /* 53 */ 109 + PGM_CHECK_DEFAULT /* 54 */ 110 + PGM_CHECK_DEFAULT /* 55 */ 111 + PGM_CHECK_DEFAULT /* 56 */ 112 + PGM_CHECK_DEFAULT /* 57 */ 113 + PGM_CHECK_DEFAULT /* 58 */ 114 + PGM_CHECK_DEFAULT /* 59 */ 115 + PGM_CHECK_DEFAULT /* 5a */ 116 + PGM_CHECK_DEFAULT /* 5b */ 117 + PGM_CHECK_DEFAULT /* 5c */ 118 + PGM_CHECK_DEFAULT /* 5d */ 119 + PGM_CHECK_DEFAULT /* 5e */ 120 + PGM_CHECK_DEFAULT /* 5f */ 121 + PGM_CHECK_DEFAULT /* 60 */ 122 + PGM_CHECK_DEFAULT /* 61 */ 123 + PGM_CHECK_DEFAULT /* 62 */ 124 + PGM_CHECK_DEFAULT /* 63 */ 125 + PGM_CHECK_DEFAULT /* 64 */ 126 + PGM_CHECK_DEFAULT /* 65 */ 127 + PGM_CHECK_DEFAULT /* 66 */ 128 + PGM_CHECK_DEFAULT /* 67 */ 129 + PGM_CHECK_DEFAULT /* 68 */ 130 + PGM_CHECK_DEFAULT /* 69 */ 131 + PGM_CHECK_DEFAULT /* 6a */ 132 + PGM_CHECK_DEFAULT /* 6b */ 133 + PGM_CHECK_DEFAULT /* 6c */ 134 + PGM_CHECK_DEFAULT /* 6d */ 135 + PGM_CHECK_DEFAULT /* 6e */ 136 + PGM_CHECK_DEFAULT /* 6f */ 137 + PGM_CHECK_DEFAULT /* 70 */ 138 + PGM_CHECK_DEFAULT /* 71 */ 139 + PGM_CHECK_DEFAULT /* 72 */ 140 + PGM_CHECK_DEFAULT /* 73 */ 141 + PGM_CHECK_DEFAULT /* 74 */ 142 + PGM_CHECK_DEFAULT /* 75 */ 143 + PGM_CHECK_DEFAULT /* 76 */ 144 + PGM_CHECK_DEFAULT /* 77 */ 145 + PGM_CHECK_DEFAULT /* 78 */ 146 + PGM_CHECK_DEFAULT /* 79 */ 147 + PGM_CHECK_DEFAULT /* 7a */ 148 + PGM_CHECK_DEFAULT /* 7b */ 149 + PGM_CHECK_DEFAULT /* 7c */ 150 + PGM_CHECK_DEFAULT /* 7d */ 151 + PGM_CHECK_DEFAULT /* 7e */ 152 + PGM_CHECK_DEFAULT /* 7f */
+4 -35
arch/s390/kernel/setup.c
··· 777 777 #endif 778 778 } 779 779 780 - static void __init init_storage_keys(unsigned long start, unsigned long end) 781 - { 782 - unsigned long boundary, function, size; 783 - 784 - while (start < end) { 785 - if (MACHINE_HAS_EDAT2) { 786 - /* set storage keys for a 2GB frame */ 787 - function = 0x22000 | PAGE_DEFAULT_KEY; 788 - size = 1UL << 31; 789 - boundary = (start + size) & ~(size - 1); 790 - if (boundary <= end) { 791 - do { 792 - start = pfmf(function, start); 793 - } while (start < boundary); 794 - continue; 795 - } 796 - } 797 - if (MACHINE_HAS_EDAT1) { 798 - /* set storage keys for a 1MB frame */ 799 - function = 0x21000 | PAGE_DEFAULT_KEY; 800 - size = 1UL << 20; 801 - boundary = (start + size) & ~(size - 1); 802 - if (boundary <= end) { 803 - do { 804 - start = pfmf(function, start); 805 - } while (start < boundary); 806 - continue; 807 - } 808 - } 809 - page_set_storage_key(start, PAGE_DEFAULT_KEY, 0); 810 - start += PAGE_SIZE; 811 - } 812 - } 813 - 814 780 static void __init setup_memory(void) 815 781 { 816 782 unsigned long bootmap_size; ··· 855 889 memblock_add_node(PFN_PHYS(start_chunk), 856 890 PFN_PHYS(end_chunk - start_chunk), 0); 857 891 pfn = max(start_chunk, start_pfn); 858 - init_storage_keys(PFN_PHYS(pfn), PFN_PHYS(end_chunk)); 892 + storage_key_init_range(PFN_PHYS(pfn), PFN_PHYS(end_chunk)); 859 893 } 860 894 861 895 psw_set_key(PAGE_DEFAULT_KEY); ··· 1005 1039 case 0x2817: 1006 1040 case 0x2818: 1007 1041 strcpy(elf_platform, "z196"); 1042 + break; 1043 + case 0x2827: 1044 + strcpy(elf_platform, "zEC12"); 1008 1045 break; 1009 1046 } 1010 1047 }
+2
arch/s390/kernel/signal.c
··· 461 461 /* Restart system call with magic TIF bit. */ 462 462 regs->gprs[2] = regs->orig_gpr2; 463 463 set_thread_flag(TIF_SYSCALL); 464 + if (test_thread_flag(TIF_SINGLE_STEP)) 465 + set_thread_flag(TIF_PER_TRAP); 464 466 break; 465 467 } 466 468 }
+54 -59
arch/s390/kernel/topology.c
··· 29 29 cpumask_t mask; 30 30 }; 31 31 32 - static int topology_enabled = 1; 32 + static void set_topology_timer(void); 33 33 static void topology_work_fn(struct work_struct *work); 34 34 static struct sysinfo_15_1_x *tl_info; 35 - static void set_topology_timer(void); 35 + 36 + static int topology_enabled = 1; 36 37 static DECLARE_WORK(topology_work, topology_work_fn); 37 - /* topology_lock protects the core linked list */ 38 + 39 + /* topology_lock protects the socket and book linked lists */ 38 40 static DEFINE_SPINLOCK(topology_lock); 39 - 40 - static struct mask_info core_info; 41 - cpumask_t cpu_core_map[NR_CPUS]; 42 - unsigned char cpu_core_id[NR_CPUS]; 43 - unsigned char cpu_socket_id[NR_CPUS]; 44 - 41 + static struct mask_info socket_info; 45 42 static struct mask_info book_info; 46 - cpumask_t cpu_book_map[NR_CPUS]; 47 - unsigned char cpu_book_id[NR_CPUS]; 43 + 44 + struct cpu_topology_s390 cpu_topology[NR_CPUS]; 48 45 49 46 static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu) 50 47 { 51 48 cpumask_t mask; 52 49 53 - cpumask_clear(&mask); 54 - if (!topology_enabled || !MACHINE_HAS_TOPOLOGY) { 55 - cpumask_copy(&mask, cpumask_of(cpu)); 50 + cpumask_copy(&mask, cpumask_of(cpu)); 51 + if (!topology_enabled || !MACHINE_HAS_TOPOLOGY) 56 52 return mask; 53 + for (; info; info = info->next) { 54 + if (cpumask_test_cpu(cpu, &info->mask)) 55 + return info->mask; 57 56 } 58 - while (info) { 59 - if (cpumask_test_cpu(cpu, &info->mask)) { 60 - mask = info->mask; 61 - break; 62 - } 63 - info = info->next; 64 - } 65 - if (cpumask_empty(&mask)) 66 - cpumask_copy(&mask, cpumask_of(cpu)); 67 57 return mask; 68 58 } 69 59 70 60 static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu, 71 61 struct mask_info *book, 72 - struct mask_info *core, 73 - int one_core_per_cpu) 62 + struct mask_info *socket, 63 + int one_socket_per_cpu) 74 64 { 75 65 unsigned int cpu; 76 66 ··· 70 80 71 81 rcpu = TOPOLOGY_CPU_BITS - 1 - cpu + tl_cpu->origin; 72 82 lcpu = smp_find_processor_id(rcpu); 73 - if (lcpu >= 0) { 74 - cpumask_set_cpu(lcpu, &book->mask); 75 - cpu_book_id[lcpu] = book->id; 76 - cpumask_set_cpu(lcpu, &core->mask); 77 - cpu_core_id[lcpu] = rcpu; 78 - if (one_core_per_cpu) { 79 - cpu_socket_id[lcpu] = rcpu; 80 - core = core->next; 81 - } else { 82 - cpu_socket_id[lcpu] = core->id; 83 - } 84 - smp_cpu_set_polarization(lcpu, tl_cpu->pp); 83 + if (lcpu < 0) 84 + continue; 85 + cpumask_set_cpu(lcpu, &book->mask); 86 + cpu_topology[lcpu].book_id = book->id; 87 + cpumask_set_cpu(lcpu, &socket->mask); 88 + cpu_topology[lcpu].core_id = rcpu; 89 + if (one_socket_per_cpu) { 90 + cpu_topology[lcpu].socket_id = rcpu; 91 + socket = socket->next; 92 + } else { 93 + cpu_topology[lcpu].socket_id = socket->id; 85 94 } 95 + smp_cpu_set_polarization(lcpu, tl_cpu->pp); 86 96 } 87 - return core; 97 + return socket; 88 98 } 89 99 90 100 static void clear_masks(void) 91 101 { 92 102 struct mask_info *info; 93 103 94 - info = &core_info; 104 + info = &socket_info; 95 105 while (info) { 96 106 cpumask_clear(&info->mask); 97 107 info = info->next; ··· 110 120 return (union topology_entry *)((struct topology_container *)tle + 1); 111 121 } 112 122 113 - static void __tl_to_cores_generic(struct sysinfo_15_1_x *info) 123 + static void __tl_to_masks_generic(struct sysinfo_15_1_x *info) 114 124 { 115 - struct mask_info *core = &core_info; 125 + struct mask_info *socket = &socket_info; 116 126 struct mask_info *book = &book_info; 117 127 union topology_entry *tle, *end; 118 128 ··· 125 135 book->id = tle->container.id; 126 136 break; 127 137 case 1: 128 - core = core->next; 129 - core->id = tle->container.id; 138 + socket = socket->next; 139 + socket->id = tle->container.id; 130 140 break; 131 141 case 0: 132 - add_cpus_to_mask(&tle->cpu, book, core, 0); 142 + add_cpus_to_mask(&tle->cpu, book, socket, 0); 133 143 break; 134 144 default: 135 145 clear_masks(); ··· 139 149 } 140 150 } 141 151 142 - static void __tl_to_cores_z10(struct sysinfo_15_1_x *info) 152 + static void __tl_to_masks_z10(struct sysinfo_15_1_x *info) 143 153 { 144 - struct mask_info *core = &core_info; 154 + struct mask_info *socket = &socket_info; 145 155 struct mask_info *book = &book_info; 146 156 union topology_entry *tle, *end; 147 157 ··· 154 164 book->id = tle->container.id; 155 165 break; 156 166 case 0: 157 - core = add_cpus_to_mask(&tle->cpu, book, core, 1); 167 + socket = add_cpus_to_mask(&tle->cpu, book, socket, 1); 158 168 break; 159 169 default: 160 170 clear_masks(); ··· 164 174 } 165 175 } 166 176 167 - static void tl_to_cores(struct sysinfo_15_1_x *info) 177 + static void tl_to_masks(struct sysinfo_15_1_x *info) 168 178 { 169 179 struct cpuid cpu_id; 170 180 171 - get_cpu_id(&cpu_id); 172 181 spin_lock_irq(&topology_lock); 182 + get_cpu_id(&cpu_id); 173 183 clear_masks(); 174 184 switch (cpu_id.machine) { 175 185 case 0x2097: 176 186 case 0x2098: 177 - __tl_to_cores_z10(info); 187 + __tl_to_masks_z10(info); 178 188 break; 179 189 default: 180 - __tl_to_cores_generic(info); 190 + __tl_to_masks_generic(info); 181 191 } 182 192 spin_unlock_irq(&topology_lock); 183 193 } ··· 222 232 return rc; 223 233 } 224 234 225 - static void update_cpu_core_map(void) 235 + static void update_cpu_masks(void) 226 236 { 227 237 unsigned long flags; 228 238 int cpu; 229 239 230 240 spin_lock_irqsave(&topology_lock, flags); 231 241 for_each_possible_cpu(cpu) { 232 - cpu_core_map[cpu] = cpu_group_map(&core_info, cpu); 233 - cpu_book_map[cpu] = cpu_group_map(&book_info, cpu); 242 + cpu_topology[cpu].core_mask = cpu_group_map(&socket_info, cpu); 243 + cpu_topology[cpu].book_mask = cpu_group_map(&book_info, cpu); 244 + if (!MACHINE_HAS_TOPOLOGY) { 245 + cpu_topology[cpu].core_id = cpu; 246 + cpu_topology[cpu].socket_id = cpu; 247 + cpu_topology[cpu].book_id = cpu; 248 + } 234 249 } 235 250 spin_unlock_irqrestore(&topology_lock, flags); 236 251 } ··· 255 260 int cpu; 256 261 257 262 if (!MACHINE_HAS_TOPOLOGY) { 258 - update_cpu_core_map(); 263 + update_cpu_masks(); 259 264 topology_update_polarization_simple(); 260 265 return 0; 261 266 } 262 267 store_topology(info); 263 - tl_to_cores(info); 264 - update_cpu_core_map(); 268 + tl_to_masks(info); 269 + update_cpu_masks(); 265 270 for_each_online_cpu(cpu) { 266 271 dev = get_cpu_device(cpu); 267 272 kobject_uevent(&dev->kobj, KOBJ_CHANGE); ··· 350 355 for (i = 0; i < TOPOLOGY_NR_MAG; i++) 351 356 printk(KERN_CONT " %d", info->mag[i]); 352 357 printk(KERN_CONT " / %d\n", info->mnest); 353 - alloc_masks(info, &core_info, 1); 358 + alloc_masks(info, &socket_info, 1); 354 359 alloc_masks(info, &book_info, 2); 355 360 } 356 361 ··· 449 454 } 450 455 set_topology_timer(); 451 456 out: 452 - update_cpu_core_map(); 457 + update_cpu_masks(); 453 458 return device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching); 454 459 } 455 460 device_initcall(topology_init);
+7 -45
arch/s390/kernel/traps.c
··· 41 41 #include <asm/ipl.h> 42 42 #include "entry.h" 43 43 44 - void (*pgm_check_table[128])(struct pt_regs *regs); 45 - 46 44 int show_unhandled_signals = 1; 47 45 48 46 #define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; }) ··· 348 350 force_sig_info(SIGTRAP, &info, current); 349 351 } 350 352 351 - static void default_trap_handler(struct pt_regs *regs) 353 + void default_trap_handler(struct pt_regs *regs) 352 354 { 353 355 if (user_mode(regs)) { 354 356 report_user_fault(regs, SIGSEGV); ··· 358 360 } 359 361 360 362 #define DO_ERROR_INFO(name, signr, sicode, str) \ 361 - static void name(struct pt_regs *regs) \ 362 - { \ 363 - do_trap(regs, signr, sicode, str); \ 363 + void name(struct pt_regs *regs) \ 364 + { \ 365 + do_trap(regs, signr, sicode, str); \ 364 366 } 365 367 366 368 DO_ERROR_INFO(addressing_exception, SIGILL, ILL_ILLADR, ··· 415 417 do_trap(regs, SIGFPE, si_code, "floating point exception"); 416 418 } 417 419 418 - static void __kprobes illegal_op(struct pt_regs *regs) 420 + void __kprobes illegal_op(struct pt_regs *regs) 419 421 { 420 422 siginfo_t info; 421 423 __u8 opcode[6]; ··· 534 536 "specification exception"); 535 537 #endif 536 538 537 - static void data_exception(struct pt_regs *regs) 539 + void data_exception(struct pt_regs *regs) 538 540 { 539 541 __u16 __user *location; 540 542 int signal = 0; ··· 609 611 do_trap(regs, signal, ILL_ILLOPN, "data exception"); 610 612 } 611 613 612 - static void space_switch_exception(struct pt_regs *regs) 614 + void space_switch_exception(struct pt_regs *regs) 613 615 { 614 616 /* Set user psw back to home space mode. */ 615 617 if (user_mode(regs)) ··· 627 629 panic("Corrupt kernel stack, can't continue."); 628 630 } 629 631 630 - /* init is done in lowcore.S and head.S */ 631 - 632 632 void __init trap_init(void) 633 633 { 634 - int i; 635 - 636 - for (i = 0; i < 128; i++) 637 - pgm_check_table[i] = &default_trap_handler; 638 - pgm_check_table[1] = &illegal_op; 639 - pgm_check_table[2] = &privileged_op; 640 - pgm_check_table[3] = &execute_exception; 641 - pgm_check_table[4] = &do_protection_exception; 642 - pgm_check_table[5] = &addressing_exception; 643 - pgm_check_table[6] = &specification_exception; 644 - pgm_check_table[7] = &data_exception; 645 - pgm_check_table[8] = &overflow_exception; 646 - pgm_check_table[9] = &divide_exception; 647 - pgm_check_table[0x0A] = &overflow_exception; 648 - pgm_check_table[0x0B] = &divide_exception; 649 - pgm_check_table[0x0C] = &hfp_overflow_exception; 650 - pgm_check_table[0x0D] = &hfp_underflow_exception; 651 - pgm_check_table[0x0E] = &hfp_significance_exception; 652 - pgm_check_table[0x0F] = &hfp_divide_exception; 653 - pgm_check_table[0x10] = &do_dat_exception; 654 - pgm_check_table[0x11] = &do_dat_exception; 655 - pgm_check_table[0x12] = &translation_exception; 656 - pgm_check_table[0x13] = &special_op_exception; 657 - #ifdef CONFIG_64BIT 658 - pgm_check_table[0x18] = &transaction_exception; 659 - pgm_check_table[0x38] = &do_asce_exception; 660 - pgm_check_table[0x39] = &do_dat_exception; 661 - pgm_check_table[0x3A] = &do_dat_exception; 662 - pgm_check_table[0x3B] = &do_dat_exception; 663 - #endif /* CONFIG_64BIT */ 664 - pgm_check_table[0x15] = &operand_exception; 665 - pgm_check_table[0x1C] = &space_switch_exception; 666 - pgm_check_table[0x1D] = &hfp_sqrt_exception; 667 - /* Enable machine checks early. */ 668 634 local_mcck_enable(); 669 635 }
+6 -6
arch/s390/mm/Makefile
··· 2 2 # Makefile for the linux s390-specific parts of the memory manager. 3 3 # 4 4 5 - obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o \ 6 - page-states.o gup.o extable.o 7 - obj-$(CONFIG_CMM) += cmm.o 8 - obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 9 - obj-$(CONFIG_DEBUG_SET_MODULE_RONX) += pageattr.o 10 - obj-$(CONFIG_S390_PTDUMP) += dump_pagetables.o 5 + obj-y := init.o fault.o extmem.o mmap.o vmem.o pgtable.o maccess.o 6 + obj-y += page-states.o gup.o extable.o pageattr.o 7 + 8 + obj-$(CONFIG_CMM) += cmm.o 9 + obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o 10 + obj-$(CONFIG_S390_PTDUMP) += dump_pagetables.o
+6 -1
arch/s390/mm/dump_pagetables.c
··· 150 150 static void walk_pud_level(struct seq_file *m, struct pg_state *st, 151 151 pgd_t *pgd, unsigned long addr) 152 152 { 153 + unsigned int prot; 153 154 pud_t *pud; 154 155 int i; 155 156 ··· 158 157 st->current_address = addr; 159 158 pud = pud_offset(pgd, addr); 160 159 if (!pud_none(*pud)) 161 - walk_pmd_level(m, st, pud, addr); 160 + if (pud_large(*pud)) { 161 + prot = pud_val(*pud) & _PAGE_RO; 162 + note_page(m, st, prot, 2); 163 + } else 164 + walk_pmd_level(m, st, pud, addr); 162 165 else 163 166 note_page(m, st, _PAGE_INVALID, 2); 164 167 addr += PUD_SIZE;
+21 -10
arch/s390/mm/fault.c
··· 49 49 #define VM_FAULT_BADCONTEXT 0x010000 50 50 #define VM_FAULT_BADMAP 0x020000 51 51 #define VM_FAULT_BADACCESS 0x040000 52 - #define VM_FAULT_SIGNAL 0x080000 52 + #define VM_FAULT_SIGNAL 0x080000 53 53 54 - static unsigned long store_indication; 54 + static unsigned long store_indication __read_mostly; 55 55 56 - void fault_init(void) 56 + #ifdef CONFIG_64BIT 57 + static int __init fault_init(void) 57 58 { 58 - if (test_facility(2) && test_facility(75)) 59 + if (test_facility(75)) 59 60 store_indication = 0xc00; 61 + return 0; 60 62 } 63 + early_initcall(fault_init); 64 + #endif 61 65 62 66 static inline int notify_page_fault(struct pt_regs *regs) 63 67 { ··· 277 273 unsigned int flags; 278 274 int fault; 279 275 276 + tsk = current; 277 + /* 278 + * The instruction that caused the program check has 279 + * been nullified. Don't signal single step via SIGTRAP. 280 + */ 281 + clear_tsk_thread_flag(tsk, TIF_PER_TRAP); 282 + 280 283 if (notify_page_fault(regs)) 281 284 return 0; 282 285 283 - tsk = current; 284 286 mm = tsk->mm; 285 287 trans_exc_code = regs->int_parm_long; 286 288 ··· 382 372 goto retry; 383 373 } 384 374 } 385 - /* 386 - * The instruction that caused the program check will 387 - * be repeated. Don't signal single step via SIGTRAP. 388 - */ 389 - clear_tsk_thread_flag(tsk, TIF_PER_TRAP); 390 375 fault = 0; 391 376 out_up: 392 377 up_read(&mm->mmap_sem); ··· 427 422 struct mm_struct *mm = current->mm; 428 423 struct vm_area_struct *vma; 429 424 unsigned long trans_exc_code; 425 + 426 + /* 427 + * The instruction that caused the program check has 428 + * been nullified. Don't signal single step via SIGTRAP. 429 + */ 430 + clear_tsk_thread_flag(current, TIF_PER_TRAP); 430 431 431 432 trans_exc_code = regs->int_parm_long; 432 433 if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm))
-29
arch/s390/mm/init.c
··· 125 125 max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS); 126 126 max_zone_pfns[ZONE_NORMAL] = max_low_pfn; 127 127 free_area_init_nodes(max_zone_pfns); 128 - fault_init(); 129 128 } 130 129 131 130 void __init mem_init(void) ··· 157 158 (unsigned long)&_stext, 158 159 PFN_ALIGN((unsigned long)&_eshared) - 1); 159 160 } 160 - 161 - #ifdef CONFIG_DEBUG_PAGEALLOC 162 - void kernel_map_pages(struct page *page, int numpages, int enable) 163 - { 164 - pgd_t *pgd; 165 - pud_t *pud; 166 - pmd_t *pmd; 167 - pte_t *pte; 168 - unsigned long address; 169 - int i; 170 - 171 - for (i = 0; i < numpages; i++) { 172 - address = page_to_phys(page + i); 173 - pgd = pgd_offset_k(address); 174 - pud = pud_offset(pgd, address); 175 - pmd = pmd_offset(pud, address); 176 - pte = pte_offset_kernel(pmd, address); 177 - if (!enable) { 178 - __ptep_ipte(address, pte); 179 - pte_val(*pte) = _PAGE_TYPE_EMPTY; 180 - continue; 181 - } 182 - *pte = mk_pte_phys(address, __pgprot(_PAGE_TYPE_RW)); 183 - /* Flush cpu write queue. */ 184 - mb(); 185 - } 186 - } 187 - #endif 188 161 189 162 void free_init_pages(char *what, unsigned long begin, unsigned long end) 190 163 {
+80 -2
arch/s390/mm/pageattr.c
··· 2 2 * Copyright IBM Corp. 2011 3 3 * Author(s): Jan Glauber <jang@linux.vnet.ibm.com> 4 4 */ 5 + #include <linux/hugetlb.h> 5 6 #include <linux/module.h> 6 7 #include <linux/mm.h> 7 - #include <linux/hugetlb.h> 8 8 #include <asm/cacheflush.h> 9 9 #include <asm/pgtable.h> 10 + #include <asm/page.h> 11 + 12 + void storage_key_init_range(unsigned long start, unsigned long end) 13 + { 14 + unsigned long boundary, function, size; 15 + 16 + while (start < end) { 17 + if (MACHINE_HAS_EDAT2) { 18 + /* set storage keys for a 2GB frame */ 19 + function = 0x22000 | PAGE_DEFAULT_KEY; 20 + size = 1UL << 31; 21 + boundary = (start + size) & ~(size - 1); 22 + if (boundary <= end) { 23 + do { 24 + start = pfmf(function, start); 25 + } while (start < boundary); 26 + continue; 27 + } 28 + } 29 + if (MACHINE_HAS_EDAT1) { 30 + /* set storage keys for a 1MB frame */ 31 + function = 0x21000 | PAGE_DEFAULT_KEY; 32 + size = 1UL << 20; 33 + boundary = (start + size) & ~(size - 1); 34 + if (boundary <= end) { 35 + do { 36 + start = pfmf(function, start); 37 + } while (start < boundary); 38 + continue; 39 + } 40 + } 41 + page_set_storage_key(start, PAGE_DEFAULT_KEY, 0); 42 + start += PAGE_SIZE; 43 + } 44 + } 10 45 11 46 static pte_t *walk_page_table(unsigned long addr) 12 47 { ··· 54 19 if (pgd_none(*pgdp)) 55 20 return NULL; 56 21 pudp = pud_offset(pgdp, addr); 57 - if (pud_none(*pudp)) 22 + if (pud_none(*pudp) || pud_large(*pudp)) 58 23 return NULL; 59 24 pmdp = pmd_offset(pudp, addr); 60 25 if (pmd_none(*pmdp) || pmd_large(*pmdp)) ··· 105 70 { 106 71 return 0; 107 72 } 73 + 74 + #ifdef CONFIG_DEBUG_PAGEALLOC 75 + void kernel_map_pages(struct page *page, int numpages, int enable) 76 + { 77 + unsigned long address; 78 + pgd_t *pgd; 79 + pud_t *pud; 80 + pmd_t *pmd; 81 + pte_t *pte; 82 + int i; 83 + 84 + for (i = 0; i < numpages; i++) { 85 + address = page_to_phys(page + i); 86 + pgd = pgd_offset_k(address); 87 + pud = pud_offset(pgd, address); 88 + pmd = pmd_offset(pud, address); 89 + pte = pte_offset_kernel(pmd, address); 90 + if (!enable) { 91 + __ptep_ipte(address, pte); 92 + pte_val(*pte) = _PAGE_TYPE_EMPTY; 93 + continue; 94 + } 95 + *pte = mk_pte_phys(address, __pgprot(_PAGE_TYPE_RW)); 96 + } 97 + } 98 + 99 + #ifdef CONFIG_HIBERNATION 100 + bool kernel_page_present(struct page *page) 101 + { 102 + unsigned long addr; 103 + int cc; 104 + 105 + addr = page_to_phys(page); 106 + asm volatile( 107 + " lra %1,0(%1)\n" 108 + " ipm %0\n" 109 + " srl %0,28" 110 + : "=d" (cc), "+a" (addr) : : "cc"); 111 + return cc == 0; 112 + } 113 + #endif /* CONFIG_HIBERNATION */ 114 + 115 + #endif /* CONFIG_DEBUG_PAGEALLOC */
-16
arch/s390/mm/pgtable.c
··· 881 881 } 882 882 EXPORT_SYMBOL_GPL(s390_enable_sie); 883 883 884 - #if defined(CONFIG_DEBUG_PAGEALLOC) && defined(CONFIG_HIBERNATION) 885 - bool kernel_page_present(struct page *page) 886 - { 887 - unsigned long addr; 888 - int cc; 889 - 890 - addr = page_to_phys(page); 891 - asm volatile( 892 - " lra %1,0(%1)\n" 893 - " ipm %0\n" 894 - " srl %0,28" 895 - : "=d" (cc), "+a" (addr) : : "cc"); 896 - return cc == 0; 897 - } 898 - #endif /* CONFIG_HIBERNATION && CONFIG_DEBUG_PAGEALLOC */ 899 - 900 884 #ifdef CONFIG_TRANSPARENT_HUGEPAGE 901 885 int pmdp_clear_flush_young(struct vm_area_struct *vma, unsigned long address, 902 886 pmd_t *pmdp)
+41 -5
arch/s390/mm/vmem.c
··· 89 89 int ret = -ENOMEM; 90 90 91 91 while (address < end) { 92 + pte = mk_pte_phys(address, __pgprot(ro ? _PAGE_RO : 0)); 92 93 pg_dir = pgd_offset_k(address); 93 94 if (pgd_none(*pg_dir)) { 94 95 pu_dir = vmem_pud_alloc(); ··· 97 96 goto out; 98 97 pgd_populate(&init_mm, pg_dir, pu_dir); 99 98 } 100 - 101 99 pu_dir = pud_offset(pg_dir, address); 100 + #if defined(CONFIG_64BIT) && !defined(CONFIG_DEBUG_PAGEALLOC) 101 + if (MACHINE_HAS_EDAT2 && pud_none(*pu_dir) && address && 102 + !(address & ~PUD_MASK) && (address + PUD_SIZE <= end)) { 103 + pte_val(pte) |= _REGION3_ENTRY_LARGE; 104 + pte_val(pte) |= _REGION_ENTRY_TYPE_R3; 105 + pud_val(*pu_dir) = pte_val(pte); 106 + address += PUD_SIZE; 107 + continue; 108 + } 109 + #endif 102 110 if (pud_none(*pu_dir)) { 103 111 pm_dir = vmem_pmd_alloc(); 104 112 if (!pm_dir) 105 113 goto out; 106 114 pud_populate(&init_mm, pu_dir, pm_dir); 107 115 } 108 - 109 - pte = mk_pte_phys(address, __pgprot(ro ? _PAGE_RO : 0)); 110 116 pm_dir = pmd_offset(pu_dir, address); 111 - 112 117 #if defined(CONFIG_64BIT) && !defined(CONFIG_DEBUG_PAGEALLOC) 113 118 if (MACHINE_HAS_EDAT1 && pmd_none(*pm_dir) && address && 114 119 !(address & ~PMD_MASK) && (address + PMD_SIZE <= end)) { ··· 167 160 address += PUD_SIZE; 168 161 continue; 169 162 } 163 + if (pud_large(*pu_dir)) { 164 + pud_clear(pu_dir); 165 + address += PUD_SIZE; 166 + continue; 167 + } 170 168 pm_dir = pmd_offset(pu_dir, address); 171 169 if (pmd_none(*pm_dir)) { 172 170 address += PMD_SIZE; ··· 205 193 start_addr = (unsigned long) start; 206 194 end_addr = (unsigned long) (start + nr); 207 195 208 - for (address = start_addr; address < end_addr; address += PAGE_SIZE) { 196 + for (address = start_addr; address < end_addr;) { 209 197 pg_dir = pgd_offset_k(address); 210 198 if (pgd_none(*pg_dir)) { 211 199 pu_dir = vmem_pud_alloc(); ··· 224 212 225 213 pm_dir = pmd_offset(pu_dir, address); 226 214 if (pmd_none(*pm_dir)) { 215 + #ifdef CONFIG_64BIT 216 + /* Use 1MB frames for vmemmap if available. We always 217 + * use large frames even if they are only partially 218 + * used. 219 + * Otherwise we would have also page tables since 220 + * vmemmap_populate gets called for each section 221 + * separately. */ 222 + if (MACHINE_HAS_EDAT1) { 223 + void *new_page; 224 + 225 + new_page = vmemmap_alloc_block(PMD_SIZE, node); 226 + if (!new_page) 227 + goto out; 228 + pte = mk_pte_phys(__pa(new_page), PAGE_RW); 229 + pte_val(pte) |= _SEGMENT_ENTRY_LARGE; 230 + pmd_val(*pm_dir) = pte_val(pte); 231 + address = (address + PMD_SIZE) & PMD_MASK; 232 + continue; 233 + } 234 + #endif 227 235 pt_dir = vmem_pte_alloc(address); 228 236 if (!pt_dir) 229 237 goto out; 230 238 pmd_populate(&init_mm, pm_dir, pt_dir); 239 + } else if (pmd_large(*pm_dir)) { 240 + address = (address + PMD_SIZE) & PMD_MASK; 241 + continue; 231 242 } 232 243 233 244 pt_dir = pte_offset_kernel(pm_dir, address); ··· 263 228 pte = pfn_pte(new_page >> PAGE_SHIFT, PAGE_KERNEL); 264 229 *pt_dir = pte; 265 230 } 231 + address += PAGE_SIZE; 266 232 } 267 233 memset(start, 0, nr * sizeof(struct page)); 268 234 ret = 0;
+28
arch/s390/net/bpf_jit_comp.c
··· 341 341 /* lr %r5,%r4 */ 342 342 EMIT2(0x1854); 343 343 break; 344 + case BPF_S_ALU_MOD_X: /* A %= X */ 345 + jit->seen |= SEEN_XREG | SEEN_RET0; 346 + /* ltr %r12,%r12 */ 347 + EMIT2(0x12cc); 348 + /* jz <ret0> */ 349 + EMIT4_PCREL(0xa7840000, (jit->ret0_ip - jit->prg)); 350 + /* lhi %r4,0 */ 351 + EMIT4(0xa7480000); 352 + /* dr %r4,%r12 */ 353 + EMIT2(0x1d4c); 354 + /* lr %r5,%r4 */ 355 + EMIT2(0x1854); 356 + break; 357 + case BPF_S_ALU_MOD_K: /* A %= K */ 358 + /* lhi %r4,0 */ 359 + EMIT4(0xa7480000); 360 + /* d %r4,<d(K)>(%r13) */ 361 + EMIT4_DISP(0x5d40d000, EMIT_CONST(K)); 362 + /* lr %r5,%r4 */ 363 + EMIT2(0x1854); 364 + break; 344 365 case BPF_S_ALU_AND_X: /* A &= X */ 345 366 jit->seen |= SEEN_XREG; 346 367 /* nr %r5,%r12 */ ··· 389 368 EMIT4_DISP(0x5650d000, EMIT_CONST(K)); 390 369 break; 391 370 case BPF_S_ANC_ALU_XOR_X: /* A ^= X; */ 371 + case BPF_S_ALU_XOR_X: 392 372 jit->seen |= SEEN_XREG; 393 373 /* xr %r5,%r12 */ 394 374 EMIT2(0x175c); 375 + break; 376 + case BPF_S_ALU_XOR_K: /* A ^= K */ 377 + if (!K) 378 + break; 379 + /* x %r5,<d(K)>(%r13) */ 380 + EMIT4_DISP(0x5750d000, EMIT_CONST(K)); 395 381 break; 396 382 case BPF_S_ALU_LSH_X: /* A <<= X; */ 397 383 jit->seen |= SEEN_XREG;
+6
arch/s390/pci/Makefile
··· 1 + # 2 + # Makefile for the s390 PCI subsystem. 3 + # 4 + 5 + obj-$(CONFIG_PCI) += pci.o pci_dma.o pci_clp.o pci_msi.o \ 6 + pci_sysfs.o pci_event.o
+1103
arch/s390/pci/pci.c
··· 1 + /* 2 + * Copyright IBM Corp. 2012 3 + * 4 + * Author(s): 5 + * Jan Glauber <jang@linux.vnet.ibm.com> 6 + * 7 + * The System z PCI code is a rewrite from a prototype by 8 + * the following people (Kudoz!): 9 + * Alexander Schmidt 10 + * Christoph Raisch 11 + * Hannes Hering 12 + * Hoang-Nam Nguyen 13 + * Jan-Bernd Themann 14 + * Stefan Roscher 15 + * Thomas Klein 16 + */ 17 + 18 + #define COMPONENT "zPCI" 19 + #define pr_fmt(fmt) COMPONENT ": " fmt 20 + 21 + #include <linux/kernel.h> 22 + #include <linux/slab.h> 23 + #include <linux/err.h> 24 + #include <linux/export.h> 25 + #include <linux/delay.h> 26 + #include <linux/irq.h> 27 + #include <linux/kernel_stat.h> 28 + #include <linux/seq_file.h> 29 + #include <linux/pci.h> 30 + #include <linux/msi.h> 31 + 32 + #include <asm/isc.h> 33 + #include <asm/airq.h> 34 + #include <asm/facility.h> 35 + #include <asm/pci_insn.h> 36 + #include <asm/pci_clp.h> 37 + #include <asm/pci_dma.h> 38 + 39 + #define DEBUG /* enable pr_debug */ 40 + 41 + #define SIC_IRQ_MODE_ALL 0 42 + #define SIC_IRQ_MODE_SINGLE 1 43 + 44 + #define ZPCI_NR_DMA_SPACES 1 45 + #define ZPCI_MSI_VEC_BITS 6 46 + #define ZPCI_NR_DEVICES CONFIG_PCI_NR_FUNCTIONS 47 + 48 + /* list of all detected zpci devices */ 49 + LIST_HEAD(zpci_list); 50 + EXPORT_SYMBOL_GPL(zpci_list); 51 + DEFINE_MUTEX(zpci_list_lock); 52 + EXPORT_SYMBOL_GPL(zpci_list_lock); 53 + 54 + struct pci_hp_callback_ops hotplug_ops; 55 + EXPORT_SYMBOL_GPL(hotplug_ops); 56 + 57 + static DECLARE_BITMAP(zpci_domain, ZPCI_NR_DEVICES); 58 + static DEFINE_SPINLOCK(zpci_domain_lock); 59 + 60 + struct callback { 61 + irq_handler_t handler; 62 + void *data; 63 + }; 64 + 65 + struct zdev_irq_map { 66 + unsigned long aibv; /* AI bit vector */ 67 + int msi_vecs; /* consecutive MSI-vectors used */ 68 + int __unused; 69 + struct callback cb[ZPCI_NR_MSI_VECS]; /* callback handler array */ 70 + spinlock_t lock; /* protect callbacks against de-reg */ 71 + }; 72 + 73 + struct intr_bucket { 74 + /* amap of adapters, one bit per dev, corresponds to one irq nr */ 75 + unsigned long *alloc; 76 + /* AI summary bit, global page for all devices */ 77 + unsigned long *aisb; 78 + /* pointer to aibv and callback data in zdev */ 79 + struct zdev_irq_map *imap[ZPCI_NR_DEVICES]; 80 + /* protects the whole bucket struct */ 81 + spinlock_t lock; 82 + }; 83 + 84 + static struct intr_bucket *bucket; 85 + 86 + /* Adapter local summary indicator */ 87 + static u8 *zpci_irq_si; 88 + 89 + static atomic_t irq_retries = ATOMIC_INIT(0); 90 + 91 + /* I/O Map */ 92 + static DEFINE_SPINLOCK(zpci_iomap_lock); 93 + static DECLARE_BITMAP(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES); 94 + struct zpci_iomap_entry *zpci_iomap_start; 95 + EXPORT_SYMBOL_GPL(zpci_iomap_start); 96 + 97 + /* highest irq summary bit */ 98 + static int __read_mostly aisb_max; 99 + 100 + static struct kmem_cache *zdev_irq_cache; 101 + 102 + static inline int irq_to_msi_nr(unsigned int irq) 103 + { 104 + return irq & ZPCI_MSI_MASK; 105 + } 106 + 107 + static inline int irq_to_dev_nr(unsigned int irq) 108 + { 109 + return irq >> ZPCI_MSI_VEC_BITS; 110 + } 111 + 112 + static inline struct zdev_irq_map *get_imap(unsigned int irq) 113 + { 114 + return bucket->imap[irq_to_dev_nr(irq)]; 115 + } 116 + 117 + struct zpci_dev *get_zdev(struct pci_dev *pdev) 118 + { 119 + return (struct zpci_dev *) pdev->sysdata; 120 + } 121 + 122 + struct zpci_dev *get_zdev_by_fid(u32 fid) 123 + { 124 + struct zpci_dev *tmp, *zdev = NULL; 125 + 126 + mutex_lock(&zpci_list_lock); 127 + list_for_each_entry(tmp, &zpci_list, entry) { 128 + if (tmp->fid == fid) { 129 + zdev = tmp; 130 + break; 131 + } 132 + } 133 + mutex_unlock(&zpci_list_lock); 134 + return zdev; 135 + } 136 + 137 + bool zpci_fid_present(u32 fid) 138 + { 139 + return (get_zdev_by_fid(fid) != NULL) ? true : false; 140 + } 141 + 142 + static struct zpci_dev *get_zdev_by_bus(struct pci_bus *bus) 143 + { 144 + return (bus && bus->sysdata) ? (struct zpci_dev *) bus->sysdata : NULL; 145 + } 146 + 147 + int pci_domain_nr(struct pci_bus *bus) 148 + { 149 + return ((struct zpci_dev *) bus->sysdata)->domain; 150 + } 151 + EXPORT_SYMBOL_GPL(pci_domain_nr); 152 + 153 + int pci_proc_domain(struct pci_bus *bus) 154 + { 155 + return pci_domain_nr(bus); 156 + } 157 + EXPORT_SYMBOL_GPL(pci_proc_domain); 158 + 159 + /* Store PCI function information block */ 160 + static int zpci_store_fib(struct zpci_dev *zdev, u8 *fc) 161 + { 162 + struct zpci_fib *fib; 163 + u8 status, cc; 164 + 165 + fib = (void *) get_zeroed_page(GFP_KERNEL); 166 + if (!fib) 167 + return -ENOMEM; 168 + 169 + do { 170 + cc = __stpcifc(zdev->fh, 0, fib, &status); 171 + if (cc == 2) { 172 + msleep(ZPCI_INSN_BUSY_DELAY); 173 + memset(fib, 0, PAGE_SIZE); 174 + } 175 + } while (cc == 2); 176 + 177 + if (cc) 178 + pr_err_once("%s: cc: %u status: %u\n", 179 + __func__, cc, status); 180 + 181 + /* Return PCI function controls */ 182 + *fc = fib->fc; 183 + 184 + free_page((unsigned long) fib); 185 + return (cc) ? -EIO : 0; 186 + } 187 + 188 + /* Modify PCI: Register adapter interruptions */ 189 + static int zpci_register_airq(struct zpci_dev *zdev, unsigned int aisb, 190 + u64 aibv) 191 + { 192 + u64 req = ZPCI_CREATE_REQ(zdev->fh, 0, ZPCI_MOD_FC_REG_INT); 193 + struct zpci_fib *fib; 194 + int rc; 195 + 196 + fib = (void *) get_zeroed_page(GFP_KERNEL); 197 + if (!fib) 198 + return -ENOMEM; 199 + 200 + fib->isc = PCI_ISC; 201 + fib->noi = zdev->irq_map->msi_vecs; 202 + fib->sum = 1; /* enable summary notifications */ 203 + fib->aibv = aibv; 204 + fib->aibvo = 0; /* every function has its own page */ 205 + fib->aisb = (u64) bucket->aisb + aisb / 8; 206 + fib->aisbo = aisb & ZPCI_MSI_MASK; 207 + 208 + rc = mpcifc_instr(req, fib); 209 + pr_debug("%s mpcifc returned noi: %d\n", __func__, fib->noi); 210 + 211 + free_page((unsigned long) fib); 212 + return rc; 213 + } 214 + 215 + struct mod_pci_args { 216 + u64 base; 217 + u64 limit; 218 + u64 iota; 219 + }; 220 + 221 + static int mod_pci(struct zpci_dev *zdev, int fn, u8 dmaas, struct mod_pci_args *args) 222 + { 223 + u64 req = ZPCI_CREATE_REQ(zdev->fh, dmaas, fn); 224 + struct zpci_fib *fib; 225 + int rc; 226 + 227 + /* The FIB must be available even if it's not used */ 228 + fib = (void *) get_zeroed_page(GFP_KERNEL); 229 + if (!fib) 230 + return -ENOMEM; 231 + 232 + fib->pba = args->base; 233 + fib->pal = args->limit; 234 + fib->iota = args->iota; 235 + 236 + rc = mpcifc_instr(req, fib); 237 + free_page((unsigned long) fib); 238 + return rc; 239 + } 240 + 241 + /* Modify PCI: Register I/O address translation parameters */ 242 + int zpci_register_ioat(struct zpci_dev *zdev, u8 dmaas, 243 + u64 base, u64 limit, u64 iota) 244 + { 245 + struct mod_pci_args args = { base, limit, iota }; 246 + 247 + WARN_ON_ONCE(iota & 0x3fff); 248 + args.iota |= ZPCI_IOTA_RTTO_FLAG; 249 + return mod_pci(zdev, ZPCI_MOD_FC_REG_IOAT, dmaas, &args); 250 + } 251 + 252 + /* Modify PCI: Unregister I/O address translation parameters */ 253 + int zpci_unregister_ioat(struct zpci_dev *zdev, u8 dmaas) 254 + { 255 + struct mod_pci_args args = { 0, 0, 0 }; 256 + 257 + return mod_pci(zdev, ZPCI_MOD_FC_DEREG_IOAT, dmaas, &args); 258 + } 259 + 260 + /* Modify PCI: Unregister adapter interruptions */ 261 + static int zpci_unregister_airq(struct zpci_dev *zdev) 262 + { 263 + struct mod_pci_args args = { 0, 0, 0 }; 264 + 265 + return mod_pci(zdev, ZPCI_MOD_FC_DEREG_INT, 0, &args); 266 + } 267 + 268 + #define ZPCI_PCIAS_CFGSPC 15 269 + 270 + static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len) 271 + { 272 + u64 req = ZPCI_CREATE_REQ(zdev->fh, ZPCI_PCIAS_CFGSPC, len); 273 + u64 data; 274 + int rc; 275 + 276 + rc = pcilg_instr(&data, req, offset); 277 + data = data << ((8 - len) * 8); 278 + data = le64_to_cpu(data); 279 + if (!rc) 280 + *val = (u32) data; 281 + else 282 + *val = 0xffffffff; 283 + return rc; 284 + } 285 + 286 + static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len) 287 + { 288 + u64 req = ZPCI_CREATE_REQ(zdev->fh, ZPCI_PCIAS_CFGSPC, len); 289 + u64 data = val; 290 + int rc; 291 + 292 + data = cpu_to_le64(data); 293 + data = data >> ((8 - len) * 8); 294 + rc = pcistg_instr(data, req, offset); 295 + return rc; 296 + } 297 + 298 + void synchronize_irq(unsigned int irq) 299 + { 300 + /* 301 + * Not needed, the handler is protected by a lock and IRQs that occur 302 + * after the handler is deleted are just NOPs. 303 + */ 304 + } 305 + EXPORT_SYMBOL_GPL(synchronize_irq); 306 + 307 + void enable_irq(unsigned int irq) 308 + { 309 + struct msi_desc *msi = irq_get_msi_desc(irq); 310 + 311 + zpci_msi_set_mask_bits(msi, 1, 0); 312 + } 313 + EXPORT_SYMBOL_GPL(enable_irq); 314 + 315 + void disable_irq(unsigned int irq) 316 + { 317 + struct msi_desc *msi = irq_get_msi_desc(irq); 318 + 319 + zpci_msi_set_mask_bits(msi, 1, 1); 320 + } 321 + EXPORT_SYMBOL_GPL(disable_irq); 322 + 323 + void disable_irq_nosync(unsigned int irq) 324 + { 325 + disable_irq(irq); 326 + } 327 + EXPORT_SYMBOL_GPL(disable_irq_nosync); 328 + 329 + unsigned long probe_irq_on(void) 330 + { 331 + return 0; 332 + } 333 + EXPORT_SYMBOL_GPL(probe_irq_on); 334 + 335 + int probe_irq_off(unsigned long val) 336 + { 337 + return 0; 338 + } 339 + EXPORT_SYMBOL_GPL(probe_irq_off); 340 + 341 + unsigned int probe_irq_mask(unsigned long val) 342 + { 343 + return val; 344 + } 345 + EXPORT_SYMBOL_GPL(probe_irq_mask); 346 + 347 + void __devinit pcibios_fixup_bus(struct pci_bus *bus) 348 + { 349 + } 350 + 351 + resource_size_t pcibios_align_resource(void *data, const struct resource *res, 352 + resource_size_t size, 353 + resource_size_t align) 354 + { 355 + return 0; 356 + } 357 + 358 + /* combine single writes by using store-block insn */ 359 + void __iowrite64_copy(void __iomem *to, const void *from, size_t count) 360 + { 361 + zpci_memcpy_toio(to, from, count); 362 + } 363 + 364 + /* Create a virtual mapping cookie for a PCI BAR */ 365 + void __iomem *pci_iomap(struct pci_dev *pdev, int bar, unsigned long max) 366 + { 367 + struct zpci_dev *zdev = get_zdev(pdev); 368 + u64 addr; 369 + int idx; 370 + 371 + if ((bar & 7) != bar) 372 + return NULL; 373 + 374 + idx = zdev->bars[bar].map_idx; 375 + spin_lock(&zpci_iomap_lock); 376 + zpci_iomap_start[idx].fh = zdev->fh; 377 + zpci_iomap_start[idx].bar = bar; 378 + spin_unlock(&zpci_iomap_lock); 379 + 380 + addr = ZPCI_IOMAP_ADDR_BASE | ((u64) idx << 48); 381 + return (void __iomem *) addr; 382 + } 383 + EXPORT_SYMBOL_GPL(pci_iomap); 384 + 385 + void pci_iounmap(struct pci_dev *pdev, void __iomem *addr) 386 + { 387 + unsigned int idx; 388 + 389 + idx = (((__force u64) addr) & ~ZPCI_IOMAP_ADDR_BASE) >> 48; 390 + spin_lock(&zpci_iomap_lock); 391 + zpci_iomap_start[idx].fh = 0; 392 + zpci_iomap_start[idx].bar = 0; 393 + spin_unlock(&zpci_iomap_lock); 394 + } 395 + EXPORT_SYMBOL_GPL(pci_iounmap); 396 + 397 + static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, 398 + int size, u32 *val) 399 + { 400 + struct zpci_dev *zdev = get_zdev_by_bus(bus); 401 + 402 + if (!zdev || devfn != ZPCI_DEVFN) 403 + return 0; 404 + return zpci_cfg_load(zdev, where, val, size); 405 + } 406 + 407 + static int pci_write(struct pci_bus *bus, unsigned int devfn, int where, 408 + int size, u32 val) 409 + { 410 + struct zpci_dev *zdev = get_zdev_by_bus(bus); 411 + 412 + if (!zdev || devfn != ZPCI_DEVFN) 413 + return 0; 414 + return zpci_cfg_store(zdev, where, val, size); 415 + } 416 + 417 + static struct pci_ops pci_root_ops = { 418 + .read = pci_read, 419 + .write = pci_write, 420 + }; 421 + 422 + /* store the last handled bit to implement fair scheduling of devices */ 423 + static DEFINE_PER_CPU(unsigned long, next_sbit); 424 + 425 + static void zpci_irq_handler(void *dont, void *need) 426 + { 427 + unsigned long sbit, mbit, last = 0, start = __get_cpu_var(next_sbit); 428 + int rescan = 0, max = aisb_max; 429 + struct zdev_irq_map *imap; 430 + 431 + kstat_cpu(smp_processor_id()).irqs[IOINT_PCI]++; 432 + sbit = start; 433 + 434 + scan: 435 + /* find summary_bit */ 436 + for_each_set_bit_left_cont(sbit, bucket->aisb, max) { 437 + clear_bit(63 - (sbit & 63), bucket->aisb + (sbit >> 6)); 438 + last = sbit; 439 + 440 + /* find vector bit */ 441 + imap = bucket->imap[sbit]; 442 + for_each_set_bit_left(mbit, &imap->aibv, imap->msi_vecs) { 443 + kstat_cpu(smp_processor_id()).irqs[IOINT_MSI]++; 444 + clear_bit(63 - mbit, &imap->aibv); 445 + 446 + spin_lock(&imap->lock); 447 + if (imap->cb[mbit].handler) 448 + imap->cb[mbit].handler(mbit, 449 + imap->cb[mbit].data); 450 + spin_unlock(&imap->lock); 451 + } 452 + } 453 + 454 + if (rescan) 455 + goto out; 456 + 457 + /* scan the skipped bits */ 458 + if (start > 0) { 459 + sbit = 0; 460 + max = start; 461 + start = 0; 462 + goto scan; 463 + } 464 + 465 + /* enable interrupts again */ 466 + sic_instr(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); 467 + 468 + /* check again to not lose initiative */ 469 + rmb(); 470 + max = aisb_max; 471 + sbit = find_first_bit_left(bucket->aisb, max); 472 + if (sbit != max) { 473 + atomic_inc(&irq_retries); 474 + rescan++; 475 + goto scan; 476 + } 477 + out: 478 + /* store next device bit to scan */ 479 + __get_cpu_var(next_sbit) = (++last >= aisb_max) ? 0 : last; 480 + } 481 + 482 + /* msi_vecs - number of requested interrupts, 0 place function to error state */ 483 + static int zpci_setup_msi(struct pci_dev *pdev, int msi_vecs) 484 + { 485 + struct zpci_dev *zdev = get_zdev(pdev); 486 + unsigned int aisb, msi_nr; 487 + struct msi_desc *msi; 488 + int rc; 489 + 490 + /* store the number of used MSI vectors */ 491 + zdev->irq_map->msi_vecs = min(msi_vecs, ZPCI_NR_MSI_VECS); 492 + 493 + spin_lock(&bucket->lock); 494 + aisb = find_first_zero_bit(bucket->alloc, PAGE_SIZE); 495 + /* alloc map exhausted? */ 496 + if (aisb == PAGE_SIZE) { 497 + spin_unlock(&bucket->lock); 498 + return -EIO; 499 + } 500 + set_bit(aisb, bucket->alloc); 501 + spin_unlock(&bucket->lock); 502 + 503 + zdev->aisb = aisb; 504 + if (aisb + 1 > aisb_max) 505 + aisb_max = aisb + 1; 506 + 507 + /* wire up IRQ shortcut pointer */ 508 + bucket->imap[zdev->aisb] = zdev->irq_map; 509 + pr_debug("%s: imap[%u] linked to %p\n", __func__, zdev->aisb, zdev->irq_map); 510 + 511 + /* TODO: irq number 0 wont be found if we return less than requested MSIs. 512 + * ignore it for now and fix in common code. 513 + */ 514 + msi_nr = aisb << ZPCI_MSI_VEC_BITS; 515 + 516 + list_for_each_entry(msi, &pdev->msi_list, list) { 517 + rc = zpci_setup_msi_irq(zdev, msi, msi_nr, 518 + aisb << ZPCI_MSI_VEC_BITS); 519 + if (rc) 520 + return rc; 521 + msi_nr++; 522 + } 523 + 524 + rc = zpci_register_airq(zdev, aisb, (u64) &zdev->irq_map->aibv); 525 + if (rc) { 526 + clear_bit(aisb, bucket->alloc); 527 + dev_err(&pdev->dev, "register MSI failed with: %d\n", rc); 528 + return rc; 529 + } 530 + return (zdev->irq_map->msi_vecs == msi_vecs) ? 531 + 0 : zdev->irq_map->msi_vecs; 532 + } 533 + 534 + static void zpci_teardown_msi(struct pci_dev *pdev) 535 + { 536 + struct zpci_dev *zdev = get_zdev(pdev); 537 + struct msi_desc *msi; 538 + int aisb, rc; 539 + 540 + rc = zpci_unregister_airq(zdev); 541 + if (rc) { 542 + dev_err(&pdev->dev, "deregister MSI failed with: %d\n", rc); 543 + return; 544 + } 545 + 546 + msi = list_first_entry(&pdev->msi_list, struct msi_desc, list); 547 + aisb = irq_to_dev_nr(msi->irq); 548 + 549 + list_for_each_entry(msi, &pdev->msi_list, list) 550 + zpci_teardown_msi_irq(zdev, msi); 551 + 552 + clear_bit(aisb, bucket->alloc); 553 + if (aisb + 1 == aisb_max) 554 + aisb_max--; 555 + } 556 + 557 + int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) 558 + { 559 + pr_debug("%s: requesting %d MSI-X interrupts...", __func__, nvec); 560 + if (type != PCI_CAP_ID_MSIX && type != PCI_CAP_ID_MSI) 561 + return -EINVAL; 562 + return zpci_setup_msi(pdev, nvec); 563 + } 564 + 565 + void arch_teardown_msi_irqs(struct pci_dev *pdev) 566 + { 567 + pr_info("%s: on pdev: %p\n", __func__, pdev); 568 + zpci_teardown_msi(pdev); 569 + } 570 + 571 + static void zpci_map_resources(struct zpci_dev *zdev) 572 + { 573 + struct pci_dev *pdev = zdev->pdev; 574 + resource_size_t len; 575 + int i; 576 + 577 + for (i = 0; i < PCI_BAR_COUNT; i++) { 578 + len = pci_resource_len(pdev, i); 579 + if (!len) 580 + continue; 581 + pdev->resource[i].start = (resource_size_t) pci_iomap(pdev, i, 0); 582 + pdev->resource[i].end = pdev->resource[i].start + len - 1; 583 + pr_debug("BAR%i: -> start: %Lx end: %Lx\n", 584 + i, pdev->resource[i].start, pdev->resource[i].end); 585 + } 586 + }; 587 + 588 + static void zpci_unmap_resources(struct pci_dev *pdev) 589 + { 590 + resource_size_t len; 591 + int i; 592 + 593 + for (i = 0; i < PCI_BAR_COUNT; i++) { 594 + len = pci_resource_len(pdev, i); 595 + if (!len) 596 + continue; 597 + pci_iounmap(pdev, (void *) pdev->resource[i].start); 598 + } 599 + }; 600 + 601 + struct zpci_dev *zpci_alloc_device(void) 602 + { 603 + struct zpci_dev *zdev; 604 + 605 + /* Alloc memory for our private pci device data */ 606 + zdev = kzalloc(sizeof(*zdev), GFP_KERNEL); 607 + if (!zdev) 608 + return ERR_PTR(-ENOMEM); 609 + 610 + /* Alloc aibv & callback space */ 611 + zdev->irq_map = kmem_cache_zalloc(zdev_irq_cache, GFP_KERNEL); 612 + if (!zdev->irq_map) 613 + goto error; 614 + WARN_ON((u64) zdev->irq_map & 0xff); 615 + return zdev; 616 + 617 + error: 618 + kfree(zdev); 619 + return ERR_PTR(-ENOMEM); 620 + } 621 + 622 + void zpci_free_device(struct zpci_dev *zdev) 623 + { 624 + kmem_cache_free(zdev_irq_cache, zdev->irq_map); 625 + kfree(zdev); 626 + } 627 + 628 + /* Called on removal of pci_dev, leaves zpci and bus device */ 629 + static void zpci_remove_device(struct pci_dev *pdev) 630 + { 631 + struct zpci_dev *zdev = get_zdev(pdev); 632 + 633 + dev_info(&pdev->dev, "Removing device %u\n", zdev->domain); 634 + zdev->state = ZPCI_FN_STATE_CONFIGURED; 635 + zpci_dma_exit_device(zdev); 636 + zpci_sysfs_remove_device(&pdev->dev); 637 + zpci_unmap_resources(pdev); 638 + list_del(&zdev->entry); /* can be called from init */ 639 + zdev->pdev = NULL; 640 + } 641 + 642 + static void zpci_scan_devices(void) 643 + { 644 + struct zpci_dev *zdev; 645 + 646 + mutex_lock(&zpci_list_lock); 647 + list_for_each_entry(zdev, &zpci_list, entry) 648 + if (zdev->state == ZPCI_FN_STATE_CONFIGURED) 649 + zpci_scan_device(zdev); 650 + mutex_unlock(&zpci_list_lock); 651 + } 652 + 653 + /* 654 + * Too late for any s390 specific setup, since interrupts must be set up 655 + * already which requires DMA setup too and the pci scan will access the 656 + * config space, which only works if the function handle is enabled. 657 + */ 658 + int pcibios_enable_device(struct pci_dev *pdev, int mask) 659 + { 660 + struct resource *res; 661 + u16 cmd; 662 + int i; 663 + 664 + pci_read_config_word(pdev, PCI_COMMAND, &cmd); 665 + 666 + for (i = 0; i < PCI_BAR_COUNT; i++) { 667 + res = &pdev->resource[i]; 668 + 669 + if (res->flags & IORESOURCE_IO) 670 + return -EINVAL; 671 + 672 + if (res->flags & IORESOURCE_MEM) 673 + cmd |= PCI_COMMAND_MEMORY; 674 + } 675 + pci_write_config_word(pdev, PCI_COMMAND, cmd); 676 + return 0; 677 + } 678 + 679 + void pcibios_disable_device(struct pci_dev *pdev) 680 + { 681 + zpci_remove_device(pdev); 682 + pdev->sysdata = NULL; 683 + } 684 + 685 + int pcibios_add_platform_entries(struct pci_dev *pdev) 686 + { 687 + return zpci_sysfs_add_device(&pdev->dev); 688 + } 689 + 690 + int zpci_request_irq(unsigned int irq, irq_handler_t handler, void *data) 691 + { 692 + int msi_nr = irq_to_msi_nr(irq); 693 + struct zdev_irq_map *imap; 694 + struct msi_desc *msi; 695 + 696 + msi = irq_get_msi_desc(irq); 697 + if (!msi) 698 + return -EIO; 699 + 700 + imap = get_imap(irq); 701 + spin_lock_init(&imap->lock); 702 + 703 + pr_debug("%s: register handler for IRQ:MSI %d:%d\n", __func__, irq >> 6, msi_nr); 704 + imap->cb[msi_nr].handler = handler; 705 + imap->cb[msi_nr].data = data; 706 + 707 + /* 708 + * The generic MSI code returns with the interrupt disabled on the 709 + * card, using the MSI mask bits. Firmware doesn't appear to unmask 710 + * at that level, so we do it here by hand. 711 + */ 712 + zpci_msi_set_mask_bits(msi, 1, 0); 713 + return 0; 714 + } 715 + 716 + void zpci_free_irq(unsigned int irq) 717 + { 718 + struct zdev_irq_map *imap = get_imap(irq); 719 + int msi_nr = irq_to_msi_nr(irq); 720 + unsigned long flags; 721 + 722 + pr_debug("%s: for irq: %d\n", __func__, irq); 723 + 724 + spin_lock_irqsave(&imap->lock, flags); 725 + imap->cb[msi_nr].handler = NULL; 726 + imap->cb[msi_nr].data = NULL; 727 + spin_unlock_irqrestore(&imap->lock, flags); 728 + } 729 + 730 + int request_irq(unsigned int irq, irq_handler_t handler, 731 + unsigned long irqflags, const char *devname, void *dev_id) 732 + { 733 + pr_debug("%s: irq: %d handler: %p flags: %lx dev: %s\n", 734 + __func__, irq, handler, irqflags, devname); 735 + 736 + return zpci_request_irq(irq, handler, dev_id); 737 + } 738 + EXPORT_SYMBOL_GPL(request_irq); 739 + 740 + void free_irq(unsigned int irq, void *dev_id) 741 + { 742 + zpci_free_irq(irq); 743 + } 744 + EXPORT_SYMBOL_GPL(free_irq); 745 + 746 + static int __init zpci_irq_init(void) 747 + { 748 + int cpu, rc; 749 + 750 + bucket = kzalloc(sizeof(*bucket), GFP_KERNEL); 751 + if (!bucket) 752 + return -ENOMEM; 753 + 754 + bucket->aisb = (unsigned long *) get_zeroed_page(GFP_KERNEL); 755 + if (!bucket->aisb) { 756 + rc = -ENOMEM; 757 + goto out_aisb; 758 + } 759 + 760 + bucket->alloc = (unsigned long *) get_zeroed_page(GFP_KERNEL); 761 + if (!bucket->alloc) { 762 + rc = -ENOMEM; 763 + goto out_alloc; 764 + } 765 + 766 + isc_register(PCI_ISC); 767 + zpci_irq_si = s390_register_adapter_interrupt(&zpci_irq_handler, NULL, PCI_ISC); 768 + if (IS_ERR(zpci_irq_si)) { 769 + rc = PTR_ERR(zpci_irq_si); 770 + zpci_irq_si = NULL; 771 + goto out_ai; 772 + } 773 + 774 + for_each_online_cpu(cpu) 775 + per_cpu(next_sbit, cpu) = 0; 776 + 777 + spin_lock_init(&bucket->lock); 778 + /* set summary to 1 to be called every time for the ISC */ 779 + *zpci_irq_si = 1; 780 + sic_instr(SIC_IRQ_MODE_SINGLE, NULL, PCI_ISC); 781 + return 0; 782 + 783 + out_ai: 784 + isc_unregister(PCI_ISC); 785 + free_page((unsigned long) bucket->alloc); 786 + out_alloc: 787 + free_page((unsigned long) bucket->aisb); 788 + out_aisb: 789 + kfree(bucket); 790 + return rc; 791 + } 792 + 793 + static void zpci_irq_exit(void) 794 + { 795 + free_page((unsigned long) bucket->alloc); 796 + free_page((unsigned long) bucket->aisb); 797 + s390_unregister_adapter_interrupt(zpci_irq_si, PCI_ISC); 798 + isc_unregister(PCI_ISC); 799 + kfree(bucket); 800 + } 801 + 802 + static struct resource *zpci_alloc_bus_resource(unsigned long start, unsigned long size, 803 + unsigned long flags, int domain) 804 + { 805 + struct resource *r; 806 + char *name; 807 + int rc; 808 + 809 + r = kzalloc(sizeof(*r), GFP_KERNEL); 810 + if (!r) 811 + return ERR_PTR(-ENOMEM); 812 + r->start = start; 813 + r->end = r->start + size - 1; 814 + r->flags = flags; 815 + r->parent = &iomem_resource; 816 + name = kmalloc(18, GFP_KERNEL); 817 + if (!name) { 818 + kfree(r); 819 + return ERR_PTR(-ENOMEM); 820 + } 821 + sprintf(name, "PCI Bus: %04x:%02x", domain, ZPCI_BUS_NR); 822 + r->name = name; 823 + 824 + rc = request_resource(&iomem_resource, r); 825 + if (rc) 826 + pr_debug("request resource %pR failed\n", r); 827 + return r; 828 + } 829 + 830 + static int zpci_alloc_iomap(struct zpci_dev *zdev) 831 + { 832 + int entry; 833 + 834 + spin_lock(&zpci_iomap_lock); 835 + entry = find_first_zero_bit(zpci_iomap, ZPCI_IOMAP_MAX_ENTRIES); 836 + if (entry == ZPCI_IOMAP_MAX_ENTRIES) { 837 + spin_unlock(&zpci_iomap_lock); 838 + return -ENOSPC; 839 + } 840 + set_bit(entry, zpci_iomap); 841 + spin_unlock(&zpci_iomap_lock); 842 + return entry; 843 + } 844 + 845 + static void zpci_free_iomap(struct zpci_dev *zdev, int entry) 846 + { 847 + spin_lock(&zpci_iomap_lock); 848 + memset(&zpci_iomap_start[entry], 0, sizeof(struct zpci_iomap_entry)); 849 + clear_bit(entry, zpci_iomap); 850 + spin_unlock(&zpci_iomap_lock); 851 + } 852 + 853 + static int zpci_create_device_bus(struct zpci_dev *zdev) 854 + { 855 + struct resource *res; 856 + LIST_HEAD(resources); 857 + int i; 858 + 859 + /* allocate mapping entry for each used bar */ 860 + for (i = 0; i < PCI_BAR_COUNT; i++) { 861 + unsigned long addr, size, flags; 862 + int entry; 863 + 864 + if (!zdev->bars[i].size) 865 + continue; 866 + entry = zpci_alloc_iomap(zdev); 867 + if (entry < 0) 868 + return entry; 869 + zdev->bars[i].map_idx = entry; 870 + 871 + /* only MMIO is supported */ 872 + flags = IORESOURCE_MEM; 873 + if (zdev->bars[i].val & 8) 874 + flags |= IORESOURCE_PREFETCH; 875 + if (zdev->bars[i].val & 4) 876 + flags |= IORESOURCE_MEM_64; 877 + 878 + addr = ZPCI_IOMAP_ADDR_BASE + ((u64) entry << 48); 879 + 880 + size = 1UL << zdev->bars[i].size; 881 + 882 + res = zpci_alloc_bus_resource(addr, size, flags, zdev->domain); 883 + if (IS_ERR(res)) { 884 + zpci_free_iomap(zdev, entry); 885 + return PTR_ERR(res); 886 + } 887 + pci_add_resource(&resources, res); 888 + } 889 + 890 + zdev->bus = pci_create_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops, 891 + zdev, &resources); 892 + if (!zdev->bus) 893 + return -EIO; 894 + 895 + zdev->bus->max_bus_speed = zdev->max_bus_speed; 896 + return 0; 897 + } 898 + 899 + static int zpci_alloc_domain(struct zpci_dev *zdev) 900 + { 901 + spin_lock(&zpci_domain_lock); 902 + zdev->domain = find_first_zero_bit(zpci_domain, ZPCI_NR_DEVICES); 903 + if (zdev->domain == ZPCI_NR_DEVICES) { 904 + spin_unlock(&zpci_domain_lock); 905 + return -ENOSPC; 906 + } 907 + set_bit(zdev->domain, zpci_domain); 908 + spin_unlock(&zpci_domain_lock); 909 + return 0; 910 + } 911 + 912 + static void zpci_free_domain(struct zpci_dev *zdev) 913 + { 914 + spin_lock(&zpci_domain_lock); 915 + clear_bit(zdev->domain, zpci_domain); 916 + spin_unlock(&zpci_domain_lock); 917 + } 918 + 919 + int zpci_enable_device(struct zpci_dev *zdev) 920 + { 921 + int rc; 922 + 923 + rc = clp_enable_fh(zdev, ZPCI_NR_DMA_SPACES); 924 + if (rc) 925 + goto out; 926 + pr_info("Enabled fh: 0x%x fid: 0x%x\n", zdev->fh, zdev->fid); 927 + 928 + rc = zpci_dma_init_device(zdev); 929 + if (rc) 930 + goto out_dma; 931 + return 0; 932 + 933 + out_dma: 934 + clp_disable_fh(zdev); 935 + out: 936 + return rc; 937 + } 938 + EXPORT_SYMBOL_GPL(zpci_enable_device); 939 + 940 + int zpci_create_device(struct zpci_dev *zdev) 941 + { 942 + int rc; 943 + 944 + rc = zpci_alloc_domain(zdev); 945 + if (rc) 946 + goto out; 947 + 948 + rc = zpci_create_device_bus(zdev); 949 + if (rc) 950 + goto out_bus; 951 + 952 + mutex_lock(&zpci_list_lock); 953 + list_add_tail(&zdev->entry, &zpci_list); 954 + if (hotplug_ops.create_slot) 955 + hotplug_ops.create_slot(zdev); 956 + mutex_unlock(&zpci_list_lock); 957 + 958 + if (zdev->state == ZPCI_FN_STATE_STANDBY) 959 + return 0; 960 + 961 + rc = zpci_enable_device(zdev); 962 + if (rc) 963 + goto out_start; 964 + return 0; 965 + 966 + out_start: 967 + mutex_lock(&zpci_list_lock); 968 + list_del(&zdev->entry); 969 + if (hotplug_ops.remove_slot) 970 + hotplug_ops.remove_slot(zdev); 971 + mutex_unlock(&zpci_list_lock); 972 + out_bus: 973 + zpci_free_domain(zdev); 974 + out: 975 + return rc; 976 + } 977 + 978 + void zpci_stop_device(struct zpci_dev *zdev) 979 + { 980 + zpci_dma_exit_device(zdev); 981 + /* 982 + * Note: SCLP disables fh via set-pci-fn so don't 983 + * do that here. 984 + */ 985 + } 986 + EXPORT_SYMBOL_GPL(zpci_stop_device); 987 + 988 + int zpci_scan_device(struct zpci_dev *zdev) 989 + { 990 + zdev->pdev = pci_scan_single_device(zdev->bus, ZPCI_DEVFN); 991 + if (!zdev->pdev) { 992 + pr_err("pci_scan_single_device failed for fid: 0x%x\n", 993 + zdev->fid); 994 + goto out; 995 + } 996 + 997 + zpci_map_resources(zdev); 998 + pci_bus_add_devices(zdev->bus); 999 + 1000 + /* now that pdev was added to the bus mark it as used */ 1001 + zdev->state = ZPCI_FN_STATE_ONLINE; 1002 + return 0; 1003 + 1004 + out: 1005 + zpci_dma_exit_device(zdev); 1006 + clp_disable_fh(zdev); 1007 + return -EIO; 1008 + } 1009 + EXPORT_SYMBOL_GPL(zpci_scan_device); 1010 + 1011 + static inline int barsize(u8 size) 1012 + { 1013 + return (size) ? (1 << size) >> 10 : 0; 1014 + } 1015 + 1016 + static int zpci_mem_init(void) 1017 + { 1018 + zdev_irq_cache = kmem_cache_create("PCI_IRQ_cache", sizeof(struct zdev_irq_map), 1019 + L1_CACHE_BYTES, SLAB_HWCACHE_ALIGN, NULL); 1020 + if (!zdev_irq_cache) 1021 + goto error_zdev; 1022 + 1023 + /* TODO: use realloc */ 1024 + zpci_iomap_start = kzalloc(ZPCI_IOMAP_MAX_ENTRIES * sizeof(*zpci_iomap_start), 1025 + GFP_KERNEL); 1026 + if (!zpci_iomap_start) 1027 + goto error_iomap; 1028 + return 0; 1029 + 1030 + error_iomap: 1031 + kmem_cache_destroy(zdev_irq_cache); 1032 + error_zdev: 1033 + return -ENOMEM; 1034 + } 1035 + 1036 + static void zpci_mem_exit(void) 1037 + { 1038 + kfree(zpci_iomap_start); 1039 + kmem_cache_destroy(zdev_irq_cache); 1040 + } 1041 + 1042 + unsigned int pci_probe = 1; 1043 + EXPORT_SYMBOL_GPL(pci_probe); 1044 + 1045 + char * __init pcibios_setup(char *str) 1046 + { 1047 + if (!strcmp(str, "off")) { 1048 + pci_probe = 0; 1049 + return NULL; 1050 + } 1051 + return str; 1052 + } 1053 + 1054 + static int __init pci_base_init(void) 1055 + { 1056 + int rc; 1057 + 1058 + if (!pci_probe) 1059 + return 0; 1060 + 1061 + if (!test_facility(2) || !test_facility(69) 1062 + || !test_facility(71) || !test_facility(72)) 1063 + return 0; 1064 + 1065 + pr_info("Probing PCI hardware: PCI:%d SID:%d AEN:%d\n", 1066 + test_facility(69), test_facility(70), 1067 + test_facility(71)); 1068 + 1069 + rc = zpci_mem_init(); 1070 + if (rc) 1071 + goto out_mem; 1072 + 1073 + rc = zpci_msihash_init(); 1074 + if (rc) 1075 + goto out_hash; 1076 + 1077 + rc = zpci_irq_init(); 1078 + if (rc) 1079 + goto out_irq; 1080 + 1081 + rc = zpci_dma_init(); 1082 + if (rc) 1083 + goto out_dma; 1084 + 1085 + rc = clp_find_pci_devices(); 1086 + if (rc) 1087 + goto out_find; 1088 + 1089 + zpci_scan_devices(); 1090 + return 0; 1091 + 1092 + out_find: 1093 + zpci_dma_exit(); 1094 + out_dma: 1095 + zpci_irq_exit(); 1096 + out_irq: 1097 + zpci_msihash_exit(); 1098 + out_hash: 1099 + zpci_mem_exit(); 1100 + out_mem: 1101 + return rc; 1102 + } 1103 + subsys_initcall(pci_base_init);
+324
arch/s390/pci/pci_clp.c
··· 1 + /* 2 + * Copyright IBM Corp. 2012 3 + * 4 + * Author(s): 5 + * Jan Glauber <jang@linux.vnet.ibm.com> 6 + */ 7 + 8 + #define COMPONENT "zPCI" 9 + #define pr_fmt(fmt) COMPONENT ": " fmt 10 + 11 + #include <linux/kernel.h> 12 + #include <linux/slab.h> 13 + #include <linux/err.h> 14 + #include <linux/delay.h> 15 + #include <linux/pci.h> 16 + #include <asm/pci_clp.h> 17 + 18 + /* 19 + * Call Logical Processor 20 + * Retry logic is handled by the caller. 21 + */ 22 + static inline u8 clp_instr(void *req) 23 + { 24 + u64 ilpm; 25 + u8 cc; 26 + 27 + asm volatile ( 28 + " .insn rrf,0xb9a00000,%[ilpm],%[req],0x0,0x2\n" 29 + " ipm %[cc]\n" 30 + " srl %[cc],28\n" 31 + : [cc] "=d" (cc), [ilpm] "=d" (ilpm) 32 + : [req] "a" (req) 33 + : "cc", "memory"); 34 + return cc; 35 + } 36 + 37 + static void *clp_alloc_block(void) 38 + { 39 + struct page *page = alloc_pages(GFP_KERNEL, get_order(CLP_BLK_SIZE)); 40 + return (page) ? page_address(page) : NULL; 41 + } 42 + 43 + static void clp_free_block(void *ptr) 44 + { 45 + free_pages((unsigned long) ptr, get_order(CLP_BLK_SIZE)); 46 + } 47 + 48 + static void clp_store_query_pci_fngrp(struct zpci_dev *zdev, 49 + struct clp_rsp_query_pci_grp *response) 50 + { 51 + zdev->tlb_refresh = response->refresh; 52 + zdev->dma_mask = response->dasm; 53 + zdev->msi_addr = response->msia; 54 + 55 + pr_debug("Supported number of MSI vectors: %u\n", response->noi); 56 + switch (response->version) { 57 + case 1: 58 + zdev->max_bus_speed = PCIE_SPEED_5_0GT; 59 + break; 60 + default: 61 + zdev->max_bus_speed = PCI_SPEED_UNKNOWN; 62 + break; 63 + } 64 + } 65 + 66 + static int clp_query_pci_fngrp(struct zpci_dev *zdev, u8 pfgid) 67 + { 68 + struct clp_req_rsp_query_pci_grp *rrb; 69 + int rc; 70 + 71 + rrb = clp_alloc_block(); 72 + if (!rrb) 73 + return -ENOMEM; 74 + 75 + memset(rrb, 0, sizeof(*rrb)); 76 + rrb->request.hdr.len = sizeof(rrb->request); 77 + rrb->request.hdr.cmd = CLP_QUERY_PCI_FNGRP; 78 + rrb->response.hdr.len = sizeof(rrb->response); 79 + rrb->request.pfgid = pfgid; 80 + 81 + rc = clp_instr(rrb); 82 + if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) 83 + clp_store_query_pci_fngrp(zdev, &rrb->response); 84 + else { 85 + pr_err("Query PCI FNGRP failed with response: %x cc: %d\n", 86 + rrb->response.hdr.rsp, rc); 87 + rc = -EIO; 88 + } 89 + clp_free_block(rrb); 90 + return rc; 91 + } 92 + 93 + static int clp_store_query_pci_fn(struct zpci_dev *zdev, 94 + struct clp_rsp_query_pci *response) 95 + { 96 + int i; 97 + 98 + for (i = 0; i < PCI_BAR_COUNT; i++) { 99 + zdev->bars[i].val = le32_to_cpu(response->bar[i]); 100 + zdev->bars[i].size = response->bar_size[i]; 101 + } 102 + zdev->start_dma = response->sdma; 103 + zdev->end_dma = response->edma; 104 + zdev->pchid = response->pchid; 105 + zdev->pfgid = response->pfgid; 106 + return 0; 107 + } 108 + 109 + static int clp_query_pci_fn(struct zpci_dev *zdev, u32 fh) 110 + { 111 + struct clp_req_rsp_query_pci *rrb; 112 + int rc; 113 + 114 + rrb = clp_alloc_block(); 115 + if (!rrb) 116 + return -ENOMEM; 117 + 118 + memset(rrb, 0, sizeof(*rrb)); 119 + rrb->request.hdr.len = sizeof(rrb->request); 120 + rrb->request.hdr.cmd = CLP_QUERY_PCI_FN; 121 + rrb->response.hdr.len = sizeof(rrb->response); 122 + rrb->request.fh = fh; 123 + 124 + rc = clp_instr(rrb); 125 + if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) { 126 + rc = clp_store_query_pci_fn(zdev, &rrb->response); 127 + if (rc) 128 + goto out; 129 + if (rrb->response.pfgid) 130 + rc = clp_query_pci_fngrp(zdev, rrb->response.pfgid); 131 + } else { 132 + pr_err("Query PCI failed with response: %x cc: %d\n", 133 + rrb->response.hdr.rsp, rc); 134 + rc = -EIO; 135 + } 136 + out: 137 + clp_free_block(rrb); 138 + return rc; 139 + } 140 + 141 + int clp_add_pci_device(u32 fid, u32 fh, int configured) 142 + { 143 + struct zpci_dev *zdev; 144 + int rc; 145 + 146 + zdev = zpci_alloc_device(); 147 + if (IS_ERR(zdev)) 148 + return PTR_ERR(zdev); 149 + 150 + zdev->fh = fh; 151 + zdev->fid = fid; 152 + 153 + /* Query function properties and update zdev */ 154 + rc = clp_query_pci_fn(zdev, fh); 155 + if (rc) 156 + goto error; 157 + 158 + if (configured) 159 + zdev->state = ZPCI_FN_STATE_CONFIGURED; 160 + else 161 + zdev->state = ZPCI_FN_STATE_STANDBY; 162 + 163 + rc = zpci_create_device(zdev); 164 + if (rc) 165 + goto error; 166 + return 0; 167 + 168 + error: 169 + zpci_free_device(zdev); 170 + return rc; 171 + } 172 + 173 + /* 174 + * Enable/Disable a given PCI function defined by its function handle. 175 + */ 176 + static int clp_set_pci_fn(u32 *fh, u8 nr_dma_as, u8 command) 177 + { 178 + struct clp_req_rsp_set_pci *rrb; 179 + int rc, retries = 1000; 180 + 181 + rrb = clp_alloc_block(); 182 + if (!rrb) 183 + return -ENOMEM; 184 + 185 + do { 186 + memset(rrb, 0, sizeof(*rrb)); 187 + rrb->request.hdr.len = sizeof(rrb->request); 188 + rrb->request.hdr.cmd = CLP_SET_PCI_FN; 189 + rrb->response.hdr.len = sizeof(rrb->response); 190 + rrb->request.fh = *fh; 191 + rrb->request.oc = command; 192 + rrb->request.ndas = nr_dma_as; 193 + 194 + rc = clp_instr(rrb); 195 + if (rrb->response.hdr.rsp == CLP_RC_SETPCIFN_BUSY) { 196 + retries--; 197 + if (retries < 0) 198 + break; 199 + msleep(1); 200 + } 201 + } while (rrb->response.hdr.rsp == CLP_RC_SETPCIFN_BUSY); 202 + 203 + if (!rc && rrb->response.hdr.rsp == CLP_RC_OK) 204 + *fh = rrb->response.fh; 205 + else { 206 + pr_err("Set PCI FN failed with response: %x cc: %d\n", 207 + rrb->response.hdr.rsp, rc); 208 + rc = -EIO; 209 + } 210 + clp_free_block(rrb); 211 + return rc; 212 + } 213 + 214 + int clp_enable_fh(struct zpci_dev *zdev, u8 nr_dma_as) 215 + { 216 + u32 fh = zdev->fh; 217 + int rc; 218 + 219 + rc = clp_set_pci_fn(&fh, nr_dma_as, CLP_SET_ENABLE_PCI_FN); 220 + if (!rc) 221 + /* Success -> store enabled handle in zdev */ 222 + zdev->fh = fh; 223 + return rc; 224 + } 225 + 226 + int clp_disable_fh(struct zpci_dev *zdev) 227 + { 228 + u32 fh = zdev->fh; 229 + int rc; 230 + 231 + if (!zdev_enabled(zdev)) 232 + return 0; 233 + 234 + dev_info(&zdev->pdev->dev, "disabling fn handle: 0x%x\n", fh); 235 + rc = clp_set_pci_fn(&fh, 0, CLP_SET_DISABLE_PCI_FN); 236 + if (!rc) 237 + /* Success -> store disabled handle in zdev */ 238 + zdev->fh = fh; 239 + else 240 + dev_err(&zdev->pdev->dev, 241 + "Failed to disable fn handle: 0x%x\n", fh); 242 + return rc; 243 + } 244 + 245 + static void clp_check_pcifn_entry(struct clp_fh_list_entry *entry) 246 + { 247 + int present, rc; 248 + 249 + if (!entry->vendor_id) 250 + return; 251 + 252 + /* TODO: be a little bit more scalable */ 253 + present = zpci_fid_present(entry->fid); 254 + 255 + if (present) 256 + pr_debug("%s: device %x already present\n", __func__, entry->fid); 257 + 258 + /* skip already used functions */ 259 + if (present && entry->config_state) 260 + return; 261 + 262 + /* aev 306: function moved to stand-by state */ 263 + if (present && !entry->config_state) { 264 + /* 265 + * The handle is already disabled, that means no iota/irq freeing via 266 + * the firmware interfaces anymore. Need to free resources manually 267 + * (DMA memory, debug, sysfs)... 268 + */ 269 + zpci_stop_device(get_zdev_by_fid(entry->fid)); 270 + return; 271 + } 272 + 273 + rc = clp_add_pci_device(entry->fid, entry->fh, entry->config_state); 274 + if (rc) 275 + pr_err("Failed to add fid: 0x%x\n", entry->fid); 276 + } 277 + 278 + int clp_find_pci_devices(void) 279 + { 280 + struct clp_req_rsp_list_pci *rrb; 281 + u64 resume_token = 0; 282 + int entries, i, rc; 283 + 284 + rrb = clp_alloc_block(); 285 + if (!rrb) 286 + return -ENOMEM; 287 + 288 + do { 289 + memset(rrb, 0, sizeof(*rrb)); 290 + rrb->request.hdr.len = sizeof(rrb->request); 291 + rrb->request.hdr.cmd = CLP_LIST_PCI; 292 + /* store as many entries as possible */ 293 + rrb->response.hdr.len = CLP_BLK_SIZE - LIST_PCI_HDR_LEN; 294 + rrb->request.resume_token = resume_token; 295 + 296 + /* Get PCI function handle list */ 297 + rc = clp_instr(rrb); 298 + if (rc || rrb->response.hdr.rsp != CLP_RC_OK) { 299 + pr_err("List PCI failed with response: 0x%x cc: %d\n", 300 + rrb->response.hdr.rsp, rc); 301 + rc = -EIO; 302 + goto out; 303 + } 304 + 305 + WARN_ON_ONCE(rrb->response.entry_size != 306 + sizeof(struct clp_fh_list_entry)); 307 + 308 + entries = (rrb->response.hdr.len - LIST_PCI_HDR_LEN) / 309 + rrb->response.entry_size; 310 + pr_info("Detected number of PCI functions: %u\n", entries); 311 + 312 + /* Store the returned resume token as input for the next call */ 313 + resume_token = rrb->response.resume_token; 314 + 315 + for (i = 0; i < entries; i++) 316 + clp_check_pcifn_entry(&rrb->response.fh_list[i]); 317 + } while (resume_token); 318 + 319 + pr_debug("Maximum number of supported PCI functions: %u\n", 320 + rrb->response.max_fn); 321 + out: 322 + clp_free_block(rrb); 323 + return rc; 324 + }
+506
arch/s390/pci/pci_dma.c
··· 1 + /* 2 + * Copyright IBM Corp. 2012 3 + * 4 + * Author(s): 5 + * Jan Glauber <jang@linux.vnet.ibm.com> 6 + */ 7 + 8 + #include <linux/kernel.h> 9 + #include <linux/slab.h> 10 + #include <linux/export.h> 11 + #include <linux/iommu-helper.h> 12 + #include <linux/dma-mapping.h> 13 + #include <linux/pci.h> 14 + #include <asm/pci_dma.h> 15 + 16 + static enum zpci_ioat_dtype zpci_ioat_dt = ZPCI_IOTA_RTTO; 17 + 18 + static struct kmem_cache *dma_region_table_cache; 19 + static struct kmem_cache *dma_page_table_cache; 20 + 21 + static unsigned long *dma_alloc_cpu_table(void) 22 + { 23 + unsigned long *table, *entry; 24 + 25 + table = kmem_cache_alloc(dma_region_table_cache, GFP_ATOMIC); 26 + if (!table) 27 + return NULL; 28 + 29 + for (entry = table; entry < table + ZPCI_TABLE_ENTRIES; entry++) 30 + *entry = ZPCI_TABLE_INVALID | ZPCI_TABLE_PROTECTED; 31 + return table; 32 + } 33 + 34 + static void dma_free_cpu_table(void *table) 35 + { 36 + kmem_cache_free(dma_region_table_cache, table); 37 + } 38 + 39 + static unsigned long *dma_alloc_page_table(void) 40 + { 41 + unsigned long *table, *entry; 42 + 43 + table = kmem_cache_alloc(dma_page_table_cache, GFP_ATOMIC); 44 + if (!table) 45 + return NULL; 46 + 47 + for (entry = table; entry < table + ZPCI_PT_ENTRIES; entry++) 48 + *entry = ZPCI_PTE_INVALID | ZPCI_TABLE_PROTECTED; 49 + return table; 50 + } 51 + 52 + static void dma_free_page_table(void *table) 53 + { 54 + kmem_cache_free(dma_page_table_cache, table); 55 + } 56 + 57 + static unsigned long *dma_get_seg_table_origin(unsigned long *entry) 58 + { 59 + unsigned long *sto; 60 + 61 + if (reg_entry_isvalid(*entry)) 62 + sto = get_rt_sto(*entry); 63 + else { 64 + sto = dma_alloc_cpu_table(); 65 + if (!sto) 66 + return NULL; 67 + 68 + set_rt_sto(entry, sto); 69 + validate_rt_entry(entry); 70 + entry_clr_protected(entry); 71 + } 72 + return sto; 73 + } 74 + 75 + static unsigned long *dma_get_page_table_origin(unsigned long *entry) 76 + { 77 + unsigned long *pto; 78 + 79 + if (reg_entry_isvalid(*entry)) 80 + pto = get_st_pto(*entry); 81 + else { 82 + pto = dma_alloc_page_table(); 83 + if (!pto) 84 + return NULL; 85 + set_st_pto(entry, pto); 86 + validate_st_entry(entry); 87 + entry_clr_protected(entry); 88 + } 89 + return pto; 90 + } 91 + 92 + static unsigned long *dma_walk_cpu_trans(unsigned long *rto, dma_addr_t dma_addr) 93 + { 94 + unsigned long *sto, *pto; 95 + unsigned int rtx, sx, px; 96 + 97 + rtx = calc_rtx(dma_addr); 98 + sto = dma_get_seg_table_origin(&rto[rtx]); 99 + if (!sto) 100 + return NULL; 101 + 102 + sx = calc_sx(dma_addr); 103 + pto = dma_get_page_table_origin(&sto[sx]); 104 + if (!pto) 105 + return NULL; 106 + 107 + px = calc_px(dma_addr); 108 + return &pto[px]; 109 + } 110 + 111 + static void dma_update_cpu_trans(struct zpci_dev *zdev, void *page_addr, 112 + dma_addr_t dma_addr, int flags) 113 + { 114 + unsigned long *entry; 115 + 116 + entry = dma_walk_cpu_trans(zdev->dma_table, dma_addr); 117 + if (!entry) { 118 + WARN_ON_ONCE(1); 119 + return; 120 + } 121 + 122 + if (flags & ZPCI_PTE_INVALID) { 123 + invalidate_pt_entry(entry); 124 + return; 125 + } else { 126 + set_pt_pfaa(entry, page_addr); 127 + validate_pt_entry(entry); 128 + } 129 + 130 + if (flags & ZPCI_TABLE_PROTECTED) 131 + entry_set_protected(entry); 132 + else 133 + entry_clr_protected(entry); 134 + } 135 + 136 + static int dma_update_trans(struct zpci_dev *zdev, unsigned long pa, 137 + dma_addr_t dma_addr, size_t size, int flags) 138 + { 139 + unsigned int nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; 140 + u8 *page_addr = (u8 *) (pa & PAGE_MASK); 141 + dma_addr_t start_dma_addr = dma_addr; 142 + unsigned long irq_flags; 143 + int i, rc = 0; 144 + 145 + if (!nr_pages) 146 + return -EINVAL; 147 + 148 + spin_lock_irqsave(&zdev->dma_table_lock, irq_flags); 149 + if (!zdev->dma_table) { 150 + dev_err(&zdev->pdev->dev, "Missing DMA table\n"); 151 + goto no_refresh; 152 + } 153 + 154 + for (i = 0; i < nr_pages; i++) { 155 + dma_update_cpu_trans(zdev, page_addr, dma_addr, flags); 156 + page_addr += PAGE_SIZE; 157 + dma_addr += PAGE_SIZE; 158 + } 159 + 160 + /* 161 + * rpcit is not required to establish new translations when previously 162 + * invalid translation-table entries are validated, however it is 163 + * required when altering previously valid entries. 164 + */ 165 + if (!zdev->tlb_refresh && 166 + ((flags & ZPCI_PTE_VALID_MASK) == ZPCI_PTE_VALID)) 167 + /* 168 + * TODO: also need to check that the old entry is indeed INVALID 169 + * and not only for one page but for the whole range... 170 + * -> now we WARN_ON in that case but with lazy unmap that 171 + * needs to be redone! 172 + */ 173 + goto no_refresh; 174 + rc = rpcit_instr((u64) zdev->fh << 32, start_dma_addr, 175 + nr_pages * PAGE_SIZE); 176 + 177 + no_refresh: 178 + spin_unlock_irqrestore(&zdev->dma_table_lock, irq_flags); 179 + return rc; 180 + } 181 + 182 + static void dma_free_seg_table(unsigned long entry) 183 + { 184 + unsigned long *sto = get_rt_sto(entry); 185 + int sx; 186 + 187 + for (sx = 0; sx < ZPCI_TABLE_ENTRIES; sx++) 188 + if (reg_entry_isvalid(sto[sx])) 189 + dma_free_page_table(get_st_pto(sto[sx])); 190 + 191 + dma_free_cpu_table(sto); 192 + } 193 + 194 + static void dma_cleanup_tables(struct zpci_dev *zdev) 195 + { 196 + unsigned long *table; 197 + int rtx; 198 + 199 + if (!zdev || !zdev->dma_table) 200 + return; 201 + 202 + table = zdev->dma_table; 203 + for (rtx = 0; rtx < ZPCI_TABLE_ENTRIES; rtx++) 204 + if (reg_entry_isvalid(table[rtx])) 205 + dma_free_seg_table(table[rtx]); 206 + 207 + dma_free_cpu_table(table); 208 + zdev->dma_table = NULL; 209 + } 210 + 211 + static unsigned long __dma_alloc_iommu(struct zpci_dev *zdev, unsigned long start, 212 + int size) 213 + { 214 + unsigned long boundary_size = 0x1000000; 215 + 216 + return iommu_area_alloc(zdev->iommu_bitmap, zdev->iommu_pages, 217 + start, size, 0, boundary_size, 0); 218 + } 219 + 220 + static unsigned long dma_alloc_iommu(struct zpci_dev *zdev, int size) 221 + { 222 + unsigned long offset, flags; 223 + 224 + spin_lock_irqsave(&zdev->iommu_bitmap_lock, flags); 225 + offset = __dma_alloc_iommu(zdev, zdev->next_bit, size); 226 + if (offset == -1) 227 + offset = __dma_alloc_iommu(zdev, 0, size); 228 + 229 + if (offset != -1) { 230 + zdev->next_bit = offset + size; 231 + if (zdev->next_bit >= zdev->iommu_pages) 232 + zdev->next_bit = 0; 233 + } 234 + spin_unlock_irqrestore(&zdev->iommu_bitmap_lock, flags); 235 + return offset; 236 + } 237 + 238 + static void dma_free_iommu(struct zpci_dev *zdev, unsigned long offset, int size) 239 + { 240 + unsigned long flags; 241 + 242 + spin_lock_irqsave(&zdev->iommu_bitmap_lock, flags); 243 + if (!zdev->iommu_bitmap) 244 + goto out; 245 + bitmap_clear(zdev->iommu_bitmap, offset, size); 246 + if (offset >= zdev->next_bit) 247 + zdev->next_bit = offset + size; 248 + out: 249 + spin_unlock_irqrestore(&zdev->iommu_bitmap_lock, flags); 250 + } 251 + 252 + int dma_set_mask(struct device *dev, u64 mask) 253 + { 254 + if (!dev->dma_mask || !dma_supported(dev, mask)) 255 + return -EIO; 256 + 257 + *dev->dma_mask = mask; 258 + return 0; 259 + } 260 + EXPORT_SYMBOL_GPL(dma_set_mask); 261 + 262 + static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page, 263 + unsigned long offset, size_t size, 264 + enum dma_data_direction direction, 265 + struct dma_attrs *attrs) 266 + { 267 + struct zpci_dev *zdev = get_zdev(container_of(dev, struct pci_dev, dev)); 268 + unsigned long nr_pages, iommu_page_index; 269 + unsigned long pa = page_to_phys(page) + offset; 270 + int flags = ZPCI_PTE_VALID; 271 + dma_addr_t dma_addr; 272 + 273 + WARN_ON_ONCE(offset > PAGE_SIZE); 274 + 275 + /* This rounds up number of pages based on size and offset */ 276 + nr_pages = iommu_num_pages(pa, size, PAGE_SIZE); 277 + iommu_page_index = dma_alloc_iommu(zdev, nr_pages); 278 + if (iommu_page_index == -1) 279 + goto out_err; 280 + 281 + /* Use rounded up size */ 282 + size = nr_pages * PAGE_SIZE; 283 + 284 + dma_addr = zdev->start_dma + iommu_page_index * PAGE_SIZE; 285 + if (dma_addr + size > zdev->end_dma) { 286 + dev_err(dev, "(dma_addr: 0x%16.16LX + size: 0x%16.16lx) > end_dma: 0x%16.16Lx\n", 287 + dma_addr, size, zdev->end_dma); 288 + goto out_free; 289 + } 290 + 291 + if (direction == DMA_NONE || direction == DMA_TO_DEVICE) 292 + flags |= ZPCI_TABLE_PROTECTED; 293 + 294 + if (!dma_update_trans(zdev, pa, dma_addr, size, flags)) 295 + return dma_addr + offset; 296 + 297 + out_free: 298 + dma_free_iommu(zdev, iommu_page_index, nr_pages); 299 + out_err: 300 + dev_err(dev, "Failed to map addr: %lx\n", pa); 301 + return DMA_ERROR_CODE; 302 + } 303 + 304 + static void s390_dma_unmap_pages(struct device *dev, dma_addr_t dma_addr, 305 + size_t size, enum dma_data_direction direction, 306 + struct dma_attrs *attrs) 307 + { 308 + struct zpci_dev *zdev = get_zdev(container_of(dev, struct pci_dev, dev)); 309 + unsigned long iommu_page_index; 310 + int npages; 311 + 312 + npages = iommu_num_pages(dma_addr, size, PAGE_SIZE); 313 + dma_addr = dma_addr & PAGE_MASK; 314 + if (dma_update_trans(zdev, 0, dma_addr, npages * PAGE_SIZE, 315 + ZPCI_TABLE_PROTECTED | ZPCI_PTE_INVALID)) 316 + dev_err(dev, "Failed to unmap addr: %Lx\n", dma_addr); 317 + 318 + iommu_page_index = (dma_addr - zdev->start_dma) >> PAGE_SHIFT; 319 + dma_free_iommu(zdev, iommu_page_index, npages); 320 + } 321 + 322 + static void *s390_dma_alloc(struct device *dev, size_t size, 323 + dma_addr_t *dma_handle, gfp_t flag, 324 + struct dma_attrs *attrs) 325 + { 326 + struct page *page; 327 + unsigned long pa; 328 + dma_addr_t map; 329 + 330 + size = PAGE_ALIGN(size); 331 + page = alloc_pages(flag, get_order(size)); 332 + if (!page) 333 + return NULL; 334 + pa = page_to_phys(page); 335 + memset((void *) pa, 0, size); 336 + 337 + map = s390_dma_map_pages(dev, page, pa % PAGE_SIZE, 338 + size, DMA_BIDIRECTIONAL, NULL); 339 + if (dma_mapping_error(dev, map)) { 340 + free_pages(pa, get_order(size)); 341 + return NULL; 342 + } 343 + 344 + if (dma_handle) 345 + *dma_handle = map; 346 + return (void *) pa; 347 + } 348 + 349 + static void s390_dma_free(struct device *dev, size_t size, 350 + void *pa, dma_addr_t dma_handle, 351 + struct dma_attrs *attrs) 352 + { 353 + s390_dma_unmap_pages(dev, dma_handle, PAGE_ALIGN(size), 354 + DMA_BIDIRECTIONAL, NULL); 355 + free_pages((unsigned long) pa, get_order(size)); 356 + } 357 + 358 + static int s390_dma_map_sg(struct device *dev, struct scatterlist *sg, 359 + int nr_elements, enum dma_data_direction dir, 360 + struct dma_attrs *attrs) 361 + { 362 + int mapped_elements = 0; 363 + struct scatterlist *s; 364 + int i; 365 + 366 + for_each_sg(sg, s, nr_elements, i) { 367 + struct page *page = sg_page(s); 368 + s->dma_address = s390_dma_map_pages(dev, page, s->offset, 369 + s->length, dir, NULL); 370 + if (!dma_mapping_error(dev, s->dma_address)) { 371 + s->dma_length = s->length; 372 + mapped_elements++; 373 + } else 374 + goto unmap; 375 + } 376 + out: 377 + return mapped_elements; 378 + 379 + unmap: 380 + for_each_sg(sg, s, mapped_elements, i) { 381 + if (s->dma_address) 382 + s390_dma_unmap_pages(dev, s->dma_address, s->dma_length, 383 + dir, NULL); 384 + s->dma_address = 0; 385 + s->dma_length = 0; 386 + } 387 + mapped_elements = 0; 388 + goto out; 389 + } 390 + 391 + static void s390_dma_unmap_sg(struct device *dev, struct scatterlist *sg, 392 + int nr_elements, enum dma_data_direction dir, 393 + struct dma_attrs *attrs) 394 + { 395 + struct scatterlist *s; 396 + int i; 397 + 398 + for_each_sg(sg, s, nr_elements, i) { 399 + s390_dma_unmap_pages(dev, s->dma_address, s->dma_length, dir, NULL); 400 + s->dma_address = 0; 401 + s->dma_length = 0; 402 + } 403 + } 404 + 405 + int zpci_dma_init_device(struct zpci_dev *zdev) 406 + { 407 + unsigned int bitmap_order; 408 + int rc; 409 + 410 + spin_lock_init(&zdev->iommu_bitmap_lock); 411 + spin_lock_init(&zdev->dma_table_lock); 412 + 413 + zdev->dma_table = dma_alloc_cpu_table(); 414 + if (!zdev->dma_table) { 415 + rc = -ENOMEM; 416 + goto out_clean; 417 + } 418 + 419 + zdev->iommu_size = (unsigned long) high_memory - PAGE_OFFSET; 420 + zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT; 421 + bitmap_order = get_order(zdev->iommu_pages / 8); 422 + pr_info("iommu_size: 0x%lx iommu_pages: 0x%lx bitmap_order: %i\n", 423 + zdev->iommu_size, zdev->iommu_pages, bitmap_order); 424 + 425 + zdev->iommu_bitmap = (void *) __get_free_pages(GFP_KERNEL | __GFP_ZERO, 426 + bitmap_order); 427 + if (!zdev->iommu_bitmap) { 428 + rc = -ENOMEM; 429 + goto out_reg; 430 + } 431 + 432 + rc = zpci_register_ioat(zdev, 433 + 0, 434 + zdev->start_dma + PAGE_OFFSET, 435 + zdev->start_dma + zdev->iommu_size - 1, 436 + (u64) zdev->dma_table); 437 + if (rc) 438 + goto out_reg; 439 + return 0; 440 + 441 + out_reg: 442 + dma_free_cpu_table(zdev->dma_table); 443 + out_clean: 444 + return rc; 445 + } 446 + 447 + void zpci_dma_exit_device(struct zpci_dev *zdev) 448 + { 449 + zpci_unregister_ioat(zdev, 0); 450 + dma_cleanup_tables(zdev); 451 + free_pages((unsigned long) zdev->iommu_bitmap, 452 + get_order(zdev->iommu_pages / 8)); 453 + zdev->iommu_bitmap = NULL; 454 + zdev->next_bit = 0; 455 + } 456 + 457 + static int __init dma_alloc_cpu_table_caches(void) 458 + { 459 + dma_region_table_cache = kmem_cache_create("PCI_DMA_region_tables", 460 + ZPCI_TABLE_SIZE, ZPCI_TABLE_ALIGN, 461 + 0, NULL); 462 + if (!dma_region_table_cache) 463 + return -ENOMEM; 464 + 465 + dma_page_table_cache = kmem_cache_create("PCI_DMA_page_tables", 466 + ZPCI_PT_SIZE, ZPCI_PT_ALIGN, 467 + 0, NULL); 468 + if (!dma_page_table_cache) { 469 + kmem_cache_destroy(dma_region_table_cache); 470 + return -ENOMEM; 471 + } 472 + return 0; 473 + } 474 + 475 + int __init zpci_dma_init(void) 476 + { 477 + return dma_alloc_cpu_table_caches(); 478 + } 479 + 480 + void zpci_dma_exit(void) 481 + { 482 + kmem_cache_destroy(dma_page_table_cache); 483 + kmem_cache_destroy(dma_region_table_cache); 484 + } 485 + 486 + #define PREALLOC_DMA_DEBUG_ENTRIES (1 << 16) 487 + 488 + static int __init dma_debug_do_init(void) 489 + { 490 + dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); 491 + return 0; 492 + } 493 + fs_initcall(dma_debug_do_init); 494 + 495 + struct dma_map_ops s390_dma_ops = { 496 + .alloc = s390_dma_alloc, 497 + .free = s390_dma_free, 498 + .map_sg = s390_dma_map_sg, 499 + .unmap_sg = s390_dma_unmap_sg, 500 + .map_page = s390_dma_map_pages, 501 + .unmap_page = s390_dma_unmap_pages, 502 + /* if we support direct DMA this must be conditional */ 503 + .is_phys = 0, 504 + /* dma_supported is unconditionally true without a callback */ 505 + }; 506 + EXPORT_SYMBOL_GPL(s390_dma_ops);
+93
arch/s390/pci/pci_event.c
··· 1 + /* 2 + * Copyright IBM Corp. 2012 3 + * 4 + * Author(s): 5 + * Jan Glauber <jang@linux.vnet.ibm.com> 6 + */ 7 + 8 + #define COMPONENT "zPCI" 9 + #define pr_fmt(fmt) COMPONENT ": " fmt 10 + 11 + #include <linux/kernel.h> 12 + #include <linux/pci.h> 13 + 14 + /* Content Code Description for PCI Function Error */ 15 + struct zpci_ccdf_err { 16 + u32 reserved1; 17 + u32 fh; /* function handle */ 18 + u32 fid; /* function id */ 19 + u32 ett : 4; /* expected table type */ 20 + u32 mvn : 12; /* MSI vector number */ 21 + u32 dmaas : 8; /* DMA address space */ 22 + u32 : 6; 23 + u32 q : 1; /* event qualifier */ 24 + u32 rw : 1; /* read/write */ 25 + u64 faddr; /* failing address */ 26 + u32 reserved3; 27 + u16 reserved4; 28 + u16 pec; /* PCI event code */ 29 + } __packed; 30 + 31 + /* Content Code Description for PCI Function Availability */ 32 + struct zpci_ccdf_avail { 33 + u32 reserved1; 34 + u32 fh; /* function handle */ 35 + u32 fid; /* function id */ 36 + u32 reserved2; 37 + u32 reserved3; 38 + u32 reserved4; 39 + u32 reserved5; 40 + u16 reserved6; 41 + u16 pec; /* PCI event code */ 42 + } __packed; 43 + 44 + static void zpci_event_log_err(struct zpci_ccdf_err *ccdf) 45 + { 46 + struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid); 47 + 48 + dev_err(&zdev->pdev->dev, "event code: 0x%x\n", ccdf->pec); 49 + } 50 + 51 + static void zpci_event_log_avail(struct zpci_ccdf_avail *ccdf) 52 + { 53 + struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid); 54 + 55 + pr_err("%s%s: availability event: fh: 0x%x fid: 0x%x event code: 0x%x reason:", 56 + (zdev) ? dev_driver_string(&zdev->pdev->dev) : "?", 57 + (zdev) ? dev_name(&zdev->pdev->dev) : "?", 58 + ccdf->fh, ccdf->fid, ccdf->pec); 59 + print_hex_dump(KERN_CONT, "ccdf", DUMP_PREFIX_OFFSET, 60 + 16, 1, ccdf, sizeof(*ccdf), false); 61 + 62 + switch (ccdf->pec) { 63 + case 0x0301: 64 + zpci_enable_device(zdev); 65 + break; 66 + case 0x0302: 67 + clp_add_pci_device(ccdf->fid, ccdf->fh, 0); 68 + break; 69 + case 0x0306: 70 + clp_find_pci_devices(); 71 + break; 72 + default: 73 + break; 74 + } 75 + } 76 + 77 + void zpci_event_error(void *data) 78 + { 79 + struct zpci_ccdf_err *ccdf = data; 80 + struct zpci_dev *zdev; 81 + 82 + zpci_event_log_err(ccdf); 83 + zdev = get_zdev_by_fid(ccdf->fid); 84 + if (!zdev) { 85 + pr_err("Error event for unknown fid: %x", ccdf->fid); 86 + return; 87 + } 88 + } 89 + 90 + void zpci_event_availability(void *data) 91 + { 92 + zpci_event_log_avail(data); 93 + }
+141
arch/s390/pci/pci_msi.c
··· 1 + /* 2 + * Copyright IBM Corp. 2012 3 + * 4 + * Author(s): 5 + * Jan Glauber <jang@linux.vnet.ibm.com> 6 + */ 7 + 8 + #define COMPONENT "zPCI" 9 + #define pr_fmt(fmt) COMPONENT ": " fmt 10 + 11 + #include <linux/kernel.h> 12 + #include <linux/err.h> 13 + #include <linux/rculist.h> 14 + #include <linux/hash.h> 15 + #include <linux/pci.h> 16 + #include <linux/msi.h> 17 + #include <asm/hw_irq.h> 18 + 19 + /* mapping of irq numbers to msi_desc */ 20 + static struct hlist_head *msi_hash; 21 + static unsigned int msihash_shift = 6; 22 + #define msi_hashfn(nr) hash_long(nr, msihash_shift) 23 + 24 + static DEFINE_SPINLOCK(msi_map_lock); 25 + 26 + struct msi_desc *__irq_get_msi_desc(unsigned int irq) 27 + { 28 + struct hlist_node *entry; 29 + struct msi_map *map; 30 + 31 + hlist_for_each_entry_rcu(map, entry, 32 + &msi_hash[msi_hashfn(irq)], msi_chain) 33 + if (map->irq == irq) 34 + return map->msi; 35 + return NULL; 36 + } 37 + 38 + int zpci_msi_set_mask_bits(struct msi_desc *msi, u32 mask, u32 flag) 39 + { 40 + if (msi->msi_attrib.is_msix) { 41 + int offset = msi->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + 42 + PCI_MSIX_ENTRY_VECTOR_CTRL; 43 + msi->masked = readl(msi->mask_base + offset); 44 + writel(flag, msi->mask_base + offset); 45 + } else { 46 + if (msi->msi_attrib.maskbit) { 47 + int pos; 48 + u32 mask_bits; 49 + 50 + pos = (long) msi->mask_base; 51 + pci_read_config_dword(msi->dev, pos, &mask_bits); 52 + mask_bits &= ~(mask); 53 + mask_bits |= flag & mask; 54 + pci_write_config_dword(msi->dev, pos, mask_bits); 55 + } else { 56 + return 0; 57 + } 58 + } 59 + 60 + msi->msi_attrib.maskbit = !!flag; 61 + return 1; 62 + } 63 + 64 + int zpci_setup_msi_irq(struct zpci_dev *zdev, struct msi_desc *msi, 65 + unsigned int nr, int offset) 66 + { 67 + struct msi_map *map; 68 + struct msi_msg msg; 69 + int rc; 70 + 71 + map = kmalloc(sizeof(*map), GFP_KERNEL); 72 + if (map == NULL) 73 + return -ENOMEM; 74 + 75 + map->irq = nr; 76 + map->msi = msi; 77 + zdev->msi_map[nr & ZPCI_MSI_MASK] = map; 78 + 79 + pr_debug("%s hashing irq: %u to bucket nr: %llu\n", 80 + __func__, nr, msi_hashfn(nr)); 81 + hlist_add_head_rcu(&map->msi_chain, &msi_hash[msi_hashfn(nr)]); 82 + 83 + spin_lock(&msi_map_lock); 84 + rc = irq_set_msi_desc(nr, msi); 85 + if (rc) { 86 + spin_unlock(&msi_map_lock); 87 + hlist_del_rcu(&map->msi_chain); 88 + kfree(map); 89 + zdev->msi_map[nr & ZPCI_MSI_MASK] = NULL; 90 + return rc; 91 + } 92 + spin_unlock(&msi_map_lock); 93 + 94 + msg.data = nr - offset; 95 + msg.address_lo = zdev->msi_addr & 0xffffffff; 96 + msg.address_hi = zdev->msi_addr >> 32; 97 + write_msi_msg(nr, &msg); 98 + return 0; 99 + } 100 + 101 + void zpci_teardown_msi_irq(struct zpci_dev *zdev, struct msi_desc *msi) 102 + { 103 + int irq = msi->irq & ZPCI_MSI_MASK; 104 + struct msi_map *map; 105 + 106 + msi->msg.address_lo = 0; 107 + msi->msg.address_hi = 0; 108 + msi->msg.data = 0; 109 + msi->irq = 0; 110 + zpci_msi_set_mask_bits(msi, 1, 1); 111 + 112 + spin_lock(&msi_map_lock); 113 + map = zdev->msi_map[irq]; 114 + hlist_del_rcu(&map->msi_chain); 115 + kfree(map); 116 + zdev->msi_map[irq] = NULL; 117 + spin_unlock(&msi_map_lock); 118 + } 119 + 120 + /* 121 + * The msi hash table has 256 entries which is good for 4..20 122 + * devices (a typical device allocates 10 + CPUs MSI's). Maybe make 123 + * the hash table size adjustable later. 124 + */ 125 + int __init zpci_msihash_init(void) 126 + { 127 + unsigned int i; 128 + 129 + msi_hash = kmalloc(256 * sizeof(*msi_hash), GFP_KERNEL); 130 + if (!msi_hash) 131 + return -ENOMEM; 132 + 133 + for (i = 0; i < (1U << msihash_shift); i++) 134 + INIT_HLIST_HEAD(&msi_hash[i]); 135 + return 0; 136 + } 137 + 138 + void __init zpci_msihash_exit(void) 139 + { 140 + kfree(msi_hash); 141 + }
+86
arch/s390/pci/pci_sysfs.c
··· 1 + /* 2 + * Copyright IBM Corp. 2012 3 + * 4 + * Author(s): 5 + * Jan Glauber <jang@linux.vnet.ibm.com> 6 + */ 7 + 8 + #define COMPONENT "zPCI" 9 + #define pr_fmt(fmt) COMPONENT ": " fmt 10 + 11 + #include <linux/kernel.h> 12 + #include <linux/stat.h> 13 + #include <linux/pci.h> 14 + 15 + static ssize_t show_fid(struct device *dev, struct device_attribute *attr, 16 + char *buf) 17 + { 18 + struct zpci_dev *zdev = get_zdev(container_of(dev, struct pci_dev, dev)); 19 + 20 + sprintf(buf, "0x%08x\n", zdev->fid); 21 + return strlen(buf); 22 + } 23 + static DEVICE_ATTR(function_id, S_IRUGO, show_fid, NULL); 24 + 25 + static ssize_t show_fh(struct device *dev, struct device_attribute *attr, 26 + char *buf) 27 + { 28 + struct zpci_dev *zdev = get_zdev(container_of(dev, struct pci_dev, dev)); 29 + 30 + sprintf(buf, "0x%08x\n", zdev->fh); 31 + return strlen(buf); 32 + } 33 + static DEVICE_ATTR(function_handle, S_IRUGO, show_fh, NULL); 34 + 35 + static ssize_t show_pchid(struct device *dev, struct device_attribute *attr, 36 + char *buf) 37 + { 38 + struct zpci_dev *zdev = get_zdev(container_of(dev, struct pci_dev, dev)); 39 + 40 + sprintf(buf, "0x%04x\n", zdev->pchid); 41 + return strlen(buf); 42 + } 43 + static DEVICE_ATTR(pchid, S_IRUGO, show_pchid, NULL); 44 + 45 + static ssize_t show_pfgid(struct device *dev, struct device_attribute *attr, 46 + char *buf) 47 + { 48 + struct zpci_dev *zdev = get_zdev(container_of(dev, struct pci_dev, dev)); 49 + 50 + sprintf(buf, "0x%02x\n", zdev->pfgid); 51 + return strlen(buf); 52 + } 53 + static DEVICE_ATTR(pfgid, S_IRUGO, show_pfgid, NULL); 54 + 55 + static struct device_attribute *zpci_dev_attrs[] = { 56 + &dev_attr_function_id, 57 + &dev_attr_function_handle, 58 + &dev_attr_pchid, 59 + &dev_attr_pfgid, 60 + NULL, 61 + }; 62 + 63 + int zpci_sysfs_add_device(struct device *dev) 64 + { 65 + int i, rc = 0; 66 + 67 + for (i = 0; zpci_dev_attrs[i]; i++) { 68 + rc = device_create_file(dev, zpci_dev_attrs[i]); 69 + if (rc) 70 + goto error; 71 + } 72 + return 0; 73 + 74 + error: 75 + while (--i >= 0) 76 + device_remove_file(dev, zpci_dev_attrs[i]); 77 + return rc; 78 + } 79 + 80 + void zpci_sysfs_remove_device(struct device *dev) 81 + { 82 + int i; 83 + 84 + for (i = 0; zpci_dev_attrs[i]; i++) 85 + device_remove_file(dev, zpci_dev_attrs[i]); 86 + }
+1 -1
drivers/gpu/vga/Kconfig
··· 1 1 config VGA_ARB 2 2 bool "VGA Arbitration" if EXPERT 3 3 default y 4 - depends on PCI 4 + depends on (PCI && !S390) 5 5 help 6 6 Some "legacy" VGA devices implemented on PCI typically have the same 7 7 hard-decoded addresses as they did on ISA. When multiple PCI devices
+11
drivers/pci/hotplug/Kconfig
··· 151 151 152 152 When in doubt, say N. 153 153 154 + config HOTPLUG_PCI_S390 155 + tristate "System z PCI Hotplug Support" 156 + depends on S390 && 64BIT 157 + help 158 + Say Y here if you want to use the System z PCI Hotplug 159 + driver for PCI devices. Without this driver it is not 160 + possible to access stand-by PCI functions nor to deconfigure 161 + PCI functions. 162 + 163 + When in doubt, say Y. 164 + 154 165 endif # HOTPLUG_PCI
+1
drivers/pci/hotplug/Makefile
··· 18 18 obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR) += rpadlpar_io.o 19 19 obj-$(CONFIG_HOTPLUG_PCI_SGI) += sgi_hotplug.o 20 20 obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o 21 + obj-$(CONFIG_HOTPLUG_PCI_S390) += s390_pci_hpc.o 21 22 22 23 # acpiphp_ibm extends acpiphp, so should be linked afterwards. 23 24
+252
drivers/pci/hotplug/s390_pci_hpc.c
··· 1 + /* 2 + * PCI Hot Plug Controller Driver for System z 3 + * 4 + * Copyright 2012 IBM Corp. 5 + * 6 + * Author(s): 7 + * Jan Glauber <jang@linux.vnet.ibm.com> 8 + */ 9 + 10 + #define COMPONENT "zPCI hpc" 11 + #define pr_fmt(fmt) COMPONENT ": " fmt 12 + 13 + #include <linux/module.h> 14 + #include <linux/kernel.h> 15 + #include <linux/slab.h> 16 + #include <linux/pci.h> 17 + #include <linux/pci_hotplug.h> 18 + #include <linux/init.h> 19 + #include <asm/sclp.h> 20 + 21 + #define SLOT_NAME_SIZE 10 22 + static LIST_HEAD(s390_hotplug_slot_list); 23 + 24 + MODULE_AUTHOR("Jan Glauber <jang@linux.vnet.ibm.com"); 25 + MODULE_DESCRIPTION("Hot Plug PCI Controller for System z"); 26 + MODULE_LICENSE("GPL"); 27 + 28 + static int zpci_fn_configured(enum zpci_state state) 29 + { 30 + return state == ZPCI_FN_STATE_CONFIGURED || 31 + state == ZPCI_FN_STATE_ONLINE; 32 + } 33 + 34 + /* 35 + * struct slot - slot information for each *physical* slot 36 + */ 37 + struct slot { 38 + struct list_head slot_list; 39 + struct hotplug_slot *hotplug_slot; 40 + struct zpci_dev *zdev; 41 + }; 42 + 43 + static int enable_slot(struct hotplug_slot *hotplug_slot) 44 + { 45 + struct slot *slot = hotplug_slot->private; 46 + int rc; 47 + 48 + if (slot->zdev->state != ZPCI_FN_STATE_STANDBY) 49 + return -EIO; 50 + 51 + rc = sclp_pci_configure(slot->zdev->fid); 52 + if (!rc) { 53 + slot->zdev->state = ZPCI_FN_STATE_CONFIGURED; 54 + /* automatically scan the device after is was configured */ 55 + zpci_enable_device(slot->zdev); 56 + zpci_scan_device(slot->zdev); 57 + } 58 + return rc; 59 + } 60 + 61 + static int disable_slot(struct hotplug_slot *hotplug_slot) 62 + { 63 + struct slot *slot = hotplug_slot->private; 64 + int rc; 65 + 66 + if (!zpci_fn_configured(slot->zdev->state)) 67 + return -EIO; 68 + 69 + /* TODO: we rely on the user to unbind/remove the device, is that plausible 70 + * or do we need to trigger that here? 71 + */ 72 + rc = sclp_pci_deconfigure(slot->zdev->fid); 73 + if (!rc) { 74 + /* Fixme: better call List-PCI to find the disabled FH 75 + for the FID since the FH should be opaque... */ 76 + slot->zdev->fh &= 0x7fffffff; 77 + slot->zdev->state = ZPCI_FN_STATE_STANDBY; 78 + } 79 + return rc; 80 + } 81 + 82 + static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) 83 + { 84 + struct slot *slot = hotplug_slot->private; 85 + 86 + switch (slot->zdev->state) { 87 + case ZPCI_FN_STATE_STANDBY: 88 + *value = 0; 89 + break; 90 + default: 91 + *value = 1; 92 + break; 93 + } 94 + return 0; 95 + } 96 + 97 + static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) 98 + { 99 + /* if the slot exits it always contains a function */ 100 + *value = 1; 101 + return 0; 102 + } 103 + 104 + static void release_slot(struct hotplug_slot *hotplug_slot) 105 + { 106 + struct slot *slot = hotplug_slot->private; 107 + 108 + pr_debug("%s - physical_slot = %s\n", __func__, hotplug_slot_name(hotplug_slot)); 109 + kfree(slot->hotplug_slot->info); 110 + kfree(slot->hotplug_slot); 111 + kfree(slot); 112 + } 113 + 114 + static struct hotplug_slot_ops s390_hotplug_slot_ops = { 115 + .enable_slot = enable_slot, 116 + .disable_slot = disable_slot, 117 + .get_power_status = get_power_status, 118 + .get_adapter_status = get_adapter_status, 119 + }; 120 + 121 + static int init_pci_slot(struct zpci_dev *zdev) 122 + { 123 + struct hotplug_slot *hotplug_slot; 124 + struct hotplug_slot_info *info; 125 + char name[SLOT_NAME_SIZE]; 126 + struct slot *slot; 127 + int rc; 128 + 129 + if (!zdev) 130 + return 0; 131 + 132 + slot = kzalloc(sizeof(*slot), GFP_KERNEL); 133 + if (!slot) 134 + goto error; 135 + 136 + hotplug_slot = kzalloc(sizeof(*hotplug_slot), GFP_KERNEL); 137 + if (!hotplug_slot) 138 + goto error_hp; 139 + hotplug_slot->private = slot; 140 + 141 + slot->hotplug_slot = hotplug_slot; 142 + slot->zdev = zdev; 143 + 144 + info = kzalloc(sizeof(*info), GFP_KERNEL); 145 + if (!info) 146 + goto error_info; 147 + hotplug_slot->info = info; 148 + 149 + hotplug_slot->ops = &s390_hotplug_slot_ops; 150 + hotplug_slot->release = &release_slot; 151 + 152 + get_power_status(hotplug_slot, &info->power_status); 153 + get_adapter_status(hotplug_slot, &info->adapter_status); 154 + 155 + snprintf(name, SLOT_NAME_SIZE, "%08x", zdev->fid); 156 + rc = pci_hp_register(slot->hotplug_slot, zdev->bus, 157 + ZPCI_DEVFN, name); 158 + if (rc) { 159 + pr_err("pci_hp_register failed with error %d\n", rc); 160 + goto error_reg; 161 + } 162 + list_add(&slot->slot_list, &s390_hotplug_slot_list); 163 + return 0; 164 + 165 + error_reg: 166 + kfree(info); 167 + error_info: 168 + kfree(hotplug_slot); 169 + error_hp: 170 + kfree(slot); 171 + error: 172 + return -ENOMEM; 173 + } 174 + 175 + static int __init init_pci_slots(void) 176 + { 177 + struct zpci_dev *zdev; 178 + int device = 0; 179 + 180 + /* 181 + * Create a structure for each slot, and register that slot 182 + * with the pci_hotplug subsystem. 183 + */ 184 + mutex_lock(&zpci_list_lock); 185 + list_for_each_entry(zdev, &zpci_list, entry) { 186 + init_pci_slot(zdev); 187 + device++; 188 + } 189 + 190 + mutex_unlock(&zpci_list_lock); 191 + return (device) ? 0 : -ENODEV; 192 + } 193 + 194 + static void exit_pci_slot(struct zpci_dev *zdev) 195 + { 196 + struct list_head *tmp, *n; 197 + struct slot *slot; 198 + 199 + list_for_each_safe(tmp, n, &s390_hotplug_slot_list) { 200 + slot = list_entry(tmp, struct slot, slot_list); 201 + if (slot->zdev != zdev) 202 + continue; 203 + list_del(&slot->slot_list); 204 + pci_hp_deregister(slot->hotplug_slot); 205 + } 206 + } 207 + 208 + static void __exit exit_pci_slots(void) 209 + { 210 + struct list_head *tmp, *n; 211 + struct slot *slot; 212 + 213 + /* 214 + * Unregister all of our slots with the pci_hotplug subsystem. 215 + * Memory will be freed in release_slot() callback after slot's 216 + * lifespan is finished. 217 + */ 218 + list_for_each_safe(tmp, n, &s390_hotplug_slot_list) { 219 + slot = list_entry(tmp, struct slot, slot_list); 220 + list_del(&slot->slot_list); 221 + pci_hp_deregister(slot->hotplug_slot); 222 + } 223 + } 224 + 225 + static int __init pci_hotplug_s390_init(void) 226 + { 227 + /* 228 + * Do specific initialization stuff for your driver here 229 + * like initializing your controller hardware (if any) and 230 + * determining the number of slots you have in the system 231 + * right now. 232 + */ 233 + 234 + if (!pci_probe) 235 + return -EOPNOTSUPP; 236 + 237 + /* register callbacks for slot handling from arch code */ 238 + mutex_lock(&zpci_list_lock); 239 + hotplug_ops.create_slot = init_pci_slot; 240 + hotplug_ops.remove_slot = exit_pci_slot; 241 + mutex_unlock(&zpci_list_lock); 242 + pr_info("registered hotplug slot callbacks\n"); 243 + return init_pci_slots(); 244 + } 245 + 246 + static void __exit pci_hotplug_s390_exit(void) 247 + { 248 + exit_pci_slots(); 249 + } 250 + 251 + module_init(pci_hotplug_s390_init); 252 + module_exit(pci_hotplug_s390_exit);
+6
drivers/pci/msi.c
··· 207 207 desc->masked = __msix_mask_irq(desc, flag); 208 208 } 209 209 210 + #ifdef CONFIG_GENERIC_HARDIRQS 211 + 210 212 static void msi_set_mask_bit(struct irq_data *data, u32 flag) 211 213 { 212 214 struct msi_desc *desc = irq_data_get_msi(data); ··· 231 229 { 232 230 msi_set_mask_bit(data, 0); 233 231 } 232 + 233 + #endif /* CONFIG_GENERIC_HARDIRQS */ 234 234 235 235 void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg) 236 236 { ··· 341 337 if (!entry->irq) 342 338 continue; 343 339 nvec = 1 << entry->msi_attrib.multiple; 340 + #ifdef CONFIG_GENERIC_HARDIRQS 344 341 for (i = 0; i < nvec; i++) 345 342 BUG_ON(irq_has_action(entry->irq + i)); 343 + #endif 346 344 } 347 345 348 346 arch_teardown_msi_irqs(dev);
+80 -17
drivers/s390/block/dasd.c
··· 349 349 return rc; 350 350 } 351 351 352 + static inline 353 + int _wait_for_empty_queues(struct dasd_device *device) 354 + { 355 + if (device->block) 356 + return list_empty(&device->ccw_queue) && 357 + list_empty(&device->block->ccw_queue); 358 + else 359 + return list_empty(&device->ccw_queue); 360 + } 361 + 352 362 /* 353 363 * Remove device from block device layer. Destroy dirty buffers. 354 364 * Forget format information. Check if the target level is basic ··· 1851 1841 cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, devlist); 1852 1842 if ((cqr->status == DASD_CQR_IN_IO && cqr->expires != 0) && 1853 1843 (time_after_eq(jiffies, cqr->expires + cqr->starttime))) { 1844 + if (test_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) { 1845 + /* 1846 + * IO in safe offline processing should not 1847 + * run out of retries 1848 + */ 1849 + cqr->retries++; 1850 + } 1854 1851 if (device->discipline->term_IO(cqr) != 0) { 1855 1852 /* Hmpf, try again in 5 sec */ 1856 1853 dev_err(&device->cdev->dev, ··· 3041 3024 3042 3025 cdev->handler = NULL; 3043 3026 3044 - dasd_remove_sysfs_files(cdev); 3045 3027 device = dasd_device_from_cdev(cdev); 3046 3028 if (IS_ERR(device)) 3047 3029 return; 3048 - if (test_and_set_bit(DASD_FLAG_OFFLINE, &device->flags)) { 3030 + if (test_and_set_bit(DASD_FLAG_OFFLINE, &device->flags) && 3031 + !test_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) { 3049 3032 /* Already doing offline processing */ 3050 3033 dasd_put_device(device); 3051 3034 return; ··· 3065 3048 */ 3066 3049 if (block) 3067 3050 dasd_free_block(block); 3051 + 3052 + dasd_remove_sysfs_files(cdev); 3068 3053 } 3069 3054 3070 3055 /* ··· 3145 3126 { 3146 3127 struct dasd_device *device; 3147 3128 struct dasd_block *block; 3148 - int max_count, open_count; 3129 + int max_count, open_count, rc; 3149 3130 3131 + rc = 0; 3150 3132 device = dasd_device_from_cdev(cdev); 3151 3133 if (IS_ERR(device)) 3152 3134 return PTR_ERR(device); 3153 - if (test_and_set_bit(DASD_FLAG_OFFLINE, &device->flags)) { 3154 - /* Already doing offline processing */ 3155 - dasd_put_device(device); 3156 - return 0; 3157 - } 3135 + 3158 3136 /* 3159 3137 * We must make sure that this device is currently not in use. 3160 3138 * The open_count is increased for every opener, that includes ··· 3175 3159 return -EBUSY; 3176 3160 } 3177 3161 } 3162 + 3163 + if (test_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) { 3164 + /* 3165 + * safe offline allready running 3166 + * could only be called by normal offline so safe_offline flag 3167 + * needs to be removed to run normal offline and kill all I/O 3168 + */ 3169 + if (test_and_set_bit(DASD_FLAG_OFFLINE, &device->flags)) { 3170 + /* Already doing normal offline processing */ 3171 + dasd_put_device(device); 3172 + return -EBUSY; 3173 + } else 3174 + clear_bit(DASD_FLAG_SAFE_OFFLINE, &device->flags); 3175 + 3176 + } else 3177 + if (test_bit(DASD_FLAG_OFFLINE, &device->flags)) { 3178 + /* Already doing offline processing */ 3179 + dasd_put_device(device); 3180 + return -EBUSY; 3181 + } 3182 + 3183 + /* 3184 + * if safe_offline called set safe_offline_running flag and 3185 + * clear safe_offline so that a call to normal offline 3186 + * can overrun safe_offline processing 3187 + */ 3188 + if (test_and_clear_bit(DASD_FLAG_SAFE_OFFLINE, &device->flags) && 3189 + !test_and_set_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) { 3190 + /* 3191 + * If we want to set the device safe offline all IO operations 3192 + * should be finished before continuing the offline process 3193 + * so sync bdev first and then wait for our queues to become 3194 + * empty 3195 + */ 3196 + /* sync blockdev and partitions */ 3197 + rc = fsync_bdev(device->block->bdev); 3198 + if (rc != 0) 3199 + goto interrupted; 3200 + 3201 + /* schedule device tasklet and wait for completion */ 3202 + dasd_schedule_device_bh(device); 3203 + rc = wait_event_interruptible(shutdown_waitq, 3204 + _wait_for_empty_queues(device)); 3205 + if (rc != 0) 3206 + goto interrupted; 3207 + } 3208 + 3209 + set_bit(DASD_FLAG_OFFLINE, &device->flags); 3178 3210 dasd_set_target_state(device, DASD_STATE_NEW); 3179 3211 /* dasd_delete_device destroys the device reference. */ 3180 3212 block = device->block; ··· 3234 3170 if (block) 3235 3171 dasd_free_block(block); 3236 3172 return 0; 3173 + 3174 + interrupted: 3175 + /* interrupted by signal */ 3176 + clear_bit(DASD_FLAG_SAFE_OFFLINE, &device->flags); 3177 + clear_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags); 3178 + clear_bit(DASD_FLAG_OFFLINE, &device->flags); 3179 + dasd_put_device(device); 3180 + return rc; 3237 3181 } 3238 3182 3239 3183 int dasd_generic_last_path_gone(struct dasd_device *device) ··· 3560 3488 return sense; 3561 3489 } 3562 3490 EXPORT_SYMBOL_GPL(dasd_get_sense); 3563 - 3564 - static inline int _wait_for_empty_queues(struct dasd_device *device) 3565 - { 3566 - if (device->block) 3567 - return list_empty(&device->ccw_queue) && 3568 - list_empty(&device->block->ccw_queue); 3569 - else 3570 - return list_empty(&device->ccw_queue); 3571 - } 3572 3491 3573 3492 void dasd_generic_shutdown(struct ccw_device *cdev) 3574 3493 {
+34
drivers/s390/block/dasd_devmap.c
··· 952 952 dasd_use_raw_store); 953 953 954 954 static ssize_t 955 + dasd_safe_offline_store(struct device *dev, struct device_attribute *attr, 956 + const char *buf, size_t count) 957 + { 958 + struct ccw_device *cdev = to_ccwdev(dev); 959 + struct dasd_device *device; 960 + int rc; 961 + 962 + device = dasd_device_from_cdev(cdev); 963 + if (IS_ERR(device)) { 964 + rc = PTR_ERR(device); 965 + goto out; 966 + } 967 + 968 + if (test_bit(DASD_FLAG_OFFLINE, &device->flags) || 969 + test_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) { 970 + /* Already doing offline processing */ 971 + dasd_put_device(device); 972 + rc = -EBUSY; 973 + goto out; 974 + } 975 + 976 + set_bit(DASD_FLAG_SAFE_OFFLINE, &device->flags); 977 + dasd_put_device(device); 978 + 979 + rc = ccw_device_set_offline(cdev); 980 + 981 + out: 982 + return rc ? rc : count; 983 + } 984 + 985 + static DEVICE_ATTR(safe_offline, 0200, NULL, dasd_safe_offline_store); 986 + 987 + static ssize_t 955 988 dasd_discipline_show(struct device *dev, struct device_attribute *attr, 956 989 char *buf) 957 990 { ··· 1353 1320 &dev_attr_expires.attr, 1354 1321 &dev_attr_reservation_policy.attr, 1355 1322 &dev_attr_last_known_reservation_state.attr, 1323 + &dev_attr_safe_offline.attr, 1356 1324 NULL, 1357 1325 }; 1358 1326
+44 -48
drivers/s390/block/dasd_eckd.c
··· 1026 1026 { 1027 1027 void *conf_data; 1028 1028 int conf_len, conf_data_saved; 1029 - int rc; 1029 + int rc, path_err; 1030 1030 __u8 lpm, opm; 1031 1031 struct dasd_eckd_private *private, path_private; 1032 1032 struct dasd_path *path_data; ··· 1037 1037 path_data = &device->path_data; 1038 1038 opm = ccw_device_get_path_mask(device->cdev); 1039 1039 conf_data_saved = 0; 1040 + path_err = 0; 1040 1041 /* get configuration data per operational path */ 1041 1042 for (lpm = 0x80; lpm; lpm>>= 1) { 1042 1043 if (!(lpm & opm)) ··· 1123 1122 "the same device, path %02X leads to " 1124 1123 "device %s instead of %s\n", lpm, 1125 1124 print_path_uid, print_device_uid); 1126 - return -EINVAL; 1125 + path_err = -EINVAL; 1126 + continue; 1127 1127 } 1128 1128 1129 1129 path_private.conf_data = NULL; ··· 1144 1142 kfree(conf_data); 1145 1143 } 1146 1144 1147 - return 0; 1145 + return path_err; 1148 1146 } 1149 1147 1150 1148 static int verify_fcx_max_data(struct dasd_device *device, __u8 lpm) ··· 3849 3847 3850 3848 len = 0; 3851 3849 while (from <= to) { 3852 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3850 + len += sprintf(page + len, PRINTK_HEADER 3853 3851 " CCW %p: %08X %08X DAT:", 3854 3852 from, ((int *) from)[0], ((int *) from)[1]); 3855 3853 ··· 3910 3908 return; 3911 3909 } 3912 3910 /* dump the sense data */ 3913 - len = sprintf(page, KERN_ERR PRINTK_HEADER 3911 + len = sprintf(page, PRINTK_HEADER 3914 3912 " I/O status report for device %s:\n", 3915 3913 dev_name(&device->cdev->dev)); 3916 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3914 + len += sprintf(page + len, PRINTK_HEADER 3917 3915 " in req: %p CC:%02X FC:%02X AC:%02X SC:%02X DS:%02X " 3918 3916 "CS:%02X RC:%d\n", 3919 3917 req, scsw_cc(&irb->scsw), scsw_fctl(&irb->scsw), 3920 3918 scsw_actl(&irb->scsw), scsw_stctl(&irb->scsw), 3921 3919 scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw), 3922 3920 req ? req->intrc : 0); 3923 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3921 + len += sprintf(page + len, PRINTK_HEADER 3924 3922 " device %s: Failing CCW: %p\n", 3925 3923 dev_name(&device->cdev->dev), 3926 3924 (void *) (addr_t) irb->scsw.cmd.cpa); 3927 3925 if (irb->esw.esw0.erw.cons) { 3928 3926 for (sl = 0; sl < 4; sl++) { 3929 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3927 + len += sprintf(page + len, PRINTK_HEADER 3930 3928 " Sense(hex) %2d-%2d:", 3931 3929 (8 * sl), ((8 * sl) + 7)); 3932 3930 ··· 3939 3937 3940 3938 if (irb->ecw[27] & DASD_SENSE_BIT_0) { 3941 3939 /* 24 Byte Sense Data */ 3942 - sprintf(page + len, KERN_ERR PRINTK_HEADER 3940 + sprintf(page + len, PRINTK_HEADER 3943 3941 " 24 Byte: %x MSG %x, " 3944 3942 "%s MSGb to SYSOP\n", 3945 3943 irb->ecw[7] >> 4, irb->ecw[7] & 0x0f, 3946 3944 irb->ecw[1] & 0x10 ? "" : "no"); 3947 3945 } else { 3948 3946 /* 32 Byte Sense Data */ 3949 - sprintf(page + len, KERN_ERR PRINTK_HEADER 3947 + sprintf(page + len, PRINTK_HEADER 3950 3948 " 32 Byte: Format: %x " 3951 3949 "Exception class %x\n", 3952 3950 irb->ecw[6] & 0x0f, irb->ecw[22] >> 4); 3953 3951 } 3954 3952 } else { 3955 - sprintf(page + len, KERN_ERR PRINTK_HEADER 3953 + sprintf(page + len, PRINTK_HEADER 3956 3954 " SORRY - NO VALID SENSE AVAILABLE\n"); 3957 3955 } 3958 - printk("%s", page); 3956 + printk(KERN_ERR "%s", page); 3959 3957 3960 3958 if (req) { 3961 3959 /* req == NULL for unsolicited interrupts */ ··· 3964 3962 first = req->cpaddr; 3965 3963 for (last = first; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++); 3966 3964 to = min(first + 6, last); 3967 - len = sprintf(page, KERN_ERR PRINTK_HEADER 3965 + len = sprintf(page, PRINTK_HEADER 3968 3966 " Related CP in req: %p\n", req); 3969 3967 dasd_eckd_dump_ccw_range(first, to, page + len); 3970 - printk("%s", page); 3968 + printk(KERN_ERR "%s", page); 3971 3969 3972 3970 /* print failing CCW area (maximum 4) */ 3973 3971 /* scsw->cda is either valid or zero */ ··· 3977 3975 irb->scsw.cmd.cpa; /* failing CCW */ 3978 3976 if (from < fail - 2) { 3979 3977 from = fail - 2; /* there is a gap - print header */ 3980 - len += sprintf(page, KERN_ERR PRINTK_HEADER "......\n"); 3978 + len += sprintf(page, PRINTK_HEADER "......\n"); 3981 3979 } 3982 3980 to = min(fail + 1, last); 3983 3981 len += dasd_eckd_dump_ccw_range(from, to, page + len); ··· 3986 3984 from = max(from, ++to); 3987 3985 if (from < last - 1) { 3988 3986 from = last - 1; /* there is a gap - print header */ 3989 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); 3987 + len += sprintf(page + len, PRINTK_HEADER "......\n"); 3990 3988 } 3991 3989 len += dasd_eckd_dump_ccw_range(from, last, page + len); 3992 3990 if (len > 0) 3993 - printk("%s", page); 3991 + printk(KERN_ERR "%s", page); 3994 3992 } 3995 3993 free_page((unsigned long) page); 3996 3994 } ··· 4014 4012 return; 4015 4013 } 4016 4014 /* dump the sense data */ 4017 - len = sprintf(page, KERN_ERR PRINTK_HEADER 4015 + len = sprintf(page, PRINTK_HEADER 4018 4016 " I/O status report for device %s:\n", 4019 4017 dev_name(&device->cdev->dev)); 4020 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4018 + len += sprintf(page + len, PRINTK_HEADER 4021 4019 " in req: %p CC:%02X FC:%02X AC:%02X SC:%02X DS:%02X " 4022 4020 "CS:%02X fcxs:%02X schxs:%02X RC:%d\n", 4023 4021 req, scsw_cc(&irb->scsw), scsw_fctl(&irb->scsw), ··· 4025 4023 scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw), 4026 4024 irb->scsw.tm.fcxs, irb->scsw.tm.schxs, 4027 4025 req ? req->intrc : 0); 4028 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4026 + len += sprintf(page + len, PRINTK_HEADER 4029 4027 " device %s: Failing TCW: %p\n", 4030 4028 dev_name(&device->cdev->dev), 4031 4029 (void *) (addr_t) irb->scsw.tm.tcw); ··· 4037 4035 (struct tcw *)(unsigned long)irb->scsw.tm.tcw); 4038 4036 4039 4037 if (tsb) { 4040 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4038 + len += sprintf(page + len, PRINTK_HEADER 4041 4039 " tsb->length %d\n", tsb->length); 4042 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4040 + len += sprintf(page + len, PRINTK_HEADER 4043 4041 " tsb->flags %x\n", tsb->flags); 4044 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4042 + len += sprintf(page + len, PRINTK_HEADER 4045 4043 " tsb->dcw_offset %d\n", tsb->dcw_offset); 4046 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4044 + len += sprintf(page + len, PRINTK_HEADER 4047 4045 " tsb->count %d\n", tsb->count); 4048 4046 residual = tsb->count - 28; 4049 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4047 + len += sprintf(page + len, PRINTK_HEADER 4050 4048 " residual %d\n", residual); 4051 4049 4052 4050 switch (tsb->flags & 0x07) { 4053 4051 case 1: /* tsa_iostat */ 4054 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4052 + len += sprintf(page + len, PRINTK_HEADER 4055 4053 " tsb->tsa.iostat.dev_time %d\n", 4056 4054 tsb->tsa.iostat.dev_time); 4057 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4055 + len += sprintf(page + len, PRINTK_HEADER 4058 4056 " tsb->tsa.iostat.def_time %d\n", 4059 4057 tsb->tsa.iostat.def_time); 4060 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4058 + len += sprintf(page + len, PRINTK_HEADER 4061 4059 " tsb->tsa.iostat.queue_time %d\n", 4062 4060 tsb->tsa.iostat.queue_time); 4063 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4061 + len += sprintf(page + len, PRINTK_HEADER 4064 4062 " tsb->tsa.iostat.dev_busy_time %d\n", 4065 4063 tsb->tsa.iostat.dev_busy_time); 4066 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4064 + len += sprintf(page + len, PRINTK_HEADER 4067 4065 " tsb->tsa.iostat.dev_act_time %d\n", 4068 4066 tsb->tsa.iostat.dev_act_time); 4069 4067 sense = tsb->tsa.iostat.sense; 4070 4068 break; 4071 4069 case 2: /* ts_ddpc */ 4072 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4070 + len += sprintf(page + len, PRINTK_HEADER 4073 4071 " tsb->tsa.ddpc.rc %d\n", tsb->tsa.ddpc.rc); 4074 4072 for (sl = 0; sl < 2; sl++) { 4075 - len += sprintf(page + len, 4076 - KERN_ERR PRINTK_HEADER 4073 + len += sprintf(page + len, PRINTK_HEADER 4077 4074 " tsb->tsa.ddpc.rcq %2d-%2d: ", 4078 4075 (8 * sl), ((8 * sl) + 7)); 4079 4076 rcq = tsb->tsa.ddpc.rcq; ··· 4085 4084 sense = tsb->tsa.ddpc.sense; 4086 4085 break; 4087 4086 case 3: /* tsa_intrg */ 4088 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4089 - " tsb->tsa.intrg.: not supportet yet \n"); 4087 + len += sprintf(page + len, PRINTK_HEADER 4088 + " tsb->tsa.intrg.: not supportet yet\n"); 4090 4089 break; 4091 4090 } 4092 4091 4093 4092 if (sense) { 4094 4093 for (sl = 0; sl < 4; sl++) { 4095 - len += sprintf(page + len, 4096 - KERN_ERR PRINTK_HEADER 4094 + len += sprintf(page + len, PRINTK_HEADER 4097 4095 " Sense(hex) %2d-%2d:", 4098 4096 (8 * sl), ((8 * sl) + 7)); 4099 4097 for (sct = 0; sct < 8; sct++) { ··· 4104 4104 4105 4105 if (sense[27] & DASD_SENSE_BIT_0) { 4106 4106 /* 24 Byte Sense Data */ 4107 - sprintf(page + len, KERN_ERR PRINTK_HEADER 4107 + sprintf(page + len, PRINTK_HEADER 4108 4108 " 24 Byte: %x MSG %x, " 4109 4109 "%s MSGb to SYSOP\n", 4110 4110 sense[7] >> 4, sense[7] & 0x0f, 4111 4111 sense[1] & 0x10 ? "" : "no"); 4112 4112 } else { 4113 4113 /* 32 Byte Sense Data */ 4114 - sprintf(page + len, KERN_ERR PRINTK_HEADER 4114 + sprintf(page + len, PRINTK_HEADER 4115 4115 " 32 Byte: Format: %x " 4116 4116 "Exception class %x\n", 4117 4117 sense[6] & 0x0f, sense[22] >> 4); 4118 4118 } 4119 4119 } else { 4120 - sprintf(page + len, KERN_ERR PRINTK_HEADER 4120 + sprintf(page + len, PRINTK_HEADER 4121 4121 " SORRY - NO VALID SENSE AVAILABLE\n"); 4122 4122 } 4123 4123 } else { 4124 - sprintf(page + len, KERN_ERR PRINTK_HEADER 4124 + sprintf(page + len, PRINTK_HEADER 4125 4125 " SORRY - NO TSB DATA AVAILABLE\n"); 4126 4126 } 4127 - printk("%s", page); 4127 + printk(KERN_ERR "%s", page); 4128 4128 free_page((unsigned long) page); 4129 4129 } 4130 4130 ··· 4161 4161 private = (struct dasd_eckd_private *) device->private; 4162 4162 4163 4163 /* Read Configuration Data */ 4164 - rc = dasd_eckd_read_conf(device); 4165 - if (rc) 4166 - goto out_err; 4164 + dasd_eckd_read_conf(device); 4167 4165 4168 4166 dasd_eckd_get_uid(device, &temp_uid); 4169 4167 /* Generate device unique id */ ··· 4181 4183 dasd_eckd_validate_server(device, DASD_CQR_FLAGS_FAILFAST); 4182 4184 4183 4185 /* RE-Read Configuration Data */ 4184 - rc = dasd_eckd_read_conf(device); 4185 - if (rc) 4186 - goto out_err; 4186 + dasd_eckd_read_conf(device); 4187 4187 4188 4188 /* Read Feature Codes */ 4189 4189 dasd_eckd_read_features(device);
+11 -12
drivers/s390/block/dasd_fba.c
··· 479 479 "No memory to dump sense data"); 480 480 return; 481 481 } 482 - len = sprintf(page, KERN_ERR PRINTK_HEADER 482 + len = sprintf(page, PRINTK_HEADER 483 483 " I/O status report for device %s:\n", 484 484 dev_name(&device->cdev->dev)); 485 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 485 + len += sprintf(page + len, PRINTK_HEADER 486 486 " in req: %p CS: 0x%02X DS: 0x%02X\n", req, 487 487 irb->scsw.cmd.cstat, irb->scsw.cmd.dstat); 488 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 488 + len += sprintf(page + len, PRINTK_HEADER 489 489 " device %s: Failing CCW: %p\n", 490 490 dev_name(&device->cdev->dev), 491 491 (void *) (addr_t) irb->scsw.cmd.cpa); 492 492 if (irb->esw.esw0.erw.cons) { 493 493 for (sl = 0; sl < 4; sl++) { 494 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 494 + len += sprintf(page + len, PRINTK_HEADER 495 495 " Sense(hex) %2d-%2d:", 496 496 (8 * sl), ((8 * sl) + 7)); 497 497 ··· 502 502 len += sprintf(page + len, "\n"); 503 503 } 504 504 } else { 505 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 505 + len += sprintf(page + len, PRINTK_HEADER 506 506 " SORRY - NO VALID SENSE AVAILABLE\n"); 507 507 } 508 508 printk(KERN_ERR "%s", page); ··· 512 512 act = req->cpaddr; 513 513 for (last = act; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++); 514 514 end = min(act + 8, last); 515 - len = sprintf(page, KERN_ERR PRINTK_HEADER 516 - " Related CP in req: %p\n", req); 515 + len = sprintf(page, PRINTK_HEADER " Related CP in req: %p\n", req); 517 516 while (act <= end) { 518 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 517 + len += sprintf(page + len, PRINTK_HEADER 519 518 " CCW %p: %08X %08X DAT:", 520 519 act, ((int *) act)[0], ((int *) act)[1]); 521 520 for (count = 0; count < 32 && count < act->count; ··· 532 533 len = 0; 533 534 if (act < ((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa) - 2) { 534 535 act = ((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa) - 2; 535 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); 536 + len += sprintf(page + len, PRINTK_HEADER "......\n"); 536 537 } 537 538 end = min((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa + 2, last); 538 539 while (act <= end) { 539 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 540 + len += sprintf(page + len, PRINTK_HEADER 540 541 " CCW %p: %08X %08X DAT:", 541 542 act, ((int *) act)[0], ((int *) act)[1]); 542 543 for (count = 0; count < 32 && count < act->count; ··· 551 552 /* print last CCWs */ 552 553 if (act < last - 2) { 553 554 act = last - 2; 554 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); 555 + len += sprintf(page + len, PRINTK_HEADER "......\n"); 555 556 } 556 557 while (act <= last) { 557 - len += sprintf(page + len, KERN_ERR PRINTK_HEADER 558 + len += sprintf(page + len, PRINTK_HEADER 558 559 " CCW %p: %08X %08X DAT:", 559 560 act, ((int *) act)[0], ((int *) act)[1]); 560 561 for (count = 0; count < 32 && count < act->count;
+2
drivers/s390/block/dasd_int.h
··· 516 516 #define DASD_FLAG_IS_RESERVED 7 /* The device is reserved */ 517 517 #define DASD_FLAG_LOCK_STOLEN 8 /* The device lock was stolen */ 518 518 #define DASD_FLAG_SUSPENDED 9 /* The device was suspended */ 519 + #define DASD_FLAG_SAFE_OFFLINE 10 /* safe offline processing requested*/ 520 + #define DASD_FLAG_SAFE_OFFLINE_RUNNING 11 /* safe offline running */ 519 521 520 522 521 523 void dasd_put_device_wake(struct dasd_device *);
+7 -4
drivers/s390/block/dasd_ioctl.c
··· 19 19 #include <linux/slab.h> 20 20 #include <asm/compat.h> 21 21 #include <asm/ccwdev.h> 22 + #include <asm/schid.h> 22 23 #include <asm/cmb.h> 23 24 #include <asm/uaccess.h> 24 25 ··· 309 308 unsigned int cmd, void __user *argp) 310 309 { 311 310 struct dasd_information2_t *dasd_info; 312 - unsigned long flags; 313 - int rc; 311 + struct subchannel_id sch_id; 312 + struct ccw_dev_id dev_id; 314 313 struct dasd_device *base; 315 314 struct ccw_device *cdev; 316 - struct ccw_dev_id dev_id; 315 + unsigned long flags; 316 + int rc; 317 317 318 318 base = block->base; 319 319 if (!base->discipline || !base->discipline->fill_info) ··· 332 330 333 331 cdev = base->cdev; 334 332 ccw_device_get_id(cdev, &dev_id); 333 + ccw_device_get_schid(cdev, &sch_id); 335 334 336 335 dasd_info->devno = dev_id.devno; 337 - dasd_info->schid = _ccw_device_get_subchannel_number(base->cdev); 336 + dasd_info->schid = sch_id.sch_no; 338 337 dasd_info->cu_type = cdev->id.cu_type; 339 338 dasd_info->cu_model = cdev->id.cu_model; 340 339 dasd_info->dev_type = cdev->id.dev_type;
+2 -1
drivers/s390/char/sclp.h
··· 1 1 /* 2 - * Copyright IBM Corp. 1999, 2009 2 + * Copyright IBM Corp. 1999,2012 3 3 * 4 4 * Author(s): Martin Peschke <mpeschke@de.ibm.com> 5 5 * Martin Schwidefsky <schwidefsky@de.ibm.com> ··· 103 103 #define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL) 104 104 #define SCLP_HAS_CPU_INFO (sclp_facilities & 0x0800000000000000ULL) 105 105 #define SCLP_HAS_CPU_RECONFIG (sclp_facilities & 0x0400000000000000ULL) 106 + #define SCLP_HAS_PCI_RECONFIG (sclp_facilities & 0x0000000040000000ULL) 106 107 107 108 108 109 struct gds_subvector {
+72 -11
drivers/s390/char/sclp_cmd.c
··· 1 1 /* 2 - * Copyright IBM Corp. 2007, 2009 2 + * Copyright IBM Corp. 2007,2012 3 3 * 4 4 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>, 5 5 * Peter Oberparleiter <peter.oberparleiter@de.ibm.com> ··· 12 12 #include <linux/init.h> 13 13 #include <linux/errno.h> 14 14 #include <linux/err.h> 15 + #include <linux/export.h> 15 16 #include <linux/slab.h> 16 17 #include <linux/string.h> 17 18 #include <linux/mm.h> ··· 20 19 #include <linux/memory.h> 21 20 #include <linux/module.h> 22 21 #include <linux/platform_device.h> 23 - #include <asm/chpid.h> 24 - #include <asm/sclp.h> 25 - #include <asm/setup.h> 26 22 #include <asm/ctl_reg.h> 23 + #include <asm/chpid.h> 24 + #include <asm/setup.h> 25 + #include <asm/page.h> 26 + #include <asm/sclp.h> 27 27 28 28 #include "sclp.h" 29 29 ··· 402 400 403 401 static int sclp_assign_storage(u16 rn) 404 402 { 405 - unsigned long long start, address; 403 + unsigned long long start; 406 404 int rc; 407 405 408 406 rc = do_assign_storage(0x000d0001, rn); 409 407 if (rc) 410 - goto out; 411 - start = address = rn2addr(rn); 412 - for (; address < start + rzm; address += PAGE_SIZE) 413 - page_set_storage_key(address, PAGE_DEFAULT_KEY, 0); 414 - out: 415 - return rc; 408 + return rc; 409 + start = rn2addr(rn); 410 + storage_key_init_range(start, start + rzm); 411 + return 0; 416 412 } 417 413 418 414 static int sclp_unassign_storage(u16 rn) ··· 700 700 __initcall(sclp_detect_standby_memory); 701 701 702 702 #endif /* CONFIG_MEMORY_HOTPLUG */ 703 + 704 + /* 705 + * PCI I/O adapter configuration related functions. 706 + */ 707 + #define SCLP_CMDW_CONFIGURE_PCI 0x001a0001 708 + #define SCLP_CMDW_DECONFIGURE_PCI 0x001b0001 709 + 710 + #define SCLP_RECONFIG_PCI_ATPYE 2 711 + 712 + struct pci_cfg_sccb { 713 + struct sccb_header header; 714 + u8 atype; /* adapter type */ 715 + u8 reserved1; 716 + u16 reserved2; 717 + u32 aid; /* adapter identifier */ 718 + } __packed; 719 + 720 + static int do_pci_configure(sclp_cmdw_t cmd, u32 fid) 721 + { 722 + struct pci_cfg_sccb *sccb; 723 + int rc; 724 + 725 + if (!SCLP_HAS_PCI_RECONFIG) 726 + return -EOPNOTSUPP; 727 + 728 + sccb = (struct pci_cfg_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); 729 + if (!sccb) 730 + return -ENOMEM; 731 + 732 + sccb->header.length = PAGE_SIZE; 733 + sccb->atype = SCLP_RECONFIG_PCI_ATPYE; 734 + sccb->aid = fid; 735 + rc = do_sync_request(cmd, sccb); 736 + if (rc) 737 + goto out; 738 + switch (sccb->header.response_code) { 739 + case 0x0020: 740 + case 0x0120: 741 + break; 742 + default: 743 + pr_warn("configure PCI I/O adapter failed: cmd=0x%08x response=0x%04x\n", 744 + cmd, sccb->header.response_code); 745 + rc = -EIO; 746 + break; 747 + } 748 + out: 749 + free_page((unsigned long) sccb); 750 + return rc; 751 + } 752 + 753 + int sclp_pci_configure(u32 fid) 754 + { 755 + return do_pci_configure(SCLP_CMDW_CONFIGURE_PCI, fid); 756 + } 757 + EXPORT_SYMBOL(sclp_pci_configure); 758 + 759 + int sclp_pci_deconfigure(u32 fid) 760 + { 761 + return do_pci_configure(SCLP_CMDW_DECONFIGURE_PCI, fid); 762 + } 763 + EXPORT_SYMBOL(sclp_pci_deconfigure); 703 764 704 765 /* 705 766 * Channel path configuration related functions.
+22 -4
drivers/s390/cio/ccwgroup.c
··· 65 65 } 66 66 } 67 67 68 - static int ccwgroup_set_online(struct ccwgroup_device *gdev) 68 + /** 69 + * ccwgroup_set_online() - enable a ccwgroup device 70 + * @gdev: target ccwgroup device 71 + * 72 + * This function attempts to put the ccwgroup device into the online state. 73 + * Returns: 74 + * %0 on success and a negative error value on failure. 75 + */ 76 + int ccwgroup_set_online(struct ccwgroup_device *gdev) 69 77 { 70 78 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); 71 - int ret = 0; 79 + int ret = -EINVAL; 72 80 73 81 if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0) 74 82 return -EAGAIN; ··· 92 84 atomic_set(&gdev->onoff, 0); 93 85 return ret; 94 86 } 87 + EXPORT_SYMBOL(ccwgroup_set_online); 95 88 96 - static int ccwgroup_set_offline(struct ccwgroup_device *gdev) 89 + /** 90 + * ccwgroup_set_offline() - disable a ccwgroup device 91 + * @gdev: target ccwgroup device 92 + * 93 + * This function attempts to put the ccwgroup device into the offline state. 94 + * Returns: 95 + * %0 on success and a negative error value on failure. 96 + */ 97 + int ccwgroup_set_offline(struct ccwgroup_device *gdev) 97 98 { 98 99 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); 99 - int ret = 0; 100 + int ret = -EINVAL; 100 101 101 102 if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0) 102 103 return -EAGAIN; ··· 121 104 atomic_set(&gdev->onoff, 0); 122 105 return ret; 123 106 } 107 + EXPORT_SYMBOL(ccwgroup_set_offline); 124 108 125 109 static ssize_t ccwgroup_online_store(struct device *dev, 126 110 struct device_attribute *attr,
+111 -43
drivers/s390/cio/chsc.c
··· 1 1 /* 2 2 * S/390 common I/O routines -- channel subsystem call 3 3 * 4 - * Copyright IBM Corp. 1999, 2010 4 + * Copyright IBM Corp. 1999,2012 5 5 * Author(s): Ingo Adlung (adlung@de.ibm.com) 6 6 * Cornelia Huck (cornelia.huck@de.ibm.com) 7 7 * Arnd Bergmann (arndb@de.ibm.com) ··· 14 14 #include <linux/slab.h> 15 15 #include <linux/init.h> 16 16 #include <linux/device.h> 17 + #include <linux/pci.h> 17 18 18 19 #include <asm/cio.h> 19 20 #include <asm/chpid.h> ··· 261 260 return (u16) (lir->indesc[0]&0x000000ff); 262 261 } 263 262 264 - struct chsc_sei_area { 265 - struct chsc_header request; 263 + struct chsc_sei_nt0_area { 264 + u8 flags; 265 + u8 vf; /* validity flags */ 266 + u8 rs; /* reporting source */ 267 + u8 cc; /* content code */ 268 + u16 fla; /* full link address */ 269 + u16 rsid; /* reporting source id */ 266 270 u32 reserved1; 267 271 u32 reserved2; 268 - u32 reserved3; 269 - struct chsc_header response; 270 - u32 reserved4; 271 - u8 flags; 272 - u8 vf; /* validity flags */ 273 - u8 rs; /* reporting source */ 274 - u8 cc; /* content code */ 275 - u16 fla; /* full link address */ 276 - u16 rsid; /* reporting source id */ 277 - u32 reserved5; 278 - u32 reserved6; 279 - u8 ccdf[4096 - 16 - 24]; /* content-code dependent field */ 280 272 /* ccdf has to be big enough for a link-incident record */ 281 - } __attribute__ ((packed)); 273 + u8 ccdf[PAGE_SIZE - 24 - 16]; /* content-code dependent field */ 274 + } __packed; 282 275 283 - static void chsc_process_sei_link_incident(struct chsc_sei_area *sei_area) 276 + struct chsc_sei_nt2_area { 277 + u8 flags; /* p and v bit */ 278 + u8 reserved1; 279 + u8 reserved2; 280 + u8 cc; /* content code */ 281 + u32 reserved3[13]; 282 + u8 ccdf[PAGE_SIZE - 24 - 56]; /* content-code dependent field */ 283 + } __packed; 284 + 285 + #define CHSC_SEI_NT0 0ULL 286 + #define CHSC_SEI_NT2 (1ULL << 61) 287 + 288 + struct chsc_sei { 289 + struct chsc_header request; 290 + u32 reserved1; 291 + u64 ntsm; /* notification type mask */ 292 + struct chsc_header response; 293 + u32 reserved2; 294 + union { 295 + struct chsc_sei_nt0_area nt0_area; 296 + struct chsc_sei_nt2_area nt2_area; 297 + u8 nt_area[PAGE_SIZE - 24]; 298 + } u; 299 + } __packed; 300 + 301 + static void chsc_process_sei_link_incident(struct chsc_sei_nt0_area *sei_area) 284 302 { 285 303 struct chp_id chpid; 286 304 int id; ··· 318 298 } 319 299 } 320 300 321 - static void chsc_process_sei_res_acc(struct chsc_sei_area *sei_area) 301 + static void chsc_process_sei_res_acc(struct chsc_sei_nt0_area *sei_area) 322 302 { 323 303 struct chp_link link; 324 304 struct chp_id chpid; ··· 350 330 s390_process_res_acc(&link); 351 331 } 352 332 353 - static void chsc_process_sei_chp_avail(struct chsc_sei_area *sei_area) 333 + static void chsc_process_sei_chp_avail(struct chsc_sei_nt0_area *sei_area) 354 334 { 355 335 struct channel_path *chp; 356 336 struct chp_id chpid; ··· 386 366 u8 pc; 387 367 }; 388 368 389 - static void chsc_process_sei_chp_config(struct chsc_sei_area *sei_area) 369 + static void chsc_process_sei_chp_config(struct chsc_sei_nt0_area *sei_area) 390 370 { 391 371 struct chp_config_data *data; 392 372 struct chp_id chpid; ··· 418 398 } 419 399 } 420 400 421 - static void chsc_process_sei_scm_change(struct chsc_sei_area *sei_area) 401 + static void chsc_process_sei_scm_change(struct chsc_sei_nt0_area *sei_area) 422 402 { 423 403 int ret; 424 404 ··· 432 412 " failed (rc=%d).\n", ret); 433 413 } 434 414 435 - static void chsc_process_sei(struct chsc_sei_area *sei_area) 415 + static void chsc_process_sei_nt2(struct chsc_sei_nt2_area *sei_area) 436 416 { 437 - /* Check if we might have lost some information. */ 438 - if (sei_area->flags & 0x40) { 439 - CIO_CRW_EVENT(2, "chsc: event overflow\n"); 440 - css_schedule_eval_all(); 417 + #ifdef CONFIG_PCI 418 + switch (sei_area->cc) { 419 + case 1: 420 + zpci_event_error(sei_area->ccdf); 421 + break; 422 + case 2: 423 + zpci_event_availability(sei_area->ccdf); 424 + break; 425 + default: 426 + CIO_CRW_EVENT(2, "chsc: unhandled sei content code %d\n", 427 + sei_area->cc); 428 + break; 441 429 } 430 + #endif 431 + } 432 + 433 + static void chsc_process_sei_nt0(struct chsc_sei_nt0_area *sei_area) 434 + { 442 435 /* which kind of information was stored? */ 443 436 switch (sei_area->cc) { 444 437 case 1: /* link incident*/ ··· 476 443 } 477 444 } 478 445 446 + static int __chsc_process_crw(struct chsc_sei *sei, u64 ntsm) 447 + { 448 + do { 449 + memset(sei, 0, sizeof(*sei)); 450 + sei->request.length = 0x0010; 451 + sei->request.code = 0x000e; 452 + sei->ntsm = ntsm; 453 + 454 + if (chsc(sei)) 455 + break; 456 + 457 + if (sei->response.code == 0x0001) { 458 + CIO_CRW_EVENT(2, "chsc: sei successful\n"); 459 + 460 + /* Check if we might have lost some information. */ 461 + if (sei->u.nt0_area.flags & 0x40) { 462 + CIO_CRW_EVENT(2, "chsc: event overflow\n"); 463 + css_schedule_eval_all(); 464 + } 465 + 466 + switch (sei->ntsm) { 467 + case CHSC_SEI_NT0: 468 + chsc_process_sei_nt0(&sei->u.nt0_area); 469 + return 1; 470 + case CHSC_SEI_NT2: 471 + chsc_process_sei_nt2(&sei->u.nt2_area); 472 + return 1; 473 + default: 474 + CIO_CRW_EVENT(2, "chsc: unhandled nt (nt=%08Lx)\n", 475 + sei->ntsm); 476 + return 0; 477 + } 478 + } else { 479 + CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x)\n", 480 + sei->response.code); 481 + break; 482 + } 483 + } while (sei->u.nt0_area.flags & 0x80); 484 + 485 + return 0; 486 + } 487 + 479 488 static void chsc_process_crw(struct crw *crw0, struct crw *crw1, int overflow) 480 489 { 481 - struct chsc_sei_area *sei_area; 490 + struct chsc_sei *sei; 482 491 483 492 if (overflow) { 484 493 css_schedule_eval_all(); ··· 534 459 return; 535 460 /* Access to sei_page is serialized through machine check handler 536 461 * thread, so no need for locking. */ 537 - sei_area = sei_page; 462 + sei = sei_page; 538 463 539 464 CIO_TRACE_EVENT(2, "prcss"); 540 - do { 541 - memset(sei_area, 0, sizeof(*sei_area)); 542 - sei_area->request.length = 0x0010; 543 - sei_area->request.code = 0x000e; 544 - if (chsc(sei_area)) 545 - break; 546 465 547 - if (sei_area->response.code == 0x0001) { 548 - CIO_CRW_EVENT(4, "chsc: sei successful\n"); 549 - chsc_process_sei(sei_area); 550 - } else { 551 - CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x)\n", 552 - sei_area->response.code); 553 - break; 554 - } 555 - } while (sei_area->flags & 0x80); 466 + /* 467 + * The ntsm does not allow to select NT0 and NT2 together. We need to 468 + * first check for NT2, than additionally for NT0... 469 + */ 470 + #ifdef CONFIG_PCI 471 + if (!__chsc_process_crw(sei, CHSC_SEI_NT2)) 472 + #endif 473 + __chsc_process_crw(sei, CHSC_SEI_NT0); 556 474 } 557 475 558 476 void chsc_chp_online(struct chp_id chpid)
-11
drivers/s390/cio/device.c
··· 2036 2036 driver_unregister(&cdriver->driver); 2037 2037 } 2038 2038 2039 - /* Helper func for qdio. */ 2040 - struct subchannel_id 2041 - ccw_device_get_subchannel_id(struct ccw_device *cdev) 2042 - { 2043 - struct subchannel *sch; 2044 - 2045 - sch = to_subchannel(cdev->dev.parent); 2046 - return sch->schid; 2047 - } 2048 - 2049 2039 static void ccw_device_todo(struct work_struct *work) 2050 2040 { 2051 2041 struct ccw_device_private *priv; ··· 2128 2138 EXPORT_SYMBOL(ccw_driver_register); 2129 2139 EXPORT_SYMBOL(ccw_driver_unregister); 2130 2140 EXPORT_SYMBOL(get_ccwdev_by_busid); 2131 - EXPORT_SYMBOL_GPL(ccw_device_get_subchannel_id);
-2
drivers/s390/cio/device.h
··· 142 142 void ccw_device_set_disconnected(struct ccw_device *cdev); 143 143 void ccw_device_set_notoper(struct ccw_device *cdev); 144 144 145 - /* qdio needs this. */ 146 145 void ccw_device_set_timeout(struct ccw_device *, int); 147 - extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *); 148 146 149 147 /* Channel measurement facility related */ 150 148 void retry_set_schib(struct ccw_device *cdev);
+10 -7
drivers/s390/cio/device_ops.c
··· 755 755 } 756 756 EXPORT_SYMBOL(ccw_device_tm_intrg); 757 757 758 - // FIXME: these have to go: 759 - 760 - int 761 - _ccw_device_get_subchannel_number(struct ccw_device *cdev) 758 + /** 759 + * ccw_device_get_schid - obtain a subchannel id 760 + * @cdev: device to obtain the id for 761 + * @schid: where to fill in the values 762 + */ 763 + void ccw_device_get_schid(struct ccw_device *cdev, struct subchannel_id *schid) 762 764 { 763 - return cdev->private->schid.sch_no; 764 - } 765 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 765 766 767 + *schid = sch->schid; 768 + } 769 + EXPORT_SYMBOL_GPL(ccw_device_get_schid); 766 770 767 771 MODULE_LICENSE("GPL"); 768 772 EXPORT_SYMBOL(ccw_device_set_options_mask); ··· 781 777 EXPORT_SYMBOL(ccw_device_start_key); 782 778 EXPORT_SYMBOL(ccw_device_get_ciw); 783 779 EXPORT_SYMBOL(ccw_device_get_path_mask); 784 - EXPORT_SYMBOL(_ccw_device_get_subchannel_number); 785 780 EXPORT_SYMBOL_GPL(ccw_device_get_chp_desc);
+5 -5
drivers/s390/cio/device_pgid.c
··· 234 234 * Determine pathgroup state from PGID data. 235 235 */ 236 236 static void pgid_analyze(struct ccw_device *cdev, struct pgid **p, 237 - int *mismatch, int *reserved, u8 *reset) 237 + int *mismatch, u8 *reserved, u8 *reset) 238 238 { 239 239 struct pgid *pgid = &cdev->private->pgid[0]; 240 240 struct pgid *first = NULL; ··· 248 248 if ((cdev->private->pgid_valid_mask & lpm) == 0) 249 249 continue; 250 250 if (pgid->inf.ps.state2 == SNID_STATE2_RESVD_ELSE) 251 - *reserved = 1; 251 + *reserved |= lpm; 252 252 if (pgid_is_reset(pgid)) { 253 253 *reset |= lpm; 254 254 continue; ··· 316 316 struct subchannel *sch = to_subchannel(cdev->dev.parent); 317 317 struct pgid *pgid; 318 318 int mismatch = 0; 319 - int reserved = 0; 319 + u8 reserved = 0; 320 320 u8 reset = 0; 321 321 u8 donepm; 322 322 323 323 if (rc) 324 324 goto out; 325 325 pgid_analyze(cdev, &pgid, &mismatch, &reserved, &reset); 326 - if (reserved) 326 + if (reserved == cdev->private->pgid_valid_mask) 327 327 rc = -EUSERS; 328 328 else if (mismatch) 329 329 rc = -EOPNOTSUPP; ··· 336 336 } 337 337 out: 338 338 CIO_MSG_EVENT(2, "snid: device 0.%x.%04x: rc=%d pvm=%02x vpm=%02x " 339 - "todo=%02x mism=%d rsvd=%d reset=%02x\n", id->ssid, 339 + "todo=%02x mism=%d rsvd=%02x reset=%02x\n", id->ssid, 340 340 id->devno, rc, cdev->private->pgid_valid_mask, sch->vpm, 341 341 cdev->private->pgid_todo_mask, mismatch, reserved, reset); 342 342 switch (rc) {
+11 -41
drivers/s390/cio/qdio_main.c
··· 129 129 int rc, tmp_count = count, tmp_start = start, nr = q->nr, retried = 0; 130 130 unsigned int ccq = 0; 131 131 132 - BUG_ON(!q->irq_ptr->sch_token); 133 132 qperf_inc(q, eqbs); 134 133 135 134 if (!q->is_input_q) ··· 146 147 } 147 148 148 149 if (rc == 2) { 149 - BUG_ON(tmp_count == count); 150 150 qperf_inc(q, eqbs_partial); 151 151 DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "EQBS part:%02x", 152 152 tmp_count); ··· 187 189 188 190 if (!count) 189 191 return 0; 190 - 191 - BUG_ON(!q->irq_ptr->sch_token); 192 192 qperf_inc(q, sqbs); 193 193 194 194 if (!q->is_input_q) ··· 195 199 ccq = do_sqbs(q->irq_ptr->sch_token, state, nr, &tmp_start, &tmp_count); 196 200 rc = qdio_check_ccq(q, ccq); 197 201 if (!rc) { 198 - WARN_ON(tmp_count); 202 + WARN_ON_ONCE(tmp_count); 199 203 return count - tmp_count; 200 204 } 201 205 ··· 219 223 { 220 224 unsigned char __state = 0; 221 225 int i; 222 - 223 - BUG_ON(bufnr > QDIO_MAX_BUFFERS_MASK); 224 - BUG_ON(count > QDIO_MAX_BUFFERS_PER_Q); 225 226 226 227 if (is_qebsm(q)) 227 228 return qdio_do_eqbs(q, state, bufnr, count, auto_ack); ··· 250 257 unsigned char state, int count) 251 258 { 252 259 int i; 253 - 254 - BUG_ON(bufnr > QDIO_MAX_BUFFERS_MASK); 255 - BUG_ON(count > QDIO_MAX_BUFFERS_PER_Q); 256 260 257 261 if (is_qebsm(q)) 258 262 return qdio_do_sqbs(q, state, bufnr, count); ··· 335 345 336 346 /* hipersocket busy condition */ 337 347 if (unlikely(*busy_bit)) { 338 - WARN_ON(queue_type(q) != QDIO_IQDIO_QFMT || cc != 2); 339 348 retries++; 340 349 341 350 if (!start_time) { ··· 548 559 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in nop"); 549 560 break; 550 561 default: 551 - BUG(); 562 + WARN_ON_ONCE(1); 552 563 } 553 564 out: 554 565 return q->first_to_check; ··· 667 678 if (aob == NULL) 668 679 continue; 669 680 670 - BUG_ON(q->u.out.sbal_state == NULL); 671 681 q->u.out.sbal_state[b].flags |= 672 682 QDIO_OUTBUF_STATE_FLAG_PENDING; 673 683 q->u.out.aobs[b] = NULL; 674 684 } else if (state == SLSB_P_OUTPUT_EMPTY) { 675 - BUG_ON(q->u.out.sbal_state == NULL); 676 685 q->u.out.sbal_state[b].aob = NULL; 677 686 } 678 687 b = next_buf(b); ··· 690 703 q->aobs[bufnr] = aob; 691 704 } 692 705 if (q->aobs[bufnr]) { 693 - BUG_ON(q->sbal_state == NULL); 694 706 q->sbal_state[bufnr].flags = QDIO_OUTBUF_STATE_FLAG_NONE; 695 707 q->sbal_state[bufnr].aob = q->aobs[bufnr]; 696 708 q->aobs[bufnr]->user1 = (u64) q->sbal_state[bufnr].user; 697 709 phys_aob = virt_to_phys(q->aobs[bufnr]); 698 - BUG_ON(phys_aob & 0xFF); 710 + WARN_ON_ONCE(phys_aob & 0xFF); 699 711 } 700 712 701 713 out: ··· 795 809 goto out; 796 810 797 811 switch (state) { 798 - case SLSB_P_OUTPUT_PENDING: 799 - BUG(); 800 812 case SLSB_P_OUTPUT_EMPTY: 801 813 /* the adapter got it */ 802 814 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, ··· 824 840 case SLSB_P_OUTPUT_HALTED: 825 841 break; 826 842 default: 827 - BUG(); 843 + WARN_ON_ONCE(1); 828 844 } 829 845 830 846 out: ··· 896 912 static void __qdio_outbound_processing(struct qdio_q *q) 897 913 { 898 914 qperf_inc(q, tasklet_outbound); 899 - BUG_ON(atomic_read(&q->nr_buf_used) < 0); 915 + WARN_ON_ONCE(atomic_read(&q->nr_buf_used) < 0); 900 916 901 917 if (qdio_outbound_q_moved(q)) 902 918 qdio_kick_handler(q); ··· 1122 1138 irq_ptr->perf_stat.qdio_int++; 1123 1139 1124 1140 if (IS_ERR(irb)) { 1125 - switch (PTR_ERR(irb)) { 1126 - case -EIO: 1127 - DBF_ERROR("%4x IO error", irq_ptr->schid.sch_no); 1128 - qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); 1129 - wake_up(&cdev->private->wait_q); 1130 - return; 1131 - default: 1132 - WARN_ON(1); 1133 - return; 1134 - } 1141 + DBF_ERROR("%4x IO error", irq_ptr->schid.sch_no); 1142 + qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); 1143 + wake_up(&cdev->private->wait_q); 1144 + return; 1135 1145 } 1136 1146 qdio_irq_check_sense(irq_ptr, irb); 1137 1147 cstat = irb->scsw.cmd.cstat; ··· 1151 1173 case QDIO_IRQ_STATE_STOPPED: 1152 1174 break; 1153 1175 default: 1154 - WARN_ON(1); 1176 + WARN_ON_ONCE(1); 1155 1177 } 1156 1178 wake_up(&cdev->private->wait_q); 1157 1179 } ··· 1205 1227 if (!irq_ptr) 1206 1228 return -ENODEV; 1207 1229 1208 - BUG_ON(irqs_disabled()); 1230 + WARN_ON_ONCE(irqs_disabled()); 1209 1231 DBF_EVENT("qshutdown:%4x", cdev->private->schid.sch_no); 1210 1232 1211 1233 mutex_lock(&irq_ptr->setup_mutex); ··· 1336 1358 irq_ptr->qdr = (struct qdr *) get_zeroed_page(GFP_KERNEL | GFP_DMA); 1337 1359 if (!irq_ptr->qdr) 1338 1360 goto out_rel; 1339 - WARN_ON((unsigned long)irq_ptr->qdr & 0xfff); 1340 1361 1341 1362 if (qdio_allocate_qs(irq_ptr, init_data->no_input_qs, 1342 1363 init_data->no_output_qs)) ··· 1574 1597 1575 1598 set: 1576 1599 count = set_buf_states(q, bufnr, SLSB_CU_INPUT_EMPTY, count); 1577 - 1578 1600 used = atomic_add_return(count, &q->nr_buf_used) - count; 1579 - BUG_ON(used + count > QDIO_MAX_BUFFERS_PER_Q); 1580 1601 1581 1602 if (need_siga_in(q)) 1582 1603 return qdio_siga_input(q); ··· 1599 1624 1600 1625 count = set_buf_states(q, bufnr, SLSB_CU_OUTPUT_PRIMED, count); 1601 1626 used = atomic_add_return(count, &q->nr_buf_used); 1602 - BUG_ON(used > QDIO_MAX_BUFFERS_PER_Q); 1603 1627 1604 1628 if (used == QDIO_MAX_BUFFERS_PER_Q) 1605 1629 qperf_inc(q, outbound_queue_full); ··· 1652 1678 { 1653 1679 struct qdio_irq *irq_ptr; 1654 1680 1655 - 1656 1681 if (bufnr >= QDIO_MAX_BUFFERS_PER_Q || count > QDIO_MAX_BUFFERS_PER_Q) 1657 1682 return -EINVAL; 1658 1683 ··· 1693 1720 if (!irq_ptr) 1694 1721 return -ENODEV; 1695 1722 q = irq_ptr->input_qs[nr]; 1696 - 1697 - WARN_ON(queue_irqs_enabled(q)); 1698 1723 1699 1724 clear_nonshared_ind(irq_ptr); 1700 1725 qdio_stop_polling(q); ··· 1740 1769 if (!irq_ptr) 1741 1770 return -ENODEV; 1742 1771 q = irq_ptr->input_qs[nr]; 1743 - WARN_ON(queue_irqs_enabled(q)); 1744 1772 1745 1773 /* 1746 1774 * Cannot rely on automatic sync after interrupt since queues may
+3 -6
drivers/s390/cio/qdio_setup.c
··· 140 140 q->sl = (struct sl *)((char *)q->slib + PAGE_SIZE / 2); 141 141 142 142 /* fill in sbal */ 143 - for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) { 143 + for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) 144 144 q->sbal[j] = *sbals_array++; 145 - BUG_ON((unsigned long)q->sbal[j] & 0xff); 146 - } 147 145 148 146 /* fill in slib */ 149 147 if (i > 0) { ··· 432 434 irq_ptr->int_parm = init_data->int_parm; 433 435 irq_ptr->nr_input_qs = init_data->no_input_qs; 434 436 irq_ptr->nr_output_qs = init_data->no_output_qs; 435 - 436 - irq_ptr->schid = ccw_device_get_subchannel_id(init_data->cdev); 437 437 irq_ptr->cdev = init_data->cdev; 438 + ccw_device_get_schid(irq_ptr->cdev, &irq_ptr->schid); 438 439 setup_queues(irq_ptr, init_data); 439 440 440 441 setup_qib(irq_ptr, init_data); ··· 480 483 char s[80]; 481 484 482 485 snprintf(s, 80, "qdio: %s %s on SC %x using " 483 - "AI:%d QEBSM:%d PCI:%d TDD:%d SIGA:%s%s%s%s%s\n", 486 + "AI:%d QEBSM:%d PRI:%d TDD:%d SIGA:%s%s%s%s%s\n", 484 487 dev_name(&cdev->dev), 485 488 (irq_ptr->qib.qfmt == QDIO_QETH_QFMT) ? "OSA" : 486 489 ((irq_ptr->qib.qfmt == QDIO_ZFCP_QFMT) ? "ZFCP" : "HS"),
-2
drivers/s390/cio/qdio_thinint.c
··· 73 73 void tiqdio_add_input_queues(struct qdio_irq *irq_ptr) 74 74 { 75 75 mutex_lock(&tiq_list_lock); 76 - BUG_ON(irq_ptr->nr_input_qs < 1); 77 76 list_add_rcu(&irq_ptr->input_qs[0]->entry, &tiq_list); 78 77 mutex_unlock(&tiq_list_lock); 79 78 xchg(irq_ptr->dsci, 1 << 7); ··· 82 83 { 83 84 struct qdio_q *q; 84 85 85 - BUG_ON(irq_ptr->nr_input_qs < 1); 86 86 q = irq_ptr->input_qs[0]; 87 87 /* if establish triggered an error */ 88 88 if (!q || !q->entry.prev || !q->entry.next)
+27 -41
drivers/s390/crypto/zcrypt_msgtype50.c
··· 241 241 struct ap_message *ap_msg, 242 242 struct ica_rsa_modexpo_crt *crt) 243 243 { 244 - int mod_len, short_len, long_len, long_offset, limit; 244 + int mod_len, short_len; 245 245 unsigned char *p, *q, *dp, *dq, *u, *inp; 246 246 247 247 mod_len = crt->inputdatalength; 248 248 short_len = mod_len / 2; 249 - long_len = mod_len / 2 + 8; 250 249 251 250 /* 252 - * CEX2A cannot handle p, dp, or U > 128 bytes. 253 - * If we have one of these, we need to do extra checking. 254 - * For CEX3A the limit is 256 bytes. 251 + * CEX2A and CEX3A w/o FW update can handle requests up to 252 + * 256 byte modulus (2k keys). 253 + * CEX3A with FW update and CEX4A cards are able to handle 254 + * 512 byte modulus (4k keys). 255 255 */ 256 - if (zdev->max_mod_size == CEX3A_MAX_MOD_SIZE) 257 - limit = 256; 258 - else 259 - limit = 128; 260 - 261 - if (long_len > limit) { 262 - /* 263 - * zcrypt_rsa_crt already checked for the leading 264 - * zeroes of np_prime, bp_key and u_mult_inc. 265 - */ 266 - long_offset = long_len - limit; 267 - long_len = limit; 268 - } else 269 - long_offset = 0; 270 - 271 - /* 272 - * Instead of doing extra work for p, dp, U > 64 bytes, we'll just use 273 - * the larger message structure. 274 - */ 275 - if (long_len <= 64) { 256 + if (mod_len <= 128) { /* up to 1024 bit key size */ 276 257 struct type50_crb1_msg *crb1 = ap_msg->message; 277 258 memset(crb1, 0, sizeof(*crb1)); 278 259 ap_msg->length = sizeof(*crb1); 279 260 crb1->header.msg_type_code = TYPE50_TYPE_CODE; 280 261 crb1->header.msg_len = sizeof(*crb1); 281 262 crb1->keyblock_type = TYPE50_CRB1_FMT; 282 - p = crb1->p + sizeof(crb1->p) - long_len; 263 + p = crb1->p + sizeof(crb1->p) - short_len; 283 264 q = crb1->q + sizeof(crb1->q) - short_len; 284 - dp = crb1->dp + sizeof(crb1->dp) - long_len; 265 + dp = crb1->dp + sizeof(crb1->dp) - short_len; 285 266 dq = crb1->dq + sizeof(crb1->dq) - short_len; 286 - u = crb1->u + sizeof(crb1->u) - long_len; 267 + u = crb1->u + sizeof(crb1->u) - short_len; 287 268 inp = crb1->message + sizeof(crb1->message) - mod_len; 288 - } else if (long_len <= 128) { 269 + } else if (mod_len <= 256) { /* up to 2048 bit key size */ 289 270 struct type50_crb2_msg *crb2 = ap_msg->message; 290 271 memset(crb2, 0, sizeof(*crb2)); 291 272 ap_msg->length = sizeof(*crb2); 292 273 crb2->header.msg_type_code = TYPE50_TYPE_CODE; 293 274 crb2->header.msg_len = sizeof(*crb2); 294 275 crb2->keyblock_type = TYPE50_CRB2_FMT; 295 - p = crb2->p + sizeof(crb2->p) - long_len; 276 + p = crb2->p + sizeof(crb2->p) - short_len; 296 277 q = crb2->q + sizeof(crb2->q) - short_len; 297 - dp = crb2->dp + sizeof(crb2->dp) - long_len; 278 + dp = crb2->dp + sizeof(crb2->dp) - short_len; 298 279 dq = crb2->dq + sizeof(crb2->dq) - short_len; 299 - u = crb2->u + sizeof(crb2->u) - long_len; 280 + u = crb2->u + sizeof(crb2->u) - short_len; 300 281 inp = crb2->message + sizeof(crb2->message) - mod_len; 301 - } else { 302 - /* long_len >= 256 */ 282 + } else if ((mod_len <= 512) && /* up to 4096 bit key size */ 283 + (zdev->max_mod_size == CEX3A_MAX_MOD_SIZE)) { /* >= CEX3A */ 303 284 struct type50_crb3_msg *crb3 = ap_msg->message; 304 285 memset(crb3, 0, sizeof(*crb3)); 305 286 ap_msg->length = sizeof(*crb3); 306 287 crb3->header.msg_type_code = TYPE50_TYPE_CODE; 307 288 crb3->header.msg_len = sizeof(*crb3); 308 289 crb3->keyblock_type = TYPE50_CRB3_FMT; 309 - p = crb3->p + sizeof(crb3->p) - long_len; 290 + p = crb3->p + sizeof(crb3->p) - short_len; 310 291 q = crb3->q + sizeof(crb3->q) - short_len; 311 - dp = crb3->dp + sizeof(crb3->dp) - long_len; 292 + dp = crb3->dp + sizeof(crb3->dp) - short_len; 312 293 dq = crb3->dq + sizeof(crb3->dq) - short_len; 313 - u = crb3->u + sizeof(crb3->u) - long_len; 294 + u = crb3->u + sizeof(crb3->u) - short_len; 314 295 inp = crb3->message + sizeof(crb3->message) - mod_len; 315 - } 296 + } else 297 + return -EINVAL; 316 298 317 - if (copy_from_user(p, crt->np_prime + long_offset, long_len) || 299 + /* 300 + * correct the offset of p, bp and mult_inv according zcrypt.h 301 + * block size right aligned (skip the first byte) 302 + */ 303 + if (copy_from_user(p, crt->np_prime + MSGTYPE_ADJUSTMENT, short_len) || 318 304 copy_from_user(q, crt->nq_prime, short_len) || 319 - copy_from_user(dp, crt->bp_key + long_offset, long_len) || 305 + copy_from_user(dp, crt->bp_key + MSGTYPE_ADJUSTMENT, short_len) || 320 306 copy_from_user(dq, crt->bq_key, short_len) || 321 - copy_from_user(u, crt->u_mult_inv + long_offset, long_len) || 307 + copy_from_user(u, crt->u_mult_inv + MSGTYPE_ADJUSTMENT, short_len) || 322 308 copy_from_user(inp, crt->inputdata, mod_len)) 323 309 return -EFAULT; 324 310
+2
drivers/s390/crypto/zcrypt_msgtype50.h
··· 33 33 #define MSGTYPE50_CRB2_MAX_MSG_SIZE 0x390 /*sizeof(struct type50_crb2_msg)*/ 34 34 #define MSGTYPE50_CRB3_MAX_MSG_SIZE 0x710 /*sizeof(struct type50_crb3_msg)*/ 35 35 36 + #define MSGTYPE_ADJUSTMENT 0x08 /*type04 extension (not needed in type50)*/ 37 + 36 38 int zcrypt_msgtype50_init(void); 37 39 void zcrypt_msgtype50_exit(void); 38 40
+20 -1
include/asm-generic/io.h
··· 83 83 #define writel(b,addr) __raw_writel(__cpu_to_le32(b),addr) 84 84 85 85 #ifdef CONFIG_64BIT 86 + #ifndef __raw_readq 86 87 static inline u64 __raw_readq(const volatile void __iomem *addr) 87 88 { 88 89 return *(const volatile u64 __force *) addr; 89 90 } 91 + #endif 92 + 90 93 #define readq(addr) __le64_to_cpu(__raw_readq(addr)) 91 94 95 + #ifndef __raw_writeq 92 96 static inline void __raw_writeq(u64 b, volatile void __iomem *addr) 93 97 { 94 98 *(volatile u64 __force *) addr = b; 95 99 } 96 - #define writeq(b,addr) __raw_writeq(__cpu_to_le64(b),addr) 97 100 #endif 101 + 102 + #define writeq(b, addr) __raw_writeq(__cpu_to_le64(b), addr) 103 + #endif /* CONFIG_64BIT */ 98 104 99 105 #ifndef PCI_IOBASE 100 106 #define PCI_IOBASE ((void __iomem *) 0) ··· 292 286 293 287 #ifndef CONFIG_GENERIC_IOMAP 294 288 struct pci_dev; 289 + extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); 290 + 291 + #ifndef pci_iounmap 295 292 static inline void pci_iounmap(struct pci_dev *dev, void __iomem *p) 296 293 { 297 294 } 295 + #endif 298 296 #endif /* CONFIG_GENERIC_IOMAP */ 299 297 300 298 /* 301 299 * Change virtual addresses to physical addresses and vv. 302 300 * These are pretty trivial 303 301 */ 302 + #ifndef virt_to_phys 304 303 static inline unsigned long virt_to_phys(volatile void *address) 305 304 { 306 305 return __pa((unsigned long)address); ··· 315 304 { 316 305 return __va(address); 317 306 } 307 + #endif 318 308 319 309 /* 320 310 * Change "struct page" to physical address. ··· 375 363 } 376 364 #endif 377 365 366 + #ifndef memset_io 378 367 #define memset_io(a, b, c) memset(__io_virt(a), (b), (c)) 368 + #endif 369 + 370 + #ifndef memcpy_fromio 379 371 #define memcpy_fromio(a, b, c) memcpy((a), __io_virt(b), (c)) 372 + #endif 373 + #ifndef memcpy_toio 380 374 #define memcpy_toio(a, b, c) memcpy(__io_virt(a), (b), (c)) 375 + #endif 381 376 382 377 #endif /* __KERNEL__ */ 383 378
+5 -5
include/linux/irq.h
··· 10 10 */ 11 11 12 12 #include <linux/smp.h> 13 - 14 - #ifndef CONFIG_S390 15 - 16 13 #include <linux/linkage.h> 17 14 #include <linux/cache.h> 18 15 #include <linux/spinlock.h> ··· 743 746 static inline void irq_gc_unlock(struct irq_chip_generic *gc) { } 744 747 #endif 745 748 746 - #endif /* CONFIG_GENERIC_HARDIRQS */ 749 + #else /* !CONFIG_GENERIC_HARDIRQS */ 747 750 748 - #endif /* !CONFIG_S390 */ 751 + extern struct msi_desc *irq_get_msi_desc(unsigned int irq); 752 + extern int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry); 753 + 754 + #endif /* CONFIG_GENERIC_HARDIRQS */ 749 755 750 756 #endif /* _LINUX_IRQ_H */