mirror of
https://github.com/torvalds/linux.git
synced 2024-11-16 00:52:01 +00:00
[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>
This commit is contained in:
parent
a0016408f2
commit
d4b6899678
@ -57,7 +57,6 @@ int sysctl_userprocess_debug = 0;
|
||||
|
||||
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 @@ asmlinkage void kernel_stack_overflow(struct pt_regs * regs)
|
||||
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 @@ void __init trap_init(void)
|
||||
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 @@ void __init trap_init(void)
|
||||
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");
|
||||
@ -747,10 +728,6 @@ void __init trap_init(void)
|
||||
/* Tough luck, no pfault. */
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -352,115 +352,6 @@ void do_dat_exception(struct pt_regs *regs, unsigned long error_code)
|
||||
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 @@ int pfault_init(void)
|
||||
" .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 @@ void pfault_fini(void)
|
||||
" .quad 0b,0b\n"
|
||||
#endif /* CONFIG_ARCH_S390X */
|
||||
".previous"
|
||||
: : "a" (&refbk) : "cc" );
|
||||
: : "a" (&refbk), "m" (refbk) : "cc" );
|
||||
}
|
||||
|
||||
asmlinkage void
|
||||
|
Loading…
Reference in New Issue
Block a user