Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
fa9d3b4d
Commit
fa9d3b4d
authored
Aug 22, 2009
by
Paul Mundt
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'sh/dwarf-unwinder'
Conflicts: arch/sh/kernel/cpu/sh3/entry.S
parents
c01f0f1a
74db2479
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
265 additions
and
130 deletions
+265
-130
arch/sh/include/asm/bug.h
arch/sh/include/asm/bug.h
+31
-0
arch/sh/include/asm/dwarf.h
arch/sh/include/asm/dwarf.h
+10
-18
arch/sh/include/asm/system.h
arch/sh/include/asm/system.h
+5
-0
arch/sh/include/asm/unwinder.h
arch/sh/include/asm/unwinder.h
+6
-0
arch/sh/kernel/cpu/sh3/entry.S
arch/sh/kernel/cpu/sh3/entry.S
+2
-0
arch/sh/kernel/dwarf.c
arch/sh/kernel/dwarf.c
+181
-97
arch/sh/kernel/irq.c
arch/sh/kernel/irq.c
+0
-4
arch/sh/kernel/traps.c
arch/sh/kernel/traps.c
+20
-4
arch/sh/kernel/traps_32.c
arch/sh/kernel/traps_32.c
+1
-0
arch/sh/kernel/unwinder.c
arch/sh/kernel/unwinder.c
+9
-7
No files found.
arch/sh/include/asm/bug.h
View file @
fa9d3b4d
...
...
@@ -2,6 +2,7 @@
#define __ASM_SH_BUG_H
#define TRAPA_BUG_OPCODE 0xc33e
/* trapa #0x3e */
#define BUGFLAG_UNWINDER (1 << 1)
#ifdef CONFIG_GENERIC_BUG
#define HAVE_ARCH_BUG
...
...
@@ -72,6 +73,36 @@ do { \
unlikely(__ret_warn_on); \
})
#define UNWINDER_BUG() \
do { \
__asm__ __volatile__ ( \
"1:\t.short %O0\n" \
_EMIT_BUG_ENTRY \
: \
: "n" (TRAPA_BUG_OPCODE), \
"i" (__FILE__), \
"i" (__LINE__), \
"i" (BUGFLAG_UNWINDER), \
"i" (sizeof(struct bug_entry))); \
} while (0)
#define UNWINDER_BUG_ON(x) ({ \
int __ret_unwinder_on = !!(x); \
if (__builtin_constant_p(__ret_unwinder_on)) { \
if (__ret_unwinder_on) \
UNWINDER_BUG(); \
} else { \
if (unlikely(__ret_unwinder_on)) \
UNWINDER_BUG(); \
} \
unlikely(__ret_unwinder_on); \
})
#else
#define UNWINDER_BUG BUG
#define UNWINDER_BUG_ON BUG_ON
#endif
/* CONFIG_GENERIC_BUG */
#include <asm-generic/bug.h>
...
...
arch/sh/include/asm/dwarf.h
View file @
fa9d3b4d
...
...
@@ -265,10 +265,7 @@ struct dwarf_frame {
unsigned
long
pc
;
struct
dwarf_reg
*
regs
;
unsigned
int
num_regs
;
/* how many regs are allocated? */
unsigned
int
depth
;
/* what level are we in the callstack? */
struct
list_head
reg_list
;
unsigned
long
cfa
;
...
...
@@ -292,20 +289,15 @@ struct dwarf_frame {
* @flags: Describes how to calculate the value of this register
*/
struct
dwarf_reg
{
struct
list_head
link
;
unsigned
int
number
;
unsigned
long
addr
;
unsigned
long
flags
;
#define DWARF_REG_OFFSET (1 << 0)
};
/**
* dwarf_stack - a DWARF stack contains a collection of DWARF frames
* @depth: the number of frames in the stack
* @level: an array of DWARF frames, indexed by stack level
*
*/
struct
dwarf_stack
{
unsigned
int
depth
;
struct
dwarf_frame
**
level
;
#define DWARF_VAL_OFFSET (1 << 1)
#define DWARF_UNDEFINED (1 << 2)
};
/*
...
...
@@ -370,17 +362,16 @@ static inline unsigned int DW_CFA_operand(unsigned long insn)
#define DW_EXT_HI 0xffffffff
#define DW_EXT_DWARF64 DW_EXT_HI
extern
void
dwarf_unwinder_init
(
void
);
extern
struct
dwarf_frame
*
dwarf_unwind_stack
(
unsigned
long
,
struct
dwarf_frame
*
);
#endif
/* __ASSEMBLY__ */
#endif
/*
!
__ASSEMBLY__ */
#define CFI_STARTPROC .cfi_startproc
#define CFI_ENDPROC .cfi_endproc
#define CFI_DEF_CFA .cfi_def_cfa
#define CFI_REGISTER .cfi_register
#define CFI_REL_OFFSET .cfi_rel_offset
#define CFI_UNDEFINED .cfi_undefined
#else
...
...
@@ -394,6 +385,7 @@ extern struct dwarf_frame *dwarf_unwind_stack(unsigned long,
#define CFI_DEF_CFA CFI_IGNORE
#define CFI_REGISTER CFI_IGNORE
#define CFI_REL_OFFSET CFI_IGNORE
#define CFI_UNDEFINED CFI_IGNORE
#ifndef __ASSEMBLY__
static
inline
void
dwarf_unwinder_init
(
void
)
...
...
arch/sh/include/asm/system.h
View file @
fa9d3b4d
...
...
@@ -181,6 +181,11 @@ BUILD_TRAP_HANDLER(breakpoint);
BUILD_TRAP_HANDLER
(
singlestep
);
BUILD_TRAP_HANDLER
(
fpu_error
);
BUILD_TRAP_HANDLER
(
fpu_state_restore
);
BUILD_TRAP_HANDLER
(
unwinder
);
#ifdef CONFIG_BUG
extern
void
handle_BUG
(
struct
pt_regs
*
);
#endif
#define arch_align_stack(x) (x)
...
...
arch/sh/include/asm/unwinder.h
View file @
fa9d3b4d
...
...
@@ -22,4 +22,10 @@ extern void stack_reader_dump(struct task_struct *, struct pt_regs *,
unsigned
long
*
,
const
struct
stacktrace_ops
*
,
void
*
);
/*
* Used by fault handling code to signal to the unwinder code that it
* should switch to a different unwinder.
*/
extern
int
unwinder_faulted
;
#endif
/* _LINUX_UNWINDER_H */
arch/sh/kernel/cpu/sh3/entry.S
View file @
fa9d3b4d
...
...
@@ -508,6 +508,8 @@ ENTRY(handle_interrupt)
bsr
save_regs
!
needs
original
pr
value
in
k3
mov
#-
1
,
k2
!
default
vector
kept
in
k2
setup_frame_reg
stc
sr
,
r0
!
get
status
register
shlr2
r0
and
#
0x3c
,
r0
...
...
arch/sh/kernel/dwarf.c
View file @
fa9d3b4d
This diff is collapsed.
Click to expand it.
arch/sh/kernel/irq.c
View file @
fa9d3b4d
...
...
@@ -14,7 +14,6 @@
#include <asm/processor.h>
#include <asm/machvec.h>
#include <asm/uaccess.h>
#include <asm/dwarf.h>
#include <asm/thread_info.h>
#include <cpu/mmu_context.h>
...
...
@@ -262,9 +261,6 @@ void __init init_IRQ(void)
sh_mv
.
mv_init_irq
();
irq_ctx_init
(
smp_processor_id
());
/* This needs to be early, but not too early.. */
dwarf_unwinder_init
();
}
#ifdef CONFIG_SPARSE_IRQ
...
...
arch/sh/kernel/traps.c
View file @
fa9d3b4d
...
...
@@ -5,18 +5,32 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <asm/unwinder.h>
#include <asm/system.h>
#ifdef CONFIG_BUG
static
void
handle_BUG
(
struct
pt_regs
*
regs
)
void
handle_BUG
(
struct
pt_regs
*
regs
)
{
const
struct
bug_entry
*
bug
;
unsigned
long
bugaddr
=
regs
->
pc
;
enum
bug_trap_type
tt
;
tt
=
report_bug
(
regs
->
pc
,
regs
);
if
(
!
is_valid_bugaddr
(
bugaddr
))
goto
invalid
;
bug
=
find_bug
(
bugaddr
);
/* Switch unwinders when unwind_stack() is called */
if
(
bug
->
flags
&
BUGFLAG_UNWINDER
)
unwinder_faulted
=
1
;
tt
=
report_bug
(
bugaddr
,
regs
);
if
(
tt
==
BUG_TRAP_TYPE_WARN
)
{
regs
->
pc
+=
instruction_size
(
regs
->
pc
);
regs
->
pc
+=
instruction_size
(
bugaddr
);
return
;
}
invalid:
die
(
"Kernel BUG"
,
regs
,
TRAPA_BUG_OPCODE
&
0xff
);
}
...
...
@@ -28,8 +42,10 @@ int is_valid_bugaddr(unsigned long addr)
return
0
;
if
(
probe_kernel_address
((
insn_size_t
*
)
addr
,
opcode
))
return
0
;
if
(
opcode
==
TRAPA_BUG_OPCODE
)
return
1
;
return
opcode
==
TRAPA_BUG_OPCODE
;
return
0
;
}
#endif
...
...
arch/sh/kernel/traps_32.c
View file @
fa9d3b4d
...
...
@@ -136,6 +136,7 @@ static void die_if_no_fixup(const char * str, struct pt_regs * regs, long err)
regs
->
pc
=
fixup
->
fixup
;
return
;
}
die
(
str
,
regs
,
err
);
}
}
...
...
arch/sh/kernel/unwinder.c
View file @
fa9d3b4d
...
...
@@ -11,6 +11,7 @@
#include <linux/errno.h>
#include <linux/list.h>
#include <linux/spinlock.h>
#include <linux/module.h>
#include <asm/unwinder.h>
#include <asm/atomic.h>
...
...
@@ -53,8 +54,6 @@ static struct list_head unwinder_list = {
static
DEFINE_SPINLOCK
(
unwinder_lock
);
static
atomic_t
unwinder_running
=
ATOMIC_INIT
(
0
);
/**
* select_unwinder - Select the best registered stack unwinder.
*
...
...
@@ -122,6 +121,8 @@ int unwinder_register(struct unwinder *u)
return
ret
;
}
int
unwinder_faulted
=
0
;
/*
* Unwind the call stack and pass information to the stacktrace_ops
* functions. Also handle the case where we need to switch to a new
...
...
@@ -144,19 +145,20 @@ void unwind_stack(struct task_struct *task, struct pt_regs *regs,
* Hopefully this will give us a semi-reliable stacktrace so we
* can diagnose why curr_unwinder->dump() faulted.
*/
if
(
atomic_inc_return
(
&
unwinder_running
)
!=
1
)
{
if
(
unwinder_faulted
)
{
spin_lock_irqsave
(
&
unwinder_lock
,
flags
);
if
(
!
list_is_singular
(
&
unwinder_list
))
{
/* Make sure no one beat us to changing the unwinder */
if
(
unwinder_faulted
&&
!
list_is_singular
(
&
unwinder_list
))
{
list_del
(
&
curr_unwinder
->
list
);
curr_unwinder
=
select_unwinder
();
unwinder_faulted
=
0
;
}
spin_unlock_irqrestore
(
&
unwinder_lock
,
flags
);
atomic_dec
(
&
unwinder_running
);
}
curr_unwinder
->
dump
(
task
,
regs
,
sp
,
ops
,
data
);
atomic_dec
(
&
unwinder_running
);
}
EXPORT_SYMBOL_GPL
(
unwind_stack
);
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment