Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
f5074429
cloud-kernel
项目概览
openanolis
/
cloud-kernel
1 年多 前同步成功
通知
160
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
f5074429
编写于
7月 21, 2010
作者:
M
Mike Frysinger
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Blackfin: add support for dynamic ftrace
Signed-off-by:
N
Mike Frysinger
<
vapier@gentoo.org
>
上级
67df6cc6
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
181 addition
and
9 deletion
+181
-9
arch/blackfin/Kconfig
arch/blackfin/Kconfig
+2
-0
arch/blackfin/include/asm/ftrace.h
arch/blackfin/include/asm/ftrace.h
+16
-0
arch/blackfin/kernel/Makefile
arch/blackfin/kernel/Makefile
+1
-0
arch/blackfin/kernel/ftrace-entry.S
arch/blackfin/kernel/ftrace-entry.S
+77
-8
arch/blackfin/kernel/ftrace.c
arch/blackfin/kernel/ftrace.c
+85
-1
未找到文件。
arch/blackfin/Kconfig
浏览文件 @
f5074429
...
...
@@ -25,6 +25,8 @@ config BLACKFIN
def_bool y
select HAVE_ARCH_KGDB
select HAVE_ARCH_TRACEHOOK
select HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
...
...
arch/blackfin/include/asm/ftrace.h
浏览文件 @
f5074429
...
...
@@ -12,6 +12,22 @@
#ifndef __ASSEMBLY__
#ifdef CONFIG_DYNAMIC_FTRACE
extern
void
_mcount
(
void
);
#define MCOUNT_ADDR ((unsigned long)_mcount)
static
inline
unsigned
long
ftrace_call_adjust
(
unsigned
long
addr
)
{
return
addr
;
}
struct
dyn_arch_ftrace
{
/* No extra data needed for Blackfin */
};
#endif
#ifdef CONFIG_FRAME_POINTER
#include <linux/mm.h>
...
...
arch/blackfin/kernel/Makefile
浏览文件 @
f5074429
...
...
@@ -16,6 +16,7 @@ else
obj-y
+=
time.o
endif
obj-$(CONFIG_DYNAMIC_FTRACE)
+=
ftrace.o
obj-$(CONFIG_FUNCTION_TRACER)
+=
ftrace-entry.o
obj-$(CONFIG_FUNCTION_GRAPH_TRACER)
+=
ftrace.o
CFLAGS_REMOVE_ftrace.o
=
-pg
...
...
arch/blackfin/kernel/ftrace-entry.S
浏览文件 @
f5074429
...
...
@@ -10,6 +10,18 @@
.
text
#ifdef CONFIG_DYNAMIC_FTRACE
/*
Simple
stub
so
we
can
boot
the
kernel
until
runtime
patching
has
*
disabled
all
calls
to
this
.
Then
it
'll be unused.
*/
ENTRY
(
__mcount
)
# if ANOMALY_05000371
nop
; nop; nop; nop;
# endif
rts
;
ENDPROC
(
__mcount
)
/*
GCC
will
have
called
us
before
setting
up
the
function
prologue
,
so
we
*
can
clobber
the
normal
scratch
registers
,
but
we
need
to
make
sure
to
*
save
/
restore
the
registers
used
for
argument
passing
(
R0
-
R2
)
in
case
...
...
@@ -20,15 +32,65 @@
*
function
.
And
since
GCC
pushed
the
previous
RETS
for
us
,
the
previous
*
function
will
be
waiting
there
.
mmmm
pie
.
*/
ENTRY
(
_ftrace_caller
)
# ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
/
*
optional
micro
optimization
:
return
if
stopped
*/
p1.l
=
_function_trace_stop
;
p1.h
=
_function_trace_stop
;
r3
=
[
p1
]
;
cc
=
r3
==
0
;
if
!
cc
jump
_ftrace_stub
(
bp
)
;
# endif
/
*
save
first
/
second
/
third
function
arg
and
the
return
register
*/
[--
sp
]
=
r2
;
[--
sp
]
=
r0
;
[--
sp
]
=
r1
;
[--
sp
]
=
rets
;
/
*
function_trace_call
(
unsigned
long
ip
,
unsigned
long
parent_ip
)
:
*
ip
:
this
point
was
called
by
...
*
parent_ip
:
...
this
function
*
the
ip
itself
will
need
adjusting
for
the
mcount
call
*/
r0
=
rets
;
r1
=
[
sp
+
16
]
; /* skip the 4 local regs on stack */
r0
+=
-
MCOUNT_INSN_SIZE
;
.
globl
_ftrace_call
_ftrace_call
:
call
_ftrace_stub
# ifdef CONFIG_FUNCTION_GRAPH_TRACER
.
globl
_ftrace_graph_call
_ftrace_graph_call
:
nop
; /* jump _ftrace_graph_caller; */
# endif
/
*
restore
state
and
get
out
of
dodge
*/
.
Lfinish_trace
:
rets
=
[
sp
++]
;
r1
=
[
sp
++]
;
r0
=
[
sp
++]
;
r2
=
[
sp
++]
;
.
globl
_ftrace_stub
_ftrace_stub
:
rts
;
ENDPROC
(
_ftrace_caller
)
#else
/*
See
documentation
for
_ftrace_caller
*/
ENTRY
(
__mcount
)
#ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
#
ifdef CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST
/
*
optional
micro
optimization
:
return
if
stopped
*/
p1.l
=
_function_trace_stop
;
p1.h
=
_function_trace_stop
;
r3
=
[
p1
]
;
cc
=
r3
==
0
;
if
!
cc
jump
_ftrace_stub
(
bp
)
;
#endif
#
endif
/
*
save
third
function
arg
early
so
we
can
do
testing
below
*/
[--
sp
]
=
r2
;
...
...
@@ -44,7 +106,7 @@ ENTRY(__mcount)
cc
=
r2
==
r3
;
if
!
cc
jump
.
Ldo_trace
;
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
#
ifdef CONFIG_FUNCTION_GRAPH_TRACER
/
*
if
the
ftrace_graph_return
function
pointer
is
not
set
to
*
the
ftrace_stub
entry
,
call
prepare_ftrace_return
()
.
*/
...
...
@@ -64,7 +126,7 @@ ENTRY(__mcount)
r3
=
[
p0
]
;
cc
=
r2
==
r3
;
if
!
cc
jump
_ftrace_graph_caller
;
#endif
#
endif
r2
=
[
sp
++]
;
rts
;
...
...
@@ -103,6 +165,8 @@ _ftrace_stub:
rts
;
ENDPROC
(
__mcount
)
#endif
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
/*
The
prepare_ftrace_return
()
function
is
similar
to
the
trace
function
*
except
it
takes
a
pointer
to
the
location
of
the
frompc
.
This
is
so
...
...
@@ -110,6 +174,7 @@ ENDPROC(__mcount)
*
purposes
.
*/
ENTRY
(
_ftrace_graph_caller
)
# ifndef CONFIG_DYNAMIC_FTRACE
/
*
save
first
/
second
function
arg
and
the
return
register
*/
[--
sp
]
=
r0
;
[--
sp
]
=
r1
;
...
...
@@ -118,9 +183,13 @@ ENTRY(_ftrace_graph_caller)
/
*
prepare_ftrace_return
(
parent
,
self_addr
,
frame_pointer
)
*/
r0
=
sp
; /* unsigned long *parent */
r1
=
rets
; /* unsigned long self_addr */
#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST
# else
r0
=
sp
; /* unsigned long *parent */
r1
=
[
sp
]
; /* unsigned long self_addr */
# endif
# ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST
r2
=
fp
; /* unsigned long frame_pointer */
#endif
#
endif
r0
+=
16
; /* skip the 4 local regs on stack */
r1
+=
-
MCOUNT_INSN_SIZE
;
call
_prepare_ftrace_return
;
...
...
@@ -139,9 +208,9 @@ ENTRY(_return_to_handler)
[--
sp
]
=
r1
;
/
*
get
original
return
address
*/
#ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST
#
ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST
r0
=
fp
; /* Blackfin is sane, so omit this */
#endif
#
endif
call
_ftrace_return_to_handler
;
rets
=
r0
;
...
...
arch/blackfin/kernel/ftrace.c
浏览文件 @
f5074429
/*
* ftrace graph code
*
* Copyright (C) 2009 Analog Devices Inc.
* Copyright (C) 2009
-2010
Analog Devices Inc.
* Licensed under the GPL-2 or later.
*/
#include <linux/ftrace.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <asm/atomic.h>
#include <asm/cacheflush.h>
#ifdef CONFIG_DYNAMIC_FTRACE
static
const
unsigned
char
mnop
[]
=
{
0x03
,
0xc0
,
0x00
,
0x18
,
/* MNOP; */
0x03
,
0xc0
,
0x00
,
0x18
,
/* MNOP; */
};
static
void
bfin_make_pcrel24
(
unsigned
char
*
insn
,
unsigned
long
src
,
unsigned
long
dst
)
{
uint32_t
pcrel
=
(
dst
-
src
)
>>
1
;
insn
[
0
]
=
pcrel
>>
16
;
insn
[
1
]
=
0xe3
;
insn
[
2
]
=
pcrel
;
insn
[
3
]
=
pcrel
>>
8
;
}
#define bfin_make_pcrel24(insn, src, dst) bfin_make_pcrel24(insn, src, (unsigned long)(dst))
static
int
ftrace_modify_code
(
unsigned
long
ip
,
const
unsigned
char
*
code
,
unsigned
long
len
)
{
int
ret
=
probe_kernel_write
((
void
*
)
ip
,
(
void
*
)
code
,
len
);
flush_icache_range
(
ip
,
ip
+
len
);
return
ret
;
}
int
ftrace_make_nop
(
struct
module
*
mod
,
struct
dyn_ftrace
*
rec
,
unsigned
long
addr
)
{
/* Turn the mcount call site into two MNOPs as those are 32bit insns */
return
ftrace_modify_code
(
rec
->
ip
,
mnop
,
sizeof
(
mnop
));
}
int
ftrace_make_call
(
struct
dyn_ftrace
*
rec
,
unsigned
long
addr
)
{
/* Restore the mcount call site */
unsigned
char
call
[
8
];
call
[
0
]
=
0x67
;
/* [--SP] = RETS; */
call
[
1
]
=
0x01
;
bfin_make_pcrel24
(
&
call
[
2
],
rec
->
ip
+
2
,
addr
);
call
[
6
]
=
0x27
;
/* RETS = [SP++]; */
call
[
7
]
=
0x01
;
return
ftrace_modify_code
(
rec
->
ip
,
call
,
sizeof
(
call
));
}
int
ftrace_update_ftrace_func
(
ftrace_func_t
func
)
{
unsigned
char
call
[
4
];
unsigned
long
ip
=
(
unsigned
long
)
&
ftrace_call
;
bfin_make_pcrel24
(
call
,
ip
,
func
);
return
ftrace_modify_code
(
ip
,
call
,
sizeof
(
call
));
}
int
__init
ftrace_dyn_arch_init
(
void
*
data
)
{
/* return value is done indirectly via data */
*
(
unsigned
long
*
)
data
=
0
;
return
0
;
}
#endif
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
# ifdef CONFIG_DYNAMIC_FTRACE
extern
void
ftrace_graph_call
(
void
);
int
ftrace_enable_ftrace_graph_caller
(
void
)
{
unsigned
long
ip
=
(
unsigned
long
)
&
ftrace_graph_call
;
uint16_t
jump_pcrel12
=
((
unsigned
long
)
&
ftrace_graph_caller
-
ip
)
>>
1
;
jump_pcrel12
|=
0x2000
;
return
ftrace_modify_code
(
ip
,
(
void
*
)
&
jump_pcrel12
,
sizeof
(
jump_pcrel12
));
}
int
ftrace_disable_ftrace_graph_caller
(
void
)
{
return
ftrace_modify_code
((
unsigned
long
)
&
ftrace_graph_call
,
empty_zero_page
,
2
);
}
# endif
/*
* Hook the return address and push it in the stack of return addrs
* in current thread info.
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录