diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2005-11-07 03:59:06 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-07 10:53:33 -0500 |
commit | d4b68996785326a67e9842219ab69984243ec658 (patch) | |
tree | ed929419af82f8086e82aa6dd190712a3493d122 /arch/s390 | |
parent | a0016408f2428225f1532cbf63ca1c7008e1cc93 (diff) |
[PATCH] s390: remove pagex support
Remove pagex pseudo page fault code. It does not work together with the
system call speedup that makes the complete system call path enabled for
interrupts. To make pagex and the syscall speedup code work together we would
have to add code to the program check handler to do a critical section cleanup
like the asynchronous interrupt code. This would make program checks slower.
Not what we want.
Newer versions of z/VM have the improved pfault pseudo page fault interface.
This replaces the old pagex interface and does not have the problem. So its
better to just rip out the pagex code.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/kernel/traps.c | 29 | ||||
-rw-r--r-- | arch/s390/mm/fault.c | 113 |
2 files changed, 5 insertions, 137 deletions
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 6b8703ec2ae6..c5bd36fae56b 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c | |||
@@ -57,7 +57,6 @@ int sysctl_userprocess_debug = 0; | |||
57 | 57 | ||
58 | extern pgm_check_handler_t do_protection_exception; | 58 | extern pgm_check_handler_t do_protection_exception; |
59 | extern pgm_check_handler_t do_dat_exception; | 59 | extern pgm_check_handler_t do_dat_exception; |
60 | extern pgm_check_handler_t do_pseudo_page_fault; | ||
61 | #ifdef CONFIG_PFAULT | 60 | #ifdef CONFIG_PFAULT |
62 | extern int pfault_init(void); | 61 | extern int pfault_init(void); |
63 | extern void pfault_fini(void); | 62 | extern void pfault_fini(void); |
@@ -676,20 +675,6 @@ asmlinkage void kernel_stack_overflow(struct pt_regs * regs) | |||
676 | panic("Corrupt kernel stack, can't continue."); | 675 | panic("Corrupt kernel stack, can't continue."); |
677 | } | 676 | } |
678 | 677 | ||
679 | #ifndef CONFIG_ARCH_S390X | ||
680 | static int | ||
681 | pagex_reboot_event(struct notifier_block *this, unsigned long event, void *ptr) | ||
682 | { | ||
683 | if (MACHINE_IS_VM) | ||
684 | cpcmd("SET PAGEX OFF", NULL, 0, NULL); | ||
685 | return NOTIFY_DONE; | ||
686 | } | ||
687 | |||
688 | static struct notifier_block pagex_reboot_notifier = { | ||
689 | .notifier_call = &pagex_reboot_event, | ||
690 | }; | ||
691 | #endif | ||
692 | |||
693 | /* init is done in lowcore.S and head.S */ | 678 | /* init is done in lowcore.S and head.S */ |
694 | 679 | ||
695 | void __init trap_init(void) | 680 | void __init trap_init(void) |
@@ -717,9 +702,7 @@ void __init trap_init(void) | |||
717 | pgm_check_table[0x11] = &do_dat_exception; | 702 | pgm_check_table[0x11] = &do_dat_exception; |
718 | pgm_check_table[0x12] = &translation_exception; | 703 | pgm_check_table[0x12] = &translation_exception; |
719 | pgm_check_table[0x13] = &special_op_exception; | 704 | pgm_check_table[0x13] = &special_op_exception; |
720 | #ifndef CONFIG_ARCH_S390X | 705 | #ifdef CONFIG_ARCH_S390X |
721 | pgm_check_table[0x14] = &do_pseudo_page_fault; | ||
722 | #else /* CONFIG_ARCH_S390X */ | ||
723 | pgm_check_table[0x38] = &do_dat_exception; | 706 | pgm_check_table[0x38] = &do_dat_exception; |
724 | pgm_check_table[0x39] = &do_dat_exception; | 707 | pgm_check_table[0x39] = &do_dat_exception; |
725 | pgm_check_table[0x3A] = &do_dat_exception; | 708 | pgm_check_table[0x3A] = &do_dat_exception; |
@@ -731,12 +714,10 @@ void __init trap_init(void) | |||
731 | pgm_check_table[0x40] = &do_monitor_call; | 714 | pgm_check_table[0x40] = &do_monitor_call; |
732 | 715 | ||
733 | if (MACHINE_IS_VM) { | 716 | if (MACHINE_IS_VM) { |
717 | #ifdef CONFIG_PFAULT | ||
734 | /* | 718 | /* |
735 | * First try to get pfault pseudo page faults going. | 719 | * Try to get pfault pseudo page faults going. |
736 | * If this isn't available turn on pagex page faults. | ||
737 | */ | 720 | */ |
738 | #ifdef CONFIG_PFAULT | ||
739 | /* request the 0x2603 external interrupt */ | ||
740 | if (register_early_external_interrupt(0x2603, pfault_interrupt, | 721 | if (register_early_external_interrupt(0x2603, pfault_interrupt, |
741 | &ext_int_pfault) != 0) | 722 | &ext_int_pfault) != 0) |
742 | panic("Couldn't request external interrupt 0x2603"); | 723 | panic("Couldn't request external interrupt 0x2603"); |
@@ -748,9 +729,5 @@ void __init trap_init(void) | |||
748 | unregister_early_external_interrupt(0x2603, pfault_interrupt, | 729 | unregister_early_external_interrupt(0x2603, pfault_interrupt, |
749 | &ext_int_pfault); | 730 | &ext_int_pfault); |
750 | #endif | 731 | #endif |
751 | #ifndef CONFIG_ARCH_S390X | ||
752 | register_reboot_notifier(&pagex_reboot_notifier); | ||
753 | cpcmd("SET PAGEX ON", NULL, 0, NULL); | ||
754 | #endif | ||
755 | } | 732 | } |
756 | } | 733 | } |
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 856a971759b1..64e32da77754 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c | |||
@@ -352,115 +352,6 @@ void do_dat_exception(struct pt_regs *regs, unsigned long error_code) | |||
352 | do_exception(regs, error_code & 0xff, 0); | 352 | do_exception(regs, error_code & 0xff, 0); |
353 | } | 353 | } |
354 | 354 | ||
355 | #ifndef CONFIG_ARCH_S390X | ||
356 | |||
357 | typedef struct _pseudo_wait_t { | ||
358 | struct _pseudo_wait_t *next; | ||
359 | wait_queue_head_t queue; | ||
360 | unsigned long address; | ||
361 | int resolved; | ||
362 | } pseudo_wait_t; | ||
363 | |||
364 | static pseudo_wait_t *pseudo_lock_queue = NULL; | ||
365 | static spinlock_t pseudo_wait_spinlock; /* spinlock to protect lock queue */ | ||
366 | |||
367 | /* | ||
368 | * This routine handles 'pagex' pseudo page faults. | ||
369 | */ | ||
370 | asmlinkage void | ||
371 | do_pseudo_page_fault(struct pt_regs *regs, unsigned long error_code) | ||
372 | { | ||
373 | pseudo_wait_t wait_struct; | ||
374 | pseudo_wait_t *ptr, *last, *next; | ||
375 | unsigned long address; | ||
376 | |||
377 | /* | ||
378 | * get the failing address | ||
379 | * more specific the segment and page table portion of | ||
380 | * the address | ||
381 | */ | ||
382 | address = S390_lowcore.trans_exc_code & 0xfffff000; | ||
383 | |||
384 | if (address & 0x80000000) { | ||
385 | /* high bit set -> a page has been swapped in by VM */ | ||
386 | address &= 0x7fffffff; | ||
387 | spin_lock(&pseudo_wait_spinlock); | ||
388 | last = NULL; | ||
389 | ptr = pseudo_lock_queue; | ||
390 | while (ptr != NULL) { | ||
391 | next = ptr->next; | ||
392 | if (address == ptr->address) { | ||
393 | /* | ||
394 | * This is one of the processes waiting | ||
395 | * for the page. Unchain from the queue. | ||
396 | * There can be more than one process | ||
397 | * waiting for the same page. VM presents | ||
398 | * an initial and a completion interrupt for | ||
399 | * every process that tries to access a | ||
400 | * page swapped out by VM. | ||
401 | */ | ||
402 | if (last == NULL) | ||
403 | pseudo_lock_queue = next; | ||
404 | else | ||
405 | last->next = next; | ||
406 | /* now wake up the process */ | ||
407 | ptr->resolved = 1; | ||
408 | wake_up(&ptr->queue); | ||
409 | } else | ||
410 | last = ptr; | ||
411 | ptr = next; | ||
412 | } | ||
413 | spin_unlock(&pseudo_wait_spinlock); | ||
414 | } else { | ||
415 | /* Pseudo page faults in kernel mode is a bad idea */ | ||
416 | if (!(regs->psw.mask & PSW_MASK_PSTATE)) { | ||
417 | /* | ||
418 | * VM presents pseudo page faults if the interrupted | ||
419 | * state was not disabled for interrupts. So we can | ||
420 | * get pseudo page fault interrupts while running | ||
421 | * in kernel mode. We simply access the page here | ||
422 | * while we are running disabled. VM will then swap | ||
423 | * in the page synchronously. | ||
424 | */ | ||
425 | if (check_user_space(regs, error_code) == 0) | ||
426 | /* dereference a virtual kernel address */ | ||
427 | __asm__ __volatile__ ( | ||
428 | " ic 0,0(%0)" | ||
429 | : : "a" (address) : "0"); | ||
430 | else | ||
431 | /* dereference a virtual user address */ | ||
432 | __asm__ __volatile__ ( | ||
433 | " la 2,0(%0)\n" | ||
434 | " sacf 512\n" | ||
435 | " ic 2,0(2)\n" | ||
436 | "0:sacf 0\n" | ||
437 | ".section __ex_table,\"a\"\n" | ||
438 | " .align 4\n" | ||
439 | " .long 0b,0b\n" | ||
440 | ".previous" | ||
441 | : : "a" (address) : "2" ); | ||
442 | |||
443 | return; | ||
444 | } | ||
445 | /* initialize and add element to pseudo_lock_queue */ | ||
446 | init_waitqueue_head (&wait_struct.queue); | ||
447 | wait_struct.address = address; | ||
448 | wait_struct.resolved = 0; | ||
449 | spin_lock(&pseudo_wait_spinlock); | ||
450 | wait_struct.next = pseudo_lock_queue; | ||
451 | pseudo_lock_queue = &wait_struct; | ||
452 | spin_unlock(&pseudo_wait_spinlock); | ||
453 | /* | ||
454 | * The instruction that caused the program check will | ||
455 | * be repeated. Don't signal single step via SIGTRAP. | ||
456 | */ | ||
457 | clear_tsk_thread_flag(current, TIF_SINGLE_STEP); | ||
458 | /* go to sleep */ | ||
459 | wait_event(wait_struct.queue, wait_struct.resolved); | ||
460 | } | ||
461 | } | ||
462 | #endif /* CONFIG_ARCH_S390X */ | ||
463 | |||
464 | #ifdef CONFIG_PFAULT | 355 | #ifdef CONFIG_PFAULT |
465 | /* | 356 | /* |
466 | * 'pfault' pseudo page faults routines. | 357 | * 'pfault' pseudo page faults routines. |
@@ -508,7 +399,7 @@ int pfault_init(void) | |||
508 | " .quad 0b,1b\n" | 399 | " .quad 0b,1b\n" |
509 | #endif /* CONFIG_ARCH_S390X */ | 400 | #endif /* CONFIG_ARCH_S390X */ |
510 | ".previous" | 401 | ".previous" |
511 | : "=d" (rc) : "a" (&refbk) : "cc" ); | 402 | : "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc" ); |
512 | __ctl_set_bit(0, 9); | 403 | __ctl_set_bit(0, 9); |
513 | return rc; | 404 | return rc; |
514 | } | 405 | } |
@@ -532,7 +423,7 @@ void pfault_fini(void) | |||
532 | " .quad 0b,0b\n" | 423 | " .quad 0b,0b\n" |
533 | #endif /* CONFIG_ARCH_S390X */ | 424 | #endif /* CONFIG_ARCH_S390X */ |
534 | ".previous" | 425 | ".previous" |
535 | : : "a" (&refbk) : "cc" ); | 426 | : : "a" (&refbk), "m" (refbk) : "cc" ); |
536 | } | 427 | } |
537 | 428 | ||
538 | asmlinkage void | 429 | asmlinkage void |