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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 's390-6.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 updates from Alexander Gordeev:

- Factor out handle_write() function and simplify 3215 console write
operation

- When 3170 terminal emulator is connected to the 3215 console driver
the boot time could be very long due to limited buffer space or
missing operator input. Add con3215_drop command line parameter and
con3215_drop sysfs attribute file to instruct the kernel drop console
data when such conditions are met

- Fix white space errors in 3215 console driver

- Move enum paiext_mode definition to a header file and rename it to
paievt_mode to indicate this is now used for several events. Rename
PAI_MODE_COUNTER to PAI_MODE_COUNTING to make consistent with
PAI_MODE_SAMPLING

- Simplify the logic of PMU pai_crypto mapped buffer reference counter
and make it consistent with PMU pai_ext

- Rename PMU pai_crypto mapped buffer structure member users to
active_events to make it consistent with PMU pai_ext

- Enable HUGETLB_PAGE_OPTIMIZE_VMEMMAP configuration option. This
results in saving of 12K per 1M hugetlb page (~1.2%) and 32764K per
2G hugetlb page (~1.6%)

- Use generic serial.h, bugs.h, shmparam.h and vga.h header files and
scrap s390-specific versions

- The generic percpu setup code does not expect the s390-like
implementation and emits a warning. To get rid of that warning and
provide sane CPU-to-node and CPU-to-CPU distance mappings implementat
a minimal version of setup_per_cpu_areas()

- Use kstrtobool() instead of strtobool() for re-IPL sysfs device
attributes

- Avoid unnecessary lookup of a pointer to MSI descriptor when setting
IRQ affinity for a PCI device

- Get rid of "an incompatible function type cast" warning by changing
debug_sprintf_format_fn() function prototype so it matches the
debug_format_proc_t function type

- Remove unused info_blk_hdr__pcpus() and get_page_state() functions

- Get rid of clang "unused unused insn cache ops function" warning by
moving s390_insn definition to a private header

- Get rid of clang "unused function" warning by making function
raw3270_state_final() only available if CONFIG_TN3270_CONSOLE is
enabled

- Use kstrobool() to parse sclp_con_drop parameter to make it identical
to the con3215_drop parameter and allow passing values like "yes" and
"true"

- Use sysfs_emit() for all SCLP sysfs show functions, which is the
current standard way to generate output strings

- Make SCLP con_drop sysfs attribute also writable and allow to change
its value during runtime. This makes SCLP console drop handling
consistent with the 3215 device driver

- Virtual and physical addresses are indentical on s390. However, there
is still a confusion when pointers are directly casted to physical
addresses or vice versa. Use correct address converters
virt_to_phys() and phys_to_virt() for s390 channel IO drivers

- Support for power managemant has been removed from s390 since quite
some time. Remove unused power managemant code from the appldata
device driver

- Allow memory tools like KASAN see memory accesses from the checksum
code. Switch to GENERIC_CSUM if KASAN is enabled, just like x86 does

- Add support of ECKD DASDs disks so it could be used as boot and dump
devices

- Follow checkpatch recommendations and use octal values instead of
S_IRUGO and S_IWUSR for dump device attributes in sysfs

- Changes to vx-insn.h do not cause a recompile of C files that use
asm(".include \"asm/vx-insn.h\"\n") magic to access vector
instruction macros from inline assemblies. Add wrapper include header
file to avoid this problem

- Use vector instruction macros instead of byte patterns to increase
register validation routine readability

- The current machine check register validation handling does not take
into account various scenarios and might lead to killing a wrong user
process or potentially ignore corrupted FPU registers. Simplify logic
of the machine check handler and stop the whole machine if the
previous context was kerenel mode. If the previous context was user
mode, kill the current task

- Introduce sclp_emergency_printk() function which can be used to emit
a message in emergency cases. It is supposed to be used in cases
where regular console device drivers may not work anymore, e.g.
unrecoverable machine checks

Keep the early Service-Call Control Block so it can also be used
after initdata has been freed to allow sclp_emergency_printk()
implementation

- In case a system will be stopped because of an unrecoverable machine
check error print the machine check interruption code to give a hint
of what went wrong

- Move storage error checking from the assembly entry code to C in
order to simplify machine check handling. Enter the handler with DAT
turned on, which simplifies the entry code even more

- The machine check extended save areas are allocated using a private
"nmi_save_areas" slab cache which guarantees a required power-of-two
alignment. Get rid of that cache in favour of kmalloc()

* tag 's390-6.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (38 commits)
s390/nmi: get rid of private slab cache
s390/nmi: move storage error checking back to C, enter with DAT on
s390/nmi: print machine check interruption code before stopping system
s390/sclp: introduce sclp_emergency_printk()
s390/sclp: keep sclp_early_sccb
s390/nmi: rework register validation handling
s390/nmi: use vector instruction macros instead of byte patterns
s390/vx: add vx-insn.h wrapper include file
s390/ipl: use octal values instead of S_* macros
s390/ipl: add eckd dump support
s390/ipl: add eckd support
vfio/ccw: identify CCW data addresses as physical
vfio/ccw: sort out physical vs virtual pointers usage
s390/checksum: support GENERIC_CSUM, enable it for KASAN
s390/appldata: remove power management callbacks
s390/cio: sort out physical vs virtual pointers usage
s390/sclp: allow to change sclp_console_drop during runtime
s390/sclp: convert to use sysfs_emit()
s390/sclp: use kstrobool() to parse sclp_con_drop parameter
s390/3270: make raw3270_state_final() depend on CONFIG_TN3270_CONSOLE
...

+1608 -1209
+11
Documentation/admin-guide/kernel-parameters.txt
··· 703 703 condev= [HW,S390] console device 704 704 conmode= 705 705 706 + con3215_drop= [S390] 3215 console drop mode. 707 + Format: y|n|Y|N|1|0 708 + When set to true, drop data on the 3215 console when 709 + the console buffer is full. In this case the 710 + operator using a 3270 terminal emulator (for example 711 + x3270) does not have to enter the clear key for the 712 + console output to advance and the kernel to continue. 713 + This leads to a much faster boot time when a 3270 714 + terminal emulator is active. If no 3270 terminal 715 + emulator is used, this parameter has no effect. 716 + 706 717 console= [KNL] Output console device and options. 707 718 708 719 tty<n> Use the virtual console device <n>.
+7
arch/s390/Kconfig
··· 26 26 config GENERIC_BUG_RELATIVE_POINTERS 27 27 def_bool y 28 28 29 + config GENERIC_CSUM 30 + bool 31 + default y if KASAN 32 + 29 33 config GENERIC_LOCKBREAK 30 34 def_bool y if PREEMPTION 31 35 ··· 126 122 select ARCH_WANTS_NO_INSTR 127 123 select ARCH_WANT_DEFAULT_BPF_JIT 128 124 select ARCH_WANT_IPC_PARSE_VERSION 125 + select ARCH_WANT_HUGETLB_PAGE_OPTIMIZE_VMEMMAP 129 126 select BUILDTIME_TABLE_SORT 130 127 select CLONE_BACKWARDS2 131 128 select DMA_OPS if PCI ··· 202 197 select HAVE_RSEQ 203 198 select HAVE_SAMPLE_FTRACE_DIRECT 204 199 select HAVE_SAMPLE_FTRACE_DIRECT_MULTI 200 + select HAVE_SETUP_PER_CPU_AREA 205 201 select HAVE_SOFTIRQ_ON_OWN_STACK 206 202 select HAVE_SYSCALL_TRACEPOINTS 207 203 select HAVE_VIRT_CPU_ACCOUNTING ··· 214 208 select MMU_GATHER_MERGE_VMAS 215 209 select MODULES_USE_ELF_RELA 216 210 select NEED_DMA_MAP_STATE if PCI 211 + select NEED_PER_CPU_EMBED_FIRST_CHUNK 217 212 select NEED_SG_DMA_LENGTH if PCI 218 213 select OLD_SIGACTION 219 214 select OLD_SIGSUSPEND3
+2 -111
arch/s390/appldata/appldata_base.c
··· 26 26 #include <linux/notifier.h> 27 27 #include <linux/cpu.h> 28 28 #include <linux/workqueue.h> 29 - #include <linux/suspend.h> 30 - #include <linux/platform_device.h> 31 29 #include <asm/appldata.h> 32 30 #include <asm/vtimer.h> 33 31 #include <linux/uaccess.h> ··· 41 43 42 44 #define TOD_MICRO 0x01000 /* nr. of TOD clock units 43 45 for 1 microsecond */ 44 - 45 - static struct platform_device *appldata_pdev; 46 46 47 47 /* 48 48 * /proc entries (sysctl) ··· 84 88 static DEFINE_SPINLOCK(appldata_timer_lock); 85 89 static int appldata_interval = APPLDATA_CPU_INTERVAL; 86 90 static int appldata_timer_active; 87 - static int appldata_timer_suspended = 0; 88 91 89 92 /* 90 93 * Work queue ··· 407 412 /********************** module-ops management <END> **************************/ 408 413 409 414 410 - /**************************** suspend / resume *******************************/ 411 - static int appldata_freeze(struct device *dev) 412 - { 413 - struct appldata_ops *ops; 414 - int rc; 415 - struct list_head *lh; 416 - 417 - spin_lock(&appldata_timer_lock); 418 - if (appldata_timer_active) { 419 - __appldata_vtimer_setup(APPLDATA_DEL_TIMER); 420 - appldata_timer_suspended = 1; 421 - } 422 - spin_unlock(&appldata_timer_lock); 423 - 424 - mutex_lock(&appldata_ops_mutex); 425 - list_for_each(lh, &appldata_ops_list) { 426 - ops = list_entry(lh, struct appldata_ops, list); 427 - if (ops->active == 1) { 428 - rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, 429 - (unsigned long) ops->data, ops->size, 430 - ops->mod_lvl); 431 - if (rc != 0) 432 - pr_err("Stopping the data collection for %s " 433 - "failed with rc=%d\n", ops->name, rc); 434 - } 435 - } 436 - mutex_unlock(&appldata_ops_mutex); 437 - return 0; 438 - } 439 - 440 - static int appldata_restore(struct device *dev) 441 - { 442 - struct appldata_ops *ops; 443 - int rc; 444 - struct list_head *lh; 445 - 446 - spin_lock(&appldata_timer_lock); 447 - if (appldata_timer_suspended) { 448 - __appldata_vtimer_setup(APPLDATA_ADD_TIMER); 449 - appldata_timer_suspended = 0; 450 - } 451 - spin_unlock(&appldata_timer_lock); 452 - 453 - mutex_lock(&appldata_ops_mutex); 454 - list_for_each(lh, &appldata_ops_list) { 455 - ops = list_entry(lh, struct appldata_ops, list); 456 - if (ops->active == 1) { 457 - ops->callback(ops->data); // init record 458 - rc = appldata_diag(ops->record_nr, 459 - APPLDATA_START_INTERVAL_REC, 460 - (unsigned long) ops->data, ops->size, 461 - ops->mod_lvl); 462 - if (rc != 0) { 463 - pr_err("Starting the data collection for %s " 464 - "failed with rc=%d\n", ops->name, rc); 465 - } 466 - } 467 - } 468 - mutex_unlock(&appldata_ops_mutex); 469 - return 0; 470 - } 471 - 472 - static int appldata_thaw(struct device *dev) 473 - { 474 - return appldata_restore(dev); 475 - } 476 - 477 - static const struct dev_pm_ops appldata_pm_ops = { 478 - .freeze = appldata_freeze, 479 - .thaw = appldata_thaw, 480 - .restore = appldata_restore, 481 - }; 482 - 483 - static struct platform_driver appldata_pdrv = { 484 - .driver = { 485 - .name = "appldata", 486 - .pm = &appldata_pm_ops, 487 - }, 488 - }; 489 - /************************* suspend / resume <END> ****************************/ 490 - 491 - 492 415 /******************************* init / exit *********************************/ 493 416 494 417 /* ··· 416 503 */ 417 504 static int __init appldata_init(void) 418 505 { 419 - int rc; 420 - 421 506 init_virt_timer(&appldata_timer); 422 507 appldata_timer.function = appldata_timer_function; 423 508 appldata_timer.data = (unsigned long) &appldata_work; 424 - 425 - rc = platform_driver_register(&appldata_pdrv); 426 - if (rc) 427 - return rc; 428 - 429 - appldata_pdev = platform_device_register_simple("appldata", -1, NULL, 430 - 0); 431 - if (IS_ERR(appldata_pdev)) { 432 - rc = PTR_ERR(appldata_pdev); 433 - goto out_driver; 434 - } 435 509 appldata_wq = alloc_ordered_workqueue("appldata", 0); 436 - if (!appldata_wq) { 437 - rc = -ENOMEM; 438 - goto out_device; 439 - } 440 - 510 + if (!appldata_wq) 511 + return -ENOMEM; 441 512 appldata_sysctl_header = register_sysctl_table(appldata_dir_table); 442 513 return 0; 443 - 444 - out_device: 445 - platform_device_unregister(appldata_pdev); 446 - out_driver: 447 - platform_driver_unregister(&appldata_pdrv); 448 - return rc; 449 514 } 450 515 451 516 __initcall(appldata_init);
+9
arch/s390/boot/ipl_parm.c
··· 77 77 if (ipl_block.pb0_hdr.pbt == IPL_PBT_NVME && 78 78 ipl_block.nvme.opt == IPL_PB0_NVME_OPT_DUMP) 79 79 return true; 80 + if (ipl_block.pb0_hdr.pbt == IPL_PBT_ECKD && 81 + ipl_block.eckd.opt == IPL_PB0_ECKD_OPT_DUMP) 82 + return true; 80 83 return false; 81 84 } 82 85 ··· 111 108 scp_data_len = ipb->nvme.scp_data_len; 112 109 scp_data = ipb->nvme.scp_data; 113 110 break; 111 + case IPL_PBT_ECKD: 112 + scp_data_len = ipb->eckd.scp_data_len; 113 + scp_data = ipb->eckd.scp_data; 114 + break; 115 + 114 116 default: 115 117 goto out; 116 118 } ··· 161 153 break; 162 154 case IPL_PBT_FCP: 163 155 case IPL_PBT_NVME: 156 + case IPL_PBT_ECKD: 164 157 rc = ipl_block_get_ascii_scpdata( 165 158 parm, COMMAND_LINE_SIZE - len - 1, &ipl_block); 166 159 break;
-8
arch/s390/hypfs/hypfs_diag.c
··· 68 68 return ((struct diag204_x_info_blk_hdr *)hdr)->flags; 69 69 } 70 70 71 - static inline __u16 info_blk_hdr__pcpus(enum diag204_format type, void *hdr) 72 - { 73 - if (type == DIAG204_INFO_SIMPLE) 74 - return ((struct diag204_info_blk_hdr *)hdr)->phys_cpus; 75 - else /* DIAG204_INFO_EXT */ 76 - return ((struct diag204_x_info_blk_hdr *)hdr)->phys_cpus; 77 - } 78 - 79 71 /* Partition header */ 80 72 81 73 static inline int part_hdr__size(enum diag204_format type)
-21
arch/s390/include/asm/bugs.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - /* 3 - * S390 version 4 - * Copyright IBM Corp. 1999 5 - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) 6 - * 7 - * Derived from "include/asm-i386/bugs.h" 8 - * Copyright (C) 1994 Linus Torvalds 9 - */ 10 - 11 - /* 12 - * This is included by init/main.c to check for architecture-dependent bugs. 13 - * 14 - * Needs: 15 - * void check_bugs(void); 16 - */ 17 - 18 - static inline void check_bugs(void) 19 - { 20 - /* s390 has no bugs ... */ 21 - }
+7
arch/s390/include/asm/checksum.h
··· 12 12 #ifndef _S390_CHECKSUM_H 13 13 #define _S390_CHECKSUM_H 14 14 15 + #ifdef CONFIG_GENERIC_CSUM 16 + 17 + #include <asm-generic/checksum.h> 18 + 19 + #else /* CONFIG_GENERIC_CSUM */ 20 + 15 21 #include <linux/uaccess.h> 16 22 #include <linux/in6.h> 17 23 ··· 135 129 return csum_fold((__force __wsum)(sum >> 32)); 136 130 } 137 131 132 + #endif /* CONFIG_GENERIC_CSUM */ 138 133 #endif /* _S390_CHECKSUM_H */
+11
arch/s390/include/asm/ipl.h
··· 22 22 struct ipl_pb0_common common; 23 23 struct ipl_pb0_fcp fcp; 24 24 struct ipl_pb0_ccw ccw; 25 + struct ipl_pb0_eckd eckd; 25 26 struct ipl_pb0_nvme nvme; 26 27 char raw[PAGE_SIZE - sizeof(struct ipl_pl_hdr)]; 27 28 }; ··· 41 40 #define IPL_BP_CCW_LEN (sizeof(struct ipl_pl_hdr) + \ 42 41 sizeof(struct ipl_pb0_ccw)) 43 42 #define IPL_BP0_CCW_LEN (sizeof(struct ipl_pb0_ccw)) 43 + 44 + #define IPL_BP_ECKD_LEN (sizeof(struct ipl_pl_hdr) + \ 45 + sizeof(struct ipl_pb0_eckd)) 46 + #define IPL_BP0_ECKD_LEN (sizeof(struct ipl_pb0_eckd)) 44 47 45 48 #define IPL_MAX_SUPPORTED_VERSION (0) 46 49 ··· 73 68 IPL_TYPE_NSS = 16, 74 69 IPL_TYPE_NVME = 32, 75 70 IPL_TYPE_NVME_DUMP = 64, 71 + IPL_TYPE_ECKD = 128, 72 + IPL_TYPE_ECKD_DUMP = 256, 76 73 }; 77 74 78 75 struct ipl_info ··· 84 77 struct { 85 78 struct ccw_dev_id dev_id; 86 79 } ccw; 80 + struct { 81 + struct ccw_dev_id dev_id; 82 + } eckd; 87 83 struct { 88 84 struct ccw_dev_id dev_id; 89 85 u64 wwpn; ··· 109 99 static inline bool is_ipl_type_dump(void) 110 100 { 111 101 return (ipl_info.type == IPL_TYPE_FCP_DUMP) || 102 + (ipl_info.type == IPL_TYPE_ECKD_DUMP) || 112 103 (ipl_info.type == IPL_TYPE_NVME_DUMP); 113 104 } 114 105
+6
arch/s390/include/asm/pai.h
··· 75 75 WRITE_ONCE(S390_lowcore.ccd, S390_lowcore.ccd & ~PAI_CRYPTO_KERNEL_OFFSET); 76 76 } 77 77 78 + enum paievt_mode { 79 + PAI_MODE_NONE, 80 + PAI_MODE_SAMPLING, 81 + PAI_MODE_COUNTING, 82 + }; 83 + 78 84 #endif
+2
arch/s390/include/asm/sclp.h
··· 87 87 unsigned char has_gisaf : 1; 88 88 unsigned char has_diag318 : 1; 89 89 unsigned char has_sipl : 1; 90 + unsigned char has_sipl_eckd : 1; 90 91 unsigned char has_dirq : 1; 91 92 unsigned char has_iplcc : 1; 92 93 unsigned char has_zpci_lsi : 1; ··· 132 131 void sclp_early_detect(void); 133 132 void sclp_early_printk(const char *s); 134 133 void __sclp_early_printk(const char *s, unsigned int len); 134 + void sclp_emergency_printk(const char *s); 135 135 136 136 int sclp_early_get_memsize(unsigned long *mem); 137 137 int sclp_early_get_hsa_size(unsigned long *hsa_size);
-7
arch/s390/include/asm/serial.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifndef _ASM_S390_SERIAL_H 3 - #define _ASM_S390_SERIAL_H 4 - 5 - #define BASE_BAUD 0 6 - 7 - #endif /* _ASM_S390_SERIAL_H */
-12
arch/s390/include/asm/shmparam.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - /* 3 - * S390 version 4 - * 5 - * Derived from "include/asm-i386/shmparam.h" 6 - */ 7 - #ifndef _ASM_S390_SHMPARAM_H 8 - #define _ASM_S390_SHMPARAM_H 9 - 10 - #define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ 11 - 12 - #endif /* _ASM_S390_SHMPARAM_H */
-7
arch/s390/include/asm/vga.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - #ifndef _ASM_S390_VGA_H 3 - #define _ASM_S390_VGA_H 4 - 5 - /* Avoid compile errors due to missing asm/vga.h */ 6 - 7 - #endif /* _ASM_S390_VGA_H */
+681
arch/s390/include/asm/vx-insn-asm.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Support for Vector Instructions 4 + * 5 + * Assembler macros to generate .byte/.word code for particular 6 + * vector instructions that are supported by recent binutils (>= 2.26) only. 7 + * 8 + * Copyright IBM Corp. 2015 9 + * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com> 10 + */ 11 + 12 + #ifndef __ASM_S390_VX_INSN_INTERNAL_H 13 + #define __ASM_S390_VX_INSN_INTERNAL_H 14 + 15 + #ifndef __ASM_S390_VX_INSN_H 16 + #error only <asm/vx-insn.h> can be included directly 17 + #endif 18 + 19 + #ifdef __ASSEMBLY__ 20 + 21 + /* Macros to generate vector instruction byte code */ 22 + 23 + /* GR_NUM - Retrieve general-purpose register number 24 + * 25 + * @opd: Operand to store register number 26 + * @r64: String designation register in the format "%rN" 27 + */ 28 + .macro GR_NUM opd gr 29 + \opd = 255 30 + .ifc \gr,%r0 31 + \opd = 0 32 + .endif 33 + .ifc \gr,%r1 34 + \opd = 1 35 + .endif 36 + .ifc \gr,%r2 37 + \opd = 2 38 + .endif 39 + .ifc \gr,%r3 40 + \opd = 3 41 + .endif 42 + .ifc \gr,%r4 43 + \opd = 4 44 + .endif 45 + .ifc \gr,%r5 46 + \opd = 5 47 + .endif 48 + .ifc \gr,%r6 49 + \opd = 6 50 + .endif 51 + .ifc \gr,%r7 52 + \opd = 7 53 + .endif 54 + .ifc \gr,%r8 55 + \opd = 8 56 + .endif 57 + .ifc \gr,%r9 58 + \opd = 9 59 + .endif 60 + .ifc \gr,%r10 61 + \opd = 10 62 + .endif 63 + .ifc \gr,%r11 64 + \opd = 11 65 + .endif 66 + .ifc \gr,%r12 67 + \opd = 12 68 + .endif 69 + .ifc \gr,%r13 70 + \opd = 13 71 + .endif 72 + .ifc \gr,%r14 73 + \opd = 14 74 + .endif 75 + .ifc \gr,%r15 76 + \opd = 15 77 + .endif 78 + .if \opd == 255 79 + \opd = \gr 80 + .endif 81 + .endm 82 + 83 + /* VX_NUM - Retrieve vector register number 84 + * 85 + * @opd: Operand to store register number 86 + * @vxr: String designation register in the format "%vN" 87 + * 88 + * The vector register number is used for as input number to the 89 + * instruction and, as well as, to compute the RXB field of the 90 + * instruction. 91 + */ 92 + .macro VX_NUM opd vxr 93 + \opd = 255 94 + .ifc \vxr,%v0 95 + \opd = 0 96 + .endif 97 + .ifc \vxr,%v1 98 + \opd = 1 99 + .endif 100 + .ifc \vxr,%v2 101 + \opd = 2 102 + .endif 103 + .ifc \vxr,%v3 104 + \opd = 3 105 + .endif 106 + .ifc \vxr,%v4 107 + \opd = 4 108 + .endif 109 + .ifc \vxr,%v5 110 + \opd = 5 111 + .endif 112 + .ifc \vxr,%v6 113 + \opd = 6 114 + .endif 115 + .ifc \vxr,%v7 116 + \opd = 7 117 + .endif 118 + .ifc \vxr,%v8 119 + \opd = 8 120 + .endif 121 + .ifc \vxr,%v9 122 + \opd = 9 123 + .endif 124 + .ifc \vxr,%v10 125 + \opd = 10 126 + .endif 127 + .ifc \vxr,%v11 128 + \opd = 11 129 + .endif 130 + .ifc \vxr,%v12 131 + \opd = 12 132 + .endif 133 + .ifc \vxr,%v13 134 + \opd = 13 135 + .endif 136 + .ifc \vxr,%v14 137 + \opd = 14 138 + .endif 139 + .ifc \vxr,%v15 140 + \opd = 15 141 + .endif 142 + .ifc \vxr,%v16 143 + \opd = 16 144 + .endif 145 + .ifc \vxr,%v17 146 + \opd = 17 147 + .endif 148 + .ifc \vxr,%v18 149 + \opd = 18 150 + .endif 151 + .ifc \vxr,%v19 152 + \opd = 19 153 + .endif 154 + .ifc \vxr,%v20 155 + \opd = 20 156 + .endif 157 + .ifc \vxr,%v21 158 + \opd = 21 159 + .endif 160 + .ifc \vxr,%v22 161 + \opd = 22 162 + .endif 163 + .ifc \vxr,%v23 164 + \opd = 23 165 + .endif 166 + .ifc \vxr,%v24 167 + \opd = 24 168 + .endif 169 + .ifc \vxr,%v25 170 + \opd = 25 171 + .endif 172 + .ifc \vxr,%v26 173 + \opd = 26 174 + .endif 175 + .ifc \vxr,%v27 176 + \opd = 27 177 + .endif 178 + .ifc \vxr,%v28 179 + \opd = 28 180 + .endif 181 + .ifc \vxr,%v29 182 + \opd = 29 183 + .endif 184 + .ifc \vxr,%v30 185 + \opd = 30 186 + .endif 187 + .ifc \vxr,%v31 188 + \opd = 31 189 + .endif 190 + .if \opd == 255 191 + \opd = \vxr 192 + .endif 193 + .endm 194 + 195 + /* RXB - Compute most significant bit used vector registers 196 + * 197 + * @rxb: Operand to store computed RXB value 198 + * @v1: First vector register designated operand 199 + * @v2: Second vector register designated operand 200 + * @v3: Third vector register designated operand 201 + * @v4: Fourth vector register designated operand 202 + */ 203 + .macro RXB rxb v1 v2=0 v3=0 v4=0 204 + \rxb = 0 205 + .if \v1 & 0x10 206 + \rxb = \rxb | 0x08 207 + .endif 208 + .if \v2 & 0x10 209 + \rxb = \rxb | 0x04 210 + .endif 211 + .if \v3 & 0x10 212 + \rxb = \rxb | 0x02 213 + .endif 214 + .if \v4 & 0x10 215 + \rxb = \rxb | 0x01 216 + .endif 217 + .endm 218 + 219 + /* MRXB - Generate Element Size Control and RXB value 220 + * 221 + * @m: Element size control 222 + * @v1: First vector register designated operand (for RXB) 223 + * @v2: Second vector register designated operand (for RXB) 224 + * @v3: Third vector register designated operand (for RXB) 225 + * @v4: Fourth vector register designated operand (for RXB) 226 + */ 227 + .macro MRXB m v1 v2=0 v3=0 v4=0 228 + rxb = 0 229 + RXB rxb, \v1, \v2, \v3, \v4 230 + .byte (\m << 4) | rxb 231 + .endm 232 + 233 + /* MRXBOPC - Generate Element Size Control, RXB, and final Opcode fields 234 + * 235 + * @m: Element size control 236 + * @opc: Opcode 237 + * @v1: First vector register designated operand (for RXB) 238 + * @v2: Second vector register designated operand (for RXB) 239 + * @v3: Third vector register designated operand (for RXB) 240 + * @v4: Fourth vector register designated operand (for RXB) 241 + */ 242 + .macro MRXBOPC m opc v1 v2=0 v3=0 v4=0 243 + MRXB \m, \v1, \v2, \v3, \v4 244 + .byte \opc 245 + .endm 246 + 247 + /* Vector support instructions */ 248 + 249 + /* VECTOR GENERATE BYTE MASK */ 250 + .macro VGBM vr imm2 251 + VX_NUM v1, \vr 252 + .word (0xE700 | ((v1&15) << 4)) 253 + .word \imm2 254 + MRXBOPC 0, 0x44, v1 255 + .endm 256 + .macro VZERO vxr 257 + VGBM \vxr, 0 258 + .endm 259 + .macro VONE vxr 260 + VGBM \vxr, 0xFFFF 261 + .endm 262 + 263 + /* VECTOR LOAD VR ELEMENT FROM GR */ 264 + .macro VLVG v, gr, disp, m 265 + VX_NUM v1, \v 266 + GR_NUM b2, "%r0" 267 + GR_NUM r3, \gr 268 + .word 0xE700 | ((v1&15) << 4) | r3 269 + .word (b2 << 12) | (\disp) 270 + MRXBOPC \m, 0x22, v1 271 + .endm 272 + .macro VLVGB v, gr, index, base 273 + VLVG \v, \gr, \index, \base, 0 274 + .endm 275 + .macro VLVGH v, gr, index 276 + VLVG \v, \gr, \index, 1 277 + .endm 278 + .macro VLVGF v, gr, index 279 + VLVG \v, \gr, \index, 2 280 + .endm 281 + .macro VLVGG v, gr, index 282 + VLVG \v, \gr, \index, 3 283 + .endm 284 + 285 + /* VECTOR LOAD REGISTER */ 286 + .macro VLR v1, v2 287 + VX_NUM v1, \v1 288 + VX_NUM v2, \v2 289 + .word 0xE700 | ((v1&15) << 4) | (v2&15) 290 + .word 0 291 + MRXBOPC 0, 0x56, v1, v2 292 + .endm 293 + 294 + /* VECTOR LOAD */ 295 + .macro VL v, disp, index="%r0", base 296 + VX_NUM v1, \v 297 + GR_NUM x2, \index 298 + GR_NUM b2, \base 299 + .word 0xE700 | ((v1&15) << 4) | x2 300 + .word (b2 << 12) | (\disp) 301 + MRXBOPC 0, 0x06, v1 302 + .endm 303 + 304 + /* VECTOR LOAD ELEMENT */ 305 + .macro VLEx vr1, disp, index="%r0", base, m3, opc 306 + VX_NUM v1, \vr1 307 + GR_NUM x2, \index 308 + GR_NUM b2, \base 309 + .word 0xE700 | ((v1&15) << 4) | x2 310 + .word (b2 << 12) | (\disp) 311 + MRXBOPC \m3, \opc, v1 312 + .endm 313 + .macro VLEB vr1, disp, index="%r0", base, m3 314 + VLEx \vr1, \disp, \index, \base, \m3, 0x00 315 + .endm 316 + .macro VLEH vr1, disp, index="%r0", base, m3 317 + VLEx \vr1, \disp, \index, \base, \m3, 0x01 318 + .endm 319 + .macro VLEF vr1, disp, index="%r0", base, m3 320 + VLEx \vr1, \disp, \index, \base, \m3, 0x03 321 + .endm 322 + .macro VLEG vr1, disp, index="%r0", base, m3 323 + VLEx \vr1, \disp, \index, \base, \m3, 0x02 324 + .endm 325 + 326 + /* VECTOR LOAD ELEMENT IMMEDIATE */ 327 + .macro VLEIx vr1, imm2, m3, opc 328 + VX_NUM v1, \vr1 329 + .word 0xE700 | ((v1&15) << 4) 330 + .word \imm2 331 + MRXBOPC \m3, \opc, v1 332 + .endm 333 + .macro VLEIB vr1, imm2, index 334 + VLEIx \vr1, \imm2, \index, 0x40 335 + .endm 336 + .macro VLEIH vr1, imm2, index 337 + VLEIx \vr1, \imm2, \index, 0x41 338 + .endm 339 + .macro VLEIF vr1, imm2, index 340 + VLEIx \vr1, \imm2, \index, 0x43 341 + .endm 342 + .macro VLEIG vr1, imm2, index 343 + VLEIx \vr1, \imm2, \index, 0x42 344 + .endm 345 + 346 + /* VECTOR LOAD GR FROM VR ELEMENT */ 347 + .macro VLGV gr, vr, disp, base="%r0", m 348 + GR_NUM r1, \gr 349 + GR_NUM b2, \base 350 + VX_NUM v3, \vr 351 + .word 0xE700 | (r1 << 4) | (v3&15) 352 + .word (b2 << 12) | (\disp) 353 + MRXBOPC \m, 0x21, v3 354 + .endm 355 + .macro VLGVB gr, vr, disp, base="%r0" 356 + VLGV \gr, \vr, \disp, \base, 0 357 + .endm 358 + .macro VLGVH gr, vr, disp, base="%r0" 359 + VLGV \gr, \vr, \disp, \base, 1 360 + .endm 361 + .macro VLGVF gr, vr, disp, base="%r0" 362 + VLGV \gr, \vr, \disp, \base, 2 363 + .endm 364 + .macro VLGVG gr, vr, disp, base="%r0" 365 + VLGV \gr, \vr, \disp, \base, 3 366 + .endm 367 + 368 + /* VECTOR LOAD MULTIPLE */ 369 + .macro VLM vfrom, vto, disp, base, hint=3 370 + VX_NUM v1, \vfrom 371 + VX_NUM v3, \vto 372 + GR_NUM b2, \base 373 + .word 0xE700 | ((v1&15) << 4) | (v3&15) 374 + .word (b2 << 12) | (\disp) 375 + MRXBOPC \hint, 0x36, v1, v3 376 + .endm 377 + 378 + /* VECTOR STORE */ 379 + .macro VST vr1, disp, index="%r0", base 380 + VX_NUM v1, \vr1 381 + GR_NUM x2, \index 382 + GR_NUM b2, \base 383 + .word 0xE700 | ((v1&15) << 4) | (x2&15) 384 + .word (b2 << 12) | (\disp) 385 + MRXBOPC 0, 0x0E, v1 386 + .endm 387 + 388 + /* VECTOR STORE MULTIPLE */ 389 + .macro VSTM vfrom, vto, disp, base, hint=3 390 + VX_NUM v1, \vfrom 391 + VX_NUM v3, \vto 392 + GR_NUM b2, \base 393 + .word 0xE700 | ((v1&15) << 4) | (v3&15) 394 + .word (b2 << 12) | (\disp) 395 + MRXBOPC \hint, 0x3E, v1, v3 396 + .endm 397 + 398 + /* VECTOR PERMUTE */ 399 + .macro VPERM vr1, vr2, vr3, vr4 400 + VX_NUM v1, \vr1 401 + VX_NUM v2, \vr2 402 + VX_NUM v3, \vr3 403 + VX_NUM v4, \vr4 404 + .word 0xE700 | ((v1&15) << 4) | (v2&15) 405 + .word ((v3&15) << 12) 406 + MRXBOPC (v4&15), 0x8C, v1, v2, v3, v4 407 + .endm 408 + 409 + /* VECTOR UNPACK LOGICAL LOW */ 410 + .macro VUPLL vr1, vr2, m3 411 + VX_NUM v1, \vr1 412 + VX_NUM v2, \vr2 413 + .word 0xE700 | ((v1&15) << 4) | (v2&15) 414 + .word 0x0000 415 + MRXBOPC \m3, 0xD4, v1, v2 416 + .endm 417 + .macro VUPLLB vr1, vr2 418 + VUPLL \vr1, \vr2, 0 419 + .endm 420 + .macro VUPLLH vr1, vr2 421 + VUPLL \vr1, \vr2, 1 422 + .endm 423 + .macro VUPLLF vr1, vr2 424 + VUPLL \vr1, \vr2, 2 425 + .endm 426 + 427 + /* VECTOR PERMUTE DOUBLEWORD IMMEDIATE */ 428 + .macro VPDI vr1, vr2, vr3, m4 429 + VX_NUM v1, \vr1 430 + VX_NUM v2, \vr2 431 + VX_NUM v3, \vr3 432 + .word 0xE700 | ((v1&15) << 4) | (v2&15) 433 + .word ((v3&15) << 12) 434 + MRXBOPC \m4, 0x84, v1, v2, v3 435 + .endm 436 + 437 + /* VECTOR REPLICATE */ 438 + .macro VREP vr1, vr3, imm2, m4 439 + VX_NUM v1, \vr1 440 + VX_NUM v3, \vr3 441 + .word 0xE700 | ((v1&15) << 4) | (v3&15) 442 + .word \imm2 443 + MRXBOPC \m4, 0x4D, v1, v3 444 + .endm 445 + .macro VREPB vr1, vr3, imm2 446 + VREP \vr1, \vr3, \imm2, 0 447 + .endm 448 + .macro VREPH vr1, vr3, imm2 449 + VREP \vr1, \vr3, \imm2, 1 450 + .endm 451 + .macro VREPF vr1, vr3, imm2 452 + VREP \vr1, \vr3, \imm2, 2 453 + .endm 454 + .macro VREPG vr1, vr3, imm2 455 + VREP \vr1, \vr3, \imm2, 3 456 + .endm 457 + 458 + /* VECTOR MERGE HIGH */ 459 + .macro VMRH vr1, vr2, vr3, m4 460 + VX_NUM v1, \vr1 461 + VX_NUM v2, \vr2 462 + VX_NUM v3, \vr3 463 + .word 0xE700 | ((v1&15) << 4) | (v2&15) 464 + .word ((v3&15) << 12) 465 + MRXBOPC \m4, 0x61, v1, v2, v3 466 + .endm 467 + .macro VMRHB vr1, vr2, vr3 468 + VMRH \vr1, \vr2, \vr3, 0 469 + .endm 470 + .macro VMRHH vr1, vr2, vr3 471 + VMRH \vr1, \vr2, \vr3, 1 472 + .endm 473 + .macro VMRHF vr1, vr2, vr3 474 + VMRH \vr1, \vr2, \vr3, 2 475 + .endm 476 + .macro VMRHG vr1, vr2, vr3 477 + VMRH \vr1, \vr2, \vr3, 3 478 + .endm 479 + 480 + /* VECTOR MERGE LOW */ 481 + .macro VMRL vr1, vr2, vr3, m4 482 + VX_NUM v1, \vr1 483 + VX_NUM v2, \vr2 484 + VX_NUM v3, \vr3 485 + .word 0xE700 | ((v1&15) << 4) | (v2&15) 486 + .word ((v3&15) << 12) 487 + MRXBOPC \m4, 0x60, v1, v2, v3 488 + .endm 489 + .macro VMRLB vr1, vr2, vr3 490 + VMRL \vr1, \vr2, \vr3, 0 491 + .endm 492 + .macro VMRLH vr1, vr2, vr3 493 + VMRL \vr1, \vr2, \vr3, 1 494 + .endm 495 + .macro VMRLF vr1, vr2, vr3 496 + VMRL \vr1, \vr2, \vr3, 2 497 + .endm 498 + .macro VMRLG vr1, vr2, vr3 499 + VMRL \vr1, \vr2, \vr3, 3 500 + .endm 501 + 502 + 503 + /* Vector integer instructions */ 504 + 505 + /* VECTOR AND */ 506 + .macro VN vr1, vr2, vr3 507 + VX_NUM v1, \vr1 508 + VX_NUM v2, \vr2 509 + VX_NUM v3, \vr3 510 + .word 0xE700 | ((v1&15) << 4) | (v2&15) 511 + .word ((v3&15) << 12) 512 + MRXBOPC 0, 0x68, v1, v2, v3 513 + .endm 514 + 515 + /* VECTOR EXCLUSIVE OR */ 516 + .macro VX vr1, vr2, vr3 517 + VX_NUM v1, \vr1 518 + VX_NUM v2, \vr2 519 + VX_NUM v3, \vr3 520 + .word 0xE700 | ((v1&15) << 4) | (v2&15) 521 + .word ((v3&15) << 12) 522 + MRXBOPC 0, 0x6D, v1, v2, v3 523 + .endm 524 + 525 + /* VECTOR GALOIS FIELD MULTIPLY SUM */ 526 + .macro VGFM vr1, vr2, vr3, m4 527 + VX_NUM v1, \vr1 528 + VX_NUM v2, \vr2 529 + VX_NUM v3, \vr3 530 + .word 0xE700 | ((v1&15) << 4) | (v2&15) 531 + .word ((v3&15) << 12) 532 + MRXBOPC \m4, 0xB4, v1, v2, v3 533 + .endm 534 + .macro VGFMB vr1, vr2, vr3 535 + VGFM \vr1, \vr2, \vr3, 0 536 + .endm 537 + .macro VGFMH vr1, vr2, vr3 538 + VGFM \vr1, \vr2, \vr3, 1 539 + .endm 540 + .macro VGFMF vr1, vr2, vr3 541 + VGFM \vr1, \vr2, \vr3, 2 542 + .endm 543 + .macro VGFMG vr1, vr2, vr3 544 + VGFM \vr1, \vr2, \vr3, 3 545 + .endm 546 + 547 + /* VECTOR GALOIS FIELD MULTIPLY SUM AND ACCUMULATE */ 548 + .macro VGFMA vr1, vr2, vr3, vr4, m5 549 + VX_NUM v1, \vr1 550 + VX_NUM v2, \vr2 551 + VX_NUM v3, \vr3 552 + VX_NUM v4, \vr4 553 + .word 0xE700 | ((v1&15) << 4) | (v2&15) 554 + .word ((v3&15) << 12) | (\m5 << 8) 555 + MRXBOPC (v4&15), 0xBC, v1, v2, v3, v4 556 + .endm 557 + .macro VGFMAB vr1, vr2, vr3, vr4 558 + VGFMA \vr1, \vr2, \vr3, \vr4, 0 559 + .endm 560 + .macro VGFMAH vr1, vr2, vr3, vr4 561 + VGFMA \vr1, \vr2, \vr3, \vr4, 1 562 + .endm 563 + .macro VGFMAF vr1, vr2, vr3, vr4 564 + VGFMA \vr1, \vr2, \vr3, \vr4, 2 565 + .endm 566 + .macro VGFMAG vr1, vr2, vr3, vr4 567 + VGFMA \vr1, \vr2, \vr3, \vr4, 3 568 + .endm 569 + 570 + /* VECTOR SHIFT RIGHT LOGICAL BY BYTE */ 571 + .macro VSRLB vr1, vr2, vr3 572 + VX_NUM v1, \vr1 573 + VX_NUM v2, \vr2 574 + VX_NUM v3, \vr3 575 + .word 0xE700 | ((v1&15) << 4) | (v2&15) 576 + .word ((v3&15) << 12) 577 + MRXBOPC 0, 0x7D, v1, v2, v3 578 + .endm 579 + 580 + /* VECTOR REPLICATE IMMEDIATE */ 581 + .macro VREPI vr1, imm2, m3 582 + VX_NUM v1, \vr1 583 + .word 0xE700 | ((v1&15) << 4) 584 + .word \imm2 585 + MRXBOPC \m3, 0x45, v1 586 + .endm 587 + .macro VREPIB vr1, imm2 588 + VREPI \vr1, \imm2, 0 589 + .endm 590 + .macro VREPIH vr1, imm2 591 + VREPI \vr1, \imm2, 1 592 + .endm 593 + .macro VREPIF vr1, imm2 594 + VREPI \vr1, \imm2, 2 595 + .endm 596 + .macro VREPIG vr1, imm2 597 + VREP \vr1, \imm2, 3 598 + .endm 599 + 600 + /* VECTOR ADD */ 601 + .macro VA vr1, vr2, vr3, m4 602 + VX_NUM v1, \vr1 603 + VX_NUM v2, \vr2 604 + VX_NUM v3, \vr3 605 + .word 0xE700 | ((v1&15) << 4) | (v2&15) 606 + .word ((v3&15) << 12) 607 + MRXBOPC \m4, 0xF3, v1, v2, v3 608 + .endm 609 + .macro VAB vr1, vr2, vr3 610 + VA \vr1, \vr2, \vr3, 0 611 + .endm 612 + .macro VAH vr1, vr2, vr3 613 + VA \vr1, \vr2, \vr3, 1 614 + .endm 615 + .macro VAF vr1, vr2, vr3 616 + VA \vr1, \vr2, \vr3, 2 617 + .endm 618 + .macro VAG vr1, vr2, vr3 619 + VA \vr1, \vr2, \vr3, 3 620 + .endm 621 + .macro VAQ vr1, vr2, vr3 622 + VA \vr1, \vr2, \vr3, 4 623 + .endm 624 + 625 + /* VECTOR ELEMENT SHIFT RIGHT ARITHMETIC */ 626 + .macro VESRAV vr1, vr2, vr3, m4 627 + VX_NUM v1, \vr1 628 + VX_NUM v2, \vr2 629 + VX_NUM v3, \vr3 630 + .word 0xE700 | ((v1&15) << 4) | (v2&15) 631 + .word ((v3&15) << 12) 632 + MRXBOPC \m4, 0x7A, v1, v2, v3 633 + .endm 634 + 635 + .macro VESRAVB vr1, vr2, vr3 636 + VESRAV \vr1, \vr2, \vr3, 0 637 + .endm 638 + .macro VESRAVH vr1, vr2, vr3 639 + VESRAV \vr1, \vr2, \vr3, 1 640 + .endm 641 + .macro VESRAVF vr1, vr2, vr3 642 + VESRAV \vr1, \vr2, \vr3, 2 643 + .endm 644 + .macro VESRAVG vr1, vr2, vr3 645 + VESRAV \vr1, \vr2, \vr3, 3 646 + .endm 647 + 648 + /* VECTOR ELEMENT ROTATE LEFT LOGICAL */ 649 + .macro VERLL vr1, vr3, disp, base="%r0", m4 650 + VX_NUM v1, \vr1 651 + VX_NUM v3, \vr3 652 + GR_NUM b2, \base 653 + .word 0xE700 | ((v1&15) << 4) | (v3&15) 654 + .word (b2 << 12) | (\disp) 655 + MRXBOPC \m4, 0x33, v1, v3 656 + .endm 657 + .macro VERLLB vr1, vr3, disp, base="%r0" 658 + VERLL \vr1, \vr3, \disp, \base, 0 659 + .endm 660 + .macro VERLLH vr1, vr3, disp, base="%r0" 661 + VERLL \vr1, \vr3, \disp, \base, 1 662 + .endm 663 + .macro VERLLF vr1, vr3, disp, base="%r0" 664 + VERLL \vr1, \vr3, \disp, \base, 2 665 + .endm 666 + .macro VERLLG vr1, vr3, disp, base="%r0" 667 + VERLL \vr1, \vr3, \disp, \base, 3 668 + .endm 669 + 670 + /* VECTOR SHIFT LEFT DOUBLE BY BYTE */ 671 + .macro VSLDB vr1, vr2, vr3, imm4 672 + VX_NUM v1, \vr1 673 + VX_NUM v2, \vr2 674 + VX_NUM v3, \vr3 675 + .word 0xE700 | ((v1&15) << 4) | (v2&15) 676 + .word ((v3&15) << 12) | (\imm4) 677 + MRXBOPC 0, 0x77, v1, v2, v3 678 + .endm 679 + 680 + #endif /* __ASSEMBLY__ */ 681 + #endif /* __ASM_S390_VX_INSN_INTERNAL_H */
+6 -665
arch/s390/include/asm/vx-insn.h
··· 2 2 /* 3 3 * Support for Vector Instructions 4 4 * 5 - * Assembler macros to generate .byte/.word code for particular 6 - * vector instructions that are supported by recent binutils (>= 2.26) only. 7 - * 8 - * Copyright IBM Corp. 2015 9 - * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com> 5 + * This wrapper header file allows to use the vector instruction macros in 6 + * both assembler files as well as in inline assemblies in C files. 10 7 */ 11 8 12 9 #ifndef __ASM_S390_VX_INSN_H 13 10 #define __ASM_S390_VX_INSN_H 14 11 15 - #ifdef __ASSEMBLY__ 12 + #include <asm/vx-insn-asm.h> 16 13 14 + #ifndef __ASSEMBLY__ 17 15 18 - /* Macros to generate vector instruction byte code */ 16 + asm(".include \"asm/vx-insn-asm.h\"\n"); 19 17 20 - /* GR_NUM - Retrieve general-purpose register number 21 - * 22 - * @opd: Operand to store register number 23 - * @r64: String designation register in the format "%rN" 24 - */ 25 - .macro GR_NUM opd gr 26 - \opd = 255 27 - .ifc \gr,%r0 28 - \opd = 0 29 - .endif 30 - .ifc \gr,%r1 31 - \opd = 1 32 - .endif 33 - .ifc \gr,%r2 34 - \opd = 2 35 - .endif 36 - .ifc \gr,%r3 37 - \opd = 3 38 - .endif 39 - .ifc \gr,%r4 40 - \opd = 4 41 - .endif 42 - .ifc \gr,%r5 43 - \opd = 5 44 - .endif 45 - .ifc \gr,%r6 46 - \opd = 6 47 - .endif 48 - .ifc \gr,%r7 49 - \opd = 7 50 - .endif 51 - .ifc \gr,%r8 52 - \opd = 8 53 - .endif 54 - .ifc \gr,%r9 55 - \opd = 9 56 - .endif 57 - .ifc \gr,%r10 58 - \opd = 10 59 - .endif 60 - .ifc \gr,%r11 61 - \opd = 11 62 - .endif 63 - .ifc \gr,%r12 64 - \opd = 12 65 - .endif 66 - .ifc \gr,%r13 67 - \opd = 13 68 - .endif 69 - .ifc \gr,%r14 70 - \opd = 14 71 - .endif 72 - .ifc \gr,%r15 73 - \opd = 15 74 - .endif 75 - .if \opd == 255 76 - \opd = \gr 77 - .endif 78 - .endm 79 - 80 - /* VX_NUM - Retrieve vector register number 81 - * 82 - * @opd: Operand to store register number 83 - * @vxr: String designation register in the format "%vN" 84 - * 85 - * The vector register number is used for as input number to the 86 - * instruction and, as well as, to compute the RXB field of the 87 - * instruction. 88 - */ 89 - .macro VX_NUM opd vxr 90 - \opd = 255 91 - .ifc \vxr,%v0 92 - \opd = 0 93 - .endif 94 - .ifc \vxr,%v1 95 - \opd = 1 96 - .endif 97 - .ifc \vxr,%v2 98 - \opd = 2 99 - .endif 100 - .ifc \vxr,%v3 101 - \opd = 3 102 - .endif 103 - .ifc \vxr,%v4 104 - \opd = 4 105 - .endif 106 - .ifc \vxr,%v5 107 - \opd = 5 108 - .endif 109 - .ifc \vxr,%v6 110 - \opd = 6 111 - .endif 112 - .ifc \vxr,%v7 113 - \opd = 7 114 - .endif 115 - .ifc \vxr,%v8 116 - \opd = 8 117 - .endif 118 - .ifc \vxr,%v9 119 - \opd = 9 120 - .endif 121 - .ifc \vxr,%v10 122 - \opd = 10 123 - .endif 124 - .ifc \vxr,%v11 125 - \opd = 11 126 - .endif 127 - .ifc \vxr,%v12 128 - \opd = 12 129 - .endif 130 - .ifc \vxr,%v13 131 - \opd = 13 132 - .endif 133 - .ifc \vxr,%v14 134 - \opd = 14 135 - .endif 136 - .ifc \vxr,%v15 137 - \opd = 15 138 - .endif 139 - .ifc \vxr,%v16 140 - \opd = 16 141 - .endif 142 - .ifc \vxr,%v17 143 - \opd = 17 144 - .endif 145 - .ifc \vxr,%v18 146 - \opd = 18 147 - .endif 148 - .ifc \vxr,%v19 149 - \opd = 19 150 - .endif 151 - .ifc \vxr,%v20 152 - \opd = 20 153 - .endif 154 - .ifc \vxr,%v21 155 - \opd = 21 156 - .endif 157 - .ifc \vxr,%v22 158 - \opd = 22 159 - .endif 160 - .ifc \vxr,%v23 161 - \opd = 23 162 - .endif 163 - .ifc \vxr,%v24 164 - \opd = 24 165 - .endif 166 - .ifc \vxr,%v25 167 - \opd = 25 168 - .endif 169 - .ifc \vxr,%v26 170 - \opd = 26 171 - .endif 172 - .ifc \vxr,%v27 173 - \opd = 27 174 - .endif 175 - .ifc \vxr,%v28 176 - \opd = 28 177 - .endif 178 - .ifc \vxr,%v29 179 - \opd = 29 180 - .endif 181 - .ifc \vxr,%v30 182 - \opd = 30 183 - .endif 184 - .ifc \vxr,%v31 185 - \opd = 31 186 - .endif 187 - .if \opd == 255 188 - \opd = \vxr 189 - .endif 190 - .endm 191 - 192 - /* RXB - Compute most significant bit used vector registers 193 - * 194 - * @rxb: Operand to store computed RXB value 195 - * @v1: First vector register designated operand 196 - * @v2: Second vector register designated operand 197 - * @v3: Third vector register designated operand 198 - * @v4: Fourth vector register designated operand 199 - */ 200 - .macro RXB rxb v1 v2=0 v3=0 v4=0 201 - \rxb = 0 202 - .if \v1 & 0x10 203 - \rxb = \rxb | 0x08 204 - .endif 205 - .if \v2 & 0x10 206 - \rxb = \rxb | 0x04 207 - .endif 208 - .if \v3 & 0x10 209 - \rxb = \rxb | 0x02 210 - .endif 211 - .if \v4 & 0x10 212 - \rxb = \rxb | 0x01 213 - .endif 214 - .endm 215 - 216 - /* MRXB - Generate Element Size Control and RXB value 217 - * 218 - * @m: Element size control 219 - * @v1: First vector register designated operand (for RXB) 220 - * @v2: Second vector register designated operand (for RXB) 221 - * @v3: Third vector register designated operand (for RXB) 222 - * @v4: Fourth vector register designated operand (for RXB) 223 - */ 224 - .macro MRXB m v1 v2=0 v3=0 v4=0 225 - rxb = 0 226 - RXB rxb, \v1, \v2, \v3, \v4 227 - .byte (\m << 4) | rxb 228 - .endm 229 - 230 - /* MRXBOPC - Generate Element Size Control, RXB, and final Opcode fields 231 - * 232 - * @m: Element size control 233 - * @opc: Opcode 234 - * @v1: First vector register designated operand (for RXB) 235 - * @v2: Second vector register designated operand (for RXB) 236 - * @v3: Third vector register designated operand (for RXB) 237 - * @v4: Fourth vector register designated operand (for RXB) 238 - */ 239 - .macro MRXBOPC m opc v1 v2=0 v3=0 v4=0 240 - MRXB \m, \v1, \v2, \v3, \v4 241 - .byte \opc 242 - .endm 243 - 244 - /* Vector support instructions */ 245 - 246 - /* VECTOR GENERATE BYTE MASK */ 247 - .macro VGBM vr imm2 248 - VX_NUM v1, \vr 249 - .word (0xE700 | ((v1&15) << 4)) 250 - .word \imm2 251 - MRXBOPC 0, 0x44, v1 252 - .endm 253 - .macro VZERO vxr 254 - VGBM \vxr, 0 255 - .endm 256 - .macro VONE vxr 257 - VGBM \vxr, 0xFFFF 258 - .endm 259 - 260 - /* VECTOR LOAD VR ELEMENT FROM GR */ 261 - .macro VLVG v, gr, disp, m 262 - VX_NUM v1, \v 263 - GR_NUM b2, "%r0" 264 - GR_NUM r3, \gr 265 - .word 0xE700 | ((v1&15) << 4) | r3 266 - .word (b2 << 12) | (\disp) 267 - MRXBOPC \m, 0x22, v1 268 - .endm 269 - .macro VLVGB v, gr, index, base 270 - VLVG \v, \gr, \index, \base, 0 271 - .endm 272 - .macro VLVGH v, gr, index 273 - VLVG \v, \gr, \index, 1 274 - .endm 275 - .macro VLVGF v, gr, index 276 - VLVG \v, \gr, \index, 2 277 - .endm 278 - .macro VLVGG v, gr, index 279 - VLVG \v, \gr, \index, 3 280 - .endm 281 - 282 - /* VECTOR LOAD REGISTER */ 283 - .macro VLR v1, v2 284 - VX_NUM v1, \v1 285 - VX_NUM v2, \v2 286 - .word 0xE700 | ((v1&15) << 4) | (v2&15) 287 - .word 0 288 - MRXBOPC 0, 0x56, v1, v2 289 - .endm 290 - 291 - /* VECTOR LOAD */ 292 - .macro VL v, disp, index="%r0", base 293 - VX_NUM v1, \v 294 - GR_NUM x2, \index 295 - GR_NUM b2, \base 296 - .word 0xE700 | ((v1&15) << 4) | x2 297 - .word (b2 << 12) | (\disp) 298 - MRXBOPC 0, 0x06, v1 299 - .endm 300 - 301 - /* VECTOR LOAD ELEMENT */ 302 - .macro VLEx vr1, disp, index="%r0", base, m3, opc 303 - VX_NUM v1, \vr1 304 - GR_NUM x2, \index 305 - GR_NUM b2, \base 306 - .word 0xE700 | ((v1&15) << 4) | x2 307 - .word (b2 << 12) | (\disp) 308 - MRXBOPC \m3, \opc, v1 309 - .endm 310 - .macro VLEB vr1, disp, index="%r0", base, m3 311 - VLEx \vr1, \disp, \index, \base, \m3, 0x00 312 - .endm 313 - .macro VLEH vr1, disp, index="%r0", base, m3 314 - VLEx \vr1, \disp, \index, \base, \m3, 0x01 315 - .endm 316 - .macro VLEF vr1, disp, index="%r0", base, m3 317 - VLEx \vr1, \disp, \index, \base, \m3, 0x03 318 - .endm 319 - .macro VLEG vr1, disp, index="%r0", base, m3 320 - VLEx \vr1, \disp, \index, \base, \m3, 0x02 321 - .endm 322 - 323 - /* VECTOR LOAD ELEMENT IMMEDIATE */ 324 - .macro VLEIx vr1, imm2, m3, opc 325 - VX_NUM v1, \vr1 326 - .word 0xE700 | ((v1&15) << 4) 327 - .word \imm2 328 - MRXBOPC \m3, \opc, v1 329 - .endm 330 - .macro VLEIB vr1, imm2, index 331 - VLEIx \vr1, \imm2, \index, 0x40 332 - .endm 333 - .macro VLEIH vr1, imm2, index 334 - VLEIx \vr1, \imm2, \index, 0x41 335 - .endm 336 - .macro VLEIF vr1, imm2, index 337 - VLEIx \vr1, \imm2, \index, 0x43 338 - .endm 339 - .macro VLEIG vr1, imm2, index 340 - VLEIx \vr1, \imm2, \index, 0x42 341 - .endm 342 - 343 - /* VECTOR LOAD GR FROM VR ELEMENT */ 344 - .macro VLGV gr, vr, disp, base="%r0", m 345 - GR_NUM r1, \gr 346 - GR_NUM b2, \base 347 - VX_NUM v3, \vr 348 - .word 0xE700 | (r1 << 4) | (v3&15) 349 - .word (b2 << 12) | (\disp) 350 - MRXBOPC \m, 0x21, v3 351 - .endm 352 - .macro VLGVB gr, vr, disp, base="%r0" 353 - VLGV \gr, \vr, \disp, \base, 0 354 - .endm 355 - .macro VLGVH gr, vr, disp, base="%r0" 356 - VLGV \gr, \vr, \disp, \base, 1 357 - .endm 358 - .macro VLGVF gr, vr, disp, base="%r0" 359 - VLGV \gr, \vr, \disp, \base, 2 360 - .endm 361 - .macro VLGVG gr, vr, disp, base="%r0" 362 - VLGV \gr, \vr, \disp, \base, 3 363 - .endm 364 - 365 - /* VECTOR LOAD MULTIPLE */ 366 - .macro VLM vfrom, vto, disp, base, hint=3 367 - VX_NUM v1, \vfrom 368 - VX_NUM v3, \vto 369 - GR_NUM b2, \base 370 - .word 0xE700 | ((v1&15) << 4) | (v3&15) 371 - .word (b2 << 12) | (\disp) 372 - MRXBOPC \hint, 0x36, v1, v3 373 - .endm 374 - 375 - /* VECTOR STORE */ 376 - .macro VST vr1, disp, index="%r0", base 377 - VX_NUM v1, \vr1 378 - GR_NUM x2, \index 379 - GR_NUM b2, \base 380 - .word 0xE700 | ((v1&15) << 4) | (x2&15) 381 - .word (b2 << 12) | (\disp) 382 - MRXBOPC 0, 0x0E, v1 383 - .endm 384 - 385 - /* VECTOR STORE MULTIPLE */ 386 - .macro VSTM vfrom, vto, disp, base, hint=3 387 - VX_NUM v1, \vfrom 388 - VX_NUM v3, \vto 389 - GR_NUM b2, \base 390 - .word 0xE700 | ((v1&15) << 4) | (v3&15) 391 - .word (b2 << 12) | (\disp) 392 - MRXBOPC \hint, 0x3E, v1, v3 393 - .endm 394 - 395 - /* VECTOR PERMUTE */ 396 - .macro VPERM vr1, vr2, vr3, vr4 397 - VX_NUM v1, \vr1 398 - VX_NUM v2, \vr2 399 - VX_NUM v3, \vr3 400 - VX_NUM v4, \vr4 401 - .word 0xE700 | ((v1&15) << 4) | (v2&15) 402 - .word ((v3&15) << 12) 403 - MRXBOPC (v4&15), 0x8C, v1, v2, v3, v4 404 - .endm 405 - 406 - /* VECTOR UNPACK LOGICAL LOW */ 407 - .macro VUPLL vr1, vr2, m3 408 - VX_NUM v1, \vr1 409 - VX_NUM v2, \vr2 410 - .word 0xE700 | ((v1&15) << 4) | (v2&15) 411 - .word 0x0000 412 - MRXBOPC \m3, 0xD4, v1, v2 413 - .endm 414 - .macro VUPLLB vr1, vr2 415 - VUPLL \vr1, \vr2, 0 416 - .endm 417 - .macro VUPLLH vr1, vr2 418 - VUPLL \vr1, \vr2, 1 419 - .endm 420 - .macro VUPLLF vr1, vr2 421 - VUPLL \vr1, \vr2, 2 422 - .endm 423 - 424 - /* VECTOR PERMUTE DOUBLEWORD IMMEDIATE */ 425 - .macro VPDI vr1, vr2, vr3, m4 426 - VX_NUM v1, \vr1 427 - VX_NUM v2, \vr2 428 - VX_NUM v3, \vr3 429 - .word 0xE700 | ((v1&15) << 4) | (v2&15) 430 - .word ((v3&15) << 12) 431 - MRXBOPC \m4, 0x84, v1, v2, v3 432 - .endm 433 - 434 - /* VECTOR REPLICATE */ 435 - .macro VREP vr1, vr3, imm2, m4 436 - VX_NUM v1, \vr1 437 - VX_NUM v3, \vr3 438 - .word 0xE700 | ((v1&15) << 4) | (v3&15) 439 - .word \imm2 440 - MRXBOPC \m4, 0x4D, v1, v3 441 - .endm 442 - .macro VREPB vr1, vr3, imm2 443 - VREP \vr1, \vr3, \imm2, 0 444 - .endm 445 - .macro VREPH vr1, vr3, imm2 446 - VREP \vr1, \vr3, \imm2, 1 447 - .endm 448 - .macro VREPF vr1, vr3, imm2 449 - VREP \vr1, \vr3, \imm2, 2 450 - .endm 451 - .macro VREPG vr1, vr3, imm2 452 - VREP \vr1, \vr3, \imm2, 3 453 - .endm 454 - 455 - /* VECTOR MERGE HIGH */ 456 - .macro VMRH vr1, vr2, vr3, m4 457 - VX_NUM v1, \vr1 458 - VX_NUM v2, \vr2 459 - VX_NUM v3, \vr3 460 - .word 0xE700 | ((v1&15) << 4) | (v2&15) 461 - .word ((v3&15) << 12) 462 - MRXBOPC \m4, 0x61, v1, v2, v3 463 - .endm 464 - .macro VMRHB vr1, vr2, vr3 465 - VMRH \vr1, \vr2, \vr3, 0 466 - .endm 467 - .macro VMRHH vr1, vr2, vr3 468 - VMRH \vr1, \vr2, \vr3, 1 469 - .endm 470 - .macro VMRHF vr1, vr2, vr3 471 - VMRH \vr1, \vr2, \vr3, 2 472 - .endm 473 - .macro VMRHG vr1, vr2, vr3 474 - VMRH \vr1, \vr2, \vr3, 3 475 - .endm 476 - 477 - /* VECTOR MERGE LOW */ 478 - .macro VMRL vr1, vr2, vr3, m4 479 - VX_NUM v1, \vr1 480 - VX_NUM v2, \vr2 481 - VX_NUM v3, \vr3 482 - .word 0xE700 | ((v1&15) << 4) | (v2&15) 483 - .word ((v3&15) << 12) 484 - MRXBOPC \m4, 0x60, v1, v2, v3 485 - .endm 486 - .macro VMRLB vr1, vr2, vr3 487 - VMRL \vr1, \vr2, \vr3, 0 488 - .endm 489 - .macro VMRLH vr1, vr2, vr3 490 - VMRL \vr1, \vr2, \vr3, 1 491 - .endm 492 - .macro VMRLF vr1, vr2, vr3 493 - VMRL \vr1, \vr2, \vr3, 2 494 - .endm 495 - .macro VMRLG vr1, vr2, vr3 496 - VMRL \vr1, \vr2, \vr3, 3 497 - .endm 498 - 499 - 500 - /* Vector integer instructions */ 501 - 502 - /* VECTOR AND */ 503 - .macro VN vr1, vr2, vr3 504 - VX_NUM v1, \vr1 505 - VX_NUM v2, \vr2 506 - VX_NUM v3, \vr3 507 - .word 0xE700 | ((v1&15) << 4) | (v2&15) 508 - .word ((v3&15) << 12) 509 - MRXBOPC 0, 0x68, v1, v2, v3 510 - .endm 511 - 512 - /* VECTOR EXCLUSIVE OR */ 513 - .macro VX vr1, vr2, vr3 514 - VX_NUM v1, \vr1 515 - VX_NUM v2, \vr2 516 - VX_NUM v3, \vr3 517 - .word 0xE700 | ((v1&15) << 4) | (v2&15) 518 - .word ((v3&15) << 12) 519 - MRXBOPC 0, 0x6D, v1, v2, v3 520 - .endm 521 - 522 - /* VECTOR GALOIS FIELD MULTIPLY SUM */ 523 - .macro VGFM vr1, vr2, vr3, m4 524 - VX_NUM v1, \vr1 525 - VX_NUM v2, \vr2 526 - VX_NUM v3, \vr3 527 - .word 0xE700 | ((v1&15) << 4) | (v2&15) 528 - .word ((v3&15) << 12) 529 - MRXBOPC \m4, 0xB4, v1, v2, v3 530 - .endm 531 - .macro VGFMB vr1, vr2, vr3 532 - VGFM \vr1, \vr2, \vr3, 0 533 - .endm 534 - .macro VGFMH vr1, vr2, vr3 535 - VGFM \vr1, \vr2, \vr3, 1 536 - .endm 537 - .macro VGFMF vr1, vr2, vr3 538 - VGFM \vr1, \vr2, \vr3, 2 539 - .endm 540 - .macro VGFMG vr1, vr2, vr3 541 - VGFM \vr1, \vr2, \vr3, 3 542 - .endm 543 - 544 - /* VECTOR GALOIS FIELD MULTIPLY SUM AND ACCUMULATE */ 545 - .macro VGFMA vr1, vr2, vr3, vr4, m5 546 - VX_NUM v1, \vr1 547 - VX_NUM v2, \vr2 548 - VX_NUM v3, \vr3 549 - VX_NUM v4, \vr4 550 - .word 0xE700 | ((v1&15) << 4) | (v2&15) 551 - .word ((v3&15) << 12) | (\m5 << 8) 552 - MRXBOPC (v4&15), 0xBC, v1, v2, v3, v4 553 - .endm 554 - .macro VGFMAB vr1, vr2, vr3, vr4 555 - VGFMA \vr1, \vr2, \vr3, \vr4, 0 556 - .endm 557 - .macro VGFMAH vr1, vr2, vr3, vr4 558 - VGFMA \vr1, \vr2, \vr3, \vr4, 1 559 - .endm 560 - .macro VGFMAF vr1, vr2, vr3, vr4 561 - VGFMA \vr1, \vr2, \vr3, \vr4, 2 562 - .endm 563 - .macro VGFMAG vr1, vr2, vr3, vr4 564 - VGFMA \vr1, \vr2, \vr3, \vr4, 3 565 - .endm 566 - 567 - /* VECTOR SHIFT RIGHT LOGICAL BY BYTE */ 568 - .macro VSRLB vr1, vr2, vr3 569 - VX_NUM v1, \vr1 570 - VX_NUM v2, \vr2 571 - VX_NUM v3, \vr3 572 - .word 0xE700 | ((v1&15) << 4) | (v2&15) 573 - .word ((v3&15) << 12) 574 - MRXBOPC 0, 0x7D, v1, v2, v3 575 - .endm 576 - 577 - /* VECTOR REPLICATE IMMEDIATE */ 578 - .macro VREPI vr1, imm2, m3 579 - VX_NUM v1, \vr1 580 - .word 0xE700 | ((v1&15) << 4) 581 - .word \imm2 582 - MRXBOPC \m3, 0x45, v1 583 - .endm 584 - .macro VREPIB vr1, imm2 585 - VREPI \vr1, \imm2, 0 586 - .endm 587 - .macro VREPIH vr1, imm2 588 - VREPI \vr1, \imm2, 1 589 - .endm 590 - .macro VREPIF vr1, imm2 591 - VREPI \vr1, \imm2, 2 592 - .endm 593 - .macro VREPIG vr1, imm2 594 - VREP \vr1, \imm2, 3 595 - .endm 596 - 597 - /* VECTOR ADD */ 598 - .macro VA vr1, vr2, vr3, m4 599 - VX_NUM v1, \vr1 600 - VX_NUM v2, \vr2 601 - VX_NUM v3, \vr3 602 - .word 0xE700 | ((v1&15) << 4) | (v2&15) 603 - .word ((v3&15) << 12) 604 - MRXBOPC \m4, 0xF3, v1, v2, v3 605 - .endm 606 - .macro VAB vr1, vr2, vr3 607 - VA \vr1, \vr2, \vr3, 0 608 - .endm 609 - .macro VAH vr1, vr2, vr3 610 - VA \vr1, \vr2, \vr3, 1 611 - .endm 612 - .macro VAF vr1, vr2, vr3 613 - VA \vr1, \vr2, \vr3, 2 614 - .endm 615 - .macro VAG vr1, vr2, vr3 616 - VA \vr1, \vr2, \vr3, 3 617 - .endm 618 - .macro VAQ vr1, vr2, vr3 619 - VA \vr1, \vr2, \vr3, 4 620 - .endm 621 - 622 - /* VECTOR ELEMENT SHIFT RIGHT ARITHMETIC */ 623 - .macro VESRAV vr1, vr2, vr3, m4 624 - VX_NUM v1, \vr1 625 - VX_NUM v2, \vr2 626 - VX_NUM v3, \vr3 627 - .word 0xE700 | ((v1&15) << 4) | (v2&15) 628 - .word ((v3&15) << 12) 629 - MRXBOPC \m4, 0x7A, v1, v2, v3 630 - .endm 631 - 632 - .macro VESRAVB vr1, vr2, vr3 633 - VESRAV \vr1, \vr2, \vr3, 0 634 - .endm 635 - .macro VESRAVH vr1, vr2, vr3 636 - VESRAV \vr1, \vr2, \vr3, 1 637 - .endm 638 - .macro VESRAVF vr1, vr2, vr3 639 - VESRAV \vr1, \vr2, \vr3, 2 640 - .endm 641 - .macro VESRAVG vr1, vr2, vr3 642 - VESRAV \vr1, \vr2, \vr3, 3 643 - .endm 644 - 645 - /* VECTOR ELEMENT ROTATE LEFT LOGICAL */ 646 - .macro VERLL vr1, vr3, disp, base="%r0", m4 647 - VX_NUM v1, \vr1 648 - VX_NUM v3, \vr3 649 - GR_NUM b2, \base 650 - .word 0xE700 | ((v1&15) << 4) | (v3&15) 651 - .word (b2 << 12) | (\disp) 652 - MRXBOPC \m4, 0x33, v1, v3 653 - .endm 654 - .macro VERLLB vr1, vr3, disp, base="%r0" 655 - VERLL \vr1, \vr3, \disp, \base, 0 656 - .endm 657 - .macro VERLLH vr1, vr3, disp, base="%r0" 658 - VERLL \vr1, \vr3, \disp, \base, 1 659 - .endm 660 - .macro VERLLF vr1, vr3, disp, base="%r0" 661 - VERLL \vr1, \vr3, \disp, \base, 2 662 - .endm 663 - .macro VERLLG vr1, vr3, disp, base="%r0" 664 - VERLL \vr1, \vr3, \disp, \base, 3 665 - .endm 666 - 667 - /* VECTOR SHIFT LEFT DOUBLE BY BYTE */ 668 - .macro VSLDB vr1, vr2, vr3, imm4 669 - VX_NUM v1, \vr1 670 - VX_NUM v2, \vr2 671 - VX_NUM v3, \vr3 672 - .word 0xE700 | ((v1&15) << 4) | (v2&15) 673 - .word ((v3&15) << 12) | (\imm4) 674 - MRXBOPC 0, 0x77, v1, v2, v3 675 - .endm 676 - 677 - #endif /* __ASSEMBLY__ */ 18 + #endif /* __ASSEMBLY__ */ 678 19 #endif /* __ASM_S390_VX_INSN_H */
+29
arch/s390/include/uapi/asm/ipl.h
··· 27 27 IPL_PBT_FCP = 0, 28 28 IPL_PBT_SCP_DATA = 1, 29 29 IPL_PBT_CCW = 2, 30 + IPL_PBT_ECKD = 3, 30 31 IPL_PBT_NVME = 4, 31 32 }; 32 33 ··· 111 110 __u8 vm_parm[64]; 112 111 __u8 reserved5[8]; 113 112 } __packed; 113 + 114 + /* IPL Parameter Block 0 for ECKD */ 115 + struct ipl_pb0_eckd { 116 + __u32 len; 117 + __u8 pbt; 118 + __u8 reserved1[3]; 119 + __u32 reserved2[78]; 120 + __u8 opt; 121 + __u8 reserved4[4]; 122 + __u8 reserved5:5; 123 + __u8 ssid:3; 124 + __u16 devno; 125 + __u32 reserved6[5]; 126 + __u32 bootprog; 127 + __u8 reserved7[12]; 128 + struct { 129 + __u16 cyl; 130 + __u8 head; 131 + __u8 record; 132 + __u32 reserved; 133 + } br_chr __packed; 134 + __u32 scp_data_len; 135 + __u8 reserved8[260]; 136 + __u8 scp_data[]; 137 + } __packed; 138 + 139 + #define IPL_PB0_ECKD_OPT_IPL 0x10 140 + #define IPL_PB0_ECKD_OPT_DUMP 0x20 114 141 115 142 #define IPL_PB0_CCW_VM_FLAG_NSS 0x80 116 143 #define IPL_PB0_CCW_VM_FLAG_VP 0x40
+4 -3
arch/s390/kernel/debug.c
··· 92 92 static int debug_hex_ascii_format_fn(debug_info_t *id, struct debug_view *view, 93 93 char *out_buf, const char *in_buf); 94 94 static int debug_sprintf_format_fn(debug_info_t *id, struct debug_view *view, 95 - char *out_buf, debug_sprintf_entry_t *curr_event); 95 + char *out_buf, const char *inbuf); 96 96 static void debug_areas_swap(debug_info_t *a, debug_info_t *b); 97 97 static void debug_events_append(debug_info_t *dest, debug_info_t *src); 98 98 ··· 139 139 "sprintf", 140 140 NULL, 141 141 &debug_dflt_header_fn, 142 - (debug_format_proc_t *)&debug_sprintf_format_fn, 142 + &debug_sprintf_format_fn, 143 143 NULL, 144 144 NULL 145 145 }; ··· 1532 1532 #define DEBUG_SPRINTF_MAX_ARGS 10 1533 1533 1534 1534 static int debug_sprintf_format_fn(debug_info_t *id, struct debug_view *view, 1535 - char *out_buf, debug_sprintf_entry_t *curr_event) 1535 + char *out_buf, const char *inbuf) 1536 1536 { 1537 + debug_sprintf_entry_t *curr_event = (debug_sprintf_entry_t *)inbuf; 1537 1538 int num_longs, num_used_args = 0, i, rc = 0; 1538 1539 int index[DEBUG_SPRINTF_MAX_ARGS]; 1539 1540
+4 -30
arch/s390/kernel/entry.S
··· 122 122 "jnz .+8; .insn rrf,0xb2e80000,0,0,13,0", 82 123 123 .endm 124 124 125 - /* 126 - * The CHKSTG macro jumps to the provided label in case the 127 - * machine check interruption code reports one of unrecoverable 128 - * storage errors: 129 - * - Storage error uncorrected 130 - * - Storage key error uncorrected 131 - * - Storage degradation with Failing-storage-address validity 132 - */ 133 - .macro CHKSTG errlabel 134 - TSTMSK __LC_MCCK_CODE,(MCCK_CODE_STG_ERROR|MCCK_CODE_STG_KEY_ERROR) 135 - jnz \errlabel 136 - TSTMSK __LC_MCCK_CODE,MCCK_CODE_STG_DEGRAD 137 - jz .Loklabel\@ 138 - TSTMSK __LC_MCCK_CODE,MCCK_CODE_STG_FAIL_ADDR 139 - jnz \errlabel 140 - .Loklabel\@: 141 - .endm 142 - 143 125 #if IS_ENABLED(CONFIG_KVM) 144 126 /* 145 127 * The OUTSIDE macro jumps to the provided label in case the value ··· 528 546 3: TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_MWP_VALID 529 547 jno .Lmcck_panic 530 548 tmhh %r8,0x0001 # interrupting from user ? 531 - jnz 6f 549 + jnz .Lmcck_user 532 550 TSTMSK __LC_MCCK_CODE,MCCK_CODE_PSW_IA_VALID 533 551 jno .Lmcck_panic 534 552 #if IS_ENABLED(CONFIG_KVM) 535 - OUTSIDE %r9,.Lsie_gmap,.Lsie_done,6f 553 + OUTSIDE %r9,.Lsie_gmap,.Lsie_done,.Lmcck_stack 536 554 OUTSIDE %r9,.Lsie_entry,.Lsie_leave,4f 537 555 oi __LC_CPU_FLAGS+7, _CIF_MCCK_GUEST 538 - j 5f 539 - 4: CHKSTG .Lmcck_panic 540 - 5: larl %r14,.Lstosm_tmp 541 - stosm 0(%r14),0x04 # turn dat on, keep irqs off 542 - BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 556 + 4: BPENTER __SF_SIE_FLAGS(%r15),(_TIF_ISOLATE_BP|_TIF_ISOLATE_BP_GUEST) 543 557 SIEEXIT 544 558 j .Lmcck_stack 545 559 #endif 546 - 6: CHKSTG .Lmcck_panic 547 - larl %r14,.Lstosm_tmp 548 - stosm 0(%r14),0x04 # turn dat on, keep irqs off 549 - tmhh %r8,0x0001 # interrupting from user ? 550 - jz .Lmcck_stack 560 + .Lmcck_user: 551 561 BPENTER __TI_flags(%r12),_TIF_ISOLATE_BP 552 562 .Lmcck_stack: 553 563 lg %r15,__LC_MCCK_STACK
+1 -2
arch/s390/kernel/fpu.c
··· 10 10 #include <linux/sched.h> 11 11 #include <asm/fpu/types.h> 12 12 #include <asm/fpu/api.h> 13 - 14 - asm(".include \"asm/vx-insn.h\"\n"); 13 + #include <asm/vx-insn.h> 15 14 16 15 void __kernel_fpu_begin(struct kernel_fpu *state, u32 flags) 17 16 {
+375 -28
arch/s390/kernel/ipl.c
··· 12 12 #include <linux/init.h> 13 13 #include <linux/device.h> 14 14 #include <linux/delay.h> 15 + #include <linux/kstrtox.h> 15 16 #include <linux/panic_notifier.h> 16 17 #include <linux/reboot.h> 17 18 #include <linux/ctype.h> ··· 40 39 41 40 #define IPL_UNKNOWN_STR "unknown" 42 41 #define IPL_CCW_STR "ccw" 42 + #define IPL_ECKD_STR "eckd" 43 + #define IPL_ECKD_DUMP_STR "eckd_dump" 43 44 #define IPL_FCP_STR "fcp" 44 45 #define IPL_FCP_DUMP_STR "fcp_dump" 45 46 #define IPL_NVME_STR "nvme" ··· 49 46 #define IPL_NSS_STR "nss" 50 47 51 48 #define DUMP_CCW_STR "ccw" 49 + #define DUMP_ECKD_STR "eckd" 52 50 #define DUMP_FCP_STR "fcp" 53 51 #define DUMP_NVME_STR "nvme" 54 52 #define DUMP_NONE_STR "none" ··· 96 92 switch (type) { 97 93 case IPL_TYPE_CCW: 98 94 return IPL_CCW_STR; 95 + case IPL_TYPE_ECKD: 96 + return IPL_ECKD_STR; 97 + case IPL_TYPE_ECKD_DUMP: 98 + return IPL_ECKD_DUMP_STR; 99 99 case IPL_TYPE_FCP: 100 100 return IPL_FCP_STR; 101 101 case IPL_TYPE_FCP_DUMP: ··· 121 113 DUMP_TYPE_CCW = 2, 122 114 DUMP_TYPE_FCP = 4, 123 115 DUMP_TYPE_NVME = 8, 116 + DUMP_TYPE_ECKD = 16, 124 117 }; 125 118 126 119 static char *dump_type_str(enum dump_type type) ··· 131 122 return DUMP_NONE_STR; 132 123 case DUMP_TYPE_CCW: 133 124 return DUMP_CCW_STR; 125 + case DUMP_TYPE_ECKD: 126 + return DUMP_ECKD_STR; 134 127 case DUMP_TYPE_FCP: 135 128 return DUMP_FCP_STR; 136 129 case DUMP_TYPE_NVME: ··· 158 147 static struct ipl_parameter_block *reipl_block_fcp; 159 148 static struct ipl_parameter_block *reipl_block_nvme; 160 149 static struct ipl_parameter_block *reipl_block_ccw; 150 + static struct ipl_parameter_block *reipl_block_eckd; 161 151 static struct ipl_parameter_block *reipl_block_nss; 162 152 static struct ipl_parameter_block *reipl_block_actual; 163 153 ··· 167 155 static struct ipl_parameter_block *dump_block_fcp; 168 156 static struct ipl_parameter_block *dump_block_nvme; 169 157 static struct ipl_parameter_block *dump_block_ccw; 158 + static struct ipl_parameter_block *dump_block_eckd; 170 159 171 160 static struct sclp_ipl_info sclp_ipl_info; 172 161 173 162 static bool reipl_nvme_clear; 174 163 static bool reipl_fcp_clear; 175 164 static bool reipl_ccw_clear; 165 + static bool reipl_eckd_clear; 176 166 177 167 static inline int __diag308(unsigned long subcode, void *addr) 178 168 { ··· 232 218 _ipl_blk.ssid, _ipl_blk.devno); \ 233 219 IPL_ATTR_CCW_STORE_FN(_prefix, _name, _ipl_blk); \ 234 220 static struct kobj_attribute sys_##_prefix##_##_name##_attr = \ 235 - __ATTR(_name, (S_IRUGO | S_IWUSR), \ 221 + __ATTR(_name, 0644, \ 236 222 sys_##_prefix##_##_name##_show, \ 237 223 sys_##_prefix##_##_name##_store) \ 238 224 239 225 #define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value) \ 240 226 IPL_ATTR_SHOW_FN(_prefix, _name, _format, _value) \ 241 227 static struct kobj_attribute sys_##_prefix##_##_name##_attr = \ 242 - __ATTR(_name, S_IRUGO, sys_##_prefix##_##_name##_show, NULL) 228 + __ATTR(_name, 0444, sys_##_prefix##_##_name##_show, NULL) 243 229 244 230 #define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value) \ 245 231 IPL_ATTR_SHOW_FN(_prefix, _name, _fmt_out, (unsigned long long) _value) \ ··· 254 240 return len; \ 255 241 } \ 256 242 static struct kobj_attribute sys_##_prefix##_##_name##_attr = \ 257 - __ATTR(_name,(S_IRUGO | S_IWUSR), \ 243 + __ATTR(_name, 0644, \ 258 244 sys_##_prefix##_##_name##_show, \ 259 245 sys_##_prefix##_##_name##_store) 260 246 ··· 269 255 return len; \ 270 256 } \ 271 257 static struct kobj_attribute sys_##_prefix##_##_name##_attr = \ 272 - __ATTR(_name,(S_IRUGO | S_IWUSR), \ 258 + __ATTR(_name, 0644, \ 273 259 sys_##_prefix##_##_name##_show, \ 274 260 sys_##_prefix##_##_name##_store) 275 261 ··· 295 281 return IPL_TYPE_NVME_DUMP; 296 282 else 297 283 return IPL_TYPE_NVME; 284 + case IPL_PBT_ECKD: 285 + if (ipl_block.eckd.opt == IPL_PB0_ECKD_OPT_DUMP) 286 + return IPL_TYPE_ECKD_DUMP; 287 + else 288 + return IPL_TYPE_ECKD; 298 289 } 299 290 return IPL_TYPE_UNKNOWN; 300 291 } ··· 344 325 } 345 326 346 327 static struct kobj_attribute sys_ipl_vm_parm_attr = 347 - __ATTR(parm, S_IRUGO, ipl_vm_parm_show, NULL); 328 + __ATTR(parm, 0444, ipl_vm_parm_show, NULL); 348 329 349 330 static ssize_t sys_ipl_device_show(struct kobject *kobj, 350 331 struct kobj_attribute *attr, char *page) ··· 353 334 case IPL_TYPE_CCW: 354 335 return sprintf(page, "0.%x.%04x\n", ipl_block.ccw.ssid, 355 336 ipl_block.ccw.devno); 337 + case IPL_TYPE_ECKD: 338 + case IPL_TYPE_ECKD_DUMP: 339 + return sprintf(page, "0.%x.%04x\n", ipl_block.eckd.ssid, 340 + ipl_block.eckd.devno); 356 341 case IPL_TYPE_FCP: 357 342 case IPL_TYPE_FCP_DUMP: 358 343 return sprintf(page, "0.0.%04x\n", ipl_block.fcp.devno); ··· 369 346 } 370 347 371 348 static struct kobj_attribute sys_ipl_device_attr = 372 - __ATTR(device, S_IRUGO, sys_ipl_device_show, NULL); 349 + __ATTR(device, 0444, sys_ipl_device_show, NULL); 373 350 374 351 static ssize_t ipl_parameter_read(struct file *filp, struct kobject *kobj, 375 352 struct bin_attribute *attr, char *buf, ··· 379 356 ipl_block.hdr.len); 380 357 } 381 358 static struct bin_attribute ipl_parameter_attr = 382 - __BIN_ATTR(binary_parameter, S_IRUGO, ipl_parameter_read, NULL, 359 + __BIN_ATTR(binary_parameter, 0444, ipl_parameter_read, NULL, 383 360 PAGE_SIZE); 384 361 385 362 static ssize_t ipl_scp_data_read(struct file *filp, struct kobject *kobj, ··· 402 379 return memory_read_from_buffer(buf, count, &off, scp_data, size); 403 380 } 404 381 382 + static ssize_t ipl_eckd_scp_data_read(struct file *filp, struct kobject *kobj, 383 + struct bin_attribute *attr, char *buf, 384 + loff_t off, size_t count) 385 + { 386 + unsigned int size = ipl_block.eckd.scp_data_len; 387 + void *scp_data = &ipl_block.eckd.scp_data; 388 + 389 + return memory_read_from_buffer(buf, count, &off, scp_data, size); 390 + } 391 + 405 392 static struct bin_attribute ipl_scp_data_attr = 406 - __BIN_ATTR(scp_data, S_IRUGO, ipl_scp_data_read, NULL, PAGE_SIZE); 393 + __BIN_ATTR(scp_data, 0444, ipl_scp_data_read, NULL, PAGE_SIZE); 407 394 408 395 static struct bin_attribute ipl_nvme_scp_data_attr = 409 - __BIN_ATTR(scp_data, S_IRUGO, ipl_nvme_scp_data_read, NULL, PAGE_SIZE); 396 + __BIN_ATTR(scp_data, 0444, ipl_nvme_scp_data_read, NULL, PAGE_SIZE); 397 + 398 + static struct bin_attribute ipl_eckd_scp_data_attr = 399 + __BIN_ATTR(scp_data, 0444, ipl_eckd_scp_data_read, NULL, PAGE_SIZE); 410 400 411 401 static struct bin_attribute *ipl_fcp_bin_attrs[] = { 412 402 &ipl_parameter_attr, ··· 430 394 static struct bin_attribute *ipl_nvme_bin_attrs[] = { 431 395 &ipl_parameter_attr, 432 396 &ipl_nvme_scp_data_attr, 397 + NULL, 398 + }; 399 + 400 + static struct bin_attribute *ipl_eckd_bin_attrs[] = { 401 + &ipl_parameter_attr, 402 + &ipl_eckd_scp_data_attr, 433 403 NULL, 434 404 }; 435 405 ··· 459 417 (unsigned long long)ipl_block.nvme.bootprog); 460 418 DEFINE_IPL_ATTR_RO(ipl_nvme, br_lba, "%lld\n", 461 419 (unsigned long long)ipl_block.nvme.br_lba); 420 + 421 + /* ECKD ipl device attributes */ 422 + DEFINE_IPL_ATTR_RO(ipl_eckd, bootprog, "%lld\n", 423 + (unsigned long long)ipl_block.eckd.bootprog); 424 + 425 + #define IPL_ATTR_BR_CHR_SHOW_FN(_name, _ipb) \ 426 + static ssize_t eckd_##_name##_br_chr_show(struct kobject *kobj, \ 427 + struct kobj_attribute *attr, \ 428 + char *buf) \ 429 + { \ 430 + struct ipl_pb0_eckd *ipb = &(_ipb); \ 431 + \ 432 + if (!ipb->br_chr.cyl && \ 433 + !ipb->br_chr.head && \ 434 + !ipb->br_chr.record) \ 435 + return sprintf(buf, "auto\n"); \ 436 + \ 437 + return sprintf(buf, "0x%x,0x%x,0x%x\n", \ 438 + ipb->br_chr.cyl, \ 439 + ipb->br_chr.head, \ 440 + ipb->br_chr.record); \ 441 + } 442 + 443 + #define IPL_ATTR_BR_CHR_STORE_FN(_name, _ipb) \ 444 + static ssize_t eckd_##_name##_br_chr_store(struct kobject *kobj, \ 445 + struct kobj_attribute *attr, \ 446 + const char *buf, size_t len) \ 447 + { \ 448 + struct ipl_pb0_eckd *ipb = &(_ipb); \ 449 + unsigned long args[3] = { 0 }; \ 450 + char *p, *p1, *tmp = NULL; \ 451 + int i, rc; \ 452 + \ 453 + if (!strncmp(buf, "auto", 4)) \ 454 + goto out; \ 455 + \ 456 + tmp = kstrdup(buf, GFP_KERNEL); \ 457 + p = tmp; \ 458 + for (i = 0; i < 3; i++) { \ 459 + p1 = strsep(&p, ", "); \ 460 + if (!p1) { \ 461 + rc = -EINVAL; \ 462 + goto err; \ 463 + } \ 464 + rc = kstrtoul(p1, 0, args + i); \ 465 + if (rc) \ 466 + goto err; \ 467 + } \ 468 + \ 469 + rc = -EINVAL; \ 470 + if (i != 3) \ 471 + goto err; \ 472 + \ 473 + if ((args[0] || args[1]) && !args[2]) \ 474 + goto err; \ 475 + \ 476 + if (args[0] > UINT_MAX || args[1] > 255 || args[2] > 255) \ 477 + goto err; \ 478 + \ 479 + out: \ 480 + ipb->br_chr.cyl = args[0]; \ 481 + ipb->br_chr.head = args[1]; \ 482 + ipb->br_chr.record = args[2]; \ 483 + rc = len; \ 484 + err: \ 485 + kfree(tmp); \ 486 + return rc; \ 487 + } 488 + 489 + IPL_ATTR_BR_CHR_SHOW_FN(ipl, ipl_block.eckd); 490 + static struct kobj_attribute sys_ipl_eckd_br_chr_attr = 491 + __ATTR(br_chr, 0644, eckd_ipl_br_chr_show, NULL); 492 + 493 + IPL_ATTR_BR_CHR_SHOW_FN(reipl, reipl_block_eckd->eckd); 494 + IPL_ATTR_BR_CHR_STORE_FN(reipl, reipl_block_eckd->eckd); 495 + 496 + static struct kobj_attribute sys_reipl_eckd_br_chr_attr = 497 + __ATTR(br_chr, 0644, eckd_reipl_br_chr_show, eckd_reipl_br_chr_store); 462 498 463 499 static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj, 464 500 struct kobj_attribute *attr, char *page) ··· 589 469 .bin_attrs = ipl_nvme_bin_attrs, 590 470 }; 591 471 472 + static struct attribute *ipl_eckd_attrs[] = { 473 + &sys_ipl_type_attr.attr, 474 + &sys_ipl_eckd_bootprog_attr.attr, 475 + &sys_ipl_eckd_br_chr_attr.attr, 476 + &sys_ipl_device_attr.attr, 477 + &sys_ipl_secure_attr.attr, 478 + &sys_ipl_has_secure_attr.attr, 479 + NULL, 480 + }; 481 + 482 + static struct attribute_group ipl_eckd_attr_group = { 483 + .attrs = ipl_eckd_attrs, 484 + .bin_attrs = ipl_eckd_bin_attrs, 485 + }; 592 486 593 487 /* CCW ipl device attributes */ 594 488 ··· 674 540 else 675 541 rc = sysfs_create_group(&ipl_kset->kobj, 676 542 &ipl_ccw_attr_group_lpar); 543 + break; 544 + case IPL_TYPE_ECKD: 545 + rc = sysfs_create_group(&ipl_kset->kobj, &ipl_eckd_attr_group); 677 546 break; 678 547 case IPL_TYPE_FCP: 679 548 case IPL_TYPE_FCP_DUMP: ··· 779 642 } 780 643 781 644 static struct kobj_attribute sys_reipl_nss_vmparm_attr = 782 - __ATTR(parm, S_IRUGO | S_IWUSR, reipl_nss_vmparm_show, 783 - reipl_nss_vmparm_store); 645 + __ATTR(parm, 0644, reipl_nss_vmparm_show, 646 + reipl_nss_vmparm_store); 784 647 static struct kobj_attribute sys_reipl_ccw_vmparm_attr = 785 - __ATTR(parm, S_IRUGO | S_IWUSR, reipl_ccw_vmparm_show, 786 - reipl_ccw_vmparm_store); 648 + __ATTR(parm, 0644, reipl_ccw_vmparm_show, 649 + reipl_ccw_vmparm_store); 787 650 788 651 /* FCP reipl device attributes */ 789 652 ··· 823 686 return count; 824 687 } 825 688 static struct bin_attribute sys_reipl_fcp_scp_data_attr = 826 - __BIN_ATTR(scp_data, (S_IRUGO | S_IWUSR), reipl_fcp_scpdata_read, 689 + __BIN_ATTR(scp_data, 0644, reipl_fcp_scpdata_read, 827 690 reipl_fcp_scpdata_write, DIAG308_SCPDATA_SIZE); 828 691 829 692 static struct bin_attribute *reipl_fcp_bin_attrs[] = { ··· 903 766 } 904 767 905 768 static struct kobj_attribute sys_reipl_fcp_loadparm_attr = 906 - __ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_fcp_loadparm_show, 907 - reipl_fcp_loadparm_store); 769 + __ATTR(loadparm, 0644, reipl_fcp_loadparm_show, 770 + reipl_fcp_loadparm_store); 908 771 909 772 static ssize_t reipl_fcp_clear_show(struct kobject *kobj, 910 773 struct kobj_attribute *attr, char *page) ··· 916 779 struct kobj_attribute *attr, 917 780 const char *buf, size_t len) 918 781 { 919 - if (strtobool(buf, &reipl_fcp_clear) < 0) 782 + if (kstrtobool(buf, &reipl_fcp_clear) < 0) 920 783 return -EINVAL; 921 784 return len; 922 785 } ··· 977 840 } 978 841 979 842 static struct bin_attribute sys_reipl_nvme_scp_data_attr = 980 - __BIN_ATTR(scp_data, (S_IRUGO | S_IWUSR), reipl_nvme_scpdata_read, 843 + __BIN_ATTR(scp_data, 0644, reipl_nvme_scpdata_read, 981 844 reipl_nvme_scpdata_write, DIAG308_SCPDATA_SIZE); 982 845 983 846 static struct bin_attribute *reipl_nvme_bin_attrs[] = { ··· 1009 872 } 1010 873 1011 874 static struct kobj_attribute sys_reipl_nvme_loadparm_attr = 1012 - __ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_nvme_loadparm_show, 1013 - reipl_nvme_loadparm_store); 875 + __ATTR(loadparm, 0644, reipl_nvme_loadparm_show, 876 + reipl_nvme_loadparm_store); 1014 877 1015 878 static struct attribute *reipl_nvme_attrs[] = { 1016 879 &sys_reipl_nvme_fid_attr.attr, ··· 1036 899 struct kobj_attribute *attr, 1037 900 const char *buf, size_t len) 1038 901 { 1039 - if (strtobool(buf, &reipl_nvme_clear) < 0) 902 + if (kstrtobool(buf, &reipl_nvme_clear) < 0) 1040 903 return -EINVAL; 1041 904 return len; 1042 905 } ··· 1076 939 } 1077 940 1078 941 static struct kobj_attribute sys_reipl_ccw_loadparm_attr = 1079 - __ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_ccw_loadparm_show, 1080 - reipl_ccw_loadparm_store); 942 + __ATTR(loadparm, 0644, reipl_ccw_loadparm_show, 943 + reipl_ccw_loadparm_store); 1081 944 1082 945 static ssize_t reipl_ccw_clear_show(struct kobject *kobj, 1083 946 struct kobj_attribute *attr, char *page) ··· 1089 952 struct kobj_attribute *attr, 1090 953 const char *buf, size_t len) 1091 954 { 1092 - if (strtobool(buf, &reipl_ccw_clear) < 0) 955 + if (kstrtobool(buf, &reipl_ccw_clear) < 0) 1093 956 return -EINVAL; 1094 957 return len; 1095 958 } ··· 1122 985 .attrs = reipl_ccw_attrs_lpar, 1123 986 }; 1124 987 988 + /* ECKD reipl device attributes */ 989 + 990 + static ssize_t reipl_eckd_scpdata_read(struct file *filp, struct kobject *kobj, 991 + struct bin_attribute *attr, 992 + char *buf, loff_t off, size_t count) 993 + { 994 + size_t size = reipl_block_eckd->eckd.scp_data_len; 995 + void *scp_data = reipl_block_eckd->eckd.scp_data; 996 + 997 + return memory_read_from_buffer(buf, count, &off, scp_data, size); 998 + } 999 + 1000 + static ssize_t reipl_eckd_scpdata_write(struct file *filp, struct kobject *kobj, 1001 + struct bin_attribute *attr, 1002 + char *buf, loff_t off, size_t count) 1003 + { 1004 + size_t scpdata_len = count; 1005 + size_t padding; 1006 + 1007 + if (off) 1008 + return -EINVAL; 1009 + 1010 + memcpy(reipl_block_eckd->eckd.scp_data, buf, count); 1011 + if (scpdata_len % 8) { 1012 + padding = 8 - (scpdata_len % 8); 1013 + memset(reipl_block_eckd->eckd.scp_data + scpdata_len, 1014 + 0, padding); 1015 + scpdata_len += padding; 1016 + } 1017 + 1018 + reipl_block_eckd->hdr.len = IPL_BP_ECKD_LEN + scpdata_len; 1019 + reipl_block_eckd->eckd.len = IPL_BP0_ECKD_LEN + scpdata_len; 1020 + reipl_block_eckd->eckd.scp_data_len = scpdata_len; 1021 + 1022 + return count; 1023 + } 1024 + 1025 + static struct bin_attribute sys_reipl_eckd_scp_data_attr = 1026 + __BIN_ATTR(scp_data, 0644, reipl_eckd_scpdata_read, 1027 + reipl_eckd_scpdata_write, DIAG308_SCPDATA_SIZE); 1028 + 1029 + static struct bin_attribute *reipl_eckd_bin_attrs[] = { 1030 + &sys_reipl_eckd_scp_data_attr, 1031 + NULL, 1032 + }; 1033 + 1034 + DEFINE_IPL_CCW_ATTR_RW(reipl_eckd, device, reipl_block_eckd->eckd); 1035 + DEFINE_IPL_ATTR_RW(reipl_eckd, bootprog, "%lld\n", "%lld\n", 1036 + reipl_block_eckd->eckd.bootprog); 1037 + 1038 + static struct attribute *reipl_eckd_attrs[] = { 1039 + &sys_reipl_eckd_device_attr.attr, 1040 + &sys_reipl_eckd_bootprog_attr.attr, 1041 + &sys_reipl_eckd_br_chr_attr.attr, 1042 + NULL, 1043 + }; 1044 + 1045 + static struct attribute_group reipl_eckd_attr_group = { 1046 + .attrs = reipl_eckd_attrs, 1047 + .bin_attrs = reipl_eckd_bin_attrs 1048 + }; 1049 + 1050 + static ssize_t reipl_eckd_clear_show(struct kobject *kobj, 1051 + struct kobj_attribute *attr, char *page) 1052 + { 1053 + return sprintf(page, "%u\n", reipl_eckd_clear); 1054 + } 1055 + 1056 + static ssize_t reipl_eckd_clear_store(struct kobject *kobj, 1057 + struct kobj_attribute *attr, 1058 + const char *buf, size_t len) 1059 + { 1060 + if (strtobool(buf, &reipl_eckd_clear) < 0) 1061 + return -EINVAL; 1062 + return len; 1063 + } 1064 + 1065 + static struct kobj_attribute sys_reipl_eckd_clear_attr = 1066 + __ATTR(clear, 0644, reipl_eckd_clear_show, reipl_eckd_clear_store); 1125 1067 1126 1068 /* NSS reipl device attributes */ 1127 1069 static void reipl_get_ascii_nss_name(char *dst, ··· 1248 1032 } 1249 1033 1250 1034 static struct kobj_attribute sys_reipl_nss_name_attr = 1251 - __ATTR(name, S_IRUGO | S_IWUSR, reipl_nss_name_show, 1252 - reipl_nss_name_store); 1035 + __ATTR(name, 0644, reipl_nss_name_show, 1036 + reipl_nss_name_store); 1253 1037 1254 1038 static struct kobj_attribute sys_reipl_nss_loadparm_attr = 1255 - __ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_nss_loadparm_show, 1256 - reipl_nss_loadparm_store); 1039 + __ATTR(loadparm, 0644, reipl_nss_loadparm_show, 1040 + reipl_nss_loadparm_store); 1257 1041 1258 1042 static struct attribute *reipl_nss_attrs[] = { 1259 1043 &sys_reipl_nss_name_attr.attr, ··· 1283 1067 switch(type) { 1284 1068 case IPL_TYPE_CCW: 1285 1069 reipl_block_actual = reipl_block_ccw; 1070 + break; 1071 + case IPL_TYPE_ECKD: 1072 + reipl_block_actual = reipl_block_eckd; 1286 1073 break; 1287 1074 case IPL_TYPE_FCP: 1288 1075 reipl_block_actual = reipl_block_fcp; ··· 1317 1098 1318 1099 if (strncmp(buf, IPL_CCW_STR, strlen(IPL_CCW_STR)) == 0) 1319 1100 rc = reipl_set_type(IPL_TYPE_CCW); 1101 + else if (strncmp(buf, IPL_ECKD_STR, strlen(IPL_ECKD_STR)) == 0) 1102 + rc = reipl_set_type(IPL_TYPE_ECKD); 1320 1103 else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0) 1321 1104 rc = reipl_set_type(IPL_TYPE_FCP); 1322 1105 else if (strncmp(buf, IPL_NVME_STR, strlen(IPL_NVME_STR)) == 0) ··· 1334 1113 static struct kset *reipl_kset; 1335 1114 static struct kset *reipl_fcp_kset; 1336 1115 static struct kset *reipl_nvme_kset; 1116 + static struct kset *reipl_eckd_kset; 1337 1117 1338 1118 static void __reipl_run(void *unused) 1339 1119 { ··· 1345 1123 diag308(DIAG308_LOAD_CLEAR, NULL); 1346 1124 else 1347 1125 diag308(DIAG308_LOAD_NORMAL_DUMP, NULL); 1126 + break; 1127 + case IPL_TYPE_ECKD: 1128 + diag308(DIAG308_SET, reipl_block_eckd); 1129 + if (reipl_eckd_clear) 1130 + diag308(DIAG308_LOAD_CLEAR, NULL); 1131 + else 1132 + diag308(DIAG308_LOAD_NORMAL, NULL); 1348 1133 break; 1349 1134 case IPL_TYPE_FCP: 1350 1135 diag308(DIAG308_SET, reipl_block_fcp); ··· 1376 1147 break; 1377 1148 case IPL_TYPE_FCP_DUMP: 1378 1149 case IPL_TYPE_NVME_DUMP: 1150 + case IPL_TYPE_ECKD_DUMP: 1379 1151 break; 1380 1152 } 1381 1153 disabled_wait(); ··· 1574 1344 return rc; 1575 1345 } 1576 1346 1347 + static int __init reipl_eckd_init(void) 1348 + { 1349 + int rc; 1350 + 1351 + if (!sclp.has_sipl_eckd) 1352 + return 0; 1353 + 1354 + reipl_block_eckd = (void *)get_zeroed_page(GFP_KERNEL); 1355 + if (!reipl_block_eckd) 1356 + return -ENOMEM; 1357 + 1358 + /* sysfs: create kset for mixing attr group and bin attrs */ 1359 + reipl_eckd_kset = kset_create_and_add(IPL_ECKD_STR, NULL, 1360 + &reipl_kset->kobj); 1361 + if (!reipl_eckd_kset) { 1362 + free_page((unsigned long)reipl_block_eckd); 1363 + return -ENOMEM; 1364 + } 1365 + 1366 + rc = sysfs_create_group(&reipl_eckd_kset->kobj, &reipl_eckd_attr_group); 1367 + if (rc) 1368 + goto out1; 1369 + 1370 + if (test_facility(141)) { 1371 + rc = sysfs_create_file(&reipl_eckd_kset->kobj, 1372 + &sys_reipl_eckd_clear_attr.attr); 1373 + if (rc) 1374 + goto out2; 1375 + } else { 1376 + reipl_eckd_clear = true; 1377 + } 1378 + 1379 + if (ipl_info.type == IPL_TYPE_ECKD) { 1380 + memcpy(reipl_block_eckd, &ipl_block, sizeof(ipl_block)); 1381 + } else { 1382 + reipl_block_eckd->hdr.len = IPL_BP_ECKD_LEN; 1383 + reipl_block_eckd->hdr.version = IPL_PARM_BLOCK_VERSION; 1384 + reipl_block_eckd->eckd.len = IPL_BP0_ECKD_LEN; 1385 + reipl_block_eckd->eckd.pbt = IPL_PBT_ECKD; 1386 + reipl_block_eckd->eckd.opt = IPL_PB0_ECKD_OPT_IPL; 1387 + } 1388 + reipl_capabilities |= IPL_TYPE_ECKD; 1389 + return 0; 1390 + 1391 + out2: 1392 + sysfs_remove_group(&reipl_eckd_kset->kobj, &reipl_eckd_attr_group); 1393 + out1: 1394 + kset_unregister(reipl_eckd_kset); 1395 + free_page((unsigned long)reipl_block_eckd); 1396 + return rc; 1397 + } 1398 + 1577 1399 static int __init reipl_type_init(void) 1578 1400 { 1579 1401 enum ipl_type reipl_type = ipl_info.type; ··· 1647 1365 } else if (reipl_block->pb0_hdr.pbt == IPL_PBT_CCW) { 1648 1366 memcpy(reipl_block_ccw, reipl_block, size); 1649 1367 reipl_type = IPL_TYPE_CCW; 1368 + } else if (reipl_block->pb0_hdr.pbt == IPL_PBT_ECKD) { 1369 + memcpy(reipl_block_eckd, reipl_block, size); 1370 + reipl_type = IPL_TYPE_ECKD; 1650 1371 } 1651 1372 out: 1652 1373 return reipl_set_type(reipl_type); ··· 1668 1383 return rc; 1669 1384 } 1670 1385 rc = reipl_ccw_init(); 1386 + if (rc) 1387 + return rc; 1388 + rc = reipl_eckd_init(); 1671 1389 if (rc) 1672 1390 return rc; 1673 1391 rc = reipl_fcp_init(); ··· 1745 1457 .attrs = dump_nvme_attrs, 1746 1458 }; 1747 1459 1460 + /* ECKD dump device attributes */ 1461 + DEFINE_IPL_CCW_ATTR_RW(dump_eckd, device, dump_block_eckd->eckd); 1462 + DEFINE_IPL_ATTR_RW(dump_eckd, bootprog, "%lld\n", "%llx\n", 1463 + dump_block_eckd->eckd.bootprog); 1464 + 1465 + IPL_ATTR_BR_CHR_SHOW_FN(dump, dump_block_eckd->eckd); 1466 + IPL_ATTR_BR_CHR_STORE_FN(dump, dump_block_eckd->eckd); 1467 + 1468 + static struct kobj_attribute sys_dump_eckd_br_chr_attr = 1469 + __ATTR(br_chr, 0644, eckd_dump_br_chr_show, eckd_dump_br_chr_store); 1470 + 1471 + static struct attribute *dump_eckd_attrs[] = { 1472 + &sys_dump_eckd_device_attr.attr, 1473 + &sys_dump_eckd_bootprog_attr.attr, 1474 + &sys_dump_eckd_br_chr_attr.attr, 1475 + NULL, 1476 + }; 1477 + 1478 + static struct attribute_group dump_eckd_attr_group = { 1479 + .name = IPL_ECKD_STR, 1480 + .attrs = dump_eckd_attrs, 1481 + }; 1482 + 1748 1483 /* CCW dump device attributes */ 1749 1484 DEFINE_IPL_CCW_ATTR_RW(dump_ccw, device, dump_block_ccw->ccw); 1750 1485 ··· 1807 1496 rc = dump_set_type(DUMP_TYPE_NONE); 1808 1497 else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0) 1809 1498 rc = dump_set_type(DUMP_TYPE_CCW); 1499 + else if (strncmp(buf, DUMP_ECKD_STR, strlen(DUMP_ECKD_STR)) == 0) 1500 + rc = dump_set_type(DUMP_TYPE_ECKD); 1810 1501 else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0) 1811 1502 rc = dump_set_type(DUMP_TYPE_FCP); 1812 1503 else if (strncmp(buf, DUMP_NVME_STR, strlen(DUMP_NVME_STR)) == 0) ··· 1836 1523 switch (dump_type) { 1837 1524 case DUMP_TYPE_CCW: 1838 1525 diag308_dump(dump_block_ccw); 1526 + break; 1527 + case DUMP_TYPE_ECKD: 1528 + diag308_dump(dump_block_eckd); 1839 1529 break; 1840 1530 case DUMP_TYPE_FCP: 1841 1531 diag308_dump(dump_block_fcp); ··· 1925 1609 return 0; 1926 1610 } 1927 1611 1612 + static int __init dump_eckd_init(void) 1613 + { 1614 + int rc; 1615 + 1616 + if (!sclp_ipl_info.has_dump || !sclp.has_sipl_eckd) 1617 + return 0; /* LDIPL DUMP is not installed */ 1618 + dump_block_eckd = (void *)get_zeroed_page(GFP_KERNEL); 1619 + if (!dump_block_eckd) 1620 + return -ENOMEM; 1621 + rc = sysfs_create_group(&dump_kset->kobj, &dump_eckd_attr_group); 1622 + if (rc) { 1623 + free_page((unsigned long)dump_block_eckd); 1624 + return rc; 1625 + } 1626 + dump_block_eckd->hdr.len = IPL_BP_ECKD_LEN; 1627 + dump_block_eckd->hdr.version = IPL_PARM_BLOCK_VERSION; 1628 + dump_block_eckd->eckd.len = IPL_BP0_ECKD_LEN; 1629 + dump_block_eckd->eckd.pbt = IPL_PBT_ECKD; 1630 + dump_block_eckd->eckd.opt = IPL_PB0_ECKD_OPT_DUMP; 1631 + dump_capabilities |= DUMP_TYPE_ECKD; 1632 + return 0; 1633 + } 1634 + 1928 1635 static int __init dump_init(void) 1929 1636 { 1930 1637 int rc; ··· 1961 1622 return rc; 1962 1623 } 1963 1624 rc = dump_ccw_init(); 1625 + if (rc) 1626 + return rc; 1627 + rc = dump_eckd_init(); 1964 1628 if (rc) 1965 1629 return rc; 1966 1630 rc = dump_fcp_init(); ··· 2398 2056 case IPL_TYPE_CCW: 2399 2057 ipl_info.data.ccw.dev_id.ssid = ipl_block.ccw.ssid; 2400 2058 ipl_info.data.ccw.dev_id.devno = ipl_block.ccw.devno; 2059 + break; 2060 + case IPL_TYPE_ECKD: 2061 + case IPL_TYPE_ECKD_DUMP: 2062 + ipl_info.data.eckd.dev_id.ssid = ipl_block.eckd.ssid; 2063 + ipl_info.data.eckd.dev_id.devno = ipl_block.eckd.devno; 2401 2064 break; 2402 2065 case IPL_TYPE_FCP: 2403 2066 case IPL_TYPE_FCP_DUMP:
+1 -2
arch/s390/kernel/kprobes.c
··· 24 24 #include <asm/set_memory.h> 25 25 #include <asm/sections.h> 26 26 #include <asm/dis.h> 27 + #include "kprobes.h" 27 28 #include "entry.h" 28 29 29 30 DEFINE_PER_CPU(struct kprobe *, current_kprobe); 30 31 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 31 32 32 33 struct kretprobe_blackpoint kretprobe_blacklist[] = { }; 33 - 34 - DEFINE_INSN_CACHE_OPS(s390_insn); 35 34 36 35 static int insn_page_in_use; 37 36
+9
arch/s390/kernel/kprobes.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ */ 2 + #ifndef _ARCH_S390_KPROBES_H 3 + #define _ARCH_S390_KPROBES_H 4 + 5 + #include <linux/kprobes.h> 6 + 7 + DEFINE_INSN_CACHE_OPS(s390_insn); 8 + 9 + #endif
+90 -91
arch/s390/kernel/nmi.c
··· 19 19 #include <linux/time.h> 20 20 #include <linux/module.h> 21 21 #include <linux/sched/signal.h> 22 - 22 + #include <linux/kvm_host.h> 23 23 #include <linux/export.h> 24 24 #include <asm/lowcore.h> 25 25 #include <asm/smp.h> ··· 31 31 #include <asm/ctl_reg.h> 32 32 #include <asm/asm-offsets.h> 33 33 #include <asm/pai.h> 34 - 35 - #include <linux/kvm_host.h> 34 + #include <asm/vx-insn.h> 36 35 37 36 struct mcck_struct { 38 37 unsigned int kill_task : 1; ··· 42 43 }; 43 44 44 45 static DEFINE_PER_CPU(struct mcck_struct, cpu_mcck); 45 - static struct kmem_cache *mcesa_cache; 46 - static unsigned long mcesa_origin_lc; 47 46 48 47 static inline int nmi_needs_mcesa(void) 49 48 { 50 49 return MACHINE_HAS_VX || MACHINE_HAS_GS; 51 - } 52 - 53 - static inline unsigned long nmi_get_mcesa_size(void) 54 - { 55 - if (MACHINE_HAS_GS) 56 - return MCESA_MAX_SIZE; 57 - return MCESA_MIN_SIZE; 58 50 } 59 51 60 52 /* ··· 65 75 *mcesad |= ilog2(MCESA_MAX_SIZE); 66 76 } 67 77 68 - static void __init nmi_alloc_cache(void) 78 + int nmi_alloc_mcesa(u64 *mcesad) 69 79 { 70 80 unsigned long size; 71 - 72 - if (!nmi_needs_mcesa()) 73 - return; 74 - size = nmi_get_mcesa_size(); 75 - if (size > MCESA_MIN_SIZE) 76 - mcesa_origin_lc = ilog2(size); 77 - /* create slab cache for the machine-check-extended-save-areas */ 78 - mcesa_cache = kmem_cache_create("nmi_save_areas", size, size, 0, NULL); 79 - if (!mcesa_cache) 80 - panic("Couldn't create nmi save area cache"); 81 - } 82 - 83 - int __ref nmi_alloc_mcesa(u64 *mcesad) 84 - { 85 - unsigned long origin; 81 + void *origin; 86 82 87 83 *mcesad = 0; 88 84 if (!nmi_needs_mcesa()) 89 85 return 0; 90 - if (!mcesa_cache) 91 - nmi_alloc_cache(); 92 - origin = (unsigned long) kmem_cache_alloc(mcesa_cache, GFP_KERNEL); 86 + size = MACHINE_HAS_GS ? MCESA_MAX_SIZE : MCESA_MIN_SIZE; 87 + origin = kmalloc(size, GFP_KERNEL); 93 88 if (!origin) 94 89 return -ENOMEM; 95 90 /* The pointer is stored with mcesa_bits ORed in */ 96 - kmemleak_not_leak((void *) origin); 97 - *mcesad = __pa(origin) | mcesa_origin_lc; 91 + kmemleak_not_leak(origin); 92 + *mcesad = __pa(origin); 93 + if (MACHINE_HAS_GS) 94 + *mcesad |= ilog2(MCESA_MAX_SIZE); 98 95 return 0; 99 96 } 100 97 ··· 89 112 { 90 113 if (!nmi_needs_mcesa()) 91 114 return; 92 - kmem_cache_free(mcesa_cache, __va(*mcesad & MCESA_ORIGIN_MASK)); 115 + kfree(__va(*mcesad & MCESA_ORIGIN_MASK)); 116 + } 117 + 118 + static __always_inline char *nmi_puts(char *dest, const char *src) 119 + { 120 + while (*src) 121 + *dest++ = *src++; 122 + *dest = 0; 123 + return dest; 124 + } 125 + 126 + static __always_inline char *u64_to_hex(char *dest, u64 val) 127 + { 128 + int i, num; 129 + 130 + for (i = 1; i <= 16; i++) { 131 + num = (val >> (64 - 4 * i)) & 0xf; 132 + if (num >= 10) 133 + *dest++ = 'A' + num - 10; 134 + else 135 + *dest++ = '0' + num; 136 + } 137 + *dest = 0; 138 + return dest; 93 139 } 94 140 95 141 static notrace void s390_handle_damage(void) 96 142 { 143 + union ctlreg0 cr0, cr0_new; 144 + char message[100]; 145 + psw_t psw_save; 146 + char *ptr; 147 + 97 148 smp_emergency_stop(); 149 + diag_amode31_ops.diag308_reset(); 150 + ptr = nmi_puts(message, "System stopped due to unrecoverable machine check, code: 0x"); 151 + u64_to_hex(ptr, S390_lowcore.mcck_interruption_code); 152 + 153 + /* 154 + * Disable low address protection and make machine check new PSW a 155 + * disabled wait PSW. Any additional machine check cannot be handled. 156 + */ 157 + __ctl_store(cr0.val, 0, 0); 158 + cr0_new = cr0; 159 + cr0_new.lap = 0; 160 + __ctl_load(cr0_new.val, 0, 0); 161 + psw_save = S390_lowcore.mcck_new_psw; 162 + psw_bits(S390_lowcore.mcck_new_psw).io = 0; 163 + psw_bits(S390_lowcore.mcck_new_psw).ext = 0; 164 + psw_bits(S390_lowcore.mcck_new_psw).wait = 1; 165 + sclp_emergency_printk(message); 166 + 167 + /* 168 + * Restore machine check new PSW and control register 0 to original 169 + * values. This makes possible system dump analysis easier. 170 + */ 171 + S390_lowcore.mcck_new_psw = psw_save; 172 + __ctl_load(cr0.val, 0, 0); 98 173 disabled_wait(); 99 174 while (1); 100 175 } ··· 210 181 trace_hardirqs_on(); 211 182 } 212 183 /* 213 - * returns 0 if all required registers are available 184 + * returns 0 if register contents could be validated 214 185 * returns 1 otherwise 215 186 */ 216 - static int notrace s390_validate_registers(union mci mci, int umode) 187 + static int notrace s390_validate_registers(union mci mci) 217 188 { 218 189 struct mcesa *mcesa; 219 190 void *fpt_save_area; ··· 224 195 kill_task = 0; 225 196 zero = 0; 226 197 227 - if (!mci.gr) { 228 - /* 229 - * General purpose registers couldn't be restored and have 230 - * unknown contents. Stop system or terminate process. 231 - */ 232 - if (!umode) 233 - s390_handle_damage(); 198 + if (!mci.gr || !mci.fp) 234 199 kill_task = 1; 235 - } 236 - if (!mci.fp) { 237 - /* 238 - * Floating point registers can't be restored. If the 239 - * kernel currently uses floating point registers the 240 - * system is stopped. If the process has its floating 241 - * pointer registers loaded it is terminated. 242 - */ 243 - if (S390_lowcore.fpu_flags & KERNEL_VXR_V0V7) 244 - s390_handle_damage(); 245 - if (!test_cpu_flag(CIF_FPU)) 246 - kill_task = 1; 247 - } 248 200 fpt_save_area = &S390_lowcore.floating_pt_save_area; 249 201 if (!mci.fc) { 250 - /* 251 - * Floating point control register can't be restored. 252 - * If the kernel currently uses the floating pointer 253 - * registers and needs the FPC register the system is 254 - * stopped. If the process has its floating pointer 255 - * registers loaded it is terminated. Otherwise the 256 - * FPC is just validated. 257 - */ 258 - if (S390_lowcore.fpu_flags & KERNEL_FPC) 259 - s390_handle_damage(); 202 + kill_task = 1; 260 203 asm volatile( 261 204 " lfpc %0\n" 262 205 : 263 206 : "Q" (zero)); 264 - if (!test_cpu_flag(CIF_FPU)) 265 - kill_task = 1; 266 207 } else { 267 208 asm volatile( 268 209 " lfpc %0\n" ··· 274 275 * appropriate actions. The host vector or FPU values have been 275 276 * saved by KVM and will be restored by KVM. 276 277 */ 277 - if (!mci.vr && !test_cpu_flag(CIF_MCCK_GUEST)) { 278 - /* 279 - * Vector registers can't be restored. If the kernel 280 - * currently uses vector registers the system is 281 - * stopped. If the process has its vector registers 282 - * loaded it is terminated. Otherwise just validate 283 - * the registers. 284 - */ 285 - if (S390_lowcore.fpu_flags & KERNEL_VXR) 286 - s390_handle_damage(); 287 - if (!test_cpu_flag(CIF_FPU)) 288 - kill_task = 1; 289 - } 278 + if (!mci.vr && !test_cpu_flag(CIF_MCCK_GUEST)) 279 + kill_task = 1; 290 280 cr0.val = S390_lowcore.cregs_save_area[0]; 291 281 cr0.afp = cr0.vx = 1; 292 282 __ctl_load(cr0.val, 0, 0); 293 283 asm volatile( 294 284 " la 1,%0\n" 295 - " .word 0xe70f,0x1000,0x0036\n" /* vlm 0,15,0(1) */ 296 - " .word 0xe70f,0x1100,0x0c36\n" /* vlm 16,31,256(1) */ 285 + " VLM 0,15,0,1\n" 286 + " VLM 16,31,256,1\n" 297 287 : 298 288 : "Q" (*(struct vx_array *)mcesa->vector_save_area) 299 289 : "1"); ··· 294 306 : 295 307 : "a" (&S390_lowcore.access_regs_save_area) 296 308 : "memory"); 297 - if (!mci.ar) { 298 - /* 299 - * Access registers have unknown contents. 300 - * Terminating task. 301 - */ 309 + if (!mci.ar) 302 310 kill_task = 1; 303 - } 304 311 /* Validate guarded storage registers */ 305 312 cr2.val = S390_lowcore.cregs_save_area[2]; 306 313 if (cr2.gse) { ··· 434 451 s390_handle_damage(); 435 452 } 436 453 } 437 - if (s390_validate_registers(mci, user_mode(regs))) { 454 + if (s390_validate_registers(mci)) { 455 + if (!user_mode(regs)) 456 + s390_handle_damage(); 438 457 /* 439 458 * Couldn't restore all register contents for the 440 459 * user space process -> mark task for termination. ··· 465 480 mcck->stp_queue |= stp_island_check(); 466 481 mcck_pending = 1; 467 482 } 468 - 483 + /* 484 + * Reinject storage related machine checks into the guest if they 485 + * happen when the guest is running. 486 + */ 487 + if (!test_cpu_flag(CIF_MCCK_GUEST)) { 488 + /* Storage error uncorrected */ 489 + if (mci.se) 490 + s390_handle_damage(); 491 + /* Storage key-error uncorrected */ 492 + if (mci.ke) 493 + s390_handle_damage(); 494 + /* Storage degradation */ 495 + if (mci.ds && mci.fa) 496 + s390_handle_damage(); 497 + } 469 498 if (mci.cp) { 470 499 /* Channel report word pending */ 471 500 mcck->channel_report = 1;
+23 -25
arch/s390/kernel/perf_pai_crypto.c
··· 35 35 struct paicrypt_map { 36 36 unsigned long *page; /* Page for CPU to store counters */ 37 37 struct pai_userdata *save; /* Page to store no-zero counters */ 38 - unsigned int users; /* # of PAI crypto users */ 39 - unsigned int sampler; /* # of PAI crypto samplers */ 40 - unsigned int counter; /* # of PAI crypto counters */ 38 + unsigned int active_events; /* # of PAI crypto users */ 39 + unsigned int refcnt; /* Reference count mapped buffers */ 40 + enum paievt_mode mode; /* Type of event */ 41 41 struct perf_event *event; /* Perf event for sampling */ 42 42 }; 43 43 ··· 56 56 cpump->event = NULL; 57 57 static_branch_dec(&pai_key); 58 58 mutex_lock(&pai_reserve_mutex); 59 - if (event->attr.sample_period) 60 - cpump->sampler -= 1; 61 - else 62 - cpump->counter -= 1; 63 - debug_sprintf_event(cfm_dbg, 5, "%s event %#llx cpu %d" 64 - " sampler %d counter %d\n", __func__, 65 - event->attr.config, event->cpu, cpump->sampler, 66 - cpump->counter); 67 - if (!cpump->counter && !cpump->sampler) { 59 + debug_sprintf_event(cfm_dbg, 5, "%s event %#llx cpu %d users %d" 60 + " mode %d refcnt %d\n", __func__, 61 + event->attr.config, event->cpu, 62 + cpump->active_events, cpump->mode, cpump->refcnt); 63 + if (!--cpump->refcnt) { 68 64 debug_sprintf_event(cfm_dbg, 4, "%s page %#lx save %p\n", 69 65 __func__, (unsigned long)cpump->page, 70 66 cpump->save); ··· 68 72 cpump->page = NULL; 69 73 kvfree(cpump->save); 70 74 cpump->save = NULL; 75 + cpump->mode = PAI_MODE_NONE; 71 76 } 72 77 mutex_unlock(&pai_reserve_mutex); 73 78 } ··· 133 136 */ 134 137 static int paicrypt_busy(struct perf_event_attr *a, struct paicrypt_map *cpump) 135 138 { 136 - unsigned int *use_ptr; 137 139 int rc = 0; 138 140 139 141 mutex_lock(&pai_reserve_mutex); 140 142 if (a->sample_period) { /* Sampling requested */ 141 - use_ptr = &cpump->sampler; 142 - if (cpump->counter || cpump->sampler) 143 + if (cpump->mode != PAI_MODE_NONE) 143 144 rc = -EBUSY; /* ... sampling/counting active */ 144 145 } else { /* Counting requested */ 145 - use_ptr = &cpump->counter; 146 - if (cpump->sampler) 146 + if (cpump->mode == PAI_MODE_SAMPLING) 147 147 rc = -EBUSY; /* ... and sampling active */ 148 148 } 149 149 if (rc) ··· 166 172 rc = 0; 167 173 168 174 unlock: 169 - /* If rc is non-zero, do not increment counter/sampler. */ 170 - if (!rc) 171 - *use_ptr += 1; 172 - debug_sprintf_event(cfm_dbg, 5, "%s sample_period %#llx sampler %d" 173 - " counter %d page %#lx save %p rc %d\n", __func__, 174 - a->sample_period, cpump->sampler, cpump->counter, 175 + /* If rc is non-zero, do not set mode and reference count */ 176 + if (!rc) { 177 + cpump->refcnt++; 178 + cpump->mode = a->sample_period ? PAI_MODE_SAMPLING 179 + : PAI_MODE_COUNTING; 180 + } 181 + debug_sprintf_event(cfm_dbg, 5, "%s sample_period %#llx users %d" 182 + " mode %d refcnt %d page %#lx save %p rc %d\n", 183 + __func__, a->sample_period, cpump->active_events, 184 + cpump->mode, cpump->refcnt, 175 185 (unsigned long)cpump->page, cpump->save, rc); 176 186 mutex_unlock(&pai_reserve_mutex); 177 187 return rc; ··· 260 262 struct paicrypt_map *cpump = this_cpu_ptr(&paicrypt_map); 261 263 unsigned long ccd; 262 264 263 - if (cpump->users++ == 0) { 265 + if (++cpump->active_events == 1) { 264 266 ccd = virt_to_phys(cpump->page) | PAI_CRYPTO_KERNEL_OFFSET; 265 267 WRITE_ONCE(S390_lowcore.ccd, ccd); 266 268 __ctl_set_bit(0, 50); ··· 291 293 if (!event->attr.sample_period) 292 294 /* Only counting needs to read counter */ 293 295 paicrypt_stop(event, PERF_EF_UPDATE); 294 - if (cpump->users-- == 1) { 296 + if (--cpump->active_events == 0) { 295 297 __ctl_clear_bit(0, 50); 296 298 WRITE_ONCE(S390_lowcore.ccd, 0); 297 299 }
+3 -9
arch/s390/kernel/perf_pai_ext.c
··· 28 28 static debug_info_t *paiext_dbg; 29 29 static unsigned int paiext_cnt; /* Extracted with QPACI instruction */ 30 30 31 - enum paiext_mode { 32 - PAI_MODE_NONE, 33 - PAI_MODE_SAMPLING, 34 - PAI_MODE_COUNTER, 35 - }; 36 - 37 31 struct pai_userdata { 38 32 u16 num; 39 33 u64 value; ··· 48 54 struct paiext_map { 49 55 unsigned long *area; /* Area for CPU to store counters */ 50 56 struct pai_userdata *save; /* Area to store non-zero counters */ 51 - enum paiext_mode mode; /* Type of event */ 57 + enum paievt_mode mode; /* Type of event */ 52 58 unsigned int active_events; /* # of PAI Extension users */ 53 59 unsigned int refcnt; 54 60 struct perf_event *event; /* Perf event for sampling */ ··· 186 192 goto unlock; 187 193 } 188 194 cpump->mode = a->sample_period ? PAI_MODE_SAMPLING 189 - : PAI_MODE_COUNTER; 195 + : PAI_MODE_COUNTING; 190 196 } else { 191 197 /* Multiple invocation, check whats active. 192 198 * Supported are multiple counter events or only one sampling 193 199 * event concurrently at any one time. 194 200 */ 195 201 if (cpump->mode == PAI_MODE_SAMPLING || 196 - (cpump->mode == PAI_MODE_COUNTER && a->sample_period)) { 202 + (cpump->mode == PAI_MODE_COUNTING && a->sample_period)) { 197 203 rc = -EBUSY; 198 204 goto unlock; 199 205 }
+2 -1
arch/s390/kernel/setup.c
··· 437 437 lc->svc_new_psw.addr = (unsigned long) system_call; 438 438 lc->program_new_psw.mask = int_psw_mask | PSW_MASK_MCHECK; 439 439 lc->program_new_psw.addr = (unsigned long) pgm_check_handler; 440 - lc->mcck_new_psw.mask = PSW_KERNEL_BITS; 440 + lc->mcck_new_psw.mask = int_psw_mask; 441 441 lc->mcck_new_psw.addr = (unsigned long) mcck_int_handler; 442 442 lc->io_new_psw.mask = int_psw_mask | PSW_MASK_MCHECK; 443 443 lc->io_new_psw.addr = (unsigned long) io_int_handler; ··· 512 512 S390_lowcore.external_new_psw.mask |= PSW_MASK_DAT; 513 513 S390_lowcore.svc_new_psw.mask |= PSW_MASK_DAT; 514 514 S390_lowcore.program_new_psw.mask |= PSW_MASK_DAT; 515 + S390_lowcore.mcck_new_psw.mask |= PSW_MASK_DAT; 515 516 S390_lowcore.io_new_psw.mask |= PSW_MASK_DAT; 516 517 __ctl_set_bit(0, 28); 517 518 __ctl_store(S390_lowcore.cregs_save_area, 0, 15);
+36 -3
arch/s390/mm/init.c
··· 31 31 #include <linux/cma.h> 32 32 #include <linux/gfp.h> 33 33 #include <linux/dma-direct.h> 34 + #include <linux/percpu.h> 34 35 #include <asm/processor.h> 35 36 #include <linux/uaccess.h> 36 37 #include <asm/pgalloc.h> ··· 208 207 __set_memory((unsigned long)_sinittext, 209 208 (unsigned long)(_einittext - _sinittext) >> PAGE_SHIFT, 210 209 SET_MEMORY_RW | SET_MEMORY_NX); 211 - free_reserved_area(sclp_early_sccb, 212 - sclp_early_sccb + EXT_SCCB_READ_SCP, 213 - POISON_FREE_INITMEM, "unused early sccb"); 214 210 free_initmem_default(POISON_FREE_INITMEM); 215 211 } 216 212 ··· 218 220 * or equal than the memory increment size. 219 221 */ 220 222 return max_t(unsigned long, MIN_MEMORY_BLOCK_SIZE, sclp.rzm); 223 + } 224 + 225 + unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; 226 + EXPORT_SYMBOL(__per_cpu_offset); 227 + 228 + static int __init pcpu_cpu_distance(unsigned int from, unsigned int to) 229 + { 230 + return LOCAL_DISTANCE; 231 + } 232 + 233 + static int __init pcpu_cpu_to_node(int cpu) 234 + { 235 + return 0; 236 + } 237 + 238 + void __init setup_per_cpu_areas(void) 239 + { 240 + unsigned long delta; 241 + unsigned int cpu; 242 + int rc; 243 + 244 + /* 245 + * Always reserve area for module percpu variables. That's 246 + * what the legacy allocator did. 247 + */ 248 + rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE, 249 + PERCPU_DYNAMIC_RESERVE, PAGE_SIZE, 250 + pcpu_cpu_distance, 251 + pcpu_cpu_to_node); 252 + if (rc < 0) 253 + panic("Failed to initialize percpu areas."); 254 + 255 + delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start; 256 + for_each_possible_cpu(cpu) 257 + __per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu]; 221 258 } 222 259 223 260 #ifdef CONFIG_MEMORY_HOTPLUG
-11
arch/s390/mm/page-states.c
··· 58 58 cmma_flag = 2; 59 59 } 60 60 61 - static inline unsigned char get_page_state(struct page *page) 62 - { 63 - unsigned char state; 64 - 65 - asm volatile(" .insn rrf,0xb9ab0000,%0,%1,%2,0" 66 - : "=&d" (state) 67 - : "a" (page_to_phys(page)), 68 - "i" (ESSA_GET_STATE)); 69 - return state & 0x3f; 70 - } 71 - 72 61 static inline void set_page_unused(struct page *page, int order) 73 62 { 74 63 int i, rc;
+1 -1
arch/s390/pci/pci_irq.c
··· 132 132 static int zpci_set_irq_affinity(struct irq_data *data, const struct cpumask *dest, 133 133 bool force) 134 134 { 135 - struct msi_desc *entry = irq_get_msi_desc(data->irq); 135 + struct msi_desc *entry = irq_data_get_msi_desc(data); 136 136 struct msi_msg msg = entry->msg; 137 137 int cpu_addr = smp_cpu_get_cpu_address(cpumask_first(dest)); 138 138
+185 -108
drivers/s390/char/con3215.c
··· 102 102 static DEFINE_SPINLOCK(raw3215_freelist_lock); 103 103 104 104 static struct tty_driver *tty3215_driver; 105 + static bool con3215_drop = true; 105 106 106 107 /* 107 108 * Get a request structure from the free list ··· 160 159 ccw->cmd_code = 0x0A; /* read inquiry */ 161 160 ccw->flags = 0x20; /* ignore incorrect length */ 162 161 ccw->count = 160; 163 - ccw->cda = (__u32) __pa(raw->inbuf); 162 + ccw->cda = (__u32)__pa(raw->inbuf); 164 163 } 165 164 166 165 /* ··· 219 218 ccw[-1].flags |= 0x40; /* use command chaining */ 220 219 ccw->cmd_code = 0x01; /* write, auto carrier return */ 221 220 ccw->flags = 0x20; /* ignore incorrect length ind. */ 222 - ccw->cda = 223 - (__u32) __pa(raw->buffer + ix); 221 + ccw->cda = (__u32)__pa(raw->buffer + ix); 224 222 count = len; 225 223 if (ix + count > RAW3215_BUFFER_SIZE) 226 224 count = RAW3215_BUFFER_SIZE - ix; ··· 447 447 } 448 448 449 449 /* 450 + * Need to drop data to avoid blocking. Drop as much data as possible. 451 + * This is unqueued part in the buffer and the queued part in the request. 452 + * Also adjust the head position to append new data and set count 453 + * accordingly. 454 + * 455 + * Return number of bytes available in buffer. 456 + */ 457 + static unsigned int raw3215_drop(struct raw3215_info *raw) 458 + { 459 + struct raw3215_req *req; 460 + 461 + req = raw->queued_write; 462 + if (req) { 463 + /* Drop queued data and delete request */ 464 + raw->written -= req->len; 465 + raw3215_free_req(req); 466 + raw->queued_write = NULL; 467 + } 468 + raw->head = (raw->head - raw->count + raw->written) & 469 + (RAW3215_BUFFER_SIZE - 1); 470 + raw->count = raw->written; 471 + 472 + return RAW3215_BUFFER_SIZE - raw->count; 473 + } 474 + 475 + /* 450 476 * Wait until length bytes are available int the output buffer. 477 + * If drop mode is active and wait condition holds true, start dropping 478 + * data. 451 479 * Has to be called with the s390irq lock held. Can be called 452 480 * disabled. 453 481 */ 454 - static void raw3215_make_room(struct raw3215_info *raw, unsigned int length) 482 + static unsigned int raw3215_make_room(struct raw3215_info *raw, 483 + unsigned int length, bool drop) 455 484 { 456 485 while (RAW3215_BUFFER_SIZE - raw->count < length) { 486 + if (drop) 487 + return raw3215_drop(raw); 488 + 457 489 /* there might be a request pending */ 458 490 raw->flags |= RAW3215_FLUSHING; 459 491 raw3215_mk_write_req(raw); ··· 502 470 udelay(100); 503 471 spin_lock(get_ccwdev_lock(raw->cdev)); 504 472 } 473 + return length; 474 + } 475 + 476 + #define RAW3215_COUNT 1 477 + #define RAW3215_STORE 2 478 + 479 + /* 480 + * Add text to console buffer. Find tabs in input and calculate size 481 + * including tab replacement. 482 + * This function operates in 2 different modes, depending on parameter 483 + * opmode: 484 + * RAW3215_COUNT: Get the size needed for the input string with 485 + * proper tab replacement calculation. 486 + * Return value is the number of bytes required to store the 487 + * input. However no data is actually stored. 488 + * The parameter todrop is not used. 489 + * RAW3215_STORE: Add data to the console buffer. The parameter todrop is 490 + * valid and contains the number of bytes to be dropped from head of 491 + * string without blocking. 492 + * Return value is the number of bytes copied. 493 + */ 494 + static unsigned int raw3215_addtext(const char *str, unsigned int length, 495 + struct raw3215_info *raw, int opmode, 496 + unsigned int todrop) 497 + { 498 + unsigned int c, ch, i, blanks, expanded_size = 0; 499 + unsigned int column = raw->line_pos; 500 + 501 + if (opmode == RAW3215_COUNT) 502 + todrop = 0; 503 + 504 + for (c = 0; c < length; ++c) { 505 + blanks = 1; 506 + ch = str[c]; 507 + 508 + switch (ch) { 509 + case '\n': 510 + expanded_size++; 511 + column = 0; 512 + break; 513 + case '\t': 514 + blanks = TAB_STOP_SIZE - (column % TAB_STOP_SIZE); 515 + column += blanks; 516 + expanded_size += blanks; 517 + ch = ' '; 518 + break; 519 + default: 520 + expanded_size++; 521 + column++; 522 + break; 523 + } 524 + 525 + if (opmode == RAW3215_COUNT) 526 + continue; 527 + if (todrop && expanded_size < todrop) /* Drop head data */ 528 + continue; 529 + for (i = 0; i < blanks; i++) { 530 + raw->buffer[raw->head] = (char)_ascebc[(int)ch]; 531 + raw->head = (raw->head + 1) & (RAW3215_BUFFER_SIZE - 1); 532 + raw->count++; 533 + } 534 + raw->line_pos = column; 535 + } 536 + return expanded_size - todrop; 505 537 } 506 538 507 539 /* ··· 574 478 static void raw3215_write(struct raw3215_info *raw, const char *str, 575 479 unsigned int length) 576 480 { 481 + unsigned int count, avail; 577 482 unsigned long flags; 578 - int c, count; 579 - 580 - while (length > 0) { 581 - spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); 582 - count = (length > RAW3215_BUFFER_SIZE) ? 583 - RAW3215_BUFFER_SIZE : length; 584 - length -= count; 585 - 586 - raw3215_make_room(raw, count); 587 - 588 - /* copy string to output buffer and convert it to EBCDIC */ 589 - while (1) { 590 - c = min_t(int, count, 591 - min(RAW3215_BUFFER_SIZE - raw->count, 592 - RAW3215_BUFFER_SIZE - raw->head)); 593 - if (c <= 0) 594 - break; 595 - memcpy(raw->buffer + raw->head, str, c); 596 - ASCEBC(raw->buffer + raw->head, c); 597 - raw->head = (raw->head + c) & (RAW3215_BUFFER_SIZE - 1); 598 - raw->count += c; 599 - raw->line_pos += c; 600 - str += c; 601 - count -= c; 602 - } 603 - if (!(raw->flags & RAW3215_WORKING)) { 604 - raw3215_mk_write_req(raw); 605 - /* start or queue request */ 606 - raw3215_try_io(raw); 607 - } 608 - spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); 609 - } 610 - } 611 - 612 - /* 613 - * Put character routine for 3215 devices 614 - */ 615 - static void raw3215_putchar(struct raw3215_info *raw, unsigned char ch) 616 - { 617 - unsigned long flags; 618 - unsigned int length, i; 619 483 620 484 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); 621 - if (ch == '\t') { 622 - length = TAB_STOP_SIZE - (raw->line_pos%TAB_STOP_SIZE); 623 - raw->line_pos += length; 624 - ch = ' '; 625 - } else if (ch == '\n') { 626 - length = 1; 627 - raw->line_pos = 0; 628 - } else { 629 - length = 1; 630 - raw->line_pos++; 631 - } 632 - raw3215_make_room(raw, length); 633 485 634 - for (i = 0; i < length; i++) { 635 - raw->buffer[raw->head] = (char) _ascebc[(int) ch]; 636 - raw->head = (raw->head + 1) & (RAW3215_BUFFER_SIZE - 1); 637 - raw->count++; 486 + count = raw3215_addtext(str, length, raw, RAW3215_COUNT, 0); 487 + 488 + avail = raw3215_make_room(raw, count, con3215_drop); 489 + if (avail) { 490 + raw3215_addtext(str, length, raw, RAW3215_STORE, 491 + count - avail); 638 492 } 639 493 if (!(raw->flags & RAW3215_WORKING)) { 640 494 raw3215_mk_write_req(raw); ··· 592 546 raw3215_try_io(raw); 593 547 } 594 548 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); 549 + } 550 + 551 + /* 552 + * Put character routine for 3215 devices 553 + */ 554 + static void raw3215_putchar(struct raw3215_info *raw, unsigned char ch) 555 + { 556 + raw3215_write(raw, &ch, 1); 595 557 } 596 558 597 559 /* ··· 696 642 kfree(raw); 697 643 } 698 644 699 - static int raw3215_probe (struct ccw_device *cdev) 645 + static int raw3215_probe(struct ccw_device *cdev) 700 646 { 701 647 struct raw3215_info *raw; 702 648 int line; ··· 729 675 return 0; 730 676 } 731 677 732 - static void raw3215_remove (struct ccw_device *cdev) 678 + static void raw3215_remove(struct ccw_device *cdev) 733 679 { 734 680 struct raw3215_info *raw; 735 681 unsigned int line; ··· 748 694 } 749 695 } 750 696 751 - static int raw3215_set_online (struct ccw_device *cdev) 697 + static int raw3215_set_online(struct ccw_device *cdev) 752 698 { 753 699 struct raw3215_info *raw; 754 700 ··· 759 705 return raw3215_startup(raw); 760 706 } 761 707 762 - static int raw3215_set_offline (struct ccw_device *cdev) 708 + static int raw3215_set_offline(struct ccw_device *cdev) 763 709 { 764 710 struct raw3215_info *raw; 765 711 ··· 777 723 { /* end of list */ }, 778 724 }; 779 725 726 + static ssize_t con_drop_store(struct device_driver *dev, const char *buf, size_t count) 727 + { 728 + bool drop; 729 + int rc; 730 + 731 + rc = kstrtobool(buf, &drop); 732 + if (!rc) 733 + con3215_drop = drop; 734 + return rc ?: count; 735 + } 736 + 737 + static ssize_t con_drop_show(struct device_driver *dev, char *buf) 738 + { 739 + return sysfs_emit(buf, "%d\n", con3215_drop ? 1 : 0); 740 + } 741 + 742 + static DRIVER_ATTR_RW(con_drop); 743 + 744 + static struct attribute *con3215_drv_attrs[] = { 745 + &driver_attr_con_drop.attr, 746 + NULL, 747 + }; 748 + 749 + static struct attribute_group con3215_drv_attr_group = { 750 + .attrs = con3215_drv_attrs, 751 + NULL, 752 + }; 753 + 754 + static const struct attribute_group *con3215_drv_attr_groups[] = { 755 + &con3215_drv_attr_group, 756 + NULL, 757 + }; 758 + 780 759 static struct ccw_driver raw3215_ccw_driver = { 781 760 .driver = { 782 761 .name = "3215", 762 + .groups = con3215_drv_attr_groups, 783 763 .owner = THIS_MODULE, 784 764 }, 785 765 .ids = raw3215_id, ··· 824 736 .int_class = IRQIO_C15, 825 737 }; 826 738 739 + static void handle_write(struct raw3215_info *raw, const char *str, int count) 740 + { 741 + int i; 742 + 743 + while (count > 0) { 744 + i = min_t(int, count, RAW3215_BUFFER_SIZE - 1); 745 + raw3215_write(raw, str, i); 746 + count -= i; 747 + str += i; 748 + } 749 + } 750 + 827 751 #ifdef CONFIG_TN3215_CONSOLE 828 752 /* 829 753 * Write a string to the 3215 console 830 754 */ 831 - static void con3215_write(struct console *co, const char *str, 832 - unsigned int count) 755 + static void con3215_write(struct console *co, const char *str, unsigned int count) 833 756 { 834 - struct raw3215_info *raw; 835 - int i; 836 - 837 - if (count <= 0) 838 - return; 839 - raw = raw3215[0]; /* console 3215 is the first one */ 840 - while (count > 0) { 841 - for (i = 0; i < count; i++) 842 - if (str[i] == '\t' || str[i] == '\n') 843 - break; 844 - raw3215_write(raw, str, i); 845 - count -= i; 846 - str += i; 847 - if (count > 0) { 848 - raw3215_putchar(raw, *str); 849 - count--; 850 - str++; 851 - } 852 - } 757 + handle_write(raw3215[0], str, count); 853 758 } 854 759 855 760 static struct tty_driver *con3215_device(struct console *c, int *index) ··· 868 787 raw = raw3215[0]; /* console 3215 is the first one */ 869 788 if (!spin_trylock_irqsave(get_ccwdev_lock(raw->cdev), flags)) 870 789 return NOTIFY_DONE; 871 - raw3215_make_room(raw, RAW3215_BUFFER_SIZE); 790 + raw3215_make_room(raw, RAW3215_BUFFER_SIZE, false); 872 791 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); 873 792 874 793 return NOTIFY_DONE; ··· 1021 940 /* 1022 941 * String write routine for 3215 ttys 1023 942 */ 1024 - static int tty3215_write(struct tty_struct * tty, 943 + static int tty3215_write(struct tty_struct *tty, 1025 944 const unsigned char *buf, int count) 1026 945 { 1027 - struct raw3215_info *raw = tty->driver_data; 1028 - int i, written; 1029 - 1030 - written = count; 1031 - while (count > 0) { 1032 - for (i = 0; i < count; i++) 1033 - if (buf[i] == '\t' || buf[i] == '\n') 1034 - break; 1035 - raw3215_write(raw, buf, i); 1036 - count -= i; 1037 - buf += i; 1038 - if (count > 0) { 1039 - raw3215_putchar(raw, *buf); 1040 - count--; 1041 - buf++; 1042 - } 1043 - } 1044 - return written; 946 + handle_write(tty->driver_data, buf, count); 947 + return count; 1045 948 } 1046 949 1047 950 /* ··· 1065 1000 /* 1066 1001 * Disable reading from a 3215 tty 1067 1002 */ 1068 - static void tty3215_throttle(struct tty_struct * tty) 1003 + static void tty3215_throttle(struct tty_struct *tty) 1069 1004 { 1070 1005 struct raw3215_info *raw = tty->driver_data; 1071 1006 ··· 1075 1010 /* 1076 1011 * Enable reading from a 3215 tty 1077 1012 */ 1078 - static void tty3215_unthrottle(struct tty_struct * tty) 1013 + static void tty3215_unthrottle(struct tty_struct *tty) 1079 1014 { 1080 1015 struct raw3215_info *raw = tty->driver_data; 1081 1016 unsigned long flags; ··· 1129 1064 .stop = tty3215_stop, 1130 1065 .start = tty3215_start, 1131 1066 }; 1067 + 1068 + static int __init con3215_setup_drop(char *str) 1069 + { 1070 + bool drop; 1071 + int rc; 1072 + 1073 + rc = kstrtobool(str, &drop); 1074 + if (!rc) 1075 + con3215_drop = drop; 1076 + return rc; 1077 + } 1078 + early_param("con3215_drop", con3215_setup_drop); 1132 1079 1133 1080 /* 1134 1081 * 3215 tty registration code called from tty_init().
+6 -6
drivers/s390/char/raw3270.c
··· 111 111 return rp->state == RAW3270_STATE_READY; 112 112 } 113 113 114 - static inline int raw3270_state_final(struct raw3270 *rp) 115 - { 116 - return rp->state == RAW3270_STATE_INIT || 117 - rp->state == RAW3270_STATE_READY; 118 - } 119 - 120 114 void 121 115 raw3270_buffer_address(struct raw3270 *rp, char *cp, unsigned short addr) 122 116 { ··· 742 748 #ifdef CONFIG_TN3270_CONSOLE 743 749 /* Tentative definition - see below for actual definition. */ 744 750 static struct ccw_driver raw3270_ccw_driver; 751 + 752 + static inline int raw3270_state_final(struct raw3270 *rp) 753 + { 754 + return rp->state == RAW3270_STATE_INIT || 755 + rp->state == RAW3270_STATE_READY; 756 + } 745 757 746 758 /* 747 759 * Setup 3270 device configured as console.
+15 -12
drivers/s390/char/sclp.c
··· 69 69 /* Number of console pages to allocate, used by sclp_con.c and sclp_vt220.c */ 70 70 int sclp_console_pages = SCLP_CONSOLE_PAGES; 71 71 /* Flag to indicate if buffer pages are dropped on buffer full condition */ 72 - int sclp_console_drop = 1; 72 + bool sclp_console_drop = true; 73 73 /* Number of times the console dropped buffer pages */ 74 74 unsigned long sclp_console_full; 75 75 ··· 195 195 196 196 static int __init sclp_setup_console_drop(char *str) 197 197 { 198 - int drop, rc; 199 - 200 - rc = kstrtoint(str, 0, &drop); 201 - if (!rc) 202 - sclp_console_drop = drop; 203 - return 1; 198 + return kstrtobool(str, &sclp_console_drop) == 0; 204 199 } 205 200 206 201 __setup("sclp_con_drop=", sclp_setup_console_drop); ··· 1200 1205 1201 1206 static ssize_t con_pages_show(struct device_driver *dev, char *buf) 1202 1207 { 1203 - return sprintf(buf, "%i\n", sclp_console_pages); 1208 + return sysfs_emit(buf, "%i\n", sclp_console_pages); 1204 1209 } 1205 1210 1206 1211 static DRIVER_ATTR_RO(con_pages); 1207 1212 1208 - static ssize_t con_drop_show(struct device_driver *dev, char *buf) 1213 + static ssize_t con_drop_store(struct device_driver *dev, const char *buf, size_t count) 1209 1214 { 1210 - return sprintf(buf, "%i\n", sclp_console_drop); 1215 + int rc; 1216 + 1217 + rc = kstrtobool(buf, &sclp_console_drop); 1218 + return rc ?: count; 1211 1219 } 1212 1220 1213 - static DRIVER_ATTR_RO(con_drop); 1221 + static ssize_t con_drop_show(struct device_driver *dev, char *buf) 1222 + { 1223 + return sysfs_emit(buf, "%i\n", sclp_console_drop); 1224 + } 1225 + 1226 + static DRIVER_ATTR_RW(con_drop); 1214 1227 1215 1228 static ssize_t con_full_show(struct device_driver *dev, char *buf) 1216 1229 { 1217 - return sprintf(buf, "%lu\n", sclp_console_full); 1230 + return sysfs_emit(buf, "%lu\n", sclp_console_full); 1218 1231 } 1219 1232 1220 1233 static DRIVER_ATTR_RO(con_full);
+1 -1
drivers/s390/char/sclp.h
··· 307 307 308 308 extern int sclp_init_state; 309 309 extern int sclp_console_pages; 310 - extern int sclp_console_drop; 310 + extern bool sclp_console_drop; 311 311 extern unsigned long sclp_console_full; 312 312 extern bool sclp_mask_compat_mode; 313 313
+3 -1
drivers/s390/char/sclp_early.c
··· 57 57 sclp.has_diag318 = !!(sccb->byte_134 & 0x80); 58 58 sclp.has_iplcc = !!(sccb->byte_134 & 0x02); 59 59 } 60 - if (sccb->cpuoff > 137) 60 + if (sccb->cpuoff > 137) { 61 61 sclp.has_sipl = !!(sccb->cbl & 0x4000); 62 + sclp.has_sipl_eckd = !!(sccb->cbl & 0x2000); 63 + } 62 64 sclp.rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2; 63 65 sclp.rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; 64 66 sclp.rzm <<= 20;
+25 -1
drivers/s390/char/sclp_early_core.c
··· 17 17 18 18 static struct read_info_sccb __bootdata(sclp_info_sccb); 19 19 static int __bootdata(sclp_info_sccb_valid); 20 - char *__bootdata(sclp_early_sccb); 20 + char *__bootdata_preserved(sclp_early_sccb); 21 21 int sclp_init_state = sclp_init_state_uninitialized; 22 22 /* 23 23 * Used to keep track of the size of the event masks. Qemu until version 2.11 ··· 238 238 void sclp_early_printk(const char *str) 239 239 { 240 240 __sclp_early_printk(str, strlen(str)); 241 + } 242 + 243 + /* 244 + * Use sclp_emergency_printk() to print a string when the system is in a 245 + * state where regular console drivers cannot be assumed to work anymore. 246 + * 247 + * Callers must make sure that no concurrent SCLP requests are outstanding 248 + * and all other CPUs are stopped, or at least disabled for external 249 + * interrupts. 250 + */ 251 + void sclp_emergency_printk(const char *str) 252 + { 253 + int have_linemode, have_vt220; 254 + unsigned int len; 255 + 256 + len = strlen(str); 257 + /* 258 + * Don't care about return values; if requests fail, just ignore and 259 + * continue to have a rather high chance that anything is printed. 260 + */ 261 + sclp_early_setup(0, &have_linemode, &have_vt220); 262 + sclp_early_print_lm(str, len); 263 + sclp_early_print_vt220(str, len); 264 + sclp_early_setup(1, &have_linemode, &have_vt220); 241 265 } 242 266 243 267 /*
+4
drivers/s390/char/zcore.c
··· 282 282 TRACE("type: nvme\n"); 283 283 TRACE("fid: %x\n", ipl_info.data.nvme.fid); 284 284 TRACE("nsid: %x\n", ipl_info.data.nvme.nsid); 285 + } else if (ipl_info.type == IPL_TYPE_ECKD_DUMP) { 286 + TRACE("type: eckd\n"); 287 + TRACE("devno: %x\n", ipl_info.data.eckd.dev_id.devno); 288 + TRACE("ssid: %x\n", ipl_info.data.eckd.dev_id.ssid); 285 289 } 286 290 287 291 rc = sclp_sdias_init();
+2 -1
drivers/s390/cio/chsc_sch.c
··· 11 11 #include <linux/slab.h> 12 12 #include <linux/compat.h> 13 13 #include <linux/device.h> 14 + #include <linux/io.h> 14 15 #include <linux/module.h> 15 16 #include <linux/uaccess.h> 16 17 #include <linux/miscdevice.h> ··· 86 85 if (!private) 87 86 return -ENOMEM; 88 87 dev_set_drvdata(&sch->dev, private); 89 - ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch); 88 + ret = cio_enable_subchannel(sch, (u32)virt_to_phys(sch)); 90 89 if (ret) { 91 90 CHSC_MSG(0, "Failed to enable 0.%x.%04x: %d\n", 92 91 sch->schid.ssid, sch->schid.sch_no, ret);
+7 -7
drivers/s390/cio/cio.c
··· 134 134 135 135 memset(orb, 0, sizeof(union orb)); 136 136 /* sch is always under 2G. */ 137 - orb->cmd.intparm = (u32)(addr_t)sch; 137 + orb->cmd.intparm = (u32)virt_to_phys(sch); 138 138 orb->cmd.fmt = 1; 139 139 140 140 orb->cmd.pfch = priv->options.prefetch == 0; ··· 148 148 orb->cmd.i2k = 0; 149 149 orb->cmd.key = key >> 4; 150 150 /* issue "Start Subchannel" */ 151 - orb->cmd.cpa = (__u32) __pa(cpa); 151 + orb->cmd.cpa = (u32)virt_to_phys(cpa); 152 152 ccode = ssch(sch->schid, orb); 153 153 154 154 /* process condition code */ ··· 539 539 tpi_info = &get_irq_regs()->tpi_info; 540 540 trace_s390_cio_interrupt(tpi_info); 541 541 irb = this_cpu_ptr(&cio_irb); 542 - sch = (struct subchannel *)(unsigned long) tpi_info->intparm; 543 - if (!sch) { 542 + if (!tpi_info->intparm) { 544 543 /* Clear pending interrupt condition. */ 545 544 inc_irq_stat(IRQIO_CIO); 546 545 tsch(tpi_info->schid, irb); 547 546 return IRQ_HANDLED; 548 547 } 548 + sch = phys_to_virt(tpi_info->intparm); 549 549 spin_lock(sch->lock); 550 550 /* Store interrupt response block to lowcore. */ 551 551 if (tsch(tpi_info->schid, irb) == 0) { ··· 666 666 lockdep_set_class(sch->lock, &console_sch_key); 667 667 isc_register(CONSOLE_ISC); 668 668 sch->config.isc = CONSOLE_ISC; 669 - sch->config.intparm = (u32)(addr_t)sch; 669 + sch->config.intparm = (u32)virt_to_phys(sch); 670 670 ret = cio_commit_config(sch); 671 671 if (ret) { 672 672 isc_unregister(CONSOLE_ISC); ··· 713 713 union orb *orb = &to_io_private(sch)->orb; 714 714 715 715 memset(orb, 0, sizeof(union orb)); 716 - orb->tm.intparm = (u32) (addr_t) sch; 716 + orb->tm.intparm = (u32)virt_to_phys(sch); 717 717 orb->tm.key = key >> 4; 718 718 orb->tm.b = 1; 719 719 orb->tm.lpm = lpm ? lpm : sch->lpm; 720 - orb->tm.tcw = (u32) (addr_t) tcw; 720 + orb->tm.tcw = (u32)virt_to_phys(tcw); 721 721 cc = ssch(sch->schid, orb); 722 722 switch (cc) { 723 723 case 0:
+1 -1
drivers/s390/cio/device.c
··· 936 936 if (old_enabled) { 937 937 /* Try to reenable the old subchannel. */ 938 938 spin_lock_irq(old_sch->lock); 939 - cio_enable_subchannel(old_sch, (u32)(addr_t)old_sch); 939 + cio_enable_subchannel(old_sch, (u32)virt_to_phys(old_sch)); 940 940 spin_unlock_irq(old_sch->lock); 941 941 } 942 942 /* Release child reference for new parent. */
+7 -6
drivers/s390/cio/device_fsm.c
··· 9 9 10 10 #include <linux/module.h> 11 11 #include <linux/init.h> 12 + #include <linux/io.h> 12 13 #include <linux/jiffies.h> 13 14 #include <linux/string.h> 14 15 ··· 64 63 printk(KERN_WARNING "cio: orb indicates transport mode\n"); 65 64 printk(KERN_WARNING "cio: last tcw:\n"); 66 65 print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, 67 - (void *)(addr_t)orb->tm.tcw, 66 + phys_to_virt(orb->tm.tcw), 68 67 sizeof(struct tcw), 0); 69 68 } else { 70 69 printk(KERN_WARNING "cio: orb indicates command mode\n"); ··· 78 77 printk(KERN_WARNING "cio: last channel program:\n"); 79 78 80 79 print_hex_dump(KERN_WARNING, "cio: ", DUMP_PREFIX_NONE, 16, 1, 81 - (void *)(addr_t)orb->cmd.cpa, 80 + phys_to_virt(orb->cmd.cpa), 82 81 sizeof(struct ccw1), 0); 83 82 } 84 83 printk(KERN_WARNING "cio: ccw device state: %d\n", ··· 398 397 */ 399 398 cdev->private->flags.recog_done = 0; 400 399 cdev->private->state = DEV_STATE_SENSE_ID; 401 - if (cio_enable_subchannel(sch, (u32) (addr_t) sch)) { 400 + if (cio_enable_subchannel(sch, (u32)virt_to_phys(sch))) { 402 401 ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER); 403 402 return; 404 403 } ··· 549 548 (cdev->private->state != DEV_STATE_BOXED)) 550 549 return -EINVAL; 551 550 sch = to_subchannel(cdev->dev.parent); 552 - ret = cio_enable_subchannel(sch, (u32)(addr_t)sch); 551 + ret = cio_enable_subchannel(sch, (u32)virt_to_phys(sch)); 553 552 if (ret != 0) { 554 553 /* Couldn't enable the subchannel for i/o. Sick device. */ 555 554 if (ret == -ENODEV) ··· 692 691 struct subchannel *sch = to_subchannel(cdev->dev.parent); 693 692 694 693 if (cdev->online) { 695 - if (cio_enable_subchannel(sch, (u32) (addr_t) sch)) 694 + if (cio_enable_subchannel(sch, (u32)virt_to_phys(sch))) 696 695 ccw_device_done(cdev, DEV_STATE_NOT_OPER); 697 696 else 698 697 ccw_device_online_verify(cdev, dev_event); ··· 923 922 struct subchannel *sch; 924 923 925 924 sch = to_subchannel(cdev->dev.parent); 926 - if (cio_enable_subchannel(sch, (u32)(addr_t)sch) != 0) 925 + if (cio_enable_subchannel(sch, (u32)virt_to_phys(sch)) != 0) 927 926 /* Couldn't enable the subchannel for i/o. Sick device. */ 928 927 return; 929 928 cdev->private->state = DEV_STATE_DISCONNECTED_SENSE_ID;
+1 -1
drivers/s390/cio/device_id.c
··· 210 210 snsid_init(cdev); 211 211 /* Channel program setup. */ 212 212 cp->cmd_code = CCW_CMD_SENSE_ID; 213 - cp->cda = (u32) (addr_t) &cdev->private->dma_area->senseid; 213 + cp->cda = (u32)virt_to_phys(&cdev->private->dma_area->senseid); 214 214 cp->count = sizeof(struct senseid); 215 215 cp->flags = CCW_FLAG_SLI; 216 216 /* Request setup. */
+6 -5
drivers/s390/cio/device_pgid.c
··· 14 14 #include <linux/types.h> 15 15 #include <linux/errno.h> 16 16 #include <linux/slab.h> 17 + #include <linux/io.h> 17 18 #include <asm/ccwdev.h> 18 19 #include <asm/cio.h> 19 20 ··· 141 140 142 141 pgid->inf.fc = fn; 143 142 cp->cmd_code = CCW_CMD_SET_PGID; 144 - cp->cda = (u32) (addr_t) pgid; 143 + cp->cda = (u32)virt_to_phys(pgid); 145 144 cp->count = sizeof(*pgid); 146 145 cp->flags = CCW_FLAG_SLI; 147 146 req->cp = cp; ··· 442 441 443 442 /* Channel program setup. */ 444 443 cp->cmd_code = CCW_CMD_SENSE_PGID; 445 - cp->cda = (u32) (addr_t) &cdev->private->dma_area->pgid[i]; 444 + cp->cda = (u32)virt_to_phys(&cdev->private->dma_area->pgid[i]); 446 445 cp->count = sizeof(struct pgid); 447 446 cp->flags = CCW_FLAG_SLI; 448 447 req->cp = cp; ··· 632 631 struct ccw1 *cp = cdev->private->dma_area->iccws; 633 632 634 633 cp[0].cmd_code = CCW_CMD_STLCK; 635 - cp[0].cda = (u32) (addr_t) buf1; 634 + cp[0].cda = (u32)virt_to_phys(buf1); 636 635 cp[0].count = 32; 637 636 cp[0].flags = CCW_FLAG_CC; 638 637 cp[1].cmd_code = CCW_CMD_RELEASE; 639 - cp[1].cda = (u32) (addr_t) buf2; 638 + cp[1].cda = (u32)virt_to_phys(buf2); 640 639 cp[1].count = 32; 641 640 cp[1].flags = 0; 642 641 req->cp = cp; ··· 699 698 init_completion(&data.done); 700 699 data.rc = -EIO; 701 700 spin_lock_irq(sch->lock); 702 - rc = cio_enable_subchannel(sch, (u32) (addr_t) sch); 701 + rc = cio_enable_subchannel(sch, (u32)virt_to_phys(sch)); 703 702 if (rc) 704 703 goto out_unlock; 705 704 /* Perform operation. */
+2 -1
drivers/s390/cio/device_status.c
··· 9 9 10 10 #include <linux/module.h> 11 11 #include <linux/init.h> 12 + #include <linux/io.h> 12 13 13 14 #include <asm/ccwdev.h> 14 15 #include <asm/cio.h> ··· 332 331 */ 333 332 sense_ccw = &to_io_private(sch)->dma_area->sense_ccw; 334 333 sense_ccw->cmd_code = CCW_CMD_BASIC_SENSE; 335 - sense_ccw->cda = (__u32) __pa(cdev->private->dma_area->irb.ecw); 334 + sense_ccw->cda = virt_to_phys(cdev->private->dma_area->irb.ecw); 336 335 sense_ccw->count = SENSE_MAX_COUNT; 337 336 sense_ccw->flags = CCW_FLAG_SLI; 338 337
+5 -4
drivers/s390/cio/eadm_sch.c
··· 15 15 #include <linux/timer.h> 16 16 #include <linux/slab.h> 17 17 #include <linux/list.h> 18 + #include <linux/io.h> 18 19 19 20 #include <asm/css_chars.h> 20 21 #include <asm/debug.h> ··· 63 62 int cc; 64 63 65 64 orb_init(orb); 66 - orb->eadm.aob = (u32)__pa(aob); 67 - orb->eadm.intparm = (u32)(addr_t)sch; 65 + orb->eadm.aob = (u32)virt_to_phys(aob); 66 + orb->eadm.intparm = (u32)virt_to_phys(sch); 68 67 orb->eadm.key = PAGE_DEFAULT_KEY >> 4; 69 68 70 69 EADM_LOG(6, "start"); ··· 147 146 css_sched_sch_todo(sch, SCH_TODO_EVAL); 148 147 return; 149 148 } 150 - scm_irq_handler((struct aob *)(unsigned long)scsw->aob, error); 149 + scm_irq_handler(phys_to_virt(scsw->aob), error); 151 150 private->state = EADM_IDLE; 152 151 153 152 if (private->completion) ··· 226 225 private->state = EADM_IDLE; 227 226 private->sch = sch; 228 227 sch->isc = EADM_SCH_ISC; 229 - ret = cio_enable_subchannel(sch, (u32)(unsigned long)sch); 228 + ret = cio_enable_subchannel(sch, (u32)virt_to_phys(sch)); 230 229 if (ret) { 231 230 set_eadm_private(sch, NULL); 232 231 spin_unlock_irq(sch->lock);
+12 -11
drivers/s390/cio/fcx.c
··· 9 9 #include <linux/kernel.h> 10 10 #include <linux/types.h> 11 11 #include <linux/string.h> 12 + #include <linux/io.h> 12 13 #include <linux/errno.h> 13 14 #include <linux/err.h> 14 15 #include <linux/module.h> ··· 25 24 */ 26 25 struct tcw *tcw_get_intrg(struct tcw *tcw) 27 26 { 28 - return (struct tcw *) ((addr_t) tcw->intrg); 27 + return phys_to_virt(tcw->intrg); 29 28 } 30 29 EXPORT_SYMBOL(tcw_get_intrg); 31 30 ··· 40 39 void *tcw_get_data(struct tcw *tcw) 41 40 { 42 41 if (tcw->r) 43 - return (void *) ((addr_t) tcw->input); 42 + return phys_to_virt(tcw->input); 44 43 if (tcw->w) 45 - return (void *) ((addr_t) tcw->output); 44 + return phys_to_virt(tcw->output); 46 45 return NULL; 47 46 } 48 47 EXPORT_SYMBOL(tcw_get_data); ··· 55 54 */ 56 55 struct tccb *tcw_get_tccb(struct tcw *tcw) 57 56 { 58 - return (struct tccb *) ((addr_t) tcw->tccb); 57 + return phys_to_virt(tcw->tccb); 59 58 } 60 59 EXPORT_SYMBOL(tcw_get_tccb); 61 60 ··· 67 66 */ 68 67 struct tsb *tcw_get_tsb(struct tcw *tcw) 69 68 { 70 - return (struct tsb *) ((addr_t) tcw->tsb); 69 + return phys_to_virt(tcw->tsb); 71 70 } 72 71 EXPORT_SYMBOL(tcw_get_tsb); 73 72 ··· 190 189 */ 191 190 void tcw_set_intrg(struct tcw *tcw, struct tcw *intrg_tcw) 192 191 { 193 - tcw->intrg = (u32) ((addr_t) intrg_tcw); 192 + tcw->intrg = (u32)virt_to_phys(intrg_tcw); 194 193 } 195 194 EXPORT_SYMBOL(tcw_set_intrg); 196 195 ··· 208 207 void tcw_set_data(struct tcw *tcw, void *data, int use_tidal) 209 208 { 210 209 if (tcw->r) { 211 - tcw->input = (u64) ((addr_t) data); 210 + tcw->input = virt_to_phys(data); 212 211 if (use_tidal) 213 212 tcw->flags |= TCW_FLAGS_INPUT_TIDA; 214 213 } else if (tcw->w) { 215 - tcw->output = (u64) ((addr_t) data); 214 + tcw->output = virt_to_phys(data); 216 215 if (use_tidal) 217 216 tcw->flags |= TCW_FLAGS_OUTPUT_TIDA; 218 217 } ··· 228 227 */ 229 228 void tcw_set_tccb(struct tcw *tcw, struct tccb *tccb) 230 229 { 231 - tcw->tccb = (u64) ((addr_t) tccb); 230 + tcw->tccb = virt_to_phys(tccb); 232 231 } 233 232 EXPORT_SYMBOL(tcw_set_tccb); 234 233 ··· 241 240 */ 242 241 void tcw_set_tsb(struct tcw *tcw, struct tsb *tsb) 243 242 { 244 - tcw->tsb = (u64) ((addr_t) tsb); 243 + tcw->tsb = virt_to_phys(tsb); 245 244 } 246 245 EXPORT_SYMBOL(tcw_set_tsb); 247 246 ··· 346 345 memset(tidaw, 0, sizeof(struct tidaw)); 347 346 tidaw->flags = flags; 348 347 tidaw->count = count; 349 - tidaw->addr = (u64) ((addr_t) addr); 348 + tidaw->addr = virt_to_phys(addr); 350 349 return tidaw; 351 350 } 352 351 EXPORT_SYMBOL(tcw_add_tidaw);
+2 -1
drivers/s390/cio/itcw.c
··· 9 9 #include <linux/kernel.h> 10 10 #include <linux/types.h> 11 11 #include <linux/string.h> 12 + #include <linux/io.h> 12 13 #include <linux/errno.h> 13 14 #include <linux/err.h> 14 15 #include <linux/module.h> ··· 188 187 /* Check for 2G limit. */ 189 188 start = (addr_t) buffer; 190 189 end = start + size; 191 - if (end > (1 << 31)) 190 + if ((virt_to_phys(buffer) + size) > (1 << 31)) 192 191 return ERR_PTR(-EINVAL); 193 192 memset(buffer, 0, size); 194 193 /* ITCW. */
+2 -2
drivers/s390/cio/vfio_ccw_cp.c
··· 394 394 if (ccw_is_tic(ccw)) 395 395 return; 396 396 397 - kfree((void *)(u64)ccw->cda); 397 + kfree(phys_to_virt(ccw->cda)); 398 398 } 399 399 400 400 /** ··· 845 845 846 846 chain = list_first_entry(&cp->ccwchain_list, struct ccwchain, next); 847 847 cpa = chain->ch_ccw; 848 - orb->cmd.cpa = (__u32) __pa(cpa); 848 + orb->cmd.cpa = (__u32)virt_to_phys(cpa); 849 849 850 850 return orb; 851 851 }
+1 -1
drivers/s390/cio/vfio_ccw_fsm.c
··· 29 29 30 30 spin_lock_irqsave(sch->lock, flags); 31 31 32 - orb = cp_get_orb(&private->cp, (u32)(addr_t)sch, sch->lpm); 32 + orb = cp_get_orb(&private->cp, (u32)virt_to_phys(sch), sch->lpm); 33 33 if (!orb) { 34 34 ret = -EIO; 35 35 goto out;
+1 -2
lib/raid6/s390vx.uc
··· 13 13 14 14 #include <linux/raid/pq.h> 15 15 #include <asm/fpu/api.h> 16 - 17 - asm(".include \"asm/vx-insn.h\"\n"); 16 + #include <asm/vx-insn.h> 18 17 19 18 #define NSIZE 16 20 19