forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[S390] ftrace: add dynamic ftrace support
Dynamic ftrace support for s390. Signed-off-by: Heiko Carstens <[email protected]> Signed-off-by: Martin Schwidefsky <[email protected]>
- Loading branch information
Showing
10 changed files
with
276 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
/* | ||
* Dynamic function tracer architecture backend. | ||
* | ||
* Copyright IBM Corp. 2009 | ||
* | ||
* Author(s): Heiko Carstens <[email protected]>, | ||
* | ||
*/ | ||
|
||
#include <linux/uaccess.h> | ||
#include <linux/ftrace.h> | ||
#include <linux/kernel.h> | ||
#include <linux/types.h> | ||
#include <asm/lowcore.h> | ||
|
||
void ftrace_disable_code(void); | ||
void ftrace_call_code(void); | ||
void ftrace_nop_code(void); | ||
|
||
#define FTRACE_INSN_SIZE 4 | ||
|
||
#ifdef CONFIG_64BIT | ||
|
||
asm( | ||
" .align 4\n" | ||
"ftrace_disable_code:\n" | ||
" j 0f\n" | ||
" .word 0x0024\n" | ||
" lg %r1,"__stringify(__LC_FTRACE_FUNC)"\n" | ||
" basr %r14,%r1\n" | ||
" lg %r14,8(15)\n" | ||
" lgr %r0,%r0\n" | ||
"0:\n"); | ||
|
||
asm( | ||
" .align 4\n" | ||
"ftrace_nop_code:\n" | ||
" j .+"__stringify(MCOUNT_INSN_SIZE)"\n"); | ||
|
||
asm( | ||
" .align 4\n" | ||
"ftrace_call_code:\n" | ||
" stg %r14,8(%r15)\n"); | ||
|
||
#else /* CONFIG_64BIT */ | ||
|
||
asm( | ||
" .align 4\n" | ||
"ftrace_disable_code:\n" | ||
" j 0f\n" | ||
" l %r1,"__stringify(__LC_FTRACE_FUNC)"\n" | ||
" basr %r14,%r1\n" | ||
" l %r14,4(%r15)\n" | ||
" j 0f\n" | ||
" bcr 0,%r7\n" | ||
" bcr 0,%r7\n" | ||
" bcr 0,%r7\n" | ||
" bcr 0,%r7\n" | ||
" bcr 0,%r7\n" | ||
" bcr 0,%r7\n" | ||
"0:\n"); | ||
|
||
asm( | ||
" .align 4\n" | ||
"ftrace_nop_code:\n" | ||
" j .+"__stringify(MCOUNT_INSN_SIZE)"\n"); | ||
|
||
asm( | ||
" .align 4\n" | ||
"ftrace_call_code:\n" | ||
" st %r14,4(%r15)\n"); | ||
|
||
#endif /* CONFIG_64BIT */ | ||
|
||
static int ftrace_modify_code(unsigned long ip, | ||
void *old_code, int old_size, | ||
void *new_code, int new_size) | ||
{ | ||
unsigned char replaced[MCOUNT_INSN_SIZE]; | ||
|
||
/* | ||
* Note: Due to modules code can disappear and change. | ||
* We need to protect against faulting as well as code | ||
* changing. We do this by using the probe_kernel_* | ||
* functions. | ||
* This however is just a simple sanity check. | ||
*/ | ||
if (probe_kernel_read(replaced, (void *)ip, old_size)) | ||
return -EFAULT; | ||
if (memcmp(replaced, old_code, old_size) != 0) | ||
return -EINVAL; | ||
if (probe_kernel_write((void *)ip, new_code, new_size)) | ||
return -EPERM; | ||
return 0; | ||
} | ||
|
||
static int ftrace_make_initial_nop(struct module *mod, struct dyn_ftrace *rec, | ||
unsigned long addr) | ||
{ | ||
return ftrace_modify_code(rec->ip, | ||
ftrace_call_code, FTRACE_INSN_SIZE, | ||
ftrace_disable_code, MCOUNT_INSN_SIZE); | ||
} | ||
|
||
int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, | ||
unsigned long addr) | ||
{ | ||
if (addr == MCOUNT_ADDR) | ||
return ftrace_make_initial_nop(mod, rec, addr); | ||
return ftrace_modify_code(rec->ip, | ||
ftrace_call_code, FTRACE_INSN_SIZE, | ||
ftrace_nop_code, FTRACE_INSN_SIZE); | ||
} | ||
|
||
int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | ||
{ | ||
return ftrace_modify_code(rec->ip, | ||
ftrace_nop_code, FTRACE_INSN_SIZE, | ||
ftrace_call_code, FTRACE_INSN_SIZE); | ||
} | ||
|
||
int ftrace_update_ftrace_func(ftrace_func_t func) | ||
{ | ||
ftrace_dyn_func = (unsigned long)func; | ||
return 0; | ||
} | ||
|
||
int __init ftrace_dyn_arch_init(void *data) | ||
{ | ||
*(unsigned long *)data = 0; | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,52 @@ | ||
/* | ||
* Copyright IBM Corp. 2008 | ||
* Copyright IBM Corp. 2008,2009 | ||
* | ||
* Author(s): Heiko Carstens <[email protected]>, | ||
* | ||
*/ | ||
|
||
#include <asm/asm-offsets.h> | ||
|
||
#ifndef CONFIG_64BIT | ||
.globl _mcount | ||
.globl ftrace_stub | ||
ftrace_stub: | ||
br %r14 | ||
|
||
#ifdef CONFIG_64BIT | ||
|
||
#ifdef CONFIG_DYNAMIC_FTRACE | ||
|
||
.globl _mcount | ||
_mcount: | ||
stm %r0,%r5,8(%r15) | ||
st %r14,56(%r15) | ||
lr %r1,%r15 | ||
ahi %r15,-96 | ||
l %r3,100(%r15) | ||
la %r2,0(%r14) | ||
st %r1,__SF_BACKCHAIN(%r15) | ||
la %r3,0(%r3) | ||
bras %r14,0f | ||
.long ftrace_trace_function | ||
0: l %r14,0(%r14) | ||
l %r14,0(%r14) | ||
basr %r14,%r14 | ||
ahi %r15,96 | ||
lm %r0,%r5,8(%r15) | ||
l %r14,56(%r15) | ||
br %r14 | ||
|
||
.globl ftrace_stub | ||
ftrace_stub: | ||
.globl ftrace_caller | ||
ftrace_caller: | ||
stmg %r2,%r5,32(%r15) | ||
stg %r14,112(%r15) | ||
lgr %r1,%r15 | ||
aghi %r15,-160 | ||
stg %r1,__SF_BACKCHAIN(%r15) | ||
lgr %r2,%r14 | ||
lg %r3,168(%r15) | ||
larl %r14,ftrace_dyn_func | ||
lg %r14,0(%r14) | ||
basr %r14,%r14 | ||
aghi %r15,160 | ||
lmg %r2,%r5,32(%r15) | ||
lg %r14,112(%r15) | ||
br %r14 | ||
|
||
#else /* CONFIG_64BIT */ | ||
.data | ||
.globl ftrace_dyn_func | ||
ftrace_dyn_func: | ||
.quad ftrace_stub | ||
.previous | ||
|
||
#else /* CONFIG_DYNAMIC_FTRACE */ | ||
|
||
.globl _mcount | ||
.globl _mcount | ||
_mcount: | ||
stmg %r0,%r5,16(%r15) | ||
stmg %r2,%r5,32(%r15) | ||
stg %r14,112(%r15) | ||
lgr %r1,%r15 | ||
aghi %r15,-160 | ||
|
@@ -47,12 +57,67 @@ _mcount: | |
lg %r14,0(%r14) | ||
basr %r14,%r14 | ||
aghi %r15,160 | ||
lmg %r0,%r5,16(%r15) | ||
lmg %r2,%r5,32(%r15) | ||
lg %r14,112(%r15) | ||
br %r14 | ||
|
||
.globl ftrace_stub | ||
ftrace_stub: | ||
#endif /* CONFIG_DYNAMIC_FTRACE */ | ||
|
||
#else /* CONFIG_64BIT */ | ||
|
||
#ifdef CONFIG_DYNAMIC_FTRACE | ||
|
||
.globl _mcount | ||
_mcount: | ||
br %r14 | ||
|
||
.globl ftrace_caller | ||
ftrace_caller: | ||
stm %r2,%r5,16(%r15) | ||
st %r14,56(%r15) | ||
lr %r1,%r15 | ||
ahi %r15,-96 | ||
l %r3,100(%r15) | ||
la %r2,0(%r14) | ||
st %r1,__SF_BACKCHAIN(%r15) | ||
la %r3,0(%r3) | ||
bras %r14,0f | ||
.long ftrace_dyn_func | ||
0: l %r14,0(%r14) | ||
l %r14,0(%r14) | ||
basr %r14,%r14 | ||
ahi %r15,96 | ||
lm %r2,%r5,16(%r15) | ||
l %r14,56(%r15) | ||
br %r14 | ||
|
||
.data | ||
.globl ftrace_dyn_func | ||
ftrace_dyn_func: | ||
.long ftrace_stub | ||
.previous | ||
|
||
#else /* CONFIG_DYNAMIC_FTRACE */ | ||
|
||
.globl _mcount | ||
_mcount: | ||
stm %r2,%r5,16(%r15) | ||
st %r14,56(%r15) | ||
lr %r1,%r15 | ||
ahi %r15,-96 | ||
l %r3,100(%r15) | ||
la %r2,0(%r14) | ||
st %r1,__SF_BACKCHAIN(%r15) | ||
la %r3,0(%r3) | ||
bras %r14,0f | ||
.long ftrace_trace_function | ||
0: l %r14,0(%r14) | ||
l %r14,0(%r14) | ||
basr %r14,%r14 | ||
ahi %r15,96 | ||
lm %r2,%r5,16(%r15) | ||
l %r14,56(%r15) | ||
br %r14 | ||
|
||
#endif /* CONFIG_DYNAMIC_FTRACE */ | ||
#endif /* CONFIG_64BIT */ |
Oops, something went wrong.