Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
d0c0cf74
Commit
d0c0cf74
authored
Jun 09, 2003
by
Anton Blanchard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ppc64: Update BUG handling based on ppc32
parent
d8b4bc5c
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
148 additions
and
20 deletions
+148
-20
arch/ppc64/kernel/module.c
arch/ppc64/kernel/module.c
+42
-0
arch/ppc64/kernel/traps.c
arch/ppc64/kernel/traps.c
+55
-0
arch/ppc64/vmlinux.lds.S
arch/ppc64/vmlinux.lds.S
+4
-0
include/asm-ppc64/bug.h
include/asm-ppc64/bug.h
+37
-20
include/asm-ppc64/module.h
include/asm-ppc64/module.h
+10
-0
No files found.
arch/ppc64/kernel/module.c
View file @
d0c0cf74
...
...
@@ -376,15 +376,57 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
return
0
;
}
LIST_HEAD
(
module_bug_list
);
int
module_finalize
(
const
Elf_Ehdr
*
hdr
,
const
Elf_Shdr
*
sechdrs
,
struct
module
*
me
)
{
char
*
secstrings
;
unsigned
int
i
;
me
->
arch
.
bug_table
=
NULL
;
me
->
arch
.
num_bugs
=
0
;
/* Find the __bug_table section, if present */
secstrings
=
(
char
*
)
hdr
+
sechdrs
[
hdr
->
e_shstrndx
].
sh_offset
;
for
(
i
=
1
;
i
<
hdr
->
e_shnum
;
i
++
)
{
if
(
strcmp
(
secstrings
+
sechdrs
[
i
].
sh_name
,
"__bug_table"
))
continue
;
me
->
arch
.
bug_table
=
(
void
*
)
sechdrs
[
i
].
sh_addr
;
me
->
arch
.
num_bugs
=
sechdrs
[
i
].
sh_size
/
sizeof
(
struct
bug_entry
);
break
;
}
/*
* Strictly speaking this should have a spinlock to protect against
* traversals, but since we only traverse on BUG()s, a spinlock
* could potentially lead to deadlock and thus be counter-productive.
*/
list_add
(
&
me
->
arch
.
bug_list
,
&
module_bug_list
);
sort_ex_table
((
struct
exception_table_entry
*
)
me
->
extable
,
(
struct
exception_table_entry
*
)
me
->
extable
+
me
->
num_exentries
);
return
0
;
}
void
module_arch_cleanup
(
struct
module
*
mod
)
{
list_del
(
&
mod
->
arch
.
bug_list
);
}
struct
bug_entry
*
module_find_bug
(
unsigned
long
bugaddr
)
{
struct
mod_arch_specific
*
mod
;
unsigned
int
i
;
struct
bug_entry
*
bug
;
list_for_each_entry
(
mod
,
&
module_bug_list
,
bug_list
)
{
bug
=
mod
->
bug_table
;
for
(
i
=
0
;
i
<
mod
->
num_bugs
;
++
i
,
++
bug
)
if
(
bugaddr
==
bug
->
bug_addr
)
return
bug
;
}
return
NULL
;
}
arch/ppc64/kernel/traps.c
View file @
d0c0cf74
...
...
@@ -28,6 +28,7 @@
#include <linux/interrupt.h>
#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
...
...
@@ -306,6 +307,56 @@ static void parse_fpe(struct pt_regs *regs)
_exception
(
SIGFPE
,
&
info
,
regs
);
}
/*
* Look through the list of trap instructions that are used for BUG(),
* BUG_ON() and WARN_ON() and see if we hit one. At this point we know
* that the exception was caused by a trap instruction of some kind.
* Returns 1 if we should continue (i.e. it was a WARN_ON) or 0
* otherwise.
*/
extern
struct
bug_entry
__start___bug_table
[],
__stop___bug_table
[];
#ifndef CONFIG_MODULES
#define module_find_bug(x) NULL
#endif
static
struct
bug_entry
*
find_bug
(
unsigned
long
bugaddr
)
{
struct
bug_entry
*
bug
;
for
(
bug
=
__start___bug_table
;
bug
<
__stop___bug_table
;
++
bug
)
if
(
bugaddr
==
bug
->
bug_addr
)
return
bug
;
return
module_find_bug
(
bugaddr
);
}
int
check_bug_trap
(
struct
pt_regs
*
regs
)
{
struct
bug_entry
*
bug
;
unsigned
long
addr
;
if
(
regs
->
msr
&
MSR_PR
)
return
0
;
/* not in kernel */
addr
=
regs
->
nip
;
/* address of trap instruction */
if
(
addr
<
PAGE_OFFSET
)
return
0
;
bug
=
find_bug
(
regs
->
nip
);
if
(
bug
==
NULL
)
return
0
;
if
(
bug
->
line
&
BUG_WARNING_TRAP
)
{
/* this is a WARN_ON rather than BUG/BUG_ON */
printk
(
KERN_ERR
"Badness in %s at %s:%d
\n
"
,
bug
->
function
,
bug
->
file
,
bug
->
line
&
~
BUG_WARNING_TRAP
);
dump_stack
();
return
1
;
}
printk
(
KERN_CRIT
"kernel BUG in %s at %s:%d!
\n
"
,
bug
->
function
,
bug
->
file
,
bug
->
line
);
return
0
;
}
void
ProgramCheckException
(
struct
pt_regs
*
regs
)
{
...
...
@@ -330,6 +381,10 @@ ProgramCheckException(struct pt_regs *regs)
if
(
debugger_bpt
&&
debugger_bpt
(
regs
))
return
;
#endif
if
(
check_bug_trap
(
regs
))
{
regs
->
nip
+=
4
;
return
;
}
info
.
si_signo
=
SIGTRAP
;
info
.
si_errno
=
0
;
info
.
si_code
=
TRAP_BRKPT
;
...
...
arch/ppc64/vmlinux.lds.S
View file @
d0c0cf74
...
...
@@ -65,6 +65,10 @@ SECTIONS
__ex_table
:
{
*(
__ex_table
)
}
__stop___ex_table
=
.
;
__start___bug_table
=
.
;
__bug_table
:
{
*(
__bug_table
)
}
__stop___bug_table
=
.
;
__start___ftr_fixup
=
.
;
__ftr_fixup
:
{
*(
__ftr_fixup
)
}
__stop___ftr_fixup
=
.
;
...
...
include/asm-ppc64/bug.h
View file @
d0c0cf74
#ifndef _PPC64_BUG_H
#define _PPC64_BUG_H
#include <linux/config.h>
/*
* Define an illegal instr to trap on the bug.
* We don't use 0 because that marks the end of a function
...
...
@@ -13,29 +11,48 @@
#ifndef __ASSEMBLY__
#ifdef CONFIG_XMON
struct
pt_regs
;
extern
void
xmon
(
struct
pt_regs
*
excp
);
#define BUG() do { \
printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
xmon(0); \
} while (0)
#else
#define BUG() do { \
printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
__asm__ __volatile__(".long " BUG_ILLEGAL_INSTR); \
struct
bug_entry
{
unsigned
long
bug_addr
;
long
line
;
const
char
*
file
;
const
char
*
function
;
};
/*
* If this bit is set in the line number it means that the trap
* is for WARN_ON rather than BUG or BUG_ON.
*/
#define BUG_WARNING_TRAP 0x1000000
#define BUG() do { \
__asm__ __volatile__( \
"1: twi 31,0,0\n" \
".section __bug_table,\"a\"\n\t" \
" .llong 1b,%0,%1,%2\n" \
".previous" \
: : "i" (__LINE__), "i" (__FILE__), "i" (__FUNCTION__)); \
} while (0)
#endif
#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
#define BUG_ON(x) do { \
__asm__ __volatile__( \
"1: tdnei %0,0\n" \
".section __bug_table,\"a\"\n\t" \
" .llong 1b,%1,%2,%3\n" \
".previous" \
: : "r" (x), "i" (__LINE__), "i" (__FILE__), \
"i" (__FUNCTION__)); \
} while (0)
#define PAGE_BUG(page) do { BUG(); } while (0)
#define WARN_ON(condition) do { \
if (unlikely((condition)!=0)) { \
printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \
dump_stack(); \
} \
#define WARN_ON(x) do { \
__asm__ __volatile__( \
"1: tdnei %0,0\n" \
".section __bug_table,\"a\"\n\t" \
" .llong 1b,%1,%2,%3\n" \
".previous" \
: : "r" (x), "i" (__LINE__ + BUG_WARNING_TRAP), \
"i" (__FILE__), "i" (__FUNCTION__)); \
} while (0)
#endif
...
...
include/asm-ppc64/module.h
View file @
d0c0cf74
#ifndef _ASM_PPC64_MODULE_H
#define _ASM_PPC64_MODULE_H
#include <linux/list.h>
#include <asm/bug.h>
struct
mod_arch_specific
{
/* Index of stubs section within module. */
...
...
@@ -8,8 +11,15 @@ struct mod_arch_specific
/* What section is the TOC? */
unsigned
int
toc_section
;
/* List of BUG addresses, source line numbers and filenames */
struct
list_head
bug_list
;
struct
bug_entry
*
bug_table
;
unsigned
int
num_bugs
;
};
extern
struct
bug_entry
*
module_find_bug
(
unsigned
long
bugaddr
);
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
#define Elf_Ehdr Elf64_Ehdr
...
...
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