lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Thu, 8 Oct 2020 12:45:32 +0530 From: Maninder Singh <maninder1.s@...sung.com> To: linux@...linux.org.uk, ndesaulniers@...gle.com, caij2003@...il.com, tglx@...utronix.de, bigeasy@...utronix.de, maz@...nel.org, valentin.schneider@....com, vincent.whitchurch@...s.com, nhuck@...gle.com, akpm@...ux-foundation.org, 0x7f454c46@...il.com, will@...nel.org Cc: a.sahrawat@...sung.com, v.narang@...sung.com, linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org, Maninder Singh <maninder1.s@...sung.com> Subject: [PATCH 2/3] arm: introduce IRQ stacks This patch adds code for switching to IRQ stack. IRQ stack and Kernel SVC stack have below design. IRQ STACK:- ------------ IRQ stack top | | ------------ . . . . . . ------------ | sp | <- irq_stack_base + 0x8 ------------ | fp | <- irq_stack_base + 0x4 ------------ |tinfo_ptr | /* pointer to thread info */ irq_stack_ptr --> ------------ IRQ stack base Kernel SVC stack:- ------------ Kernel stack top | | ------------ . . . . . . ------------ | | | | ------------ |tinfo_ptr | /* pointer to thread info */ ------------ Kernel stack base Co-developed-by: Vaneet Narang <v.narang@...sung.com> Signed-off-by: Vaneet Narang <v.narang@...sung.com> Signed-off-by: Maninder Singh <maninder1.s@...sung.com> --- arch/arm/include/asm/assembler.h | 8 ++++++++ arch/arm/include/asm/irq.h | 6 ++++++ arch/arm/kernel/entry-armv.S | 41 +++++++++++++++++++++++++++++++++++++++- arch/arm/kernel/irq.c | 24 +++++++++++++++++++++++ 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 8512bdc..82ee6ee 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -212,6 +212,14 @@ #endif .endm + .macro this_cpu_ptr, sym, reg, tmp + ldr \reg, =\sym +#if defined(CONFIG_SMP) && !defined(CONFIG_CPU_V6) + mrc p15, 0, \tmp, cr13, c0, 4 + add \reg, \reg, \tmp +#endif + .endm + /* * Increment/decrement the preempt count. */ diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h index 46d4114..f3299ab 100644 --- a/arch/arm/include/asm/irq.h +++ b/arch/arm/include/asm/irq.h @@ -22,10 +22,16 @@ #define NO_IRQ ((unsigned int)(-1)) #endif +#define IRQ_STACK_SIZE THREAD_SIZE + #ifndef __ASSEMBLY__ struct irqaction; struct pt_regs; +#ifdef CONFIG_IRQ_STACK +DECLARE_PER_CPU(unsigned long *, irq_stack_ptr); +#endif + extern void asm_do_IRQ(unsigned int, struct pt_regs *); void handle_IRQ(unsigned int, struct pt_regs *); void init_IRQ(void); diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 55a47df..13a5889 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S @@ -32,6 +32,43 @@ #include "entry-header.S" #include <asm/entry-macro-multi.S> #include <asm/probes.h> +#ifdef CONFIG_IRQ_STACK +#include <asm/irq.h> +#endif + + .macro irq_stack_entry +#ifdef CONFIG_IRQ_STACK + mov r6, sp /* preserve sp */ + + this_cpu_ptr irq_stack_ptr, r7, r8 + ldr r7, [r7] + mov r8, r7 + + /* + * Compare sp with base of IRQ stack. + * if the top ~(#THREAD_SIZE_ORDER + PAGE_SHIFT) bits match, + * we are on a irq stack. + */ + eor r8, r8, sp + lsrs r8, #THREAD_SIZE_ORDER + PAGE_SHIFT + beq 9998f + + /* + * store thread info pointer on IRQ stack and + * switch to the irq stack. + */ + get_thread_info r8 + stm r7, {r8, fp, sp} + add sp, r7, #IRQ_STACK_SIZE +9998: +#endif + .endm + + .macro irq_stack_exit +#ifdef CONFIG_IRQ_STACK + mov sp, r6 /* restore sp */ +#endif + .endm /* * Interrupt handling. @@ -41,11 +78,13 @@ ldr r1, =handle_arch_irq mov r0, sp badr lr, 9997f + irq_stack_entry ldr pc, [r1] +9997: + irq_stack_exit #else arch_irq_handler_default #endif -9997: .endm .macro pabt_helper diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 698b6f6..79872e5 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c @@ -43,6 +43,15 @@ unsigned long irq_err_count; +#ifdef CONFIG_IRQ_STACK +DEFINE_PER_CPU(unsigned long *, irq_stack_ptr); + +/* + * irq_stack must be IRQ_STACK_SIZE(THREAD_SIZE) aligned, + */ +DEFINE_PER_CPU(unsigned long [IRQ_STACK_SIZE/sizeof(long)], irq_stack) __aligned(IRQ_STACK_SIZE); +#endif + int arch_show_interrupts(struct seq_file *p, int prec) { #ifdef CONFIG_FIQ @@ -55,6 +64,20 @@ int arch_show_interrupts(struct seq_file *p, int prec) return 0; } +#ifdef CONFIG_IRQ_STACK +static void init_irq_stacks(void) +{ + int cpu; + + for_each_possible_cpu(cpu) + per_cpu(irq_stack_ptr, cpu) = per_cpu(irq_stack, cpu); +} +#else +static inline void init_irq_stacks(void) +{ +} +#endif + /* * handle_IRQ handles all hardware IRQ's. Decoded IRQs should * not come via this function. Instead, they should provide their @@ -79,6 +102,7 @@ void __init init_IRQ(void) { int ret; + init_irq_stacks(); if (IS_ENABLED(CONFIG_OF) && !machine_desc->init_irq) irqchip_init(); else -- 1.9.1
Powered by blists - more mailing lists