Skip to content

Commit

Permalink
powerpc: Have patch_instruction detect faults
Browse files Browse the repository at this point in the history
For ftrace to use the patch_instruction code, it needs to check for
faults on write. Ftrace updates code all over the kernel, and we need to
know if code is updated or not due to protections that are placed on
some portions of the kernel. If ftrace does not detect a fault, it will
error later on, and it will be much more difficult to find the problem.

By changing patch_instruction() to detect faults, then ftrace will be
able to make use of it too.

Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Steven Rostedt authored and Benjamin Herrenschmidt committed Jul 3, 2012
1 parent ee456bb commit b6e3796
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 6 deletions.
4 changes: 2 additions & 2 deletions arch/powerpc/include/asm/code-patching.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ unsigned int create_branch(const unsigned int *addr,
unsigned long target, int flags);
unsigned int create_cond_branch(const unsigned int *addr,
unsigned long target, int flags);
void patch_branch(unsigned int *addr, unsigned long target, int flags);
void patch_instruction(unsigned int *addr, unsigned int instr);
int patch_branch(unsigned int *addr, unsigned long target, int flags);
int patch_instruction(unsigned int *addr, unsigned int instr);

int instr_is_relative_branch(unsigned int instr);
int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr);
Expand Down
14 changes: 10 additions & 4 deletions arch/powerpc/lib/code-patching.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,23 @@
#include <linux/mm.h>
#include <asm/page.h>
#include <asm/code-patching.h>
#include <asm/uaccess.h>


void patch_instruction(unsigned int *addr, unsigned int instr)
int patch_instruction(unsigned int *addr, unsigned int instr)
{
*addr = instr;
int err;

err = __put_user(instr, addr);
if (err)
return err;
asm ("dcbst 0, %0; sync; icbi 0,%0; sync; isync" : : "r" (addr));
return 0;
}

void patch_branch(unsigned int *addr, unsigned long target, int flags)
int patch_branch(unsigned int *addr, unsigned long target, int flags)
{
patch_instruction(addr, create_branch(addr, target, flags));
return patch_instruction(addr, create_branch(addr, target, flags));
}

unsigned int create_branch(const unsigned int *addr,
Expand Down

0 comments on commit b6e3796

Please sign in to comment.