Commit 8f34c5b5 authored by Thomas Gleixner's avatar Thomas Gleixner Committed by Borislav Petkov

x86/exceptions: Make IST index zero based

The defines for the exception stack (IST) array in the TSS are using the
SDM convention IST1 - IST7. That causes all sorts of code to subtract 1 for
array indices related to IST. That's confusing at best and does not provide
any value.

Make the indices zero based and fixup the usage sites. The only code which
needs to adjust the 0 based index is the interrupt descriptor setup which
needs to add 1 now.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Signed-off-by: default avatarBorislav Petkov <bp@suse.de>
Reviewed-by: default avatarSean Christopherson <sean.j.christopherson@intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Baoquan He <bhe@redhat.com>
Cc: "Chang S. Bae" <chang.seok.bae@intel.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Dou Liyang <douly.fnst@cn.fujitsu.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: linux-doc@vger.kernel.org
Cc: Nicolai Stange <nstange@suse.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Qian Cai <cai@lca.pw>
Cc: x86-ml <x86@kernel.org>
Link: https://lkml.kernel.org/r/20190414160144.331772825@linutronix.de
parent 30842211
...@@ -59,7 +59,7 @@ If that assumption is ever broken then the stacks will become corrupt. ...@@ -59,7 +59,7 @@ If that assumption is ever broken then the stacks will become corrupt.
The currently assigned IST stacks are :- The currently assigned IST stacks are :-
* DOUBLEFAULT_STACK. EXCEPTION_STKSZ (PAGE_SIZE). * ESTACK_DF. EXCEPTION_STKSZ (PAGE_SIZE).
Used for interrupt 8 - Double Fault Exception (#DF). Used for interrupt 8 - Double Fault Exception (#DF).
...@@ -68,7 +68,7 @@ The currently assigned IST stacks are :- ...@@ -68,7 +68,7 @@ The currently assigned IST stacks are :-
Using a separate stack allows the kernel to recover from it well enough Using a separate stack allows the kernel to recover from it well enough
in many cases to still output an oops. in many cases to still output an oops.
* NMI_STACK. EXCEPTION_STKSZ (PAGE_SIZE). * ESTACK_NMI. EXCEPTION_STKSZ (PAGE_SIZE).
Used for non-maskable interrupts (NMI). Used for non-maskable interrupts (NMI).
...@@ -76,7 +76,7 @@ The currently assigned IST stacks are :- ...@@ -76,7 +76,7 @@ The currently assigned IST stacks are :-
middle of switching stacks. Using IST for NMI events avoids making middle of switching stacks. Using IST for NMI events avoids making
assumptions about the previous state of the kernel stack. assumptions about the previous state of the kernel stack.
* DEBUG_STACK. DEBUG_STKSZ * ESTACK_DB. DEBUG_STKSZ
Used for hardware debug interrupts (interrupt 1) and for software Used for hardware debug interrupts (interrupt 1) and for software
debug interrupts (INT3). debug interrupts (INT3).
...@@ -86,7 +86,7 @@ The currently assigned IST stacks are :- ...@@ -86,7 +86,7 @@ The currently assigned IST stacks are :-
avoids making assumptions about the previous state of the kernel avoids making assumptions about the previous state of the kernel
stack. stack.
* MCE_STACK. EXCEPTION_STKSZ (PAGE_SIZE). * ESTACK_MCE. EXCEPTION_STKSZ (PAGE_SIZE).
Used for interrupt 18 - Machine Check Exception (#MC). Used for interrupt 18 - Machine Check Exception (#MC).
......
...@@ -841,7 +841,7 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt ...@@ -841,7 +841,7 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt
/* /*
* Exception entry points. * Exception entry points.
*/ */
#define CPU_TSS_IST(x) PER_CPU_VAR(cpu_tss_rw) + (TSS_ist + ((x) - 1) * 8) #define CPU_TSS_IST(x) PER_CPU_VAR(cpu_tss_rw) + (TSS_ist + (x) * 8)
/** /**
* idtentry - Generate an IDT entry stub * idtentry - Generate an IDT entry stub
...@@ -1129,7 +1129,7 @@ apicinterrupt3 HYPERV_STIMER0_VECTOR \ ...@@ -1129,7 +1129,7 @@ apicinterrupt3 HYPERV_STIMER0_VECTOR \
hv_stimer0_callback_vector hv_stimer0_vector_handler hv_stimer0_callback_vector hv_stimer0_vector_handler
#endif /* CONFIG_HYPERV */ #endif /* CONFIG_HYPERV */
idtentry debug do_debug has_error_code=0 paranoid=1 shift_ist=DEBUG_STACK idtentry debug do_debug has_error_code=0 paranoid=1 shift_ist=ESTACK_DB
idtentry int3 do_int3 has_error_code=0 idtentry int3 do_int3 has_error_code=0
idtentry stack_segment do_stack_segment has_error_code=1 idtentry stack_segment do_stack_segment has_error_code=1
......
...@@ -24,11 +24,14 @@ ...@@ -24,11 +24,14 @@
#define IRQ_STACK_ORDER (2 + KASAN_STACK_ORDER) #define IRQ_STACK_ORDER (2 + KASAN_STACK_ORDER)
#define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER) #define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER)
#define DOUBLEFAULT_STACK 1 /*
#define NMI_STACK 2 * The index for the tss.ist[] array. The hardware limit is 7 entries.
#define DEBUG_STACK 3 */
#define MCE_STACK 4 #define ESTACK_DF 0
#define N_EXCEPTION_STACKS 4 /* hw limit: 7 */ #define ESTACK_NMI 1
#define ESTACK_DB 2
#define ESTACK_MCE 3
#define N_EXCEPTION_STACKS 4
/* /*
* Set __PAGE_OFFSET to the most negative possible address + * Set __PAGE_OFFSET to the most negative possible address +
......
...@@ -516,7 +516,7 @@ DEFINE_PER_CPU(struct cpu_entry_area *, cpu_entry_area); ...@@ -516,7 +516,7 @@ DEFINE_PER_CPU(struct cpu_entry_area *, cpu_entry_area);
*/ */
static const unsigned int exception_stack_sizes[N_EXCEPTION_STACKS] = { static const unsigned int exception_stack_sizes[N_EXCEPTION_STACKS] = {
[0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ, [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ,
[DEBUG_STACK - 1] = DEBUG_STKSZ [ESTACK_DB] = DEBUG_STKSZ
}; };
#endif #endif
...@@ -1760,7 +1760,7 @@ void cpu_init(void) ...@@ -1760,7 +1760,7 @@ void cpu_init(void)
estacks += exception_stack_sizes[v]; estacks += exception_stack_sizes[v];
oist->ist[v] = t->x86_tss.ist[v] = oist->ist[v] = t->x86_tss.ist[v] =
(unsigned long)estacks; (unsigned long)estacks;
if (v == DEBUG_STACK-1) if (v == ESTACK_DB)
per_cpu(debug_stack_addr, cpu) = (unsigned long)estacks; per_cpu(debug_stack_addr, cpu) = (unsigned long)estacks;
} }
} }
......
...@@ -18,16 +18,16 @@ ...@@ -18,16 +18,16 @@
#include <asm/stacktrace.h> #include <asm/stacktrace.h>
static char *exception_stack_names[N_EXCEPTION_STACKS] = { static const char *exception_stack_names[N_EXCEPTION_STACKS] = {
[ DOUBLEFAULT_STACK-1 ] = "#DF", [ ESTACK_DF ] = "#DF",
[ NMI_STACK-1 ] = "NMI", [ ESTACK_NMI ] = "NMI",
[ DEBUG_STACK-1 ] = "#DB", [ ESTACK_DB ] = "#DB",
[ MCE_STACK-1 ] = "#MC", [ ESTACK_MCE ] = "#MC",
}; };
static unsigned long exception_stack_sizes[N_EXCEPTION_STACKS] = { static const unsigned long exception_stack_sizes[N_EXCEPTION_STACKS] = {
[0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ, [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ,
[DEBUG_STACK - 1] = DEBUG_STKSZ [ESTACK_DB] = DEBUG_STKSZ
}; };
const char *stack_type_name(enum stack_type type) const char *stack_type_name(enum stack_type type)
......
...@@ -41,9 +41,12 @@ struct idt_data { ...@@ -41,9 +41,12 @@ struct idt_data {
#define SYSG(_vector, _addr) \ #define SYSG(_vector, _addr) \
G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL3, __KERNEL_CS) G(_vector, _addr, DEFAULT_STACK, GATE_INTERRUPT, DPL3, __KERNEL_CS)
/* Interrupt gate with interrupt stack */ /*
* Interrupt gate with interrupt stack. The _ist index is the index in
* the tss.ist[] array, but for the descriptor it needs to start at 1.
*/
#define ISTG(_vector, _addr, _ist) \ #define ISTG(_vector, _addr, _ist) \
G(_vector, _addr, _ist, GATE_INTERRUPT, DPL0, __KERNEL_CS) G(_vector, _addr, _ist + 1, GATE_INTERRUPT, DPL0, __KERNEL_CS)
/* Task gate */ /* Task gate */
#define TSKG(_vector, _gdt) \ #define TSKG(_vector, _gdt) \
...@@ -180,11 +183,11 @@ gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss; ...@@ -180,11 +183,11 @@ gate_desc debug_idt_table[IDT_ENTRIES] __page_aligned_bss;
* cpu_init() when the TSS has been initialized. * cpu_init() when the TSS has been initialized.
*/ */
static const __initconst struct idt_data ist_idts[] = { static const __initconst struct idt_data ist_idts[] = {
ISTG(X86_TRAP_DB, debug, DEBUG_STACK), ISTG(X86_TRAP_DB, debug, ESTACK_DB),
ISTG(X86_TRAP_NMI, nmi, NMI_STACK), ISTG(X86_TRAP_NMI, nmi, ESTACK_NMI),
ISTG(X86_TRAP_DF, double_fault, DOUBLEFAULT_STACK), ISTG(X86_TRAP_DF, double_fault, ESTACK_DF),
#ifdef CONFIG_X86_MCE #ifdef CONFIG_X86_MCE
ISTG(X86_TRAP_MC, &machine_check, MCE_STACK), ISTG(X86_TRAP_MC, &machine_check, ESTACK_MCE),
#endif #endif
}; };
......
...@@ -61,7 +61,7 @@ static inline void stack_overflow_check(struct pt_regs *regs) ...@@ -61,7 +61,7 @@ static inline void stack_overflow_check(struct pt_regs *regs)
return; return;
oist = this_cpu_ptr(&orig_ist); oist = this_cpu_ptr(&orig_ist);
estack_top = (u64)oist->ist[DEBUG_STACK]; estack_top = (u64)oist->ist[ESTACK_DB];
estack_bottom = estack_top - DEBUG_STKSZ + STACK_MARGIN; estack_bottom = estack_top - DEBUG_STKSZ + STACK_MARGIN;
if (regs->sp >= estack_bottom && regs->sp <= estack_top) if (regs->sp >= estack_bottom && regs->sp <= estack_top)
return; return;
......
...@@ -793,7 +793,7 @@ no_context(struct pt_regs *regs, unsigned long error_code, ...@@ -793,7 +793,7 @@ no_context(struct pt_regs *regs, unsigned long error_code,
if (is_vmalloc_addr((void *)address) && if (is_vmalloc_addr((void *)address) &&
(((unsigned long)tsk->stack - 1 - address < PAGE_SIZE) || (((unsigned long)tsk->stack - 1 - address < PAGE_SIZE) ||
address - ((unsigned long)tsk->stack + THREAD_SIZE) < PAGE_SIZE)) { address - ((unsigned long)tsk->stack + THREAD_SIZE) < PAGE_SIZE)) {
unsigned long stack = this_cpu_read(orig_ist.ist[DOUBLEFAULT_STACK]) - sizeof(void *); unsigned long stack = this_cpu_read(orig_ist.ist[ESTACK_DF]) - sizeof(void *);
/* /*
* We're likely to be running with very little stack space * We're likely to be running with very little stack space
* left. It's plausible that we'd hit this condition but * left. It's plausible that we'd hit this condition but
......
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