diff options
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/crypto/aes_s390.c | 15 | ||||
-rw-r--r-- | arch/s390/kernel/ipl.c | 32 | ||||
-rw-r--r-- | arch/s390/kernel/kprobes.c | 3 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 111 | ||||
-rw-r--r-- | arch/s390/mm/fault.c | 40 |
5 files changed, 151 insertions, 50 deletions
diff --git a/arch/s390/crypto/aes_s390.c b/arch/s390/crypto/aes_s390.c index 91636353f6f0..3660ca6a3306 100644 --- a/arch/s390/crypto/aes_s390.c +++ b/arch/s390/crypto/aes_s390.c | |||
@@ -119,7 +119,8 @@ static struct crypto_alg aes_alg = { | |||
119 | .cra_name = "aes", | 119 | .cra_name = "aes", |
120 | .cra_driver_name = "aes-s390", | 120 | .cra_driver_name = "aes-s390", |
121 | .cra_priority = CRYPT_S390_PRIORITY, | 121 | .cra_priority = CRYPT_S390_PRIORITY, |
122 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | 122 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER | |
123 | CRYPTO_ALG_NEED_FALLBACK, | ||
123 | .cra_blocksize = AES_BLOCK_SIZE, | 124 | .cra_blocksize = AES_BLOCK_SIZE, |
124 | .cra_ctxsize = sizeof(struct s390_aes_ctx), | 125 | .cra_ctxsize = sizeof(struct s390_aes_ctx), |
125 | .cra_module = THIS_MODULE, | 126 | .cra_module = THIS_MODULE, |
@@ -206,7 +207,8 @@ static struct crypto_alg ecb_aes_alg = { | |||
206 | .cra_name = "ecb(aes)", | 207 | .cra_name = "ecb(aes)", |
207 | .cra_driver_name = "ecb-aes-s390", | 208 | .cra_driver_name = "ecb-aes-s390", |
208 | .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, | 209 | .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, |
209 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | 210 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | |
211 | CRYPTO_ALG_NEED_FALLBACK, | ||
210 | .cra_blocksize = AES_BLOCK_SIZE, | 212 | .cra_blocksize = AES_BLOCK_SIZE, |
211 | .cra_ctxsize = sizeof(struct s390_aes_ctx), | 213 | .cra_ctxsize = sizeof(struct s390_aes_ctx), |
212 | .cra_type = &crypto_blkcipher_type, | 214 | .cra_type = &crypto_blkcipher_type, |
@@ -300,7 +302,8 @@ static struct crypto_alg cbc_aes_alg = { | |||
300 | .cra_name = "cbc(aes)", | 302 | .cra_name = "cbc(aes)", |
301 | .cra_driver_name = "cbc-aes-s390", | 303 | .cra_driver_name = "cbc-aes-s390", |
302 | .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, | 304 | .cra_priority = CRYPT_S390_COMPOSITE_PRIORITY, |
303 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | 305 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | |
306 | CRYPTO_ALG_NEED_FALLBACK, | ||
304 | .cra_blocksize = AES_BLOCK_SIZE, | 307 | .cra_blocksize = AES_BLOCK_SIZE, |
305 | .cra_ctxsize = sizeof(struct s390_aes_ctx), | 308 | .cra_ctxsize = sizeof(struct s390_aes_ctx), |
306 | .cra_type = &crypto_blkcipher_type, | 309 | .cra_type = &crypto_blkcipher_type, |
@@ -333,10 +336,14 @@ static int __init aes_init(void) | |||
333 | return -EOPNOTSUPP; | 336 | return -EOPNOTSUPP; |
334 | 337 | ||
335 | /* z9 109 and z9 BC/EC only support 128 bit key length */ | 338 | /* z9 109 and z9 BC/EC only support 128 bit key length */ |
336 | if (keylen_flag == AES_KEYLEN_128) | 339 | if (keylen_flag == AES_KEYLEN_128) { |
340 | aes_alg.cra_u.cipher.cia_max_keysize = AES_MIN_KEY_SIZE; | ||
341 | ecb_aes_alg.cra_u.blkcipher.max_keysize = AES_MIN_KEY_SIZE; | ||
342 | cbc_aes_alg.cra_u.blkcipher.max_keysize = AES_MIN_KEY_SIZE; | ||
337 | printk(KERN_INFO | 343 | printk(KERN_INFO |
338 | "aes_s390: hardware acceleration only available for" | 344 | "aes_s390: hardware acceleration only available for" |
339 | "128 bit keys\n"); | 345 | "128 bit keys\n"); |
346 | } | ||
340 | 347 | ||
341 | ret = crypto_register_alg(&aes_alg); | 348 | ret = crypto_register_alg(&aes_alg); |
342 | if (ret) | 349 | if (ret) |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 06833ac2b115..0ea048d350d8 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -164,7 +164,7 @@ EXPORT_SYMBOL_GPL(diag308); | |||
164 | /* SYSFS */ | 164 | /* SYSFS */ |
165 | 165 | ||
166 | #define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value) \ | 166 | #define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value) \ |
167 | static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \ | 167 | static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset, \ |
168 | char *page) \ | 168 | char *page) \ |
169 | { \ | 169 | { \ |
170 | return sprintf(page, _format, _value); \ | 170 | return sprintf(page, _format, _value); \ |
@@ -173,13 +173,13 @@ static struct subsys_attribute sys_##_prefix##_##_name##_attr = \ | |||
173 | __ATTR(_name, S_IRUGO, sys_##_prefix##_##_name##_show, NULL); | 173 | __ATTR(_name, S_IRUGO, sys_##_prefix##_##_name##_show, NULL); |
174 | 174 | ||
175 | #define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value) \ | 175 | #define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value) \ |
176 | static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \ | 176 | static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset, \ |
177 | char *page) \ | 177 | char *page) \ |
178 | { \ | 178 | { \ |
179 | return sprintf(page, _fmt_out, \ | 179 | return sprintf(page, _fmt_out, \ |
180 | (unsigned long long) _value); \ | 180 | (unsigned long long) _value); \ |
181 | } \ | 181 | } \ |
182 | static ssize_t sys_##_prefix##_##_name##_store(struct subsystem *subsys,\ | 182 | static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset, \ |
183 | const char *buf, size_t len) \ | 183 | const char *buf, size_t len) \ |
184 | { \ | 184 | { \ |
185 | unsigned long long value; \ | 185 | unsigned long long value; \ |
@@ -194,12 +194,12 @@ static struct subsys_attribute sys_##_prefix##_##_name##_attr = \ | |||
194 | sys_##_prefix##_##_name##_store); | 194 | sys_##_prefix##_##_name##_store); |
195 | 195 | ||
196 | #define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\ | 196 | #define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\ |
197 | static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \ | 197 | static ssize_t sys_##_prefix##_##_name##_show(struct kset *kset, \ |
198 | char *page) \ | 198 | char *page) \ |
199 | { \ | 199 | { \ |
200 | return sprintf(page, _fmt_out, _value); \ | 200 | return sprintf(page, _fmt_out, _value); \ |
201 | } \ | 201 | } \ |
202 | static ssize_t sys_##_prefix##_##_name##_store(struct subsystem *subsys,\ | 202 | static ssize_t sys_##_prefix##_##_name##_store(struct kset *kset, \ |
203 | const char *buf, size_t len) \ | 203 | const char *buf, size_t len) \ |
204 | { \ | 204 | { \ |
205 | if (sscanf(buf, _fmt_in, _value) != 1) \ | 205 | if (sscanf(buf, _fmt_in, _value) != 1) \ |
@@ -272,14 +272,14 @@ void __init setup_ipl_info(void) | |||
272 | struct ipl_info ipl_info; | 272 | struct ipl_info ipl_info; |
273 | EXPORT_SYMBOL_GPL(ipl_info); | 273 | EXPORT_SYMBOL_GPL(ipl_info); |
274 | 274 | ||
275 | static ssize_t ipl_type_show(struct subsystem *subsys, char *page) | 275 | static ssize_t ipl_type_show(struct kset *kset, char *page) |
276 | { | 276 | { |
277 | return sprintf(page, "%s\n", ipl_type_str(ipl_info.type)); | 277 | return sprintf(page, "%s\n", ipl_type_str(ipl_info.type)); |
278 | } | 278 | } |
279 | 279 | ||
280 | static struct subsys_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); | 280 | static struct subsys_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type); |
281 | 281 | ||
282 | static ssize_t sys_ipl_device_show(struct subsystem *subsys, char *page) | 282 | static ssize_t sys_ipl_device_show(struct kset *kset, char *page) |
283 | { | 283 | { |
284 | struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START; | 284 | struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START; |
285 | 285 | ||
@@ -371,7 +371,7 @@ static struct attribute_group ipl_fcp_attr_group = { | |||
371 | 371 | ||
372 | /* CCW ipl device attributes */ | 372 | /* CCW ipl device attributes */ |
373 | 373 | ||
374 | static ssize_t ipl_ccw_loadparm_show(struct subsystem *subsys, char *page) | 374 | static ssize_t ipl_ccw_loadparm_show(struct kset *kset, char *page) |
375 | { | 375 | { |
376 | char loadparm[LOADPARM_LEN + 1] = {}; | 376 | char loadparm[LOADPARM_LEN + 1] = {}; |
377 | 377 | ||
@@ -469,7 +469,7 @@ static void reipl_get_ascii_loadparm(char *loadparm) | |||
469 | strstrip(loadparm); | 469 | strstrip(loadparm); |
470 | } | 470 | } |
471 | 471 | ||
472 | static ssize_t reipl_ccw_loadparm_show(struct subsystem *subsys, char *page) | 472 | static ssize_t reipl_ccw_loadparm_show(struct kset *kset, char *page) |
473 | { | 473 | { |
474 | char buf[LOADPARM_LEN + 1]; | 474 | char buf[LOADPARM_LEN + 1]; |
475 | 475 | ||
@@ -477,7 +477,7 @@ static ssize_t reipl_ccw_loadparm_show(struct subsystem *subsys, char *page) | |||
477 | return sprintf(page, "%s\n", buf); | 477 | return sprintf(page, "%s\n", buf); |
478 | } | 478 | } |
479 | 479 | ||
480 | static ssize_t reipl_ccw_loadparm_store(struct subsystem *subsys, | 480 | static ssize_t reipl_ccw_loadparm_store(struct kset *kset, |
481 | const char *buf, size_t len) | 481 | const char *buf, size_t len) |
482 | { | 482 | { |
483 | int i, lp_len; | 483 | int i, lp_len; |
@@ -572,12 +572,12 @@ static int reipl_set_type(enum ipl_type type) | |||
572 | return 0; | 572 | return 0; |
573 | } | 573 | } |
574 | 574 | ||
575 | static ssize_t reipl_type_show(struct subsystem *subsys, char *page) | 575 | static ssize_t reipl_type_show(struct kset *kset, char *page) |
576 | { | 576 | { |
577 | return sprintf(page, "%s\n", ipl_type_str(reipl_type)); | 577 | return sprintf(page, "%s\n", ipl_type_str(reipl_type)); |
578 | } | 578 | } |
579 | 579 | ||
580 | static ssize_t reipl_type_store(struct subsystem *subsys, const char *buf, | 580 | static ssize_t reipl_type_store(struct kset *kset, const char *buf, |
581 | size_t len) | 581 | size_t len) |
582 | { | 582 | { |
583 | int rc = -EINVAL; | 583 | int rc = -EINVAL; |
@@ -665,12 +665,12 @@ static int dump_set_type(enum dump_type type) | |||
665 | return 0; | 665 | return 0; |
666 | } | 666 | } |
667 | 667 | ||
668 | static ssize_t dump_type_show(struct subsystem *subsys, char *page) | 668 | static ssize_t dump_type_show(struct kset *kset, char *page) |
669 | { | 669 | { |
670 | return sprintf(page, "%s\n", dump_type_str(dump_type)); | 670 | return sprintf(page, "%s\n", dump_type_str(dump_type)); |
671 | } | 671 | } |
672 | 672 | ||
673 | static ssize_t dump_type_store(struct subsystem *subsys, const char *buf, | 673 | static ssize_t dump_type_store(struct kset *kset, const char *buf, |
674 | size_t len) | 674 | size_t len) |
675 | { | 675 | { |
676 | int rc = -EINVAL; | 676 | int rc = -EINVAL; |
@@ -697,12 +697,12 @@ static decl_subsys(shutdown_actions, NULL, NULL); | |||
697 | 697 | ||
698 | /* on panic */ | 698 | /* on panic */ |
699 | 699 | ||
700 | static ssize_t on_panic_show(struct subsystem *subsys, char *page) | 700 | static ssize_t on_panic_show(struct kset *kset, char *page) |
701 | { | 701 | { |
702 | return sprintf(page, "%s\n", shutdown_action_str(on_panic_action)); | 702 | return sprintf(page, "%s\n", shutdown_action_str(on_panic_action)); |
703 | } | 703 | } |
704 | 704 | ||
705 | static ssize_t on_panic_store(struct subsystem *subsys, const char *buf, | 705 | static ssize_t on_panic_store(struct kset *kset, const char *buf, |
706 | size_t len) | 706 | size_t len) |
707 | { | 707 | { |
708 | if (strncmp(buf, SHUTDOWN_REIPL_STR, strlen(SHUTDOWN_REIPL_STR)) == 0) | 708 | if (strncmp(buf, SHUTDOWN_REIPL_STR, strlen(SHUTDOWN_REIPL_STR)) == 0) |
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c index 993f35381496..23c61f6d965b 100644 --- a/arch/s390/kernel/kprobes.c +++ b/arch/s390/kernel/kprobes.c | |||
@@ -516,7 +516,7 @@ out: | |||
516 | return 1; | 516 | return 1; |
517 | } | 517 | } |
518 | 518 | ||
519 | static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) | 519 | int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) |
520 | { | 520 | { |
521 | struct kprobe *cur = kprobe_running(); | 521 | struct kprobe *cur = kprobe_running(); |
522 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 522 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
@@ -603,7 +603,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | |||
603 | ret = NOTIFY_STOP; | 603 | ret = NOTIFY_STOP; |
604 | break; | 604 | break; |
605 | case DIE_TRAP: | 605 | case DIE_TRAP: |
606 | case DIE_PAGE_FAULT: | ||
607 | /* kprobe_running() needs smp_processor_id() */ | 606 | /* kprobe_running() needs smp_processor_id() */ |
608 | preempt_disable(); | 607 | preempt_disable(); |
609 | if (kprobe_running() && | 608 | if (kprobe_running() && |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 3dfd0985861c..6bfb0889eb10 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -65,7 +65,7 @@ long psw_user_bits = (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME | | |||
65 | * User copy operations. | 65 | * User copy operations. |
66 | */ | 66 | */ |
67 | struct uaccess_ops uaccess; | 67 | struct uaccess_ops uaccess; |
68 | EXPORT_SYMBOL_GPL(uaccess); | 68 | EXPORT_SYMBOL(uaccess); |
69 | 69 | ||
70 | /* | 70 | /* |
71 | * Machine setup.. | 71 | * Machine setup.. |
@@ -74,6 +74,8 @@ unsigned int console_mode = 0; | |||
74 | unsigned int console_devno = -1; | 74 | unsigned int console_devno = -1; |
75 | unsigned int console_irq = -1; | 75 | unsigned int console_irq = -1; |
76 | unsigned long machine_flags = 0; | 76 | unsigned long machine_flags = 0; |
77 | unsigned long elf_hwcap = 0; | ||
78 | char elf_platform[ELF_PLATFORM_SIZE]; | ||
77 | 79 | ||
78 | struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS]; | 80 | struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS]; |
79 | volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ | 81 | volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ |
@@ -749,6 +751,98 @@ setup_memory(void) | |||
749 | #endif | 751 | #endif |
750 | } | 752 | } |
751 | 753 | ||
754 | static __init unsigned int stfl(void) | ||
755 | { | ||
756 | asm volatile( | ||
757 | " .insn s,0xb2b10000,0(0)\n" /* stfl */ | ||
758 | "0:\n" | ||
759 | EX_TABLE(0b,0b)); | ||
760 | return S390_lowcore.stfl_fac_list; | ||
761 | } | ||
762 | |||
763 | static __init int stfle(unsigned long long *list, int doublewords) | ||
764 | { | ||
765 | typedef struct { unsigned long long _[doublewords]; } addrtype; | ||
766 | register unsigned long __nr asm("0") = doublewords - 1; | ||
767 | |||
768 | asm volatile(".insn s,0xb2b00000,%0" /* stfle */ | ||
769 | : "=m" (*(addrtype *) list), "+d" (__nr) : : "cc"); | ||
770 | return __nr + 1; | ||
771 | } | ||
772 | |||
773 | /* | ||
774 | * Setup hardware capabilities. | ||
775 | */ | ||
776 | static void __init setup_hwcaps(void) | ||
777 | { | ||
778 | static const int stfl_bits[6] = { 0, 2, 7, 17, 19, 21 }; | ||
779 | struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data; | ||
780 | unsigned long long facility_list_extended; | ||
781 | unsigned int facility_list; | ||
782 | int i; | ||
783 | |||
784 | facility_list = stfl(); | ||
785 | /* | ||
786 | * The store facility list bits numbers as found in the principles | ||
787 | * of operation are numbered with bit 1UL<<31 as number 0 to | ||
788 | * bit 1UL<<0 as number 31. | ||
789 | * Bit 0: instructions named N3, "backported" to esa-mode | ||
790 | * Bit 2: z/Architecture mode is active | ||
791 | * Bit 7: the store-facility-list-extended facility is installed | ||
792 | * Bit 17: the message-security assist is installed | ||
793 | * Bit 19: the long-displacement facility is installed | ||
794 | * Bit 21: the extended-immediate facility is installed | ||
795 | * These get translated to: | ||
796 | * HWCAP_S390_ESAN3 bit 0, HWCAP_S390_ZARCH bit 1, | ||
797 | * HWCAP_S390_STFLE bit 2, HWCAP_S390_MSA bit 3, | ||
798 | * HWCAP_S390_LDISP bit 4, and HWCAP_S390_EIMM bit 5. | ||
799 | */ | ||
800 | for (i = 0; i < 6; i++) | ||
801 | if (facility_list & (1UL << (31 - stfl_bits[i]))) | ||
802 | elf_hwcap |= 1UL << i; | ||
803 | |||
804 | /* | ||
805 | * Check for additional facilities with store-facility-list-extended. | ||
806 | * stfle stores doublewords (8 byte) with bit 1ULL<<63 as bit 0 | ||
807 | * and 1ULL<<0 as bit 63. Bits 0-31 contain the same information | ||
808 | * as stored by stfl, bits 32-xxx contain additional facilities. | ||
809 | * How many facility words are stored depends on the number of | ||
810 | * doublewords passed to the instruction. The additional facilites | ||
811 | * are: | ||
812 | * Bit 43: decimal floating point facility is installed | ||
813 | * translated to: | ||
814 | * HWCAP_S390_DFP bit 6. | ||
815 | */ | ||
816 | if ((elf_hwcap & (1UL << 2)) && | ||
817 | stfle(&facility_list_extended, 1) > 0) { | ||
818 | if (facility_list_extended & (1ULL << (64 - 43))) | ||
819 | elf_hwcap |= 1UL << 6; | ||
820 | } | ||
821 | |||
822 | switch (cpuinfo->cpu_id.machine) { | ||
823 | case 0x9672: | ||
824 | #if !defined(CONFIG_64BIT) | ||
825 | default: /* Use "g5" as default for 31 bit kernels. */ | ||
826 | #endif | ||
827 | strcpy(elf_platform, "g5"); | ||
828 | break; | ||
829 | case 0x2064: | ||
830 | case 0x2066: | ||
831 | #if defined(CONFIG_64BIT) | ||
832 | default: /* Use "z900" as default for 64 bit kernels. */ | ||
833 | #endif | ||
834 | strcpy(elf_platform, "z900"); | ||
835 | break; | ||
836 | case 0x2084: | ||
837 | case 0x2086: | ||
838 | strcpy(elf_platform, "z990"); | ||
839 | break; | ||
840 | case 0x2094: | ||
841 | strcpy(elf_platform, "z9-109"); | ||
842 | break; | ||
843 | } | ||
844 | } | ||
845 | |||
752 | /* | 846 | /* |
753 | * Setup function called from init/main.c just after the banner | 847 | * Setup function called from init/main.c just after the banner |
754 | * was printed. | 848 | * was printed. |
@@ -805,6 +899,11 @@ setup_arch(char **cmdline_p) | |||
805 | smp_setup_cpu_possible_map(); | 899 | smp_setup_cpu_possible_map(); |
806 | 900 | ||
807 | /* | 901 | /* |
902 | * Setup capabilities (ELF_HWCAP & ELF_PLATFORM). | ||
903 | */ | ||
904 | setup_hwcaps(); | ||
905 | |||
906 | /* | ||
808 | * Create kernel page tables and switch to virtual addressing. | 907 | * Create kernel page tables and switch to virtual addressing. |
809 | */ | 908 | */ |
810 | paging_init(); | 909 | paging_init(); |
@@ -839,8 +938,12 @@ void print_cpu_info(struct cpuinfo_S390 *cpuinfo) | |||
839 | 938 | ||
840 | static int show_cpuinfo(struct seq_file *m, void *v) | 939 | static int show_cpuinfo(struct seq_file *m, void *v) |
841 | { | 940 | { |
941 | static const char *hwcap_str[7] = { | ||
942 | "esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp" | ||
943 | }; | ||
842 | struct cpuinfo_S390 *cpuinfo; | 944 | struct cpuinfo_S390 *cpuinfo; |
843 | unsigned long n = (unsigned long) v - 1; | 945 | unsigned long n = (unsigned long) v - 1; |
946 | int i; | ||
844 | 947 | ||
845 | s390_adjust_jiffies(); | 948 | s390_adjust_jiffies(); |
846 | preempt_disable(); | 949 | preempt_disable(); |
@@ -850,7 +953,13 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
850 | "bogomips per cpu: %lu.%02lu\n", | 953 | "bogomips per cpu: %lu.%02lu\n", |
851 | num_online_cpus(), loops_per_jiffy/(500000/HZ), | 954 | num_online_cpus(), loops_per_jiffy/(500000/HZ), |
852 | (loops_per_jiffy/(5000/HZ))%100); | 955 | (loops_per_jiffy/(5000/HZ))%100); |
956 | seq_puts(m, "features\t: "); | ||
957 | for (i = 0; i < 7; i++) | ||
958 | if (hwcap_str[i] && (elf_hwcap & (1UL << i))) | ||
959 | seq_printf(m, "%s ", hwcap_str[i]); | ||
960 | seq_puts(m, "\n"); | ||
853 | } | 961 | } |
962 | |||
854 | if (cpu_online(n)) { | 963 | if (cpu_online(n)) { |
855 | #ifdef CONFIG_SMP | 964 | #ifdef CONFIG_SMP |
856 | if (smp_processor_id() == n) | 965 | if (smp_processor_id() == n) |
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 2b76a879a7b5..91f705adc3f9 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c | |||
@@ -52,38 +52,24 @@ extern int sysctl_userprocess_debug; | |||
52 | extern void die(const char *,struct pt_regs *,long); | 52 | extern void die(const char *,struct pt_regs *,long); |
53 | 53 | ||
54 | #ifdef CONFIG_KPROBES | 54 | #ifdef CONFIG_KPROBES |
55 | static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); | ||
56 | int register_page_fault_notifier(struct notifier_block *nb) | ||
57 | { | ||
58 | return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); | ||
59 | } | ||
60 | |||
61 | int unregister_page_fault_notifier(struct notifier_block *nb) | ||
62 | { | ||
63 | return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); | ||
64 | } | ||
65 | |||
66 | static int __kprobes __notify_page_fault(struct pt_regs *regs, long err) | ||
67 | { | ||
68 | struct die_args args = { .str = "page fault", | ||
69 | .trapnr = 14, | ||
70 | .signr = SIGSEGV }; | ||
71 | args.regs = regs; | ||
72 | args.err = err; | ||
73 | return atomic_notifier_call_chain(¬ify_page_fault_chain, | ||
74 | DIE_PAGE_FAULT, &args); | ||
75 | } | ||
76 | |||
77 | static inline int notify_page_fault(struct pt_regs *regs, long err) | 55 | static inline int notify_page_fault(struct pt_regs *regs, long err) |
78 | { | 56 | { |
79 | if (unlikely(kprobe_running())) | 57 | int ret = 0; |
80 | return __notify_page_fault(regs, err); | 58 | |
81 | return NOTIFY_DONE; | 59 | /* kprobe_running() needs smp_processor_id() */ |
60 | if (!user_mode(regs)) { | ||
61 | preempt_disable(); | ||
62 | if (kprobe_running() && kprobe_fault_handler(regs, 14)) | ||
63 | ret = 1; | ||
64 | preempt_enable(); | ||
65 | } | ||
66 | |||
67 | return ret; | ||
82 | } | 68 | } |
83 | #else | 69 | #else |
84 | static inline int notify_page_fault(struct pt_regs *regs, long err) | 70 | static inline int notify_page_fault(struct pt_regs *regs, long err) |
85 | { | 71 | { |
86 | return NOTIFY_DONE; | 72 | return 0; |
87 | } | 73 | } |
88 | #endif | 74 | #endif |
89 | 75 | ||
@@ -319,7 +305,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int write) | |||
319 | int space; | 305 | int space; |
320 | int si_code; | 306 | int si_code; |
321 | 307 | ||
322 | if (notify_page_fault(regs, error_code) == NOTIFY_STOP) | 308 | if (notify_page_fault(regs, error_code)) |
323 | return; | 309 | return; |
324 | 310 | ||
325 | tsk = current; | 311 | tsk = current; |