diff options
Diffstat (limited to 'arch/s390/mm/fault.c')
-rw-r--r-- | arch/s390/mm/fault.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index fe5701e9efbf..2c57806c0858 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c | |||
@@ -10,6 +10,7 @@ | |||
10 | * Copyright (C) 1995 Linus Torvalds | 10 | * Copyright (C) 1995 Linus Torvalds |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/kernel_stat.h> | ||
13 | #include <linux/perf_event.h> | 14 | #include <linux/perf_event.h> |
14 | #include <linux/signal.h> | 15 | #include <linux/signal.h> |
15 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
@@ -234,13 +235,13 @@ static noinline int signal_return(struct pt_regs *regs, long int_code, | |||
234 | rc = __get_user(instruction, (u16 __user *) regs->psw.addr); | 235 | rc = __get_user(instruction, (u16 __user *) regs->psw.addr); |
235 | 236 | ||
236 | if (!rc && instruction == 0x0a77) { | 237 | if (!rc && instruction == 0x0a77) { |
237 | clear_tsk_thread_flag(current, TIF_SINGLE_STEP); | 238 | clear_tsk_thread_flag(current, TIF_PER_TRAP); |
238 | if (is_compat_task()) | 239 | if (is_compat_task()) |
239 | sys32_sigreturn(); | 240 | sys32_sigreturn(); |
240 | else | 241 | else |
241 | sys_sigreturn(); | 242 | sys_sigreturn(); |
242 | } else if (!rc && instruction == 0x0aad) { | 243 | } else if (!rc && instruction == 0x0aad) { |
243 | clear_tsk_thread_flag(current, TIF_SINGLE_STEP); | 244 | clear_tsk_thread_flag(current, TIF_PER_TRAP); |
244 | if (is_compat_task()) | 245 | if (is_compat_task()) |
245 | sys32_rt_sigreturn(); | 246 | sys32_rt_sigreturn(); |
246 | else | 247 | else |
@@ -378,7 +379,7 @@ static inline int do_exception(struct pt_regs *regs, int access, | |||
378 | * The instruction that caused the program check will | 379 | * The instruction that caused the program check will |
379 | * be repeated. Don't signal single step via SIGTRAP. | 380 | * be repeated. Don't signal single step via SIGTRAP. |
380 | */ | 381 | */ |
381 | clear_tsk_thread_flag(tsk, TIF_SINGLE_STEP); | 382 | clear_tsk_thread_flag(tsk, TIF_PER_TRAP); |
382 | fault = 0; | 383 | fault = 0; |
383 | out_up: | 384 | out_up: |
384 | up_read(&mm->mmap_sem); | 385 | up_read(&mm->mmap_sem); |
@@ -480,8 +481,7 @@ int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write) | |||
480 | /* | 481 | /* |
481 | * 'pfault' pseudo page faults routines. | 482 | * 'pfault' pseudo page faults routines. |
482 | */ | 483 | */ |
483 | static ext_int_info_t ext_int_pfault; | 484 | static int pfault_disable; |
484 | static int pfault_disable = 0; | ||
485 | 485 | ||
486 | static int __init nopfault(char *str) | 486 | static int __init nopfault(char *str) |
487 | { | 487 | { |
@@ -543,6 +543,7 @@ static void pfault_interrupt(unsigned int ext_int_code, | |||
543 | struct task_struct *tsk; | 543 | struct task_struct *tsk; |
544 | __u16 subcode; | 544 | __u16 subcode; |
545 | 545 | ||
546 | kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++; | ||
546 | /* | 547 | /* |
547 | * Get the external interruption subcode & pfault | 548 | * Get the external interruption subcode & pfault |
548 | * initial/completion signal bit. VM stores this | 549 | * initial/completion signal bit. VM stores this |
@@ -592,24 +593,28 @@ static void pfault_interrupt(unsigned int ext_int_code, | |||
592 | } | 593 | } |
593 | } | 594 | } |
594 | 595 | ||
595 | void __init pfault_irq_init(void) | 596 | static int __init pfault_irq_init(void) |
596 | { | 597 | { |
597 | if (!MACHINE_IS_VM) | 598 | int rc; |
598 | return; | ||
599 | 599 | ||
600 | if (!MACHINE_IS_VM) | ||
601 | return 0; | ||
600 | /* | 602 | /* |
601 | * Try to get pfault pseudo page faults going. | 603 | * Try to get pfault pseudo page faults going. |
602 | */ | 604 | */ |
603 | if (register_early_external_interrupt(0x2603, pfault_interrupt, | 605 | rc = register_external_interrupt(0x2603, pfault_interrupt); |
604 | &ext_int_pfault) != 0) | 606 | if (rc) { |
605 | panic("Couldn't request external interrupt 0x2603"); | 607 | pfault_disable = 1; |
606 | 608 | return rc; | |
609 | } | ||
607 | if (pfault_init() == 0) | 610 | if (pfault_init() == 0) |
608 | return; | 611 | return 0; |
609 | 612 | ||
610 | /* Tough luck, no pfault. */ | 613 | /* Tough luck, no pfault. */ |
611 | pfault_disable = 1; | 614 | pfault_disable = 1; |
612 | unregister_early_external_interrupt(0x2603, pfault_interrupt, | 615 | unregister_external_interrupt(0x2603, pfault_interrupt); |
613 | &ext_int_pfault); | 616 | return 0; |
614 | } | 617 | } |
618 | early_initcall(pfault_irq_init); | ||
619 | |||
615 | #endif | 620 | #endif |