x86: Introduce int3 (breakpoint)-based instruction patching
authorJiri Kosina <jkosina@suse.cz>
Fri, 12 Jul 2013 09:21:48 +0000 (11:21 +0200)
committerH. Peter Anvin <hpa@linux.intel.com>
Wed, 17 Jul 2013 00:55:29 +0000 (17:55 -0700)
commitfd4363fff3d96795d3feb1b3fb48ce590f186bdd
treedf1cc6d557edc0f3088323cf43cd7630f0f5ec49
parentad81f0545ef01ea651886dddac4bef6cec930092
x86: Introduce int3 (breakpoint)-based instruction patching

Introduce a method for run-time instruction patching on a live SMP kernel
based on int3 breakpoint, completely avoiding the need for stop_machine().

The way this is achieved:

- add a int3 trap to the address that will be patched
- sync cores
- update all but the first byte of the patched range
- sync cores
- replace the first byte (int3) by the first byte of
  replacing opcode
- sync cores

According to

http://lkml.indiana.edu/hypermail/linux/kernel/1001.1/01530.html

synchronization after replacing "all but first" instructions should not
be necessary (on Intel hardware), as the syncing after the subsequent
patching of the first byte provides enough safety.
But there's not only Intel HW out there, and we'd rather be on a safe
side.

If any CPU instruction execution would collide with the patching,
it'd be trapped by the int3 breakpoint and redirected to the provided
"handler" (which would typically mean just skipping over the patched
region, acting as "nop" has been there, in case we are doing nop -> jump
and jump -> nop transitions).

Ftrace has been using this very technique since 08d636b ("ftrace/x86:
Have arch x86_64 use breakpoints instead of stop machine") for ages
already, and jump labels are another obvious potential user of this.

Based on activities of Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
a few years ago.

Reviewed-by: Steven Rostedt <rostedt@goodmis.org>
Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Link: http://lkml.kernel.org/r/alpine.LNX.2.00.1307121102440.29788@pobox.suse.cz
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
arch/x86/include/asm/alternative.h
arch/x86/kernel/alternative.c
kernel/kprobes.c