hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/arch/x86/kernel/irq_64.c
....@@ -18,72 +18,61 @@
1818 #include <linux/uaccess.h>
1919 #include <linux/smp.h>
2020 #include <linux/sched/task_stack.h>
21
+
22
+#include <asm/cpu_entry_area.h>
23
+#include <asm/irq_stack.h>
2124 #include <asm/io_apic.h>
2225 #include <asm/apic.h>
2326
24
-int sysctl_panic_on_stackoverflow;
27
+DEFINE_PER_CPU_PAGE_ALIGNED(struct irq_stack, irq_stack_backing_store) __visible;
28
+DECLARE_INIT_PER_CPU(irq_stack_backing_store);
2529
30
+#ifdef CONFIG_VMAP_STACK
2631 /*
27
- * Probabilistic stack overflow check:
28
- *
29
- * Regular device interrupts can enter on the following stacks:
30
- *
31
- * - User stack
32
- *
33
- * - Kernel task stack
34
- *
35
- * - Interrupt stack if a device driver reenables interrupts
36
- * which should only happen in really old drivers.
37
- *
38
- * - Debug IST stack
39
- *
40
- * All other contexts are invalid.
32
+ * VMAP the backing store with guard pages
4133 */
42
-static inline void stack_overflow_check(struct pt_regs *regs)
34
+static int map_irq_stack(unsigned int cpu)
4335 {
44
-#ifdef CONFIG_DEBUG_STACKOVERFLOW
45
-#define STACK_TOP_MARGIN 128
46
- struct orig_ist *oist;
47
- u64 irq_stack_top, irq_stack_bottom;
48
- u64 estack_top, estack_bottom;
49
- u64 curbase = (u64)task_stack_page(current);
36
+ char *stack = (char *)per_cpu_ptr(&irq_stack_backing_store, cpu);
37
+ struct page *pages[IRQ_STACK_SIZE / PAGE_SIZE];
38
+ void *va;
39
+ int i;
5040
51
- if (user_mode(regs))
52
- return;
41
+ for (i = 0; i < IRQ_STACK_SIZE / PAGE_SIZE; i++) {
42
+ phys_addr_t pa = per_cpu_ptr_to_phys(stack + (i << PAGE_SHIFT));
5343
54
- if (regs->sp >= curbase + sizeof(struct pt_regs) + STACK_TOP_MARGIN &&
55
- regs->sp <= curbase + THREAD_SIZE)
56
- return;
44
+ pages[i] = pfn_to_page(pa >> PAGE_SHIFT);
45
+ }
5746
58
- irq_stack_top = (u64)this_cpu_ptr(irq_stack_union.irq_stack) +
59
- STACK_TOP_MARGIN;
60
- irq_stack_bottom = (u64)__this_cpu_read(irq_stack_ptr);
61
- if (regs->sp >= irq_stack_top && regs->sp <= irq_stack_bottom)
62
- return;
47
+ va = vmap(pages, IRQ_STACK_SIZE / PAGE_SIZE, VM_MAP, PAGE_KERNEL);
48
+ if (!va)
49
+ return -ENOMEM;
6350
64
- oist = this_cpu_ptr(&orig_ist);
65
- estack_bottom = (u64)oist->ist[DEBUG_STACK];
66
- estack_top = estack_bottom - DEBUG_STKSZ + STACK_TOP_MARGIN;
67
- if (regs->sp >= estack_top && regs->sp <= estack_bottom)
68
- return;
51
+ per_cpu(hardirq_stack_ptr, cpu) = va + IRQ_STACK_SIZE;
52
+ return 0;
53
+}
54
+#else
55
+/*
56
+ * If VMAP stacks are disabled due to KASAN, just use the per cpu
57
+ * backing store without guard pages.
58
+ */
59
+static int map_irq_stack(unsigned int cpu)
60
+{
61
+ void *va = per_cpu_ptr(&irq_stack_backing_store, cpu);
6962
70
- WARN_ONCE(1, "do_IRQ(): %s has overflown the kernel stack (cur:%Lx,sp:%lx,irq stk top-bottom:%Lx-%Lx,exception stk top-bottom:%Lx-%Lx,ip:%pF)\n",
71
- current->comm, curbase, regs->sp,
72
- irq_stack_top, irq_stack_bottom,
73
- estack_top, estack_bottom, (void *)regs->ip);
74
-
75
- if (sysctl_panic_on_stackoverflow)
76
- panic("low stack detected by irq handler - check messages\n");
63
+ per_cpu(hardirq_stack_ptr, cpu) = va + IRQ_STACK_SIZE;
64
+ return 0;
65
+}
7766 #endif
67
+
68
+int irq_init_percpu_irqstack(unsigned int cpu)
69
+{
70
+ if (per_cpu(hardirq_stack_ptr, cpu))
71
+ return 0;
72
+ return map_irq_stack(cpu);
7873 }
7974
80
-bool handle_irq(struct irq_desc *desc, struct pt_regs *regs)
75
+void do_softirq_own_stack(void)
8176 {
82
- stack_overflow_check(regs);
83
-
84
- if (IS_ERR_OR_NULL(desc))
85
- return false;
86
-
87
- generic_handle_irq_desc(desc);
88
- return true;
77
+ run_on_irqstack_cond(__do_softirq, NULL);
8978 }