[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>
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 6b8703e..c5bd36f 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -57,7 +57,6 @@
 
 extern pgm_check_handler_t do_protection_exception;
 extern pgm_check_handler_t do_dat_exception;
-extern pgm_check_handler_t do_pseudo_page_fault;
 #ifdef CONFIG_PFAULT
 extern int pfault_init(void);
 extern void pfault_fini(void);
@@ -676,20 +675,6 @@
 	panic("Corrupt kernel stack, can't continue.");
 }
 
-#ifndef CONFIG_ARCH_S390X
-static int
-pagex_reboot_event(struct notifier_block *this, unsigned long event, void *ptr)
-{
-	if (MACHINE_IS_VM)
-		cpcmd("SET PAGEX OFF", NULL, 0, NULL);
-	return NOTIFY_DONE;
-}
-
-static struct notifier_block pagex_reboot_notifier = {
-	.notifier_call = &pagex_reboot_event,
-};
-#endif
-
 /* init is done in lowcore.S and head.S */
 
 void __init trap_init(void)
@@ -717,9 +702,7 @@
         pgm_check_table[0x11] = &do_dat_exception;
         pgm_check_table[0x12] = &translation_exception;
         pgm_check_table[0x13] = &special_op_exception;
-#ifndef CONFIG_ARCH_S390X
- 	pgm_check_table[0x14] = &do_pseudo_page_fault;
-#else /* CONFIG_ARCH_S390X */
+#ifdef CONFIG_ARCH_S390X
         pgm_check_table[0x38] = &do_dat_exception;
 	pgm_check_table[0x39] = &do_dat_exception;
 	pgm_check_table[0x3A] = &do_dat_exception;
@@ -731,12 +714,10 @@
 	pgm_check_table[0x40] = &do_monitor_call;
 
 	if (MACHINE_IS_VM) {
-		/*
-		 * First try to get pfault pseudo page faults going.
-		 * If this isn't available turn on pagex page faults.
-		 */
 #ifdef CONFIG_PFAULT
-		/* request the 0x2603 external interrupt */
+		/*
+		 * Try to get pfault pseudo page faults going.
+		 */
 		if (register_early_external_interrupt(0x2603, pfault_interrupt,
 						      &ext_int_pfault) != 0)
 			panic("Couldn't request external interrupt 0x2603");
@@ -748,9 +729,5 @@
 		unregister_early_external_interrupt(0x2603, pfault_interrupt,
 						    &ext_int_pfault);
 #endif
-#ifndef CONFIG_ARCH_S390X
-		register_reboot_notifier(&pagex_reboot_notifier);
-		cpcmd("SET PAGEX ON", NULL, 0, NULL);
-#endif
 	}
 }
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 856a971..64e32da 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -352,115 +352,6 @@
 	do_exception(regs, error_code & 0xff, 0);
 }
 
-#ifndef CONFIG_ARCH_S390X
-
-typedef struct _pseudo_wait_t {
-       struct _pseudo_wait_t *next;
-       wait_queue_head_t queue;
-       unsigned long address;
-       int resolved;
-} pseudo_wait_t;
-
-static pseudo_wait_t *pseudo_lock_queue = NULL;
-static spinlock_t pseudo_wait_spinlock; /* spinlock to protect lock queue */
-
-/*
- * This routine handles 'pagex' pseudo page faults.
- */
-asmlinkage void
-do_pseudo_page_fault(struct pt_regs *regs, unsigned long error_code)
-{
-        pseudo_wait_t wait_struct;
-        pseudo_wait_t *ptr, *last, *next;
-        unsigned long address;
-
-        /*
-         * get the failing address
-         * more specific the segment and page table portion of
-         * the address
-         */
-        address = S390_lowcore.trans_exc_code & 0xfffff000;
-
-        if (address & 0x80000000) {
-                /* high bit set -> a page has been swapped in by VM */
-                address &= 0x7fffffff;
-                spin_lock(&pseudo_wait_spinlock);
-                last = NULL;
-                ptr = pseudo_lock_queue;
-                while (ptr != NULL) {
-                        next = ptr->next;
-                        if (address == ptr->address) {
-				 /*
-                                 * This is one of the processes waiting
-                                 * for the page. Unchain from the queue.
-                                 * There can be more than one process
-                                 * waiting for the same page. VM presents
-                                 * an initial and a completion interrupt for
-                                 * every process that tries to access a 
-                                 * page swapped out by VM. 
-                                 */
-                                if (last == NULL)
-                                        pseudo_lock_queue = next;
-                                else
-                                        last->next = next;
-                                /* now wake up the process */
-                                ptr->resolved = 1;
-                                wake_up(&ptr->queue);
-                        } else
-                                last = ptr;
-                        ptr = next;
-                }
-                spin_unlock(&pseudo_wait_spinlock);
-        } else {
-                /* Pseudo page faults in kernel mode is a bad idea */
-                if (!(regs->psw.mask & PSW_MASK_PSTATE)) {
-                        /*
-			 * VM presents pseudo page faults if the interrupted
-			 * state was not disabled for interrupts. So we can
-			 * get pseudo page fault interrupts while running
-			 * in kernel mode. We simply access the page here
-			 * while we are running disabled. VM will then swap
-			 * in the page synchronously.
-                         */
-                         if (check_user_space(regs, error_code) == 0)
-                                 /* dereference a virtual kernel address */
-                                 __asm__ __volatile__ (
-                                         "  ic 0,0(%0)"
-                                         : : "a" (address) : "0");
-                         else
-                                 /* dereference a virtual user address */
-                                 __asm__ __volatile__ (
-                                         "  la   2,0(%0)\n"
-                                         "  sacf 512\n"
-                                         "  ic   2,0(2)\n"
-					 "0:sacf 0\n"
-					 ".section __ex_table,\"a\"\n"
-					 "  .align 4\n"
-					 "  .long  0b,0b\n"
-					 ".previous"
-                                         : : "a" (address) : "2" );
-
-                        return;
-                }
-		/* initialize and add element to pseudo_lock_queue */
-                init_waitqueue_head (&wait_struct.queue);
-                wait_struct.address = address;
-                wait_struct.resolved = 0;
-                spin_lock(&pseudo_wait_spinlock);
-                wait_struct.next = pseudo_lock_queue;
-                pseudo_lock_queue = &wait_struct;
-                spin_unlock(&pseudo_wait_spinlock);
-		/*
-		 * The instruction that caused the program check will
-		 * be repeated. Don't signal single step via SIGTRAP.
-		 */
-		clear_tsk_thread_flag(current, TIF_SINGLE_STEP);
-                /* go to sleep */
-                wait_event(wait_struct.queue, wait_struct.resolved);
-        }
-}
-#endif /* CONFIG_ARCH_S390X */
-
 #ifdef CONFIG_PFAULT 
 /*
  * 'pfault' pseudo page faults routines.
@@ -508,7 +399,7 @@
 		"   .quad  0b,1b\n"
 #endif /* CONFIG_ARCH_S390X */
 		".previous"
-                : "=d" (rc) : "a" (&refbk) : "cc" );
+                : "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc" );
         __ctl_set_bit(0, 9);
         return rc;
 }
@@ -532,7 +423,7 @@
 		"   .quad  0b,0b\n"
 #endif /* CONFIG_ARCH_S390X */
 		".previous"
-		: : "a" (&refbk) : "cc" );
+		: : "a" (&refbk), "m" (refbk) : "cc" );
 }
 
 asmlinkage void