Commit f0178fc0 authored by Thomas Gleixner's avatar Thomas Gleixner

x86/entry: Unbreak __irqentry_text_start/end magic

The entry rework moved interrupt entry code from the irqentry to the
noinstr section which made the irqentry section empty.

This breaks boundary checks which rely on the __irqentry_text_start/end
markers to find out whether a function in a stack trace is
interrupt/exception entry code. This affects the function graph tracer and
filter_irq_stacks().

As the IDT entry points are all sequentialy emitted this is rather simple
to unbreak by injecting __irqentry_text_start/end as global labels.

To make this work correctly:

  - Remove the IRQENTRY_TEXT section from the x86 linker script
  - Define __irqentry so it breaks the build if it's used
  - Adjust the entry mirroring in PTI
  - Remove the redundant kprobes and unwinder bound checks
Reported-by: default avatarQian Cai <cai@lca.pw>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 2823e83a
...@@ -743,10 +743,19 @@ SYM_CODE_END(asm_\cfunc) ...@@ -743,10 +743,19 @@ SYM_CODE_END(asm_\cfunc)
/* /*
* Include the defines which emit the idt entries which are shared * Include the defines which emit the idt entries which are shared
* shared between 32 and 64 bit. * shared between 32 and 64 bit and emit the __irqentry_text_* markers
* so the stacktrace boundary checks work.
*/ */
.align 16
.globl __irqentry_text_start
__irqentry_text_start:
#include <asm/idtentry.h> #include <asm/idtentry.h>
.align 16
.globl __irqentry_text_end
__irqentry_text_end:
/* /*
* %eax: prev task * %eax: prev task
* %edx: next task * %edx: next task
......
...@@ -478,10 +478,19 @@ SYM_CODE_END(\asmsym) ...@@ -478,10 +478,19 @@ SYM_CODE_END(\asmsym)
/* /*
* Include the defines which emit the idt entries which are shared * Include the defines which emit the idt entries which are shared
* shared between 32 and 64 bit. * shared between 32 and 64 bit and emit the __irqentry_text_* markers
* so the stacktrace boundary checks work.
*/ */
.align 16
.globl __irqentry_text_start
__irqentry_text_start:
#include <asm/idtentry.h> #include <asm/idtentry.h>
.align 16
.globl __irqentry_text_end
__irqentry_text_end:
SYM_CODE_START_LOCAL(common_interrupt_return) SYM_CODE_START_LOCAL(common_interrupt_return)
SYM_INNER_LABEL(swapgs_restore_regs_and_return_to_usermode, SYM_L_GLOBAL) SYM_INNER_LABEL(swapgs_restore_regs_and_return_to_usermode, SYM_L_GLOBAL)
#ifdef CONFIG_DEBUG_ENTRY #ifdef CONFIG_DEBUG_ENTRY
......
...@@ -11,6 +11,13 @@ ...@@ -11,6 +11,13 @@
#include <asm/apicdef.h> #include <asm/apicdef.h>
#include <asm/irq_vectors.h> #include <asm/irq_vectors.h>
/*
* The irq entry code is in the noinstr section and the start/end of
* __irqentry_text is emitted via labels. Make the build fail if
* something moves a C function into the __irq_entry section.
*/
#define __irq_entry __invalid_section
static inline int irq_canonicalize(int irq) static inline int irq_canonicalize(int irq)
{ {
return ((irq == 2) ? 9 : irq); return ((irq == 2) ? 9 : irq);
......
...@@ -1073,13 +1073,6 @@ NOKPROBE_SYMBOL(kprobe_fault_handler); ...@@ -1073,13 +1073,6 @@ NOKPROBE_SYMBOL(kprobe_fault_handler);
int __init arch_populate_kprobe_blacklist(void) int __init arch_populate_kprobe_blacklist(void)
{ {
int ret;
ret = kprobe_add_area_blacklist((unsigned long)__irqentry_text_start,
(unsigned long)__irqentry_text_end);
if (ret)
return ret;
return kprobe_add_area_blacklist((unsigned long)__entry_text_start, return kprobe_add_area_blacklist((unsigned long)__entry_text_start,
(unsigned long)__entry_text_end); (unsigned long)__entry_text_end);
} }
......
...@@ -286,9 +286,7 @@ static int can_optimize(unsigned long paddr) ...@@ -286,9 +286,7 @@ static int can_optimize(unsigned long paddr)
* stack handling and registers setup. * stack handling and registers setup.
*/ */
if (((paddr >= (unsigned long)__entry_text_start) && if (((paddr >= (unsigned long)__entry_text_start) &&
(paddr < (unsigned long)__entry_text_end)) || (paddr < (unsigned long)__entry_text_end)))
((paddr >= (unsigned long)__irqentry_text_start) &&
(paddr < (unsigned long)__irqentry_text_end)))
return 0; return 0;
/* Check there is enough space for a relative jump. */ /* Check there is enough space for a relative jump. */
......
...@@ -74,13 +74,7 @@ static bool in_entry_code(unsigned long ip) ...@@ -74,13 +74,7 @@ static bool in_entry_code(unsigned long ip)
{ {
char *addr = (char *)ip; char *addr = (char *)ip;
if (addr >= __entry_text_start && addr < __entry_text_end) return addr >= __entry_text_start && addr < __entry_text_end;
return true;
if (addr >= __irqentry_text_start && addr < __irqentry_text_end)
return true;
return false;
} }
static inline unsigned long *last_frame(struct unwind_state *state) static inline unsigned long *last_frame(struct unwind_state *state)
......
...@@ -134,7 +134,6 @@ SECTIONS ...@@ -134,7 +134,6 @@ SECTIONS
KPROBES_TEXT KPROBES_TEXT
ALIGN_ENTRY_TEXT_BEGIN ALIGN_ENTRY_TEXT_BEGIN
ENTRY_TEXT ENTRY_TEXT
IRQENTRY_TEXT
ALIGN_ENTRY_TEXT_END ALIGN_ENTRY_TEXT_END
SOFTIRQENTRY_TEXT SOFTIRQENTRY_TEXT
*(.fixup) *(.fixup)
......
...@@ -492,12 +492,12 @@ static void __init pti_setup_espfix64(void) ...@@ -492,12 +492,12 @@ static void __init pti_setup_espfix64(void)
} }
/* /*
* Clone the populated PMDs of the entry and irqentry text and force it RO. * Clone the populated PMDs of the entry text and force it RO.
*/ */
static void pti_clone_entry_text(void) static void pti_clone_entry_text(void)
{ {
pti_clone_pgtable((unsigned long) __entry_text_start, pti_clone_pgtable((unsigned long) __entry_text_start,
(unsigned long) __irqentry_text_end, (unsigned long) __entry_text_end,
PTI_CLONE_PMD); PTI_CLONE_PMD);
} }
......
...@@ -760,8 +760,10 @@ extern int arch_early_irq_init(void); ...@@ -760,8 +760,10 @@ extern int arch_early_irq_init(void);
/* /*
* We want to know which function is an entrypoint of a hardirq or a softirq. * We want to know which function is an entrypoint of a hardirq or a softirq.
*/ */
#define __irq_entry __attribute__((__section__(".irqentry.text"))) #ifndef __irq_entry
#define __softirq_entry \ # define __irq_entry __attribute__((__section__(".irqentry.text")))
__attribute__((__section__(".softirqentry.text"))) #endif
#define __softirq_entry __attribute__((__section__(".softirqentry.text")))
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment