2012-03-05 11:49:29 +00:00
/*
* Based on arch / arm / kernel / irq . c
*
* Copyright ( C ) 1992 Linus Torvalds
* Modifications for ARM processor Copyright ( C ) 1995 - 2000 Russell King .
* Support for Dynamic Tick Timer Copyright ( C ) 2004 - 2005 Nokia Corporation .
* Dynamic Tick Timer written by Tony Lindgren < tony @ atomide . com > and
* Tuukka Tikkanen < tuukka . tikkanen @ elektrobit . com > .
* Copyright ( C ) 2012 ARM Ltd .
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include <linux/kernel_stat.h>
# include <linux/irq.h>
# include <linux/smp.h>
# include <linux/init.h>
2013-01-14 12:39:31 +00:00
# include <linux/irqchip.h>
2012-03-05 11:49:29 +00:00
# include <linux/seq_file.h>
unsigned long irq_err_count ;
arm64: remove irq_count and do_softirq_own_stack()
sysrq_handle_reboot() re-enables interrupts while on the irq stack. The
irq_stack implementation wrongly assumed this would only ever happen
via the softirq path, allowing it to update irq_count late, in
do_softirq_own_stack().
This means if an irq occurs in sysrq_handle_reboot(), during
emergency_restart() the stack will be corrupted, as irq_count wasn't
updated.
Lose the optimisation, and instead of moving the adding/subtracting of
irq_count into irq_stack_entry/irq_stack_exit, remove it, and compare
sp_el0 (struct thread_info) with sp & ~(THREAD_SIZE - 1). This tells us
if we are on a task stack, if so, we can safely switch to the irq stack.
Finally, remove do_softirq_own_stack(), we don't need it anymore.
Reported-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: James Morse <james.morse@arm.com>
[will: use get_thread_info macro]
Signed-off-by: Will Deacon <will.deacon@arm.com>
2015-12-18 16:01:47 +00:00
/* irq stack only needs to be 16 byte aligned - not IRQ_STACK_SIZE aligned. */
2015-12-04 11:02:26 +00:00
DEFINE_PER_CPU ( unsigned long [ IRQ_STACK_SIZE / sizeof ( long ) ] , irq_stack ) __aligned ( 16 ) ;
2012-03-05 11:49:29 +00:00
int arch_show_interrupts ( struct seq_file * p , int prec )
{
show_ipi_list ( p , prec ) ;
seq_printf ( p , " %*s: %10lu \n " , prec , " Err " , irq_err_count ) ;
return 0 ;
}
2014-11-21 21:50:38 +00:00
void ( * handle_arch_irq ) ( struct pt_regs * ) = NULL ;
2013-01-14 12:39:31 +00:00
void __init set_handle_irq ( void ( * handle_irq ) ( struct pt_regs * ) )
{
if ( handle_arch_irq )
return ;
handle_arch_irq = handle_irq ;
}
2012-03-05 11:49:29 +00:00
void __init init_IRQ ( void )
{
2013-01-14 12:39:31 +00:00
irqchip_init ( ) ;
2012-03-05 11:49:29 +00:00
if ( ! handle_arch_irq )
panic ( " No interrupt controller found. " ) ;
}