From: Peter Zijlstra <peterz@infradead.org>
To: Masami Hiramatsu <mhiramat@kernel.org>
Cc: linux-kernel@vger.kernel.org, x86@kernel.org,
Nadav Amit <nadav.amit@gmail.com>,
Andy Lutomirski <luto@kernel.org>,
Dave Hansen <dave.hansen@linux.intel.com>,
Song Liu <songliubraving@fb.com>,
Steven Rostedt <rostedt@goodmis.org>,
Daniel Bristot de Oliveira <bristot@redhat.com>
Subject: Re: [PATCH 1/3] x86/alternatives: Teach text_poke_bp() to emulate instructions
Date: Thu, 3 Oct 2019 15:05:09 +0200 [thread overview]
Message-ID: <20191003130509.GL4581@hirez.programming.kicks-ass.net> (raw)
In-Reply-To: <20191003082751.GQ4536@hirez.programming.kicks-ass.net>
On Thu, Oct 03, 2019 at 10:27:51AM +0200, Peter Zijlstra wrote:
> On Thu, Oct 03, 2019 at 02:00:50PM +0900, Masami Hiramatsu wrote:
>
> > > This fits almost all text_poke_bp() users, except
> > > arch_unoptimize_kprobe() which restores random text, and for that site
> > > we have to build an explicit emulate instruction.
> >
> > OK, and in this case, I would like to change RELATIVEJUMP_OPCODE
> > to JMP32_INSN_OPCODE for readability. (or at least
> > making RELATIVEJUMP_OPCODE as an alias of JMP32_INSN_OPCODE)
>
> > > @@ -448,12 +447,18 @@ void arch_optimize_kprobes(struct list_h
> > > void arch_unoptimize_kprobe(struct optimized_kprobe *op)
> > > {
> > > u8 insn_buff[RELATIVEJUMP_SIZE];
> > > + u8 emulate_buff[RELATIVEJUMP_SIZE];
> > >
> > > /* Set int3 to first byte for kprobes */
> > > insn_buff[0] = BREAKPOINT_INSTRUCTION;
> > > memcpy(insn_buff + 1, op->optinsn.copied_insn, RELATIVE_ADDR_SIZE);
> > > +
> > > + emulate_buff[0] = RELATIVEJUMP_OPCODE;
> > > + *(s32 *)(&emulate_buff[1]) = (s32)((long)op->optinsn.insn -
> > > + ((long)op->kp.addr + RELATIVEJUMP_SIZE));
>
> I'm halfway through a patch introducing:
>
> union text_poke_insn {
> u8 code[POKE_MAX_OPCODE_SUZE];
> struct {
> u8 opcode;
> s32 disp;
> } __attribute__((packed));
> };
>
> to text-patching.h to unify all such custom unions we have all over the
> place. I'll mob up the above in that.
How's something like so?
--- a/arch/x86/include/asm/text-patching.h
+++ b/arch/x86/include/asm/text-patching.h
@@ -49,6 +49,8 @@ extern void text_poke_bp(void *addr, con
extern void text_poke_queue(void *addr, const void *opcode, size_t len, const void *emulate);
extern void text_poke_finish(void);
+extern void *text_gen_insn(u8 opcode, unsigned long addr, unsigned long dest);
+
extern int after_bootmem;
extern __ro_after_init struct mm_struct *poking_mm;
extern __ro_after_init unsigned long poking_addr;
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -1237,3 +1237,39 @@ void text_poke_bp(void *addr, const void
text_poke_loc_init(&tp, addr, opcode, len, emulate);
text_poke_bp_batch(&tp, 1);
}
+
+union text_poke_insn {
+ u8 text[POKE_MAX_OPCODE_SIZE];
+ struct {
+ u8 opcode;
+ s32 disp;
+ } __attribute__((packed));
+};
+
+void *text_gen_insn(u8 opcode, unsigned long addr, unsigned long dest)
+{
+ static union text_poke_insn insn; /* text_mutex */
+ int size = 0;
+
+ lockdep_assert_held(&text_mutex);
+
+ insn.opcode = opcode;
+
+#define __CASE(insn) \
+ case insn##_INSN_OPCODE: size = insn##_INSN_SIZE; break
+
+ switch(opcode) {
+ __CASE(INT3);
+ __CASE(CALL);
+ __CASE(JMP32);
+ __CASE(JMP8);
+ }
+
+ if (size > 1) {
+ insn.disp = dest - (addr + size);
+ if (size == 2)
+ BUG_ON((insn.disp >> 31) != (insn.disp >> 7));
+ }
+
+ return &insn.text;
+}
--- a/arch/x86/kernel/jump_label.c
+++ b/arch/x86/kernel/jump_label.c
@@ -16,14 +16,6 @@
#include <asm/alternative.h>
#include <asm/text-patching.h>
-union jump_code_union {
- char code[JUMP_LABEL_NOP_SIZE];
- struct {
- char jump;
- int offset;
- } __attribute__((packed));
-};
-
static void bug_at(unsigned char *ip, int line)
{
/*
@@ -38,33 +30,29 @@ static void bug_at(unsigned char *ip, in
static const void *
__jump_label_set_jump_code(struct jump_entry *entry, enum jump_label_type type, int init)
{
- static union jump_code_union code; /* relies on text_mutex */
const unsigned char default_nop[] = { STATIC_KEY_INIT_NOP };
const unsigned char *ideal_nop = ideal_nops[NOP_ATOMIC5];
- const void *expect;
+ const void *expect, *code;
int line;
- lockdep_assert_held(&text_mutex);
-
- code.jump = JMP32_INSN_OPCODE;
- code.offset = jump_entry_target(entry) -
- (jump_entry_code(entry) + JUMP_LABEL_NOP_SIZE);
+ code = text_gen_insn(JMP32_INSN_OPCODE, jump_entry_code(entry),
+ jump_entry_target(entry));
if (init) {
expect = default_nop; line = __LINE__;
} else if (type == JUMP_LABEL_JMP) {
expect = ideal_nop; line = __LINE__;
} else {
- expect = code.code; line = __LINE__;
+ expect = code; line = __LINE__;
}
if (memcmp((void *)jump_entry_code(entry), expect, JUMP_LABEL_NOP_SIZE))
bug_at((void *)jump_entry_code(entry), line);
if (type == JUMP_LABEL_NOP)
- memcpy(&code, ideal_nop, JUMP_LABEL_NOP_SIZE);
+ code = ideal_nop;
- return &code;
+ return code;
}
static void inline __jump_label_transform(struct jump_entry *entry,
--- a/arch/x86/kernel/kprobes/opt.c
+++ b/arch/x86/kernel/kprobes/opt.c
@@ -447,18 +447,13 @@ void arch_optimize_kprobes(struct list_h
void arch_unoptimize_kprobe(struct optimized_kprobe *op)
{
u8 insn_buff[RELATIVEJUMP_SIZE];
- u8 emulate_buff[RELATIVEJUMP_SIZE];
/* Set int3 to first byte for kprobes */
insn_buff[0] = BREAKPOINT_INSTRUCTION;
memcpy(insn_buff + 1, op->optinsn.copied_insn, RELATIVE_ADDR_SIZE);
- emulate_buff[0] = RELATIVEJUMP_OPCODE;
- *(s32 *)(&emulate_buff[1]) = (s32)((long)op->optinsn.insn -
- ((long)op->kp.addr + RELATIVEJUMP_SIZE));
-
text_poke_bp(op->kp.addr, insn_buff, RELATIVEJUMP_SIZE,
- emulate_buff);
+ text_gen_insn(JMP32_INSN_OPCODE, (long)op->kp.addr, (long)op->optinsn.insn));
}
/*
next prev parent reply other threads:[~2019-10-03 13:05 UTC|newest]
Thread overview: 61+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-27 18:06 [PATCH 0/3] Rewrite x86/ftrace to use text_poke() Peter Zijlstra
2019-08-27 18:06 ` [PATCH 1/3] x86/alternatives: Teach text_poke_bp() to emulate instructions Peter Zijlstra
2019-10-03 5:00 ` Masami Hiramatsu
2019-10-03 8:27 ` Peter Zijlstra
2019-10-03 11:01 ` Peter Zijlstra
2019-10-03 12:32 ` Peter Zijlstra
2019-10-04 13:45 ` Masami Hiramatsu
2019-10-07 8:05 ` Peter Zijlstra
2019-10-09 13:07 ` x86/kprobes bug? (was: [PATCH 1/3] x86/alternatives: Teach text_poke_bp() to emulate instructions) Peter Zijlstra
2019-10-09 13:26 ` Peter Zijlstra
2019-10-09 13:28 ` Peter Zijlstra
2019-10-09 14:26 ` Mathieu Desnoyers
2019-10-17 19:59 ` Peter Zijlstra
2019-10-03 13:05 ` Peter Zijlstra [this message]
2019-08-27 18:06 ` [PATCH 2/3] x86/alternatives,jump_label: Provide better text_poke() batching interface Peter Zijlstra
2019-10-02 16:34 ` Daniel Bristot de Oliveira
2019-10-03 5:50 ` Masami Hiramatsu
2019-08-27 18:06 ` [PATCH 3/3] x86/ftrace: Use text_poke() Peter Zijlstra
2019-10-02 16:35 ` Daniel Bristot de Oliveira
2019-10-02 18:21 ` Peter Zijlstra
2019-10-03 22:10 ` Steven Rostedt
2019-10-04 8:10 ` Daniel Bristot de Oliveira
2019-10-04 13:40 ` Steven Rostedt
2019-10-04 14:44 ` Daniel Bristot de Oliveira
2019-10-04 15:13 ` Steven Rostedt
2019-10-07 8:08 ` Peter Zijlstra
2019-10-11 7:01 ` Peter Zijlstra
2019-10-11 7:37 ` Daniel Bristot de Oliveira
2019-10-11 10:57 ` Peter Zijlstra
2019-10-11 13:11 ` Steven Rostedt
2019-10-04 11:22 ` Peter Zijlstra
2019-10-04 13:42 ` Steven Rostedt
2019-10-22 0:36 ` Alexei Starovoitov
2019-10-22 0:43 ` Steven Rostedt
2019-10-22 3:10 ` Alexei Starovoitov
2019-10-22 3:16 ` Steven Rostedt
2019-10-22 3:19 ` Steven Rostedt
2019-10-22 4:05 ` Alexei Starovoitov
2019-10-22 11:19 ` Steven Rostedt
2019-10-22 13:44 ` Steven Rostedt
2019-10-22 17:50 ` Alexei Starovoitov
2019-10-22 18:10 ` Steven Rostedt
2019-10-22 20:46 ` Alexei Starovoitov
2019-10-22 21:04 ` Steven Rostedt
2019-10-22 21:58 ` Alexei Starovoitov
2019-10-22 22:17 ` Steven Rostedt
2019-10-23 2:02 ` Steven Rostedt
2019-10-22 22:45 ` Andy Lutomirski
2019-10-22 23:21 ` Steven Rostedt
2019-10-22 23:49 ` Alexei Starovoitov
2019-10-23 4:20 ` Andy Lutomirski
2019-10-23 9:02 ` Peter Zijlstra
2019-10-23 16:23 ` Steven Rostedt
2019-10-23 17:42 ` Steven Rostedt
2019-10-23 19:34 ` Alexei Starovoitov
2019-10-23 20:08 ` Steven Rostedt
2019-10-23 22:36 ` Alexei Starovoitov
2019-10-22 3:55 ` Alexei Starovoitov
2019-10-03 5:52 ` Masami Hiramatsu
2019-08-28 7:22 ` [PATCH 0/3] Rewrite x86/ftrace to use text_poke() Song Liu
-- strict thread matches above, loose matches on Subject: below --
2019-08-26 12:51 Peter Zijlstra
2019-08-26 12:51 ` [PATCH 1/3] x86/alternatives: Teach text_poke_bp() to emulate instructions Peter Zijlstra
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=20191003130509.GL4581@hirez.programming.kicks-ass.net \
--to=peterz@infradead.org \
--cc=bristot@redhat.com \
--cc=dave.hansen@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mhiramat@kernel.org \
--cc=nadav.amit@gmail.com \
--cc=rostedt@goodmis.org \
--cc=songliubraving@fb.com \
--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