s390: remove critical section cleanup from entry.S
The current code is rather complex and caused a lot of subtle and hard to debug bugs in the past. Simplify the code by calling the system_call handler with interrupts disabled, save machine state, and re-enable them later. This requires significant changes to the machine check handling code as well. When the machine check interrupt arrived while being in kernel mode the new code will signal pending machine checks with a SIGP external call. When userspace was interrupted, the handler will switch to the kernel stack and directly execute s390_handle_mcck(). Signed-off-by: Sven Schnelle <svens@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:

committed by
Vasily Gorbik

parent
11886c199d
commit
0b0ed657fe
@@ -24,19 +24,19 @@ void enabled_wait(void)
|
||||
{
|
||||
struct s390_idle_data *idle = this_cpu_ptr(&s390_idle);
|
||||
unsigned long long idle_time;
|
||||
unsigned long psw_mask;
|
||||
unsigned long psw_mask, flags;
|
||||
|
||||
trace_hardirqs_on();
|
||||
|
||||
/* Wait for external, I/O or machine check interrupt. */
|
||||
psw_mask = PSW_KERNEL_BITS | PSW_MASK_WAIT | PSW_MASK_DAT |
|
||||
PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK;
|
||||
clear_cpu_flag(CIF_NOHZ_DELAY);
|
||||
|
||||
local_irq_save(flags);
|
||||
/* Call the assembler magic in entry.S */
|
||||
psw_idle(idle, psw_mask);
|
||||
local_irq_restore(flags);
|
||||
|
||||
trace_hardirqs_off();
|
||||
|
||||
/* Account time spent with enabled wait psw loaded as idle time. */
|
||||
write_seqcount_begin(&idle->seqcount);
|
||||
@@ -118,22 +118,16 @@ u64 arch_cpu_idle_time(int cpu)
|
||||
|
||||
void arch_cpu_idle_enter(void)
|
||||
{
|
||||
local_mcck_disable();
|
||||
}
|
||||
|
||||
void arch_cpu_idle(void)
|
||||
{
|
||||
if (!test_cpu_flag(CIF_MCCK_PENDING))
|
||||
/* Halt the cpu and keep track of cpu time accounting. */
|
||||
enabled_wait();
|
||||
enabled_wait();
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
void arch_cpu_idle_exit(void)
|
||||
{
|
||||
local_mcck_enable();
|
||||
if (test_cpu_flag(CIF_MCCK_PENDING))
|
||||
s390_handle_mcck();
|
||||
}
|
||||
|
||||
void arch_cpu_idle_dead(void)
|
||||
|
Reference in New Issue
Block a user