From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Thomas Gleixner <tglx@linutronix.de>
Cc: LKML <linux-kernel@vger.kernel.org>,
x86@kernel.org, Andy Lutomirski <luto@kernel.org>,
Josh Poimboeuf <jpoimboe@redhat.com>
Subject: Re: [patch V2 19/29] x86/exceptions: Split debug IST stack
Date: Fri, 5 Apr 2019 13:55:49 -0700 [thread overview]
Message-ID: <20190405205549.GE15808@linux.intel.com> (raw)
In-Reply-To: <20190405150930.129884669@linutronix.de>
On Fri, Apr 05, 2019 at 05:07:17PM +0200, Thomas Gleixner wrote:
> The debug IST stack is actually two separate debug stacks to handle #DB
> recursion. This is required because the CPU starts always at top of stack
> on exception entry, which means on #DB recursion the second #DB would
> overwrite the stack of the first.
>
> The low level entry code therefore adjusts the top of stack on entry so a
> secondary #DB starts from a different stack page. But the stack pages are
> adjacent without a guard page between them.
>
> Split the debug stack into 3 stacks which are separated by guard pages. The
> 3rd stack is never mapped into the cpu_entry_area and is only there to
> catch triple #DB nesting:
>
> --- top of DB_stack <- Initial stack
> --- end of DB_stack
> guard page
>
> --- top of DB1_stack <- Top of stack after entering first #DB
> --- end of DB1_stack
> guard page
>
> --- top of DB2_stack <- Top of stack after entering second #DB
> --- end of DB2_stack
> guard page
>
> If DB2 would not act as the final guard hole, a second #DB would point the
> top of #DB stack to the stack below #DB1 which would be valid and not catch
> the not so desired triple nesting.
>
> The backing store does not allocate any memory for DB2 and its guard page
> as it is not going to be mapped into the cpu_entry_area.
>
> - Adjust the low level entry code so it adjusts top of #DB with the offset
> between the stacks instead of exception stack size.
>
> - Make the dumpstack code aware of the new stacks.
>
> - Adjust the in_debug_stack() implementation and move it into the NMI code
> where it belongs. As this is NMI hotpath code, it just checks the full
> area between top of DB_stack and bottom of DB1_stack without checking
> for the guard page. That's correct because the NMI cannot hit a
> stackpointer pointing to the guard page between DB and DB1 stack. Even
> if it would, then the NMI operation still is unaffected, but the resume
> of the debug exception on the topmost DB stack will crash by touching
> the guard page.
>
> Suggested-by: Andy Lutomirski <luto@kernel.org>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
...
> +static bool notrace is_debug_stack(unsigned long addr)
> +{
> + struct cea_exception_stacks *cs = __this_cpu_read(cea_exception_stacks);
> + unsigned long top = CEA_ESTACK_TOP(cs, DB);
> + unsigned long bot = CEA_ESTACK_BOT(cs, DB1);
> +
> + if (__this_cpu_read(debug_stack_usage))
> + return true;
> + /*
> + * Note, this covers the guard page between DB and DB1 as well to
> + * avoid two checks. But by all means @addr can never point into
> + * the guard page.
> + */
> + return addr > bot && addr < top;
Isn't this an off by one error? I.e. "return addr >= bot && addr < top".
%rsp == bot is technically still in the DB1 stack even though the next
PUSH/CALL will explode on the guard page.
> +}
> +NOKPROBE_SYMBOL(is_debug_stack);
> #endif
>
> dotraplinkage notrace void
> --- a/arch/x86/mm/cpu_entry_area.c
> +++ b/arch/x86/mm/cpu_entry_area.c
> @@ -98,10 +98,12 @@ static void __init percpu_setup_exceptio
>
> /*
> * The exceptions stack mappings in the per cpu area are protected
> - * by guard pages so each stack must be mapped separately.
> + * by guard pages so each stack must be mapped separately. DB2 is
> + * not mapped; it just exists to catch triple nesting of #DB.
> */
> cea_map_stack(DF);
> cea_map_stack(NMI);
> + cea_map_stack(DB1);
> cea_map_stack(DB);
> cea_map_stack(MCE);
> }
>
>
next prev parent reply other threads:[~2019-04-05 20:55 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-05 15:06 [patch V2 00/29] x86: Add guard pages to exception and interrupt stacks Thomas Gleixner
2019-04-05 15:06 ` [patch V2 01/29] x86/irq/64: Limit IST stack overflow check to #DB stack Thomas Gleixner
2019-04-05 15:07 ` [patch V2 02/29] x86/dumpstack: Fix off-by-one errors in stack identification Thomas Gleixner
2019-04-05 15:44 ` Sean Christopherson
2019-04-05 15:07 ` [patch V2 03/29] x86/irq/64: Remove a hardcoded irq_stack_union access Thomas Gleixner
2019-04-05 16:37 ` Sean Christopherson
2019-04-05 16:38 ` Sean Christopherson
2019-04-05 17:18 ` Josh Poimboeuf
2019-04-05 17:47 ` Thomas Gleixner
2019-04-05 15:07 ` [patch V2 04/29] x86/irq/64: Sanitize the top/bottom confusion Thomas Gleixner
2019-04-05 16:54 ` Sean Christopherson
2019-04-05 15:07 ` [patch V2 05/29] x86/idt: Remove unused macro SISTG Thomas Gleixner
2019-04-05 15:07 ` [patch V2 06/29] x86/exceptions: Remove unused stack defines on 32bit Thomas Gleixner
2019-04-05 15:07 ` [patch V2 07/29] x86/exceptions: Make IST index zero based Thomas Gleixner
2019-04-05 18:59 ` Sean Christopherson
2019-04-05 15:07 ` [patch V2 08/29] x86/cpu_entry_area: Cleanup setup functions Thomas Gleixner
2019-04-05 19:25 ` Sean Christopherson
2019-04-05 15:07 ` [patch V2 09/29] x86/exceptions: Add structs for exception stacks Thomas Gleixner
2019-04-05 20:48 ` Sean Christopherson
2019-04-05 20:50 ` Sean Christopherson
2019-04-05 21:00 ` Thomas Gleixner
2019-04-05 15:07 ` [patch V2 10/29] x86/cpu_entry_area: Prepare for IST guard pages Thomas Gleixner
2019-04-05 15:07 ` [patch V2 11/29] x86/cpu_entry_area: Provide exception stack accessor Thomas Gleixner
2019-04-05 15:07 ` [patch V2 12/29] x86/traps: Use cpu_entry_area instead of orig_ist Thomas Gleixner
2019-04-05 15:07 ` [patch V2 13/29] x86/irq/64: Use cpu entry area " Thomas Gleixner
2019-04-05 15:07 ` [patch V2 14/29] x86/dumpstack/64: Use cpu_entry_area " Thomas Gleixner
2019-04-05 15:07 ` [patch V2 15/29] x86/cpu: Prepare TSS.IST setup for guard pages Thomas Gleixner
2019-04-05 15:07 ` [patch V2 16/29] x86/cpu: Remove orig_ist array Thomas Gleixner
2019-04-05 15:07 ` [patch V2 17/29] x86/exceptions: Disconnect IST index and stack order Thomas Gleixner
2019-04-05 21:57 ` Josh Poimboeuf
2019-04-05 22:00 ` Thomas Gleixner
2019-04-05 15:07 ` [patch V2 18/29] x86/exceptions: Enable IST guard pages Thomas Gleixner
2019-04-05 15:07 ` [patch V2 19/29] x86/exceptions: Split debug IST stack Thomas Gleixner
2019-04-05 20:55 ` Sean Christopherson [this message]
2019-04-05 21:01 ` Thomas Gleixner
2019-04-05 15:07 ` [patch V2 20/29] x86/dumpstack/64: Speedup in_exception_stack() Thomas Gleixner
2019-04-05 21:55 ` Josh Poimboeuf
2019-04-05 21:56 ` Thomas Gleixner
2019-04-05 15:07 ` [patch V2 21/29] x86/irq/32: Define IRQ_STACK_SIZE Thomas Gleixner
2019-04-05 15:07 ` [patch V2 22/29] x86/irq/32: Make irq stack a character array Thomas Gleixner
2019-04-05 15:07 ` [patch V2 23/29] x86/irq/32: Rename hard/softirq_stack to hard/softirq_stack_ptr Thomas Gleixner
2019-04-05 15:07 ` [patch V2 24/29] x86/irq/64: Rename irq_stack_ptr to hardirq_stack_ptr Thomas Gleixner
2019-04-05 15:07 ` [patch V2 25/29] x86/irq/32: Invoke irq_ctx_init() from init_IRQ() Thomas Gleixner
2019-04-05 15:27 ` Juergen Gross
2019-04-05 15:07 ` [patch V2 26/29] x86/irq/32: Handle irq stack allocation failure proper Thomas Gleixner
2019-04-05 15:07 ` [patch V2 27/29] x86/irq/64: Split the IRQ stack into its own pages Thomas Gleixner
2019-04-05 15:07 ` [patch V2 28/29] x86/irq/64: Remap the IRQ stack with guard pages Thomas Gleixner
2019-04-07 4:56 ` Andy Lutomirski
2019-04-07 6:08 ` Thomas Gleixner
2019-04-07 9:28 ` Andy Lutomirski
2019-04-07 9:34 ` Thomas Gleixner
2019-04-07 14:03 ` Andy Lutomirski
2019-04-07 22:44 ` Thomas Gleixner
2019-04-08 2:23 ` Andy Lutomirski
2019-04-08 6:46 ` Thomas Gleixner
2019-04-08 16:18 ` Andy Lutomirski
2019-04-08 16:36 ` Josh Poimboeuf
2019-04-08 16:44 ` Thomas Gleixner
2019-04-08 18:19 ` Thomas Gleixner
2019-04-05 15:07 ` [patch V2 29/29] x86/irq/64: Remove stack overflow debug code Thomas Gleixner
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=20190405205549.GE15808@linux.intel.com \
--to=sean.j.christopherson@intel.com \
--cc=jpoimboe@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=tglx@linutronix.de \
--cc=x86@kernel.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