diff options
Diffstat (limited to 'arch/s390/mm/fault.c')
| -rw-r--r-- | arch/s390/mm/fault.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 1c323bbfda91..cd85e34d8703 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
| 32 | #include <asm/pgtable.h> | 32 | #include <asm/pgtable.h> |
| 33 | #include <asm/kdebug.h> | 33 | #include <asm/kdebug.h> |
| 34 | #include <asm/s390_ext.h> | ||
| 34 | 35 | ||
| 35 | #ifndef CONFIG_64BIT | 36 | #ifndef CONFIG_64BIT |
| 36 | #define __FAIL_ADDR_MASK 0x7ffff000 | 37 | #define __FAIL_ADDR_MASK 0x7ffff000 |
| @@ -394,6 +395,7 @@ void do_dat_exception(struct pt_regs *regs, unsigned long error_code) | |||
| 394 | /* | 395 | /* |
| 395 | * 'pfault' pseudo page faults routines. | 396 | * 'pfault' pseudo page faults routines. |
| 396 | */ | 397 | */ |
| 398 | static ext_int_info_t ext_int_pfault; | ||
| 397 | static int pfault_disable = 0; | 399 | static int pfault_disable = 0; |
| 398 | 400 | ||
| 399 | static int __init nopfault(char *str) | 401 | static int __init nopfault(char *str) |
| @@ -422,7 +424,7 @@ int pfault_init(void) | |||
| 422 | __PF_RES_FIELD }; | 424 | __PF_RES_FIELD }; |
| 423 | int rc; | 425 | int rc; |
| 424 | 426 | ||
| 425 | if (pfault_disable) | 427 | if (!MACHINE_IS_VM || pfault_disable) |
| 426 | return -1; | 428 | return -1; |
| 427 | asm volatile( | 429 | asm volatile( |
| 428 | " diag %1,%0,0x258\n" | 430 | " diag %1,%0,0x258\n" |
| @@ -440,7 +442,7 @@ void pfault_fini(void) | |||
| 440 | pfault_refbk_t refbk = | 442 | pfault_refbk_t refbk = |
| 441 | { 0x258, 1, 5, 2, 0ULL, 0ULL, 0ULL, 0ULL }; | 443 | { 0x258, 1, 5, 2, 0ULL, 0ULL, 0ULL, 0ULL }; |
| 442 | 444 | ||
| 443 | if (pfault_disable) | 445 | if (!MACHINE_IS_VM || pfault_disable) |
| 444 | return; | 446 | return; |
| 445 | __ctl_clear_bit(0,9); | 447 | __ctl_clear_bit(0,9); |
| 446 | asm volatile( | 448 | asm volatile( |
| @@ -500,5 +502,25 @@ pfault_interrupt(__u16 error_code) | |||
| 500 | set_tsk_need_resched(tsk); | 502 | set_tsk_need_resched(tsk); |
| 501 | } | 503 | } |
| 502 | } | 504 | } |
| 503 | #endif | ||
| 504 | 505 | ||
| 506 | void __init pfault_irq_init(void) | ||
| 507 | { | ||
| 508 | if (!MACHINE_IS_VM) | ||
| 509 | return; | ||
| 510 | |||
| 511 | /* | ||
| 512 | * Try to get pfault pseudo page faults going. | ||
| 513 | */ | ||
| 514 | if (register_early_external_interrupt(0x2603, pfault_interrupt, | ||
| 515 | &ext_int_pfault) != 0) | ||
| 516 | panic("Couldn't request external interrupt 0x2603"); | ||
| 517 | |||
| 518 | if (pfault_init() == 0) | ||
| 519 | return; | ||
| 520 | |||
| 521 | /* Tough luck, no pfault. */ | ||
| 522 | pfault_disable = 1; | ||
| 523 | unregister_early_external_interrupt(0x2603, pfault_interrupt, | ||
| 524 | &ext_int_pfault); | ||
| 525 | } | ||
| 526 | #endif | ||
