aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@kernel.org>2018-09-03 18:59:42 -0400
committerThomas Gleixner <tglx@linutronix.de>2018-09-08 05:20:11 -0400
commitbd7b1f7cbf9cb35dab8e1b99145d07afc5b7a132 (patch)
tree684b0f84d64a49498a6b0f01d3771f0c4117833a
parentdb44bf4b4768a0664d3c9d9000ecb747de31ded8 (diff)
x86/entry/64: Document idtentry
The idtentry macro is complicated and magical. Document what it does to help future readers and to allow future patches to adjust the code and docs at the same time. Signed-off-by: Andy Lutomirski <luto@kernel.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Borislav Petkov <bp@suse.de> Cc: Borislav Petkov <bp@alien8.de> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Arnaldo Carvalho de Melo <acme@kernel.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Joerg Roedel <joro@8bytes.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Peter Zijlstra <peterz@infradead.org> Link: https://lkml.kernel.org/r/6e56c3ad94879e41afe345750bc28ccc0e820ea8.1536015544.git.luto@kernel.org
-rw-r--r--arch/x86/entry/entry_64.S36
-rw-r--r--arch/x86/kernel/traps.c4
2 files changed, 40 insertions, 0 deletions
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 957dfb693ecc..ce6af4460e9c 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -900,6 +900,42 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt
900 */ 900 */
901#define CPU_TSS_IST(x) PER_CPU_VAR(cpu_tss_rw) + (TSS_ist + ((x) - 1) * 8) 901#define CPU_TSS_IST(x) PER_CPU_VAR(cpu_tss_rw) + (TSS_ist + ((x) - 1) * 8)
902 902
903/**
904 * idtentry - Generate an IDT entry stub
905 * @sym: Name of the generated entry point
906 * @do_sym: C function to be called
907 * @has_error_code: True if this IDT vector has an error code on the stack
908 * @paranoid: non-zero means that this vector may be invoked from
909 * kernel mode with user GSBASE and/or user CR3.
910 * 2 is special -- see below.
911 * @shift_ist: Set to an IST index if entries from kernel mode should
912 * decrement the IST stack so that nested entries get a
913 * fresh stack. (This is for #DB, which has a nasty habit
914 * of recursing.)
915 *
916 * idtentry generates an IDT stub that sets up a usable kernel context,
917 * creates struct pt_regs, and calls @do_sym. The stub has the following
918 * special behaviors:
919 *
920 * On an entry from user mode, the stub switches from the trampoline or
921 * IST stack to the normal thread stack. On an exit to user mode, the
922 * normal exit-to-usermode path is invoked.
923 *
924 * On an exit to kernel mode, if @paranoid == 0, we check for preemption,
925 * whereas we omit the preemption check if @paranoid != 0. This is purely
926 * because the implementation is simpler this way. The kernel only needs
927 * to check for asynchronous kernel preemption when IRQ handlers return.
928 *
929 * If @paranoid == 0, then the stub will handle IRET faults by pretending
930 * that the fault came from user mode. It will handle gs_change faults by
931 * pretending that the fault happened with kernel GSBASE. Since this handling
932 * is omitted for @paranoid != 0, the #GP, #SS, and #NP stubs must have
933 * @paranoid == 0. This special handling will do the wrong thing for
934 * espfix-induced #DF on IRET, so #DF must not use @paranoid == 0.
935 *
936 * @paranoid == 2 is special: the stub will never switch stacks. This is for
937 * #DF: if the thread stack is somehow unusable, we'll still get a useful OOPS.
938 */
903.macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1 939.macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1
904ENTRY(\sym) 940ENTRY(\sym)
905 UNWIND_HINT_IRET_REGS offset=\has_error_code*8 941 UNWIND_HINT_IRET_REGS offset=\has_error_code*8
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index e6db475164ed..1a90821c0b74 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -383,6 +383,10 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
383 * we won't enable interupts or schedule before we invoke 383 * we won't enable interupts or schedule before we invoke
384 * general_protection, so nothing will clobber the stack 384 * general_protection, so nothing will clobber the stack
385 * frame we just set up. 385 * frame we just set up.
386 *
387 * We will enter general_protection with kernel GSBASE,
388 * which is what the stub expects, given that the faulting
389 * RIP will be the IRET instruction.
386 */ 390 */
387 regs->ip = (unsigned long)general_protection; 391 regs->ip = (unsigned long)general_protection;
388 regs->sp = (unsigned long)&gpregs->orig_ax; 392 regs->sp = (unsigned long)&gpregs->orig_ax;