]>
git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - arch/s390/kernel/ftrace.c
2 * Dynamic function tracer architecture backend.
4 * Copyright IBM Corp. 2009
6 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>,
10 #include <linux/uaccess.h>
11 #include <linux/ftrace.h>
12 #include <linux/kernel.h>
13 #include <linux/types.h>
14 #include <asm/lowcore.h>
16 void ftrace_disable_code(void);
17 void ftrace_call_code(void);
18 void ftrace_nop_code(void);
20 #define FTRACE_INSN_SIZE 4
26 "ftrace_disable_code:\n"
29 " lg %r1,"__stringify(__LC_FTRACE_FUNC
)"\n"
38 " j .+"__stringify(MCOUNT_INSN_SIZE
)"\n");
43 " stg %r14,8(%r15)\n");
45 #else /* CONFIG_64BIT */
49 "ftrace_disable_code:\n"
51 " l %r1,"__stringify(__LC_FTRACE_FUNC
)"\n"
66 " j .+"__stringify(MCOUNT_INSN_SIZE
)"\n");
71 " st %r14,4(%r15)\n");
73 #endif /* CONFIG_64BIT */
75 static int ftrace_modify_code(unsigned long ip
,
76 void *old_code
, int old_size
,
77 void *new_code
, int new_size
)
79 unsigned char replaced
[MCOUNT_INSN_SIZE
];
82 * Note: Due to modules code can disappear and change.
83 * We need to protect against faulting as well as code
84 * changing. We do this by using the probe_kernel_*
86 * This however is just a simple sanity check.
88 if (probe_kernel_read(replaced
, (void *)ip
, old_size
))
90 if (memcmp(replaced
, old_code
, old_size
) != 0)
92 if (probe_kernel_write((void *)ip
, new_code
, new_size
))
97 static int ftrace_make_initial_nop(struct module
*mod
, struct dyn_ftrace
*rec
,
100 return ftrace_modify_code(rec
->ip
,
101 ftrace_call_code
, FTRACE_INSN_SIZE
,
102 ftrace_disable_code
, MCOUNT_INSN_SIZE
);
105 int ftrace_make_nop(struct module
*mod
, struct dyn_ftrace
*rec
,
108 if (addr
== MCOUNT_ADDR
)
109 return ftrace_make_initial_nop(mod
, rec
, addr
);
110 return ftrace_modify_code(rec
->ip
,
111 ftrace_call_code
, FTRACE_INSN_SIZE
,
112 ftrace_nop_code
, FTRACE_INSN_SIZE
);
115 int ftrace_make_call(struct dyn_ftrace
*rec
, unsigned long addr
)
117 return ftrace_modify_code(rec
->ip
,
118 ftrace_nop_code
, FTRACE_INSN_SIZE
,
119 ftrace_call_code
, FTRACE_INSN_SIZE
);
122 int ftrace_update_ftrace_func(ftrace_func_t func
)
124 ftrace_dyn_func
= (unsigned long)func
;
128 int __init
ftrace_dyn_arch_init(void *data
)
130 *(unsigned long *)data
= 0;