From: peterz at infradead.org (Peter Zijlstra) Subject: [RFC][PATCH 1.5/2] x86: Add int3_emulate_call() selftest Date: Fri, 3 May 2019 12:22:47 +0200 [thread overview] Message-ID: <20190503102247.GC2623@hirez.programming.kicks-ass.net> (raw) In-Reply-To: <20190501202830.347656894@goodmis.org> Given that the entry_*.S changes for this functionality are somewhat tricky, make sure the paths are tested every boot, instead of on the rare occasion when we trip an INT3 while rewriting text. Getting the INT3 frame setup even slightly wrong will make this come unstuck something spectacular. Requested-by: Andy Lutomirski <luto at kernel.org> Signed-off-by: Peter Zijlstra (Intel) <peterz at infradead.org> --- arch/x86/kernel/alternative.c | 81 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 4db9c0d29bc1..2b853c2ab894 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -613,11 +613,83 @@ extern struct paravirt_patch_site __start_parainstructions[], __stop_parainstructions[]; #endif /* CONFIG_PARAVIRT */ +/* + * Self-test for the INT3 based CALL emulation code. + * + * This exercises int3_emulate_call() to make sure INT3 pt_regs are set up + * properly and that there is a stack gap between the INT3 frame and the + * previous context. Without this gap doing a virtual PUSH on the interrupted + * stack would corrupt the INT3 IRET frame. + * + * See entry_{32,64}.S for more details. + */ +static void __init int3_magic(unsigned int *ptr) +{ + *ptr = 1; +} + +extern __initdata unsigned long int3_selftest_ip; /* defined in asm below */ + +static int __init +int3_exception_notify(struct notifier_block *self, unsigned long val, void *data) +{ + struct die_args *args = data; + struct pt_regs *regs = args->regs; + + if (!regs || user_mode(regs)) + return NOTIFY_DONE; + + if (val != DIE_INT3) + return NOTIFY_DONE; + + if (regs->ip - INT3_INSN_SIZE != int3_selftest_ip) + return NOTIFY_DONE; + + int3_emulate_call(regs, (unsigned long)&int3_magic); + return NOTIFY_STOP; +} + +static void __init int3_selftest(void) +{ + static __initdata struct notifier_block int3_exception_nb = { + .notifier_call = int3_exception_notify, + .priority = INT_MAX-1, /* last */ + }; + unsigned int val = 0; + + BUG_ON(register_die_notifier(&int3_exception_nb)); + + /* + * Basically: int3_magic(&val); but really complicated :-) + * + * Stick the address of the INT3 instruction into int3_selftest_ip, + * then trigger the INT3, padded with NOPs to match a CALL instruction + * length. + */ + asm volatile ("1: int3; nop; nop; nop; nop\n\t" + ".pushsection .init.data,\"aw\"\n\t" + ".align " __ASM_SEL(4, 8) "\n\t" + ".type int3_selftest_ip, @object\n\t" + ".size int3_selftest_ip, " __ASM_SEL(4, 8) "\n\t" + "int3_selftest_ip:\n\t" + __ASM_SEL(.long, .quad) " 1b\n\t" + ".popsection\n\t" + : : __ASM_SEL_RAW(a, D) (&val) : "memory"); + + BUG_ON(val != 1); + + unregister_die_notifier(&int3_exception_nb); +} + void __init alternative_instructions(void) { - /* The patching is not fully atomic, so try to avoid local interruptions - that might execute the to be patched code. - Other CPUs are not running. */ + int3_selftest(); + + /* + * The patching is not fully atomic, so try to avoid local + * interruptions that might execute the to be patched code. + * Other CPUs are not running. + */ stop_nmi(); /* @@ -642,10 +714,11 @@ void __init alternative_instructions(void) _text, _etext); } - if (!uniproc_patched || num_possible_cpus() == 1) + if (!uniproc_patched || num_possible_cpus() == 1) { free_init_pages("SMP alternatives", (unsigned long)__smp_locks, (unsigned long)__smp_locks_end); + } #endif apply_paravirt(__parainstructions, __parainstructions_end);
WARNING: multiple messages have this Message-ID (diff)
From: peterz@infradead.org (Peter Zijlstra) Subject: [RFC][PATCH 1.5/2] x86: Add int3_emulate_call() selftest Date: Fri, 3 May 2019 12:22:47 +0200 [thread overview] Message-ID: <20190503102247.GC2623@hirez.programming.kicks-ass.net> (raw) Message-ID: <20190503102247.EqIKRuOKK-MflDQIkazy6q6UIvo6VsB475bdLA4jcII@z> (raw) In-Reply-To: <20190501202830.347656894@goodmis.org> Given that the entry_*.S changes for this functionality are somewhat tricky, make sure the paths are tested every boot, instead of on the rare occasion when we trip an INT3 while rewriting text. Getting the INT3 frame setup even slightly wrong will make this come unstuck something spectacular. Requested-by: Andy Lutomirski <luto at kernel.org> Signed-off-by: Peter Zijlstra (Intel) <peterz at infradead.org> --- arch/x86/kernel/alternative.c | 81 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 4db9c0d29bc1..2b853c2ab894 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -613,11 +613,83 @@ extern struct paravirt_patch_site __start_parainstructions[], __stop_parainstructions[]; #endif /* CONFIG_PARAVIRT */ +/* + * Self-test for the INT3 based CALL emulation code. + * + * This exercises int3_emulate_call() to make sure INT3 pt_regs are set up + * properly and that there is a stack gap between the INT3 frame and the + * previous context. Without this gap doing a virtual PUSH on the interrupted + * stack would corrupt the INT3 IRET frame. + * + * See entry_{32,64}.S for more details. + */ +static void __init int3_magic(unsigned int *ptr) +{ + *ptr = 1; +} + +extern __initdata unsigned long int3_selftest_ip; /* defined in asm below */ + +static int __init +int3_exception_notify(struct notifier_block *self, unsigned long val, void *data) +{ + struct die_args *args = data; + struct pt_regs *regs = args->regs; + + if (!regs || user_mode(regs)) + return NOTIFY_DONE; + + if (val != DIE_INT3) + return NOTIFY_DONE; + + if (regs->ip - INT3_INSN_SIZE != int3_selftest_ip) + return NOTIFY_DONE; + + int3_emulate_call(regs, (unsigned long)&int3_magic); + return NOTIFY_STOP; +} + +static void __init int3_selftest(void) +{ + static __initdata struct notifier_block int3_exception_nb = { + .notifier_call = int3_exception_notify, + .priority = INT_MAX-1, /* last */ + }; + unsigned int val = 0; + + BUG_ON(register_die_notifier(&int3_exception_nb)); + + /* + * Basically: int3_magic(&val); but really complicated :-) + * + * Stick the address of the INT3 instruction into int3_selftest_ip, + * then trigger the INT3, padded with NOPs to match a CALL instruction + * length. + */ + asm volatile ("1: int3; nop; nop; nop; nop\n\t" + ".pushsection .init.data,\"aw\"\n\t" + ".align " __ASM_SEL(4, 8) "\n\t" + ".type int3_selftest_ip, @object\n\t" + ".size int3_selftest_ip, " __ASM_SEL(4, 8) "\n\t" + "int3_selftest_ip:\n\t" + __ASM_SEL(.long, .quad) " 1b\n\t" + ".popsection\n\t" + : : __ASM_SEL_RAW(a, D) (&val) : "memory"); + + BUG_ON(val != 1); + + unregister_die_notifier(&int3_exception_nb); +} + void __init alternative_instructions(void) { - /* The patching is not fully atomic, so try to avoid local interruptions - that might execute the to be patched code. - Other CPUs are not running. */ + int3_selftest(); + + /* + * The patching is not fully atomic, so try to avoid local + * interruptions that might execute the to be patched code. + * Other CPUs are not running. + */ stop_nmi(); /* @@ -642,10 +714,11 @@ void __init alternative_instructions(void) _text, _etext); } - if (!uniproc_patched || num_possible_cpus() == 1) + if (!uniproc_patched || num_possible_cpus() == 1) { free_init_pages("SMP alternatives", (unsigned long)__smp_locks, (unsigned long)__smp_locks_end); + } #endif apply_paravirt(__parainstructions, __parainstructions_end);
next prev parent reply other threads:[~2019-05-03 10:22 UTC|newest] Thread overview: 204+ messages / expand[flat|nested] mbox.gz Atom feed top [not found] <20190501202830.347656894@goodmis.org> 2019-05-01 20:28 ` [RFC][PATCH 1/2] x86: Allow breakpoints to emulate call functions rostedt 2019-05-01 20:28 ` Steven Rostedt 2019-05-02 3:24 ` rostedt 2019-05-02 3:24 ` Steven Rostedt 2019-05-02 16:21 ` peterz 2019-05-02 16:21 ` Peter Zijlstra 2019-05-02 16:29 ` peterz 2019-05-02 16:29 ` Peter Zijlstra 2019-05-02 18:02 ` torvalds 2019-05-02 18:02 ` Linus Torvalds 2019-05-02 18:18 ` peterz 2019-05-02 18:18 ` Peter Zijlstra 2019-05-02 18:30 ` peterz 2019-05-02 18:30 ` Peter Zijlstra 2019-05-02 18:43 ` torvalds 2019-05-02 18:43 ` Linus Torvalds 2019-05-02 19:28 ` jikos 2019-05-02 19:28 ` Jiri Kosina 2019-05-02 20:25 ` luto 2019-05-02 20:25 ` Andy Lutomirski 2019-05-02 20:21 ` peterz 2019-05-02 20:21 ` Peter Zijlstra 2019-05-02 20:49 ` torvalds 2019-05-02 20:49 ` Linus Torvalds 2019-05-02 21:32 ` peterz 2019-05-02 21:32 ` Peter Zijlstra 2019-05-03 19:24 ` rostedt 2019-05-03 19:24 ` Steven Rostedt 2019-05-03 21:46 ` torvalds 2019-05-03 21:46 ` Linus Torvalds 2019-05-03 22:49 ` rostedt 2019-05-03 22:49 ` Steven Rostedt 2019-05-03 23:07 ` torvalds 2019-05-03 23:07 ` Linus Torvalds 2019-05-04 4:17 ` rostedt 2019-05-04 4:17 ` Steven Rostedt [not found] ` <CAHk-=wiuSFbv_rELND-BLWcP0GSZ0yF=xOAEcf61GE3bU9d=yg@mail.gmail.com> 2019-05-04 18:59 ` torvalds 2019-05-04 18:59 ` Linus Torvalds 2019-05-04 20:12 ` luto 2019-05-04 20:12 ` Andy Lutomirski 2019-05-04 20:28 ` torvalds 2019-05-04 20:28 ` Linus Torvalds 2019-05-04 20:36 ` torvalds 2019-05-04 20:36 ` Linus Torvalds 2019-05-03 22:55 ` luto 2019-05-03 22:55 ` Andy Lutomirski 2019-05-03 23:16 ` torvalds 2019-05-03 23:16 ` Linus Torvalds 2019-05-03 23:32 ` luto 2019-05-03 23:32 ` Andy Lutomirski 2019-05-02 22:52 ` rostedt 2019-05-02 22:52 ` Steven Rostedt 2019-05-02 23:31 ` rostedt 2019-05-02 23:31 ` Steven Rostedt 2019-05-02 23:50 ` rostedt 2019-05-02 23:50 ` Steven Rostedt 2019-05-03 1:51 ` [RFC][PATCH 1/2 v2] " rostedt 2019-05-03 1:51 ` Steven Rostedt 2019-05-03 9:29 ` [RFC][PATCH 1/2] " peterz 2019-05-03 9:29 ` Peter Zijlstra 2019-05-03 13:22 ` rostedt 2019-05-03 13:22 ` Steven Rostedt 2019-05-03 16:20 ` luto 2019-05-03 16:20 ` Andy Lutomirski 2019-05-03 16:31 ` rostedt 2019-05-03 16:31 ` Steven Rostedt 2019-05-03 16:35 ` peterz 2019-05-03 16:35 ` Peter Zijlstra 2019-05-03 16:44 ` luto 2019-05-03 16:44 ` Andy Lutomirski 2019-05-03 16:49 ` rostedt 2019-05-03 16:49 ` Steven Rostedt 2019-05-03 16:32 ` peterz 2019-05-03 16:32 ` Peter Zijlstra 2019-05-03 18:57 ` torvalds 2019-05-03 18:57 ` Linus Torvalds 2019-05-06 8:19 ` peterz 2019-05-06 8:19 ` Peter Zijlstra 2019-05-06 13:56 ` rostedt 2019-05-06 13:56 ` Steven Rostedt 2019-05-06 16:17 ` torvalds 2019-05-06 16:17 ` Linus Torvalds 2019-05-06 16:19 ` torvalds 2019-05-06 16:19 ` Linus Torvalds 2019-05-06 17:06 ` rostedt 2019-05-06 17:06 ` Steven Rostedt 2019-05-06 18:06 ` torvalds 2019-05-06 18:06 ` Linus Torvalds 2019-05-06 18:57 ` rostedt 2019-05-06 18:57 ` Steven Rostedt 2019-05-06 19:46 ` torvalds 2019-05-06 19:46 ` Linus Torvalds 2019-05-06 20:29 ` rostedt 2019-05-06 20:29 ` Steven Rostedt 2019-05-06 20:42 ` torvalds 2019-05-06 20:42 ` Linus Torvalds 2019-05-06 20:44 ` torvalds 2019-05-06 20:44 ` Linus Torvalds 2019-05-06 21:45 ` rostedt 2019-05-06 21:45 ` Steven Rostedt 2019-05-06 22:06 ` torvalds 2019-05-06 22:06 ` Linus Torvalds 2019-05-06 22:31 ` torvalds 2019-05-06 22:31 ` Linus Torvalds 2019-05-07 0:10 ` rostedt 2019-05-07 0:10 ` Steven Rostedt 2019-05-07 1:06 ` torvalds 2019-05-07 1:06 ` Linus Torvalds 2019-05-07 1:04 ` rostedt 2019-05-07 1:04 ` Steven Rostedt 2019-05-07 1:34 ` rostedt 2019-05-07 1:34 ` Steven Rostedt 2019-05-07 1:34 ` torvalds 2019-05-07 1:34 ` Linus Torvalds 2019-05-07 1:53 ` rostedt 2019-05-07 1:53 ` Steven Rostedt 2019-05-07 2:22 ` torvalds 2019-05-07 2:22 ` Linus Torvalds 2019-05-07 2:58 ` rostedt 2019-05-07 2:58 ` Steven Rostedt 2019-05-07 3:05 ` torvalds 2019-05-07 3:05 ` Linus Torvalds 2019-05-07 3:21 ` rostedt 2019-05-07 3:21 ` Steven Rostedt 2019-05-07 3:28 ` torvalds 2019-05-07 3:28 ` Linus Torvalds 2019-05-07 14:54 ` torvalds 2019-05-07 14:54 ` Linus Torvalds 2019-05-07 15:12 ` rostedt 2019-05-07 15:12 ` Steven Rostedt 2019-05-07 15:25 ` rostedt 2019-05-07 15:25 ` Steven Rostedt 2019-05-07 16:25 ` rostedt 2019-05-07 16:25 ` Steven Rostedt 2019-05-07 15:31 ` torvalds 2019-05-07 15:31 ` Linus Torvalds 2019-05-07 15:45 ` rostedt 2019-05-07 15:45 ` Steven Rostedt 2019-05-07 16:34 ` peterz 2019-05-07 16:34 ` Peter Zijlstra 2019-05-07 17:08 ` torvalds 2019-05-07 17:08 ` Linus Torvalds 2019-05-07 17:21 ` jpoimboe 2019-05-07 17:21 ` Josh Poimboeuf 2019-05-07 21:24 ` rostedt 2019-05-07 21:24 ` Steven Rostedt 2019-05-08 4:50 ` torvalds 2019-05-08 4:50 ` Linus Torvalds 2019-05-08 16:37 ` rostedt 2019-05-08 16:37 ` Steven Rostedt 2019-05-07 17:38 ` peterz 2019-05-07 17:38 ` Peter Zijlstra 2019-05-07 9:51 ` peterz 2019-05-07 9:51 ` Peter Zijlstra 2019-05-07 14:48 ` luto 2019-05-07 14:48 ` Andy Lutomirski 2019-05-07 14:57 ` torvalds 2019-05-07 14:57 ` Linus Torvalds 2019-05-07 14:13 ` mhiramat 2019-05-07 14:13 ` Masami Hiramatsu 2019-05-07 17:15 ` mhiramat 2019-05-07 17:15 ` Masami Hiramatsu 2019-05-06 14:22 ` peterz 2019-05-06 14:22 ` Peter Zijlstra 2019-05-07 8:57 ` peterz 2019-05-07 8:57 ` Peter Zijlstra 2019-05-07 9:18 ` David.Laight 2019-05-07 9:18 ` David Laight 2019-05-07 11:30 ` peterz 2019-05-07 11:30 ` Peter Zijlstra 2019-05-07 12:57 ` David.Laight 2019-05-07 12:57 ` David Laight 2019-05-07 13:14 ` rostedt 2019-05-07 13:14 ` Steven Rostedt 2019-05-07 14:50 ` David.Laight 2019-05-07 14:50 ` David Laight 2019-05-07 14:57 ` rostedt 2019-05-07 14:57 ` Steven Rostedt 2019-05-07 15:46 ` David.Laight 2019-05-07 15:46 ` David Laight 2019-05-07 13:32 ` peterz 2019-05-07 13:32 ` Peter Zijlstra 2019-05-07 9:27 ` peterz 2019-05-07 9:27 ` Peter Zijlstra 2019-05-07 12:27 ` rostedt 2019-05-07 12:27 ` Steven Rostedt 2019-05-07 12:41 ` peterz 2019-05-07 12:41 ` Peter Zijlstra 2019-05-07 12:54 ` rostedt 2019-05-07 12:54 ` Steven Rostedt 2019-05-07 17:22 ` masami.hiramatsu 2019-05-07 17:22 ` Masami Hiramatsu 2019-05-07 14:28 ` peterz 2019-05-07 14:28 ` Peter Zijlstra 2019-05-02 20:48 ` rostedt 2019-05-02 20:48 ` Steven Rostedt 2019-05-06 15:14 ` jpoimboe 2019-05-06 15:14 ` Josh Poimboeuf 2019-05-01 20:28 ` [RFC][PATCH 2/2] ftrace/x86: Emulate call function while updating in breakpoint handler rostedt 2019-05-01 20:28 ` Steven Rostedt 2019-05-03 10:22 ` peterz [this message] 2019-05-03 10:22 ` [RFC][PATCH 1.5/2] x86: Add int3_emulate_call() selftest Peter Zijlstra 2019-05-03 18:46 ` rostedt 2019-05-03 18:46 ` Steven Rostedt
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=20190503102247.GC2623@hirez.programming.kicks-ass.net \ --to=linux-kselftest@vger.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: linkBe 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; as well as URLs for NNTP newsgroup(s).