diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-05 14:13:10 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-05 14:13:10 -0500 |
| commit | 3591b19511ed88e2e82f64b7d7bf54a5f8d10363 (patch) | |
| tree | d08896f1aeb2083960bdc5e8537ab9e8d56bd43c | |
| parent | 45f5532a2f65afeda9e8a02bf1aca15c2b4c9be8 (diff) | |
| parent | fcc082f35c6d565d351b5b89bb03a82333e9ffe8 (diff) | |
Merge tag 's390-5.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky:
- A copy of Arnds compat wrapper generation series
- Pass information about the KVM guest to the host in form the control
program code and the control program version code
- Map IOV resources to support PCI physical functions on s390
- Add vector load and store alignment hints to improve performance
- Use the "jdd" constraint with gcc 9 to make jump labels working again
- Remove amode workaround for old z/VM releases from the DCSS code
- Add support for in-kernel performance measurements using the CPU
measurement counter facility
- Introduce a new PMU device cpum_cf_diag to capture counters and store
thenn as event raw data.
- Bug fixes and cleanups
* tag 's390-5.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (54 commits)
Revert "s390/cpum_cf: Add kernel message exaplanations"
s390/dasd: fix read device characteristic with CONFIG_VMAP_STACK=y
s390/suspend: fix prefix register reset in swsusp_arch_resume
s390: warn about clearing als implied facilities
s390: allow overriding facilities via command line
s390: clean up redundant facilities list setup
s390/als: remove duplicated in-place implementation of stfle
s390/cio: Use cpa range elsewhere within vfio-ccw
s390/cio: Fix vfio-ccw handling of recursive TICs
s390: vfio_ap: link the vfio_ap devices to the vfio_ap bus subsystem
s390/cpum_cf: Handle EBUSY return code from CPU counter facility reservation
s390/cpum_cf: Add kernel message exaplanations
s390/cpum_cf_diag: Add support for s390 counter facility diagnostic trace
s390/cpum_cf: add ctr_stcctm() function
s390/cpum_cf: move common functions into a separate file
s390/cpum_cf: introduce kernel_cpumcf_avail() function
s390/cpu_mf: replace stcctm5() with the stcctm() function
s390/cpu_mf: add store cpu counter multiple instruction support
s390/cpum_cf: Add minimal in-kernel interface for counter measurements
s390/cpum_cf: introduce kernel_cpumcf_alert() to obtain measurement alerts
...
71 files changed, 1846 insertions, 1080 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index ed554b09eb3f..b6e3d0653002 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
| @@ -75,6 +75,7 @@ config S390 | |||
| 75 | select ARCH_HAS_SET_MEMORY | 75 | select ARCH_HAS_SET_MEMORY |
| 76 | select ARCH_HAS_STRICT_KERNEL_RWX | 76 | select ARCH_HAS_STRICT_KERNEL_RWX |
| 77 | select ARCH_HAS_STRICT_MODULE_RWX | 77 | select ARCH_HAS_STRICT_MODULE_RWX |
| 78 | select ARCH_HAS_SYSCALL_WRAPPER | ||
| 78 | select ARCH_HAS_UBSAN_SANITIZE_ALL | 79 | select ARCH_HAS_UBSAN_SANITIZE_ALL |
| 79 | select ARCH_HAVE_NMI_SAFE_CMPXCHG | 80 | select ARCH_HAVE_NMI_SAFE_CMPXCHG |
| 80 | select ARCH_INLINE_READ_LOCK | 81 | select ARCH_INLINE_READ_LOCK |
| @@ -379,6 +380,7 @@ config COMPAT | |||
| 379 | select COMPAT_BINFMT_ELF if BINFMT_ELF | 380 | select COMPAT_BINFMT_ELF if BINFMT_ELF |
| 380 | select ARCH_WANT_OLD_COMPAT_IPC | 381 | select ARCH_WANT_OLD_COMPAT_IPC |
| 381 | select COMPAT_OLD_SIGACTION | 382 | select COMPAT_OLD_SIGACTION |
| 383 | select HAVE_UID16 | ||
| 382 | depends on MULTIUSER | 384 | depends on MULTIUSER |
| 383 | help | 385 | help |
| 384 | Select this option if you want to enable your system kernel to | 386 | Select this option if you want to enable your system kernel to |
diff --git a/arch/s390/boot/als.c b/arch/s390/boot/als.c index d592e0d90d9f..f902215e9cd9 100644 --- a/arch/s390/boot/als.c +++ b/arch/s390/boot/als.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <asm/facility.h> | 7 | #include <asm/facility.h> |
| 8 | #include <asm/lowcore.h> | 8 | #include <asm/lowcore.h> |
| 9 | #include <asm/sclp.h> | 9 | #include <asm/sclp.h> |
| 10 | #include "boot.h" | ||
| 10 | 11 | ||
| 11 | /* | 12 | /* |
| 12 | * The code within this file will be called very early. It may _not_ | 13 | * The code within this file will be called very early. It may _not_ |
| @@ -58,7 +59,7 @@ static void u16_to_decimal(char *str, u16 val) | |||
| 58 | *str = '\0'; | 59 | *str = '\0'; |
| 59 | } | 60 | } |
| 60 | 61 | ||
| 61 | static void print_missing_facilities(void) | 62 | void print_missing_facilities(void) |
| 62 | { | 63 | { |
| 63 | static char als_str[80] = "Missing facilities: "; | 64 | static char als_str[80] = "Missing facilities: "; |
| 64 | unsigned long val; | 65 | unsigned long val; |
| @@ -90,7 +91,6 @@ static void print_missing_facilities(void) | |||
| 90 | } | 91 | } |
| 91 | strcat(als_str, "\n"); | 92 | strcat(als_str, "\n"); |
| 92 | sclp_early_printk(als_str); | 93 | sclp_early_printk(als_str); |
| 93 | sclp_early_printk("See Principles of Operations for facility bits\n"); | ||
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | static void facility_mismatch(void) | 96 | static void facility_mismatch(void) |
| @@ -98,6 +98,7 @@ static void facility_mismatch(void) | |||
| 98 | sclp_early_printk("The Linux kernel requires more recent processor hardware\n"); | 98 | sclp_early_printk("The Linux kernel requires more recent processor hardware\n"); |
| 99 | print_machine_type(); | 99 | print_machine_type(); |
| 100 | print_missing_facilities(); | 100 | print_missing_facilities(); |
| 101 | sclp_early_printk("See Principles of Operations for facility bits\n"); | ||
| 101 | disabled_wait(0x8badcccc); | 102 | disabled_wait(0x8badcccc); |
| 102 | } | 103 | } |
| 103 | 104 | ||
| @@ -105,20 +106,7 @@ void verify_facilities(void) | |||
| 105 | { | 106 | { |
| 106 | int i; | 107 | int i; |
| 107 | 108 | ||
| 108 | for (i = 0; i < ARRAY_SIZE(S390_lowcore.stfle_fac_list); i++) | 109 | __stfle(S390_lowcore.stfle_fac_list, ARRAY_SIZE(S390_lowcore.stfle_fac_list)); |
| 109 | S390_lowcore.stfle_fac_list[i] = 0; | ||
| 110 | asm volatile( | ||
| 111 | " stfl 0(0)\n" | ||
| 112 | : "=m" (S390_lowcore.stfl_fac_list)); | ||
| 113 | S390_lowcore.stfle_fac_list[0] = (u64)S390_lowcore.stfl_fac_list << 32; | ||
| 114 | if (S390_lowcore.stfl_fac_list & 0x01000000) { | ||
| 115 | register unsigned long reg0 asm("0") = ARRAY_SIZE(als) - 1; | ||
| 116 | |||
| 117 | asm volatile(".insn s,0xb2b00000,0(%1)" /* stfle */ | ||
| 118 | : "+d" (reg0) | ||
| 119 | : "a" (&S390_lowcore.stfle_fac_list) | ||
| 120 | : "memory", "cc"); | ||
| 121 | } | ||
| 122 | for (i = 0; i < ARRAY_SIZE(als); i++) { | 110 | for (i = 0; i < ARRAY_SIZE(als); i++) { |
| 123 | if ((S390_lowcore.stfle_fac_list[i] & als[i]) != als[i]) | 111 | if ((S390_lowcore.stfle_fac_list[i] & als[i]) != als[i]) |
| 124 | facility_mismatch(); | 112 | facility_mismatch(); |
diff --git a/arch/s390/boot/boot.h b/arch/s390/boot/boot.h index fc41e2277ea8..82bc06346e05 100644 --- a/arch/s390/boot/boot.h +++ b/arch/s390/boot/boot.h | |||
| @@ -6,6 +6,8 @@ void startup_kernel(void); | |||
| 6 | void detect_memory(void); | 6 | void detect_memory(void); |
| 7 | void store_ipl_parmblock(void); | 7 | void store_ipl_parmblock(void); |
| 8 | void setup_boot_command_line(void); | 8 | void setup_boot_command_line(void); |
| 9 | void parse_boot_command_line(void); | ||
| 9 | void setup_memory_end(void); | 10 | void setup_memory_end(void); |
| 11 | void print_missing_facilities(void); | ||
| 10 | 12 | ||
| 11 | #endif /* BOOT_BOOT_H */ | 13 | #endif /* BOOT_BOOT_H */ |
diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c index 9dab596be98e..36beb56de021 100644 --- a/arch/s390/boot/ipl_parm.c +++ b/arch/s390/boot/ipl_parm.c | |||
| @@ -1,10 +1,12 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | 1 | // SPDX-License-Identifier: GPL-2.0 |
| 2 | #include <linux/kernel.h> | ||
| 2 | #include <linux/init.h> | 3 | #include <linux/init.h> |
| 3 | #include <linux/ctype.h> | 4 | #include <linux/ctype.h> |
| 4 | #include <asm/ebcdic.h> | 5 | #include <asm/ebcdic.h> |
| 5 | #include <asm/sclp.h> | 6 | #include <asm/sclp.h> |
| 6 | #include <asm/sections.h> | 7 | #include <asm/sections.h> |
| 7 | #include <asm/boot_data.h> | 8 | #include <asm/boot_data.h> |
| 9 | #include <asm/facility.h> | ||
| 8 | #include "boot.h" | 10 | #include "boot.h" |
| 9 | 11 | ||
| 10 | char __bootdata(early_command_line)[COMMAND_LINE_SIZE]; | 12 | char __bootdata(early_command_line)[COMMAND_LINE_SIZE]; |
| @@ -143,8 +145,66 @@ void setup_boot_command_line(void) | |||
| 143 | append_ipl_block_parm(); | 145 | append_ipl_block_parm(); |
| 144 | } | 146 | } |
| 145 | 147 | ||
| 148 | static void modify_facility(unsigned long nr, bool clear) | ||
| 149 | { | ||
| 150 | if (clear) | ||
| 151 | __clear_facility(nr, S390_lowcore.stfle_fac_list); | ||
| 152 | else | ||
| 153 | __set_facility(nr, S390_lowcore.stfle_fac_list); | ||
| 154 | } | ||
| 155 | |||
| 156 | static void check_cleared_facilities(void) | ||
| 157 | { | ||
| 158 | unsigned long als[] = { FACILITIES_ALS }; | ||
| 159 | int i; | ||
| 160 | |||
| 161 | for (i = 0; i < ARRAY_SIZE(als); i++) { | ||
| 162 | if ((S390_lowcore.stfle_fac_list[i] & als[i]) != als[i]) { | ||
| 163 | sclp_early_printk("Warning: The Linux kernel requires facilities cleared via command line option\n"); | ||
| 164 | print_missing_facilities(); | ||
| 165 | break; | ||
| 166 | } | ||
| 167 | } | ||
| 168 | } | ||
| 169 | |||
| 170 | static void modify_fac_list(char *str) | ||
| 171 | { | ||
| 172 | unsigned long val, endval; | ||
| 173 | char *endp; | ||
| 174 | bool clear; | ||
| 175 | |||
| 176 | while (*str) { | ||
| 177 | clear = false; | ||
| 178 | if (*str == '!') { | ||
| 179 | clear = true; | ||
| 180 | str++; | ||
| 181 | } | ||
| 182 | val = simple_strtoull(str, &endp, 0); | ||
| 183 | if (str == endp) | ||
| 184 | break; | ||
| 185 | str = endp; | ||
| 186 | if (*str == '-') { | ||
| 187 | str++; | ||
| 188 | endval = simple_strtoull(str, &endp, 0); | ||
| 189 | if (str == endp) | ||
| 190 | break; | ||
| 191 | str = endp; | ||
| 192 | while (val <= endval) { | ||
| 193 | modify_facility(val, clear); | ||
| 194 | val++; | ||
| 195 | } | ||
| 196 | } else { | ||
| 197 | modify_facility(val, clear); | ||
| 198 | } | ||
| 199 | if (*str != ',') | ||
| 200 | break; | ||
| 201 | str++; | ||
| 202 | } | ||
| 203 | check_cleared_facilities(); | ||
| 204 | } | ||
| 205 | |||
| 146 | static char command_line_buf[COMMAND_LINE_SIZE] __section(.data); | 206 | static char command_line_buf[COMMAND_LINE_SIZE] __section(.data); |
| 147 | static void parse_mem_opt(void) | 207 | void parse_boot_command_line(void) |
| 148 | { | 208 | { |
| 149 | char *param, *val; | 209 | char *param, *val; |
| 150 | bool enabled; | 210 | bool enabled; |
| @@ -165,12 +225,14 @@ static void parse_mem_opt(void) | |||
| 165 | if (!rc && !enabled) | 225 | if (!rc && !enabled) |
| 166 | noexec_disabled = 1; | 226 | noexec_disabled = 1; |
| 167 | } | 227 | } |
| 228 | |||
| 229 | if (!strcmp(param, "facilities")) | ||
| 230 | modify_fac_list(val); | ||
| 168 | } | 231 | } |
| 169 | } | 232 | } |
| 170 | 233 | ||
| 171 | void setup_memory_end(void) | 234 | void setup_memory_end(void) |
| 172 | { | 235 | { |
| 173 | parse_mem_opt(); | ||
| 174 | #ifdef CONFIG_CRASH_DUMP | 236 | #ifdef CONFIG_CRASH_DUMP |
| 175 | if (!OLDMEM_BASE && early_ipl_block_valid && | 237 | if (!OLDMEM_BASE && early_ipl_block_valid && |
| 176 | early_ipl_block.hdr.pbt == DIAG308_IPL_TYPE_FCP && | 238 | early_ipl_block.hdr.pbt == DIAG308_IPL_TYPE_FCP && |
diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c index 4d441317cdeb..bdfc5549a299 100644 --- a/arch/s390/boot/startup.c +++ b/arch/s390/boot/startup.c | |||
| @@ -53,6 +53,7 @@ void startup_kernel(void) | |||
| 53 | sclp_early_read_info(); | 53 | sclp_early_read_info(); |
| 54 | store_ipl_parmblock(); | 54 | store_ipl_parmblock(); |
| 55 | setup_boot_command_line(); | 55 | setup_boot_command_line(); |
| 56 | parse_boot_command_line(); | ||
| 56 | setup_memory_end(); | 57 | setup_memory_end(); |
| 57 | detect_memory(); | 58 | detect_memory(); |
| 58 | if (!IS_ENABLED(CONFIG_KERNEL_UNCOMPRESSED)) { | 59 | if (!IS_ENABLED(CONFIG_KERNEL_UNCOMPRESSED)) { |
diff --git a/arch/s390/boot/string.c b/arch/s390/boot/string.c index 25aca07898ba..b11e8108773a 100644 --- a/arch/s390/boot/string.c +++ b/arch/s390/boot/string.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #include <linux/ctype.h> | 2 | #include <linux/ctype.h> |
| 3 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
| 4 | #include <linux/errno.h> | 4 | #include <linux/errno.h> |
| 5 | #undef CONFIG_KASAN | ||
| 5 | #include "../lib/string.c" | 6 | #include "../lib/string.c" |
| 6 | 7 | ||
| 7 | int strncmp(const char *cs, const char *ct, size_t count) | 8 | int strncmp(const char *cs, const char *ct, size_t count) |
diff --git a/arch/s390/hypfs/hypfs.h b/arch/s390/hypfs/hypfs.h index 52348e0a812e..05f3f9aee5fc 100644 --- a/arch/s390/hypfs/hypfs.h +++ b/arch/s390/hypfs/hypfs.h | |||
| @@ -43,7 +43,7 @@ int hypfs_diag0c_init(void); | |||
| 43 | void hypfs_diag0c_exit(void); | 43 | void hypfs_diag0c_exit(void); |
| 44 | 44 | ||
| 45 | /* Set Partition-Resource Parameter */ | 45 | /* Set Partition-Resource Parameter */ |
| 46 | int hypfs_sprp_init(void); | 46 | void hypfs_sprp_init(void); |
| 47 | void hypfs_sprp_exit(void); | 47 | void hypfs_sprp_exit(void); |
| 48 | 48 | ||
| 49 | /* debugfs interface */ | 49 | /* debugfs interface */ |
| @@ -69,9 +69,9 @@ struct hypfs_dbfs_file { | |||
| 69 | struct dentry *dentry; | 69 | struct dentry *dentry; |
| 70 | }; | 70 | }; |
| 71 | 71 | ||
| 72 | extern int hypfs_dbfs_init(void); | 72 | extern void hypfs_dbfs_init(void); |
| 73 | extern void hypfs_dbfs_exit(void); | 73 | extern void hypfs_dbfs_exit(void); |
| 74 | extern int hypfs_dbfs_create_file(struct hypfs_dbfs_file *df); | 74 | extern void hypfs_dbfs_create_file(struct hypfs_dbfs_file *df); |
| 75 | extern void hypfs_dbfs_remove_file(struct hypfs_dbfs_file *df); | 75 | extern void hypfs_dbfs_remove_file(struct hypfs_dbfs_file *df); |
| 76 | 76 | ||
| 77 | #endif /* _HYPFS_H_ */ | 77 | #endif /* _HYPFS_H_ */ |
diff --git a/arch/s390/hypfs/hypfs_dbfs.c b/arch/s390/hypfs/hypfs_dbfs.c index b9bdf5c1918e..f4c7dbfaf8ee 100644 --- a/arch/s390/hypfs/hypfs_dbfs.c +++ b/arch/s390/hypfs/hypfs_dbfs.c | |||
| @@ -78,14 +78,11 @@ static const struct file_operations dbfs_ops = { | |||
| 78 | .unlocked_ioctl = dbfs_ioctl, | 78 | .unlocked_ioctl = dbfs_ioctl, |
| 79 | }; | 79 | }; |
| 80 | 80 | ||
| 81 | int hypfs_dbfs_create_file(struct hypfs_dbfs_file *df) | 81 | void hypfs_dbfs_create_file(struct hypfs_dbfs_file *df) |
| 82 | { | 82 | { |
| 83 | df->dentry = debugfs_create_file(df->name, 0400, dbfs_dir, df, | 83 | df->dentry = debugfs_create_file(df->name, 0400, dbfs_dir, df, |
| 84 | &dbfs_ops); | 84 | &dbfs_ops); |
| 85 | if (IS_ERR(df->dentry)) | ||
| 86 | return PTR_ERR(df->dentry); | ||
| 87 | mutex_init(&df->lock); | 85 | mutex_init(&df->lock); |
| 88 | return 0; | ||
| 89 | } | 86 | } |
| 90 | 87 | ||
| 91 | void hypfs_dbfs_remove_file(struct hypfs_dbfs_file *df) | 88 | void hypfs_dbfs_remove_file(struct hypfs_dbfs_file *df) |
| @@ -93,10 +90,9 @@ void hypfs_dbfs_remove_file(struct hypfs_dbfs_file *df) | |||
| 93 | debugfs_remove(df->dentry); | 90 | debugfs_remove(df->dentry); |
| 94 | } | 91 | } |
| 95 | 92 | ||
| 96 | int hypfs_dbfs_init(void) | 93 | void hypfs_dbfs_init(void) |
| 97 | { | 94 | { |
| 98 | dbfs_dir = debugfs_create_dir("s390_hypfs", NULL); | 95 | dbfs_dir = debugfs_create_dir("s390_hypfs", NULL); |
| 99 | return PTR_ERR_OR_ZERO(dbfs_dir); | ||
| 100 | } | 96 | } |
| 101 | 97 | ||
| 102 | void hypfs_dbfs_exit(void) | 98 | void hypfs_dbfs_exit(void) |
diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c index 3452e18bb1ca..f0bc4dc3e9bf 100644 --- a/arch/s390/hypfs/hypfs_diag.c +++ b/arch/s390/hypfs/hypfs_diag.c | |||
| @@ -440,11 +440,10 @@ __init int hypfs_diag_init(void) | |||
| 440 | pr_err("The hardware system does not support hypfs\n"); | 440 | pr_err("The hardware system does not support hypfs\n"); |
| 441 | return -ENODATA; | 441 | return -ENODATA; |
| 442 | } | 442 | } |
| 443 | if (diag204_info_type == DIAG204_INFO_EXT) { | 443 | |
| 444 | rc = hypfs_dbfs_create_file(&dbfs_file_d204); | 444 | if (diag204_info_type == DIAG204_INFO_EXT) |
| 445 | if (rc) | 445 | hypfs_dbfs_create_file(&dbfs_file_d204); |
| 446 | return rc; | 446 | |
| 447 | } | ||
| 448 | if (MACHINE_IS_LPAR) { | 447 | if (MACHINE_IS_LPAR) { |
| 449 | rc = diag224_get_name_table(); | 448 | rc = diag224_get_name_table(); |
| 450 | if (rc) { | 449 | if (rc) { |
diff --git a/arch/s390/hypfs/hypfs_diag0c.c b/arch/s390/hypfs/hypfs_diag0c.c index cebf05150cc1..72e3140fafb5 100644 --- a/arch/s390/hypfs/hypfs_diag0c.c +++ b/arch/s390/hypfs/hypfs_diag0c.c | |||
| @@ -54,8 +54,7 @@ static void *diag0c_store(unsigned int *count) | |||
| 54 | if (!cpu_vec) | 54 | if (!cpu_vec) |
| 55 | goto fail_put_online_cpus; | 55 | goto fail_put_online_cpus; |
| 56 | /* Note: Diag 0c needs 8 byte alignment and real storage */ | 56 | /* Note: Diag 0c needs 8 byte alignment and real storage */ |
| 57 | diag0c_data = kzalloc(sizeof(struct hypfs_diag0c_hdr) + | 57 | diag0c_data = kzalloc(struct_size(diag0c_data, entry, cpu_count), |
| 58 | cpu_count * sizeof(struct hypfs_diag0c_entry), | ||
| 59 | GFP_KERNEL | GFP_DMA); | 58 | GFP_KERNEL | GFP_DMA); |
| 60 | if (!diag0c_data) | 59 | if (!diag0c_data) |
| 61 | goto fail_kfree_cpu_vec; | 60 | goto fail_kfree_cpu_vec; |
| @@ -125,7 +124,8 @@ int __init hypfs_diag0c_init(void) | |||
| 125 | { | 124 | { |
| 126 | if (!MACHINE_IS_VM) | 125 | if (!MACHINE_IS_VM) |
| 127 | return 0; | 126 | return 0; |
| 128 | return hypfs_dbfs_create_file(&dbfs_file_0c); | 127 | hypfs_dbfs_create_file(&dbfs_file_0c); |
| 128 | return 0; | ||
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | /* | 131 | /* |
diff --git a/arch/s390/hypfs/hypfs_sprp.c b/arch/s390/hypfs/hypfs_sprp.c index 601b70786dc8..7d9fb496d155 100644 --- a/arch/s390/hypfs/hypfs_sprp.c +++ b/arch/s390/hypfs/hypfs_sprp.c | |||
| @@ -137,11 +137,11 @@ static struct hypfs_dbfs_file hypfs_sprp_file = { | |||
| 137 | .unlocked_ioctl = hypfs_sprp_ioctl, | 137 | .unlocked_ioctl = hypfs_sprp_ioctl, |
| 138 | }; | 138 | }; |
| 139 | 139 | ||
| 140 | int hypfs_sprp_init(void) | 140 | void hypfs_sprp_init(void) |
| 141 | { | 141 | { |
| 142 | if (!sclp.has_sprp) | 142 | if (!sclp.has_sprp) |
| 143 | return 0; | 143 | return; |
| 144 | return hypfs_dbfs_create_file(&hypfs_sprp_file); | 144 | hypfs_dbfs_create_file(&hypfs_sprp_file); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | void hypfs_sprp_exit(void) | 147 | void hypfs_sprp_exit(void) |
diff --git a/arch/s390/hypfs/hypfs_vm.c b/arch/s390/hypfs/hypfs_vm.c index c4b7b681e055..42f2375c203e 100644 --- a/arch/s390/hypfs/hypfs_vm.c +++ b/arch/s390/hypfs/hypfs_vm.c | |||
| @@ -279,7 +279,8 @@ int hypfs_vm_init(void) | |||
| 279 | guest_query = local_guest; | 279 | guest_query = local_guest; |
| 280 | else | 280 | else |
| 281 | return -EACCES; | 281 | return -EACCES; |
| 282 | return hypfs_dbfs_create_file(&dbfs_file_2fc); | 282 | hypfs_dbfs_create_file(&dbfs_file_2fc); |
| 283 | return 0; | ||
| 283 | } | 284 | } |
| 284 | 285 | ||
| 285 | void hypfs_vm_exit(void) | 286 | void hypfs_vm_exit(void) |
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index c681329fdeec..ccad1398abd4 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c | |||
| @@ -456,9 +456,8 @@ static int __init hypfs_init(void) | |||
| 456 | { | 456 | { |
| 457 | int rc; | 457 | int rc; |
| 458 | 458 | ||
| 459 | rc = hypfs_dbfs_init(); | 459 | hypfs_dbfs_init(); |
| 460 | if (rc) | 460 | |
| 461 | return rc; | ||
| 462 | if (hypfs_diag_init()) { | 461 | if (hypfs_diag_init()) { |
| 463 | rc = -ENODATA; | 462 | rc = -ENODATA; |
| 464 | goto fail_dbfs_exit; | 463 | goto fail_dbfs_exit; |
| @@ -467,10 +466,7 @@ static int __init hypfs_init(void) | |||
| 467 | rc = -ENODATA; | 466 | rc = -ENODATA; |
| 468 | goto fail_hypfs_diag_exit; | 467 | goto fail_hypfs_diag_exit; |
| 469 | } | 468 | } |
| 470 | if (hypfs_sprp_init()) { | 469 | hypfs_sprp_init(); |
| 471 | rc = -ENODATA; | ||
| 472 | goto fail_hypfs_vm_exit; | ||
| 473 | } | ||
| 474 | if (hypfs_diag0c_init()) { | 470 | if (hypfs_diag0c_init()) { |
| 475 | rc = -ENODATA; | 471 | rc = -ENODATA; |
| 476 | goto fail_hypfs_sprp_exit; | 472 | goto fail_hypfs_sprp_exit; |
| @@ -489,7 +485,6 @@ fail_hypfs_diag0c_exit: | |||
| 489 | hypfs_diag0c_exit(); | 485 | hypfs_diag0c_exit(); |
| 490 | fail_hypfs_sprp_exit: | 486 | fail_hypfs_sprp_exit: |
| 491 | hypfs_sprp_exit(); | 487 | hypfs_sprp_exit(); |
| 492 | fail_hypfs_vm_exit: | ||
| 493 | hypfs_vm_exit(); | 488 | hypfs_vm_exit(); |
| 494 | fail_hypfs_diag_exit: | 489 | fail_hypfs_diag_exit: |
| 495 | hypfs_diag_exit(); | 490 | hypfs_diag_exit(); |
diff --git a/arch/s390/include/asm/cpu_mcf.h b/arch/s390/include/asm/cpu_mcf.h new file mode 100644 index 000000000000..649b9fc60685 --- /dev/null +++ b/arch/s390/include/asm/cpu_mcf.h | |||
| @@ -0,0 +1,126 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /* | ||
| 3 | * Counter facility support definitions for the Linux perf | ||
| 4 | * | ||
| 5 | * Copyright IBM Corp. 2019 | ||
| 6 | * Author(s): Hendrik Brueckner <brueckner@linux.ibm.com> | ||
| 7 | */ | ||
| 8 | #ifndef _ASM_S390_CPU_MCF_H | ||
| 9 | #define _ASM_S390_CPU_MCF_H | ||
| 10 | |||
| 11 | #include <linux/perf_event.h> | ||
| 12 | #include <asm/cpu_mf.h> | ||
| 13 | |||
| 14 | enum cpumf_ctr_set { | ||
| 15 | CPUMF_CTR_SET_BASIC = 0, /* Basic Counter Set */ | ||
| 16 | CPUMF_CTR_SET_USER = 1, /* Problem-State Counter Set */ | ||
| 17 | CPUMF_CTR_SET_CRYPTO = 2, /* Crypto-Activity Counter Set */ | ||
| 18 | CPUMF_CTR_SET_EXT = 3, /* Extended Counter Set */ | ||
| 19 | CPUMF_CTR_SET_MT_DIAG = 4, /* MT-diagnostic Counter Set */ | ||
| 20 | |||
| 21 | /* Maximum number of counter sets */ | ||
| 22 | CPUMF_CTR_SET_MAX, | ||
| 23 | }; | ||
| 24 | |||
| 25 | #define CPUMF_LCCTL_ENABLE_SHIFT 16 | ||
| 26 | #define CPUMF_LCCTL_ACTCTL_SHIFT 0 | ||
| 27 | static const u64 cpumf_ctr_ctl[CPUMF_CTR_SET_MAX] = { | ||
| 28 | [CPUMF_CTR_SET_BASIC] = 0x02, | ||
| 29 | [CPUMF_CTR_SET_USER] = 0x04, | ||
| 30 | [CPUMF_CTR_SET_CRYPTO] = 0x08, | ||
| 31 | [CPUMF_CTR_SET_EXT] = 0x01, | ||
| 32 | [CPUMF_CTR_SET_MT_DIAG] = 0x20, | ||
| 33 | }; | ||
| 34 | |||
| 35 | static inline void ctr_set_enable(u64 *state, int ctr_set) | ||
| 36 | { | ||
| 37 | *state |= cpumf_ctr_ctl[ctr_set] << CPUMF_LCCTL_ENABLE_SHIFT; | ||
| 38 | } | ||
| 39 | static inline void ctr_set_disable(u64 *state, int ctr_set) | ||
| 40 | { | ||
| 41 | *state &= ~(cpumf_ctr_ctl[ctr_set] << CPUMF_LCCTL_ENABLE_SHIFT); | ||
| 42 | } | ||
| 43 | static inline void ctr_set_start(u64 *state, int ctr_set) | ||
| 44 | { | ||
| 45 | *state |= cpumf_ctr_ctl[ctr_set] << CPUMF_LCCTL_ACTCTL_SHIFT; | ||
| 46 | } | ||
| 47 | static inline void ctr_set_stop(u64 *state, int ctr_set) | ||
| 48 | { | ||
| 49 | *state &= ~(cpumf_ctr_ctl[ctr_set] << CPUMF_LCCTL_ACTCTL_SHIFT); | ||
| 50 | } | ||
| 51 | |||
| 52 | static inline void ctr_set_multiple_enable(u64 *state, u64 ctrsets) | ||
| 53 | { | ||
| 54 | *state |= ctrsets << CPUMF_LCCTL_ENABLE_SHIFT; | ||
| 55 | } | ||
| 56 | |||
| 57 | static inline void ctr_set_multiple_disable(u64 *state, u64 ctrsets) | ||
| 58 | { | ||
| 59 | *state &= ~(ctrsets << CPUMF_LCCTL_ENABLE_SHIFT); | ||
| 60 | } | ||
| 61 | |||
| 62 | static inline void ctr_set_multiple_start(u64 *state, u64 ctrsets) | ||
| 63 | { | ||
| 64 | *state |= ctrsets << CPUMF_LCCTL_ACTCTL_SHIFT; | ||
| 65 | } | ||
| 66 | |||
| 67 | static inline void ctr_set_multiple_stop(u64 *state, u64 ctrsets) | ||
| 68 | { | ||
| 69 | *state &= ~(ctrsets << CPUMF_LCCTL_ACTCTL_SHIFT); | ||
| 70 | } | ||
| 71 | |||
| 72 | static inline int ctr_stcctm(enum cpumf_ctr_set set, u64 range, u64 *dest) | ||
| 73 | { | ||
| 74 | switch (set) { | ||
| 75 | case CPUMF_CTR_SET_BASIC: | ||
| 76 | return stcctm(BASIC, range, dest); | ||
| 77 | case CPUMF_CTR_SET_USER: | ||
| 78 | return stcctm(PROBLEM_STATE, range, dest); | ||
| 79 | case CPUMF_CTR_SET_CRYPTO: | ||
| 80 | return stcctm(CRYPTO_ACTIVITY, range, dest); | ||
| 81 | case CPUMF_CTR_SET_EXT: | ||
| 82 | return stcctm(EXTENDED, range, dest); | ||
| 83 | case CPUMF_CTR_SET_MT_DIAG: | ||
| 84 | return stcctm(MT_DIAG_CLEARING, range, dest); | ||
| 85 | case CPUMF_CTR_SET_MAX: | ||
| 86 | return 3; | ||
| 87 | } | ||
| 88 | return 3; | ||
| 89 | } | ||
| 90 | |||
| 91 | struct cpu_cf_events { | ||
| 92 | struct cpumf_ctr_info info; | ||
| 93 | atomic_t ctr_set[CPUMF_CTR_SET_MAX]; | ||
| 94 | atomic64_t alert; | ||
| 95 | u64 state, tx_state; | ||
| 96 | unsigned int flags; | ||
| 97 | unsigned int txn_flags; | ||
| 98 | }; | ||
| 99 | DECLARE_PER_CPU(struct cpu_cf_events, cpu_cf_events); | ||
| 100 | |||
| 101 | bool kernel_cpumcf_avail(void); | ||
| 102 | int __kernel_cpumcf_begin(void); | ||
| 103 | unsigned long kernel_cpumcf_alert(int clear); | ||
| 104 | void __kernel_cpumcf_end(void); | ||
| 105 | |||
| 106 | static inline int kernel_cpumcf_begin(void) | ||
| 107 | { | ||
| 108 | if (!cpum_cf_avail()) | ||
| 109 | return -ENODEV; | ||
| 110 | |||
| 111 | preempt_disable(); | ||
| 112 | return __kernel_cpumcf_begin(); | ||
| 113 | } | ||
| 114 | static inline void kernel_cpumcf_end(void) | ||
| 115 | { | ||
| 116 | __kernel_cpumcf_end(); | ||
| 117 | preempt_enable(); | ||
| 118 | } | ||
| 119 | |||
| 120 | /* Return true if store counter set multiple instruction is available */ | ||
| 121 | static inline int stccm_avail(void) | ||
| 122 | { | ||
| 123 | return test_facility(142); | ||
| 124 | } | ||
| 125 | |||
| 126 | #endif /* _ASM_S390_CPU_MCF_H */ | ||
diff --git a/arch/s390/include/asm/cpu_mf-insn.h b/arch/s390/include/asm/cpu_mf-insn.h new file mode 100644 index 000000000000..a68b362e0964 --- /dev/null +++ b/arch/s390/include/asm/cpu_mf-insn.h | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /* | ||
| 3 | * Support for CPU-MF instructions | ||
| 4 | * | ||
| 5 | * Copyright IBM Corp. 2019 | ||
| 6 | * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com> | ||
| 7 | */ | ||
| 8 | #ifndef _ASM_S390_CPU_MF_INSN_H | ||
| 9 | #define _ASM_S390_CPU_MF_INSN_H | ||
| 10 | |||
| 11 | #ifdef __ASSEMBLY__ | ||
| 12 | |||
| 13 | /* Macro to generate the STCCTM instruction with a customized | ||
| 14 | * M3 field designating the counter set. | ||
| 15 | */ | ||
| 16 | .macro STCCTM r1 m3 db2 | ||
| 17 | .insn rsy,0xeb0000000017,\r1,\m3 & 0xf,\db2 | ||
| 18 | .endm | ||
| 19 | |||
| 20 | #endif /* __ASSEMBLY__ */ | ||
| 21 | |||
| 22 | #endif | ||
diff --git a/arch/s390/include/asm/cpu_mf.h b/arch/s390/include/asm/cpu_mf.h index bf2cbff926ef..ae3e3221d4b5 100644 --- a/arch/s390/include/asm/cpu_mf.h +++ b/arch/s390/include/asm/cpu_mf.h | |||
| @@ -12,6 +12,8 @@ | |||
| 12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
| 13 | #include <asm/facility.h> | 13 | #include <asm/facility.h> |
| 14 | 14 | ||
| 15 | asm(".include \"asm/cpu_mf-insn.h\"\n"); | ||
| 16 | |||
| 15 | #define CPU_MF_INT_SF_IAE (1 << 31) /* invalid entry address */ | 17 | #define CPU_MF_INT_SF_IAE (1 << 31) /* invalid entry address */ |
| 16 | #define CPU_MF_INT_SF_ISE (1 << 30) /* incorrect SDBT entry */ | 18 | #define CPU_MF_INT_SF_ISE (1 << 30) /* incorrect SDBT entry */ |
| 17 | #define CPU_MF_INT_SF_PRA (1 << 29) /* program request alert */ | 19 | #define CPU_MF_INT_SF_PRA (1 << 29) /* program request alert */ |
| @@ -209,17 +211,25 @@ static inline int ecctr(u64 ctr, u64 *val) | |||
| 209 | return cc; | 211 | return cc; |
| 210 | } | 212 | } |
| 211 | 213 | ||
| 212 | /* Store CPU counter multiple for the MT utilization counter set */ | 214 | /* Store CPU counter multiple for a particular counter set */ |
| 213 | static inline int stcctm5(u64 num, u64 *val) | 215 | enum stcctm_ctr_set { |
| 216 | EXTENDED = 0, | ||
| 217 | BASIC = 1, | ||
| 218 | PROBLEM_STATE = 2, | ||
| 219 | CRYPTO_ACTIVITY = 3, | ||
| 220 | MT_DIAG = 5, | ||
| 221 | MT_DIAG_CLEARING = 9, /* clears loss-of-MT-ctr-data alert */ | ||
| 222 | }; | ||
| 223 | static inline int stcctm(enum stcctm_ctr_set set, u64 range, u64 *dest) | ||
| 214 | { | 224 | { |
| 215 | int cc; | 225 | int cc; |
| 216 | 226 | ||
| 217 | asm volatile ( | 227 | asm volatile ( |
| 218 | " .insn rsy,0xeb0000000017,%2,5,%1\n" | 228 | " STCCTM %2,%3,%1\n" |
| 219 | " ipm %0\n" | 229 | " ipm %0\n" |
| 220 | " srl %0,28\n" | 230 | " srl %0,28\n" |
| 221 | : "=d" (cc) | 231 | : "=d" (cc) |
| 222 | : "Q" (*val), "d" (num) | 232 | : "Q" (*dest), "d" (range), "i" (set) |
| 223 | : "cc", "memory"); | 233 | : "cc", "memory"); |
| 224 | return cc; | 234 | return cc; |
| 225 | } | 235 | } |
diff --git a/arch/s390/include/asm/diag.h b/arch/s390/include/asm/diag.h index cdbaad50c7c7..19562be22b7e 100644 --- a/arch/s390/include/asm/diag.h +++ b/arch/s390/include/asm/diag.h | |||
| @@ -32,6 +32,7 @@ enum diag_stat_enum { | |||
| 32 | DIAG_STAT_X2FC, | 32 | DIAG_STAT_X2FC, |
| 33 | DIAG_STAT_X304, | 33 | DIAG_STAT_X304, |
| 34 | DIAG_STAT_X308, | 34 | DIAG_STAT_X308, |
| 35 | DIAG_STAT_X318, | ||
| 35 | DIAG_STAT_X500, | 36 | DIAG_STAT_X500, |
| 36 | NR_DIAG_STAT | 37 | NR_DIAG_STAT |
| 37 | }; | 38 | }; |
| @@ -293,6 +294,17 @@ struct diag26c_mac_resp { | |||
| 293 | u8 res[2]; | 294 | u8 res[2]; |
| 294 | } __aligned(8); | 295 | } __aligned(8); |
| 295 | 296 | ||
| 297 | #define CPNC_LINUX 0x4 | ||
| 298 | union diag318_info { | ||
| 299 | unsigned long val; | ||
| 300 | struct { | ||
| 301 | unsigned int cpnc : 8; | ||
| 302 | unsigned int cpvc_linux : 24; | ||
| 303 | unsigned char cpvc_distro[3]; | ||
| 304 | unsigned char zero; | ||
| 305 | }; | ||
| 306 | }; | ||
| 307 | |||
| 296 | int diag204(unsigned long subcode, unsigned long size, void *addr); | 308 | int diag204(unsigned long subcode, unsigned long size, void *addr); |
| 297 | int diag224(void *ptr); | 309 | int diag224(void *ptr); |
| 298 | int diag26c(void *req, void *resp, enum diag26c_sc subcode); | 310 | int diag26c(void *req, void *resp, enum diag26c_sc subcode); |
diff --git a/arch/s390/include/asm/ftrace.h b/arch/s390/include/asm/ftrace.h index 8ea270fdc7fb..5a3c95b11952 100644 --- a/arch/s390/include/asm/ftrace.h +++ b/arch/s390/include/asm/ftrace.h | |||
| @@ -81,5 +81,30 @@ static inline void ftrace_generate_call_insn(struct ftrace_insn *insn, | |||
| 81 | #endif | 81 | #endif |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | /* | ||
| 85 | * Even though the system call numbers are identical for s390/s390x a | ||
| 86 | * different system call table is used for compat tasks. This may lead | ||
| 87 | * to e.g. incorrect or missing trace event sysfs files. | ||
| 88 | * Therefore simply do not trace compat system calls at all. | ||
| 89 | * See kernel/trace/trace_syscalls.c. | ||
| 90 | */ | ||
| 91 | #define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS | ||
| 92 | static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs) | ||
| 93 | { | ||
| 94 | return is_compat_task(); | ||
| 95 | } | ||
| 96 | |||
| 97 | #define ARCH_HAS_SYSCALL_MATCH_SYM_NAME | ||
| 98 | static inline bool arch_syscall_match_sym_name(const char *sym, | ||
| 99 | const char *name) | ||
| 100 | { | ||
| 101 | /* | ||
| 102 | * Skip __s390_ and __s390x_ prefix - due to compat wrappers | ||
| 103 | * and aliasing some symbols of 64 bit system call functions | ||
| 104 | * may get the __s390_ prefix instead of the __s390x_ prefix. | ||
| 105 | */ | ||
| 106 | return !strcmp(sym + 7, name) || !strcmp(sym + 8, name); | ||
| 107 | } | ||
| 108 | |||
| 84 | #endif /* __ASSEMBLY__ */ | 109 | #endif /* __ASSEMBLY__ */ |
| 85 | #endif /* _ASM_S390_FTRACE_H */ | 110 | #endif /* _ASM_S390_FTRACE_H */ |
diff --git a/arch/s390/include/asm/jump_label.h b/arch/s390/include/asm/jump_label.h index e2d3e6c43395..e548ec1ec12c 100644 --- a/arch/s390/include/asm/jump_label.h +++ b/arch/s390/include/asm/jump_label.h | |||
| @@ -10,6 +10,12 @@ | |||
| 10 | #define JUMP_LABEL_NOP_SIZE 6 | 10 | #define JUMP_LABEL_NOP_SIZE 6 |
| 11 | #define JUMP_LABEL_NOP_OFFSET 2 | 11 | #define JUMP_LABEL_NOP_OFFSET 2 |
| 12 | 12 | ||
| 13 | #if __GNUC__ < 9 | ||
| 14 | #define JUMP_LABEL_STATIC_KEY_CONSTRAINT "X" | ||
| 15 | #else | ||
| 16 | #define JUMP_LABEL_STATIC_KEY_CONSTRAINT "jdd" | ||
| 17 | #endif | ||
| 18 | |||
| 13 | /* | 19 | /* |
| 14 | * We use a brcl 0,2 instruction for jump labels at compile time so it | 20 | * We use a brcl 0,2 instruction for jump labels at compile time so it |
| 15 | * can be easily distinguished from a hotpatch generated instruction. | 21 | * can be easily distinguished from a hotpatch generated instruction. |
| @@ -20,9 +26,9 @@ static inline bool arch_static_branch(struct static_key *key, bool branch) | |||
| 20 | ".pushsection __jump_table,\"aw\"\n" | 26 | ".pushsection __jump_table,\"aw\"\n" |
| 21 | ".balign 8\n" | 27 | ".balign 8\n" |
| 22 | ".long 0b-.,%l[label]-.\n" | 28 | ".long 0b-.,%l[label]-.\n" |
| 23 | ".quad %0-.\n" | 29 | ".quad %0+%1-.\n" |
| 24 | ".popsection\n" | 30 | ".popsection\n" |
| 25 | : : "X" (&((char *)key)[branch]) : : label); | 31 | : : JUMP_LABEL_STATIC_KEY_CONSTRAINT (key), "i" (branch) : : label); |
| 26 | return false; | 32 | return false; |
| 27 | label: | 33 | label: |
| 28 | return true; | 34 | return true; |
| @@ -34,9 +40,9 @@ static inline bool arch_static_branch_jump(struct static_key *key, bool branch) | |||
| 34 | ".pushsection __jump_table,\"aw\"\n" | 40 | ".pushsection __jump_table,\"aw\"\n" |
| 35 | ".balign 8\n" | 41 | ".balign 8\n" |
| 36 | ".long 0b-.,%l[label]-.\n" | 42 | ".long 0b-.,%l[label]-.\n" |
| 37 | ".quad %0-.\n" | 43 | ".quad %0+%1-.\n" |
| 38 | ".popsection\n" | 44 | ".popsection\n" |
| 39 | : : "X" (&((char *)key)[branch]) : : label); | 45 | : : JUMP_LABEL_STATIC_KEY_CONSTRAINT (key), "i" (branch) : : label); |
| 40 | return false; | 46 | return false; |
| 41 | label: | 47 | label: |
| 42 | return true; | 48 | return true; |
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h index 10fe982f2b4b..4e0efebc56a9 100644 --- a/arch/s390/include/asm/pci.h +++ b/arch/s390/include/asm/pci.h | |||
| @@ -148,7 +148,6 @@ struct zpci_dev { | |||
| 148 | enum pci_bus_speed max_bus_speed; | 148 | enum pci_bus_speed max_bus_speed; |
| 149 | 149 | ||
| 150 | struct dentry *debugfs_dev; | 150 | struct dentry *debugfs_dev; |
| 151 | struct dentry *debugfs_perf; | ||
| 152 | 151 | ||
| 153 | struct s390_domain *s390_domain; /* s390 IOMMU domain data */ | 152 | struct s390_domain *s390_domain; /* s390 IOMMU domain data */ |
| 154 | }; | 153 | }; |
diff --git a/arch/s390/include/asm/perf_event.h b/arch/s390/include/asm/perf_event.h index b9c0e361748b..560d8f766ddf 100644 --- a/arch/s390/include/asm/perf_event.h +++ b/arch/s390/include/asm/perf_event.h | |||
| @@ -12,7 +12,6 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/perf_event.h> | 13 | #include <linux/perf_event.h> |
| 14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
| 15 | #include <asm/cpu_mf.h> | ||
| 16 | 15 | ||
| 17 | /* Per-CPU flags for PMU states */ | 16 | /* Per-CPU flags for PMU states */ |
| 18 | #define PMU_F_RESERVED 0x1000 | 17 | #define PMU_F_RESERVED 0x1000 |
| @@ -55,6 +54,7 @@ struct perf_sf_sde_regs { | |||
| 55 | #define PERF_CPUM_SF_MAX_CTR 2 | 54 | #define PERF_CPUM_SF_MAX_CTR 2 |
| 56 | #define PERF_EVENT_CPUM_SF 0xB0000UL /* Event: Basic-sampling */ | 55 | #define PERF_EVENT_CPUM_SF 0xB0000UL /* Event: Basic-sampling */ |
| 57 | #define PERF_EVENT_CPUM_SF_DIAG 0xBD000UL /* Event: Combined-sampling */ | 56 | #define PERF_EVENT_CPUM_SF_DIAG 0xBD000UL /* Event: Combined-sampling */ |
| 57 | #define PERF_EVENT_CPUM_CF_DIAG 0xBC000UL /* Event: Counter sets */ | ||
| 58 | #define PERF_CPUM_SF_BASIC_MODE 0x0001 /* Basic-sampling flag */ | 58 | #define PERF_CPUM_SF_BASIC_MODE 0x0001 /* Basic-sampling flag */ |
| 59 | #define PERF_CPUM_SF_DIAG_MODE 0x0002 /* Diagnostic-sampling flag */ | 59 | #define PERF_CPUM_SF_DIAG_MODE 0x0002 /* Diagnostic-sampling flag */ |
| 60 | #define PERF_CPUM_SF_MODE_MASK (PERF_CPUM_SF_BASIC_MODE| \ | 60 | #define PERF_CPUM_SF_MODE_MASK (PERF_CPUM_SF_BASIC_MODE| \ |
diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h index d46edde7e458..db5ef22c46e4 100644 --- a/arch/s390/include/asm/qdio.h +++ b/arch/s390/include/asm/qdio.h | |||
| @@ -361,8 +361,8 @@ struct qdio_initialize { | |||
| 361 | unsigned long); | 361 | unsigned long); |
| 362 | int scan_threshold; | 362 | int scan_threshold; |
| 363 | unsigned long int_parm; | 363 | unsigned long int_parm; |
| 364 | void **input_sbal_addr_array; | 364 | struct qdio_buffer **input_sbal_addr_array; |
| 365 | void **output_sbal_addr_array; | 365 | struct qdio_buffer **output_sbal_addr_array; |
| 366 | struct qdio_outbuf_state *output_sbal_state_array; | 366 | struct qdio_outbuf_state *output_sbal_state_array; |
| 367 | }; | 367 | }; |
| 368 | 368 | ||
diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index 0cd4bda85eb1..ef4c9dec06a4 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h | |||
| @@ -78,6 +78,7 @@ struct sclp_info { | |||
| 78 | unsigned char has_skey : 1; | 78 | unsigned char has_skey : 1; |
| 79 | unsigned char has_kss : 1; | 79 | unsigned char has_kss : 1; |
| 80 | unsigned char has_gisaf : 1; | 80 | unsigned char has_gisaf : 1; |
| 81 | unsigned char has_diag318 : 1; | ||
| 81 | unsigned int ibc; | 82 | unsigned int ibc; |
| 82 | unsigned int mtid; | 83 | unsigned int mtid; |
| 83 | unsigned int mtid_cp; | 84 | unsigned int mtid_cp; |
diff --git a/arch/s390/include/asm/string.h b/arch/s390/include/asm/string.h index 116cc15a4b8a..70d87db54e62 100644 --- a/arch/s390/include/asm/string.h +++ b/arch/s390/include/asm/string.h | |||
| @@ -12,15 +12,21 @@ | |||
| 12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
| 13 | #endif | 13 | #endif |
| 14 | 14 | ||
| 15 | #define __HAVE_ARCH_MEMCHR /* inline & arch function */ | ||
| 16 | #define __HAVE_ARCH_MEMCMP /* arch function */ | ||
| 17 | #define __HAVE_ARCH_MEMCPY /* gcc builtin & arch function */ | 15 | #define __HAVE_ARCH_MEMCPY /* gcc builtin & arch function */ |
| 18 | #define __HAVE_ARCH_MEMMOVE /* gcc builtin & arch function */ | 16 | #define __HAVE_ARCH_MEMMOVE /* gcc builtin & arch function */ |
| 19 | #define __HAVE_ARCH_MEMSCAN /* inline & arch function */ | ||
| 20 | #define __HAVE_ARCH_MEMSET /* gcc builtin & arch function */ | 17 | #define __HAVE_ARCH_MEMSET /* gcc builtin & arch function */ |
| 21 | #define __HAVE_ARCH_MEMSET16 /* arch function */ | 18 | #define __HAVE_ARCH_MEMSET16 /* arch function */ |
| 22 | #define __HAVE_ARCH_MEMSET32 /* arch function */ | 19 | #define __HAVE_ARCH_MEMSET32 /* arch function */ |
| 23 | #define __HAVE_ARCH_MEMSET64 /* arch function */ | 20 | #define __HAVE_ARCH_MEMSET64 /* arch function */ |
| 21 | |||
| 22 | void *memcpy(void *dest, const void *src, size_t n); | ||
| 23 | void *memset(void *s, int c, size_t n); | ||
| 24 | void *memmove(void *dest, const void *src, size_t n); | ||
| 25 | |||
| 26 | #ifndef CONFIG_KASAN | ||
| 27 | #define __HAVE_ARCH_MEMCHR /* inline & arch function */ | ||
| 28 | #define __HAVE_ARCH_MEMCMP /* arch function */ | ||
| 29 | #define __HAVE_ARCH_MEMSCAN /* inline & arch function */ | ||
| 24 | #define __HAVE_ARCH_STRCAT /* inline & arch function */ | 30 | #define __HAVE_ARCH_STRCAT /* inline & arch function */ |
| 25 | #define __HAVE_ARCH_STRCMP /* arch function */ | 31 | #define __HAVE_ARCH_STRCMP /* arch function */ |
| 26 | #define __HAVE_ARCH_STRCPY /* inline & arch function */ | 32 | #define __HAVE_ARCH_STRCPY /* inline & arch function */ |
| @@ -35,9 +41,6 @@ | |||
| 35 | 41 | ||
| 36 | /* Prototypes for non-inlined arch strings functions. */ | 42 | /* Prototypes for non-inlined arch strings functions. */ |
| 37 | int memcmp(const void *s1, const void *s2, size_t n); | 43 | int memcmp(const void *s1, const void *s2, size_t n); |
| 38 | void *memcpy(void *dest, const void *src, size_t n); | ||
| 39 | void *memset(void *s, int c, size_t n); | ||
| 40 | void *memmove(void *dest, const void *src, size_t n); | ||
| 41 | int strcmp(const char *s1, const char *s2); | 44 | int strcmp(const char *s1, const char *s2); |
| 42 | size_t strlcat(char *dest, const char *src, size_t n); | 45 | size_t strlcat(char *dest, const char *src, size_t n); |
| 43 | size_t strlcpy(char *dest, const char *src, size_t size); | 46 | size_t strlcpy(char *dest, const char *src, size_t size); |
| @@ -45,6 +48,7 @@ char *strncat(char *dest, const char *src, size_t n); | |||
| 45 | char *strncpy(char *dest, const char *src, size_t n); | 48 | char *strncpy(char *dest, const char *src, size_t n); |
| 46 | char *strrchr(const char *s, int c); | 49 | char *strrchr(const char *s, int c); |
| 47 | char *strstr(const char *s1, const char *s2); | 50 | char *strstr(const char *s1, const char *s2); |
| 51 | #endif /* !CONFIG_KASAN */ | ||
| 48 | 52 | ||
| 49 | #undef __HAVE_ARCH_STRCHR | 53 | #undef __HAVE_ARCH_STRCHR |
| 50 | #undef __HAVE_ARCH_STRNCHR | 54 | #undef __HAVE_ARCH_STRNCHR |
| @@ -95,6 +99,7 @@ static inline void *memset64(uint64_t *s, uint64_t v, size_t count) | |||
| 95 | 99 | ||
| 96 | #if !defined(IN_ARCH_STRING_C) && (!defined(CONFIG_FORTIFY_SOURCE) || defined(__NO_FORTIFY)) | 100 | #if !defined(IN_ARCH_STRING_C) && (!defined(CONFIG_FORTIFY_SOURCE) || defined(__NO_FORTIFY)) |
| 97 | 101 | ||
| 102 | #ifdef __HAVE_ARCH_MEMCHR | ||
| 98 | static inline void *memchr(const void * s, int c, size_t n) | 103 | static inline void *memchr(const void * s, int c, size_t n) |
| 99 | { | 104 | { |
| 100 | register int r0 asm("0") = (char) c; | 105 | register int r0 asm("0") = (char) c; |
| @@ -109,7 +114,9 @@ static inline void *memchr(const void * s, int c, size_t n) | |||
| 109 | : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); | 114 | : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); |
| 110 | return (void *) ret; | 115 | return (void *) ret; |
| 111 | } | 116 | } |
| 117 | #endif | ||
| 112 | 118 | ||
| 119 | #ifdef __HAVE_ARCH_MEMSCAN | ||
| 113 | static inline void *memscan(void *s, int c, size_t n) | 120 | static inline void *memscan(void *s, int c, size_t n) |
| 114 | { | 121 | { |
| 115 | register int r0 asm("0") = (char) c; | 122 | register int r0 asm("0") = (char) c; |
| @@ -121,7 +128,9 @@ static inline void *memscan(void *s, int c, size_t n) | |||
| 121 | : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); | 128 | : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); |
| 122 | return (void *) ret; | 129 | return (void *) ret; |
| 123 | } | 130 | } |
| 131 | #endif | ||
| 124 | 132 | ||
| 133 | #ifdef __HAVE_ARCH_STRCAT | ||
| 125 | static inline char *strcat(char *dst, const char *src) | 134 | static inline char *strcat(char *dst, const char *src) |
| 126 | { | 135 | { |
| 127 | register int r0 asm("0") = 0; | 136 | register int r0 asm("0") = 0; |
| @@ -137,7 +146,9 @@ static inline char *strcat(char *dst, const char *src) | |||
| 137 | : "d" (r0), "0" (0) : "cc", "memory" ); | 146 | : "d" (r0), "0" (0) : "cc", "memory" ); |
| 138 | return ret; | 147 | return ret; |
| 139 | } | 148 | } |
| 149 | #endif | ||
| 140 | 150 | ||
| 151 | #ifdef __HAVE_ARCH_STRCPY | ||
| 141 | static inline char *strcpy(char *dst, const char *src) | 152 | static inline char *strcpy(char *dst, const char *src) |
| 142 | { | 153 | { |
| 143 | register int r0 asm("0") = 0; | 154 | register int r0 asm("0") = 0; |
| @@ -150,7 +161,9 @@ static inline char *strcpy(char *dst, const char *src) | |||
| 150 | : "cc", "memory"); | 161 | : "cc", "memory"); |
| 151 | return ret; | 162 | return ret; |
| 152 | } | 163 | } |
| 164 | #endif | ||
| 153 | 165 | ||
| 166 | #ifdef __HAVE_ARCH_STRLEN | ||
| 154 | static inline size_t strlen(const char *s) | 167 | static inline size_t strlen(const char *s) |
| 155 | { | 168 | { |
| 156 | register unsigned long r0 asm("0") = 0; | 169 | register unsigned long r0 asm("0") = 0; |
| @@ -162,7 +175,9 @@ static inline size_t strlen(const char *s) | |||
| 162 | : "+d" (r0), "+a" (tmp) : : "cc", "memory"); | 175 | : "+d" (r0), "+a" (tmp) : : "cc", "memory"); |
| 163 | return r0 - (unsigned long) s; | 176 | return r0 - (unsigned long) s; |
| 164 | } | 177 | } |
| 178 | #endif | ||
| 165 | 179 | ||
| 180 | #ifdef __HAVE_ARCH_STRNLEN | ||
| 166 | static inline size_t strnlen(const char * s, size_t n) | 181 | static inline size_t strnlen(const char * s, size_t n) |
| 167 | { | 182 | { |
| 168 | register int r0 asm("0") = 0; | 183 | register int r0 asm("0") = 0; |
| @@ -175,6 +190,7 @@ static inline size_t strnlen(const char * s, size_t n) | |||
| 175 | : "+a" (end), "+a" (tmp) : "d" (r0) : "cc", "memory"); | 190 | : "+a" (end), "+a" (tmp) : "d" (r0) : "cc", "memory"); |
| 176 | return end - s; | 191 | return end - s; |
| 177 | } | 192 | } |
| 193 | #endif | ||
| 178 | #else /* IN_ARCH_STRING_C */ | 194 | #else /* IN_ARCH_STRING_C */ |
| 179 | void *memchr(const void * s, int c, size_t n); | 195 | void *memchr(const void * s, int c, size_t n); |
| 180 | void *memscan(void *s, int c, size_t n); | 196 | void *memscan(void *s, int c, size_t n); |
diff --git a/arch/s390/include/asm/syscall_wrapper.h b/arch/s390/include/asm/syscall_wrapper.h new file mode 100644 index 000000000000..5596c5c625d2 --- /dev/null +++ b/arch/s390/include/asm/syscall_wrapper.h | |||
| @@ -0,0 +1,135 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /* | ||
| 3 | * syscall_wrapper.h - s390 specific wrappers to syscall definitions | ||
| 4 | * | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef _ASM_S390_SYSCALL_WRAPPER_H | ||
| 8 | #define _ASM_S390_SYSCALL_WRAPPER_H | ||
| 9 | |||
| 10 | #ifdef CONFIG_COMPAT | ||
| 11 | #define __SC_COMPAT_TYPE(t, a) \ | ||
| 12 | __typeof(__builtin_choose_expr(sizeof(t) > 4, 0L, (t)0)) a | ||
| 13 | |||
| 14 | #define __SC_COMPAT_CAST(t, a) \ | ||
| 15 | ({ \ | ||
| 16 | long __ReS = a; \ | ||
| 17 | \ | ||
| 18 | BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \ | ||
| 19 | !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t) && \ | ||
| 20 | !__TYPE_IS_LL(t)); \ | ||
| 21 | if (__TYPE_IS_L(t)) \ | ||
| 22 | __ReS = (s32)a; \ | ||
| 23 | if (__TYPE_IS_UL(t)) \ | ||
| 24 | __ReS = (u32)a; \ | ||
| 25 | if (__TYPE_IS_PTR(t)) \ | ||
| 26 | __ReS = a & 0x7fffffff; \ | ||
| 27 | if (__TYPE_IS_LL(t)) \ | ||
| 28 | return -ENOSYS; \ | ||
| 29 | (t)__ReS; \ | ||
| 30 | }) | ||
| 31 | |||
| 32 | #define __S390_SYS_STUBx(x, name, ...) \ | ||
| 33 | asmlinkage long __s390_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__))\ | ||
| 34 | ALLOW_ERROR_INJECTION(__s390_sys##name, ERRNO); \ | ||
| 35 | asmlinkage long __s390_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__))\ | ||
| 36 | { \ | ||
| 37 | long ret = __s390x_sys##name(__MAP(x,__SC_COMPAT_CAST,__VA_ARGS__));\ | ||
| 38 | __MAP(x,__SC_TEST,__VA_ARGS__); \ | ||
| 39 | return ret; \ | ||
| 40 | } | ||
| 41 | |||
| 42 | /* | ||
| 43 | * To keep the naming coherent, re-define SYSCALL_DEFINE0 to create an alias | ||
| 44 | * named __s390x_sys_*() | ||
| 45 | */ | ||
| 46 | #define COMPAT_SYSCALL_DEFINE0(sname) \ | ||
| 47 | SYSCALL_METADATA(_##sname, 0); \ | ||
| 48 | asmlinkage long __s390_compat_sys_##sname(void); \ | ||
| 49 | ALLOW_ERROR_INJECTION(__s390_compat__sys_##sname, ERRNO); \ | ||
| 50 | asmlinkage long __s390_compat_sys_##sname(void) | ||
| 51 | |||
| 52 | #define SYSCALL_DEFINE0(sname) \ | ||
| 53 | SYSCALL_METADATA(_##sname, 0); \ | ||
| 54 | asmlinkage long __s390x_sys_##sname(void); \ | ||
| 55 | ALLOW_ERROR_INJECTION(__s390x_sys_##sname, ERRNO); \ | ||
| 56 | asmlinkage long __s390_sys_##sname(void) \ | ||
| 57 | __attribute__((alias(__stringify(__s390x_sys_##sname)))); \ | ||
| 58 | asmlinkage long __s390x_sys_##sname(void) | ||
| 59 | |||
| 60 | #define COND_SYSCALL(name) \ | ||
| 61 | cond_syscall(__s390x_sys_##name); \ | ||
| 62 | cond_syscall(__s390_sys_##name) | ||
| 63 | |||
| 64 | #define SYS_NI(name) \ | ||
| 65 | SYSCALL_ALIAS(__s390x_sys_##name, sys_ni_posix_timers); \ | ||
| 66 | SYSCALL_ALIAS(__s390_sys_##name, sys_ni_posix_timers) | ||
| 67 | |||
| 68 | #define COMPAT_SYSCALL_DEFINEx(x, name, ...) \ | ||
| 69 | __diag_push(); \ | ||
| 70 | __diag_ignore(GCC, 8, "-Wattribute-alias", \ | ||
| 71 | "Type aliasing is used to sanitize syscall arguments");\ | ||
| 72 | asmlinkage long __s390_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ | ||
| 73 | asmlinkage long __s390_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \ | ||
| 74 | __attribute__((alias(__stringify(__se_compat_sys##name)))); \ | ||
| 75 | ALLOW_ERROR_INJECTION(compat_sys##name, ERRNO); \ | ||
| 76 | static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__));\ | ||
| 77 | asmlinkage long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ | ||
| 78 | asmlinkage long __se_compat_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ | ||
| 79 | { \ | ||
| 80 | long ret = __do_compat_sys##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__));\ | ||
| 81 | __MAP(x,__SC_TEST,__VA_ARGS__); \ | ||
| 82 | return ret; \ | ||
| 83 | } \ | ||
| 84 | __diag_pop(); \ | ||
| 85 | static inline long __do_compat_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) | ||
| 86 | |||
| 87 | /* | ||
| 88 | * As some compat syscalls may not be implemented, we need to expand | ||
| 89 | * COND_SYSCALL_COMPAT in kernel/sys_ni.c and COMPAT_SYS_NI in | ||
| 90 | * kernel/time/posix-stubs.c to cover this case as well. | ||
| 91 | */ | ||
| 92 | #define COND_SYSCALL_COMPAT(name) \ | ||
| 93 | cond_syscall(__s390_compat_sys_##name) | ||
| 94 | |||
| 95 | #define COMPAT_SYS_NI(name) \ | ||
| 96 | SYSCALL_ALIAS(__s390_compat_sys_##name, sys_ni_posix_timers) | ||
| 97 | |||
| 98 | #else /* CONFIG_COMPAT */ | ||
| 99 | |||
| 100 | #define __S390_SYS_STUBx(x, fullname, name, ...) | ||
| 101 | |||
| 102 | #define SYSCALL_DEFINE0(sname) \ | ||
| 103 | SYSCALL_METADATA(_##sname, 0); \ | ||
| 104 | asmlinkage long __s390x_sys_##sname(void); \ | ||
| 105 | ALLOW_ERROR_INJECTION(__s390x_sys_##sname, ERRNO); \ | ||
| 106 | asmlinkage long __s390x_sys_##sname(void) | ||
| 107 | |||
| 108 | #define COND_SYSCALL(name) \ | ||
| 109 | cond_syscall(__s390x_sys_##name) | ||
| 110 | |||
| 111 | #define SYS_NI(name) \ | ||
| 112 | SYSCALL_ALIAS(__s390x_sys_##name, sys_ni_posix_timers); | ||
| 113 | |||
| 114 | #endif /* CONFIG_COMPAT */ | ||
| 115 | |||
| 116 | #define __SYSCALL_DEFINEx(x, name, ...) \ | ||
| 117 | __diag_push(); \ | ||
| 118 | __diag_ignore(GCC, 8, "-Wattribute-alias", \ | ||
| 119 | "Type aliasing is used to sanitize syscall arguments");\ | ||
| 120 | asmlinkage long __s390x_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \ | ||
| 121 | __attribute__((alias(__stringify(__se_sys##name)))); \ | ||
| 122 | ALLOW_ERROR_INJECTION(__s390x_sys##name, ERRNO); \ | ||
| 123 | static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ | ||
| 124 | static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ | ||
| 125 | __S390_SYS_STUBx(x, name, __VA_ARGS__) \ | ||
| 126 | asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ | ||
| 127 | { \ | ||
| 128 | long ret = __do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__)); \ | ||
| 129 | __MAP(x,__SC_TEST,__VA_ARGS__); \ | ||
| 130 | return ret; \ | ||
| 131 | } \ | ||
| 132 | __diag_pop(); \ | ||
| 133 | static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) | ||
| 134 | |||
| 135 | #endif /* _ASM_X86_SYSCALL_WRAPPER_H */ | ||
diff --git a/arch/s390/include/asm/vx-insn.h b/arch/s390/include/asm/vx-insn.h index 266a72320e05..0c05a673811c 100644 --- a/arch/s390/include/asm/vx-insn.h +++ b/arch/s390/include/asm/vx-insn.h | |||
| @@ -363,23 +363,23 @@ | |||
| 363 | .endm | 363 | .endm |
| 364 | 364 | ||
| 365 | /* VECTOR LOAD MULTIPLE */ | 365 | /* VECTOR LOAD MULTIPLE */ |
| 366 | .macro VLM vfrom, vto, disp, base | 366 | .macro VLM vfrom, vto, disp, base, hint=3 |
| 367 | VX_NUM v1, \vfrom | 367 | VX_NUM v1, \vfrom |
| 368 | VX_NUM v3, \vto | 368 | VX_NUM v3, \vto |
| 369 | GR_NUM b2, \base /* Base register */ | 369 | GR_NUM b2, \base /* Base register */ |
| 370 | .word 0xE700 | ((v1&15) << 4) | (v3&15) | 370 | .word 0xE700 | ((v1&15) << 4) | (v3&15) |
| 371 | .word (b2 << 12) | (\disp) | 371 | .word (b2 << 12) | (\disp) |
| 372 | MRXBOPC 0, 0x36, v1, v3 | 372 | MRXBOPC \hint, 0x36, v1, v3 |
| 373 | .endm | 373 | .endm |
| 374 | 374 | ||
| 375 | /* VECTOR STORE MULTIPLE */ | 375 | /* VECTOR STORE MULTIPLE */ |
| 376 | .macro VSTM vfrom, vto, disp, base | 376 | .macro VSTM vfrom, vto, disp, base, hint=3 |
| 377 | VX_NUM v1, \vfrom | 377 | VX_NUM v1, \vfrom |
| 378 | VX_NUM v3, \vto | 378 | VX_NUM v3, \vto |
| 379 | GR_NUM b2, \base /* Base register */ | 379 | GR_NUM b2, \base /* Base register */ |
| 380 | .word 0xE700 | ((v1&15) << 4) | (v3&15) | 380 | .word 0xE700 | ((v1&15) << 4) | (v3&15) |
| 381 | .word (b2 << 12) | (\disp) | 381 | .word (b2 << 12) | (\disp) |
| 382 | MRXBOPC 0, 0x3E, v1, v3 | 382 | MRXBOPC \hint, 0x3E, v1, v3 |
| 383 | .endm | 383 | .endm |
| 384 | 384 | ||
| 385 | /* VECTOR PERMUTE */ | 385 | /* VECTOR PERMUTE */ |
diff --git a/arch/s390/include/uapi/asm/posix_types.h b/arch/s390/include/uapi/asm/posix_types.h index 2a3fc638414b..1913613e71b6 100644 --- a/arch/s390/include/uapi/asm/posix_types.h +++ b/arch/s390/include/uapi/asm/posix_types.h | |||
| @@ -20,6 +20,12 @@ typedef long __kernel_ssize_t; | |||
| 20 | typedef unsigned short __kernel_old_dev_t; | 20 | typedef unsigned short __kernel_old_dev_t; |
| 21 | #define __kernel_old_dev_t __kernel_old_dev_t | 21 | #define __kernel_old_dev_t __kernel_old_dev_t |
| 22 | 22 | ||
| 23 | #ifdef __KERNEL__ | ||
| 24 | typedef unsigned short __kernel_old_uid_t; | ||
| 25 | typedef unsigned short __kernel_old_gid_t; | ||
| 26 | #define __kernel_old_uid_t __kernel_old_uid_t | ||
| 27 | #endif | ||
| 28 | |||
| 23 | #ifndef __s390x__ | 29 | #ifndef __s390x__ |
| 24 | 30 | ||
| 25 | typedef unsigned long __kernel_ino_t; | 31 | typedef unsigned long __kernel_ino_t; |
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index e216e116a9a9..8a62c7f72e1b 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
| @@ -65,7 +65,7 @@ obj-$(CONFIG_HIBERNATION) += suspend.o swsusp.o | |||
| 65 | obj-$(CONFIG_AUDIT) += audit.o | 65 | obj-$(CONFIG_AUDIT) += audit.o |
| 66 | compat-obj-$(CONFIG_AUDIT) += compat_audit.o | 66 | compat-obj-$(CONFIG_AUDIT) += compat_audit.o |
| 67 | obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o | 67 | obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o |
| 68 | obj-$(CONFIG_COMPAT) += compat_wrapper.o $(compat-obj-y) | 68 | obj-$(CONFIG_COMPAT) += $(compat-obj-y) |
| 69 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 69 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
| 70 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 70 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
| 71 | obj-$(CONFIG_KPROBES) += kprobes.o | 71 | obj-$(CONFIG_KPROBES) += kprobes.o |
| @@ -77,8 +77,10 @@ obj-$(CONFIG_JUMP_LABEL) += jump_label.o | |||
| 77 | obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o kexec_image.o | 77 | obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o kexec_image.o |
| 78 | obj-$(CONFIG_KEXEC_FILE) += kexec_elf.o | 78 | obj-$(CONFIG_KEXEC_FILE) += kexec_elf.o |
| 79 | 79 | ||
| 80 | obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_cpum_cf.o perf_cpum_sf.o | 80 | obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_cpum_cf_common.o |
| 81 | obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf.o perf_cpum_sf.o | ||
| 81 | obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf_events.o perf_regs.o | 82 | obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf_events.o perf_regs.o |
| 83 | obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf_diag.o | ||
| 82 | 84 | ||
| 83 | obj-$(CONFIG_TRACEPOINTS) += trace.o | 85 | obj-$(CONFIG_TRACEPOINTS) += trace.o |
| 84 | 86 | ||
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 8ac38d51ed7d..f9d418d1b619 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c | |||
| @@ -34,7 +34,6 @@ | |||
| 34 | #include <linux/stat.h> | 34 | #include <linux/stat.h> |
| 35 | #include <linux/filter.h> | 35 | #include <linux/filter.h> |
| 36 | #include <linux/highmem.h> | 36 | #include <linux/highmem.h> |
| 37 | #include <linux/highuid.h> | ||
| 38 | #include <linux/mman.h> | 37 | #include <linux/mman.h> |
| 39 | #include <linux/ipv6.h> | 38 | #include <linux/ipv6.h> |
| 40 | #include <linux/in.h> | 39 | #include <linux/in.h> |
| @@ -58,245 +57,13 @@ | |||
| 58 | 57 | ||
| 59 | #include "compat_linux.h" | 58 | #include "compat_linux.h" |
| 60 | 59 | ||
| 61 | /* For this source file, we want overflow handling. */ | ||
| 62 | |||
| 63 | #undef high2lowuid | ||
| 64 | #undef high2lowgid | ||
| 65 | #undef low2highuid | ||
| 66 | #undef low2highgid | ||
| 67 | #undef SET_UID16 | ||
| 68 | #undef SET_GID16 | ||
| 69 | #undef NEW_TO_OLD_UID | ||
| 70 | #undef NEW_TO_OLD_GID | ||
| 71 | #undef SET_OLDSTAT_UID | ||
| 72 | #undef SET_OLDSTAT_GID | ||
| 73 | #undef SET_STAT_UID | ||
| 74 | #undef SET_STAT_GID | ||
| 75 | |||
| 76 | #define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid) | ||
| 77 | #define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid) | ||
| 78 | #define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid) | ||
| 79 | #define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid) | ||
| 80 | #define SET_UID16(var, uid) var = high2lowuid(uid) | ||
| 81 | #define SET_GID16(var, gid) var = high2lowgid(gid) | ||
| 82 | #define NEW_TO_OLD_UID(uid) high2lowuid(uid) | ||
| 83 | #define NEW_TO_OLD_GID(gid) high2lowgid(gid) | ||
| 84 | #define SET_OLDSTAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid) | ||
| 85 | #define SET_OLDSTAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid) | ||
| 86 | #define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid) | ||
| 87 | #define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid) | ||
| 88 | |||
| 89 | COMPAT_SYSCALL_DEFINE3(s390_chown16, const char __user *, filename, | ||
| 90 | u16, user, u16, group) | ||
| 91 | { | ||
| 92 | return ksys_chown(filename, low2highuid(user), low2highgid(group)); | ||
| 93 | } | ||
| 94 | |||
| 95 | COMPAT_SYSCALL_DEFINE3(s390_lchown16, const char __user *, | ||
| 96 | filename, u16, user, u16, group) | ||
| 97 | { | ||
| 98 | return ksys_lchown(filename, low2highuid(user), low2highgid(group)); | ||
| 99 | } | ||
| 100 | |||
| 101 | COMPAT_SYSCALL_DEFINE3(s390_fchown16, unsigned int, fd, u16, user, u16, group) | ||
| 102 | { | ||
| 103 | return ksys_fchown(fd, low2highuid(user), low2highgid(group)); | ||
| 104 | } | ||
| 105 | |||
| 106 | COMPAT_SYSCALL_DEFINE2(s390_setregid16, u16, rgid, u16, egid) | ||
| 107 | { | ||
| 108 | return sys_setregid(low2highgid(rgid), low2highgid(egid)); | ||
| 109 | } | ||
| 110 | |||
| 111 | COMPAT_SYSCALL_DEFINE1(s390_setgid16, u16, gid) | ||
| 112 | { | ||
| 113 | return sys_setgid(low2highgid(gid)); | ||
| 114 | } | ||
| 115 | |||
| 116 | COMPAT_SYSCALL_DEFINE2(s390_setreuid16, u16, ruid, u16, euid) | ||
| 117 | { | ||
| 118 | return sys_setreuid(low2highuid(ruid), low2highuid(euid)); | ||
| 119 | } | ||
| 120 | |||
| 121 | COMPAT_SYSCALL_DEFINE1(s390_setuid16, u16, uid) | ||
| 122 | { | ||
| 123 | return sys_setuid(low2highuid(uid)); | ||
| 124 | } | ||
| 125 | |||
| 126 | COMPAT_SYSCALL_DEFINE3(s390_setresuid16, u16, ruid, u16, euid, u16, suid) | ||
| 127 | { | ||
| 128 | return sys_setresuid(low2highuid(ruid), low2highuid(euid), | ||
| 129 | low2highuid(suid)); | ||
| 130 | } | ||
| 131 | |||
| 132 | COMPAT_SYSCALL_DEFINE3(s390_getresuid16, u16 __user *, ruidp, | ||
| 133 | u16 __user *, euidp, u16 __user *, suidp) | ||
| 134 | { | ||
| 135 | const struct cred *cred = current_cred(); | ||
| 136 | int retval; | ||
| 137 | u16 ruid, euid, suid; | ||
| 138 | |||
| 139 | ruid = high2lowuid(from_kuid_munged(cred->user_ns, cred->uid)); | ||
| 140 | euid = high2lowuid(from_kuid_munged(cred->user_ns, cred->euid)); | ||
| 141 | suid = high2lowuid(from_kuid_munged(cred->user_ns, cred->suid)); | ||
| 142 | |||
| 143 | if (!(retval = put_user(ruid, ruidp)) && | ||
| 144 | !(retval = put_user(euid, euidp))) | ||
| 145 | retval = put_user(suid, suidp); | ||
| 146 | |||
| 147 | return retval; | ||
| 148 | } | ||
| 149 | |||
| 150 | COMPAT_SYSCALL_DEFINE3(s390_setresgid16, u16, rgid, u16, egid, u16, sgid) | ||
| 151 | { | ||
| 152 | return sys_setresgid(low2highgid(rgid), low2highgid(egid), | ||
| 153 | low2highgid(sgid)); | ||
| 154 | } | ||
| 155 | |||
| 156 | COMPAT_SYSCALL_DEFINE3(s390_getresgid16, u16 __user *, rgidp, | ||
| 157 | u16 __user *, egidp, u16 __user *, sgidp) | ||
| 158 | { | ||
| 159 | const struct cred *cred = current_cred(); | ||
| 160 | int retval; | ||
| 161 | u16 rgid, egid, sgid; | ||
| 162 | |||
| 163 | rgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->gid)); | ||
| 164 | egid = high2lowgid(from_kgid_munged(cred->user_ns, cred->egid)); | ||
| 165 | sgid = high2lowgid(from_kgid_munged(cred->user_ns, cred->sgid)); | ||
| 166 | |||
| 167 | if (!(retval = put_user(rgid, rgidp)) && | ||
| 168 | !(retval = put_user(egid, egidp))) | ||
| 169 | retval = put_user(sgid, sgidp); | ||
| 170 | |||
| 171 | return retval; | ||
| 172 | } | ||
| 173 | |||
| 174 | COMPAT_SYSCALL_DEFINE1(s390_setfsuid16, u16, uid) | ||
| 175 | { | ||
| 176 | return sys_setfsuid(low2highuid(uid)); | ||
| 177 | } | ||
| 178 | |||
| 179 | COMPAT_SYSCALL_DEFINE1(s390_setfsgid16, u16, gid) | ||
| 180 | { | ||
| 181 | return sys_setfsgid(low2highgid(gid)); | ||
| 182 | } | ||
| 183 | |||
| 184 | static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info) | ||
| 185 | { | ||
| 186 | struct user_namespace *user_ns = current_user_ns(); | ||
| 187 | int i; | ||
| 188 | u16 group; | ||
| 189 | kgid_t kgid; | ||
| 190 | |||
| 191 | for (i = 0; i < group_info->ngroups; i++) { | ||
| 192 | kgid = group_info->gid[i]; | ||
| 193 | group = (u16)from_kgid_munged(user_ns, kgid); | ||
| 194 | if (put_user(group, grouplist+i)) | ||
| 195 | return -EFAULT; | ||
| 196 | } | ||
| 197 | |||
| 198 | return 0; | ||
| 199 | } | ||
| 200 | |||
| 201 | static int groups16_from_user(struct group_info *group_info, u16 __user *grouplist) | ||
| 202 | { | ||
| 203 | struct user_namespace *user_ns = current_user_ns(); | ||
| 204 | int i; | ||
| 205 | u16 group; | ||
| 206 | kgid_t kgid; | ||
| 207 | |||
| 208 | for (i = 0; i < group_info->ngroups; i++) { | ||
| 209 | if (get_user(group, grouplist+i)) | ||
| 210 | return -EFAULT; | ||
| 211 | |||
| 212 | kgid = make_kgid(user_ns, (gid_t)group); | ||
| 213 | if (!gid_valid(kgid)) | ||
| 214 | return -EINVAL; | ||
| 215 | |||
| 216 | group_info->gid[i] = kgid; | ||
| 217 | } | ||
| 218 | |||
| 219 | return 0; | ||
| 220 | } | ||
| 221 | |||
| 222 | COMPAT_SYSCALL_DEFINE2(s390_getgroups16, int, gidsetsize, u16 __user *, grouplist) | ||
| 223 | { | ||
| 224 | const struct cred *cred = current_cred(); | ||
| 225 | int i; | ||
| 226 | |||
| 227 | if (gidsetsize < 0) | ||
| 228 | return -EINVAL; | ||
| 229 | |||
| 230 | get_group_info(cred->group_info); | ||
| 231 | i = cred->group_info->ngroups; | ||
| 232 | if (gidsetsize) { | ||
| 233 | if (i > gidsetsize) { | ||
| 234 | i = -EINVAL; | ||
| 235 | goto out; | ||
| 236 | } | ||
| 237 | if (groups16_to_user(grouplist, cred->group_info)) { | ||
| 238 | i = -EFAULT; | ||
| 239 | goto out; | ||
| 240 | } | ||
| 241 | } | ||
| 242 | out: | ||
| 243 | put_group_info(cred->group_info); | ||
| 244 | return i; | ||
| 245 | } | ||
| 246 | |||
| 247 | COMPAT_SYSCALL_DEFINE2(s390_setgroups16, int, gidsetsize, u16 __user *, grouplist) | ||
| 248 | { | ||
| 249 | struct group_info *group_info; | ||
| 250 | int retval; | ||
| 251 | |||
| 252 | if (!may_setgroups()) | ||
| 253 | return -EPERM; | ||
| 254 | if ((unsigned)gidsetsize > NGROUPS_MAX) | ||
| 255 | return -EINVAL; | ||
| 256 | |||
| 257 | group_info = groups_alloc(gidsetsize); | ||
| 258 | if (!group_info) | ||
| 259 | return -ENOMEM; | ||
| 260 | retval = groups16_from_user(group_info, grouplist); | ||
| 261 | if (retval) { | ||
| 262 | put_group_info(group_info); | ||
| 263 | return retval; | ||
| 264 | } | ||
| 265 | |||
| 266 | groups_sort(group_info); | ||
| 267 | retval = set_current_groups(group_info); | ||
| 268 | put_group_info(group_info); | ||
| 269 | |||
| 270 | return retval; | ||
| 271 | } | ||
| 272 | |||
| 273 | COMPAT_SYSCALL_DEFINE0(s390_getuid16) | ||
| 274 | { | ||
| 275 | return high2lowuid(from_kuid_munged(current_user_ns(), current_uid())); | ||
| 276 | } | ||
| 277 | |||
| 278 | COMPAT_SYSCALL_DEFINE0(s390_geteuid16) | ||
| 279 | { | ||
| 280 | return high2lowuid(from_kuid_munged(current_user_ns(), current_euid())); | ||
| 281 | } | ||
| 282 | |||
| 283 | COMPAT_SYSCALL_DEFINE0(s390_getgid16) | ||
| 284 | { | ||
| 285 | return high2lowgid(from_kgid_munged(current_user_ns(), current_gid())); | ||
| 286 | } | ||
| 287 | |||
| 288 | COMPAT_SYSCALL_DEFINE0(s390_getegid16) | ||
| 289 | { | ||
| 290 | return high2lowgid(from_kgid_munged(current_user_ns(), current_egid())); | ||
| 291 | } | ||
| 292 | |||
| 293 | #ifdef CONFIG_SYSVIPC | 60 | #ifdef CONFIG_SYSVIPC |
| 294 | COMPAT_SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, compat_ulong_t, second, | 61 | COMPAT_SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, compat_ulong_t, second, |
| 295 | compat_ulong_t, third, compat_uptr_t, ptr) | 62 | compat_ulong_t, third, compat_uptr_t, ptr) |
| 296 | { | 63 | { |
| 297 | if (call >> 16) /* hack for backward compatibility */ | 64 | if (call >> 16) /* hack for backward compatibility */ |
| 298 | return -EINVAL; | 65 | return -EINVAL; |
| 299 | return compat_sys_ipc(call, first, second, third, ptr, third); | 66 | return compat_ksys_ipc(call, first, second, third, ptr, third); |
| 300 | } | 67 | } |
| 301 | #endif | 68 | #endif |
| 302 | 69 | ||
diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c deleted file mode 100644 index 48c4ce668244..000000000000 --- a/arch/s390/kernel/compat_wrapper.c +++ /dev/null | |||
| @@ -1,186 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Compat system call wrappers. | ||
| 4 | * | ||
| 5 | * Copyright IBM Corp. 2014 | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <linux/syscalls.h> | ||
| 9 | #include <linux/compat.h> | ||
| 10 | #include "entry.h" | ||
| 11 | |||
| 12 | #define COMPAT_SYSCALL_WRAP1(name, ...) \ | ||
| 13 | COMPAT_SYSCALL_WRAPx(1, _##name, __VA_ARGS__) | ||
| 14 | #define COMPAT_SYSCALL_WRAP2(name, ...) \ | ||
| 15 | COMPAT_SYSCALL_WRAPx(2, _##name, __VA_ARGS__) | ||
| 16 | #define COMPAT_SYSCALL_WRAP3(name, ...) \ | ||
| 17 | COMPAT_SYSCALL_WRAPx(3, _##name, __VA_ARGS__) | ||
| 18 | #define COMPAT_SYSCALL_WRAP4(name, ...) \ | ||
| 19 | COMPAT_SYSCALL_WRAPx(4, _##name, __VA_ARGS__) | ||
| 20 | #define COMPAT_SYSCALL_WRAP5(name, ...) \ | ||
| 21 | COMPAT_SYSCALL_WRAPx(5, _##name, __VA_ARGS__) | ||
| 22 | #define COMPAT_SYSCALL_WRAP6(name, ...) \ | ||
| 23 | COMPAT_SYSCALL_WRAPx(6, _##name, __VA_ARGS__) | ||
| 24 | |||
| 25 | #define __SC_COMPAT_TYPE(t, a) \ | ||
| 26 | __typeof(__builtin_choose_expr(sizeof(t) > 4, 0L, (t)0)) a | ||
| 27 | |||
| 28 | #define __SC_COMPAT_CAST(t, a) \ | ||
| 29 | ({ \ | ||
| 30 | long __ReS = a; \ | ||
| 31 | \ | ||
| 32 | BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \ | ||
| 33 | !__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t)); \ | ||
| 34 | if (__TYPE_IS_L(t)) \ | ||
| 35 | __ReS = (s32)a; \ | ||
| 36 | if (__TYPE_IS_UL(t)) \ | ||
| 37 | __ReS = (u32)a; \ | ||
| 38 | if (__TYPE_IS_PTR(t)) \ | ||
| 39 | __ReS = a & 0x7fffffff; \ | ||
| 40 | (t)__ReS; \ | ||
| 41 | }) | ||
| 42 | |||
| 43 | /* | ||
| 44 | * The COMPAT_SYSCALL_WRAP macro generates system call wrappers to be used by | ||
| 45 | * compat tasks. These wrappers will only be used for system calls where only | ||
| 46 | * the system call arguments need sign or zero extension or zeroing of the upper | ||
| 47 | * 33 bits of pointers. | ||
| 48 | * Note: since the wrapper function will afterwards call a system call which | ||
| 49 | * again performs zero and sign extension for all system call arguments with | ||
| 50 | * a size of less than eight bytes, these compat wrappers only touch those | ||
| 51 | * system call arguments with a size of eight bytes ((unsigned) long and | ||
| 52 | * pointers). Zero and sign extension for e.g. int parameters will be done by | ||
| 53 | * the regular system call wrappers. | ||
| 54 | */ | ||
| 55 | #define COMPAT_SYSCALL_WRAPx(x, name, ...) \ | ||
| 56 | asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ | ||
| 57 | asmlinkage long notrace compat_sys##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__));\ | ||
| 58 | asmlinkage long notrace compat_sys##name(__MAP(x,__SC_COMPAT_TYPE,__VA_ARGS__)) \ | ||
| 59 | { \ | ||
| 60 | return sys##name(__MAP(x,__SC_COMPAT_CAST,__VA_ARGS__)); \ | ||
| 61 | } | ||
| 62 | |||
| 63 | COMPAT_SYSCALL_WRAP2(creat, const char __user *, pathname, umode_t, mode); | ||
| 64 | COMPAT_SYSCALL_WRAP2(link, const char __user *, oldname, const char __user *, newname); | ||
| 65 | COMPAT_SYSCALL_WRAP1(unlink, const char __user *, pathname); | ||
| 66 | COMPAT_SYSCALL_WRAP1(chdir, const char __user *, filename); | ||
| 67 | COMPAT_SYSCALL_WRAP3(mknod, const char __user *, filename, umode_t, mode, unsigned, dev); | ||
| 68 | COMPAT_SYSCALL_WRAP2(chmod, const char __user *, filename, umode_t, mode); | ||
| 69 | COMPAT_SYSCALL_WRAP1(oldumount, char __user *, name); | ||
| 70 | COMPAT_SYSCALL_WRAP2(access, const char __user *, filename, int, mode); | ||
| 71 | COMPAT_SYSCALL_WRAP2(rename, const char __user *, oldname, const char __user *, newname); | ||
| 72 | COMPAT_SYSCALL_WRAP2(mkdir, const char __user *, pathname, umode_t, mode); | ||
| 73 | COMPAT_SYSCALL_WRAP1(rmdir, const char __user *, pathname); | ||
| 74 | COMPAT_SYSCALL_WRAP1(pipe, int __user *, fildes); | ||
| 75 | COMPAT_SYSCALL_WRAP1(brk, unsigned long, brk); | ||
| 76 | COMPAT_SYSCALL_WRAP2(signal, int, sig, __sighandler_t, handler); | ||
| 77 | COMPAT_SYSCALL_WRAP1(acct, const char __user *, name); | ||
| 78 | COMPAT_SYSCALL_WRAP2(umount, char __user *, name, int, flags); | ||
| 79 | COMPAT_SYSCALL_WRAP1(chroot, const char __user *, filename); | ||
| 80 | COMPAT_SYSCALL_WRAP3(sigsuspend, int, unused1, int, unused2, old_sigset_t, mask); | ||
| 81 | COMPAT_SYSCALL_WRAP2(sethostname, char __user *, name, int, len); | ||
| 82 | COMPAT_SYSCALL_WRAP2(symlink, const char __user *, old, const char __user *, new); | ||
| 83 | COMPAT_SYSCALL_WRAP3(readlink, const char __user *, path, char __user *, buf, int, bufsiz); | ||
| 84 | COMPAT_SYSCALL_WRAP1(uselib, const char __user *, library); | ||
| 85 | COMPAT_SYSCALL_WRAP2(swapon, const char __user *, specialfile, int, swap_flags); | ||
| 86 | COMPAT_SYSCALL_WRAP4(reboot, int, magic1, int, magic2, unsigned int, cmd, void __user *, arg); | ||
| 87 | COMPAT_SYSCALL_WRAP2(munmap, unsigned long, addr, size_t, len); | ||
| 88 | COMPAT_SYSCALL_WRAP3(syslog, int, type, char __user *, buf, int, len); | ||
| 89 | COMPAT_SYSCALL_WRAP1(swapoff, const char __user *, specialfile); | ||
| 90 | COMPAT_SYSCALL_WRAP2(setdomainname, char __user *, name, int, len); | ||
| 91 | COMPAT_SYSCALL_WRAP1(newuname, struct new_utsname __user *, name); | ||
| 92 | COMPAT_SYSCALL_WRAP3(mprotect, unsigned long, start, size_t, len, unsigned long, prot); | ||
| 93 | COMPAT_SYSCALL_WRAP3(init_module, void __user *, umod, unsigned long, len, const char __user *, uargs); | ||
| 94 | COMPAT_SYSCALL_WRAP2(delete_module, const char __user *, name_user, unsigned int, flags); | ||
| 95 | COMPAT_SYSCALL_WRAP4(quotactl, unsigned int, cmd, const char __user *, special, qid_t, id, void __user *, addr); | ||
| 96 | COMPAT_SYSCALL_WRAP2(bdflush, int, func, long, data); | ||
| 97 | COMPAT_SYSCALL_WRAP3(sysfs, int, option, unsigned long, arg1, unsigned long, arg2); | ||
| 98 | COMPAT_SYSCALL_WRAP5(llseek, unsigned int, fd, unsigned long, high, unsigned long, low, loff_t __user *, result, unsigned int, whence); | ||
| 99 | COMPAT_SYSCALL_WRAP3(msync, unsigned long, start, size_t, len, int, flags); | ||
| 100 | COMPAT_SYSCALL_WRAP2(mlock, unsigned long, start, size_t, len); | ||
| 101 | COMPAT_SYSCALL_WRAP2(munlock, unsigned long, start, size_t, len); | ||
| 102 | COMPAT_SYSCALL_WRAP2(sched_setparam, pid_t, pid, struct sched_param __user *, param); | ||
| 103 | COMPAT_SYSCALL_WRAP2(sched_getparam, pid_t, pid, struct sched_param __user *, param); | ||
| 104 | COMPAT_SYSCALL_WRAP3(sched_setscheduler, pid_t, pid, int, policy, struct sched_param __user *, param); | ||
| 105 | COMPAT_SYSCALL_WRAP5(mremap, unsigned long, addr, unsigned long, old_len, unsigned long, new_len, unsigned long, flags, unsigned long, new_addr); | ||
| 106 | COMPAT_SYSCALL_WRAP3(poll, struct pollfd __user *, ufds, unsigned int, nfds, int, timeout); | ||
| 107 | COMPAT_SYSCALL_WRAP5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, unsigned long, arg4, unsigned long, arg5); | ||
| 108 | COMPAT_SYSCALL_WRAP2(getcwd, char __user *, buf, unsigned long, size); | ||
| 109 | COMPAT_SYSCALL_WRAP2(capget, cap_user_header_t, header, cap_user_data_t, dataptr); | ||
| 110 | COMPAT_SYSCALL_WRAP2(capset, cap_user_header_t, header, const cap_user_data_t, data); | ||
| 111 | COMPAT_SYSCALL_WRAP3(lchown, const char __user *, filename, uid_t, user, gid_t, group); | ||
| 112 | COMPAT_SYSCALL_WRAP2(getgroups, int, gidsetsize, gid_t __user *, grouplist); | ||
| 113 | COMPAT_SYSCALL_WRAP2(setgroups, int, gidsetsize, gid_t __user *, grouplist); | ||
| 114 | COMPAT_SYSCALL_WRAP3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __user *, suid); | ||
| 115 | COMPAT_SYSCALL_WRAP3(getresgid, gid_t __user *, rgid, gid_t __user *, egid, gid_t __user *, sgid); | ||
| 116 | COMPAT_SYSCALL_WRAP3(chown, const char __user *, filename, uid_t, user, gid_t, group); | ||
| 117 | COMPAT_SYSCALL_WRAP2(pivot_root, const char __user *, new_root, const char __user *, put_old); | ||
| 118 | COMPAT_SYSCALL_WRAP3(mincore, unsigned long, start, size_t, len, unsigned char __user *, vec); | ||
| 119 | COMPAT_SYSCALL_WRAP3(madvise, unsigned long, start, size_t, len, int, behavior); | ||
| 120 | COMPAT_SYSCALL_WRAP5(setxattr, const char __user *, path, const char __user *, name, const void __user *, value, size_t, size, int, flags); | ||
| 121 | COMPAT_SYSCALL_WRAP5(lsetxattr, const char __user *, path, const char __user *, name, const void __user *, value, size_t, size, int, flags); | ||
| 122 | COMPAT_SYSCALL_WRAP5(fsetxattr, int, fd, const char __user *, name, const void __user *, value, size_t, size, int, flags); | ||
| 123 | COMPAT_SYSCALL_WRAP3(getdents64, unsigned int, fd, struct linux_dirent64 __user *, dirent, unsigned int, count); | ||
| 124 | COMPAT_SYSCALL_WRAP4(getxattr, const char __user *, path, const char __user *, name, void __user *, value, size_t, size); | ||
| 125 | COMPAT_SYSCALL_WRAP4(lgetxattr, const char __user *, path, const char __user *, name, void __user *, value, size_t, size); | ||
| 126 | COMPAT_SYSCALL_WRAP4(fgetxattr, int, fd, const char __user *, name, void __user *, value, size_t, size); | ||
| 127 | COMPAT_SYSCALL_WRAP3(listxattr, const char __user *, path, char __user *, list, size_t, size); | ||
| 128 | COMPAT_SYSCALL_WRAP3(llistxattr, const char __user *, path, char __user *, list, size_t, size); | ||
| 129 | COMPAT_SYSCALL_WRAP3(flistxattr, int, fd, char __user *, list, size_t, size); | ||
| 130 | COMPAT_SYSCALL_WRAP2(removexattr, const char __user *, path, const char __user *, name); | ||
| 131 | COMPAT_SYSCALL_WRAP2(lremovexattr, const char __user *, path, const char __user *, name); | ||
| 132 | COMPAT_SYSCALL_WRAP2(fremovexattr, int, fd, const char __user *, name); | ||
| 133 | COMPAT_SYSCALL_WRAP1(set_tid_address, int __user *, tidptr); | ||
| 134 | COMPAT_SYSCALL_WRAP4(epoll_ctl, int, epfd, int, op, int, fd, struct epoll_event __user *, event); | ||
| 135 | COMPAT_SYSCALL_WRAP4(epoll_wait, int, epfd, struct epoll_event __user *, events, int, maxevents, int, timeout); | ||
| 136 | COMPAT_SYSCALL_WRAP1(io_destroy, aio_context_t, ctx); | ||
| 137 | COMPAT_SYSCALL_WRAP3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb, struct io_event __user *, result); | ||
| 138 | COMPAT_SYSCALL_WRAP1(mq_unlink, const char __user *, name); | ||
| 139 | COMPAT_SYSCALL_WRAP5(add_key, const char __user *, tp, const char __user *, dsc, const void __user *, pld, size_t, len, key_serial_t, id); | ||
| 140 | COMPAT_SYSCALL_WRAP4(request_key, const char __user *, tp, const char __user *, dsc, const char __user *, info, key_serial_t, id); | ||
| 141 | COMPAT_SYSCALL_WRAP5(remap_file_pages, unsigned long, start, unsigned long, size, unsigned long, prot, unsigned long, pgoff, unsigned long, flags); | ||
| 142 | COMPAT_SYSCALL_WRAP3(inotify_add_watch, int, fd, const char __user *, path, u32, mask); | ||
| 143 | COMPAT_SYSCALL_WRAP3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode); | ||
| 144 | COMPAT_SYSCALL_WRAP4(mknodat, int, dfd, const char __user *, filename, umode_t, mode, unsigned, dev); | ||
| 145 | COMPAT_SYSCALL_WRAP5(fchownat, int, dfd, const char __user *, filename, uid_t, user, gid_t, group, int, flag); | ||
| 146 | COMPAT_SYSCALL_WRAP3(unlinkat, int, dfd, const char __user *, pathname, int, flag); | ||
| 147 | COMPAT_SYSCALL_WRAP4(renameat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname); | ||
| 148 | COMPAT_SYSCALL_WRAP5(linkat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, int, flags); | ||
| 149 | COMPAT_SYSCALL_WRAP3(symlinkat, const char __user *, oldname, int, newdfd, const char __user *, newname); | ||
| 150 | COMPAT_SYSCALL_WRAP4(readlinkat, int, dfd, const char __user *, path, char __user *, buf, int, bufsiz); | ||
| 151 | COMPAT_SYSCALL_WRAP3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode); | ||
| 152 | COMPAT_SYSCALL_WRAP3(faccessat, int, dfd, const char __user *, filename, int, mode); | ||
| 153 | COMPAT_SYSCALL_WRAP1(unshare, unsigned long, unshare_flags); | ||
| 154 | COMPAT_SYSCALL_WRAP6(splice, int, fd_in, loff_t __user *, off_in, int, fd_out, loff_t __user *, off_out, size_t, len, unsigned int, flags); | ||
| 155 | COMPAT_SYSCALL_WRAP4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags); | ||
| 156 | COMPAT_SYSCALL_WRAP3(getcpu, unsigned __user *, cpu, unsigned __user *, node, struct getcpu_cache __user *, cache); | ||
| 157 | COMPAT_SYSCALL_WRAP2(pipe2, int __user *, fildes, int, flags); | ||
| 158 | COMPAT_SYSCALL_WRAP5(perf_event_open, struct perf_event_attr __user *, attr_uptr, pid_t, pid, int, cpu, int, group_fd, unsigned long, flags); | ||
| 159 | COMPAT_SYSCALL_WRAP5(clone, unsigned long, newsp, unsigned long, clone_flags, int __user *, parent_tidptr, int __user *, child_tidptr, unsigned long, tls); | ||
| 160 | COMPAT_SYSCALL_WRAP4(prlimit64, pid_t, pid, unsigned int, resource, const struct rlimit64 __user *, new_rlim, struct rlimit64 __user *, old_rlim); | ||
| 161 | COMPAT_SYSCALL_WRAP5(name_to_handle_at, int, dfd, const char __user *, name, struct file_handle __user *, handle, int __user *, mnt_id, int, flag); | ||
| 162 | COMPAT_SYSCALL_WRAP5(kcmp, pid_t, pid1, pid_t, pid2, int, type, unsigned long, idx1, unsigned long, idx2); | ||
| 163 | COMPAT_SYSCALL_WRAP3(finit_module, int, fd, const char __user *, uargs, int, flags); | ||
| 164 | COMPAT_SYSCALL_WRAP3(sched_setattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, flags); | ||
| 165 | COMPAT_SYSCALL_WRAP4(sched_getattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, size, unsigned int, flags); | ||
| 166 | COMPAT_SYSCALL_WRAP5(renameat2, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, unsigned int, flags); | ||
| 167 | COMPAT_SYSCALL_WRAP3(seccomp, unsigned int, op, unsigned int, flags, void __user *, uargs) | ||
| 168 | COMPAT_SYSCALL_WRAP3(getrandom, char __user *, buf, size_t, count, unsigned int, flags) | ||
| 169 | COMPAT_SYSCALL_WRAP2(memfd_create, const char __user *, uname, unsigned int, flags) | ||
| 170 | COMPAT_SYSCALL_WRAP3(bpf, int, cmd, union bpf_attr *, attr, unsigned int, size); | ||
| 171 | COMPAT_SYSCALL_WRAP3(s390_pci_mmio_write, const unsigned long, mmio_addr, const void __user *, user_buffer, const size_t, length); | ||
| 172 | COMPAT_SYSCALL_WRAP3(s390_pci_mmio_read, const unsigned long, mmio_addr, void __user *, user_buffer, const size_t, length); | ||
| 173 | COMPAT_SYSCALL_WRAP4(socketpair, int, family, int, type, int, protocol, int __user *, usockvec); | ||
| 174 | COMPAT_SYSCALL_WRAP3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen); | ||
| 175 | COMPAT_SYSCALL_WRAP3(connect, int, fd, struct sockaddr __user *, uservaddr, int, addrlen); | ||
| 176 | COMPAT_SYSCALL_WRAP4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr, int __user *, upeer_addrlen, int, flags); | ||
| 177 | COMPAT_SYSCALL_WRAP3(getsockname, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len); | ||
| 178 | COMPAT_SYSCALL_WRAP3(getpeername, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len); | ||
| 179 | COMPAT_SYSCALL_WRAP6(sendto, int, fd, void __user *, buff, size_t, len, unsigned int, flags, struct sockaddr __user *, addr, int, addr_len); | ||
| 180 | COMPAT_SYSCALL_WRAP3(mlock2, unsigned long, start, size_t, len, int, flags); | ||
| 181 | COMPAT_SYSCALL_WRAP6(copy_file_range, int, fd_in, loff_t __user *, off_in, int, fd_out, loff_t __user *, off_out, size_t, len, unsigned int, flags); | ||
| 182 | COMPAT_SYSCALL_WRAP2(s390_guarded_storage, int, command, struct gs_cb *, gs_cb); | ||
| 183 | COMPAT_SYSCALL_WRAP5(statx, int, dfd, const char __user *, path, unsigned, flags, unsigned, mask, struct statx __user *, buffer); | ||
| 184 | COMPAT_SYSCALL_WRAP4(s390_sthyi, unsigned long, code, void __user *, info, u64 __user *, rc, unsigned long, flags); | ||
| 185 | COMPAT_SYSCALL_WRAP5(kexec_file_load, int, kernel_fd, int, initrd_fd, unsigned long, cmdline_len, const char __user *, cmdline_ptr, unsigned long, flags) | ||
| 186 | COMPAT_SYSCALL_WRAP4(rseq, struct rseq __user *, rseq, u32, rseq_len, int, flags, u32, sig) | ||
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index d374f9b218b4..0ebf08c3b35e 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c | |||
| @@ -1056,12 +1056,6 @@ int debug_register_view(debug_info_t *id, struct debug_view *view) | |||
| 1056 | mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); | 1056 | mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); |
| 1057 | pde = debugfs_create_file(view->name, mode, id->debugfs_root_entry, | 1057 | pde = debugfs_create_file(view->name, mode, id->debugfs_root_entry, |
| 1058 | id, &debug_file_ops); | 1058 | id, &debug_file_ops); |
| 1059 | if (!pde) { | ||
| 1060 | pr_err("Registering view %s/%s failed due to out of " | ||
| 1061 | "memory\n", id->name, view->name); | ||
| 1062 | rc = -1; | ||
| 1063 | goto out; | ||
| 1064 | } | ||
| 1065 | spin_lock_irqsave(&id->lock, flags); | 1059 | spin_lock_irqsave(&id->lock, flags); |
| 1066 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { | 1060 | for (i = 0; i < DEBUG_MAX_VIEWS; i++) { |
| 1067 | if (!id->views[i]) | 1061 | if (!id->views[i]) |
diff --git a/arch/s390/kernel/diag.c b/arch/s390/kernel/diag.c index 53a5316cc4b7..7edaa733a77f 100644 --- a/arch/s390/kernel/diag.c +++ b/arch/s390/kernel/diag.c | |||
| @@ -45,6 +45,7 @@ static const struct diag_desc diag_map[NR_DIAG_STAT] = { | |||
| 45 | [DIAG_STAT_X2FC] = { .code = 0x2fc, .name = "Guest Performance Data" }, | 45 | [DIAG_STAT_X2FC] = { .code = 0x2fc, .name = "Guest Performance Data" }, |
| 46 | [DIAG_STAT_X304] = { .code = 0x304, .name = "Partition-Resource Service" }, | 46 | [DIAG_STAT_X304] = { .code = 0x304, .name = "Partition-Resource Service" }, |
| 47 | [DIAG_STAT_X308] = { .code = 0x308, .name = "List-Directed IPL" }, | 47 | [DIAG_STAT_X308] = { .code = 0x308, .name = "List-Directed IPL" }, |
| 48 | [DIAG_STAT_X318] = { .code = 0x318, .name = "CP Name and Version Codes" }, | ||
| 48 | [DIAG_STAT_X500] = { .code = 0x500, .name = "Virtio Service" }, | 49 | [DIAG_STAT_X500] = { .code = 0x500, .name = "Virtio Service" }, |
| 49 | }; | 50 | }; |
| 50 | 51 | ||
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index a8c7789b246b..d6edf45f93b9 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
| @@ -164,8 +164,6 @@ static noinline __init void setup_lowcore_early(void) | |||
| 164 | 164 | ||
| 165 | static noinline __init void setup_facility_list(void) | 165 | static noinline __init void setup_facility_list(void) |
| 166 | { | 166 | { |
| 167 | stfle(S390_lowcore.stfle_fac_list, | ||
| 168 | ARRAY_SIZE(S390_lowcore.stfle_fac_list)); | ||
| 169 | memcpy(S390_lowcore.alt_stfle_fac_list, | 167 | memcpy(S390_lowcore.alt_stfle_fac_list, |
| 170 | S390_lowcore.stfle_fac_list, | 168 | S390_lowcore.stfle_fac_list, |
| 171 | sizeof(S390_lowcore.alt_stfle_fac_list)); | 169 | sizeof(S390_lowcore.alt_stfle_fac_list)); |
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 39191a0feed1..583d65ef5007 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
| @@ -1512,7 +1512,7 @@ cleanup_critical: | |||
| 1512 | .quad .Lsie_skip - .Lsie_entry | 1512 | .quad .Lsie_skip - .Lsie_entry |
| 1513 | #endif | 1513 | #endif |
| 1514 | .section .rodata, "a" | 1514 | .section .rodata, "a" |
| 1515 | #define SYSCALL(esame,emu) .long esame | 1515 | #define SYSCALL(esame,emu) .long __s390x_ ## esame |
| 1516 | .globl sys_call_table | 1516 | .globl sys_call_table |
| 1517 | sys_call_table: | 1517 | sys_call_table: |
| 1518 | #include "asm/syscall_table.h" | 1518 | #include "asm/syscall_table.h" |
| @@ -1520,7 +1520,7 @@ sys_call_table: | |||
| 1520 | 1520 | ||
| 1521 | #ifdef CONFIG_COMPAT | 1521 | #ifdef CONFIG_COMPAT |
| 1522 | 1522 | ||
| 1523 | #define SYSCALL(esame,emu) .long emu | 1523 | #define SYSCALL(esame,emu) .long __s390_ ## emu |
| 1524 | .globl sys_call_table_emu | 1524 | .globl sys_call_table_emu |
| 1525 | sys_call_table_emu: | 1525 | sys_call_table_emu: |
| 1526 | #include "asm/syscall_table.h" | 1526 | #include "asm/syscall_table.h" |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 57bba24b1c27..56491e636eab 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
| @@ -27,8 +27,6 @@ ENTRY(startup_continue) | |||
| 27 | mvc 0(16,%r1),__LC_BOOT_CLOCK | 27 | mvc 0(16,%r1),__LC_BOOT_CLOCK |
| 28 | larl %r13,.LPG1 # get base | 28 | larl %r13,.LPG1 # get base |
| 29 | lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers | 29 | lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers |
| 30 | lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area | ||
| 31 | # move IPL device to lowcore | ||
| 32 | larl %r0,boot_vdso_data | 30 | larl %r0,boot_vdso_data |
| 33 | stg %r0,__LC_VDSO_PER_CPU | 31 | stg %r0,__LC_VDSO_PER_CPU |
| 34 | # | 32 | # |
diff --git a/arch/s390/kernel/kdebugfs.c b/arch/s390/kernel/kdebugfs.c index 2c46bd6c6fd2..33130c7daf55 100644 --- a/arch/s390/kernel/kdebugfs.c +++ b/arch/s390/kernel/kdebugfs.c | |||
| @@ -9,8 +9,6 @@ EXPORT_SYMBOL(arch_debugfs_dir); | |||
| 9 | static int __init arch_kdebugfs_init(void) | 9 | static int __init arch_kdebugfs_init(void) |
| 10 | { | 10 | { |
| 11 | arch_debugfs_dir = debugfs_create_dir("s390", NULL); | 11 | arch_debugfs_dir = debugfs_create_dir("s390", NULL); |
| 12 | if (IS_ERR(arch_debugfs_dir)) | ||
| 13 | arch_debugfs_dir = NULL; | ||
| 14 | return 0; | 12 | return 0; |
| 15 | } | 13 | } |
| 16 | postcore_initcall(arch_kdebugfs_init); | 14 | postcore_initcall(arch_kdebugfs_init); |
diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c index d5523adeddbf..e1c54d28713a 100644 --- a/arch/s390/kernel/perf_cpum_cf.c +++ b/arch/s390/kernel/perf_cpum_cf.c | |||
| @@ -10,73 +10,11 @@ | |||
| 10 | 10 | ||
| 11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
| 12 | #include <linux/kernel_stat.h> | 12 | #include <linux/kernel_stat.h> |
| 13 | #include <linux/perf_event.h> | ||
| 14 | #include <linux/percpu.h> | 13 | #include <linux/percpu.h> |
| 15 | #include <linux/notifier.h> | 14 | #include <linux/notifier.h> |
| 16 | #include <linux/init.h> | 15 | #include <linux/init.h> |
| 17 | #include <linux/export.h> | 16 | #include <linux/export.h> |
| 18 | #include <asm/ctl_reg.h> | 17 | #include <asm/cpu_mcf.h> |
| 19 | #include <asm/irq.h> | ||
| 20 | #include <asm/cpu_mf.h> | ||
| 21 | |||
| 22 | enum cpumf_ctr_set { | ||
| 23 | CPUMF_CTR_SET_BASIC = 0, /* Basic Counter Set */ | ||
| 24 | CPUMF_CTR_SET_USER = 1, /* Problem-State Counter Set */ | ||
| 25 | CPUMF_CTR_SET_CRYPTO = 2, /* Crypto-Activity Counter Set */ | ||
| 26 | CPUMF_CTR_SET_EXT = 3, /* Extended Counter Set */ | ||
| 27 | CPUMF_CTR_SET_MT_DIAG = 4, /* MT-diagnostic Counter Set */ | ||
| 28 | |||
| 29 | /* Maximum number of counter sets */ | ||
| 30 | CPUMF_CTR_SET_MAX, | ||
| 31 | }; | ||
| 32 | |||
| 33 | #define CPUMF_LCCTL_ENABLE_SHIFT 16 | ||
| 34 | #define CPUMF_LCCTL_ACTCTL_SHIFT 0 | ||
| 35 | static const u64 cpumf_state_ctl[CPUMF_CTR_SET_MAX] = { | ||
| 36 | [CPUMF_CTR_SET_BASIC] = 0x02, | ||
| 37 | [CPUMF_CTR_SET_USER] = 0x04, | ||
| 38 | [CPUMF_CTR_SET_CRYPTO] = 0x08, | ||
| 39 | [CPUMF_CTR_SET_EXT] = 0x01, | ||
| 40 | [CPUMF_CTR_SET_MT_DIAG] = 0x20, | ||
| 41 | }; | ||
| 42 | |||
| 43 | static void ctr_set_enable(u64 *state, int ctr_set) | ||
| 44 | { | ||
| 45 | *state |= cpumf_state_ctl[ctr_set] << CPUMF_LCCTL_ENABLE_SHIFT; | ||
| 46 | } | ||
| 47 | static void ctr_set_disable(u64 *state, int ctr_set) | ||
| 48 | { | ||
| 49 | *state &= ~(cpumf_state_ctl[ctr_set] << CPUMF_LCCTL_ENABLE_SHIFT); | ||
| 50 | } | ||
| 51 | static void ctr_set_start(u64 *state, int ctr_set) | ||
| 52 | { | ||
| 53 | *state |= cpumf_state_ctl[ctr_set] << CPUMF_LCCTL_ACTCTL_SHIFT; | ||
| 54 | } | ||
| 55 | static void ctr_set_stop(u64 *state, int ctr_set) | ||
| 56 | { | ||
| 57 | *state &= ~(cpumf_state_ctl[ctr_set] << CPUMF_LCCTL_ACTCTL_SHIFT); | ||
| 58 | } | ||
| 59 | |||
| 60 | /* Local CPUMF event structure */ | ||
| 61 | struct cpu_hw_events { | ||
| 62 | struct cpumf_ctr_info info; | ||
| 63 | atomic_t ctr_set[CPUMF_CTR_SET_MAX]; | ||
| 64 | u64 state, tx_state; | ||
| 65 | unsigned int flags; | ||
| 66 | unsigned int txn_flags; | ||
| 67 | }; | ||
| 68 | static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { | ||
| 69 | .ctr_set = { | ||
| 70 | [CPUMF_CTR_SET_BASIC] = ATOMIC_INIT(0), | ||
| 71 | [CPUMF_CTR_SET_USER] = ATOMIC_INIT(0), | ||
| 72 | [CPUMF_CTR_SET_CRYPTO] = ATOMIC_INIT(0), | ||
| 73 | [CPUMF_CTR_SET_EXT] = ATOMIC_INIT(0), | ||
| 74 | [CPUMF_CTR_SET_MT_DIAG] = ATOMIC_INIT(0), | ||
| 75 | }, | ||
| 76 | .state = 0, | ||
| 77 | .flags = 0, | ||
| 78 | .txn_flags = 0, | ||
| 79 | }; | ||
| 80 | 18 | ||
| 81 | static enum cpumf_ctr_set get_counter_set(u64 event) | 19 | static enum cpumf_ctr_set get_counter_set(u64 event) |
| 82 | { | 20 | { |
| @@ -98,11 +36,11 @@ static enum cpumf_ctr_set get_counter_set(u64 event) | |||
| 98 | 36 | ||
| 99 | static int validate_ctr_version(const struct hw_perf_event *hwc) | 37 | static int validate_ctr_version(const struct hw_perf_event *hwc) |
| 100 | { | 38 | { |
| 101 | struct cpu_hw_events *cpuhw; | 39 | struct cpu_cf_events *cpuhw; |
| 102 | int err = 0; | 40 | int err = 0; |
| 103 | u16 mtdiag_ctl; | 41 | u16 mtdiag_ctl; |
| 104 | 42 | ||
| 105 | cpuhw = &get_cpu_var(cpu_hw_events); | 43 | cpuhw = &get_cpu_var(cpu_cf_events); |
| 106 | 44 | ||
| 107 | /* check required version for counter sets */ | 45 | /* check required version for counter sets */ |
| 108 | switch (hwc->config_base) { | 46 | switch (hwc->config_base) { |
| @@ -135,7 +73,7 @@ static int validate_ctr_version(const struct hw_perf_event *hwc) | |||
| 135 | * Thus, the counters can only be used if SMT is on and the | 73 | * Thus, the counters can only be used if SMT is on and the |
| 136 | * counter set is enabled and active. | 74 | * counter set is enabled and active. |
| 137 | */ | 75 | */ |
| 138 | mtdiag_ctl = cpumf_state_ctl[CPUMF_CTR_SET_MT_DIAG]; | 76 | mtdiag_ctl = cpumf_ctr_ctl[CPUMF_CTR_SET_MT_DIAG]; |
| 139 | if (!((cpuhw->info.auth_ctl & mtdiag_ctl) && | 77 | if (!((cpuhw->info.auth_ctl & mtdiag_ctl) && |
| 140 | (cpuhw->info.enable_ctl & mtdiag_ctl) && | 78 | (cpuhw->info.enable_ctl & mtdiag_ctl) && |
| 141 | (cpuhw->info.act_ctl & mtdiag_ctl))) | 79 | (cpuhw->info.act_ctl & mtdiag_ctl))) |
| @@ -143,28 +81,28 @@ static int validate_ctr_version(const struct hw_perf_event *hwc) | |||
| 143 | break; | 81 | break; |
| 144 | } | 82 | } |
| 145 | 83 | ||
| 146 | put_cpu_var(cpu_hw_events); | 84 | put_cpu_var(cpu_cf_events); |
| 147 | return err; | 85 | return err; |
| 148 | } | 86 | } |
| 149 | 87 | ||
| 150 | static int validate_ctr_auth(const struct hw_perf_event *hwc) | 88 | static int validate_ctr_auth(const struct hw_perf_event *hwc) |
| 151 | { | 89 | { |
| 152 | struct cpu_hw_events *cpuhw; | 90 | struct cpu_cf_events *cpuhw; |
| 153 | u64 ctrs_state; | 91 | u64 ctrs_state; |
| 154 | int err = 0; | 92 | int err = 0; |
| 155 | 93 | ||
| 156 | cpuhw = &get_cpu_var(cpu_hw_events); | 94 | cpuhw = &get_cpu_var(cpu_cf_events); |
| 157 | 95 | ||
| 158 | /* Check authorization for cpu counter sets. | 96 | /* Check authorization for cpu counter sets. |
| 159 | * If the particular CPU counter set is not authorized, | 97 | * If the particular CPU counter set is not authorized, |
| 160 | * return with -ENOENT in order to fall back to other | 98 | * return with -ENOENT in order to fall back to other |
| 161 | * PMUs that might suffice the event request. | 99 | * PMUs that might suffice the event request. |
| 162 | */ | 100 | */ |
| 163 | ctrs_state = cpumf_state_ctl[hwc->config_base]; | 101 | ctrs_state = cpumf_ctr_ctl[hwc->config_base]; |
| 164 | if (!(ctrs_state & cpuhw->info.auth_ctl)) | 102 | if (!(ctrs_state & cpuhw->info.auth_ctl)) |
| 165 | err = -ENOENT; | 103 | err = -ENOENT; |
| 166 | 104 | ||
| 167 | put_cpu_var(cpu_hw_events); | 105 | put_cpu_var(cpu_cf_events); |
| 168 | return err; | 106 | return err; |
| 169 | } | 107 | } |
| 170 | 108 | ||
| @@ -175,7 +113,7 @@ static int validate_ctr_auth(const struct hw_perf_event *hwc) | |||
| 175 | */ | 113 | */ |
| 176 | static void cpumf_pmu_enable(struct pmu *pmu) | 114 | static void cpumf_pmu_enable(struct pmu *pmu) |
| 177 | { | 115 | { |
| 178 | struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); | 116 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); |
| 179 | int err; | 117 | int err; |
| 180 | 118 | ||
| 181 | if (cpuhw->flags & PMU_F_ENABLED) | 119 | if (cpuhw->flags & PMU_F_ENABLED) |
| @@ -198,7 +136,7 @@ static void cpumf_pmu_enable(struct pmu *pmu) | |||
| 198 | */ | 136 | */ |
| 199 | static void cpumf_pmu_disable(struct pmu *pmu) | 137 | static void cpumf_pmu_disable(struct pmu *pmu) |
| 200 | { | 138 | { |
| 201 | struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); | 139 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); |
| 202 | int err; | 140 | int err; |
| 203 | u64 inactive; | 141 | u64 inactive; |
| 204 | 142 | ||
| @@ -222,86 +160,13 @@ static atomic_t num_events = ATOMIC_INIT(0); | |||
| 222 | /* Used to avoid races in calling reserve/release_cpumf_hardware */ | 160 | /* Used to avoid races in calling reserve/release_cpumf_hardware */ |
| 223 | static DEFINE_MUTEX(pmc_reserve_mutex); | 161 | static DEFINE_MUTEX(pmc_reserve_mutex); |
| 224 | 162 | ||
| 225 | /* CPU-measurement alerts for the counter facility */ | ||
| 226 | static void cpumf_measurement_alert(struct ext_code ext_code, | ||
| 227 | unsigned int alert, unsigned long unused) | ||
| 228 | { | ||
| 229 | struct cpu_hw_events *cpuhw; | ||
| 230 | |||
| 231 | if (!(alert & CPU_MF_INT_CF_MASK)) | ||
| 232 | return; | ||
| 233 | |||
| 234 | inc_irq_stat(IRQEXT_CMC); | ||
| 235 | cpuhw = this_cpu_ptr(&cpu_hw_events); | ||
| 236 | |||
| 237 | /* Measurement alerts are shared and might happen when the PMU | ||
| 238 | * is not reserved. Ignore these alerts in this case. */ | ||
| 239 | if (!(cpuhw->flags & PMU_F_RESERVED)) | ||
| 240 | return; | ||
| 241 | |||
| 242 | /* counter authorization change alert */ | ||
| 243 | if (alert & CPU_MF_INT_CF_CACA) | ||
| 244 | qctri(&cpuhw->info); | ||
| 245 | |||
| 246 | /* loss of counter data alert */ | ||
| 247 | if (alert & CPU_MF_INT_CF_LCDA) | ||
| 248 | pr_err("CPU[%i] Counter data was lost\n", smp_processor_id()); | ||
| 249 | |||
| 250 | /* loss of MT counter data alert */ | ||
| 251 | if (alert & CPU_MF_INT_CF_MTDA) | ||
| 252 | pr_warn("CPU[%i] MT counter data was lost\n", | ||
| 253 | smp_processor_id()); | ||
| 254 | } | ||
| 255 | |||
| 256 | #define PMC_INIT 0 | ||
| 257 | #define PMC_RELEASE 1 | ||
| 258 | static void setup_pmc_cpu(void *flags) | ||
| 259 | { | ||
| 260 | struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); | ||
| 261 | |||
| 262 | switch (*((int *) flags)) { | ||
| 263 | case PMC_INIT: | ||
| 264 | memset(&cpuhw->info, 0, sizeof(cpuhw->info)); | ||
| 265 | qctri(&cpuhw->info); | ||
| 266 | cpuhw->flags |= PMU_F_RESERVED; | ||
| 267 | break; | ||
| 268 | |||
| 269 | case PMC_RELEASE: | ||
| 270 | cpuhw->flags &= ~PMU_F_RESERVED; | ||
| 271 | break; | ||
| 272 | } | ||
| 273 | |||
| 274 | /* Disable CPU counter sets */ | ||
| 275 | lcctl(0); | ||
| 276 | } | ||
| 277 | |||
| 278 | /* Initialize the CPU-measurement facility */ | ||
| 279 | static int reserve_pmc_hardware(void) | ||
| 280 | { | ||
| 281 | int flags = PMC_INIT; | ||
| 282 | |||
| 283 | on_each_cpu(setup_pmc_cpu, &flags, 1); | ||
| 284 | irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT); | ||
| 285 | |||
| 286 | return 0; | ||
| 287 | } | ||
| 288 | |||
| 289 | /* Release the CPU-measurement facility */ | ||
| 290 | static void release_pmc_hardware(void) | ||
| 291 | { | ||
| 292 | int flags = PMC_RELEASE; | ||
| 293 | |||
| 294 | on_each_cpu(setup_pmc_cpu, &flags, 1); | ||
| 295 | irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); | ||
| 296 | } | ||
| 297 | |||
| 298 | /* Release the PMU if event is the last perf event */ | 163 | /* Release the PMU if event is the last perf event */ |
| 299 | static void hw_perf_event_destroy(struct perf_event *event) | 164 | static void hw_perf_event_destroy(struct perf_event *event) |
| 300 | { | 165 | { |
| 301 | if (!atomic_add_unless(&num_events, -1, 1)) { | 166 | if (!atomic_add_unless(&num_events, -1, 1)) { |
| 302 | mutex_lock(&pmc_reserve_mutex); | 167 | mutex_lock(&pmc_reserve_mutex); |
| 303 | if (atomic_dec_return(&num_events) == 0) | 168 | if (atomic_dec_return(&num_events) == 0) |
| 304 | release_pmc_hardware(); | 169 | __kernel_cpumcf_end(); |
| 305 | mutex_unlock(&pmc_reserve_mutex); | 170 | mutex_unlock(&pmc_reserve_mutex); |
| 306 | } | 171 | } |
| 307 | } | 172 | } |
| @@ -332,7 +197,7 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
| 332 | struct perf_event_attr *attr = &event->attr; | 197 | struct perf_event_attr *attr = &event->attr; |
| 333 | struct hw_perf_event *hwc = &event->hw; | 198 | struct hw_perf_event *hwc = &event->hw; |
| 334 | enum cpumf_ctr_set set; | 199 | enum cpumf_ctr_set set; |
| 335 | int err; | 200 | int err = 0; |
| 336 | u64 ev; | 201 | u64 ev; |
| 337 | 202 | ||
| 338 | switch (attr->type) { | 203 | switch (attr->type) { |
| @@ -402,12 +267,14 @@ static int __hw_perf_event_init(struct perf_event *event) | |||
| 402 | /* Initialize for using the CPU-measurement counter facility */ | 267 | /* Initialize for using the CPU-measurement counter facility */ |
| 403 | if (!atomic_inc_not_zero(&num_events)) { | 268 | if (!atomic_inc_not_zero(&num_events)) { |
| 404 | mutex_lock(&pmc_reserve_mutex); | 269 | mutex_lock(&pmc_reserve_mutex); |
| 405 | if (atomic_read(&num_events) == 0 && reserve_pmc_hardware()) | 270 | if (atomic_read(&num_events) == 0 && __kernel_cpumcf_begin()) |
| 406 | err = -EBUSY; | 271 | err = -EBUSY; |
| 407 | else | 272 | else |
| 408 | atomic_inc(&num_events); | 273 | atomic_inc(&num_events); |
| 409 | mutex_unlock(&pmc_reserve_mutex); | 274 | mutex_unlock(&pmc_reserve_mutex); |
| 410 | } | 275 | } |
| 276 | if (err) | ||
| 277 | return err; | ||
| 411 | event->destroy = hw_perf_event_destroy; | 278 | event->destroy = hw_perf_event_destroy; |
| 412 | 279 | ||
| 413 | /* Finally, validate version and authorization of the counter set */ | 280 | /* Finally, validate version and authorization of the counter set */ |
| @@ -488,7 +355,7 @@ static void cpumf_pmu_read(struct perf_event *event) | |||
| 488 | 355 | ||
| 489 | static void cpumf_pmu_start(struct perf_event *event, int flags) | 356 | static void cpumf_pmu_start(struct perf_event *event, int flags) |
| 490 | { | 357 | { |
| 491 | struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); | 358 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); |
| 492 | struct hw_perf_event *hwc = &event->hw; | 359 | struct hw_perf_event *hwc = &event->hw; |
| 493 | 360 | ||
| 494 | if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED))) | 361 | if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED))) |
| @@ -519,7 +386,7 @@ static void cpumf_pmu_start(struct perf_event *event, int flags) | |||
| 519 | 386 | ||
| 520 | static void cpumf_pmu_stop(struct perf_event *event, int flags) | 387 | static void cpumf_pmu_stop(struct perf_event *event, int flags) |
| 521 | { | 388 | { |
| 522 | struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); | 389 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); |
| 523 | struct hw_perf_event *hwc = &event->hw; | 390 | struct hw_perf_event *hwc = &event->hw; |
| 524 | 391 | ||
| 525 | if (!(hwc->state & PERF_HES_STOPPED)) { | 392 | if (!(hwc->state & PERF_HES_STOPPED)) { |
| @@ -540,7 +407,7 @@ static void cpumf_pmu_stop(struct perf_event *event, int flags) | |||
| 540 | 407 | ||
| 541 | static int cpumf_pmu_add(struct perf_event *event, int flags) | 408 | static int cpumf_pmu_add(struct perf_event *event, int flags) |
| 542 | { | 409 | { |
| 543 | struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); | 410 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); |
| 544 | 411 | ||
| 545 | /* Check authorization for the counter set to which this | 412 | /* Check authorization for the counter set to which this |
| 546 | * counter belongs. | 413 | * counter belongs. |
| @@ -564,7 +431,7 @@ static int cpumf_pmu_add(struct perf_event *event, int flags) | |||
| 564 | 431 | ||
| 565 | static void cpumf_pmu_del(struct perf_event *event, int flags) | 432 | static void cpumf_pmu_del(struct perf_event *event, int flags) |
| 566 | { | 433 | { |
| 567 | struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); | 434 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); |
| 568 | 435 | ||
| 569 | cpumf_pmu_stop(event, PERF_EF_UPDATE); | 436 | cpumf_pmu_stop(event, PERF_EF_UPDATE); |
| 570 | 437 | ||
| @@ -592,7 +459,7 @@ static void cpumf_pmu_del(struct perf_event *event, int flags) | |||
| 592 | */ | 459 | */ |
| 593 | static void cpumf_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags) | 460 | static void cpumf_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags) |
| 594 | { | 461 | { |
| 595 | struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); | 462 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); |
| 596 | 463 | ||
| 597 | WARN_ON_ONCE(cpuhw->txn_flags); /* txn already in flight */ | 464 | WARN_ON_ONCE(cpuhw->txn_flags); /* txn already in flight */ |
| 598 | 465 | ||
| @@ -612,7 +479,7 @@ static void cpumf_pmu_start_txn(struct pmu *pmu, unsigned int txn_flags) | |||
| 612 | static void cpumf_pmu_cancel_txn(struct pmu *pmu) | 479 | static void cpumf_pmu_cancel_txn(struct pmu *pmu) |
| 613 | { | 480 | { |
| 614 | unsigned int txn_flags; | 481 | unsigned int txn_flags; |
| 615 | struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); | 482 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); |
| 616 | 483 | ||
| 617 | WARN_ON_ONCE(!cpuhw->txn_flags); /* no txn in flight */ | 484 | WARN_ON_ONCE(!cpuhw->txn_flags); /* no txn in flight */ |
| 618 | 485 | ||
| @@ -633,7 +500,7 @@ static void cpumf_pmu_cancel_txn(struct pmu *pmu) | |||
| 633 | */ | 500 | */ |
| 634 | static int cpumf_pmu_commit_txn(struct pmu *pmu) | 501 | static int cpumf_pmu_commit_txn(struct pmu *pmu) |
| 635 | { | 502 | { |
| 636 | struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); | 503 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); |
| 637 | u64 state; | 504 | u64 state; |
| 638 | 505 | ||
| 639 | WARN_ON_ONCE(!cpuhw->txn_flags); /* no txn in flight */ | 506 | WARN_ON_ONCE(!cpuhw->txn_flags); /* no txn in flight */ |
| @@ -671,54 +538,17 @@ static struct pmu cpumf_pmu = { | |||
| 671 | .cancel_txn = cpumf_pmu_cancel_txn, | 538 | .cancel_txn = cpumf_pmu_cancel_txn, |
| 672 | }; | 539 | }; |
| 673 | 540 | ||
| 674 | static int cpumf_pmf_setup(unsigned int cpu, int flags) | ||
| 675 | { | ||
| 676 | local_irq_disable(); | ||
| 677 | setup_pmc_cpu(&flags); | ||
| 678 | local_irq_enable(); | ||
| 679 | return 0; | ||
| 680 | } | ||
| 681 | |||
| 682 | static int s390_pmu_online_cpu(unsigned int cpu) | ||
| 683 | { | ||
| 684 | return cpumf_pmf_setup(cpu, PMC_INIT); | ||
| 685 | } | ||
| 686 | |||
| 687 | static int s390_pmu_offline_cpu(unsigned int cpu) | ||
| 688 | { | ||
| 689 | return cpumf_pmf_setup(cpu, PMC_RELEASE); | ||
| 690 | } | ||
| 691 | |||
| 692 | static int __init cpumf_pmu_init(void) | 541 | static int __init cpumf_pmu_init(void) |
| 693 | { | 542 | { |
| 694 | int rc; | 543 | int rc; |
| 695 | 544 | ||
| 696 | if (!cpum_cf_avail()) | 545 | if (!kernel_cpumcf_avail()) |
| 697 | return -ENODEV; | 546 | return -ENODEV; |
| 698 | 547 | ||
| 699 | /* clear bit 15 of cr0 to unauthorize problem-state to | ||
| 700 | * extract measurement counters */ | ||
| 701 | ctl_clear_bit(0, 48); | ||
| 702 | |||
| 703 | /* register handler for measurement-alert interruptions */ | ||
| 704 | rc = register_external_irq(EXT_IRQ_MEASURE_ALERT, | ||
| 705 | cpumf_measurement_alert); | ||
| 706 | if (rc) { | ||
| 707 | pr_err("Registering for CPU-measurement alerts " | ||
| 708 | "failed with rc=%i\n", rc); | ||
| 709 | return rc; | ||
| 710 | } | ||
| 711 | |||
| 712 | cpumf_pmu.attr_groups = cpumf_cf_event_group(); | 548 | cpumf_pmu.attr_groups = cpumf_cf_event_group(); |
| 713 | rc = perf_pmu_register(&cpumf_pmu, "cpum_cf", PERF_TYPE_RAW); | 549 | rc = perf_pmu_register(&cpumf_pmu, "cpum_cf", PERF_TYPE_RAW); |
| 714 | if (rc) { | 550 | if (rc) |
| 715 | pr_err("Registering the cpum_cf PMU failed with rc=%i\n", rc); | 551 | pr_err("Registering the cpum_cf PMU failed with rc=%i\n", rc); |
| 716 | unregister_external_irq(EXT_IRQ_MEASURE_ALERT, | 552 | return rc; |
| 717 | cpumf_measurement_alert); | ||
| 718 | return rc; | ||
| 719 | } | ||
| 720 | return cpuhp_setup_state(CPUHP_AP_PERF_S390_CF_ONLINE, | ||
| 721 | "perf/s390/cf:online", | ||
| 722 | s390_pmu_online_cpu, s390_pmu_offline_cpu); | ||
| 723 | } | 553 | } |
| 724 | early_initcall(cpumf_pmu_init); | 554 | subsys_initcall(cpumf_pmu_init); |
diff --git a/arch/s390/kernel/perf_cpum_cf_common.c b/arch/s390/kernel/perf_cpum_cf_common.c new file mode 100644 index 000000000000..3bced89caffb --- /dev/null +++ b/arch/s390/kernel/perf_cpum_cf_common.c | |||
| @@ -0,0 +1,201 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * CPU-Measurement Counter Facility Support - Common Layer | ||
| 4 | * | ||
| 5 | * Copyright IBM Corp. 2019 | ||
| 6 | * Author(s): Hendrik Brueckner <brueckner@linux.ibm.com> | ||
| 7 | */ | ||
| 8 | #define KMSG_COMPONENT "cpum_cf_common" | ||
| 9 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
| 10 | |||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/kernel_stat.h> | ||
| 13 | #include <linux/percpu.h> | ||
| 14 | #include <linux/notifier.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/export.h> | ||
| 17 | #include <asm/ctl_reg.h> | ||
| 18 | #include <asm/irq.h> | ||
| 19 | #include <asm/cpu_mcf.h> | ||
| 20 | |||
| 21 | /* Per-CPU event structure for the counter facility */ | ||
| 22 | DEFINE_PER_CPU(struct cpu_cf_events, cpu_cf_events) = { | ||
| 23 | .ctr_set = { | ||
| 24 | [CPUMF_CTR_SET_BASIC] = ATOMIC_INIT(0), | ||
| 25 | [CPUMF_CTR_SET_USER] = ATOMIC_INIT(0), | ||
| 26 | [CPUMF_CTR_SET_CRYPTO] = ATOMIC_INIT(0), | ||
| 27 | [CPUMF_CTR_SET_EXT] = ATOMIC_INIT(0), | ||
| 28 | [CPUMF_CTR_SET_MT_DIAG] = ATOMIC_INIT(0), | ||
| 29 | }, | ||
| 30 | .alert = ATOMIC64_INIT(0), | ||
| 31 | .state = 0, | ||
| 32 | .flags = 0, | ||
| 33 | .txn_flags = 0, | ||
| 34 | }; | ||
| 35 | /* Indicator whether the CPU-Measurement Counter Facility Support is ready */ | ||
| 36 | static bool cpum_cf_initalized; | ||
| 37 | |||
| 38 | /* CPU-measurement alerts for the counter facility */ | ||
| 39 | static void cpumf_measurement_alert(struct ext_code ext_code, | ||
| 40 | unsigned int alert, unsigned long unused) | ||
| 41 | { | ||
| 42 | struct cpu_cf_events *cpuhw; | ||
| 43 | |||
| 44 | if (!(alert & CPU_MF_INT_CF_MASK)) | ||
| 45 | return; | ||
| 46 | |||
| 47 | inc_irq_stat(IRQEXT_CMC); | ||
| 48 | cpuhw = this_cpu_ptr(&cpu_cf_events); | ||
| 49 | |||
| 50 | /* Measurement alerts are shared and might happen when the PMU | ||
| 51 | * is not reserved. Ignore these alerts in this case. */ | ||
| 52 | if (!(cpuhw->flags & PMU_F_RESERVED)) | ||
| 53 | return; | ||
| 54 | |||
| 55 | /* counter authorization change alert */ | ||
| 56 | if (alert & CPU_MF_INT_CF_CACA) | ||
| 57 | qctri(&cpuhw->info); | ||
| 58 | |||
| 59 | /* loss of counter data alert */ | ||
| 60 | if (alert & CPU_MF_INT_CF_LCDA) | ||
| 61 | pr_err("CPU[%i] Counter data was lost\n", smp_processor_id()); | ||
| 62 | |||
| 63 | /* loss of MT counter data alert */ | ||
| 64 | if (alert & CPU_MF_INT_CF_MTDA) | ||
| 65 | pr_warn("CPU[%i] MT counter data was lost\n", | ||
| 66 | smp_processor_id()); | ||
| 67 | |||
| 68 | /* store alert for special handling by in-kernel users */ | ||
| 69 | atomic64_or(alert, &cpuhw->alert); | ||
| 70 | } | ||
| 71 | |||
| 72 | #define PMC_INIT 0 | ||
| 73 | #define PMC_RELEASE 1 | ||
| 74 | static void cpum_cf_setup_cpu(void *flags) | ||
| 75 | { | ||
| 76 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); | ||
| 77 | |||
| 78 | switch (*((int *) flags)) { | ||
| 79 | case PMC_INIT: | ||
| 80 | memset(&cpuhw->info, 0, sizeof(cpuhw->info)); | ||
| 81 | qctri(&cpuhw->info); | ||
| 82 | cpuhw->flags |= PMU_F_RESERVED; | ||
| 83 | break; | ||
| 84 | |||
| 85 | case PMC_RELEASE: | ||
| 86 | cpuhw->flags &= ~PMU_F_RESERVED; | ||
| 87 | break; | ||
| 88 | } | ||
| 89 | |||
| 90 | /* Disable CPU counter sets */ | ||
| 91 | lcctl(0); | ||
| 92 | } | ||
| 93 | |||
| 94 | bool kernel_cpumcf_avail(void) | ||
| 95 | { | ||
| 96 | return cpum_cf_initalized; | ||
| 97 | } | ||
| 98 | EXPORT_SYMBOL(kernel_cpumcf_avail); | ||
| 99 | |||
| 100 | |||
| 101 | /* Reserve/release functions for sharing perf hardware */ | ||
| 102 | static DEFINE_SPINLOCK(cpumcf_owner_lock); | ||
| 103 | static void *cpumcf_owner; | ||
| 104 | |||
| 105 | /* Initialize the CPU-measurement counter facility */ | ||
| 106 | int __kernel_cpumcf_begin(void) | ||
| 107 | { | ||
| 108 | int flags = PMC_INIT; | ||
| 109 | int err = 0; | ||
| 110 | |||
| 111 | spin_lock(&cpumcf_owner_lock); | ||
| 112 | if (cpumcf_owner) | ||
| 113 | err = -EBUSY; | ||
| 114 | else | ||
| 115 | cpumcf_owner = __builtin_return_address(0); | ||
| 116 | spin_unlock(&cpumcf_owner_lock); | ||
| 117 | if (err) | ||
| 118 | return err; | ||
| 119 | |||
| 120 | on_each_cpu(cpum_cf_setup_cpu, &flags, 1); | ||
| 121 | irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT); | ||
| 122 | |||
| 123 | return 0; | ||
| 124 | } | ||
| 125 | EXPORT_SYMBOL(__kernel_cpumcf_begin); | ||
| 126 | |||
| 127 | /* Obtain the CPU-measurement alerts for the counter facility */ | ||
| 128 | unsigned long kernel_cpumcf_alert(int clear) | ||
| 129 | { | ||
| 130 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); | ||
| 131 | unsigned long alert; | ||
| 132 | |||
| 133 | alert = atomic64_read(&cpuhw->alert); | ||
| 134 | if (clear) | ||
| 135 | atomic64_set(&cpuhw->alert, 0); | ||
| 136 | |||
| 137 | return alert; | ||
| 138 | } | ||
| 139 | EXPORT_SYMBOL(kernel_cpumcf_alert); | ||
| 140 | |||
| 141 | /* Release the CPU-measurement counter facility */ | ||
| 142 | void __kernel_cpumcf_end(void) | ||
| 143 | { | ||
| 144 | int flags = PMC_RELEASE; | ||
| 145 | |||
| 146 | on_each_cpu(cpum_cf_setup_cpu, &flags, 1); | ||
| 147 | irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); | ||
| 148 | |||
| 149 | spin_lock(&cpumcf_owner_lock); | ||
| 150 | cpumcf_owner = NULL; | ||
| 151 | spin_unlock(&cpumcf_owner_lock); | ||
| 152 | } | ||
| 153 | EXPORT_SYMBOL(__kernel_cpumcf_end); | ||
| 154 | |||
| 155 | static int cpum_cf_setup(unsigned int cpu, int flags) | ||
| 156 | { | ||
| 157 | local_irq_disable(); | ||
| 158 | cpum_cf_setup_cpu(&flags); | ||
| 159 | local_irq_enable(); | ||
| 160 | return 0; | ||
| 161 | } | ||
| 162 | |||
| 163 | static int cpum_cf_online_cpu(unsigned int cpu) | ||
| 164 | { | ||
| 165 | return cpum_cf_setup(cpu, PMC_INIT); | ||
| 166 | } | ||
| 167 | |||
| 168 | static int cpum_cf_offline_cpu(unsigned int cpu) | ||
| 169 | { | ||
| 170 | return cpum_cf_setup(cpu, PMC_RELEASE); | ||
| 171 | } | ||
| 172 | |||
| 173 | static int __init cpum_cf_init(void) | ||
| 174 | { | ||
| 175 | int rc; | ||
| 176 | |||
| 177 | if (!cpum_cf_avail()) | ||
| 178 | return -ENODEV; | ||
| 179 | |||
| 180 | /* clear bit 15 of cr0 to unauthorize problem-state to | ||
| 181 | * extract measurement counters */ | ||
| 182 | ctl_clear_bit(0, 48); | ||
| 183 | |||
| 184 | /* register handler for measurement-alert interruptions */ | ||
| 185 | rc = register_external_irq(EXT_IRQ_MEASURE_ALERT, | ||
| 186 | cpumf_measurement_alert); | ||
| 187 | if (rc) { | ||
| 188 | pr_err("Registering for CPU-measurement alerts " | ||
| 189 | "failed with rc=%i\n", rc); | ||
| 190 | return rc; | ||
| 191 | } | ||
| 192 | |||
| 193 | rc = cpuhp_setup_state(CPUHP_AP_PERF_S390_CF_ONLINE, | ||
| 194 | "perf/s390/cf:online", | ||
| 195 | cpum_cf_online_cpu, cpum_cf_offline_cpu); | ||
| 196 | if (!rc) | ||
| 197 | cpum_cf_initalized = true; | ||
| 198 | |||
| 199 | return rc; | ||
| 200 | } | ||
| 201 | early_initcall(cpum_cf_init); | ||
diff --git a/arch/s390/kernel/perf_cpum_cf_diag.c b/arch/s390/kernel/perf_cpum_cf_diag.c new file mode 100644 index 000000000000..c6fad208c2fa --- /dev/null +++ b/arch/s390/kernel/perf_cpum_cf_diag.c | |||
| @@ -0,0 +1,693 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | /* | ||
| 3 | * Performance event support for s390x - CPU-measurement Counter Sets | ||
| 4 | * | ||
| 5 | * Copyright IBM Corp. 2019 | ||
| 6 | * Author(s): Hendrik Brueckner <brueckner@linux.ibm.com> | ||
| 7 | * Thomas Richer <tmricht@linux.ibm.com> | ||
| 8 | */ | ||
| 9 | #define KMSG_COMPONENT "cpum_cf_diag" | ||
| 10 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
| 11 | |||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/kernel_stat.h> | ||
| 14 | #include <linux/percpu.h> | ||
| 15 | #include <linux/notifier.h> | ||
| 16 | #include <linux/init.h> | ||
| 17 | #include <linux/export.h> | ||
| 18 | #include <linux/slab.h> | ||
| 19 | #include <linux/processor.h> | ||
| 20 | |||
| 21 | #include <asm/ctl_reg.h> | ||
| 22 | #include <asm/irq.h> | ||
| 23 | #include <asm/cpu_mcf.h> | ||
| 24 | #include <asm/timex.h> | ||
| 25 | #include <asm/debug.h> | ||
| 26 | |||
| 27 | #define CF_DIAG_CTRSET_DEF 0xfeef /* Counter set header mark */ | ||
| 28 | |||
| 29 | static unsigned int cf_diag_cpu_speed; | ||
| 30 | static debug_info_t *cf_diag_dbg; | ||
| 31 | |||
| 32 | struct cf_diag_csd { /* Counter set data per CPU */ | ||
| 33 | size_t used; /* Bytes used in data/start */ | ||
| 34 | unsigned char start[PAGE_SIZE]; /* Counter set at event start */ | ||
| 35 | unsigned char data[PAGE_SIZE]; /* Counter set at event delete */ | ||
| 36 | }; | ||
| 37 | DEFINE_PER_CPU(struct cf_diag_csd, cf_diag_csd); | ||
| 38 | |||
| 39 | /* Counter sets are stored as data stream in a page sized memory buffer and | ||
| 40 | * exported to user space via raw data attached to the event sample data. | ||
| 41 | * Each counter set starts with an eight byte header consisting of: | ||
| 42 | * - a two byte eye catcher (0xfeef) | ||
| 43 | * - a one byte counter set number | ||
| 44 | * - a two byte counter set size (indicates the number of counters in this set) | ||
| 45 | * - a three byte reserved value (must be zero) to make the header the same | ||
| 46 | * size as a counter value. | ||
| 47 | * All counter values are eight byte in size. | ||
| 48 | * | ||
| 49 | * All counter sets are followed by a 64 byte trailer. | ||
| 50 | * The trailer consists of a: | ||
| 51 | * - flag field indicating valid fields when corresponding bit set | ||
| 52 | * - the counter facility first and second version number | ||
| 53 | * - the CPU speed if nonzero | ||
| 54 | * - the time stamp the counter sets have been collected | ||
| 55 | * - the time of day (TOD) base value | ||
| 56 | * - the machine type. | ||
| 57 | * | ||
| 58 | * The counter sets are saved when the process is prepared to be executed on a | ||
| 59 | * CPU and saved again when the process is going to be removed from a CPU. | ||
| 60 | * The difference of both counter sets are calculated and stored in the event | ||
| 61 | * sample data area. | ||
| 62 | */ | ||
| 63 | |||
| 64 | struct cf_ctrset_entry { /* CPU-M CF counter set entry (8 byte) */ | ||
| 65 | unsigned int def:16; /* 0-15 Data Entry Format */ | ||
| 66 | unsigned int set:16; /* 16-31 Counter set identifier */ | ||
| 67 | unsigned int ctr:16; /* 32-47 Number of stored counters */ | ||
| 68 | unsigned int res1:16; /* 48-63 Reserved */ | ||
| 69 | }; | ||
| 70 | |||
| 71 | struct cf_trailer_entry { /* CPU-M CF_DIAG trailer (64 byte) */ | ||
| 72 | /* 0 - 7 */ | ||
| 73 | union { | ||
| 74 | struct { | ||
| 75 | unsigned int clock_base:1; /* TOD clock base set */ | ||
| 76 | unsigned int speed:1; /* CPU speed set */ | ||
| 77 | /* Measurement alerts */ | ||
| 78 | unsigned int mtda:1; /* Loss of MT ctr. data alert */ | ||
| 79 | unsigned int caca:1; /* Counter auth. change alert */ | ||
| 80 | unsigned int lcda:1; /* Loss of counter data alert */ | ||
| 81 | }; | ||
| 82 | unsigned long flags; /* 0-63 All indicators */ | ||
| 83 | }; | ||
| 84 | /* 8 - 15 */ | ||
| 85 | unsigned int cfvn:16; /* 64-79 Ctr First Version */ | ||
| 86 | unsigned int csvn:16; /* 80-95 Ctr Second Version */ | ||
| 87 | unsigned int cpu_speed:32; /* 96-127 CPU speed */ | ||
| 88 | /* 16 - 23 */ | ||
| 89 | unsigned long timestamp; /* 128-191 Timestamp (TOD) */ | ||
| 90 | /* 24 - 55 */ | ||
| 91 | union { | ||
| 92 | struct { | ||
| 93 | unsigned long progusage1; | ||
| 94 | unsigned long progusage2; | ||
| 95 | unsigned long progusage3; | ||
| 96 | unsigned long tod_base; | ||
| 97 | }; | ||
| 98 | unsigned long progusage[4]; | ||
| 99 | }; | ||
| 100 | /* 56 - 63 */ | ||
| 101 | unsigned int mach_type:16; /* Machine type */ | ||
| 102 | unsigned int res1:16; /* Reserved */ | ||
| 103 | unsigned int res2:32; /* Reserved */ | ||
| 104 | }; | ||
| 105 | |||
| 106 | /* Create the trailer data at the end of a page. */ | ||
| 107 | static void cf_diag_trailer(struct cf_trailer_entry *te) | ||
| 108 | { | ||
| 109 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); | ||
| 110 | struct cpuid cpuid; | ||
| 111 | |||
| 112 | te->cfvn = cpuhw->info.cfvn; /* Counter version numbers */ | ||
| 113 | te->csvn = cpuhw->info.csvn; | ||
| 114 | |||
| 115 | get_cpu_id(&cpuid); /* Machine type */ | ||
| 116 | te->mach_type = cpuid.machine; | ||
| 117 | te->cpu_speed = cf_diag_cpu_speed; | ||
| 118 | if (te->cpu_speed) | ||
| 119 | te->speed = 1; | ||
| 120 | te->clock_base = 1; /* Save clock base */ | ||
| 121 | memcpy(&te->tod_base, &tod_clock_base[1], 8); | ||
| 122 | store_tod_clock((__u64 *)&te->timestamp); | ||
| 123 | } | ||
| 124 | |||
| 125 | /* | ||
| 126 | * Change the CPUMF state to active. | ||
| 127 | * Enable and activate the CPU-counter sets according | ||
| 128 | * to the per-cpu control state. | ||
| 129 | */ | ||
| 130 | static void cf_diag_enable(struct pmu *pmu) | ||
| 131 | { | ||
| 132 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); | ||
| 133 | int err; | ||
| 134 | |||
| 135 | debug_sprintf_event(cf_diag_dbg, 5, | ||
| 136 | "%s pmu %p cpu %d flags %#x state %#llx\n", | ||
| 137 | __func__, pmu, smp_processor_id(), cpuhw->flags, | ||
| 138 | cpuhw->state); | ||
| 139 | if (cpuhw->flags & PMU_F_ENABLED) | ||
| 140 | return; | ||
| 141 | |||
| 142 | err = lcctl(cpuhw->state); | ||
| 143 | if (err) { | ||
| 144 | pr_err("Enabling the performance measuring unit " | ||
| 145 | "failed with rc=%x\n", err); | ||
| 146 | return; | ||
| 147 | } | ||
| 148 | cpuhw->flags |= PMU_F_ENABLED; | ||
| 149 | } | ||
| 150 | |||
| 151 | /* | ||
| 152 | * Change the CPUMF state to inactive. | ||
| 153 | * Disable and enable (inactive) the CPU-counter sets according | ||
| 154 | * to the per-cpu control state. | ||
| 155 | */ | ||
| 156 | static void cf_diag_disable(struct pmu *pmu) | ||
| 157 | { | ||
| 158 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); | ||
| 159 | u64 inactive; | ||
| 160 | int err; | ||
| 161 | |||
| 162 | debug_sprintf_event(cf_diag_dbg, 5, | ||
| 163 | "%s pmu %p cpu %d flags %#x state %#llx\n", | ||
| 164 | __func__, pmu, smp_processor_id(), cpuhw->flags, | ||
| 165 | cpuhw->state); | ||
| 166 | if (!(cpuhw->flags & PMU_F_ENABLED)) | ||
| 167 | return; | ||
| 168 | |||
| 169 | inactive = cpuhw->state & ~((1 << CPUMF_LCCTL_ENABLE_SHIFT) - 1); | ||
| 170 | err = lcctl(inactive); | ||
| 171 | if (err) { | ||
| 172 | pr_err("Disabling the performance measuring unit " | ||
| 173 | "failed with rc=%x\n", err); | ||
| 174 | return; | ||
| 175 | } | ||
| 176 | cpuhw->flags &= ~PMU_F_ENABLED; | ||
| 177 | } | ||
| 178 | |||
| 179 | /* Number of perf events counting hardware events */ | ||
| 180 | static atomic_t cf_diag_events = ATOMIC_INIT(0); | ||
| 181 | |||
| 182 | /* Release the PMU if event is the last perf event */ | ||
| 183 | static void cf_diag_perf_event_destroy(struct perf_event *event) | ||
| 184 | { | ||
| 185 | debug_sprintf_event(cf_diag_dbg, 5, | ||
| 186 | "%s event %p cpu %d cf_diag_events %d\n", | ||
| 187 | __func__, event, event->cpu, | ||
| 188 | atomic_read(&cf_diag_events)); | ||
| 189 | if (atomic_dec_return(&cf_diag_events) == 0) | ||
| 190 | __kernel_cpumcf_end(); | ||
| 191 | } | ||
| 192 | |||
| 193 | /* Setup the event. Test for authorized counter sets and only include counter | ||
| 194 | * sets which are authorized at the time of the setup. Including unauthorized | ||
| 195 | * counter sets result in specification exception (and panic). | ||
| 196 | */ | ||
| 197 | static int __hw_perf_event_init(struct perf_event *event) | ||
| 198 | { | ||
| 199 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); | ||
| 200 | struct perf_event_attr *attr = &event->attr; | ||
| 201 | enum cpumf_ctr_set i; | ||
| 202 | int err = 0; | ||
| 203 | |||
| 204 | debug_sprintf_event(cf_diag_dbg, 5, | ||
| 205 | "%s event %p cpu %d authorized %#x\n", __func__, | ||
| 206 | event, event->cpu, cpuhw->info.auth_ctl); | ||
| 207 | |||
| 208 | event->hw.config = attr->config; | ||
| 209 | event->hw.config_base = 0; | ||
| 210 | local64_set(&event->count, 0); | ||
| 211 | |||
| 212 | /* Add all authorized counter sets to config_base */ | ||
| 213 | for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) | ||
| 214 | if (cpuhw->info.auth_ctl & cpumf_ctr_ctl[i]) | ||
| 215 | event->hw.config_base |= cpumf_ctr_ctl[i]; | ||
| 216 | |||
| 217 | /* No authorized counter sets, nothing to count/sample */ | ||
| 218 | if (!event->hw.config_base) { | ||
| 219 | err = -EINVAL; | ||
| 220 | goto out; | ||
| 221 | } | ||
| 222 | |||
| 223 | /* Set sample_period to indicate sampling */ | ||
| 224 | event->hw.sample_period = attr->sample_period; | ||
| 225 | local64_set(&event->hw.period_left, event->hw.sample_period); | ||
| 226 | event->hw.last_period = event->hw.sample_period; | ||
| 227 | out: | ||
| 228 | debug_sprintf_event(cf_diag_dbg, 5, "%s err %d config_base %#lx\n", | ||
| 229 | __func__, err, event->hw.config_base); | ||
| 230 | return err; | ||
| 231 | } | ||
| 232 | |||
| 233 | static int cf_diag_event_init(struct perf_event *event) | ||
| 234 | { | ||
| 235 | struct perf_event_attr *attr = &event->attr; | ||
| 236 | int err = -ENOENT; | ||
| 237 | |||
| 238 | debug_sprintf_event(cf_diag_dbg, 5, | ||
| 239 | "%s event %p cpu %d config %#llx " | ||
| 240 | "sample_type %#llx cf_diag_events %d\n", __func__, | ||
| 241 | event, event->cpu, attr->config, attr->sample_type, | ||
| 242 | atomic_read(&cf_diag_events)); | ||
| 243 | |||
| 244 | if (event->attr.config != PERF_EVENT_CPUM_CF_DIAG || | ||
| 245 | event->attr.type != PERF_TYPE_RAW) | ||
| 246 | goto out; | ||
| 247 | |||
| 248 | /* Raw events are used to access counters directly, | ||
| 249 | * hence do not permit excludes. | ||
| 250 | * This event is usesless without PERF_SAMPLE_RAW to return counter set | ||
| 251 | * values as raw data. | ||
| 252 | */ | ||
| 253 | if (attr->exclude_kernel || attr->exclude_user || attr->exclude_hv || | ||
| 254 | !(attr->sample_type & (PERF_SAMPLE_CPU | PERF_SAMPLE_RAW))) { | ||
| 255 | err = -EOPNOTSUPP; | ||
| 256 | goto out; | ||
| 257 | } | ||
| 258 | |||
| 259 | /* Initialize for using the CPU-measurement counter facility */ | ||
| 260 | if (atomic_inc_return(&cf_diag_events) == 1) { | ||
| 261 | if (__kernel_cpumcf_begin()) { | ||
| 262 | atomic_dec(&cf_diag_events); | ||
| 263 | err = -EBUSY; | ||
| 264 | goto out; | ||
| 265 | } | ||
| 266 | } | ||
| 267 | event->destroy = cf_diag_perf_event_destroy; | ||
| 268 | |||
| 269 | err = __hw_perf_event_init(event); | ||
| 270 | if (unlikely(err)) | ||
| 271 | event->destroy(event); | ||
| 272 | out: | ||
| 273 | debug_sprintf_event(cf_diag_dbg, 5, "%s err %d\n", __func__, err); | ||
| 274 | return err; | ||
| 275 | } | ||
| 276 | |||
| 277 | static void cf_diag_read(struct perf_event *event) | ||
| 278 | { | ||
| 279 | debug_sprintf_event(cf_diag_dbg, 5, "%s event %p\n", __func__, event); | ||
| 280 | } | ||
| 281 | |||
| 282 | /* Return the maximum possible counter set size (in number of 8 byte counters) | ||
| 283 | * depending on type and model number. | ||
| 284 | */ | ||
| 285 | static size_t cf_diag_ctrset_size(enum cpumf_ctr_set ctrset, | ||
| 286 | struct cpumf_ctr_info *info) | ||
| 287 | { | ||
| 288 | size_t ctrset_size = 0; | ||
| 289 | |||
| 290 | switch (ctrset) { | ||
| 291 | case CPUMF_CTR_SET_BASIC: | ||
| 292 | if (info->cfvn >= 1) | ||
| 293 | ctrset_size = 6; | ||
| 294 | break; | ||
| 295 | case CPUMF_CTR_SET_USER: | ||
| 296 | if (info->cfvn == 1) | ||
| 297 | ctrset_size = 6; | ||
| 298 | else if (info->cfvn >= 3) | ||
| 299 | ctrset_size = 2; | ||
| 300 | break; | ||
| 301 | case CPUMF_CTR_SET_CRYPTO: | ||
| 302 | ctrset_size = 16; | ||
| 303 | break; | ||
| 304 | case CPUMF_CTR_SET_EXT: | ||
| 305 | if (info->csvn == 1) | ||
| 306 | ctrset_size = 32; | ||
| 307 | else if (info->csvn == 2) | ||
| 308 | ctrset_size = 48; | ||
| 309 | else if (info->csvn >= 3) | ||
| 310 | ctrset_size = 128; | ||
| 311 | break; | ||
| 312 | case CPUMF_CTR_SET_MT_DIAG: | ||
| 313 | if (info->csvn > 3) | ||
| 314 | ctrset_size = 48; | ||
| 315 | break; | ||
| 316 | case CPUMF_CTR_SET_MAX: | ||
| 317 | break; | ||
| 318 | } | ||
| 319 | |||
| 320 | return ctrset_size; | ||
| 321 | } | ||
| 322 | |||
| 323 | /* Calculate memory needed to store all counter sets together with header and | ||
| 324 | * trailer data. This is independend of the counter set authorization which | ||
| 325 | * can vary depending on the configuration. | ||
| 326 | */ | ||
| 327 | static size_t cf_diag_ctrset_maxsize(struct cpumf_ctr_info *info) | ||
| 328 | { | ||
| 329 | size_t max_size = sizeof(struct cf_trailer_entry); | ||
| 330 | enum cpumf_ctr_set i; | ||
| 331 | |||
| 332 | for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) { | ||
| 333 | size_t size = cf_diag_ctrset_size(i, info); | ||
| 334 | |||
| 335 | if (size) | ||
| 336 | max_size += size * sizeof(u64) + | ||
| 337 | sizeof(struct cf_ctrset_entry); | ||
| 338 | } | ||
| 339 | debug_sprintf_event(cf_diag_dbg, 5, "%s max_size %zu\n", __func__, | ||
| 340 | max_size); | ||
| 341 | |||
| 342 | return max_size; | ||
| 343 | } | ||
| 344 | |||
| 345 | /* Read a counter set. The counter set number determines which counter set and | ||
| 346 | * the CPUM-CF first and second version number determine the number of | ||
| 347 | * available counters in this counter set. | ||
| 348 | * Each counter set starts with header containing the counter set number and | ||
| 349 | * the number of 8 byte counters. | ||
| 350 | * | ||
| 351 | * The functions returns the number of bytes occupied by this counter set | ||
| 352 | * including the header. | ||
| 353 | * If there is no counter in the counter set, this counter set is useless and | ||
| 354 | * zero is returned on this case. | ||
| 355 | */ | ||
| 356 | static size_t cf_diag_getctrset(struct cf_ctrset_entry *ctrdata, int ctrset, | ||
| 357 | size_t room) | ||
| 358 | { | ||
| 359 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); | ||
| 360 | size_t ctrset_size, need = 0; | ||
| 361 | int rc = 3; /* Assume write failure */ | ||
| 362 | |||
| 363 | ctrdata->def = CF_DIAG_CTRSET_DEF; | ||
| 364 | ctrdata->set = ctrset; | ||
| 365 | ctrdata->res1 = 0; | ||
| 366 | ctrset_size = cf_diag_ctrset_size(ctrset, &cpuhw->info); | ||
| 367 | |||
| 368 | if (ctrset_size) { /* Save data */ | ||
| 369 | need = ctrset_size * sizeof(u64) + sizeof(*ctrdata); | ||
| 370 | if (need <= room) | ||
| 371 | rc = ctr_stcctm(ctrset, ctrset_size, | ||
| 372 | (u64 *)(ctrdata + 1)); | ||
| 373 | if (rc != 3) | ||
| 374 | ctrdata->ctr = ctrset_size; | ||
| 375 | else | ||
| 376 | need = 0; | ||
| 377 | } | ||
| 378 | |||
| 379 | debug_sprintf_event(cf_diag_dbg, 6, | ||
| 380 | "%s ctrset %d ctrset_size %zu cfvn %d csvn %d" | ||
| 381 | " need %zd rc:%d\n", | ||
| 382 | __func__, ctrset, ctrset_size, cpuhw->info.cfvn, | ||
| 383 | cpuhw->info.csvn, need, rc); | ||
| 384 | return need; | ||
| 385 | } | ||
| 386 | |||
| 387 | /* Read out all counter sets and save them in the provided data buffer. | ||
| 388 | * The last 64 byte host an artificial trailer entry. | ||
| 389 | */ | ||
| 390 | static size_t cf_diag_getctr(void *data, size_t sz, unsigned long auth) | ||
| 391 | { | ||
| 392 | struct cf_trailer_entry *trailer; | ||
| 393 | size_t offset = 0, done; | ||
| 394 | int i; | ||
| 395 | |||
| 396 | memset(data, 0, sz); | ||
| 397 | sz -= sizeof(*trailer); /* Always room for trailer */ | ||
| 398 | for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) { | ||
| 399 | struct cf_ctrset_entry *ctrdata = data + offset; | ||
| 400 | |||
| 401 | if (!(auth & cpumf_ctr_ctl[i])) | ||
| 402 | continue; /* Counter set not authorized */ | ||
| 403 | |||
| 404 | done = cf_diag_getctrset(ctrdata, i, sz - offset); | ||
| 405 | offset += done; | ||
| 406 | debug_sprintf_event(cf_diag_dbg, 6, | ||
| 407 | "%s ctrset %d offset %zu done %zu\n", | ||
| 408 | __func__, i, offset, done); | ||
| 409 | } | ||
| 410 | trailer = data + offset; | ||
| 411 | cf_diag_trailer(trailer); | ||
| 412 | return offset + sizeof(*trailer); | ||
| 413 | } | ||
| 414 | |||
| 415 | /* Calculate the difference for each counter in a counter set. */ | ||
| 416 | static void cf_diag_diffctrset(u64 *pstart, u64 *pstop, int counters) | ||
| 417 | { | ||
| 418 | for (; --counters >= 0; ++pstart, ++pstop) | ||
| 419 | if (*pstop >= *pstart) | ||
| 420 | *pstop -= *pstart; | ||
| 421 | else | ||
| 422 | *pstop = *pstart - *pstop; | ||
| 423 | } | ||
| 424 | |||
| 425 | /* Scan the counter sets and calculate the difference of each counter | ||
| 426 | * in each set. The result is the increment of each counter during the | ||
| 427 | * period the counter set has been activated. | ||
| 428 | * | ||
| 429 | * Return true on success. | ||
| 430 | */ | ||
| 431 | static int cf_diag_diffctr(struct cf_diag_csd *csd, unsigned long auth) | ||
| 432 | { | ||
| 433 | struct cf_trailer_entry *trailer_start, *trailer_stop; | ||
| 434 | struct cf_ctrset_entry *ctrstart, *ctrstop; | ||
| 435 | size_t offset = 0; | ||
| 436 | |||
| 437 | auth &= (1 << CPUMF_LCCTL_ENABLE_SHIFT) - 1; | ||
| 438 | do { | ||
| 439 | ctrstart = (struct cf_ctrset_entry *)(csd->start + offset); | ||
| 440 | ctrstop = (struct cf_ctrset_entry *)(csd->data + offset); | ||
| 441 | |||
| 442 | if (memcmp(ctrstop, ctrstart, sizeof(*ctrstop))) { | ||
| 443 | pr_err("cpum_cf_diag counter set compare error " | ||
| 444 | "in set %i\n", ctrstart->set); | ||
| 445 | return 0; | ||
| 446 | } | ||
| 447 | auth &= ~cpumf_ctr_ctl[ctrstart->set]; | ||
| 448 | if (ctrstart->def == CF_DIAG_CTRSET_DEF) { | ||
| 449 | cf_diag_diffctrset((u64 *)(ctrstart + 1), | ||
| 450 | (u64 *)(ctrstop + 1), ctrstart->ctr); | ||
| 451 | offset += ctrstart->ctr * sizeof(u64) + | ||
| 452 | sizeof(*ctrstart); | ||
| 453 | } | ||
| 454 | debug_sprintf_event(cf_diag_dbg, 6, | ||
| 455 | "%s set %d ctr %d offset %zu auth %lx\n", | ||
| 456 | __func__, ctrstart->set, ctrstart->ctr, | ||
| 457 | offset, auth); | ||
| 458 | } while (ctrstart->def && auth); | ||
| 459 | |||
| 460 | /* Save time_stamp from start of event in stop's trailer */ | ||
| 461 | trailer_start = (struct cf_trailer_entry *)(csd->start + offset); | ||
| 462 | trailer_stop = (struct cf_trailer_entry *)(csd->data + offset); | ||
| 463 | trailer_stop->progusage[0] = trailer_start->timestamp; | ||
| 464 | |||
| 465 | return 1; | ||
| 466 | } | ||
| 467 | |||
| 468 | /* Create perf event sample with the counter sets as raw data. The sample | ||
| 469 | * is then pushed to the event subsystem and the function checks for | ||
| 470 | * possible event overflows. If an event overflow occurs, the PMU is | ||
| 471 | * stopped. | ||
| 472 | * | ||
| 473 | * Return non-zero if an event overflow occurred. | ||
| 474 | */ | ||
| 475 | static int cf_diag_push_sample(struct perf_event *event, | ||
| 476 | struct cf_diag_csd *csd) | ||
| 477 | { | ||
| 478 | struct perf_sample_data data; | ||
| 479 | struct perf_raw_record raw; | ||
| 480 | struct pt_regs regs; | ||
| 481 | int overflow; | ||
| 482 | |||
| 483 | /* Setup perf sample */ | ||
| 484 | perf_sample_data_init(&data, 0, event->hw.last_period); | ||
| 485 | memset(®s, 0, sizeof(regs)); | ||
| 486 | memset(&raw, 0, sizeof(raw)); | ||
| 487 | |||
| 488 | if (event->attr.sample_type & PERF_SAMPLE_CPU) | ||
| 489 | data.cpu_entry.cpu = event->cpu; | ||
| 490 | if (event->attr.sample_type & PERF_SAMPLE_RAW) { | ||
| 491 | raw.frag.size = csd->used; | ||
| 492 | raw.frag.data = csd->data; | ||
| 493 | raw.size = csd->used; | ||
| 494 | data.raw = &raw; | ||
| 495 | } | ||
| 496 | |||
| 497 | overflow = perf_event_overflow(event, &data, ®s); | ||
| 498 | debug_sprintf_event(cf_diag_dbg, 6, | ||
| 499 | "%s event %p cpu %d sample_type %#llx raw %d " | ||
| 500 | "ov %d\n", __func__, event, event->cpu, | ||
| 501 | event->attr.sample_type, raw.size, overflow); | ||
| 502 | if (overflow) | ||
| 503 | event->pmu->stop(event, 0); | ||
| 504 | |||
| 505 | perf_event_update_userpage(event); | ||
| 506 | return overflow; | ||
| 507 | } | ||
| 508 | |||
| 509 | static void cf_diag_start(struct perf_event *event, int flags) | ||
| 510 | { | ||
| 511 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); | ||
| 512 | struct cf_diag_csd *csd = this_cpu_ptr(&cf_diag_csd); | ||
| 513 | struct hw_perf_event *hwc = &event->hw; | ||
| 514 | |||
| 515 | debug_sprintf_event(cf_diag_dbg, 5, | ||
| 516 | "%s event %p cpu %d flags %#x hwc-state %#x\n", | ||
| 517 | __func__, event, event->cpu, flags, hwc->state); | ||
| 518 | if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED))) | ||
| 519 | return; | ||
| 520 | |||
| 521 | /* (Re-)enable and activate all counter sets */ | ||
| 522 | lcctl(0); /* Reset counter sets */ | ||
| 523 | hwc->state = 0; | ||
| 524 | ctr_set_multiple_enable(&cpuhw->state, hwc->config_base); | ||
| 525 | lcctl(cpuhw->state); /* Enable counter sets */ | ||
| 526 | csd->used = cf_diag_getctr(csd->start, sizeof(csd->start), | ||
| 527 | event->hw.config_base); | ||
| 528 | ctr_set_multiple_start(&cpuhw->state, hwc->config_base); | ||
| 529 | /* Function cf_diag_enable() starts the counter sets. */ | ||
| 530 | } | ||
| 531 | |||
| 532 | static void cf_diag_stop(struct perf_event *event, int flags) | ||
| 533 | { | ||
| 534 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); | ||
| 535 | struct cf_diag_csd *csd = this_cpu_ptr(&cf_diag_csd); | ||
| 536 | struct hw_perf_event *hwc = &event->hw; | ||
| 537 | |||
| 538 | debug_sprintf_event(cf_diag_dbg, 5, | ||
| 539 | "%s event %p cpu %d flags %#x hwc-state %#x\n", | ||
| 540 | __func__, event, event->cpu, flags, hwc->state); | ||
| 541 | |||
| 542 | /* Deactivate all counter sets */ | ||
| 543 | ctr_set_multiple_stop(&cpuhw->state, hwc->config_base); | ||
| 544 | local64_inc(&event->count); | ||
| 545 | csd->used = cf_diag_getctr(csd->data, sizeof(csd->data), | ||
| 546 | event->hw.config_base); | ||
| 547 | if (cf_diag_diffctr(csd, event->hw.config_base)) | ||
| 548 | cf_diag_push_sample(event, csd); | ||
| 549 | hwc->state |= PERF_HES_STOPPED; | ||
| 550 | } | ||
| 551 | |||
| 552 | static int cf_diag_add(struct perf_event *event, int flags) | ||
| 553 | { | ||
| 554 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); | ||
| 555 | int err = 0; | ||
| 556 | |||
| 557 | debug_sprintf_event(cf_diag_dbg, 5, | ||
| 558 | "%s event %p cpu %d flags %#x cpuhw:%p\n", | ||
| 559 | __func__, event, event->cpu, flags, cpuhw); | ||
| 560 | |||
| 561 | if (cpuhw->flags & PMU_F_IN_USE) { | ||
| 562 | err = -EAGAIN; | ||
| 563 | goto out; | ||
| 564 | } | ||
| 565 | |||
| 566 | event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED; | ||
| 567 | |||
| 568 | cpuhw->flags |= PMU_F_IN_USE; | ||
| 569 | if (flags & PERF_EF_START) | ||
| 570 | cf_diag_start(event, PERF_EF_RELOAD); | ||
| 571 | out: | ||
| 572 | debug_sprintf_event(cf_diag_dbg, 5, "%s err %d\n", __func__, err); | ||
| 573 | return err; | ||
| 574 | } | ||
| 575 | |||
| 576 | static void cf_diag_del(struct perf_event *event, int flags) | ||
| 577 | { | ||
| 578 | struct cpu_cf_events *cpuhw = this_cpu_ptr(&cpu_cf_events); | ||
| 579 | |||
| 580 | debug_sprintf_event(cf_diag_dbg, 5, | ||
| 581 | "%s event %p cpu %d flags %#x\n", | ||
| 582 | __func__, event, event->cpu, flags); | ||
| 583 | |||
| 584 | cf_diag_stop(event, PERF_EF_UPDATE); | ||
| 585 | ctr_set_multiple_stop(&cpuhw->state, event->hw.config_base); | ||
| 586 | ctr_set_multiple_disable(&cpuhw->state, event->hw.config_base); | ||
| 587 | cpuhw->flags &= ~PMU_F_IN_USE; | ||
| 588 | } | ||
| 589 | |||
| 590 | CPUMF_EVENT_ATTR(CF_DIAG, CF_DIAG, PERF_EVENT_CPUM_CF_DIAG); | ||
| 591 | |||
| 592 | static struct attribute *cf_diag_events_attr[] = { | ||
| 593 | CPUMF_EVENT_PTR(CF_DIAG, CF_DIAG), | ||
| 594 | NULL, | ||
| 595 | }; | ||
| 596 | |||
| 597 | PMU_FORMAT_ATTR(event, "config:0-63"); | ||
| 598 | |||
| 599 | static struct attribute *cf_diag_format_attr[] = { | ||
| 600 | &format_attr_event.attr, | ||
| 601 | NULL, | ||
| 602 | }; | ||
| 603 | |||
| 604 | static struct attribute_group cf_diag_events_group = { | ||
| 605 | .name = "events", | ||
| 606 | .attrs = cf_diag_events_attr, | ||
| 607 | }; | ||
| 608 | static struct attribute_group cf_diag_format_group = { | ||
| 609 | .name = "format", | ||
| 610 | .attrs = cf_diag_format_attr, | ||
| 611 | }; | ||
| 612 | static const struct attribute_group *cf_diag_attr_groups[] = { | ||
| 613 | &cf_diag_events_group, | ||
| 614 | &cf_diag_format_group, | ||
| 615 | NULL, | ||
| 616 | }; | ||
| 617 | |||
| 618 | /* Performance monitoring unit for s390x */ | ||
| 619 | static struct pmu cf_diag = { | ||
| 620 | .task_ctx_nr = perf_sw_context, | ||
| 621 | .pmu_enable = cf_diag_enable, | ||
| 622 | .pmu_disable = cf_diag_disable, | ||
| 623 | .event_init = cf_diag_event_init, | ||
| 624 | .add = cf_diag_add, | ||
| 625 | .del = cf_diag_del, | ||
| 626 | .start = cf_diag_start, | ||
| 627 | .stop = cf_diag_stop, | ||
| 628 | .read = cf_diag_read, | ||
| 629 | |||
| 630 | .attr_groups = cf_diag_attr_groups | ||
| 631 | }; | ||
| 632 | |||
| 633 | /* Get the CPU speed, try sampling facility first and CPU attributes second. */ | ||
| 634 | static void cf_diag_get_cpu_speed(void) | ||
| 635 | { | ||
| 636 | if (cpum_sf_avail()) { /* Sampling facility first */ | ||
| 637 | struct hws_qsi_info_block si; | ||
| 638 | |||
| 639 | memset(&si, 0, sizeof(si)); | ||
| 640 | if (!qsi(&si)) { | ||
| 641 | cf_diag_cpu_speed = si.cpu_speed; | ||
| 642 | return; | ||
| 643 | } | ||
| 644 | } | ||
| 645 | |||
| 646 | if (test_facility(34)) { /* CPU speed extract static part */ | ||
| 647 | unsigned long mhz = __ecag(ECAG_CPU_ATTRIBUTE, 0); | ||
| 648 | |||
| 649 | if (mhz != -1UL) | ||
| 650 | cf_diag_cpu_speed = mhz & 0xffffffff; | ||
| 651 | } | ||
| 652 | } | ||
| 653 | |||
| 654 | /* Initialize the counter set PMU to generate complete counter set data as | ||
| 655 | * event raw data. This relies on the CPU Measurement Counter Facility device | ||
| 656 | * already being loaded and initialized. | ||
| 657 | */ | ||
| 658 | static int __init cf_diag_init(void) | ||
| 659 | { | ||
| 660 | struct cpumf_ctr_info info; | ||
| 661 | size_t need; | ||
| 662 | int rc; | ||
| 663 | |||
| 664 | if (!kernel_cpumcf_avail() || !stccm_avail() || qctri(&info)) | ||
| 665 | return -ENODEV; | ||
| 666 | cf_diag_get_cpu_speed(); | ||
| 667 | |||
| 668 | /* Make sure the counter set data fits into predefined buffer. */ | ||
| 669 | need = cf_diag_ctrset_maxsize(&info); | ||
| 670 | if (need > sizeof(((struct cf_diag_csd *)0)->start)) { | ||
| 671 | pr_err("Insufficient memory for PMU(cpum_cf_diag) need=%zu\n", | ||
| 672 | need); | ||
| 673 | return -ENOMEM; | ||
| 674 | } | ||
| 675 | |||
| 676 | /* Setup s390dbf facility */ | ||
| 677 | cf_diag_dbg = debug_register(KMSG_COMPONENT, 2, 1, 128); | ||
| 678 | if (!cf_diag_dbg) { | ||
| 679 | pr_err("Registration of s390dbf(cpum_cf_diag) failed\n"); | ||
| 680 | return -ENOMEM; | ||
| 681 | } | ||
| 682 | debug_register_view(cf_diag_dbg, &debug_sprintf_view); | ||
| 683 | |||
| 684 | rc = perf_pmu_register(&cf_diag, "cpum_cf_diag", PERF_TYPE_RAW); | ||
| 685 | if (rc) { | ||
| 686 | debug_unregister_view(cf_diag_dbg, &debug_sprintf_view); | ||
| 687 | debug_unregister(cf_diag_dbg); | ||
| 688 | pr_err("Registration of PMU(cpum_cf_diag) failed with rc=%i\n", | ||
| 689 | rc); | ||
| 690 | } | ||
| 691 | return rc; | ||
| 692 | } | ||
| 693 | arch_initcall(cf_diag_init); | ||
diff --git a/arch/s390/kernel/perf_cpum_cf_events.c b/arch/s390/kernel/perf_cpum_cf_events.c index d63fb3c56b8a..b45238c89728 100644 --- a/arch/s390/kernel/perf_cpum_cf_events.c +++ b/arch/s390/kernel/perf_cpum_cf_events.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include <linux/slab.h> | 7 | #include <linux/slab.h> |
| 8 | #include <linux/perf_event.h> | 8 | #include <linux/perf_event.h> |
| 9 | #include <asm/cpu_mf.h> | ||
| 9 | 10 | ||
| 10 | 11 | ||
| 11 | /* BEGIN: CPUM_CF COUNTER DEFINITIONS =================================== */ | 12 | /* BEGIN: CPUM_CF COUNTER DEFINITIONS =================================== */ |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 7ed90a759135..12934e8fbb91 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
| @@ -369,7 +369,7 @@ void __init arch_call_rest_init(void) | |||
| 369 | : : [_frame] "a" (frame)); | 369 | : : [_frame] "a" (frame)); |
| 370 | } | 370 | } |
| 371 | 371 | ||
| 372 | static void __init setup_lowcore(void) | 372 | static void __init setup_lowcore_dat_off(void) |
| 373 | { | 373 | { |
| 374 | struct lowcore *lc; | 374 | struct lowcore *lc; |
| 375 | 375 | ||
| @@ -380,19 +380,16 @@ static void __init setup_lowcore(void) | |||
| 380 | lc = memblock_alloc_low(sizeof(*lc), sizeof(*lc)); | 380 | lc = memblock_alloc_low(sizeof(*lc), sizeof(*lc)); |
| 381 | lc->restart_psw.mask = PSW_KERNEL_BITS; | 381 | lc->restart_psw.mask = PSW_KERNEL_BITS; |
| 382 | lc->restart_psw.addr = (unsigned long) restart_int_handler; | 382 | lc->restart_psw.addr = (unsigned long) restart_int_handler; |
| 383 | lc->external_new_psw.mask = PSW_KERNEL_BITS | | 383 | lc->external_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK; |
| 384 | PSW_MASK_DAT | PSW_MASK_MCHECK; | ||
| 385 | lc->external_new_psw.addr = (unsigned long) ext_int_handler; | 384 | lc->external_new_psw.addr = (unsigned long) ext_int_handler; |
| 386 | lc->svc_new_psw.mask = PSW_KERNEL_BITS | | 385 | lc->svc_new_psw.mask = PSW_KERNEL_BITS | |
| 387 | PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; | 386 | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; |
| 388 | lc->svc_new_psw.addr = (unsigned long) system_call; | 387 | lc->svc_new_psw.addr = (unsigned long) system_call; |
| 389 | lc->program_new_psw.mask = PSW_KERNEL_BITS | | 388 | lc->program_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK; |
| 390 | PSW_MASK_DAT | PSW_MASK_MCHECK; | ||
| 391 | lc->program_new_psw.addr = (unsigned long) pgm_check_handler; | 389 | lc->program_new_psw.addr = (unsigned long) pgm_check_handler; |
| 392 | lc->mcck_new_psw.mask = PSW_KERNEL_BITS; | 390 | lc->mcck_new_psw.mask = PSW_KERNEL_BITS; |
| 393 | lc->mcck_new_psw.addr = (unsigned long) mcck_int_handler; | 391 | lc->mcck_new_psw.addr = (unsigned long) mcck_int_handler; |
| 394 | lc->io_new_psw.mask = PSW_KERNEL_BITS | | 392 | lc->io_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK; |
| 395 | PSW_MASK_DAT | PSW_MASK_MCHECK; | ||
| 396 | lc->io_new_psw.addr = (unsigned long) io_int_handler; | 393 | lc->io_new_psw.addr = (unsigned long) io_int_handler; |
| 397 | lc->clock_comparator = clock_comparator_max; | 394 | lc->clock_comparator = clock_comparator_max; |
| 398 | lc->nodat_stack = ((unsigned long) &init_thread_union) | 395 | lc->nodat_stack = ((unsigned long) &init_thread_union) |
| @@ -452,6 +449,16 @@ static void __init setup_lowcore(void) | |||
| 452 | lowcore_ptr[0] = lc; | 449 | lowcore_ptr[0] = lc; |
| 453 | } | 450 | } |
| 454 | 451 | ||
| 452 | static void __init setup_lowcore_dat_on(void) | ||
| 453 | { | ||
| 454 | __ctl_clear_bit(0, 28); | ||
| 455 | S390_lowcore.external_new_psw.mask |= PSW_MASK_DAT; | ||
| 456 | S390_lowcore.svc_new_psw.mask |= PSW_MASK_DAT; | ||
| 457 | S390_lowcore.program_new_psw.mask |= PSW_MASK_DAT; | ||
| 458 | S390_lowcore.io_new_psw.mask |= PSW_MASK_DAT; | ||
| 459 | __ctl_set_bit(0, 28); | ||
| 460 | } | ||
| 461 | |||
| 455 | static struct resource code_resource = { | 462 | static struct resource code_resource = { |
| 456 | .name = "Kernel code", | 463 | .name = "Kernel code", |
| 457 | .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM, | 464 | .flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM, |
| @@ -794,18 +801,9 @@ static void __init reserve_kernel(void) | |||
| 794 | { | 801 | { |
| 795 | unsigned long start_pfn = PFN_UP(__pa(_end)); | 802 | unsigned long start_pfn = PFN_UP(__pa(_end)); |
| 796 | 803 | ||
| 797 | #ifdef CONFIG_DMA_API_DEBUG | ||
| 798 | /* | ||
| 799 | * DMA_API_DEBUG code stumbles over addresses from the | ||
| 800 | * range [PARMAREA_END, _stext]. Mark the memory as reserved | ||
| 801 | * so it is not used for CONFIG_DMA_API_DEBUG=y. | ||
| 802 | */ | ||
| 803 | memblock_reserve(0, PFN_PHYS(start_pfn)); | ||
| 804 | #else | ||
| 805 | memblock_reserve(0, PARMAREA_END); | 804 | memblock_reserve(0, PARMAREA_END); |
| 806 | memblock_reserve((unsigned long)_stext, PFN_PHYS(start_pfn) | 805 | memblock_reserve((unsigned long)_stext, PFN_PHYS(start_pfn) |
| 807 | - (unsigned long)_stext); | 806 | - (unsigned long)_stext); |
| 808 | #endif | ||
| 809 | } | 807 | } |
| 810 | 808 | ||
| 811 | static void __init setup_memory(void) | 809 | static void __init setup_memory(void) |
| @@ -990,6 +988,25 @@ static void __init setup_task_size(void) | |||
| 990 | } | 988 | } |
| 991 | 989 | ||
| 992 | /* | 990 | /* |
| 991 | * Issue diagnose 318 to set the control program name and | ||
| 992 | * version codes. | ||
| 993 | */ | ||
| 994 | static void __init setup_control_program_code(void) | ||
| 995 | { | ||
| 996 | union diag318_info diag318_info = { | ||
| 997 | .cpnc = CPNC_LINUX, | ||
| 998 | .cpvc_linux = 0, | ||
| 999 | .cpvc_distro = {0}, | ||
| 1000 | }; | ||
| 1001 | |||
| 1002 | if (!sclp.has_diag318) | ||
| 1003 | return; | ||
| 1004 | |||
| 1005 | diag_stat_inc(DIAG_STAT_X318); | ||
| 1006 | asm volatile("diag %0,0,0x318\n" : : "d" (diag318_info.val)); | ||
| 1007 | } | ||
| 1008 | |||
| 1009 | /* | ||
| 993 | * Setup function called from init/main.c just after the banner | 1010 | * Setup function called from init/main.c just after the banner |
| 994 | * was printed. | 1011 | * was printed. |
| 995 | */ | 1012 | */ |
| @@ -1033,6 +1050,7 @@ void __init setup_arch(char **cmdline_p) | |||
| 1033 | os_info_init(); | 1050 | os_info_init(); |
| 1034 | setup_ipl(); | 1051 | setup_ipl(); |
| 1035 | setup_task_size(); | 1052 | setup_task_size(); |
| 1053 | setup_control_program_code(); | ||
| 1036 | 1054 | ||
| 1037 | /* Do some memory reservations *before* memory is added to memblock */ | 1055 | /* Do some memory reservations *before* memory is added to memblock */ |
| 1038 | reserve_memory_end(); | 1056 | reserve_memory_end(); |
| @@ -1072,7 +1090,7 @@ void __init setup_arch(char **cmdline_p) | |||
| 1072 | #endif | 1090 | #endif |
| 1073 | 1091 | ||
| 1074 | setup_resources(); | 1092 | setup_resources(); |
| 1075 | setup_lowcore(); | 1093 | setup_lowcore_dat_off(); |
| 1076 | smp_fill_possible_mask(); | 1094 | smp_fill_possible_mask(); |
| 1077 | cpu_detect_mhz_feature(); | 1095 | cpu_detect_mhz_feature(); |
| 1078 | cpu_init(); | 1096 | cpu_init(); |
| @@ -1085,6 +1103,12 @@ void __init setup_arch(char **cmdline_p) | |||
| 1085 | */ | 1103 | */ |
| 1086 | paging_init(); | 1104 | paging_init(); |
| 1087 | 1105 | ||
| 1106 | /* | ||
| 1107 | * After paging_init created the kernel page table, the new PSWs | ||
| 1108 | * in lowcore can now run with DAT enabled. | ||
| 1109 | */ | ||
| 1110 | setup_lowcore_dat_on(); | ||
| 1111 | |||
| 1088 | /* Setup default console */ | 1112 | /* Setup default console */ |
| 1089 | conmode_default(); | 1113 | conmode_default(); |
| 1090 | set_preferred_console(); | 1114 | set_preferred_console(); |
diff --git a/arch/s390/kernel/swsusp.S b/arch/s390/kernel/swsusp.S index b6796e616812..993100c31d65 100644 --- a/arch/s390/kernel/swsusp.S +++ b/arch/s390/kernel/swsusp.S | |||
| @@ -124,13 +124,13 @@ ENTRY(swsusp_arch_resume) | |||
| 124 | lghi %r2,1 | 124 | lghi %r2,1 |
| 125 | brasl %r14,arch_set_page_states | 125 | brasl %r14,arch_set_page_states |
| 126 | 126 | ||
| 127 | /* Deactivate DAT */ | ||
| 128 | stnsm __SF_EMPTY(%r15),0xfb | ||
| 129 | |||
| 130 | /* Set prefix page to zero */ | 127 | /* Set prefix page to zero */ |
| 131 | xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15) | 128 | xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15) |
| 132 | spx __SF_EMPTY(%r15) | 129 | spx __SF_EMPTY(%r15) |
| 133 | 130 | ||
| 131 | /* Deactivate DAT */ | ||
| 132 | stnsm __SF_EMPTY(%r15),0xfb | ||
| 133 | |||
| 134 | /* Restore saved image */ | 134 | /* Restore saved image */ |
| 135 | larl %r1,restore_pblist | 135 | larl %r1,restore_pblist |
| 136 | lg %r1,0(%r1) | 136 | lg %r1,0(%r1) |
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c index 31cefe0c28c0..202fa73ac167 100644 --- a/arch/s390/kernel/sys_s390.c +++ b/arch/s390/kernel/sys_s390.c | |||
| @@ -58,6 +58,7 @@ out: | |||
| 58 | return error; | 58 | return error; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | #ifdef CONFIG_SYSVIPC | ||
| 61 | /* | 62 | /* |
| 62 | * sys_ipc() is the de-multiplexer for the SysV IPC calls. | 63 | * sys_ipc() is the de-multiplexer for the SysV IPC calls. |
| 63 | */ | 64 | */ |
| @@ -74,19 +75,28 @@ SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second, | |||
| 74 | * Therefore we can call the generic variant by simply passing the | 75 | * Therefore we can call the generic variant by simply passing the |
| 75 | * third parameter also as fifth parameter. | 76 | * third parameter also as fifth parameter. |
| 76 | */ | 77 | */ |
| 77 | return sys_ipc(call, first, second, third, ptr, third); | 78 | return ksys_ipc(call, first, second, third, ptr, third); |
| 78 | } | 79 | } |
| 80 | #endif /* CONFIG_SYSVIPC */ | ||
| 79 | 81 | ||
| 80 | SYSCALL_DEFINE1(s390_personality, unsigned int, personality) | 82 | SYSCALL_DEFINE1(s390_personality, unsigned int, personality) |
| 81 | { | 83 | { |
| 82 | unsigned int ret; | 84 | unsigned int ret = current->personality; |
| 83 | 85 | ||
| 84 | if (personality(current->personality) == PER_LINUX32 && | 86 | if (personality(current->personality) == PER_LINUX32 && |
| 85 | personality(personality) == PER_LINUX) | 87 | personality(personality) == PER_LINUX) |
| 86 | personality |= PER_LINUX32; | 88 | personality |= PER_LINUX32; |
| 87 | ret = sys_personality(personality); | 89 | |
| 90 | if (personality != 0xffffffff) | ||
| 91 | set_personality(personality); | ||
| 92 | |||
| 88 | if (personality(ret) == PER_LINUX32) | 93 | if (personality(ret) == PER_LINUX32) |
| 89 | ret &= ~PER_LINUX32; | 94 | ret &= ~PER_LINUX32; |
| 90 | 95 | ||
| 91 | return ret; | 96 | return ret; |
| 92 | } | 97 | } |
| 98 | |||
| 99 | SYSCALL_DEFINE0(ni_syscall) | ||
| 100 | { | ||
| 101 | return -ENOSYS; | ||
| 102 | } | ||
diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl index 022fc099b628..7413fd318e2a 100644 --- a/arch/s390/kernel/syscalls/syscall.tbl +++ b/arch/s390/kernel/syscalls/syscall.tbl | |||
| @@ -15,86 +15,86 @@ | |||
| 15 | 5 common open sys_open compat_sys_open | 15 | 5 common open sys_open compat_sys_open |
| 16 | 6 common close sys_close sys_close | 16 | 6 common close sys_close sys_close |
| 17 | 7 common restart_syscall sys_restart_syscall sys_restart_syscall | 17 | 7 common restart_syscall sys_restart_syscall sys_restart_syscall |
| 18 | 8 common creat sys_creat compat_sys_creat | 18 | 8 common creat sys_creat sys_creat |
| 19 | 9 common link sys_link compat_sys_link | 19 | 9 common link sys_link sys_link |
| 20 | 10 common unlink sys_unlink compat_sys_unlink | 20 | 10 common unlink sys_unlink sys_unlink |
| 21 | 11 common execve sys_execve compat_sys_execve | 21 | 11 common execve sys_execve compat_sys_execve |
| 22 | 12 common chdir sys_chdir compat_sys_chdir | 22 | 12 common chdir sys_chdir sys_chdir |
| 23 | 13 32 time - compat_sys_time | 23 | 13 32 time - compat_sys_time |
| 24 | 14 common mknod sys_mknod compat_sys_mknod | 24 | 14 common mknod sys_mknod sys_mknod |
| 25 | 15 common chmod sys_chmod compat_sys_chmod | 25 | 15 common chmod sys_chmod sys_chmod |
| 26 | 16 32 lchown - compat_sys_s390_lchown16 | 26 | 16 32 lchown - sys_lchown16 |
| 27 | 19 common lseek sys_lseek compat_sys_lseek | 27 | 19 common lseek sys_lseek compat_sys_lseek |
| 28 | 20 common getpid sys_getpid sys_getpid | 28 | 20 common getpid sys_getpid sys_getpid |
| 29 | 21 common mount sys_mount compat_sys_mount | 29 | 21 common mount sys_mount compat_sys_mount |
| 30 | 22 common umount sys_oldumount compat_sys_oldumount | 30 | 22 common umount sys_oldumount sys_oldumount |
| 31 | 23 32 setuid - compat_sys_s390_setuid16 | 31 | 23 32 setuid - sys_setuid16 |
| 32 | 24 32 getuid - compat_sys_s390_getuid16 | 32 | 24 32 getuid - sys_getuid16 |
| 33 | 25 32 stime - compat_sys_stime | 33 | 25 32 stime - compat_sys_stime |
| 34 | 26 common ptrace sys_ptrace compat_sys_ptrace | 34 | 26 common ptrace sys_ptrace compat_sys_ptrace |
| 35 | 27 common alarm sys_alarm sys_alarm | 35 | 27 common alarm sys_alarm sys_alarm |
| 36 | 29 common pause sys_pause sys_pause | 36 | 29 common pause sys_pause sys_pause |
| 37 | 30 common utime sys_utime compat_sys_utime | 37 | 30 common utime sys_utime compat_sys_utime |
| 38 | 33 common access sys_access compat_sys_access | 38 | 33 common access sys_access sys_access |
| 39 | 34 common nice sys_nice sys_nice | 39 | 34 common nice sys_nice sys_nice |
| 40 | 36 common sync sys_sync sys_sync | 40 | 36 common sync sys_sync sys_sync |
| 41 | 37 common kill sys_kill sys_kill | 41 | 37 common kill sys_kill sys_kill |
| 42 | 38 common rename sys_rename compat_sys_rename | 42 | 38 common rename sys_rename sys_rename |
| 43 | 39 common mkdir sys_mkdir compat_sys_mkdir | 43 | 39 common mkdir sys_mkdir sys_mkdir |
| 44 | 40 common rmdir sys_rmdir compat_sys_rmdir | 44 | 40 common rmdir sys_rmdir sys_rmdir |
| 45 | 41 common dup sys_dup sys_dup | 45 | 41 common dup sys_dup sys_dup |
| 46 | 42 common pipe sys_pipe compat_sys_pipe | 46 | 42 common pipe sys_pipe sys_pipe |
| 47 | 43 common times sys_times compat_sys_times | 47 | 43 common times sys_times compat_sys_times |
| 48 | 45 common brk sys_brk compat_sys_brk | 48 | 45 common brk sys_brk sys_brk |
| 49 | 46 32 setgid - compat_sys_s390_setgid16 | 49 | 46 32 setgid - sys_setgid16 |
| 50 | 47 32 getgid - compat_sys_s390_getgid16 | 50 | 47 32 getgid - sys_getgid16 |
| 51 | 48 common signal sys_signal compat_sys_signal | 51 | 48 common signal sys_signal sys_signal |
| 52 | 49 32 geteuid - compat_sys_s390_geteuid16 | 52 | 49 32 geteuid - sys_geteuid16 |
| 53 | 50 32 getegid - compat_sys_s390_getegid16 | 53 | 50 32 getegid - sys_getegid16 |
| 54 | 51 common acct sys_acct compat_sys_acct | 54 | 51 common acct sys_acct sys_acct |
| 55 | 52 common umount2 sys_umount compat_sys_umount | 55 | 52 common umount2 sys_umount sys_umount |
| 56 | 54 common ioctl sys_ioctl compat_sys_ioctl | 56 | 54 common ioctl sys_ioctl compat_sys_ioctl |
| 57 | 55 common fcntl sys_fcntl compat_sys_fcntl | 57 | 55 common fcntl sys_fcntl compat_sys_fcntl |
| 58 | 57 common setpgid sys_setpgid sys_setpgid | 58 | 57 common setpgid sys_setpgid sys_setpgid |
| 59 | 60 common umask sys_umask sys_umask | 59 | 60 common umask sys_umask sys_umask |
| 60 | 61 common chroot sys_chroot compat_sys_chroot | 60 | 61 common chroot sys_chroot sys_chroot |
| 61 | 62 common ustat sys_ustat compat_sys_ustat | 61 | 62 common ustat sys_ustat compat_sys_ustat |
| 62 | 63 common dup2 sys_dup2 sys_dup2 | 62 | 63 common dup2 sys_dup2 sys_dup2 |
| 63 | 64 common getppid sys_getppid sys_getppid | 63 | 64 common getppid sys_getppid sys_getppid |
| 64 | 65 common getpgrp sys_getpgrp sys_getpgrp | 64 | 65 common getpgrp sys_getpgrp sys_getpgrp |
| 65 | 66 common setsid sys_setsid sys_setsid | 65 | 66 common setsid sys_setsid sys_setsid |
| 66 | 67 common sigaction sys_sigaction compat_sys_sigaction | 66 | 67 common sigaction sys_sigaction compat_sys_sigaction |
| 67 | 70 32 setreuid - compat_sys_s390_setreuid16 | 67 | 70 32 setreuid - sys_setreuid16 |
| 68 | 71 32 setregid - compat_sys_s390_setregid16 | 68 | 71 32 setregid - sys_setregid16 |
| 69 | 72 common sigsuspend sys_sigsuspend compat_sys_sigsuspend | 69 | 72 common sigsuspend sys_sigsuspend sys_sigsuspend |
| 70 | 73 common sigpending sys_sigpending compat_sys_sigpending | 70 | 73 common sigpending sys_sigpending compat_sys_sigpending |
| 71 | 74 common sethostname sys_sethostname compat_sys_sethostname | 71 | 74 common sethostname sys_sethostname sys_sethostname |
| 72 | 75 common setrlimit sys_setrlimit compat_sys_setrlimit | 72 | 75 common setrlimit sys_setrlimit compat_sys_setrlimit |
| 73 | 76 32 getrlimit - compat_sys_old_getrlimit | 73 | 76 32 getrlimit - compat_sys_old_getrlimit |
| 74 | 77 common getrusage sys_getrusage compat_sys_getrusage | 74 | 77 common getrusage sys_getrusage compat_sys_getrusage |
| 75 | 78 common gettimeofday sys_gettimeofday compat_sys_gettimeofday | 75 | 78 common gettimeofday sys_gettimeofday compat_sys_gettimeofday |
| 76 | 79 common settimeofday sys_settimeofday compat_sys_settimeofday | 76 | 79 common settimeofday sys_settimeofday compat_sys_settimeofday |
| 77 | 80 32 getgroups - compat_sys_s390_getgroups16 | 77 | 80 32 getgroups - sys_getgroups16 |
| 78 | 81 32 setgroups - compat_sys_s390_setgroups16 | 78 | 81 32 setgroups - sys_setgroups16 |
| 79 | 83 common symlink sys_symlink compat_sys_symlink | 79 | 83 common symlink sys_symlink sys_symlink |
| 80 | 85 common readlink sys_readlink compat_sys_readlink | 80 | 85 common readlink sys_readlink sys_readlink |
| 81 | 86 common uselib sys_uselib compat_sys_uselib | 81 | 86 common uselib sys_uselib sys_uselib |
| 82 | 87 common swapon sys_swapon compat_sys_swapon | 82 | 87 common swapon sys_swapon sys_swapon |
| 83 | 88 common reboot sys_reboot compat_sys_reboot | 83 | 88 common reboot sys_reboot sys_reboot |
| 84 | 89 common readdir - compat_sys_old_readdir | 84 | 89 common readdir - compat_sys_old_readdir |
| 85 | 90 common mmap sys_old_mmap compat_sys_s390_old_mmap | 85 | 90 common mmap sys_old_mmap compat_sys_s390_old_mmap |
| 86 | 91 common munmap sys_munmap compat_sys_munmap | 86 | 91 common munmap sys_munmap sys_munmap |
| 87 | 92 common truncate sys_truncate compat_sys_truncate | 87 | 92 common truncate sys_truncate compat_sys_truncate |
| 88 | 93 common ftruncate sys_ftruncate compat_sys_ftruncate | 88 | 93 common ftruncate sys_ftruncate compat_sys_ftruncate |
| 89 | 94 common fchmod sys_fchmod sys_fchmod | 89 | 94 common fchmod sys_fchmod sys_fchmod |
| 90 | 95 32 fchown - compat_sys_s390_fchown16 | 90 | 95 32 fchown - sys_fchown16 |
| 91 | 96 common getpriority sys_getpriority sys_getpriority | 91 | 96 common getpriority sys_getpriority sys_getpriority |
| 92 | 97 common setpriority sys_setpriority sys_setpriority | 92 | 97 common setpriority sys_setpriority sys_setpriority |
| 93 | 99 common statfs sys_statfs compat_sys_statfs | 93 | 99 common statfs sys_statfs compat_sys_statfs |
| 94 | 100 common fstatfs sys_fstatfs compat_sys_fstatfs | 94 | 100 common fstatfs sys_fstatfs compat_sys_fstatfs |
| 95 | 101 32 ioperm - - | 95 | 101 32 ioperm - - |
| 96 | 102 common socketcall sys_socketcall compat_sys_socketcall | 96 | 102 common socketcall sys_socketcall compat_sys_socketcall |
| 97 | 103 common syslog sys_syslog compat_sys_syslog | 97 | 103 common syslog sys_syslog sys_syslog |
| 98 | 104 common setitimer sys_setitimer compat_sys_setitimer | 98 | 104 common setitimer sys_setitimer compat_sys_setitimer |
| 99 | 105 common getitimer sys_getitimer compat_sys_getitimer | 99 | 105 common getitimer sys_getitimer compat_sys_getitimer |
| 100 | 106 common stat sys_newstat compat_sys_newstat | 100 | 106 common stat sys_newstat compat_sys_newstat |
| @@ -104,63 +104,63 @@ | |||
| 104 | 111 common vhangup sys_vhangup sys_vhangup | 104 | 111 common vhangup sys_vhangup sys_vhangup |
| 105 | 112 common idle - - | 105 | 112 common idle - - |
| 106 | 114 common wait4 sys_wait4 compat_sys_wait4 | 106 | 114 common wait4 sys_wait4 compat_sys_wait4 |
| 107 | 115 common swapoff sys_swapoff compat_sys_swapoff | 107 | 115 common swapoff sys_swapoff sys_swapoff |
| 108 | 116 common sysinfo sys_sysinfo compat_sys_sysinfo | 108 | 116 common sysinfo sys_sysinfo compat_sys_sysinfo |
| 109 | 117 common ipc sys_s390_ipc compat_sys_s390_ipc | 109 | 117 common ipc sys_s390_ipc compat_sys_s390_ipc |
| 110 | 118 common fsync sys_fsync sys_fsync | 110 | 118 common fsync sys_fsync sys_fsync |
| 111 | 119 common sigreturn sys_sigreturn compat_sys_sigreturn | 111 | 119 common sigreturn sys_sigreturn compat_sys_sigreturn |
| 112 | 120 common clone sys_clone compat_sys_clone | 112 | 120 common clone sys_clone sys_clone |
| 113 | 121 common setdomainname sys_setdomainname compat_sys_setdomainname | 113 | 121 common setdomainname sys_setdomainname sys_setdomainname |
| 114 | 122 common uname sys_newuname compat_sys_newuname | 114 | 122 common uname sys_newuname sys_newuname |
| 115 | 124 common adjtimex sys_adjtimex compat_sys_adjtimex | 115 | 124 common adjtimex sys_adjtimex compat_sys_adjtimex |
| 116 | 125 common mprotect sys_mprotect compat_sys_mprotect | 116 | 125 common mprotect sys_mprotect sys_mprotect |
| 117 | 126 common sigprocmask sys_sigprocmask compat_sys_sigprocmask | 117 | 126 common sigprocmask sys_sigprocmask compat_sys_sigprocmask |
| 118 | 127 common create_module - - | 118 | 127 common create_module - - |
| 119 | 128 common init_module sys_init_module compat_sys_init_module | 119 | 128 common init_module sys_init_module sys_init_module |
| 120 | 129 common delete_module sys_delete_module compat_sys_delete_module | 120 | 129 common delete_module sys_delete_module sys_delete_module |
| 121 | 130 common get_kernel_syms - - | 121 | 130 common get_kernel_syms - - |
| 122 | 131 common quotactl sys_quotactl compat_sys_quotactl | 122 | 131 common quotactl sys_quotactl sys_quotactl |
| 123 | 132 common getpgid sys_getpgid sys_getpgid | 123 | 132 common getpgid sys_getpgid sys_getpgid |
| 124 | 133 common fchdir sys_fchdir sys_fchdir | 124 | 133 common fchdir sys_fchdir sys_fchdir |
| 125 | 134 common bdflush sys_bdflush compat_sys_bdflush | 125 | 134 common bdflush sys_bdflush sys_bdflush |
| 126 | 135 common sysfs sys_sysfs compat_sys_sysfs | 126 | 135 common sysfs sys_sysfs sys_sysfs |
| 127 | 136 common personality sys_s390_personality sys_s390_personality | 127 | 136 common personality sys_s390_personality sys_s390_personality |
| 128 | 137 common afs_syscall - - | 128 | 137 common afs_syscall - - |
| 129 | 138 32 setfsuid - compat_sys_s390_setfsuid16 | 129 | 138 32 setfsuid - sys_setfsuid16 |
| 130 | 139 32 setfsgid - compat_sys_s390_setfsgid16 | 130 | 139 32 setfsgid - sys_setfsgid16 |
| 131 | 140 32 _llseek - compat_sys_llseek | 131 | 140 32 _llseek - sys_llseek |
| 132 | 141 common getdents sys_getdents compat_sys_getdents | 132 | 141 common getdents sys_getdents compat_sys_getdents |
| 133 | 142 32 _newselect - compat_sys_select | 133 | 142 32 _newselect - compat_sys_select |
| 134 | 142 64 select sys_select - | 134 | 142 64 select sys_select - |
| 135 | 143 common flock sys_flock sys_flock | 135 | 143 common flock sys_flock sys_flock |
| 136 | 144 common msync sys_msync compat_sys_msync | 136 | 144 common msync sys_msync sys_msync |
| 137 | 145 common readv sys_readv compat_sys_readv | 137 | 145 common readv sys_readv compat_sys_readv |
| 138 | 146 common writev sys_writev compat_sys_writev | 138 | 146 common writev sys_writev compat_sys_writev |
| 139 | 147 common getsid sys_getsid sys_getsid | 139 | 147 common getsid sys_getsid sys_getsid |
| 140 | 148 common fdatasync sys_fdatasync sys_fdatasync | 140 | 148 common fdatasync sys_fdatasync sys_fdatasync |
| 141 | 149 common _sysctl sys_sysctl compat_sys_sysctl | 141 | 149 common _sysctl sys_sysctl compat_sys_sysctl |
| 142 | 150 common mlock sys_mlock compat_sys_mlock | 142 | 150 common mlock sys_mlock sys_mlock |
| 143 | 151 common munlock sys_munlock compat_sys_munlock | 143 | 151 common munlock sys_munlock sys_munlock |
| 144 | 152 common mlockall sys_mlockall sys_mlockall | 144 | 152 common mlockall sys_mlockall sys_mlockall |
| 145 | 153 common munlockall sys_munlockall sys_munlockall | 145 | 153 common munlockall sys_munlockall sys_munlockall |
| 146 | 154 common sched_setparam sys_sched_setparam compat_sys_sched_setparam | 146 | 154 common sched_setparam sys_sched_setparam sys_sched_setparam |
| 147 | 155 common sched_getparam sys_sched_getparam compat_sys_sched_getparam | 147 | 155 common sched_getparam sys_sched_getparam sys_sched_getparam |
| 148 | 156 common sched_setscheduler sys_sched_setscheduler compat_sys_sched_setscheduler | 148 | 156 common sched_setscheduler sys_sched_setscheduler sys_sched_setscheduler |
| 149 | 157 common sched_getscheduler sys_sched_getscheduler sys_sched_getscheduler | 149 | 157 common sched_getscheduler sys_sched_getscheduler sys_sched_getscheduler |
| 150 | 158 common sched_yield sys_sched_yield sys_sched_yield | 150 | 158 common sched_yield sys_sched_yield sys_sched_yield |
| 151 | 159 common sched_get_priority_max sys_sched_get_priority_max sys_sched_get_priority_max | 151 | 159 common sched_get_priority_max sys_sched_get_priority_max sys_sched_get_priority_max |
| 152 | 160 common sched_get_priority_min sys_sched_get_priority_min sys_sched_get_priority_min | 152 | 160 common sched_get_priority_min sys_sched_get_priority_min sys_sched_get_priority_min |
| 153 | 161 common sched_rr_get_interval sys_sched_rr_get_interval compat_sys_sched_rr_get_interval | 153 | 161 common sched_rr_get_interval sys_sched_rr_get_interval compat_sys_sched_rr_get_interval |
| 154 | 162 common nanosleep sys_nanosleep compat_sys_nanosleep | 154 | 162 common nanosleep sys_nanosleep compat_sys_nanosleep |
| 155 | 163 common mremap sys_mremap compat_sys_mremap | 155 | 163 common mremap sys_mremap sys_mremap |
| 156 | 164 32 setresuid - compat_sys_s390_setresuid16 | 156 | 164 32 setresuid - sys_setresuid16 |
| 157 | 165 32 getresuid - compat_sys_s390_getresuid16 | 157 | 165 32 getresuid - sys_getresuid16 |
| 158 | 167 common query_module - - | 158 | 167 common query_module - - |
| 159 | 168 common poll sys_poll compat_sys_poll | 159 | 168 common poll sys_poll sys_poll |
| 160 | 169 common nfsservctl - - | 160 | 169 common nfsservctl - - |
| 161 | 170 32 setresgid - compat_sys_s390_setresgid16 | 161 | 170 32 setresgid - sys_setresgid16 |
| 162 | 171 32 getresgid - compat_sys_s390_getresgid16 | 162 | 171 32 getresgid - sys_getresgid16 |
| 163 | 172 common prctl sys_prctl compat_sys_prctl | 163 | 172 common prctl sys_prctl sys_prctl |
| 164 | 173 common rt_sigreturn sys_rt_sigreturn compat_sys_rt_sigreturn | 164 | 173 common rt_sigreturn sys_rt_sigreturn compat_sys_rt_sigreturn |
| 165 | 174 common rt_sigaction sys_rt_sigaction compat_sys_rt_sigaction | 165 | 174 common rt_sigaction sys_rt_sigaction compat_sys_rt_sigaction |
| 166 | 175 common rt_sigprocmask sys_rt_sigprocmask compat_sys_rt_sigprocmask | 166 | 175 common rt_sigprocmask sys_rt_sigprocmask compat_sys_rt_sigprocmask |
| @@ -170,10 +170,10 @@ | |||
| 170 | 179 common rt_sigsuspend sys_rt_sigsuspend compat_sys_rt_sigsuspend | 170 | 179 common rt_sigsuspend sys_rt_sigsuspend compat_sys_rt_sigsuspend |
| 171 | 180 common pread64 sys_pread64 compat_sys_s390_pread64 | 171 | 180 common pread64 sys_pread64 compat_sys_s390_pread64 |
| 172 | 181 common pwrite64 sys_pwrite64 compat_sys_s390_pwrite64 | 172 | 181 common pwrite64 sys_pwrite64 compat_sys_s390_pwrite64 |
| 173 | 182 32 chown - compat_sys_s390_chown16 | 173 | 182 32 chown - sys_chown16 |
| 174 | 183 common getcwd sys_getcwd compat_sys_getcwd | 174 | 183 common getcwd sys_getcwd sys_getcwd |
| 175 | 184 common capget sys_capget compat_sys_capget | 175 | 184 common capget sys_capget sys_capget |
| 176 | 185 common capset sys_capset compat_sys_capset | 176 | 185 common capset sys_capset sys_capset |
| 177 | 186 common sigaltstack sys_sigaltstack compat_sys_sigaltstack | 177 | 186 common sigaltstack sys_sigaltstack compat_sys_sigaltstack |
| 178 | 187 common sendfile sys_sendfile64 compat_sys_sendfile | 178 | 187 common sendfile sys_sendfile64 compat_sys_sendfile |
| 179 | 188 common getpmsg - - | 179 | 188 common getpmsg - - |
| @@ -187,7 +187,7 @@ | |||
| 187 | 195 32 stat64 - compat_sys_s390_stat64 | 187 | 195 32 stat64 - compat_sys_s390_stat64 |
| 188 | 196 32 lstat64 - compat_sys_s390_lstat64 | 188 | 196 32 lstat64 - compat_sys_s390_lstat64 |
| 189 | 197 32 fstat64 - compat_sys_s390_fstat64 | 189 | 197 32 fstat64 - compat_sys_s390_fstat64 |
| 190 | 198 32 lchown32 - compat_sys_lchown | 190 | 198 32 lchown32 - sys_lchown |
| 191 | 198 64 lchown sys_lchown - | 191 | 198 64 lchown sys_lchown - |
| 192 | 199 32 getuid32 - sys_getuid | 192 | 199 32 getuid32 - sys_getuid |
| 193 | 199 64 getuid sys_getuid - | 193 | 199 64 getuid sys_getuid - |
| @@ -201,21 +201,21 @@ | |||
| 201 | 203 64 setreuid sys_setreuid - | 201 | 203 64 setreuid sys_setreuid - |
| 202 | 204 32 setregid32 - sys_setregid | 202 | 204 32 setregid32 - sys_setregid |
| 203 | 204 64 setregid sys_setregid - | 203 | 204 64 setregid sys_setregid - |
| 204 | 205 32 getgroups32 - compat_sys_getgroups | 204 | 205 32 getgroups32 - sys_getgroups |
| 205 | 205 64 getgroups sys_getgroups - | 205 | 205 64 getgroups sys_getgroups - |
| 206 | 206 32 setgroups32 - compat_sys_setgroups | 206 | 206 32 setgroups32 - sys_setgroups |
| 207 | 206 64 setgroups sys_setgroups - | 207 | 206 64 setgroups sys_setgroups - |
| 208 | 207 32 fchown32 - sys_fchown | 208 | 207 32 fchown32 - sys_fchown |
| 209 | 207 64 fchown sys_fchown - | 209 | 207 64 fchown sys_fchown - |
| 210 | 208 32 setresuid32 - sys_setresuid | 210 | 208 32 setresuid32 - sys_setresuid |
| 211 | 208 64 setresuid sys_setresuid - | 211 | 208 64 setresuid sys_setresuid - |
| 212 | 209 32 getresuid32 - compat_sys_getresuid | 212 | 209 32 getresuid32 - sys_getresuid |
| 213 | 209 64 getresuid sys_getresuid - | 213 | 209 64 getresuid sys_getresuid - |
| 214 | 210 32 setresgid32 - sys_setresgid | 214 | 210 32 setresgid32 - sys_setresgid |
| 215 | 210 64 setresgid sys_setresgid - | 215 | 210 64 setresgid sys_setresgid - |
| 216 | 211 32 getresgid32 - compat_sys_getresgid | 216 | 211 32 getresgid32 - sys_getresgid |
| 217 | 211 64 getresgid sys_getresgid - | 217 | 211 64 getresgid sys_getresgid - |
| 218 | 212 32 chown32 - compat_sys_chown | 218 | 212 32 chown32 - sys_chown |
| 219 | 212 64 chown sys_chown - | 219 | 212 64 chown sys_chown - |
| 220 | 213 32 setuid32 - sys_setuid | 220 | 213 32 setuid32 - sys_setuid |
| 221 | 213 64 setuid sys_setuid - | 221 | 213 64 setuid sys_setuid - |
| @@ -225,25 +225,25 @@ | |||
| 225 | 215 64 setfsuid sys_setfsuid - | 225 | 215 64 setfsuid sys_setfsuid - |
| 226 | 216 32 setfsgid32 - sys_setfsgid | 226 | 216 32 setfsgid32 - sys_setfsgid |
| 227 | 216 64 setfsgid sys_setfsgid - | 227 | 216 64 setfsgid sys_setfsgid - |
| 228 | 217 common pivot_root sys_pivot_root compat_sys_pivot_root | 228 | 217 common pivot_root sys_pivot_root sys_pivot_root |
| 229 | 218 common mincore sys_mincore compat_sys_mincore | 229 | 218 common mincore sys_mincore sys_mincore |
| 230 | 219 common madvise sys_madvise compat_sys_madvise | 230 | 219 common madvise sys_madvise sys_madvise |
| 231 | 220 common getdents64 sys_getdents64 compat_sys_getdents64 | 231 | 220 common getdents64 sys_getdents64 sys_getdents64 |
| 232 | 221 32 fcntl64 - compat_sys_fcntl64 | 232 | 221 32 fcntl64 - compat_sys_fcntl64 |
| 233 | 222 common readahead sys_readahead compat_sys_s390_readahead | 233 | 222 common readahead sys_readahead compat_sys_s390_readahead |
| 234 | 223 32 sendfile64 - compat_sys_sendfile64 | 234 | 223 32 sendfile64 - compat_sys_sendfile64 |
| 235 | 224 common setxattr sys_setxattr compat_sys_setxattr | 235 | 224 common setxattr sys_setxattr sys_setxattr |
| 236 | 225 common lsetxattr sys_lsetxattr compat_sys_lsetxattr | 236 | 225 common lsetxattr sys_lsetxattr sys_lsetxattr |
| 237 | 226 common fsetxattr sys_fsetxattr compat_sys_fsetxattr | 237 | 226 common fsetxattr sys_fsetxattr sys_fsetxattr |
| 238 | 227 common getxattr sys_getxattr compat_sys_getxattr | 238 | 227 common getxattr sys_getxattr sys_getxattr |
| 239 | 228 common lgetxattr sys_lgetxattr compat_sys_lgetxattr | 239 | 228 common lgetxattr sys_lgetxattr sys_lgetxattr |
| 240 | 229 common fgetxattr sys_fgetxattr compat_sys_fgetxattr | 240 | 229 common fgetxattr sys_fgetxattr sys_fgetxattr |
| 241 | 230 common listxattr sys_listxattr compat_sys_listxattr | 241 | 230 common listxattr sys_listxattr sys_listxattr |
| 242 | 231 common llistxattr sys_llistxattr compat_sys_llistxattr | 242 | 231 common llistxattr sys_llistxattr sys_llistxattr |
| 243 | 232 common flistxattr sys_flistxattr compat_sys_flistxattr | 243 | 232 common flistxattr sys_flistxattr sys_flistxattr |
| 244 | 233 common removexattr sys_removexattr compat_sys_removexattr | 244 | 233 common removexattr sys_removexattr sys_removexattr |
| 245 | 234 common lremovexattr sys_lremovexattr compat_sys_lremovexattr | 245 | 234 common lremovexattr sys_lremovexattr sys_lremovexattr |
| 246 | 235 common fremovexattr sys_fremovexattr compat_sys_fremovexattr | 246 | 235 common fremovexattr sys_fremovexattr sys_fremovexattr |
| 247 | 236 common gettid sys_gettid sys_gettid | 247 | 236 common gettid sys_gettid sys_gettid |
| 248 | 237 common tkill sys_tkill sys_tkill | 248 | 237 common tkill sys_tkill sys_tkill |
| 249 | 238 common futex sys_futex compat_sys_futex | 249 | 238 common futex sys_futex compat_sys_futex |
| @@ -251,15 +251,15 @@ | |||
| 251 | 240 common sched_getaffinity sys_sched_getaffinity compat_sys_sched_getaffinity | 251 | 240 common sched_getaffinity sys_sched_getaffinity compat_sys_sched_getaffinity |
| 252 | 241 common tgkill sys_tgkill sys_tgkill | 252 | 241 common tgkill sys_tgkill sys_tgkill |
| 253 | 243 common io_setup sys_io_setup compat_sys_io_setup | 253 | 243 common io_setup sys_io_setup compat_sys_io_setup |
| 254 | 244 common io_destroy sys_io_destroy compat_sys_io_destroy | 254 | 244 common io_destroy sys_io_destroy sys_io_destroy |
| 255 | 245 common io_getevents sys_io_getevents compat_sys_io_getevents | 255 | 245 common io_getevents sys_io_getevents compat_sys_io_getevents |
| 256 | 246 common io_submit sys_io_submit compat_sys_io_submit | 256 | 246 common io_submit sys_io_submit compat_sys_io_submit |
| 257 | 247 common io_cancel sys_io_cancel compat_sys_io_cancel | 257 | 247 common io_cancel sys_io_cancel sys_io_cancel |
| 258 | 248 common exit_group sys_exit_group sys_exit_group | 258 | 248 common exit_group sys_exit_group sys_exit_group |
| 259 | 249 common epoll_create sys_epoll_create sys_epoll_create | 259 | 249 common epoll_create sys_epoll_create sys_epoll_create |
| 260 | 250 common epoll_ctl sys_epoll_ctl compat_sys_epoll_ctl | 260 | 250 common epoll_ctl sys_epoll_ctl sys_epoll_ctl |
| 261 | 251 common epoll_wait sys_epoll_wait compat_sys_epoll_wait | 261 | 251 common epoll_wait sys_epoll_wait sys_epoll_wait |
| 262 | 252 common set_tid_address sys_set_tid_address compat_sys_set_tid_address | 262 | 252 common set_tid_address sys_set_tid_address sys_set_tid_address |
| 263 | 253 common fadvise64 sys_fadvise64_64 compat_sys_s390_fadvise64 | 263 | 253 common fadvise64 sys_fadvise64_64 compat_sys_s390_fadvise64 |
| 264 | 254 common timer_create sys_timer_create compat_sys_timer_create | 264 | 254 common timer_create sys_timer_create compat_sys_timer_create |
| 265 | 255 common timer_settime sys_timer_settime compat_sys_timer_settime | 265 | 255 common timer_settime sys_timer_settime compat_sys_timer_settime |
| @@ -273,52 +273,52 @@ | |||
| 273 | 264 32 fadvise64_64 - compat_sys_s390_fadvise64_64 | 273 | 264 32 fadvise64_64 - compat_sys_s390_fadvise64_64 |
| 274 | 265 common statfs64 sys_statfs64 compat_sys_statfs64 | 274 | 265 common statfs64 sys_statfs64 compat_sys_statfs64 |
| 275 | 266 common fstatfs64 sys_fstatfs64 compat_sys_fstatfs64 | 275 | 266 common fstatfs64 sys_fstatfs64 compat_sys_fstatfs64 |
| 276 | 267 common remap_file_pages sys_remap_file_pages compat_sys_remap_file_pages | 276 | 267 common remap_file_pages sys_remap_file_pages sys_remap_file_pages |
| 277 | 268 common mbind sys_mbind compat_sys_mbind | 277 | 268 common mbind sys_mbind compat_sys_mbind |
| 278 | 269 common get_mempolicy sys_get_mempolicy compat_sys_get_mempolicy | 278 | 269 common get_mempolicy sys_get_mempolicy compat_sys_get_mempolicy |
| 279 | 270 common set_mempolicy sys_set_mempolicy compat_sys_set_mempolicy | 279 | 270 common set_mempolicy sys_set_mempolicy compat_sys_set_mempolicy |
| 280 | 271 common mq_open sys_mq_open compat_sys_mq_open | 280 | 271 common mq_open sys_mq_open compat_sys_mq_open |
| 281 | 272 common mq_unlink sys_mq_unlink compat_sys_mq_unlink | 281 | 272 common mq_unlink sys_mq_unlink sys_mq_unlink |
| 282 | 273 common mq_timedsend sys_mq_timedsend compat_sys_mq_timedsend | 282 | 273 common mq_timedsend sys_mq_timedsend compat_sys_mq_timedsend |
| 283 | 274 common mq_timedreceive sys_mq_timedreceive compat_sys_mq_timedreceive | 283 | 274 common mq_timedreceive sys_mq_timedreceive compat_sys_mq_timedreceive |
| 284 | 275 common mq_notify sys_mq_notify compat_sys_mq_notify | 284 | 275 common mq_notify sys_mq_notify compat_sys_mq_notify |
| 285 | 276 common mq_getsetattr sys_mq_getsetattr compat_sys_mq_getsetattr | 285 | 276 common mq_getsetattr sys_mq_getsetattr compat_sys_mq_getsetattr |
| 286 | 277 common kexec_load sys_kexec_load compat_sys_kexec_load | 286 | 277 common kexec_load sys_kexec_load compat_sys_kexec_load |
| 287 | 278 common add_key sys_add_key compat_sys_add_key | 287 | 278 common add_key sys_add_key sys_add_key |
| 288 | 279 common request_key sys_request_key compat_sys_request_key | 288 | 279 common request_key sys_request_key sys_request_key |
| 289 | 280 common keyctl sys_keyctl compat_sys_keyctl | 289 | 280 common keyctl sys_keyctl compat_sys_keyctl |
| 290 | 281 common waitid sys_waitid compat_sys_waitid | 290 | 281 common waitid sys_waitid compat_sys_waitid |
| 291 | 282 common ioprio_set sys_ioprio_set sys_ioprio_set | 291 | 282 common ioprio_set sys_ioprio_set sys_ioprio_set |
| 292 | 283 common ioprio_get sys_ioprio_get sys_ioprio_get | 292 | 283 common ioprio_get sys_ioprio_get sys_ioprio_get |
| 293 | 284 common inotify_init sys_inotify_init sys_inotify_init | 293 | 284 common inotify_init sys_inotify_init sys_inotify_init |
| 294 | 285 common inotify_add_watch sys_inotify_add_watch compat_sys_inotify_add_watch | 294 | 285 common inotify_add_watch sys_inotify_add_watch sys_inotify_add_watch |
| 295 | 286 common inotify_rm_watch sys_inotify_rm_watch sys_inotify_rm_watch | 295 | 286 common inotify_rm_watch sys_inotify_rm_watch sys_inotify_rm_watch |
| 296 | 287 common migrate_pages sys_migrate_pages compat_sys_migrate_pages | 296 | 287 common migrate_pages sys_migrate_pages compat_sys_migrate_pages |
| 297 | 288 common openat sys_openat compat_sys_openat | 297 | 288 common openat sys_openat compat_sys_openat |
| 298 | 289 common mkdirat sys_mkdirat compat_sys_mkdirat | 298 | 289 common mkdirat sys_mkdirat sys_mkdirat |
| 299 | 290 common mknodat sys_mknodat compat_sys_mknodat | 299 | 290 common mknodat sys_mknodat sys_mknodat |
| 300 | 291 common fchownat sys_fchownat compat_sys_fchownat | 300 | 291 common fchownat sys_fchownat sys_fchownat |
| 301 | 292 common futimesat sys_futimesat compat_sys_futimesat | 301 | 292 common futimesat sys_futimesat compat_sys_futimesat |
| 302 | 293 32 fstatat64 - compat_sys_s390_fstatat64 | 302 | 293 32 fstatat64 - compat_sys_s390_fstatat64 |
| 303 | 293 64 newfstatat sys_newfstatat - | 303 | 293 64 newfstatat sys_newfstatat - |
| 304 | 294 common unlinkat sys_unlinkat compat_sys_unlinkat | 304 | 294 common unlinkat sys_unlinkat sys_unlinkat |
| 305 | 295 common renameat sys_renameat compat_sys_renameat | 305 | 295 common renameat sys_renameat sys_renameat |
| 306 | 296 common linkat sys_linkat compat_sys_linkat | 306 | 296 common linkat sys_linkat sys_linkat |
| 307 | 297 common symlinkat sys_symlinkat compat_sys_symlinkat | 307 | 297 common symlinkat sys_symlinkat sys_symlinkat |
| 308 | 298 common readlinkat sys_readlinkat compat_sys_readlinkat | 308 | 298 common readlinkat sys_readlinkat sys_readlinkat |
| 309 | 299 common fchmodat sys_fchmodat compat_sys_fchmodat | 309 | 299 common fchmodat sys_fchmodat sys_fchmodat |
| 310 | 300 common faccessat sys_faccessat compat_sys_faccessat | 310 | 300 common faccessat sys_faccessat sys_faccessat |
| 311 | 301 common pselect6 sys_pselect6 compat_sys_pselect6 | 311 | 301 common pselect6 sys_pselect6 compat_sys_pselect6 |
| 312 | 302 common ppoll sys_ppoll compat_sys_ppoll | 312 | 302 common ppoll sys_ppoll compat_sys_ppoll |
| 313 | 303 common unshare sys_unshare compat_sys_unshare | 313 | 303 common unshare sys_unshare sys_unshare |
| 314 | 304 common set_robust_list sys_set_robust_list compat_sys_set_robust_list | 314 | 304 common set_robust_list sys_set_robust_list compat_sys_set_robust_list |
| 315 | 305 common get_robust_list sys_get_robust_list compat_sys_get_robust_list | 315 | 305 common get_robust_list sys_get_robust_list compat_sys_get_robust_list |
| 316 | 306 common splice sys_splice compat_sys_splice | 316 | 306 common splice sys_splice sys_splice |
| 317 | 307 common sync_file_range sys_sync_file_range compat_sys_s390_sync_file_range | 317 | 307 common sync_file_range sys_sync_file_range compat_sys_s390_sync_file_range |
| 318 | 308 common tee sys_tee compat_sys_tee | 318 | 308 common tee sys_tee sys_tee |
| 319 | 309 common vmsplice sys_vmsplice compat_sys_vmsplice | 319 | 309 common vmsplice sys_vmsplice compat_sys_vmsplice |
| 320 | 310 common move_pages sys_move_pages compat_sys_move_pages | 320 | 310 common move_pages sys_move_pages compat_sys_move_pages |
| 321 | 311 common getcpu sys_getcpu compat_sys_getcpu | 321 | 311 common getcpu sys_getcpu sys_getcpu |
| 322 | 312 common epoll_pwait sys_epoll_pwait compat_sys_epoll_pwait | 322 | 312 common epoll_pwait sys_epoll_pwait compat_sys_epoll_pwait |
| 323 | 313 common utimes sys_utimes compat_sys_utimes | 323 | 313 common utimes sys_utimes compat_sys_utimes |
| 324 | 314 common fallocate sys_fallocate compat_sys_s390_fallocate | 324 | 314 common fallocate sys_fallocate compat_sys_s390_fallocate |
| @@ -332,17 +332,17 @@ | |||
| 332 | 322 common signalfd4 sys_signalfd4 compat_sys_signalfd4 | 332 | 322 common signalfd4 sys_signalfd4 compat_sys_signalfd4 |
| 333 | 323 common eventfd2 sys_eventfd2 sys_eventfd2 | 333 | 323 common eventfd2 sys_eventfd2 sys_eventfd2 |
| 334 | 324 common inotify_init1 sys_inotify_init1 sys_inotify_init1 | 334 | 324 common inotify_init1 sys_inotify_init1 sys_inotify_init1 |
| 335 | 325 common pipe2 sys_pipe2 compat_sys_pipe2 | 335 | 325 common pipe2 sys_pipe2 sys_pipe2 |
| 336 | 326 common dup3 sys_dup3 sys_dup3 | 336 | 326 common dup3 sys_dup3 sys_dup3 |
| 337 | 327 common epoll_create1 sys_epoll_create1 sys_epoll_create1 | 337 | 327 common epoll_create1 sys_epoll_create1 sys_epoll_create1 |
| 338 | 328 common preadv sys_preadv compat_sys_preadv | 338 | 328 common preadv sys_preadv compat_sys_preadv |
| 339 | 329 common pwritev sys_pwritev compat_sys_pwritev | 339 | 329 common pwritev sys_pwritev compat_sys_pwritev |
| 340 | 330 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo | 340 | 330 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo |
| 341 | 331 common perf_event_open sys_perf_event_open compat_sys_perf_event_open | 341 | 331 common perf_event_open sys_perf_event_open sys_perf_event_open |
| 342 | 332 common fanotify_init sys_fanotify_init sys_fanotify_init | 342 | 332 common fanotify_init sys_fanotify_init sys_fanotify_init |
| 343 | 333 common fanotify_mark sys_fanotify_mark compat_sys_fanotify_mark | 343 | 333 common fanotify_mark sys_fanotify_mark compat_sys_fanotify_mark |
| 344 | 334 common prlimit64 sys_prlimit64 compat_sys_prlimit64 | 344 | 334 common prlimit64 sys_prlimit64 sys_prlimit64 |
| 345 | 335 common name_to_handle_at sys_name_to_handle_at compat_sys_name_to_handle_at | 345 | 335 common name_to_handle_at sys_name_to_handle_at sys_name_to_handle_at |
| 346 | 336 common open_by_handle_at sys_open_by_handle_at compat_sys_open_by_handle_at | 346 | 336 common open_by_handle_at sys_open_by_handle_at compat_sys_open_by_handle_at |
| 347 | 337 common clock_adjtime sys_clock_adjtime compat_sys_clock_adjtime | 347 | 337 common clock_adjtime sys_clock_adjtime compat_sys_clock_adjtime |
| 348 | 338 common syncfs sys_syncfs sys_syncfs | 348 | 338 common syncfs sys_syncfs sys_syncfs |
| @@ -350,44 +350,44 @@ | |||
| 350 | 340 common process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv | 350 | 340 common process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv |
| 351 | 341 common process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev | 351 | 341 common process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev |
| 352 | 342 common s390_runtime_instr sys_s390_runtime_instr sys_s390_runtime_instr | 352 | 342 common s390_runtime_instr sys_s390_runtime_instr sys_s390_runtime_instr |
| 353 | 343 common kcmp sys_kcmp compat_sys_kcmp | 353 | 343 common kcmp sys_kcmp sys_kcmp |
| 354 | 344 common finit_module sys_finit_module compat_sys_finit_module | 354 | 344 common finit_module sys_finit_module sys_finit_module |
| 355 | 345 common sched_setattr sys_sched_setattr compat_sys_sched_setattr | 355 | 345 common sched_setattr sys_sched_setattr sys_sched_setattr |
| 356 | 346 common sched_getattr sys_sched_getattr compat_sys_sched_getattr | 356 | 346 common sched_getattr sys_sched_getattr sys_sched_getattr |
| 357 | 347 common renameat2 sys_renameat2 compat_sys_renameat2 | 357 | 347 common renameat2 sys_renameat2 sys_renameat2 |
| 358 | 348 common seccomp sys_seccomp compat_sys_seccomp | 358 | 348 common seccomp sys_seccomp sys_seccomp |
| 359 | 349 common getrandom sys_getrandom compat_sys_getrandom | 359 | 349 common getrandom sys_getrandom sys_getrandom |
| 360 | 350 common memfd_create sys_memfd_create compat_sys_memfd_create | 360 | 350 common memfd_create sys_memfd_create sys_memfd_create |
| 361 | 351 common bpf sys_bpf compat_sys_bpf | 361 | 351 common bpf sys_bpf sys_bpf |
| 362 | 352 common s390_pci_mmio_write sys_s390_pci_mmio_write compat_sys_s390_pci_mmio_write | 362 | 352 common s390_pci_mmio_write sys_s390_pci_mmio_write sys_s390_pci_mmio_write |
| 363 | 353 common s390_pci_mmio_read sys_s390_pci_mmio_read compat_sys_s390_pci_mmio_read | 363 | 353 common s390_pci_mmio_read sys_s390_pci_mmio_read sys_s390_pci_mmio_read |
| 364 | 354 common execveat sys_execveat compat_sys_execveat | 364 | 354 common execveat sys_execveat compat_sys_execveat |
| 365 | 355 common userfaultfd sys_userfaultfd sys_userfaultfd | 365 | 355 common userfaultfd sys_userfaultfd sys_userfaultfd |
| 366 | 356 common membarrier sys_membarrier sys_membarrier | 366 | 356 common membarrier sys_membarrier sys_membarrier |
| 367 | 357 common recvmmsg sys_recvmmsg compat_sys_recvmmsg | 367 | 357 common recvmmsg sys_recvmmsg compat_sys_recvmmsg |
| 368 | 358 common sendmmsg sys_sendmmsg compat_sys_sendmmsg | 368 | 358 common sendmmsg sys_sendmmsg compat_sys_sendmmsg |
| 369 | 359 common socket sys_socket sys_socket | 369 | 359 common socket sys_socket sys_socket |
| 370 | 360 common socketpair sys_socketpair compat_sys_socketpair | 370 | 360 common socketpair sys_socketpair sys_socketpair |
| 371 | 361 common bind sys_bind compat_sys_bind | 371 | 361 common bind sys_bind sys_bind |
| 372 | 362 common connect sys_connect compat_sys_connect | 372 | 362 common connect sys_connect sys_connect |
| 373 | 363 common listen sys_listen sys_listen | 373 | 363 common listen sys_listen sys_listen |
| 374 | 364 common accept4 sys_accept4 compat_sys_accept4 | 374 | 364 common accept4 sys_accept4 sys_accept4 |
| 375 | 365 common getsockopt sys_getsockopt compat_sys_getsockopt | 375 | 365 common getsockopt sys_getsockopt compat_sys_getsockopt |
| 376 | 366 common setsockopt sys_setsockopt compat_sys_setsockopt | 376 | 366 common setsockopt sys_setsockopt compat_sys_setsockopt |
| 377 | 367 common getsockname sys_getsockname compat_sys_getsockname | 377 | 367 common getsockname sys_getsockname sys_getsockname |
| 378 | 368 common getpeername sys_getpeername compat_sys_getpeername | 378 | 368 common getpeername sys_getpeername sys_getpeername |
| 379 | 369 common sendto sys_sendto compat_sys_sendto | 379 | 369 common sendto sys_sendto sys_sendto |
| 380 | 370 common sendmsg sys_sendmsg compat_sys_sendmsg | 380 | 370 common sendmsg sys_sendmsg compat_sys_sendmsg |
| 381 | 371 common recvfrom sys_recvfrom compat_sys_recvfrom | 381 | 371 common recvfrom sys_recvfrom compat_sys_recvfrom |
| 382 | 372 common recvmsg sys_recvmsg compat_sys_recvmsg | 382 | 372 common recvmsg sys_recvmsg compat_sys_recvmsg |
| 383 | 373 common shutdown sys_shutdown sys_shutdown | 383 | 373 common shutdown sys_shutdown sys_shutdown |
| 384 | 374 common mlock2 sys_mlock2 compat_sys_mlock2 | 384 | 374 common mlock2 sys_mlock2 sys_mlock2 |
| 385 | 375 common copy_file_range sys_copy_file_range compat_sys_copy_file_range | 385 | 375 common copy_file_range sys_copy_file_range sys_copy_file_range |
| 386 | 376 common preadv2 sys_preadv2 compat_sys_preadv2 | 386 | 376 common preadv2 sys_preadv2 compat_sys_preadv2 |
| 387 | 377 common pwritev2 sys_pwritev2 compat_sys_pwritev2 | 387 | 377 common pwritev2 sys_pwritev2 compat_sys_pwritev2 |
| 388 | 378 common s390_guarded_storage sys_s390_guarded_storage compat_sys_s390_guarded_storage | 388 | 378 common s390_guarded_storage sys_s390_guarded_storage sys_s390_guarded_storage |
| 389 | 379 common statx sys_statx compat_sys_statx | 389 | 379 common statx sys_statx sys_statx |
| 390 | 380 common s390_sthyi sys_s390_sthyi compat_sys_s390_sthyi | 390 | 380 common s390_sthyi sys_s390_sthyi sys_s390_sthyi |
| 391 | 381 common kexec_file_load sys_kexec_file_load compat_sys_kexec_file_load | 391 | 381 common kexec_file_load sys_kexec_file_load sys_kexec_file_load |
| 392 | 382 common io_pgetevents sys_io_pgetevents compat_sys_io_pgetevents | 392 | 382 common io_pgetevents sys_io_pgetevents compat_sys_io_pgetevents |
| 393 | 383 common rseq sys_rseq compat_sys_rseq | 393 | 383 common rseq sys_rseq sys_rseq |
diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c index 12f80d1f0415..2ac3c9b56a13 100644 --- a/arch/s390/kernel/sysinfo.c +++ b/arch/s390/kernel/sysinfo.c | |||
| @@ -545,8 +545,6 @@ static __init int stsi_init_debugfs(void) | |||
| 545 | int lvl, i; | 545 | int lvl, i; |
| 546 | 546 | ||
| 547 | stsi_root = debugfs_create_dir("stsi", arch_debugfs_dir); | 547 | stsi_root = debugfs_create_dir("stsi", arch_debugfs_dir); |
| 548 | if (IS_ERR_OR_NULL(stsi_root)) | ||
| 549 | return 0; | ||
| 550 | lvl = stsi(NULL, 0, 0, 0); | 548 | lvl = stsi(NULL, 0, 0, 0); |
| 551 | if (lvl > 0) | 549 | if (lvl > 0) |
| 552 | stsi_0_0_0 = lvl; | 550 | stsi_0_0_0 = lvl; |
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index f24395a01918..98f850e00008 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c | |||
| @@ -69,7 +69,7 @@ static void update_mt_scaling(void) | |||
| 69 | u64 delta, fac, mult, div; | 69 | u64 delta, fac, mult, div; |
| 70 | int i; | 70 | int i; |
| 71 | 71 | ||
| 72 | stcctm5(smp_cpu_mtid + 1, cycles_new); | 72 | stcctm(MT_DIAG, smp_cpu_mtid + 1, cycles_new); |
| 73 | cycles_old = this_cpu_ptr(mt_cycles); | 73 | cycles_old = this_cpu_ptr(mt_cycles); |
| 74 | fac = 1; | 74 | fac = 1; |
| 75 | mult = div = 0; | 75 | mult = div = 0; |
| @@ -432,6 +432,6 @@ void vtime_init(void) | |||
| 432 | __this_cpu_write(mt_scaling_jiffies, jiffies); | 432 | __this_cpu_write(mt_scaling_jiffies, jiffies); |
| 433 | __this_cpu_write(mt_scaling_mult, 1); | 433 | __this_cpu_write(mt_scaling_mult, 1); |
| 434 | __this_cpu_write(mt_scaling_div, 1); | 434 | __this_cpu_write(mt_scaling_div, 1); |
| 435 | stcctm5(smp_cpu_mtid + 1, this_cpu_ptr(mt_cycles)); | 435 | stcctm(MT_DIAG, smp_cpu_mtid + 1, this_cpu_ptr(mt_cycles)); |
| 436 | } | 436 | } |
| 437 | } | 437 | } |
diff --git a/arch/s390/lib/string.c b/arch/s390/lib/string.c index a10e11f7a5f7..0e30e6e43b0c 100644 --- a/arch/s390/lib/string.c +++ b/arch/s390/lib/string.c | |||
| @@ -43,11 +43,13 @@ static inline char *__strnend(const char *s, size_t n) | |||
| 43 | * | 43 | * |
| 44 | * returns the length of @s | 44 | * returns the length of @s |
| 45 | */ | 45 | */ |
| 46 | #ifdef __HAVE_ARCH_STRLEN | ||
| 46 | size_t strlen(const char *s) | 47 | size_t strlen(const char *s) |
| 47 | { | 48 | { |
| 48 | return __strend(s) - s; | 49 | return __strend(s) - s; |
| 49 | } | 50 | } |
| 50 | EXPORT_SYMBOL(strlen); | 51 | EXPORT_SYMBOL(strlen); |
| 52 | #endif | ||
| 51 | 53 | ||
| 52 | /** | 54 | /** |
| 53 | * strnlen - Find the length of a length-limited string | 55 | * strnlen - Find the length of a length-limited string |
| @@ -56,11 +58,13 @@ EXPORT_SYMBOL(strlen); | |||
| 56 | * | 58 | * |
| 57 | * returns the minimum of the length of @s and @n | 59 | * returns the minimum of the length of @s and @n |
| 58 | */ | 60 | */ |
| 61 | #ifdef __HAVE_ARCH_STRNLEN | ||
| 59 | size_t strnlen(const char *s, size_t n) | 62 | size_t strnlen(const char *s, size_t n) |
| 60 | { | 63 | { |
| 61 | return __strnend(s, n) - s; | 64 | return __strnend(s, n) - s; |
| 62 | } | 65 | } |
| 63 | EXPORT_SYMBOL(strnlen); | 66 | EXPORT_SYMBOL(strnlen); |
| 67 | #endif | ||
| 64 | 68 | ||
| 65 | /** | 69 | /** |
| 66 | * strcpy - Copy a %NUL terminated string | 70 | * strcpy - Copy a %NUL terminated string |
| @@ -69,6 +73,7 @@ EXPORT_SYMBOL(strnlen); | |||
| 69 | * | 73 | * |
| 70 | * returns a pointer to @dest | 74 | * returns a pointer to @dest |
| 71 | */ | 75 | */ |
| 76 | #ifdef __HAVE_ARCH_STRCPY | ||
| 72 | char *strcpy(char *dest, const char *src) | 77 | char *strcpy(char *dest, const char *src) |
| 73 | { | 78 | { |
| 74 | register int r0 asm("0") = 0; | 79 | register int r0 asm("0") = 0; |
| @@ -81,6 +86,7 @@ char *strcpy(char *dest, const char *src) | |||
| 81 | return ret; | 86 | return ret; |
| 82 | } | 87 | } |
| 83 | EXPORT_SYMBOL(strcpy); | 88 | EXPORT_SYMBOL(strcpy); |
| 89 | #endif | ||
| 84 | 90 | ||
| 85 | /** | 91 | /** |
| 86 | * strlcpy - Copy a %NUL terminated string into a sized buffer | 92 | * strlcpy - Copy a %NUL terminated string into a sized buffer |
| @@ -93,6 +99,7 @@ EXPORT_SYMBOL(strcpy); | |||
| 93 | * of course, the buffer size is zero). It does not pad | 99 | * of course, the buffer size is zero). It does not pad |
| 94 | * out the result like strncpy() does. | 100 | * out the result like strncpy() does. |
| 95 | */ | 101 | */ |
| 102 | #ifdef __HAVE_ARCH_STRLCPY | ||
| 96 | size_t strlcpy(char *dest, const char *src, size_t size) | 103 | size_t strlcpy(char *dest, const char *src, size_t size) |
| 97 | { | 104 | { |
| 98 | size_t ret = __strend(src) - src; | 105 | size_t ret = __strend(src) - src; |
| @@ -105,6 +112,7 @@ size_t strlcpy(char *dest, const char *src, size_t size) | |||
| 105 | return ret; | 112 | return ret; |
| 106 | } | 113 | } |
| 107 | EXPORT_SYMBOL(strlcpy); | 114 | EXPORT_SYMBOL(strlcpy); |
| 115 | #endif | ||
| 108 | 116 | ||
| 109 | /** | 117 | /** |
| 110 | * strncpy - Copy a length-limited, %NUL-terminated string | 118 | * strncpy - Copy a length-limited, %NUL-terminated string |
| @@ -115,6 +123,7 @@ EXPORT_SYMBOL(strlcpy); | |||
| 115 | * The result is not %NUL-terminated if the source exceeds | 123 | * The result is not %NUL-terminated if the source exceeds |
| 116 | * @n bytes. | 124 | * @n bytes. |
| 117 | */ | 125 | */ |
| 126 | #ifdef __HAVE_ARCH_STRNCPY | ||
| 118 | char *strncpy(char *dest, const char *src, size_t n) | 127 | char *strncpy(char *dest, const char *src, size_t n) |
| 119 | { | 128 | { |
| 120 | size_t len = __strnend(src, n) - src; | 129 | size_t len = __strnend(src, n) - src; |
| @@ -123,6 +132,7 @@ char *strncpy(char *dest, const char *src, size_t n) | |||
| 123 | return dest; | 132 | return dest; |
| 124 | } | 133 | } |
| 125 | EXPORT_SYMBOL(strncpy); | 134 | EXPORT_SYMBOL(strncpy); |
| 135 | #endif | ||
| 126 | 136 | ||
| 127 | /** | 137 | /** |
| 128 | * strcat - Append one %NUL-terminated string to another | 138 | * strcat - Append one %NUL-terminated string to another |
| @@ -131,6 +141,7 @@ EXPORT_SYMBOL(strncpy); | |||
| 131 | * | 141 | * |
| 132 | * returns a pointer to @dest | 142 | * returns a pointer to @dest |
| 133 | */ | 143 | */ |
| 144 | #ifdef __HAVE_ARCH_STRCAT | ||
| 134 | char *strcat(char *dest, const char *src) | 145 | char *strcat(char *dest, const char *src) |
| 135 | { | 146 | { |
| 136 | register int r0 asm("0") = 0; | 147 | register int r0 asm("0") = 0; |
| @@ -146,6 +157,7 @@ char *strcat(char *dest, const char *src) | |||
| 146 | return ret; | 157 | return ret; |
| 147 | } | 158 | } |
| 148 | EXPORT_SYMBOL(strcat); | 159 | EXPORT_SYMBOL(strcat); |
| 160 | #endif | ||
| 149 | 161 | ||
| 150 | /** | 162 | /** |
| 151 | * strlcat - Append a length-limited, %NUL-terminated string to another | 163 | * strlcat - Append a length-limited, %NUL-terminated string to another |
| @@ -153,6 +165,7 @@ EXPORT_SYMBOL(strcat); | |||
| 153 | * @src: The string to append to it | 165 | * @src: The string to append to it |
| 154 | * @n: The size of the destination buffer. | 166 | * @n: The size of the destination buffer. |
| 155 | */ | 167 | */ |
| 168 | #ifdef __HAVE_ARCH_STRLCAT | ||
| 156 | size_t strlcat(char *dest, const char *src, size_t n) | 169 | size_t strlcat(char *dest, const char *src, size_t n) |
| 157 | { | 170 | { |
| 158 | size_t dsize = __strend(dest) - dest; | 171 | size_t dsize = __strend(dest) - dest; |
| @@ -170,6 +183,7 @@ size_t strlcat(char *dest, const char *src, size_t n) | |||
| 170 | return res; | 183 | return res; |
| 171 | } | 184 | } |
| 172 | EXPORT_SYMBOL(strlcat); | 185 | EXPORT_SYMBOL(strlcat); |
| 186 | #endif | ||
| 173 | 187 | ||
| 174 | /** | 188 | /** |
| 175 | * strncat - Append a length-limited, %NUL-terminated string to another | 189 | * strncat - Append a length-limited, %NUL-terminated string to another |
| @@ -182,6 +196,7 @@ EXPORT_SYMBOL(strlcat); | |||
| 182 | * Note that in contrast to strncpy, strncat ensures the result is | 196 | * Note that in contrast to strncpy, strncat ensures the result is |
| 183 | * terminated. | 197 | * terminated. |
| 184 | */ | 198 | */ |
| 199 | #ifdef __HAVE_ARCH_STRNCAT | ||
| 185 | char *strncat(char *dest, const char *src, size_t n) | 200 | char *strncat(char *dest, const char *src, size_t n) |
| 186 | { | 201 | { |
| 187 | size_t len = __strnend(src, n) - src; | 202 | size_t len = __strnend(src, n) - src; |
| @@ -192,6 +207,7 @@ char *strncat(char *dest, const char *src, size_t n) | |||
| 192 | return dest; | 207 | return dest; |
| 193 | } | 208 | } |
| 194 | EXPORT_SYMBOL(strncat); | 209 | EXPORT_SYMBOL(strncat); |
| 210 | #endif | ||
| 195 | 211 | ||
| 196 | /** | 212 | /** |
| 197 | * strcmp - Compare two strings | 213 | * strcmp - Compare two strings |
| @@ -202,6 +218,7 @@ EXPORT_SYMBOL(strncat); | |||
| 202 | * < 0 if @s1 is less than @s2 | 218 | * < 0 if @s1 is less than @s2 |
| 203 | * > 0 if @s1 is greater than @s2 | 219 | * > 0 if @s1 is greater than @s2 |
| 204 | */ | 220 | */ |
| 221 | #ifdef __HAVE_ARCH_STRCMP | ||
| 205 | int strcmp(const char *s1, const char *s2) | 222 | int strcmp(const char *s1, const char *s2) |
| 206 | { | 223 | { |
| 207 | register int r0 asm("0") = 0; | 224 | register int r0 asm("0") = 0; |
| @@ -219,12 +236,14 @@ int strcmp(const char *s1, const char *s2) | |||
| 219 | return ret; | 236 | return ret; |
| 220 | } | 237 | } |
| 221 | EXPORT_SYMBOL(strcmp); | 238 | EXPORT_SYMBOL(strcmp); |
| 239 | #endif | ||
| 222 | 240 | ||
| 223 | /** | 241 | /** |
| 224 | * strrchr - Find the last occurrence of a character in a string | 242 | * strrchr - Find the last occurrence of a character in a string |
| 225 | * @s: The string to be searched | 243 | * @s: The string to be searched |
| 226 | * @c: The character to search for | 244 | * @c: The character to search for |
| 227 | */ | 245 | */ |
| 246 | #ifdef __HAVE_ARCH_STRRCHR | ||
| 228 | char *strrchr(const char *s, int c) | 247 | char *strrchr(const char *s, int c) |
| 229 | { | 248 | { |
| 230 | size_t len = __strend(s) - s; | 249 | size_t len = __strend(s) - s; |
| @@ -237,6 +256,7 @@ char *strrchr(const char *s, int c) | |||
| 237 | return NULL; | 256 | return NULL; |
| 238 | } | 257 | } |
| 239 | EXPORT_SYMBOL(strrchr); | 258 | EXPORT_SYMBOL(strrchr); |
| 259 | #endif | ||
| 240 | 260 | ||
| 241 | static inline int clcle(const char *s1, unsigned long l1, | 261 | static inline int clcle(const char *s1, unsigned long l1, |
| 242 | const char *s2, unsigned long l2) | 262 | const char *s2, unsigned long l2) |
| @@ -261,6 +281,7 @@ static inline int clcle(const char *s1, unsigned long l1, | |||
| 261 | * @s1: The string to be searched | 281 | * @s1: The string to be searched |
| 262 | * @s2: The string to search for | 282 | * @s2: The string to search for |
| 263 | */ | 283 | */ |
| 284 | #ifdef __HAVE_ARCH_STRSTR | ||
| 264 | char *strstr(const char *s1, const char *s2) | 285 | char *strstr(const char *s1, const char *s2) |
| 265 | { | 286 | { |
| 266 | int l1, l2; | 287 | int l1, l2; |
| @@ -280,6 +301,7 @@ char *strstr(const char *s1, const char *s2) | |||
| 280 | return NULL; | 301 | return NULL; |
| 281 | } | 302 | } |
| 282 | EXPORT_SYMBOL(strstr); | 303 | EXPORT_SYMBOL(strstr); |
| 304 | #endif | ||
| 283 | 305 | ||
| 284 | /** | 306 | /** |
| 285 | * memchr - Find a character in an area of memory. | 307 | * memchr - Find a character in an area of memory. |
| @@ -290,6 +312,7 @@ EXPORT_SYMBOL(strstr); | |||
| 290 | * returns the address of the first occurrence of @c, or %NULL | 312 | * returns the address of the first occurrence of @c, or %NULL |
| 291 | * if @c is not found | 313 | * if @c is not found |
| 292 | */ | 314 | */ |
| 315 | #ifdef __HAVE_ARCH_MEMCHR | ||
| 293 | void *memchr(const void *s, int c, size_t n) | 316 | void *memchr(const void *s, int c, size_t n) |
| 294 | { | 317 | { |
| 295 | register int r0 asm("0") = (char) c; | 318 | register int r0 asm("0") = (char) c; |
| @@ -304,6 +327,7 @@ void *memchr(const void *s, int c, size_t n) | |||
| 304 | return (void *) ret; | 327 | return (void *) ret; |
| 305 | } | 328 | } |
| 306 | EXPORT_SYMBOL(memchr); | 329 | EXPORT_SYMBOL(memchr); |
| 330 | #endif | ||
| 307 | 331 | ||
| 308 | /** | 332 | /** |
| 309 | * memcmp - Compare two areas of memory | 333 | * memcmp - Compare two areas of memory |
| @@ -311,6 +335,7 @@ EXPORT_SYMBOL(memchr); | |||
| 311 | * @s2: Another area of memory | 335 | * @s2: Another area of memory |
| 312 | * @count: The size of the area. | 336 | * @count: The size of the area. |
| 313 | */ | 337 | */ |
| 338 | #ifdef __HAVE_ARCH_MEMCMP | ||
| 314 | int memcmp(const void *s1, const void *s2, size_t n) | 339 | int memcmp(const void *s1, const void *s2, size_t n) |
| 315 | { | 340 | { |
| 316 | int ret; | 341 | int ret; |
| @@ -321,6 +346,7 @@ int memcmp(const void *s1, const void *s2, size_t n) | |||
| 321 | return ret; | 346 | return ret; |
| 322 | } | 347 | } |
| 323 | EXPORT_SYMBOL(memcmp); | 348 | EXPORT_SYMBOL(memcmp); |
| 349 | #endif | ||
| 324 | 350 | ||
| 325 | /** | 351 | /** |
| 326 | * memscan - Find a character in an area of memory. | 352 | * memscan - Find a character in an area of memory. |
| @@ -331,6 +357,7 @@ EXPORT_SYMBOL(memcmp); | |||
| 331 | * returns the address of the first occurrence of @c, or 1 byte past | 357 | * returns the address of the first occurrence of @c, or 1 byte past |
| 332 | * the area if @c is not found | 358 | * the area if @c is not found |
| 333 | */ | 359 | */ |
| 360 | #ifdef __HAVE_ARCH_MEMSCAN | ||
| 334 | void *memscan(void *s, int c, size_t n) | 361 | void *memscan(void *s, int c, size_t n) |
| 335 | { | 362 | { |
| 336 | register int r0 asm("0") = (char) c; | 363 | register int r0 asm("0") = (char) c; |
| @@ -342,3 +369,4 @@ void *memscan(void *s, int c, size_t n) | |||
| 342 | return (void *) ret; | 369 | return (void *) ret; |
| 343 | } | 370 | } |
| 344 | EXPORT_SYMBOL(memscan); | 371 | EXPORT_SYMBOL(memscan); |
| 372 | #endif | ||
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index eba2def3414d..0b5622714c12 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c | |||
| @@ -28,12 +28,7 @@ | |||
| 28 | #include <asm/cpcmd.h> | 28 | #include <asm/cpcmd.h> |
| 29 | #include <asm/setup.h> | 29 | #include <asm/setup.h> |
| 30 | 30 | ||
| 31 | #define DCSS_LOADSHR 0x00 | ||
| 32 | #define DCSS_LOADNSR 0x04 | ||
| 33 | #define DCSS_PURGESEG 0x08 | 31 | #define DCSS_PURGESEG 0x08 |
| 34 | #define DCSS_FINDSEG 0x0c | ||
| 35 | #define DCSS_LOADNOLY 0x10 | ||
| 36 | #define DCSS_SEGEXT 0x18 | ||
| 37 | #define DCSS_LOADSHRX 0x20 | 32 | #define DCSS_LOADSHRX 0x20 |
| 38 | #define DCSS_LOADNSRX 0x24 | 33 | #define DCSS_LOADNSRX 0x24 |
| 39 | #define DCSS_FINDSEGX 0x2c | 34 | #define DCSS_FINDSEGX 0x2c |
| @@ -53,20 +48,6 @@ struct qout64 { | |||
| 53 | struct qrange range[6]; | 48 | struct qrange range[6]; |
| 54 | }; | 49 | }; |
| 55 | 50 | ||
| 56 | struct qrange_old { | ||
| 57 | unsigned int start; /* last byte type */ | ||
| 58 | unsigned int end; /* last byte reserved */ | ||
| 59 | }; | ||
| 60 | |||
| 61 | /* output area format for the Diag x'64' old subcode x'18' */ | ||
| 62 | struct qout64_old { | ||
| 63 | int segstart; | ||
| 64 | int segend; | ||
| 65 | int segcnt; | ||
| 66 | int segrcnt; | ||
| 67 | struct qrange_old range[6]; | ||
| 68 | }; | ||
| 69 | |||
| 70 | struct qin64 { | 51 | struct qin64 { |
| 71 | char qopcode; | 52 | char qopcode; |
| 72 | char rsrv1[3]; | 53 | char rsrv1[3]; |
| @@ -95,52 +76,10 @@ static DEFINE_MUTEX(dcss_lock); | |||
| 95 | static LIST_HEAD(dcss_list); | 76 | static LIST_HEAD(dcss_list); |
| 96 | static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC", | 77 | static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC", |
| 97 | "EW/EN-MIXED" }; | 78 | "EW/EN-MIXED" }; |
| 98 | static int loadshr_scode, loadnsr_scode; | 79 | static int loadshr_scode = DCSS_LOADSHRX; |
| 99 | static int segext_scode, purgeseg_scode; | 80 | static int loadnsr_scode = DCSS_LOADNSRX; |
| 100 | static int scode_set; | 81 | static int purgeseg_scode = DCSS_PURGESEG; |
| 101 | 82 | static int segext_scode = DCSS_SEGEXTX; | |
| 102 | /* set correct Diag x'64' subcodes. */ | ||
| 103 | static int | ||
| 104 | dcss_set_subcodes(void) | ||
| 105 | { | ||
| 106 | char *name = kmalloc(8, GFP_KERNEL | GFP_DMA); | ||
| 107 | unsigned long rx, ry; | ||
| 108 | int rc; | ||
| 109 | |||
| 110 | if (name == NULL) | ||
| 111 | return -ENOMEM; | ||
| 112 | |||
| 113 | rx = (unsigned long) name; | ||
| 114 | ry = DCSS_FINDSEGX; | ||
| 115 | |||
| 116 | strcpy(name, "dummy"); | ||
| 117 | diag_stat_inc(DIAG_STAT_X064); | ||
| 118 | asm volatile( | ||
| 119 | " diag %0,%1,0x64\n" | ||
| 120 | "0: ipm %2\n" | ||
| 121 | " srl %2,28\n" | ||
| 122 | " j 2f\n" | ||
| 123 | "1: la %2,3\n" | ||
| 124 | "2:\n" | ||
| 125 | EX_TABLE(0b, 1b) | ||
| 126 | : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc", "memory"); | ||
| 127 | |||
| 128 | kfree(name); | ||
| 129 | /* Diag x'64' new subcodes are supported, set to new subcodes */ | ||
| 130 | if (rc != 3) { | ||
| 131 | loadshr_scode = DCSS_LOADSHRX; | ||
| 132 | loadnsr_scode = DCSS_LOADNSRX; | ||
| 133 | purgeseg_scode = DCSS_PURGESEG; | ||
| 134 | segext_scode = DCSS_SEGEXTX; | ||
| 135 | return 0; | ||
| 136 | } | ||
| 137 | /* Diag x'64' new subcodes are not supported, set to old subcodes */ | ||
| 138 | loadshr_scode = DCSS_LOADNOLY; | ||
| 139 | loadnsr_scode = DCSS_LOADNSR; | ||
| 140 | purgeseg_scode = DCSS_PURGESEG; | ||
| 141 | segext_scode = DCSS_SEGEXT; | ||
| 142 | return 0; | ||
| 143 | } | ||
| 144 | 83 | ||
| 145 | /* | 84 | /* |
| 146 | * Create the 8 bytes, ebcdic VM segment name from | 85 | * Create the 8 bytes, ebcdic VM segment name from |
| @@ -196,32 +135,15 @@ dcss_diag(int *func, void *parameter, | |||
| 196 | unsigned long rx, ry; | 135 | unsigned long rx, ry; |
| 197 | int rc; | 136 | int rc; |
| 198 | 137 | ||
| 199 | if (scode_set == 0) { | ||
| 200 | rc = dcss_set_subcodes(); | ||
| 201 | if (rc < 0) | ||
| 202 | return rc; | ||
| 203 | scode_set = 1; | ||
| 204 | } | ||
| 205 | rx = (unsigned long) parameter; | 138 | rx = (unsigned long) parameter; |
| 206 | ry = (unsigned long) *func; | 139 | ry = (unsigned long) *func; |
| 207 | 140 | ||
| 208 | /* 64-bit Diag x'64' new subcode, keep in 64-bit addressing mode */ | ||
| 209 | diag_stat_inc(DIAG_STAT_X064); | 141 | diag_stat_inc(DIAG_STAT_X064); |
| 210 | if (*func > DCSS_SEGEXT) | 142 | asm volatile( |
| 211 | asm volatile( | 143 | " diag %0,%1,0x64\n" |
| 212 | " diag %0,%1,0x64\n" | 144 | " ipm %2\n" |
| 213 | " ipm %2\n" | 145 | " srl %2,28\n" |
| 214 | " srl %2,28\n" | 146 | : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc"); |
| 215 | : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc"); | ||
| 216 | /* 31-bit Diag x'64' old subcode, switch to 31-bit addressing mode */ | ||
| 217 | else | ||
| 218 | asm volatile( | ||
| 219 | " sam31\n" | ||
| 220 | " diag %0,%1,0x64\n" | ||
| 221 | " sam64\n" | ||
| 222 | " ipm %2\n" | ||
| 223 | " srl %2,28\n" | ||
| 224 | : "+d" (rx), "+d" (ry), "=d" (rc) : : "cc"); | ||
| 225 | *ret1 = rx; | 147 | *ret1 = rx; |
| 226 | *ret2 = ry; | 148 | *ret2 = ry; |
| 227 | return rc; | 149 | return rc; |
| @@ -271,31 +193,6 @@ query_segment_type (struct dcss_segment *seg) | |||
| 271 | goto out_free; | 193 | goto out_free; |
| 272 | } | 194 | } |
| 273 | 195 | ||
| 274 | /* Only old format of output area of Diagnose x'64' is supported, | ||
| 275 | copy data for the new format. */ | ||
| 276 | if (segext_scode == DCSS_SEGEXT) { | ||
| 277 | struct qout64_old *qout_old; | ||
| 278 | qout_old = kzalloc(sizeof(*qout_old), GFP_KERNEL | GFP_DMA); | ||
| 279 | if (qout_old == NULL) { | ||
| 280 | rc = -ENOMEM; | ||
| 281 | goto out_free; | ||
| 282 | } | ||
| 283 | memcpy(qout_old, qout, sizeof(struct qout64_old)); | ||
| 284 | qout->segstart = (unsigned long) qout_old->segstart; | ||
| 285 | qout->segend = (unsigned long) qout_old->segend; | ||
| 286 | qout->segcnt = qout_old->segcnt; | ||
| 287 | qout->segrcnt = qout_old->segrcnt; | ||
| 288 | |||
| 289 | if (qout->segcnt > 6) | ||
| 290 | qout->segrcnt = 6; | ||
| 291 | for (i = 0; i < qout->segrcnt; i++) { | ||
| 292 | qout->range[i].start = | ||
| 293 | (unsigned long) qout_old->range[i].start; | ||
| 294 | qout->range[i].end = | ||
| 295 | (unsigned long) qout_old->range[i].end; | ||
| 296 | } | ||
| 297 | kfree(qout_old); | ||
| 298 | } | ||
| 299 | if (qout->segcnt > 6) { | 196 | if (qout->segcnt > 6) { |
| 300 | rc = -EOPNOTSUPP; | 197 | rc = -EOPNOTSUPP; |
| 301 | goto out_free; | 198 | goto out_free; |
| @@ -410,11 +307,9 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long | |||
| 410 | if (rc < 0) | 307 | if (rc < 0) |
| 411 | goto out_free; | 308 | goto out_free; |
| 412 | 309 | ||
| 413 | if (loadshr_scode == DCSS_LOADSHRX) { | 310 | if (segment_overlaps_others(seg)) { |
| 414 | if (segment_overlaps_others(seg)) { | 311 | rc = -EBUSY; |
| 415 | rc = -EBUSY; | 312 | goto out_free; |
| 416 | goto out_free; | ||
| 417 | } | ||
| 418 | } | 313 | } |
| 419 | 314 | ||
| 420 | rc = vmem_add_mapping(seg->start_addr, seg->end - seg->start_addr + 1); | 315 | rc = vmem_add_mapping(seg->start_addr, seg->end - seg->start_addr + 1); |
| @@ -472,11 +367,11 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long | |||
| 472 | *addr = seg->start_addr; | 367 | *addr = seg->start_addr; |
| 473 | *end = seg->end; | 368 | *end = seg->end; |
| 474 | if (do_nonshared) | 369 | if (do_nonshared) |
| 475 | pr_info("DCSS %s of range %p to %p and type %s loaded as " | 370 | pr_info("DCSS %s of range %px to %px and type %s loaded as " |
| 476 | "exclusive-writable\n", name, (void*) seg->start_addr, | 371 | "exclusive-writable\n", name, (void*) seg->start_addr, |
| 477 | (void*) seg->end, segtype_string[seg->vm_segtype]); | 372 | (void*) seg->end, segtype_string[seg->vm_segtype]); |
| 478 | else { | 373 | else { |
| 479 | pr_info("DCSS %s of range %p to %p and type %s loaded in " | 374 | pr_info("DCSS %s of range %px to %px and type %s loaded in " |
| 480 | "shared access mode\n", name, (void*) seg->start_addr, | 375 | "shared access mode\n", name, (void*) seg->start_addr, |
| 481 | (void*) seg->end, segtype_string[seg->vm_segtype]); | 376 | (void*) seg->end, segtype_string[seg->vm_segtype]); |
| 482 | } | 377 | } |
diff --git a/arch/s390/mm/kasan_init.c b/arch/s390/mm/kasan_init.c index bac5c27d11fc..01892dcf4029 100644 --- a/arch/s390/mm/kasan_init.c +++ b/arch/s390/mm/kasan_init.c | |||
| @@ -226,8 +226,6 @@ static void __init kasan_enable_dat(void) | |||
| 226 | 226 | ||
| 227 | static void __init kasan_early_detect_facilities(void) | 227 | static void __init kasan_early_detect_facilities(void) |
| 228 | { | 228 | { |
| 229 | __stfle(S390_lowcore.stfle_fac_list, | ||
| 230 | ARRAY_SIZE(S390_lowcore.stfle_fac_list)); | ||
| 231 | if (test_facility(8)) { | 229 | if (test_facility(8)) { |
| 232 | has_edat = true; | 230 | has_edat = true; |
| 233 | __ctl_set_bit(0, 23); | 231 | __ctl_set_bit(0, 23); |
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 0a7627cdb34e..687f2a4d3459 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c | |||
| @@ -29,14 +29,6 @@ static unsigned long stack_maxrandom_size(void) | |||
| 29 | return STACK_RND_MASK << PAGE_SHIFT; | 29 | return STACK_RND_MASK << PAGE_SHIFT; |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | /* | ||
| 33 | * Top of mmap area (just below the process stack). | ||
| 34 | * | ||
| 35 | * Leave at least a ~32 MB hole. | ||
| 36 | */ | ||
| 37 | #define MIN_GAP (32*1024*1024) | ||
| 38 | #define MAX_GAP (STACK_TOP/6*5) | ||
| 39 | |||
| 40 | static inline int mmap_is_legacy(struct rlimit *rlim_stack) | 32 | static inline int mmap_is_legacy(struct rlimit *rlim_stack) |
| 41 | { | 33 | { |
| 42 | if (current->personality & ADDR_COMPAT_LAYOUT) | 34 | if (current->personality & ADDR_COMPAT_LAYOUT) |
| @@ -60,13 +52,26 @@ static inline unsigned long mmap_base(unsigned long rnd, | |||
| 60 | struct rlimit *rlim_stack) | 52 | struct rlimit *rlim_stack) |
| 61 | { | 53 | { |
| 62 | unsigned long gap = rlim_stack->rlim_cur; | 54 | unsigned long gap = rlim_stack->rlim_cur; |
| 55 | unsigned long pad = stack_maxrandom_size() + stack_guard_gap; | ||
| 56 | unsigned long gap_min, gap_max; | ||
| 57 | |||
| 58 | /* Values close to RLIM_INFINITY can overflow. */ | ||
| 59 | if (gap + pad > gap) | ||
| 60 | gap += pad; | ||
| 61 | |||
| 62 | /* | ||
| 63 | * Top of mmap area (just below the process stack). | ||
| 64 | * Leave at least a ~32 MB hole. | ||
| 65 | */ | ||
| 66 | gap_min = 32 * 1024 * 1024UL; | ||
| 67 | gap_max = (STACK_TOP / 6) * 5; | ||
| 68 | |||
| 69 | if (gap < gap_min) | ||
| 70 | gap = gap_min; | ||
| 71 | else if (gap > gap_max) | ||
| 72 | gap = gap_max; | ||
| 63 | 73 | ||
| 64 | if (gap < MIN_GAP) | 74 | return PAGE_ALIGN(STACK_TOP - gap - rnd); |
| 65 | gap = MIN_GAP; | ||
| 66 | else if (gap > MAX_GAP) | ||
| 67 | gap = MAX_GAP; | ||
| 68 | gap &= PAGE_MASK; | ||
| 69 | return STACK_TOP - stack_maxrandom_size() - rnd - gap; | ||
| 70 | } | 75 | } |
| 71 | 76 | ||
| 72 | unsigned long | 77 | unsigned long |
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index f2cc7da473e4..689b66f29fc6 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
| @@ -318,7 +318,6 @@ pte_t ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr, | |||
| 318 | } | 318 | } |
| 319 | return old; | 319 | return old; |
| 320 | } | 320 | } |
| 321 | EXPORT_SYMBOL(ptep_modify_prot_start); | ||
| 322 | 321 | ||
| 323 | void ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr, | 322 | void ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr, |
| 324 | pte_t *ptep, pte_t pte) | 323 | pte_t *ptep, pte_t pte) |
| @@ -337,7 +336,6 @@ void ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr, | |||
| 337 | } | 336 | } |
| 338 | preempt_enable(); | 337 | preempt_enable(); |
| 339 | } | 338 | } |
| 340 | EXPORT_SYMBOL(ptep_modify_prot_commit); | ||
| 341 | 339 | ||
| 342 | static inline void pmdp_idte_local(struct mm_struct *mm, | 340 | static inline void pmdp_idte_local(struct mm_struct *mm, |
| 343 | unsigned long addr, pmd_t *pmdp) | 341 | unsigned long addr, pmd_t *pmdp) |
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 4266a4de3160..dc9bc82c072c 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c | |||
| @@ -285,7 +285,7 @@ void __iomem *pci_iomap_range(struct pci_dev *pdev, | |||
| 285 | struct zpci_dev *zdev = to_zpci(pdev); | 285 | struct zpci_dev *zdev = to_zpci(pdev); |
| 286 | int idx; | 286 | int idx; |
| 287 | 287 | ||
| 288 | if (!pci_resource_len(pdev, bar)) | 288 | if (!pci_resource_len(pdev, bar) || bar >= PCI_BAR_COUNT) |
| 289 | return NULL; | 289 | return NULL; |
| 290 | 290 | ||
| 291 | idx = zdev->bars[bar].map_idx; | 291 | idx = zdev->bars[bar].map_idx; |
| @@ -484,6 +484,15 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev) | |||
| 484 | } | 484 | } |
| 485 | } | 485 | } |
| 486 | 486 | ||
| 487 | #ifdef CONFIG_PCI_IOV | ||
| 488 | static struct resource iov_res = { | ||
| 489 | .name = "PCI IOV res", | ||
| 490 | .start = 0, | ||
| 491 | .end = -1, | ||
| 492 | .flags = IORESOURCE_MEM, | ||
| 493 | }; | ||
| 494 | #endif | ||
| 495 | |||
| 487 | static void zpci_map_resources(struct pci_dev *pdev) | 496 | static void zpci_map_resources(struct pci_dev *pdev) |
| 488 | { | 497 | { |
| 489 | resource_size_t len; | 498 | resource_size_t len; |
| @@ -497,6 +506,17 @@ static void zpci_map_resources(struct pci_dev *pdev) | |||
| 497 | (resource_size_t __force) pci_iomap(pdev, i, 0); | 506 | (resource_size_t __force) pci_iomap(pdev, i, 0); |
| 498 | pdev->resource[i].end = pdev->resource[i].start + len - 1; | 507 | pdev->resource[i].end = pdev->resource[i].start + len - 1; |
| 499 | } | 508 | } |
| 509 | |||
| 510 | #ifdef CONFIG_PCI_IOV | ||
| 511 | i = PCI_IOV_RESOURCES; | ||
| 512 | |||
| 513 | for (; i < PCI_SRIOV_NUM_BARS + PCI_IOV_RESOURCES; i++) { | ||
| 514 | len = pci_resource_len(pdev, i); | ||
| 515 | if (!len) | ||
| 516 | continue; | ||
| 517 | pdev->resource[i].parent = &iov_res; | ||
| 518 | } | ||
| 519 | #endif | ||
| 500 | } | 520 | } |
| 501 | 521 | ||
| 502 | static void zpci_unmap_resources(struct pci_dev *pdev) | 522 | static void zpci_unmap_resources(struct pci_dev *pdev) |
diff --git a/arch/s390/pci/pci_debug.c b/arch/s390/pci/pci_debug.c index 04388a254ffb..6b48ca7760a7 100644 --- a/arch/s390/pci/pci_debug.c +++ b/arch/s390/pci/pci_debug.c | |||
| @@ -172,21 +172,14 @@ static const struct file_operations debugfs_pci_perf_fops = { | |||
| 172 | void zpci_debug_init_device(struct zpci_dev *zdev, const char *name) | 172 | void zpci_debug_init_device(struct zpci_dev *zdev, const char *name) |
| 173 | { | 173 | { |
| 174 | zdev->debugfs_dev = debugfs_create_dir(name, debugfs_root); | 174 | zdev->debugfs_dev = debugfs_create_dir(name, debugfs_root); |
| 175 | if (IS_ERR(zdev->debugfs_dev)) | 175 | |
| 176 | zdev->debugfs_dev = NULL; | 176 | debugfs_create_file("statistics", S_IFREG | S_IRUGO | S_IWUSR, |
| 177 | 177 | zdev->debugfs_dev, zdev, &debugfs_pci_perf_fops); | |
| 178 | zdev->debugfs_perf = debugfs_create_file("statistics", | ||
| 179 | S_IFREG | S_IRUGO | S_IWUSR, | ||
| 180 | zdev->debugfs_dev, zdev, | ||
| 181 | &debugfs_pci_perf_fops); | ||
| 182 | if (IS_ERR(zdev->debugfs_perf)) | ||
| 183 | zdev->debugfs_perf = NULL; | ||
| 184 | } | 178 | } |
| 185 | 179 | ||
| 186 | void zpci_debug_exit_device(struct zpci_dev *zdev) | 180 | void zpci_debug_exit_device(struct zpci_dev *zdev) |
| 187 | { | 181 | { |
| 188 | debugfs_remove(zdev->debugfs_perf); | 182 | debugfs_remove_recursive(zdev->debugfs_dev); |
| 189 | debugfs_remove(zdev->debugfs_dev); | ||
| 190 | } | 183 | } |
| 191 | 184 | ||
| 192 | int __init zpci_debug_init(void) | 185 | int __init zpci_debug_init(void) |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 397af07e4d88..e03304fe25bb 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
| @@ -3965,13 +3965,11 @@ int dasd_generic_restore_device(struct ccw_device *cdev) | |||
| 3965 | EXPORT_SYMBOL_GPL(dasd_generic_restore_device); | 3965 | EXPORT_SYMBOL_GPL(dasd_generic_restore_device); |
| 3966 | 3966 | ||
| 3967 | static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device, | 3967 | static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device, |
| 3968 | void *rdc_buffer, | ||
| 3969 | int rdc_buffer_size, | 3968 | int rdc_buffer_size, |
| 3970 | int magic) | 3969 | int magic) |
| 3971 | { | 3970 | { |
| 3972 | struct dasd_ccw_req *cqr; | 3971 | struct dasd_ccw_req *cqr; |
| 3973 | struct ccw1 *ccw; | 3972 | struct ccw1 *ccw; |
| 3974 | unsigned long *idaw; | ||
| 3975 | 3973 | ||
| 3976 | cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device, | 3974 | cqr = dasd_smalloc_request(magic, 1 /* RDC */, rdc_buffer_size, device, |
| 3977 | NULL); | 3975 | NULL); |
| @@ -3986,16 +3984,8 @@ static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device, | |||
| 3986 | 3984 | ||
| 3987 | ccw = cqr->cpaddr; | 3985 | ccw = cqr->cpaddr; |
| 3988 | ccw->cmd_code = CCW_CMD_RDC; | 3986 | ccw->cmd_code = CCW_CMD_RDC; |
| 3989 | if (idal_is_needed(rdc_buffer, rdc_buffer_size)) { | 3987 | ccw->cda = (__u32)(addr_t) cqr->data; |
| 3990 | idaw = (unsigned long *) (cqr->data); | 3988 | ccw->flags = 0; |
| 3991 | ccw->cda = (__u32)(addr_t) idaw; | ||
| 3992 | ccw->flags = CCW_FLAG_IDA; | ||
| 3993 | idaw = idal_create_words(idaw, rdc_buffer, rdc_buffer_size); | ||
| 3994 | } else { | ||
| 3995 | ccw->cda = (__u32)(addr_t) rdc_buffer; | ||
| 3996 | ccw->flags = 0; | ||
| 3997 | } | ||
| 3998 | |||
| 3999 | ccw->count = rdc_buffer_size; | 3989 | ccw->count = rdc_buffer_size; |
| 4000 | cqr->startdev = device; | 3990 | cqr->startdev = device; |
| 4001 | cqr->memdev = device; | 3991 | cqr->memdev = device; |
| @@ -4013,12 +4003,13 @@ int dasd_generic_read_dev_chars(struct dasd_device *device, int magic, | |||
| 4013 | int ret; | 4003 | int ret; |
| 4014 | struct dasd_ccw_req *cqr; | 4004 | struct dasd_ccw_req *cqr; |
| 4015 | 4005 | ||
| 4016 | cqr = dasd_generic_build_rdc(device, rdc_buffer, rdc_buffer_size, | 4006 | cqr = dasd_generic_build_rdc(device, rdc_buffer_size, magic); |
| 4017 | magic); | ||
| 4018 | if (IS_ERR(cqr)) | 4007 | if (IS_ERR(cqr)) |
| 4019 | return PTR_ERR(cqr); | 4008 | return PTR_ERR(cqr); |
| 4020 | 4009 | ||
| 4021 | ret = dasd_sleep_on(cqr); | 4010 | ret = dasd_sleep_on(cqr); |
| 4011 | if (ret == 0) | ||
| 4012 | memcpy(rdc_buffer, cqr->data, rdc_buffer_size); | ||
| 4022 | dasd_sfree_request(cqr, cqr->memdev); | 4013 | dasd_sfree_request(cqr, cqr->memdev); |
| 4023 | return ret; | 4014 | return ret; |
| 4024 | } | 4015 | } |
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h index b3fcc24b1182..367e9d384d85 100644 --- a/drivers/s390/char/sclp.h +++ b/drivers/s390/char/sclp.h | |||
| @@ -195,7 +195,9 @@ struct read_info_sccb { | |||
| 195 | u16 hcpua; /* 120-121 */ | 195 | u16 hcpua; /* 120-121 */ |
| 196 | u8 _pad_122[124 - 122]; /* 122-123 */ | 196 | u8 _pad_122[124 - 122]; /* 122-123 */ |
| 197 | u32 hmfai; /* 124-127 */ | 197 | u32 hmfai; /* 124-127 */ |
| 198 | u8 _pad_128[4096 - 128]; /* 128-4095 */ | 198 | u8 _pad_128[134 - 128]; /* 128-133 */ |
| 199 | u8 byte_134; /* 134 */ | ||
| 200 | u8 _pad_135[4096 - 135]; /* 135-4095 */ | ||
| 199 | } __packed __aligned(PAGE_SIZE); | 201 | } __packed __aligned(PAGE_SIZE); |
| 200 | 202 | ||
| 201 | struct read_storage_sccb { | 203 | struct read_storage_sccb { |
diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c index e792cee3b51c..8332788681c4 100644 --- a/drivers/s390/char/sclp_early.c +++ b/drivers/s390/char/sclp_early.c | |||
| @@ -44,6 +44,8 @@ static void __init sclp_early_facilities_detect(struct read_info_sccb *sccb) | |||
| 44 | S390_lowcore.machine_flags |= MACHINE_FLAG_ESOP; | 44 | S390_lowcore.machine_flags |= MACHINE_FLAG_ESOP; |
| 45 | if (sccb->fac91 & 0x40) | 45 | if (sccb->fac91 & 0x40) |
| 46 | S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_GUEST; | 46 | S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_GUEST; |
| 47 | if (sccb->cpuoff > 134) | ||
| 48 | sclp.has_diag318 = !!(sccb->byte_134 & 0x80); | ||
| 47 | sclp.rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2; | 49 | sclp.rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2; |
| 48 | sclp.rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; | 50 | sclp.rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; |
| 49 | sclp.rzm <<= 20; | 51 | sclp.rzm <<= 20; |
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c index e324d890a4f6..a59887fad13e 100644 --- a/drivers/s390/cio/qdio_setup.c +++ b/drivers/s390/cio/qdio_setup.c | |||
| @@ -181,7 +181,7 @@ static void setup_queues_misc(struct qdio_q *q, struct qdio_irq *irq_ptr, | |||
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr, | 183 | static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr, |
| 184 | void **sbals_array, int i) | 184 | struct qdio_buffer **sbals_array, int i) |
| 185 | { | 185 | { |
| 186 | struct qdio_q *prev; | 186 | struct qdio_q *prev; |
| 187 | int j; | 187 | int j; |
| @@ -212,8 +212,8 @@ static void setup_queues(struct qdio_irq *irq_ptr, | |||
| 212 | struct qdio_initialize *qdio_init) | 212 | struct qdio_initialize *qdio_init) |
| 213 | { | 213 | { |
| 214 | struct qdio_q *q; | 214 | struct qdio_q *q; |
| 215 | void **input_sbal_array = qdio_init->input_sbal_addr_array; | 215 | struct qdio_buffer **input_sbal_array = qdio_init->input_sbal_addr_array; |
| 216 | void **output_sbal_array = qdio_init->output_sbal_addr_array; | 216 | struct qdio_buffer **output_sbal_array = qdio_init->output_sbal_addr_array; |
| 217 | struct qdio_outbuf_state *output_sbal_state_array = | 217 | struct qdio_outbuf_state *output_sbal_state_array = |
| 218 | qdio_init->output_sbal_state_array; | 218 | qdio_init->output_sbal_state_array; |
| 219 | int i; | 219 | int i; |
diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c index 70a006ba4d05..384b3987eeb4 100644 --- a/drivers/s390/cio/vfio_ccw_cp.c +++ b/drivers/s390/cio/vfio_ccw_cp.c | |||
| @@ -283,6 +283,33 @@ static long copy_ccw_from_iova(struct channel_program *cp, | |||
| 283 | 283 | ||
| 284 | #define ccw_is_chain(_ccw) ((_ccw)->flags & (CCW_FLAG_CC | CCW_FLAG_DC)) | 284 | #define ccw_is_chain(_ccw) ((_ccw)->flags & (CCW_FLAG_CC | CCW_FLAG_DC)) |
| 285 | 285 | ||
| 286 | /* | ||
| 287 | * is_cpa_within_range() | ||
| 288 | * | ||
| 289 | * @cpa: channel program address being questioned | ||
| 290 | * @head: address of the beginning of a CCW chain | ||
| 291 | * @len: number of CCWs within the chain | ||
| 292 | * | ||
| 293 | * Determine whether the address of a CCW (whether a new chain, | ||
| 294 | * or the target of a TIC) falls within a range (including the end points). | ||
| 295 | * | ||
| 296 | * Returns 1 if yes, 0 if no. | ||
| 297 | */ | ||
| 298 | static inline int is_cpa_within_range(u32 cpa, u32 head, int len) | ||
| 299 | { | ||
| 300 | u32 tail = head + (len - 1) * sizeof(struct ccw1); | ||
| 301 | |||
| 302 | return (head <= cpa && cpa <= tail); | ||
| 303 | } | ||
| 304 | |||
| 305 | static inline int is_tic_within_range(struct ccw1 *ccw, u32 head, int len) | ||
| 306 | { | ||
| 307 | if (!ccw_is_tic(ccw)) | ||
| 308 | return 0; | ||
| 309 | |||
| 310 | return is_cpa_within_range(ccw->cda, head, len); | ||
| 311 | } | ||
| 312 | |||
| 286 | static struct ccwchain *ccwchain_alloc(struct channel_program *cp, int len) | 313 | static struct ccwchain *ccwchain_alloc(struct channel_program *cp, int len) |
| 287 | { | 314 | { |
| 288 | struct ccwchain *chain; | 315 | struct ccwchain *chain; |
| @@ -392,7 +419,15 @@ static int ccwchain_calc_length(u64 iova, struct channel_program *cp) | |||
| 392 | return -EOPNOTSUPP; | 419 | return -EOPNOTSUPP; |
| 393 | } | 420 | } |
| 394 | 421 | ||
| 395 | if ((!ccw_is_chain(ccw)) && (!ccw_is_tic(ccw))) | 422 | /* |
| 423 | * We want to keep counting if the current CCW has the | ||
| 424 | * command-chaining flag enabled, or if it is a TIC CCW | ||
| 425 | * that loops back into the current chain. The latter | ||
| 426 | * is used for device orientation, where the CCW PRIOR to | ||
| 427 | * the TIC can either jump to the TIC or a CCW immediately | ||
| 428 | * after the TIC, depending on the results of its operation. | ||
| 429 | */ | ||
| 430 | if (!ccw_is_chain(ccw) && !is_tic_within_range(ccw, iova, cnt)) | ||
| 396 | break; | 431 | break; |
| 397 | 432 | ||
| 398 | ccw++; | 433 | ccw++; |
| @@ -408,13 +443,11 @@ static int ccwchain_calc_length(u64 iova, struct channel_program *cp) | |||
| 408 | static int tic_target_chain_exists(struct ccw1 *tic, struct channel_program *cp) | 443 | static int tic_target_chain_exists(struct ccw1 *tic, struct channel_program *cp) |
| 409 | { | 444 | { |
| 410 | struct ccwchain *chain; | 445 | struct ccwchain *chain; |
| 411 | u32 ccw_head, ccw_tail; | 446 | u32 ccw_head; |
| 412 | 447 | ||
| 413 | list_for_each_entry(chain, &cp->ccwchain_list, next) { | 448 | list_for_each_entry(chain, &cp->ccwchain_list, next) { |
| 414 | ccw_head = chain->ch_iova; | 449 | ccw_head = chain->ch_iova; |
| 415 | ccw_tail = ccw_head + (chain->ch_len - 1) * sizeof(struct ccw1); | 450 | if (is_cpa_within_range(tic->cda, ccw_head, chain->ch_len)) |
| 416 | |||
| 417 | if ((ccw_head <= tic->cda) && (tic->cda <= ccw_tail)) | ||
| 418 | return 1; | 451 | return 1; |
| 419 | } | 452 | } |
| 420 | 453 | ||
| @@ -481,13 +514,11 @@ static int ccwchain_fetch_tic(struct ccwchain *chain, | |||
| 481 | { | 514 | { |
| 482 | struct ccw1 *ccw = chain->ch_ccw + idx; | 515 | struct ccw1 *ccw = chain->ch_ccw + idx; |
| 483 | struct ccwchain *iter; | 516 | struct ccwchain *iter; |
| 484 | u32 ccw_head, ccw_tail; | 517 | u32 ccw_head; |
| 485 | 518 | ||
| 486 | list_for_each_entry(iter, &cp->ccwchain_list, next) { | 519 | list_for_each_entry(iter, &cp->ccwchain_list, next) { |
| 487 | ccw_head = iter->ch_iova; | 520 | ccw_head = iter->ch_iova; |
| 488 | ccw_tail = ccw_head + (iter->ch_len - 1) * sizeof(struct ccw1); | 521 | if (is_cpa_within_range(ccw->cda, ccw_head, iter->ch_len)) { |
| 489 | |||
| 490 | if ((ccw_head <= ccw->cda) && (ccw->cda <= ccw_tail)) { | ||
| 491 | ccw->cda = (__u32) (addr_t) (((char *)iter->ch_ccw) + | 522 | ccw->cda = (__u32) (addr_t) (((char *)iter->ch_ccw) + |
| 492 | (ccw->cda - ccw_head)); | 523 | (ccw->cda - ccw_head)); |
| 493 | return 0; | 524 | return 0; |
| @@ -829,7 +860,7 @@ void cp_update_scsw(struct channel_program *cp, union scsw *scsw) | |||
| 829 | { | 860 | { |
| 830 | struct ccwchain *chain; | 861 | struct ccwchain *chain; |
| 831 | u32 cpa = scsw->cmd.cpa; | 862 | u32 cpa = scsw->cmd.cpa; |
| 832 | u32 ccw_head, ccw_tail; | 863 | u32 ccw_head; |
| 833 | 864 | ||
| 834 | /* | 865 | /* |
| 835 | * LATER: | 866 | * LATER: |
| @@ -839,9 +870,7 @@ void cp_update_scsw(struct channel_program *cp, union scsw *scsw) | |||
| 839 | */ | 870 | */ |
| 840 | list_for_each_entry(chain, &cp->ccwchain_list, next) { | 871 | list_for_each_entry(chain, &cp->ccwchain_list, next) { |
| 841 | ccw_head = (u32)(u64)chain->ch_ccw; | 872 | ccw_head = (u32)(u64)chain->ch_ccw; |
| 842 | ccw_tail = (u32)(u64)(chain->ch_ccw + chain->ch_len - 1); | 873 | if (is_cpa_within_range(cpa, ccw_head, chain->ch_len)) { |
| 843 | |||
| 844 | if ((ccw_head <= cpa) && (cpa <= ccw_tail)) { | ||
| 845 | /* | 874 | /* |
| 846 | * (cpa - ccw_head) is the offset value of the host | 875 | * (cpa - ccw_head) is the offset value of the host |
| 847 | * physical ccw to its chain head. | 876 | * physical ccw to its chain head. |
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 5a699746c357..e15816ff1265 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
| @@ -1336,6 +1336,16 @@ static int __match_queue_device_with_qid(struct device *dev, void *data) | |||
| 1336 | } | 1336 | } |
| 1337 | 1337 | ||
| 1338 | /* | 1338 | /* |
| 1339 | * Helper function to be used with bus_find_dev | ||
| 1340 | * matches any queue device with given queue id | ||
| 1341 | */ | ||
| 1342 | static int __match_queue_device_with_queue_id(struct device *dev, void *data) | ||
| 1343 | { | ||
| 1344 | return is_queue_dev(dev) | ||
| 1345 | && AP_QID_QUEUE(to_ap_queue(dev)->qid) == (int)(long) data; | ||
| 1346 | } | ||
| 1347 | |||
| 1348 | /* | ||
| 1339 | * Helper function for ap_scan_bus(). | 1349 | * Helper function for ap_scan_bus(). |
| 1340 | * Does the scan bus job for the given adapter id. | 1350 | * Does the scan bus job for the given adapter id. |
| 1341 | */ | 1351 | */ |
| @@ -1435,8 +1445,13 @@ static void _ap_scan_bus_adapter(int id) | |||
| 1435 | borked = aq->state == AP_STATE_BORKED; | 1445 | borked = aq->state == AP_STATE_BORKED; |
| 1436 | spin_unlock_bh(&aq->lock); | 1446 | spin_unlock_bh(&aq->lock); |
| 1437 | } | 1447 | } |
| 1438 | if (borked) /* Remove broken device */ | 1448 | if (borked) { |
| 1449 | /* Remove broken device */ | ||
| 1450 | AP_DBF(DBF_DEBUG, | ||
| 1451 | "removing broken queue=%02x.%04x\n", | ||
| 1452 | id, dom); | ||
| 1439 | device_unregister(dev); | 1453 | device_unregister(dev); |
| 1454 | } | ||
| 1440 | put_device(dev); | 1455 | put_device(dev); |
| 1441 | continue; | 1456 | continue; |
| 1442 | } | 1457 | } |
| @@ -1506,7 +1521,7 @@ static void ap_scan_bus(struct work_struct *unused) | |||
| 1506 | struct device *dev = | 1521 | struct device *dev = |
| 1507 | bus_find_device(&ap_bus_type, NULL, | 1522 | bus_find_device(&ap_bus_type, NULL, |
| 1508 | (void *)(long) ap_domain_index, | 1523 | (void *)(long) ap_domain_index, |
| 1509 | __match_queue_device_with_qid); | 1524 | __match_queue_device_with_queue_id); |
| 1510 | if (dev) | 1525 | if (dev) |
| 1511 | put_device(dev); | 1526 | put_device(dev); |
| 1512 | else | 1527 | else |
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index bfc66e4a9de1..d0059eae5d94 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h | |||
| @@ -91,7 +91,8 @@ enum ap_state { | |||
| 91 | AP_STATE_WORKING, | 91 | AP_STATE_WORKING, |
| 92 | AP_STATE_QUEUE_FULL, | 92 | AP_STATE_QUEUE_FULL, |
| 93 | AP_STATE_SUSPEND_WAIT, | 93 | AP_STATE_SUSPEND_WAIT, |
| 94 | AP_STATE_BORKED, | 94 | AP_STATE_UNBOUND, /* momentary not bound to a driver */ |
| 95 | AP_STATE_BORKED, /* broken */ | ||
| 95 | NR_AP_STATES | 96 | NR_AP_STATES |
| 96 | }; | 97 | }; |
| 97 | 98 | ||
diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c index 576ac08777c5..ba261210c6da 100644 --- a/drivers/s390/crypto/ap_queue.c +++ b/drivers/s390/crypto/ap_queue.c | |||
| @@ -420,6 +420,10 @@ static ap_func_t *ap_jumptable[NR_AP_STATES][NR_AP_EVENTS] = { | |||
| 420 | [AP_EVENT_POLL] = ap_sm_suspend_read, | 420 | [AP_EVENT_POLL] = ap_sm_suspend_read, |
| 421 | [AP_EVENT_TIMEOUT] = ap_sm_nop, | 421 | [AP_EVENT_TIMEOUT] = ap_sm_nop, |
| 422 | }, | 422 | }, |
| 423 | [AP_STATE_UNBOUND] = { | ||
| 424 | [AP_EVENT_POLL] = ap_sm_nop, | ||
| 425 | [AP_EVENT_TIMEOUT] = ap_sm_nop, | ||
| 426 | }, | ||
| 423 | [AP_STATE_BORKED] = { | 427 | [AP_STATE_BORKED] = { |
| 424 | [AP_EVENT_POLL] = ap_sm_nop, | 428 | [AP_EVENT_POLL] = ap_sm_nop, |
| 425 | [AP_EVENT_TIMEOUT] = ap_sm_nop, | 429 | [AP_EVENT_TIMEOUT] = ap_sm_nop, |
| @@ -725,6 +729,7 @@ static void __ap_flush_queue(struct ap_queue *aq) | |||
| 725 | ap_msg->rc = -EAGAIN; | 729 | ap_msg->rc = -EAGAIN; |
| 726 | ap_msg->receive(aq, ap_msg, NULL); | 730 | ap_msg->receive(aq, ap_msg, NULL); |
| 727 | } | 731 | } |
| 732 | aq->queue_count = 0; | ||
| 728 | } | 733 | } |
| 729 | 734 | ||
| 730 | void ap_flush_queue(struct ap_queue *aq) | 735 | void ap_flush_queue(struct ap_queue *aq) |
| @@ -743,7 +748,7 @@ void ap_queue_remove(struct ap_queue *aq) | |||
| 743 | /* reset with zero, also clears irq registration */ | 748 | /* reset with zero, also clears irq registration */ |
| 744 | spin_lock_bh(&aq->lock); | 749 | spin_lock_bh(&aq->lock); |
| 745 | ap_zapq(aq->qid); | 750 | ap_zapq(aq->qid); |
| 746 | aq->state = AP_STATE_BORKED; | 751 | aq->state = AP_STATE_UNBOUND; |
| 747 | spin_unlock_bh(&aq->lock); | 752 | spin_unlock_bh(&aq->lock); |
| 748 | } | 753 | } |
| 749 | EXPORT_SYMBOL(ap_queue_remove); | 754 | EXPORT_SYMBOL(ap_queue_remove); |
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c index 2f92bbed4bf6..3e85d665c572 100644 --- a/drivers/s390/crypto/pkey_api.c +++ b/drivers/s390/crypto/pkey_api.c | |||
| @@ -1079,7 +1079,7 @@ int pkey_verifykey(const struct pkey_seckey *seckey, | |||
| 1079 | rc = mkvp_cache_fetch(cardnr, domain, mkvp); | 1079 | rc = mkvp_cache_fetch(cardnr, domain, mkvp); |
| 1080 | if (rc) | 1080 | if (rc) |
| 1081 | goto out; | 1081 | goto out; |
| 1082 | if (t->mkvp == mkvp[1]) { | 1082 | if (t->mkvp == mkvp[1] && t->mkvp != mkvp[0]) { |
| 1083 | DEBUG_DBG("%s secure key has old mkvp\n", __func__); | 1083 | DEBUG_DBG("%s secure key has old mkvp\n", __func__); |
| 1084 | if (pattributes) | 1084 | if (pattributes) |
| 1085 | *pattributes |= PKEY_VERIFY_ATTR_OLD_MKVP; | 1085 | *pattributes |= PKEY_VERIFY_ATTR_OLD_MKVP; |
diff --git a/drivers/s390/crypto/vfio_ap_drv.c b/drivers/s390/crypto/vfio_ap_drv.c index 31c6c847eaca..e9824c35c34f 100644 --- a/drivers/s390/crypto/vfio_ap_drv.c +++ b/drivers/s390/crypto/vfio_ap_drv.c | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | #include "vfio_ap_private.h" | 15 | #include "vfio_ap_private.h" |
| 16 | 16 | ||
| 17 | #define VFIO_AP_ROOT_NAME "vfio_ap" | 17 | #define VFIO_AP_ROOT_NAME "vfio_ap" |
| 18 | #define VFIO_AP_DEV_TYPE_NAME "ap_matrix" | ||
| 19 | #define VFIO_AP_DEV_NAME "matrix" | 18 | #define VFIO_AP_DEV_NAME "matrix" |
| 20 | 19 | ||
| 21 | MODULE_AUTHOR("IBM Corporation"); | 20 | MODULE_AUTHOR("IBM Corporation"); |
| @@ -24,10 +23,6 @@ MODULE_LICENSE("GPL v2"); | |||
| 24 | 23 | ||
| 25 | static struct ap_driver vfio_ap_drv; | 24 | static struct ap_driver vfio_ap_drv; |
| 26 | 25 | ||
| 27 | static struct device_type vfio_ap_dev_type = { | ||
| 28 | .name = VFIO_AP_DEV_TYPE_NAME, | ||
| 29 | }; | ||
| 30 | |||
| 31 | struct ap_matrix_dev *matrix_dev; | 26 | struct ap_matrix_dev *matrix_dev; |
| 32 | 27 | ||
| 33 | /* Only type 10 adapters (CEX4 and later) are supported | 28 | /* Only type 10 adapters (CEX4 and later) are supported |
| @@ -62,6 +57,22 @@ static void vfio_ap_matrix_dev_release(struct device *dev) | |||
| 62 | kfree(matrix_dev); | 57 | kfree(matrix_dev); |
| 63 | } | 58 | } |
| 64 | 59 | ||
| 60 | static int matrix_bus_match(struct device *dev, struct device_driver *drv) | ||
| 61 | { | ||
| 62 | return 1; | ||
| 63 | } | ||
| 64 | |||
| 65 | static struct bus_type matrix_bus = { | ||
| 66 | .name = "matrix", | ||
| 67 | .match = &matrix_bus_match, | ||
| 68 | }; | ||
| 69 | |||
| 70 | static struct device_driver matrix_driver = { | ||
| 71 | .name = "vfio_ap", | ||
| 72 | .bus = &matrix_bus, | ||
| 73 | .suppress_bind_attrs = true, | ||
| 74 | }; | ||
| 75 | |||
| 65 | static int vfio_ap_matrix_dev_create(void) | 76 | static int vfio_ap_matrix_dev_create(void) |
| 66 | { | 77 | { |
| 67 | int ret; | 78 | int ret; |
| @@ -71,6 +82,10 @@ static int vfio_ap_matrix_dev_create(void) | |||
| 71 | if (IS_ERR(root_device)) | 82 | if (IS_ERR(root_device)) |
| 72 | return PTR_ERR(root_device); | 83 | return PTR_ERR(root_device); |
| 73 | 84 | ||
| 85 | ret = bus_register(&matrix_bus); | ||
| 86 | if (ret) | ||
| 87 | goto bus_register_err; | ||
| 88 | |||
| 74 | matrix_dev = kzalloc(sizeof(*matrix_dev), GFP_KERNEL); | 89 | matrix_dev = kzalloc(sizeof(*matrix_dev), GFP_KERNEL); |
| 75 | if (!matrix_dev) { | 90 | if (!matrix_dev) { |
| 76 | ret = -ENOMEM; | 91 | ret = -ENOMEM; |
| @@ -87,30 +102,41 @@ static int vfio_ap_matrix_dev_create(void) | |||
| 87 | mutex_init(&matrix_dev->lock); | 102 | mutex_init(&matrix_dev->lock); |
| 88 | INIT_LIST_HEAD(&matrix_dev->mdev_list); | 103 | INIT_LIST_HEAD(&matrix_dev->mdev_list); |
| 89 | 104 | ||
| 90 | matrix_dev->device.type = &vfio_ap_dev_type; | ||
| 91 | dev_set_name(&matrix_dev->device, "%s", VFIO_AP_DEV_NAME); | 105 | dev_set_name(&matrix_dev->device, "%s", VFIO_AP_DEV_NAME); |
| 92 | matrix_dev->device.parent = root_device; | 106 | matrix_dev->device.parent = root_device; |
| 107 | matrix_dev->device.bus = &matrix_bus; | ||
| 93 | matrix_dev->device.release = vfio_ap_matrix_dev_release; | 108 | matrix_dev->device.release = vfio_ap_matrix_dev_release; |
| 94 | matrix_dev->device.driver = &vfio_ap_drv.driver; | 109 | matrix_dev->vfio_ap_drv = &vfio_ap_drv; |
| 95 | 110 | ||
| 96 | ret = device_register(&matrix_dev->device); | 111 | ret = device_register(&matrix_dev->device); |
| 97 | if (ret) | 112 | if (ret) |
| 98 | goto matrix_reg_err; | 113 | goto matrix_reg_err; |
| 99 | 114 | ||
| 115 | ret = driver_register(&matrix_driver); | ||
| 116 | if (ret) | ||
| 117 | goto matrix_drv_err; | ||
| 118 | |||
| 100 | return 0; | 119 | return 0; |
| 101 | 120 | ||
| 121 | matrix_drv_err: | ||
| 122 | device_unregister(&matrix_dev->device); | ||
| 102 | matrix_reg_err: | 123 | matrix_reg_err: |
| 103 | put_device(&matrix_dev->device); | 124 | put_device(&matrix_dev->device); |
| 104 | matrix_alloc_err: | 125 | matrix_alloc_err: |
| 126 | bus_unregister(&matrix_bus); | ||
| 127 | bus_register_err: | ||
| 105 | root_device_unregister(root_device); | 128 | root_device_unregister(root_device); |
| 106 | |||
| 107 | return ret; | 129 | return ret; |
| 108 | } | 130 | } |
| 109 | 131 | ||
| 110 | static void vfio_ap_matrix_dev_destroy(void) | 132 | static void vfio_ap_matrix_dev_destroy(void) |
| 111 | { | 133 | { |
| 134 | struct device *root_device = matrix_dev->device.parent; | ||
| 135 | |||
| 136 | driver_unregister(&matrix_driver); | ||
| 112 | device_unregister(&matrix_dev->device); | 137 | device_unregister(&matrix_dev->device); |
| 113 | root_device_unregister(matrix_dev->device.parent); | 138 | bus_unregister(&matrix_bus); |
| 139 | root_device_unregister(root_device); | ||
| 114 | } | 140 | } |
| 115 | 141 | ||
| 116 | static int __init vfio_ap_init(void) | 142 | static int __init vfio_ap_init(void) |
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 272ef427dcc0..900b9cf20ca5 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c | |||
| @@ -198,8 +198,8 @@ static int vfio_ap_verify_queue_reserved(unsigned long *apid, | |||
| 198 | qres.apqi = apqi; | 198 | qres.apqi = apqi; |
| 199 | qres.reserved = false; | 199 | qres.reserved = false; |
| 200 | 200 | ||
| 201 | ret = driver_for_each_device(matrix_dev->device.driver, NULL, &qres, | 201 | ret = driver_for_each_device(&matrix_dev->vfio_ap_drv->driver, NULL, |
| 202 | vfio_ap_has_queue); | 202 | &qres, vfio_ap_has_queue); |
| 203 | if (ret) | 203 | if (ret) |
| 204 | return ret; | 204 | return ret; |
| 205 | 205 | ||
diff --git a/drivers/s390/crypto/vfio_ap_private.h b/drivers/s390/crypto/vfio_ap_private.h index 5675492233c7..76b7f98e47e9 100644 --- a/drivers/s390/crypto/vfio_ap_private.h +++ b/drivers/s390/crypto/vfio_ap_private.h | |||
| @@ -40,6 +40,7 @@ struct ap_matrix_dev { | |||
| 40 | struct ap_config_info info; | 40 | struct ap_config_info info; |
| 41 | struct list_head mdev_list; | 41 | struct list_head mdev_list; |
| 42 | struct mutex lock; | 42 | struct mutex lock; |
| 43 | struct ap_driver *vfio_ap_drv; | ||
| 43 | }; | 44 | }; |
| 44 | 45 | ||
| 45 | extern struct ap_matrix_dev *matrix_dev; | 46 | extern struct ap_matrix_dev *matrix_dev; |
diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c index ed8e58f09054..3e132592c1fe 100644 --- a/drivers/s390/net/ism_drv.c +++ b/drivers/s390/net/ism_drv.c | |||
| @@ -141,10 +141,13 @@ static int register_ieq(struct ism_dev *ism) | |||
| 141 | 141 | ||
| 142 | static int unregister_sba(struct ism_dev *ism) | 142 | static int unregister_sba(struct ism_dev *ism) |
| 143 | { | 143 | { |
| 144 | int ret; | ||
| 145 | |||
| 144 | if (!ism->sba) | 146 | if (!ism->sba) |
| 145 | return 0; | 147 | return 0; |
| 146 | 148 | ||
| 147 | if (ism_cmd_simple(ism, ISM_UNREG_SBA)) | 149 | ret = ism_cmd_simple(ism, ISM_UNREG_SBA); |
| 150 | if (ret && ret != ISM_ERROR) | ||
| 148 | return -EIO; | 151 | return -EIO; |
| 149 | 152 | ||
| 150 | dma_free_coherent(&ism->pdev->dev, PAGE_SIZE, | 153 | dma_free_coherent(&ism->pdev->dev, PAGE_SIZE, |
| @@ -158,10 +161,13 @@ static int unregister_sba(struct ism_dev *ism) | |||
| 158 | 161 | ||
| 159 | static int unregister_ieq(struct ism_dev *ism) | 162 | static int unregister_ieq(struct ism_dev *ism) |
| 160 | { | 163 | { |
| 164 | int ret; | ||
| 165 | |||
| 161 | if (!ism->ieq) | 166 | if (!ism->ieq) |
| 162 | return 0; | 167 | return 0; |
| 163 | 168 | ||
| 164 | if (ism_cmd_simple(ism, ISM_UNREG_IEQ)) | 169 | ret = ism_cmd_simple(ism, ISM_UNREG_IEQ); |
| 170 | if (ret && ret != ISM_ERROR) | ||
| 165 | return -EIO; | 171 | return -EIO; |
| 166 | 172 | ||
| 167 | dma_free_coherent(&ism->pdev->dev, PAGE_SIZE, | 173 | dma_free_coherent(&ism->pdev->dev, PAGE_SIZE, |
| @@ -287,7 +293,7 @@ static int ism_unregister_dmb(struct smcd_dev *smcd, struct smcd_dmb *dmb) | |||
| 287 | cmd.request.dmb_tok = dmb->dmb_tok; | 293 | cmd.request.dmb_tok = dmb->dmb_tok; |
| 288 | 294 | ||
| 289 | ret = ism_cmd(ism, &cmd); | 295 | ret = ism_cmd(ism, &cmd); |
| 290 | if (ret) | 296 | if (ret && ret != ISM_ERROR) |
| 291 | goto out; | 297 | goto out; |
| 292 | 298 | ||
| 293 | ism_free_dmb(ism, dmb); | 299 | ism_free_dmb(ism, dmb); |
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index a44a4e0d2b19..197b0f5b63e7 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
| @@ -4884,8 +4884,8 @@ static int qeth_qdio_establish(struct qeth_card *card) | |||
| 4884 | init_data.output_handler = qeth_qdio_output_handler; | 4884 | init_data.output_handler = qeth_qdio_output_handler; |
| 4885 | init_data.queue_start_poll_array = queue_start_poll; | 4885 | init_data.queue_start_poll_array = queue_start_poll; |
| 4886 | init_data.int_parm = (unsigned long) card; | 4886 | init_data.int_parm = (unsigned long) card; |
| 4887 | init_data.input_sbal_addr_array = (void **) in_sbal_ptrs; | 4887 | init_data.input_sbal_addr_array = in_sbal_ptrs; |
| 4888 | init_data.output_sbal_addr_array = (void **) out_sbal_ptrs; | 4888 | init_data.output_sbal_addr_array = out_sbal_ptrs; |
| 4889 | init_data.output_sbal_state_array = card->qdio.out_bufstates; | 4889 | init_data.output_sbal_state_array = card->qdio.out_bufstates; |
| 4890 | init_data.scan_threshold = | 4890 | init_data.scan_threshold = |
| 4891 | (card->info.type == QETH_CARD_TYPE_IQD) ? 1 : 32; | 4891 | (card->info.type == QETH_CARD_TYPE_IQD) ? 1 : 32; |
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 10c4e8e3fd59..661436a92f8e 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c | |||
| @@ -294,8 +294,8 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id, | |||
| 294 | id->input_handler = zfcp_qdio_int_resp; | 294 | id->input_handler = zfcp_qdio_int_resp; |
| 295 | id->output_handler = zfcp_qdio_int_req; | 295 | id->output_handler = zfcp_qdio_int_req; |
| 296 | id->int_parm = (unsigned long) qdio; | 296 | id->int_parm = (unsigned long) qdio; |
| 297 | id->input_sbal_addr_array = (void **) (qdio->res_q); | 297 | id->input_sbal_addr_array = qdio->res_q; |
| 298 | id->output_sbal_addr_array = (void **) (qdio->req_q); | 298 | id->output_sbal_addr_array = qdio->req_q; |
| 299 | id->scan_threshold = | 299 | id->scan_threshold = |
| 300 | QDIO_MAX_BUFFERS_PER_Q - ZFCP_QDIO_MAX_SBALS_PER_REQ * 2; | 300 | QDIO_MAX_BUFFERS_PER_Q - ZFCP_QDIO_MAX_SBALS_PER_REQ * 2; |
| 301 | } | 301 | } |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 257cccba3062..fb63045a0fb6 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
| @@ -1185,6 +1185,10 @@ unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len, | |||
| 1185 | unsigned long prot, unsigned long flags, | 1185 | unsigned long prot, unsigned long flags, |
| 1186 | unsigned long fd, unsigned long pgoff); | 1186 | unsigned long fd, unsigned long pgoff); |
| 1187 | ssize_t ksys_readahead(int fd, loff_t offset, size_t count); | 1187 | ssize_t ksys_readahead(int fd, loff_t offset, size_t count); |
| 1188 | int ksys_ipc(unsigned int call, int first, unsigned long second, | ||
| 1189 | unsigned long third, void __user * ptr, long fifth); | ||
| 1190 | int compat_ksys_ipc(u32 call, int first, int second, | ||
| 1191 | u32 third, u32 ptr, u32 fifth); | ||
| 1188 | 1192 | ||
| 1189 | /* | 1193 | /* |
| 1190 | * The following kernel syscall equivalents are just wrappers to fs-internal | 1194 | * The following kernel syscall equivalents are just wrappers to fs-internal |
diff --git a/ipc/syscall.c b/ipc/syscall.c index 1ac06e3983c0..3cf8ad703a4d 100644 --- a/ipc/syscall.c +++ b/ipc/syscall.c | |||
| @@ -17,8 +17,8 @@ | |||
| 17 | #include <linux/shm.h> | 17 | #include <linux/shm.h> |
| 18 | #include <linux/uaccess.h> | 18 | #include <linux/uaccess.h> |
| 19 | 19 | ||
| 20 | SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, | 20 | int ksys_ipc(unsigned int call, int first, unsigned long second, |
| 21 | unsigned long, third, void __user *, ptr, long, fifth) | 21 | unsigned long third, void __user * ptr, long fifth) |
| 22 | { | 22 | { |
| 23 | int version, ret; | 23 | int version, ret; |
| 24 | 24 | ||
| @@ -106,6 +106,12 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, | |||
| 106 | return -ENOSYS; | 106 | return -ENOSYS; |
| 107 | } | 107 | } |
| 108 | } | 108 | } |
| 109 | |||
| 110 | SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second, | ||
| 111 | unsigned long, third, void __user *, ptr, long, fifth) | ||
| 112 | { | ||
| 113 | return ksys_ipc(call, first, second, third, ptr, fifth); | ||
| 114 | } | ||
| 109 | #endif | 115 | #endif |
| 110 | 116 | ||
| 111 | #ifdef CONFIG_COMPAT | 117 | #ifdef CONFIG_COMPAT |
| @@ -121,8 +127,8 @@ struct compat_ipc_kludge { | |||
| 121 | }; | 127 | }; |
| 122 | 128 | ||
| 123 | #ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC | 129 | #ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC |
| 124 | COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, | 130 | int compat_ksys_ipc(u32 call, int first, int second, |
| 125 | u32, third, compat_uptr_t, ptr, u32, fifth) | 131 | u32 third, compat_uptr_t ptr, u32 fifth) |
| 126 | { | 132 | { |
| 127 | int version; | 133 | int version; |
| 128 | u32 pad; | 134 | u32 pad; |
| @@ -195,5 +201,11 @@ COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, | |||
| 195 | 201 | ||
| 196 | return -ENOSYS; | 202 | return -ENOSYS; |
| 197 | } | 203 | } |
| 204 | |||
| 205 | COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second, | ||
| 206 | u32, third, compat_uptr_t, ptr, u32, fifth) | ||
| 207 | { | ||
| 208 | return compat_ksys_ipc(call, first, second, third, ptr, fifth); | ||
| 209 | } | ||
| 198 | #endif | 210 | #endif |
| 199 | #endif | 211 | #endif |
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index ab9d0e3c6d50..bc934f31ab10 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c | |||
| @@ -366,6 +366,7 @@ COND_SYSCALL(kexec_file_load); | |||
| 366 | /* s390 */ | 366 | /* s390 */ |
| 367 | COND_SYSCALL(s390_pci_mmio_read); | 367 | COND_SYSCALL(s390_pci_mmio_read); |
| 368 | COND_SYSCALL(s390_pci_mmio_write); | 368 | COND_SYSCALL(s390_pci_mmio_write); |
| 369 | COND_SYSCALL(s390_ipc); | ||
| 369 | COND_SYSCALL_COMPAT(s390_ipc); | 370 | COND_SYSCALL_COMPAT(s390_ipc); |
| 370 | 371 | ||
| 371 | /* powerpc */ | 372 | /* powerpc */ |
