Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/exceptions: Disconnect IST index and stack order

The entry order of the TSS.IST array and the order of the stack
storage/mapping are not required to be the same.

With the upcoming split of the debug stack this is going to fall apart as
the number of TSS.IST array entries stays the same while the actual stacks
are increasing.

Make them separate so that code like dumpstack can just utilize the mapping
order. The IST index is solely required for the actual TSS.IST array
initialization.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Baoquan He <bhe@redhat.com>
Cc: "Chang S. Bae" <chang.seok.bae@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: Jann Horn <jannh@google.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Nicolai Stange <nstange@suse.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Qian Cai <cai@lca.pw>
Cc: Sean Christopherson <sean.j.christopherson@intel.com>
Cc: x86-ml <x86@kernel.org>
Link: https://lkml.kernel.org/r/20190414160145.241588113@linutronix.de

authored by

Thomas Gleixner and committed by
Borislav Petkov
32074269 4d68c3d0

+27 -15
+1 -1
arch/x86/entry/entry_64.S
··· 1129 1129 hv_stimer0_callback_vector hv_stimer0_vector_handler 1130 1130 #endif /* CONFIG_HYPERV */ 1131 1131 1132 - idtentry debug do_debug has_error_code=0 paranoid=1 shift_ist=ESTACK_DB 1132 + idtentry debug do_debug has_error_code=0 paranoid=1 shift_ist=IST_INDEX_DB 1133 1133 idtentry int3 do_int3 has_error_code=0 1134 1134 idtentry stack_segment do_stack_segment has_error_code=1 1135 1135
+11
arch/x86/include/asm/cpu_entry_area.h
··· 35 35 ESTACKS_MEMBERS(0) 36 36 }; 37 37 38 + /* 39 + * The exception stack ordering in [cea_]exception_stacks 40 + */ 41 + enum exception_stack_ordering { 42 + ESTACK_DF, 43 + ESTACK_NMI, 44 + ESTACK_DB, 45 + ESTACK_MCE, 46 + N_EXCEPTION_STACKS 47 + }; 48 + 38 49 #define CEA_ESTACK_SIZE(st) \ 39 50 sizeof(((struct cea_exception_stacks *)0)->st## _stack) 40 51
+4 -5
arch/x86/include/asm/page_64_types.h
··· 27 27 /* 28 28 * The index for the tss.ist[] array. The hardware limit is 7 entries. 29 29 */ 30 - #define ESTACK_DF 0 31 - #define ESTACK_NMI 1 32 - #define ESTACK_DB 2 33 - #define ESTACK_MCE 3 34 - #define N_EXCEPTION_STACKS 4 30 + #define IST_INDEX_DF 0 31 + #define IST_INDEX_NMI 1 32 + #define IST_INDEX_DB 2 33 + #define IST_INDEX_MCE 3 35 34 36 35 /* 37 36 * Set __PAGE_OFFSET to the most negative possible address +
+2
arch/x86/include/asm/stacktrace.h
··· 9 9 10 10 #include <linux/uaccess.h> 11 11 #include <linux/ptrace.h> 12 + 13 + #include <asm/cpu_entry_area.h> 12 14 #include <asm/switch_to.h> 13 15 14 16 enum stack_type {
+5 -5
arch/x86/kernel/cpu/common.c
··· 1731 1731 * set up and load the per-CPU TSS 1732 1732 */ 1733 1733 if (!t->x86_tss.ist[0]) { 1734 - t->x86_tss.ist[ESTACK_DF] = __this_cpu_ist_top_va(DF); 1735 - t->x86_tss.ist[ESTACK_NMI] = __this_cpu_ist_top_va(NMI); 1736 - t->x86_tss.ist[ESTACK_DB] = __this_cpu_ist_top_va(DB); 1737 - t->x86_tss.ist[ESTACK_MCE] = __this_cpu_ist_top_va(MCE); 1738 - per_cpu(debug_stack_addr, cpu) = t->x86_tss.ist[ESTACK_DB]; 1734 + t->x86_tss.ist[IST_INDEX_DF] = __this_cpu_ist_top_va(DF); 1735 + t->x86_tss.ist[IST_INDEX_NMI] = __this_cpu_ist_top_va(NMI); 1736 + t->x86_tss.ist[IST_INDEX_DB] = __this_cpu_ist_top_va(DB); 1737 + t->x86_tss.ist[IST_INDEX_MCE] = __this_cpu_ist_top_va(MCE); 1738 + per_cpu(debug_stack_addr, cpu) = t->x86_tss.ist[IST_INDEX_DB]; 1739 1739 } 1740 1740 1741 1741 t->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET;
+4 -4
arch/x86/kernel/idt.c
··· 183 183 * cpu_init() when the TSS has been initialized. 184 184 */ 185 185 static const __initconst struct idt_data ist_idts[] = { 186 - ISTG(X86_TRAP_DB, debug, ESTACK_DB), 187 - ISTG(X86_TRAP_NMI, nmi, ESTACK_NMI), 188 - ISTG(X86_TRAP_DF, double_fault, ESTACK_DF), 186 + ISTG(X86_TRAP_DB, debug, IST_INDEX_DB), 187 + ISTG(X86_TRAP_NMI, nmi, IST_INDEX_NMI), 188 + ISTG(X86_TRAP_DF, double_fault, IST_INDEX_DF), 189 189 #ifdef CONFIG_X86_MCE 190 - ISTG(X86_TRAP_MC, &machine_check, ESTACK_MCE), 190 + ISTG(X86_TRAP_MC, &machine_check, IST_INDEX_MCE), 191 191 #endif 192 192 }; 193 193