From: tip-bot for Andy Lutomirski <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: hpa@zytor.com, efault@gmx.de, peterz@infradead.org,
mingo@kernel.org, brgerst@gmail.com, bp@alien8.de,
tglx@linutronix.de, linux-kernel@vger.kernel.org,
luto@kernel.org, jpoimboe@redhat.com,
torvalds@linux-foundation.org, jslaby@suse.cz,
dvlasenk@redhat.com
Subject: [tip:x86/asm] x86/entry/64: Refactor IRQ stacks and make them NMI-safe
Date: Tue, 18 Jul 2017 03:40:58 -0700 [thread overview]
Message-ID: <tip-1d3e53e8624a3ec85f4041ca6d973da7c1575938@git.kernel.org> (raw)
In-Reply-To: <b0b2ff5fb97d2da2e1d7e1f380190c92545c8bb5.1499786555.git.jpoimboe@redhat.com>
Commit-ID: 1d3e53e8624a3ec85f4041ca6d973da7c1575938
Gitweb: http://git.kernel.org/tip/1d3e53e8624a3ec85f4041ca6d973da7c1575938
Author: Andy Lutomirski <luto@kernel.org>
AuthorDate: Tue, 11 Jul 2017 10:33:38 -0500
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Tue, 18 Jul 2017 10:56:22 +0200
x86/entry/64: Refactor IRQ stacks and make them NMI-safe
This will allow IRQ stacks to nest inside NMIs or similar entries
that can happen during IRQ stack setup or teardown.
The new macros won't work correctly if they're invoked with IRQs on.
Add a check under CONFIG_DEBUG_ENTRY to detect that.
Signed-off-by: Andy Lutomirski <luto@kernel.org>
[ Use %r10 instead of %r11 in xen_do_hypervisor_callback to make objtool
and ORC unwinder's lives a little easier. ]
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Jiri Slaby <jslaby@suse.cz>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: live-patching@vger.kernel.org
Link: http://lkml.kernel.org/r/b0b2ff5fb97d2da2e1d7e1f380190c92545c8bb5.1499786555.git.jpoimboe@redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/Kconfig.debug | 2 --
arch/x86/entry/entry_64.S | 85 +++++++++++++++++++++++++++++++-------------
arch/x86/kernel/process_64.c | 3 ++
3 files changed, 64 insertions(+), 26 deletions(-)
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug
index fcb7604..353ed09 100644
--- a/arch/x86/Kconfig.debug
+++ b/arch/x86/Kconfig.debug
@@ -305,8 +305,6 @@ config DEBUG_ENTRY
Some of these sanity checks may slow down kernel entries and
exits or otherwise impact performance.
- This is currently used to help test NMI code.
-
If unsure, say N.
config DEBUG_NMI_SELFTEST
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index a9a8027..0d4483a 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -447,6 +447,59 @@ ENTRY(irq_entries_start)
.endr
END(irq_entries_start)
+.macro DEBUG_ENTRY_ASSERT_IRQS_OFF
+#ifdef CONFIG_DEBUG_ENTRY
+ pushfq
+ testl $X86_EFLAGS_IF, (%rsp)
+ jz .Lokay_\@
+ ud2
+.Lokay_\@:
+ addq $8, %rsp
+#endif
+.endm
+
+/*
+ * Enters the IRQ stack if we're not already using it. NMI-safe. Clobbers
+ * flags and puts old RSP into old_rsp, and leaves all other GPRs alone.
+ * Requires kernel GSBASE.
+ *
+ * The invariant is that, if irq_count != -1, then the IRQ stack is in use.
+ */
+.macro ENTER_IRQ_STACK old_rsp
+ DEBUG_ENTRY_ASSERT_IRQS_OFF
+ movq %rsp, \old_rsp
+ incl PER_CPU_VAR(irq_count)
+
+ /*
+ * Right now, if we just incremented irq_count to zero, we've
+ * claimed the IRQ stack but we haven't switched to it yet.
+ *
+ * If anything is added that can interrupt us here without using IST,
+ * it must be *extremely* careful to limit its stack usage. This
+ * could include kprobes and a hypothetical future IST-less #DB
+ * handler.
+ */
+
+ cmovzq PER_CPU_VAR(irq_stack_ptr), %rsp
+ pushq \old_rsp
+.endm
+
+/*
+ * Undoes ENTER_IRQ_STACK.
+ */
+.macro LEAVE_IRQ_STACK
+ DEBUG_ENTRY_ASSERT_IRQS_OFF
+ /* We need to be off the IRQ stack before decrementing irq_count. */
+ popq %rsp
+
+ /*
+ * As in ENTER_IRQ_STACK, irq_count == 0, we are still claiming
+ * the irq stack but we're not on it.
+ */
+
+ decl PER_CPU_VAR(irq_count)
+.endm
+
/*
* Interrupt entry/exit.
*
@@ -485,17 +538,7 @@ END(irq_entries_start)
CALL_enter_from_user_mode
1:
- /*
- * Save previous stack pointer, optionally switch to interrupt stack.
- * irq_count is used to check if a CPU is already on an interrupt stack
- * or not. While this is essentially redundant with preempt_count it is
- * a little cheaper to use a separate counter in the PDA (short of
- * moving irq_enter into assembly, which would be too much work)
- */
- movq %rsp, %rdi
- incl PER_CPU_VAR(irq_count)
- cmovzq PER_CPU_VAR(irq_stack_ptr), %rsp
- pushq %rdi
+ ENTER_IRQ_STACK old_rsp=%rdi
/* We entered an interrupt context - irqs are off: */
TRACE_IRQS_OFF
@@ -515,10 +558,8 @@ common_interrupt:
ret_from_intr:
DISABLE_INTERRUPTS(CLBR_ANY)
TRACE_IRQS_OFF
- decl PER_CPU_VAR(irq_count)
- /* Restore saved previous stack */
- popq %rsp
+ LEAVE_IRQ_STACK
testb $3, CS(%rsp)
jz retint_kernel
@@ -891,12 +932,10 @@ bad_gs:
ENTRY(do_softirq_own_stack)
pushq %rbp
mov %rsp, %rbp
- incl PER_CPU_VAR(irq_count)
- cmove PER_CPU_VAR(irq_stack_ptr), %rsp
- push %rbp /* frame pointer backlink */
+ ENTER_IRQ_STACK old_rsp=%r11
call __do_softirq
+ LEAVE_IRQ_STACK
leaveq
- decl PER_CPU_VAR(irq_count)
ret
END(do_softirq_own_stack)
@@ -923,13 +962,11 @@ ENTRY(xen_do_hypervisor_callback) /* do_hypervisor_callback(struct *pt_regs) */
* see the correct pointer to the pt_regs
*/
movq %rdi, %rsp /* we don't return, adjust the stack frame */
-11: incl PER_CPU_VAR(irq_count)
- movq %rsp, %rbp
- cmovzq PER_CPU_VAR(irq_stack_ptr), %rsp
- pushq %rbp /* frame pointer backlink */
+
+ ENTER_IRQ_STACK old_rsp=%r10
call xen_evtchn_do_upcall
- popq %rsp
- decl PER_CPU_VAR(irq_count)
+ LEAVE_IRQ_STACK
+
#ifndef CONFIG_PREEMPT
call xen_maybe_preempt_hcall
#endif
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index c3169be..2987e39 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -279,6 +279,9 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
struct tss_struct *tss = &per_cpu(cpu_tss, cpu);
unsigned prev_fsindex, prev_gsindex;
+ WARN_ON_ONCE(IS_ENABLED(CONFIG_DEBUG_ENTRY) &&
+ this_cpu_read(irq_count) != -1);
+
switch_fpu_prepare(prev_fpu, cpu);
/* We must save %fs and %gs before load_TLS() because
next prev parent reply other threads:[~2017-07-18 10:46 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-07-11 15:33 [PATCH v3 00/10] x86: ORC unwinder (previously undwarf) Josh Poimboeuf
2017-07-11 15:33 ` [PATCH v3 01/10] x86/entry/64: Refactor IRQ stacks and make them NMI-safe Josh Poimboeuf
2017-07-18 10:40 ` tip-bot for Andy Lutomirski [this message]
2017-07-11 15:33 ` [PATCH v3 02/10] x86/entry/64: Initialize the top of the IRQ stack before switching stacks Josh Poimboeuf
2017-07-18 10:41 ` [tip:x86/asm] " tip-bot for Andy Lutomirski
2017-07-11 15:33 ` [PATCH v3 03/10] x86/dumpstack: fix occasionally missing registers Josh Poimboeuf
2017-07-18 10:41 ` [tip:x86/asm] x86/dumpstack: Fix " tip-bot for Josh Poimboeuf
2017-07-11 15:33 ` [PATCH v3 04/10] x86/dumpstack: fix interrupt and exception stack boundary checks Josh Poimboeuf
2017-07-18 10:42 ` [tip:x86/asm] x86/dumpstack: Fix " tip-bot for Josh Poimboeuf
2017-07-11 15:33 ` [PATCH v3 05/10] objtool: add ORC unwind table generation Josh Poimboeuf
2017-07-18 10:42 ` [tip:x86/asm] objtool: Add " tip-bot for Josh Poimboeuf
2017-07-11 15:33 ` [PATCH v3 06/10] objtool, x86: add facility for asm code to provide unwind hints Josh Poimboeuf
2017-07-18 10:43 ` [tip:x86/asm] objtool, x86: Add " tip-bot for Josh Poimboeuf
2017-07-11 15:33 ` [PATCH v3 07/10] x86/entry/64: add unwind hint annotations Josh Poimboeuf
2017-07-18 10:43 ` [tip:x86/asm] x86/entry/64: Add " tip-bot for Josh Poimboeuf
2017-07-11 15:33 ` [PATCH v3 08/10] x86/asm: add unwind hint annotations to sync_core() Josh Poimboeuf
2017-07-18 10:43 ` [tip:x86/asm] x86/asm: Add " tip-bot for Josh Poimboeuf
2017-07-11 15:33 ` [PATCH v3 09/10] x86/unwind: add ORC unwinder Josh Poimboeuf
2017-07-14 17:22 ` [PATCH v3.1 " Josh Poimboeuf
2017-07-20 7:12 ` Jiri Slaby
2017-07-20 21:16 ` Josh Poimboeuf
2017-07-11 15:33 ` [PATCH v3 10/10] x86/kconfig: make it easier to switch to the new " Josh Poimboeuf
2017-07-12 8:27 ` [PATCH v3 00/10] x86: ORC unwinder (previously undwarf) Ingo Molnar
2017-07-12 14:42 ` Josh Poimboeuf
2017-07-12 19:27 ` Ingo Molnar
2017-07-14 17:17 ` Josh Poimboeuf
2017-07-25 9:09 ` Ingo Molnar
2017-07-25 17:58 ` Josh Poimboeuf
2017-07-25 18:46 ` Kees Cook
2017-07-12 21:49 ` Andres Freund
2017-07-12 22:32 ` Josh Poimboeuf
2017-07-12 22:36 ` Andres Freund
2017-07-12 22:40 ` Josh Poimboeuf
2017-07-12 22:54 ` Andres Freund
2017-07-13 7:12 ` Peter Zijlstra
2017-07-13 8:50 ` Peter Zijlstra
2017-07-13 8:51 ` Peter Zijlstra
2017-07-13 9:19 ` Ingo Molnar
2017-07-13 12:17 ` Josh Poimboeuf
2017-07-13 12:21 ` Josh Poimboeuf
2017-07-13 12:35 ` Josh Poimboeuf
2017-07-14 8:33 ` Ingo Molnar
2017-07-14 8:29 ` Ingo Molnar
2017-07-25 11:55 ` [RFC] perf: Delayed userspace unwind (Was: [PATCH v3 00/10] x86: ORC unwinder) Peter Zijlstra
2017-07-28 14:13 ` Jiri Olsa
2017-07-28 14:21 ` Peter Zijlstra
2017-07-29 3:35 ` Andy Lutomirski
2017-07-29 9:28 ` Peter Zijlstra
2017-07-12 22:30 ` [PATCH v3 00/10] x86: ORC unwinder (previously undwarf) Andi Kleen
2017-07-12 22:47 ` Josh Poimboeuf
2017-07-13 4:29 ` Andi Kleen
2017-07-13 13:15 ` Josh Poimboeuf
2017-07-13 9:29 ` Ingo Molnar
2017-07-12 23:22 ` Andy Lutomirski
2017-07-13 3:03 ` Mike Galbraith
2017-07-13 4:15 ` Andi Kleen
2017-07-13 4:28 ` Mike Galbraith
2017-07-13 4:40 ` Andi Kleen
2017-07-13 5:22 ` Mike Galbraith
2017-07-13 12:02 ` Jiri Kosina
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=tip-1d3e53e8624a3ec85f4041ca6d973da7c1575938@git.kernel.org \
--to=tipbot@zytor.com \
--cc=bp@alien8.de \
--cc=brgerst@gmail.com \
--cc=dvlasenk@redhat.com \
--cc=efault@gmx.de \
--cc=hpa@zytor.com \
--cc=jpoimboe@redhat.com \
--cc=jslaby@suse.cz \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mingo@kernel.org \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome