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
Kirill Smelkov
linux
Commits
ec5a5b68
Commit
ec5a5b68
authored
May 16, 2002
by
Anton Blanchard
Browse files
Options
Browse Files
Download
Plain Diff
Merge samba.org:/scratch/anton/linux-2.5
into samba.org:/scratch/anton/linux-2.5_ppc64
parents
5e8a4a7d
93f8230d
Changes
19
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
515 additions
and
562 deletions
+515
-562
arch/ppc64/Makefile
arch/ppc64/Makefile
+2
-1
arch/ppc64/boot/main.c
arch/ppc64/boot/main.c
+1
-1
arch/ppc64/config.in
arch/ppc64/config.in
+9
-0
arch/ppc64/kernel/idle.c
arch/ppc64/kernel/idle.c
+5
-0
arch/ppc64/kernel/ioctl32.c
arch/ppc64/kernel/ioctl32.c
+1
-2
arch/ppc64/kernel/pSeries_htab.c
arch/ppc64/kernel/pSeries_htab.c
+1
-1
arch/ppc64/kernel/pci.c
arch/ppc64/kernel/pci.c
+2
-0
arch/ppc64/kernel/signal.c
arch/ppc64/kernel/signal.c
+68
-165
arch/ppc64/kernel/signal32.c
arch/ppc64/kernel/signal32.c
+180
-281
arch/ppc64/kernel/stab.c
arch/ppc64/kernel/stab.c
+1
-1
arch/ppc64/kernel/traps.c
arch/ppc64/kernel/traps.c
+208
-64
arch/ppc64/mm/fault.c
arch/ppc64/mm/fault.c
+10
-13
arch/ppc64/mm/init.c
arch/ppc64/mm/init.c
+4
-0
include/asm-ppc64/fcntl.h
include/asm-ppc64/fcntl.h
+1
-1
include/asm-ppc64/memory.h
include/asm-ppc64/memory.h
+1
-1
include/asm-ppc64/mmu.h
include/asm-ppc64/mmu.h
+3
-10
include/asm-ppc64/page.h
include/asm-ppc64/page.h
+6
-3
include/asm-ppc64/pgtable.h
include/asm-ppc64/pgtable.h
+10
-18
include/asm-ppc64/thread_info.h
include/asm-ppc64/thread_info.h
+2
-0
No files found.
arch/ppc64/Makefile
View file @
ec5a5b68
...
...
@@ -18,7 +18,8 @@ KERNELLOAD =0xc000000000000000
LINKFLAGS
=
-T
arch
/ppc64/vmlinux.lds
-Bstatic
\
-e
$(KERNELLOAD)
-Ttext
$(KERNELLOAD)
CFLAGS
:=
$(CFLAGS)
-fsigned-char
-msoft-float
-pipe
\
-Wno-uninitialized
-mminimal-toc
-mtraceback
=
full
-Wno-uninitialized
-mminimal-toc
-mtraceback
=
full
\
-Wa
,-mpower4
CPP
=
$(CC)
-E
$(CFLAGS)
...
...
arch/ppc64/boot/main.c
View file @
ec5a5b68
...
...
@@ -153,7 +153,7 @@ make_bi_recs(unsigned long addr)
rec
=
bi_rec_alloc
(
rec
,
2
);
rec
->
tag
=
BI_MACHTYPE
;
rec
->
data
[
0
]
=
_MACH_pSeries
;
rec
->
data
[
0
]
=
PLATFORM_PSERIES
;
rec
->
data
[
1
]
=
1
;
if
(
initrd_size
>
0
)
{
...
...
arch/ppc64/config.in
View file @
ec5a5b68
...
...
@@ -103,8 +103,12 @@ if [ "$CONFIG_SCSI" != "n" ]; then
fi
endmenu
source drivers/message/fusion/Config.in
source drivers/ieee1394/Config.in
source drivers/message/i2o/Config.in
if [ "$CONFIG_NET" = "y" ]; then
mainmenu_option next_comment
comment 'Network device support'
...
...
@@ -181,6 +185,9 @@ if [ "$CONFIG_VIOCD" = "y" ]; then
fi
source drivers/char/Config.in
source drivers/media/Config.in
source fs/Config.in
mainmenu_option next_comment
...
...
@@ -194,6 +201,8 @@ endmenu
source drivers/usb/Config.in
source net/bluetooth/Config.in
mainmenu_option next_comment
comment 'Kernel hacking'
...
...
arch/ppc64/kernel/idle.c
View file @
ec5a5b68
...
...
@@ -146,3 +146,8 @@ int cpu_idle(void)
}
#endif
/* CONFIG_PPC_ISERIES */
void
default_idle
(
void
)
{
barrier
();
}
arch/ppc64/kernel/ioctl32.c
View file @
ec5a5b68
...
...
@@ -3756,6 +3756,7 @@ COMPATIBLE_IOCTL(TCSETSW),
COMPATIBLE_IOCTL
(
TCSETSF
),
COMPATIBLE_IOCTL
(
TIOCLINUX
),
COMPATIBLE_IOCTL
(
TIOCSTART
),
COMPATIBLE_IOCTL
(
TIOCSTOP
),
/* Little t */
COMPATIBLE_IOCTL
(
TIOCGETD
),
COMPATIBLE_IOCTL
(
TIOCSETD
),
...
...
@@ -4336,8 +4337,6 @@ COMPATIBLE_IOCTL(RNDCLEARPOOL),
COMPATIBLE_IOCTL
(
HCIDEVUP
),
COMPATIBLE_IOCTL
(
HCIDEVDOWN
),
COMPATIBLE_IOCTL
(
HCIDEVRESET
),
COMPATIBLE_IOCTL
(
HCIRESETSTAT
),
COMPATIBLE_IOCTL
(
HCIGETINFO
),
COMPATIBLE_IOCTL
(
HCIGETDEVLIST
),
COMPATIBLE_IOCTL
(
HCISETRAW
),
COMPATIBLE_IOCTL
(
HCISETSCAN
),
...
...
arch/ppc64/kernel/pSeries_htab.c
View file @
ec5a5b68
...
...
@@ -359,7 +359,7 @@ static void pSeries_hpte_invalidate(unsigned long slot, unsigned long va,
/* Invalidate the tlb */
if
(
!
large
&&
local
&&
__is_processor
(
PV_POWER4
))
{
_tlbiel
(
va
,
large
);
_tlbiel
(
va
);
}
else
{
spin_lock_irqsave
(
&
pSeries_tlbie_lock
,
flags
);
_tlbie
(
va
,
large
);
...
...
arch/ppc64/kernel/pci.c
View file @
ec5a5b68
...
...
@@ -498,6 +498,8 @@ pcibios_init(void)
}
subsys_initcall
(
pcibios_init
);
int
__init
pcibios_assign_all_busses
(
void
)
{
...
...
arch/ppc64/kernel/signal.c
View file @
ec5a5b68
/*
* linux/arch/ppc64/kernel/signal.c
*
*
*
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
...
...
@@ -108,11 +106,6 @@ long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7,
{
sigset_t
saveset
;
PPCDBG
(
PPCDBG_SYS64X
,
"sys_sigsuspend - running - pid=%ld current=%lx comm=%s
\n
"
,
current
->
pid
,
current
,
current
->
comm
);
mask
&=
_BLOCKABLE
;
spin_lock_irq
(
&
current
->
sigmask_lock
);
saveset
=
current
->
blocked
;
...
...
@@ -142,10 +135,6 @@ long sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int
{
sigset_t
saveset
,
newset
;
PPCDBG
(
PPCDBG_SYS64X
,
"sys_rt_sigsuspend - running - pid=%ld current=%lx comm=%s
\n
"
,
current
->
pid
,
current
,
current
->
comm
);
/* XXX: Don't preclude handling different sized sigset_t's. */
if
(
sigsetsize
!=
sizeof
(
sigset_t
))
return
-
EINVAL
;
...
...
@@ -171,13 +160,9 @@ long sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int
asmlinkage
long
sys_sigaltstack
(
const
stack_t
*
uss
,
stack_t
*
uoss
)
long
sys_sigaltstack
(
const
stack_t
*
uss
,
stack_t
*
uoss
)
{
struct
pt_regs
*
regs
=
(
struct
pt_regs
*
)
&
uss
;
PPCDBG
(
PPCDBG_SYS64X
,
"sys_sigaltstack - running - pid=%ld current=%lx comm=%s
\n
"
,
current
->
pid
,
current
,
current
->
comm
);
return
do_sigaltstack
(
uss
,
uoss
,
regs
->
gpr
[
1
]);
}
...
...
@@ -187,11 +172,6 @@ long sys_sigaction(int sig, const struct old_sigaction *act,
struct
k_sigaction
new_ka
,
old_ka
;
int
ret
;
PPCDBG
(
PPCDBG_SYS64X
,
"sys_sigaction - running - pid=%ld current=%lx comm=%s
\n
"
,
current
->
pid
,
current
,
current
->
comm
);
if
(
act
)
{
old_sigset_t
mask
;
if
(
verify_area
(
VERIFY_READ
,
act
,
sizeof
(
*
act
))
||
...
...
@@ -203,7 +183,7 @@ long sys_sigaction(int sig, const struct old_sigaction *act,
siginitset
(
&
new_ka
.
sa
.
sa_mask
,
mask
);
}
ret
=
do_sigaction
(
sig
,
act
?
&
new_ka
:
NULL
,
oact
?
&
old_ka
:
NULL
);
ret
=
do_sigaction
(
sig
,
(
act
?
&
new_ka
:
NULL
),
(
oact
?
&
old_ka
:
NULL
)
);
if
(
!
ret
&&
oact
)
{
if
(
verify_area
(
VERIFY_WRITE
,
oact
,
sizeof
(
*
oact
))
||
...
...
@@ -214,9 +194,6 @@ long sys_sigaction(int sig, const struct old_sigaction *act,
__put_user
(
old_ka
.
sa
.
sa_mask
.
sig
[
0
],
&
oact
->
sa_mask
);
}
return
ret
;
}
...
...
@@ -224,13 +201,11 @@ long sys_sigaction(int sig, const struct old_sigaction *act,
* When we have signals to deliver, we set up on the
* user stack, going down from the original stack pointer:
* a sigregs struct
* one or more sigcontext structs
* one or more sigcontext structs
with
* a gap of __SIGNAL_FRAMESIZE bytes
*
* Each of these things must be a multiple of 16 bytes in size.
*
* XXX ultimately we will have to stack up a siginfo and ucontext
* for each rt signal.
*/
struct
sigregs
{
elf_gregset_t
gp_regs
;
...
...
@@ -241,8 +216,6 @@ struct sigregs {
int
abigap
[
72
];
};
struct
rt_sigframe
{
unsigned
long
_unused
[
2
];
...
...
@@ -271,7 +244,6 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
struct
rt_sigframe
*
rt_sf
;
struct
sigcontext_struct
sigctx
;
struct
sigregs
*
sr
;
int
ret
;
elf_gregset_t
saved_regs
;
/* an array of ELF_NGREG unsigned longs */
sigset_t
set
;
stack_t
st
;
...
...
@@ -287,19 +259,16 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
current
->
blocked
=
set
;
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sigmask_lock
);
if
(
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
current
);
rt_sf
++
;
/* Look at next rt_sigframe */
if
(
rt_sf
==
(
struct
rt_sigframe
*
)(
sigctx
.
regs
))
{
/* Last stacked signal - restore registers -
/* restore registers -
* sigctx is initialized to point to the
* preamble frame (where registers are stored)
* see handle_signal()
*/
sr
=
(
struct
sigregs
*
)
sigctx
.
regs
;
if
(
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
current
);
if
(
copy_from_user
(
saved_regs
,
&
sr
->
gp_regs
,
sizeof
(
sr
->
gp_regs
)))
if
(
copy_from_user
(
saved_regs
,
&
sr
->
gp_regs
,
sizeof
(
sr
->
gp_regs
)))
goto
badframe
;
saved_regs
[
PT_MSR
]
=
(
regs
->
msr
&
~
MSR_USERCHANGE
)
|
(
saved_regs
[
PT_MSR
]
&
MSR_USERCHANGE
);
...
...
@@ -312,28 +281,7 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
the current task structure. */
sys_sigaltstack
(
&
st
,
NULL
);
ret
=
regs
->
result
;
}
else
{
/* More signals to go */
/* Set up registers for next signal handler */
regs
->
gpr
[
1
]
=
(
unsigned
long
)
rt_sf
-
__SIGNAL_FRAMESIZE
;
if
(
copy_from_user
(
&
sigctx
,
&
rt_sf
->
uc
.
uc_mcontext
,
sizeof
(
sigctx
)))
goto
badframe
;
sr
=
(
struct
sigregs
*
)
sigctx
.
regs
;
regs
->
gpr
[
3
]
=
ret
=
sigctx
.
signal
;
/* Get the siginfo */
get_user
(
regs
->
gpr
[
4
],
(
unsigned
long
*
)
&
rt_sf
->
pinfo
);
/* Get the ucontext */
get_user
(
regs
->
gpr
[
5
],
(
unsigned
long
*
)
&
rt_sf
->
puc
);
regs
->
gpr
[
6
]
=
(
unsigned
long
)
rt_sf
;
regs
->
link
=
(
unsigned
long
)
&
sr
->
tramp
;
regs
->
nip
=
sigctx
.
handler
;
if
(
get_user
(
prevsp
,
&
sr
->
gp_regs
[
PT_R1
])
||
put_user
(
prevsp
,
(
unsigned
long
*
)
regs
->
gpr
[
1
]))
goto
badframe
;
}
return
ret
;
return
regs
->
result
;
badframe:
do_exit
(
SIGSEGV
);
...
...
@@ -370,6 +318,7 @@ setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
goto
badframe
;
flush_icache_range
((
unsigned
long
)
&
frame
->
tramp
[
0
],
(
unsigned
long
)
&
frame
->
tramp
[
2
]);
current
->
thread
.
fpscr
=
0
;
/* turn off all fp exceptions */
/* Retrieve rt_sigframe from stack and
set up registers for signal handler
...
...
@@ -394,7 +343,6 @@ setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
regs
->
gpr
[
6
]
=
(
unsigned
long
)
rt_sf
;
regs
->
link
=
(
unsigned
long
)
frame
->
tramp
;
return
;
badframe:
...
...
@@ -414,7 +362,6 @@ long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
{
struct
sigcontext_struct
*
sc
,
sigctx
;
struct
sigregs
*
sr
;
long
ret
;
elf_gregset_t
saved_regs
;
/* an array of ELF_NGREG unsigned longs */
sigset_t
set
;
unsigned
long
prevsp
;
...
...
@@ -432,15 +379,12 @@ long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
current
->
blocked
=
set
;
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sigmask_lock
);
sc
++
;
/* Look at next sigcontext */
if
(
sc
==
(
struct
sigcontext_struct
*
)(
sigctx
.
regs
))
{
/* Last stacked signal - restore registers */
sr
=
(
struct
sigregs
*
)
sigctx
.
regs
;
if
(
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
current
);
if
(
copy_from_user
(
saved_regs
,
&
sr
->
gp_regs
,
sizeof
(
sr
->
gp_regs
)))
/* restore registers */
sr
=
(
struct
sigregs
*
)
sigctx
.
regs
;
if
(
copy_from_user
(
saved_regs
,
&
sr
->
gp_regs
,
sizeof
(
sr
->
gp_regs
)))
goto
badframe
;
saved_regs
[
PT_MSR
]
=
(
regs
->
msr
&
~
MSR_USERCHANGE
)
|
(
saved_regs
[
PT_MSR
]
&
MSR_USERCHANGE
);
...
...
@@ -451,24 +395,7 @@ long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
sizeof
(
sr
->
fp_regs
)))
goto
badframe
;
ret
=
regs
->
result
;
}
else
{
/* More signals to go */
regs
->
gpr
[
1
]
=
(
unsigned
long
)
sc
-
__SIGNAL_FRAMESIZE
;
if
(
copy_from_user
(
&
sigctx
,
sc
,
sizeof
(
sigctx
)))
goto
badframe
;
sr
=
(
struct
sigregs
*
)
sigctx
.
regs
;
regs
->
gpr
[
3
]
=
ret
=
sigctx
.
signal
;
regs
->
gpr
[
4
]
=
(
unsigned
long
)
sc
;
regs
->
link
=
(
unsigned
long
)
&
sr
->
tramp
;
regs
->
nip
=
sigctx
.
handler
;
if
(
get_user
(
prevsp
,
&
sr
->
gp_regs
[
PT_R1
])
||
put_user
(
prevsp
,
(
unsigned
long
*
)
regs
->
gpr
[
1
]))
goto
badframe
;
}
return
ret
;
return
regs
->
result
;
badframe:
do_exit
(
SIGSEGV
);
...
...
@@ -509,6 +436,7 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame,
goto
badframe
;
flush_icache_range
((
unsigned
long
)
&
frame
->
tramp
[
0
],
(
unsigned
long
)
&
frame
->
tramp
[
2
]);
current
->
thread
.
fpscr
=
0
;
/* turn off all fp exceptions */
newsp
-=
__SIGNAL_FRAMESIZE
;
if
(
get_user
(
temp_ptr
,
&
sc
->
handler
))
...
...
@@ -525,14 +453,9 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame,
regs
->
gpr
[
4
]
=
(
unsigned
long
)
sc
;
regs
->
link
=
(
unsigned
long
)
frame
->
tramp
;
PPCDBG
(
PPCDBG_SIGNAL
,
"setup_frame - returning - regs->gpr[1]=%lx, regs->gpr[4]=%lx, regs->link=%lx
\n
"
,
regs
->
gpr
[
1
],
regs
->
gpr
[
4
],
regs
->
link
);
return
;
badframe:
PPCDBG
(
PPCDBG_SIGNAL
,
"setup_frame - badframe in setup_frame, regs=%p frame=%p newsp=%lx
\n
"
,
regs
,
frame
,
newsp
);
PPCDBG_ENTER_DEBUGGER
();
badframe:
#if DEBUG_SIG
printk
(
"badframe in setup_frame, regs=%p frame=%p newsp=%lx
\n
"
,
regs
,
frame
,
newsp
);
...
...
@@ -556,8 +479,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
((
int
)
regs
->
result
==
-
ERESTARTSYS
&&
!
(
ka
->
sa
.
sa_flags
&
SA_RESTART
))))
regs
->
result
=
-
EINTR
;
/* Set up Signal Frame */
/* Set up Signal Frame */
if
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
{
/* Put a Real Time Context onto stack */
*
newspp
-=
sizeof
(
*
rt_sf
);
...
...
@@ -565,7 +488,6 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
if
(
verify_area
(
VERIFY_WRITE
,
rt_sf
,
sizeof
(
*
rt_sf
)))
goto
badframe
;
if
(
__put_user
((
unsigned
long
)
ka
->
sa
.
sa_handler
,
&
rt_sf
->
uc
.
uc_mcontext
.
handler
)
||
__put_user
(
&
rt_sf
->
info
,
&
rt_sf
->
pinfo
)
||
__put_user
(
&
rt_sf
->
uc
,
&
rt_sf
->
puc
)
...
...
@@ -583,9 +505,8 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
||
__put_user
((
struct
pt_regs
*
)
frame
,
&
rt_sf
->
uc
.
uc_mcontext
.
regs
)
||
__put_user
(
sig
,
&
rt_sf
->
uc
.
uc_mcontext
.
signal
))
goto
badframe
;
}
else
{
/* Put another
sigcontext on the stack */
/* Put a
sigcontext on the stack */
*
newspp
-=
sizeof
(
*
sc
);
sc
=
(
struct
sigcontext_struct
*
)
*
newspp
;
if
(
verify_area
(
VERIFY_WRITE
,
sc
,
sizeof
(
*
sc
)))
...
...
@@ -649,11 +570,9 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
for
(;;)
{
unsigned
long
signr
;
PPCDBG
(
PPCDBG_SIGNAL
,
"do_signal - (pre) dequeueing signal - pid=%ld current=%lx comm=%s
\n
"
,
current
->
pid
,
current
,
current
->
comm
);
spin_lock_irq
(
&
current
->
sigmask_lock
);
signr
=
dequeue_signal
(
&
current
->
blocked
,
&
info
);
spin_unlock_irq
(
&
current
->
sigmask_lock
);
PPCDBG
(
PPCDBG_SIGNAL
,
"do_signal - (aft) dequeueing signal - signal=%lx - pid=%ld current=%lx comm=%s
\n
"
,
signr
,
current
->
pid
,
current
,
current
->
comm
);
if
(
!
signr
)
break
;
...
...
@@ -691,12 +610,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
}
ka
=
&
current
->
sig
->
action
[
signr
-
1
];
PPCDBG
(
PPCDBG_SIGNAL
,
"do_signal - ka=%p, action handler=%lx
\n
"
,
ka
,
ka
->
sa
.
sa_handler
);
if
(
ka
->
sa
.
sa_handler
==
SIG_IGN
)
{
PPCDBG
(
PPCDBG_SIGNAL
,
"do_signal - into SIG_IGN logic
\n
"
);
if
(
signr
!=
SIGCHLD
)
continue
;
/* Check for SIGCHLD: it's special. */
...
...
@@ -707,14 +621,13 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
if
(
ka
->
sa
.
sa_handler
==
SIG_DFL
)
{
int
exit_code
=
signr
;
PPCDBG
(
PPCDBG_SIGNAL
,
"do_signal - into SIG_DFL logic
\n
"
);
/* Init gets no signals it doesn't want. */
if
(
current
->
pid
==
1
)
continue
;
switch
(
signr
)
{
case
SIGCONT
:
case
SIGCHLD
:
case
SIGWINCH
:
case
SIGCONT
:
case
SIGCHLD
:
case
SIGWINCH
:
case
SIGURG
:
continue
;
case
SIGTSTP
:
case
SIGTTIN
:
case
SIGTTOU
:
...
...
@@ -751,10 +664,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
newsp
=
frame
=
newsp
-
sizeof
(
struct
sigregs
);
/* Whee! Actually deliver the signal. */
PPCDBG
(
PPCDBG_SIGNAL
,
"do_signal - GOING TO RUN SIGNAL HANDLER - pid=%ld current=%lx comm=%s
\n
"
,
current
->
pid
,
current
,
current
->
comm
);
handle_signal
(
signr
,
ka
,
&
info
,
oldset
,
regs
,
&
newsp
,
frame
);
PPCDBG
(
PPCDBG_SIGNAL
,
"do_signal - after running signal handler - pid=%ld current=%lx comm=%s
\n
"
,
current
->
pid
,
current
,
current
->
comm
);
break
;
}
...
...
@@ -762,24 +672,17 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
((
int
)
regs
->
result
==
-
ERESTARTNOHAND
||
(
int
)
regs
->
result
==
-
ERESTARTSYS
||
(
int
)
regs
->
result
==
-
ERESTARTNOINTR
))
{
PPCDBG
(
PPCDBG_SIGNAL
,
"do_signal - going to back up & retry system call
\n
"
);
regs
->
gpr
[
3
]
=
regs
->
orig_gpr3
;
regs
->
nip
-=
4
;
/* Back up & retry system call */
regs
->
result
=
0
;
}
if
(
newsp
==
frame
)
{
PPCDBG
(
PPCDBG_SIGNAL
,
"do_signal - returning w/ no signal delivered
\n
"
);
return
0
;
/* no signals delivered */
}
if
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
setup_rt_frame
(
regs
,
(
struct
sigregs
*
)
frame
,
newsp
);
else
setup_frame
(
regs
,
(
struct
sigregs
*
)
frame
,
newsp
);
PPCDBG
(
PPCDBG_SIGNAL
,
"do_signal - returning a signal was delivered
\n
"
);
return
1
;
}
arch/ppc64/kernel/signal32.c
View file @
ec5a5b68
...
...
@@ -136,8 +136,6 @@ asmlinkage long sys32_sigaction(int sig, struct old_sigaction32 *act, struct old
struct
k_sigaction
new_ka
,
old_ka
;
int
ret
;
PPCDBG
(
PPCDBG_SYS32
,
"sys32_sigaction - entered - pid=%ld current=%lx comm=%s
\n
"
,
current
->
pid
,
current
,
current
->
comm
);
if
(
sig
<
0
)
{
sig
=
-
sig
;
...
...
@@ -153,12 +151,11 @@ asmlinkage long sys32_sigaction(int sig, struct old_sigaction32 *act, struct old
ret
|=
__get_user
(
mask
,
&
act
->
sa_mask
);
if
(
ret
)
return
ret
;
PPCDBG
(
PPCDBG_SIGNAL
,
"sys32_sigaction flags =%lx
\n
"
,
new_ka
.
sa
.
sa_flags
);
siginitset
(
&
new_ka
.
sa
.
sa_mask
,
mask
);
}
ret
=
do_sigaction
(
sig
,
act
?
&
new_ka
:
NULL
,
oact
?
&
old_ka
:
NULL
);
ret
=
do_sigaction
(
sig
,
(
act
?
&
new_ka
:
NULL
),
(
oact
?
&
old_ka
:
NULL
)
);
if
(
!
ret
&&
oact
)
{
...
...
@@ -168,9 +165,6 @@ asmlinkage long sys32_sigaction(int sig, struct old_sigaction32 *act, struct old
ret
|=
__put_user
(
old_ka
.
sa
.
sa_mask
.
sig
[
0
],
&
oact
->
sa_mask
);
}
PPCDBG
(
PPCDBG_SYS32
,
"sys32_sigaction - exited - pid=%ld current=%lx comm=%s
\n
"
,
current
->
pid
,
current
,
current
->
comm
);
return
ret
;
}
...
...
@@ -185,15 +179,11 @@ asmlinkage long sys32_sigpending(old_sigset_t32 *set)
int
ret
;
mm_segment_t
old_fs
=
get_fs
();
PPCDBG
(
PPCDBG_SYS32
,
"sys32_sigpending - entered - pid=%ld current=%lx comm=%s
\n
"
,
current
->
pid
,
current
,
current
->
comm
);
set_fs
(
KERNEL_DS
);
ret
=
sys_sigpending
(
&
s
);
set_fs
(
old_fs
);
if
(
put_user
(
s
,
set
))
return
-
EFAULT
;
PPCDBG
(
PPCDBG_SYS32
,
"sys32_sigpending - exited - pid=%ld current=%lx comm=%s
\n
"
,
current
->
pid
,
current
,
current
->
comm
);
return
ret
;
}
...
...
@@ -213,8 +203,6 @@ asmlinkage long sys32_sigprocmask(u32 how, old_sigset_t32 *set, old_sigset_t32 *
int
ret
;
mm_segment_t
old_fs
=
get_fs
();
PPCDBG
(
PPCDBG_SYS32
,
"sys32_sigprocmask - entered - pid=%ld current=%lx comm=%s
\n
"
,
current
->
pid
,
current
,
current
->
comm
);
if
(
set
&&
get_user
(
s
,
set
))
return
-
EFAULT
;
set_fs
(
KERNEL_DS
);
ret
=
sys_sigprocmask
((
int
)
how
,
set
?
&
s
:
NULL
,
oset
?
&
s
:
NULL
);
...
...
@@ -222,8 +210,6 @@ asmlinkage long sys32_sigprocmask(u32 how, old_sigset_t32 *set, old_sigset_t32 *
if
(
ret
)
return
ret
;
if
(
oset
&&
put_user
(
s
,
oset
))
return
-
EFAULT
;
PPCDBG
(
PPCDBG_SYS32
,
"sys32_sigprocmask - exited - pid=%ld current=%lx comm=%s
\n
"
,
current
->
pid
,
current
,
current
->
comm
);
return
0
;
}
...
...
@@ -255,8 +241,6 @@ long sys32_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
sigset_t
set
;
unsigned
int
prevsp
;
PPCDBG
(
PPCDBG_SIGNAL
,
"sys32_sigreturn - entered - pid=%ld current=%lx comm=%s
\n
"
,
current
->
pid
,
current
,
current
->
comm
);
sc
=
(
struct
sigcontext32_struct
*
)(
regs
->
gpr
[
1
]
+
__SIGNAL_FRAMESIZE32
);
if
(
copy_from_user
(
&
sigctx
,
sc
,
sizeof
(
sigctx
)))
goto
badframe
;
...
...
@@ -270,11 +254,6 @@ long sys32_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sigmask_lock
);
sc
++
;
/* Look at next sigcontext */
/* If the next sigcontext is actually the sigregs (frame) */
/* - then no more sigcontexts on the user stack */
if
(
sc
==
(
struct
sigcontext32_struct
*
)(
u64
)
sigctx
.
regs
)
{
/* Last stacked signal - restore registers */
sr
=
(
struct
sigregs32
*
)(
u64
)
sigctx
.
regs
;
if
(
regs
->
msr
&
MSR_FP
)
...
...
@@ -365,27 +344,9 @@ long sys32_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
goto
badframe
;
ret
=
regs
->
result
;
}
else
{
/* More signals to go */
regs
->
gpr
[
1
]
=
(
unsigned
long
)
sc
-
__SIGNAL_FRAMESIZE32
;
if
(
copy_from_user
(
&
sigctx
,
sc
,
sizeof
(
sigctx
)))
goto
badframe
;
sr
=
(
struct
sigregs32
*
)(
u64
)
sigctx
.
regs
;
regs
->
gpr
[
3
]
=
ret
=
sigctx
.
signal
;
regs
->
gpr
[
4
]
=
(
unsigned
long
)
sc
;
regs
->
link
=
(
unsigned
long
)
&
sr
->
tramp
;
regs
->
nip
=
sigctx
.
handler
;
if
(
get_user
(
prevsp
,
&
sr
->
gp_regs
[
PT_R1
])
||
put_user
(
prevsp
,
(
unsigned
int
*
)
regs
->
gpr
[
1
]))
goto
badframe
;
}
PPCDBG
(
PPCDBG_SIGNAL
,
"sys32_sigreturn - normal exit returning %ld - pid=%ld current=%lx comm=%s
\n
"
,
ret
,
current
->
pid
,
current
,
current
->
comm
);
return
ret
;
badframe:
PPCDBG
(
PPCDBG_SYS32NI
,
"sys32_sigreturn - badframe - pid=%ld current=%lx comm=%s
\n
"
,
current
->
pid
,
current
,
current
->
comm
);
do_exit
(
SIGSEGV
);
}
...
...
@@ -487,6 +448,7 @@ setup_frame32(struct pt_regs *regs, struct sigregs32 *frame,
flush_icache_range
((
unsigned
long
)
&
frame
->
tramp
[
0
],
(
unsigned
long
)
&
frame
->
tramp
[
2
]);
current
->
thread
.
fpscr
=
0
;
/* turn off all fp exceptions */
newsp
-=
__SIGNAL_FRAMESIZE32
;
if
(
put_user
(
regs
->
gpr
[
1
],
(
u32
*
)(
u64
)
newsp
)
...
...
@@ -505,8 +467,7 @@ setup_frame32(struct pt_regs *regs, struct sigregs32 *frame,
regs
->
link
=
(
unsigned
long
)
frame
->
tramp
;
return
;
badframe:
udbg_printf
(
"setup_frame32 - badframe in setup_frame, regs=%p frame=%p newsp=%lx
\n
"
,
regs
,
frame
,
newsp
);
PPCDBG_ENTER_DEBUGGER
();
badframe:
#if DEBUG_SIG
printk
(
"badframe in setup_frame32, regs=%p frame=%p newsp=%lx
\n
"
,
regs
,
frame
,
newsp
);
...
...
@@ -552,7 +513,6 @@ long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
elf_gregset_t32
saved_regs
;
/* an array of 32 bit register values */
sigset_t
signal_set
;
stack_t
stack
;
unsigned
int
previous_stack
;
ret
=
0
;
/* Adjust the inputted reg1 to point to the first rt signal frame */
...
...
@@ -581,10 +541,6 @@ long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
/* Set to point to the next rt_sigframe - this is used to determine whether this
* is the last signal to process
*/
rt_stack_frame
++
;
if
(
rt_stack_frame
==
(
struct
rt_sigframe_32
*
)(
u64
)(
sigctx
.
regs
))
{
signalregs
=
(
struct
sigregs32
*
)
(
u64
)
sigctx
.
regs
;
/* If currently owning the floating point - give them up */
if
(
regs
->
msr
&
MSR_FP
)
...
...
@@ -669,37 +625,6 @@ long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
regs
->
dsisr
=
0
;
regs
->
result
=
(
u64
)(
saved_regs
[
PT_RESULT
])
&
0xFFFFFFFF
;
ret
=
regs
->
result
;
}
else
/* more signals to go */
{
udbg_printf
(
"hey should not occur
\n
"
);
regs
->
gpr
[
1
]
=
(
u64
)
rt_stack_frame
-
__SIGNAL_FRAMESIZE32
;
if
(
copy_from_user
(
&
sigctx
,
&
rt_stack_frame
->
uc
.
uc_mcontext
,
sizeof
(
sigctx
)))
{
goto
badframe
;
}
signalregs
=
(
struct
sigregs32
*
)
(
u64
)
sigctx
.
regs
;
/* first parm to signal handler is the signal number */
regs
->
gpr
[
3
]
=
ret
=
sigctx
.
signal
;
/* second parm is a pointer to sig info */
get_user
(
regs
->
gpr
[
4
],
&
rt_stack_frame
->
pinfo
);
/* third parm is a pointer to the ucontext */
get_user
(
regs
->
gpr
[
5
],
&
rt_stack_frame
->
puc
);
/* fourth parm is the stack frame */
regs
->
gpr
[
6
]
=
(
u64
)
rt_stack_frame
;
/* Set up link register to return to sigreturn when the */
/* signal handler completes */
regs
->
link
=
(
u64
)
&
signalregs
->
tramp
;
/* Set next instruction to the start fo the signal handler */
regs
->
nip
=
sigctx
.
handler
;
/* Set the reg1 to look like a call to the signal handler */
if
(
get_user
(
previous_stack
,
&
signalregs
->
gp_regs
[
PT_R1
])
||
put_user
(
previous_stack
,
(
unsigned
long
*
)
regs
->
gpr
[
1
]))
{
goto
badframe
;
}
}
return
ret
;
...
...
@@ -715,8 +640,6 @@ asmlinkage long sys32_rt_sigaction(int sig, const struct sigaction32 *act, struc
int
ret
;
sigset32_t
set32
;
PPCDBG
(
PPCDBG_SIGNAL
,
"sys32_rt_sigaction - entered - sig=%x
\n
"
,
sig
);
/* XXX: Don't preclude handling different sized sigset_t's. */
if
(
sigsetsize
!=
sizeof
(
sigset32_t
))
return
-
EINVAL
;
...
...
@@ -765,8 +688,6 @@ asmlinkage long sys32_rt_sigaction(int sig, const struct sigaction32 *act, struc
ret
|=
__put_user
(
old_ka
.
sa
.
sa_flags
,
&
oact
->
sa_flags
);
}
PPCDBG
(
PPCDBG_SIGNAL
,
"sys32_rt_sigaction - exiting - sig=%x
\n
"
,
sig
);
return
ret
;
}
...
...
@@ -786,8 +707,6 @@ asmlinkage long sys32_rt_sigprocmask(u32 how, sigset32_t *set, sigset32_t *oset,
int
ret
;
mm_segment_t
old_fs
=
get_fs
();
PPCDBG
(
PPCDBG_SIGNAL
,
"sys32_rt_sigprocmask - entered how=%x
\n
"
,
(
int
)
how
);
if
(
set
)
{
if
(
copy_from_user
(
&
s32
,
set
,
sizeof
(
sigset32_t
)))
return
-
EFAULT
;
...
...
@@ -1145,6 +1064,7 @@ setup_rt_frame32(struct pt_regs *regs, struct sigregs32 *frame,
flush_icache_range
((
unsigned
long
)
&
frame
->
tramp
[
0
],
(
unsigned
long
)
&
frame
->
tramp
[
2
]);
current
->
thread
.
fpscr
=
0
;
/* turn off all fp exceptions */
/* Retrieve rt_sigframe from stack and
...
...
@@ -1172,9 +1092,7 @@ setup_rt_frame32(struct pt_regs *regs, struct sigregs32 *frame,
return
;
badframe:
udbg_printf
(
"setup_frame32 - badframe in setup_frame, regs=%p frame=%p newsp=%lx
\n
"
,
regs
,
frame
,
newsp
);
PPCDBG_ENTER_DEBUGGER
();
badframe:
#if DEBUG_SIG
printk
(
"badframe in setup_frame32, regs=%p frame=%p newsp=%lx
\n
"
,
regs
,
frame
,
newsp
);
...
...
@@ -1182,7 +1100,6 @@ setup_rt_frame32(struct pt_regs *regs, struct sigregs32 *frame,
do_exit
(
SIGSEGV
);
}
/*
* OK, we're invoking a handler
*/
...
...
@@ -1259,7 +1176,6 @@ handle_signal32(unsigned long sig, struct k_sigaction *ka,
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sigmask_lock
);
}
return
;
badframe:
...
...
@@ -1349,10 +1265,6 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
spin_lock_irq
(
&
current
->
sigmask_lock
);
signr
=
dequeue_signal
(
&
current
->
blocked
,
&
info
);
spin_unlock_irq
(
&
current
->
sigmask_lock
);
ifppcdebug
(
PPCDBG_SYS32
)
{
if
(
signr
)
udbg_printf
(
"do_signal32 - processing signal=%2lx - pid=%ld, comm=%s
\n
"
,
signr
,
current
->
pid
,
current
->
comm
);
}
if
(
!
signr
)
break
;
...
...
@@ -1390,7 +1302,6 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
}
ka
=
&
current
->
sig
->
action
[
signr
-
1
];
if
(
ka
->
sa
.
sa_handler
==
SIG_IGN
)
{
if
(
signr
!=
SIGCHLD
)
continue
;
...
...
@@ -1408,7 +1319,7 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
continue
;
switch
(
signr
)
{
case
SIGCONT
:
case
SIGCHLD
:
case
SIGWINCH
:
case
SIGCONT
:
case
SIGCHLD
:
case
SIGWINCH
:
case
SIGURG
:
continue
;
case
SIGTSTP
:
case
SIGTTIN
:
case
SIGTTOU
:
...
...
@@ -1437,19 +1348,10 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
}
}
PPCDBG
(
PPCDBG_SIGNAL
,
" do signal :sigaction flags = %lx
\n
"
,
ka
->
sa
.
sa_flags
);
PPCDBG
(
PPCDBG_SIGNAL
,
" do signal :on sig stack = %lx
\n
"
,
on_sig_stack
(
regs
->
gpr
[
1
]));
PPCDBG
(
PPCDBG_SIGNAL
,
" do signal :reg1 = %lx
\n
"
,
regs
->
gpr
[
1
]);
PPCDBG
(
PPCDBG_SIGNAL
,
" do signal :alt stack = %lx
\n
"
,
current
->
sas_ss_sp
);
PPCDBG
(
PPCDBG_SIGNAL
,
" do signal :alt stack size = %lx
\n
"
,
current
->
sas_ss_size
);
if
(
(
ka
->
sa
.
sa_flags
&
SA_ONSTACK
)
&&
(
!
on_sig_stack
(
regs
->
gpr
[
1
])))
{
newsp
=
(
current
->
sas_ss_sp
+
current
->
sas_ss_size
);
}
else
else
newsp
=
regs
->
gpr
[
1
];
newsp
=
frame
=
newsp
-
sizeof
(
struct
sigregs32
);
...
...
@@ -1468,15 +1370,12 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
}
if
(
newsp
==
frame
)
{
return
0
;
/* no signals delivered */
}
/
/ Invoke correct stack setup routine
/
* Invoke correct stack setup routine */
if
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
setup_rt_frame32
(
regs
,
(
struct
sigregs32
*
)(
u64
)
frame
,
newsp
);
else
setup_frame32
(
regs
,
(
struct
sigregs32
*
)(
u64
)
frame
,
newsp
);
return
1
;
}
arch/ppc64/kernel/stab.c
View file @
ec5a5b68
...
...
@@ -22,7 +22,7 @@ int make_ste(unsigned long stab,
unsigned
long
esid
,
unsigned
long
vsid
);
void
make_slbe
(
unsigned
long
esid
,
unsigned
long
vsid
,
int
large
);
extern
struct
Naca
*
naca
;
extern
struct
naca_struct
*
naca
;
/*
* Build an entry for the base kernel segment and put it into
...
...
arch/ppc64/kernel/traps.c
View file @
ec5a5b68
...
...
@@ -53,6 +53,7 @@ extern void (*xmon_fault_handler)(struct pt_regs *regs);
#endif
#ifdef CONFIG_XMON
#define CONFIG_DEBUGGER
void
(
*
debugger
)(
struct
pt_regs
*
regs
)
=
xmon
;
int
(
*
debugger_bpt
)(
struct
pt_regs
*
regs
)
=
xmon_bpt
;
int
(
*
debugger_sstep
)(
struct
pt_regs
*
regs
)
=
xmon_sstep
;
...
...
@@ -61,6 +62,7 @@ int (*debugger_dabr_match)(struct pt_regs *regs) = xmon_dabr_match;
void
(
*
debugger_fault_handler
)(
struct
pt_regs
*
regs
);
#else
#ifdef CONFIG_KGDB
#define CONFIG_DEBUGGER
void
(
*
debugger
)(
struct
pt_regs
*
regs
);
int
(
*
debugger_bpt
)(
struct
pt_regs
*
regs
);
int
(
*
debugger_sstep
)(
struct
pt_regs
*
regs
);
...
...
@@ -69,29 +71,46 @@ int (*debugger_dabr_match)(struct pt_regs *regs);
void
(
*
debugger_fault_handler
)(
struct
pt_regs
*
regs
);
#endif
#endif
/*
* Trap & Exception support
*/
void
_exception
(
int
signr
,
struct
pt_regs
*
regs
)
/* Should we panic on bad kernel exceptions or try to recover */
#undef PANIC_ON_ERROR
static
spinlock_t
die_lock
=
SPIN_LOCK_UNLOCKED
;
void
die
(
const
char
*
str
,
struct
pt_regs
*
regs
,
long
err
)
{
if
(
!
user_mode
(
regs
))
{
console_verbose
();
spin_lock_irq
(
&
die_lock
);
bust_spinlocks
(
1
);
printk
(
"Oops: %s, sig: %ld
\n
"
,
str
,
err
);
show_regs
(
regs
);
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
debugger
(
regs
);
#endif
print_backtrace
((
unsigned
long
*
)
regs
->
gpr
[
1
]);
panic
(
"Exception in kernel pc %lx signal %d"
,
regs
->
nip
,
signr
);
#if defined(CONFIG_PPCDBG) && (defined(CONFIG_XMON) || defined(CONFIG_KGDB))
/* Allow us to catch SIGILLs for 64-bit app/glibc debugging. -Peter */
}
else
if
(
signr
==
SIGILL
)
{
ifppcdebug
(
PPCDBG_SIGNALXMON
)
bust_spinlocks
(
0
);
spin_unlock_irq
(
&
die_lock
);
#ifdef PANIC_ON_ERROR
panic
(
str
);
#else
do_exit
(
SIGSEGV
);
#endif
}
static
void
_exception
(
int
signr
,
siginfo_t
*
info
,
struct
pt_regs
*
regs
)
{
if
(
!
user_mode
(
regs
))
{
#ifdef CONFIG_DEBUGGER
if
(
debugger
)
debugger
(
regs
);
#endif
die
(
"Exception in kernel mode
\n
"
,
regs
,
signr
);
}
force_sig
(
signr
,
current
);
force_sig_info
(
signr
,
info
,
current
);
}
/* Get the error information for errors coming through the
...
...
@@ -130,9 +149,8 @@ static void FWNMI_release_errinfo(void)
void
SystemResetException
(
struct
pt_regs
*
regs
)
{
char
*
msg
=
"System Reset in kernel mode.
\n
"
;
udbg_printf
(
msg
);
printk
(
msg
);
if
(
fwnmi_active
)
{
char
*
msg
;
unsigned
long
*
r3
=
__va
(
regs
->
gpr
[
3
]);
/* for FWNMI debug */
struct
rtas_error_log
*
errlog
;
...
...
@@ -140,17 +158,33 @@ SystemResetException(struct pt_regs *regs)
udbg_printf
(
msg
,
r3
);
printk
(
msg
,
r3
);
errlog
=
FWNMI_get_errinfo
(
regs
);
}
#if defined(CONFIG_XMON)
xmon
(
regs
);
udbg_printf
(
"leaving xmon...
\n
"
);
#ifdef CONFIG_DEBUGGER
if
(
debugger
)
debugger
(
regs
);
#endif
#ifdef PANIC_ON_ERROR
panic
(
"System Reset"
);
#else
for
(;;);
/* Must die if the interrupt is not recoverable */
if
(
!
(
regs
->
msr
&
MSR_RI
))
panic
(
"Unrecoverable System Reset"
);
#endif
/* What should we do here? We could issue a shutdown or hard reset. */
}
static
int
power4_handle_mce
(
struct
pt_regs
*
regs
)
{
return
0
;
}
void
MachineCheckException
(
struct
pt_regs
*
regs
)
{
siginfo_t
info
;
if
(
fwnmi_active
)
{
struct
rtas_error_log
*
errhdr
=
FWNMI_get_errinfo
(
regs
);
if
(
errhdr
)
{
...
...
@@ -158,117 +192,227 @@ MachineCheckException(struct pt_regs *regs)
}
FWNMI_release_errinfo
();
}
if
(
!
user_mode
(
regs
)
)
{
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
if
(
!
user_mode
(
regs
))
{
/* Attempt to recover if the interrupt is recoverable */
if
(
regs
->
msr
&
MSR_RI
)
{
if
(
__is_processor
(
PV_POWER4
)
&&
power4_handle_mce
(
regs
))
return
;
}
#ifdef CONFIG_DEBUGGER
if
(
debugger_fault_handler
)
{
debugger_fault_handler
(
regs
);
return
;
}
if
(
debugger
)
debugger
(
regs
);
#endif
console_verbose
();
spin_lock_irq
(
&
die_lock
);
bust_spinlocks
(
1
);
printk
(
"Machine check in kernel mode.
\n
"
);
printk
(
"Caused by (from SRR1=%lx): "
,
regs
->
msr
);
show_regs
(
regs
);
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
debugger
(
regs
);
#endif
print_backtrace
((
unsigned
long
*
)
regs
->
gpr
[
1
]);
panic
(
"machine check"
);
bust_spinlocks
(
0
);
spin_unlock_irq
(
&
die_lock
);
panic
(
"Unrecoverable Machine Check"
);
}
_exception
(
SIGSEGV
,
regs
);
}
void
SMIException
(
struct
pt_regs
*
regs
)
{
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
{
debugger
(
regs
);
return
;
}
#endif
show_regs
(
regs
);
print_backtrace
((
unsigned
long
*
)
regs
->
gpr
[
1
]);
panic
(
"System Management Interrupt"
);
/*
* XXX we should check RI bit on exception exit and kill the
* task if it was cleared
*/
info
.
si_signo
=
SIGBUS
;
info
.
si_errno
=
0
;
info
.
si_code
=
BUS_ADRERR
;
info
.
si_addr
=
(
void
*
)
regs
->
nip
;
_exception
(
SIGSEGV
,
&
info
,
regs
);
}
void
UnknownException
(
struct
pt_regs
*
regs
)
{
siginfo_t
info
;
printk
(
"Bad trap at PC: %lx, SR: %lx, vector=%lx
\n
"
,
regs
->
nip
,
regs
->
msr
,
regs
->
trap
);
_exception
(
SIGTRAP
,
regs
);
info
.
si_signo
=
SIGTRAP
;
info
.
si_errno
=
0
;
info
.
si_code
=
0
;
info
.
si_addr
=
0
;
_exception
(
SIGTRAP
,
&
info
,
regs
);
}
void
InstructionBreakpointException
(
struct
pt_regs
*
regs
)
{
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
if
(
debugger_iabr_match
(
regs
))
siginfo_t
info
;
#ifdef CONFIG_DEBUGGER
if
(
debugger_iabr_match
&&
debugger_iabr_match
(
regs
))
return
;
#endif
_exception
(
SIGTRAP
,
regs
);
info
.
si_signo
=
SIGTRAP
;
info
.
si_errno
=
0
;
info
.
si_code
=
TRAP_BRKPT
;
info
.
si_addr
=
(
void
*
)
regs
->
nip
;
_exception
(
SIGTRAP
,
&
info
,
regs
);
}
static
void
parse_fpe
(
struct
pt_regs
*
regs
)
{
siginfo_t
info
;
unsigned
int
*
tmp
;
unsigned
int
fpscr
;
if
(
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
current
);
tmp
=
&
current
->
thread
.
fpscr
;
fpscr
=
*
tmp
;
/* Invalid operation */
if
((
fpscr
&
FPSCR_VE
)
&&
(
fpscr
&
FPSCR_VX
))
info
.
si_code
=
FPE_FLTINV
;
/* Overflow */
else
if
((
fpscr
&
FPSCR_OE
)
&&
(
fpscr
&
FPSCR_OX
))
info
.
si_code
=
FPE_FLTOVF
;
/* Underflow */
else
if
((
fpscr
&
FPSCR_UE
)
&&
(
fpscr
&
FPSCR_UX
))
info
.
si_code
=
FPE_FLTUND
;
/* Divide by zero */
else
if
((
fpscr
&
FPSCR_ZE
)
&&
(
fpscr
&
FPSCR_ZX
))
info
.
si_code
=
FPE_FLTDIV
;
/* Inexact result */
else
if
((
fpscr
&
FPSCR_XE
)
&&
(
fpscr
&
FPSCR_XX
))
info
.
si_code
=
FPE_FLTRES
;
else
info
.
si_code
=
0
;
info
.
si_signo
=
SIGFPE
;
info
.
si_errno
=
0
;
info
.
si_addr
=
(
void
*
)
regs
->
nip
;
_exception
(
SIGFPE
,
&
info
,
regs
);
}
void
ProgramCheckException
(
struct
pt_regs
*
regs
)
{
siginfo_t
info
;
if
(
regs
->
msr
&
0x100000
)
{
/* IEEE FP exception */
_exception
(
SIGFPE
,
regs
);
parse_fpe
(
regs
);
}
else
if
(
regs
->
msr
&
0x40000
)
{
/* Privileged instruction */
info
.
si_signo
=
SIGILL
;
info
.
si_errno
=
0
;
info
.
si_code
=
ILL_PRVOPC
;
info
.
si_addr
=
(
void
*
)
regs
->
nip
;
_exception
(
SIGILL
,
&
info
,
regs
);
}
else
if
(
regs
->
msr
&
0x20000
)
{
/* trap exception */
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
if
(
debugger_bpt
(
regs
))
#ifdef CONFIG_DEBUGGER
if
(
debugger_bpt
&&
debugger_bpt
(
regs
))
return
;
#endif
_exception
(
SIGTRAP
,
regs
);
info
.
si_signo
=
SIGTRAP
;
info
.
si_errno
=
0
;
info
.
si_code
=
TRAP_BRKPT
;
info
.
si_addr
=
(
void
*
)
regs
->
nip
;
_exception
(
SIGTRAP
,
&
info
,
regs
);
}
else
{
_exception
(
SIGILL
,
regs
);
/* Illegal instruction */
info
.
si_signo
=
SIGILL
;
info
.
si_errno
=
0
;
info
.
si_code
=
ILL_ILLTRP
;
info
.
si_addr
=
(
void
*
)
regs
->
nip
;
_exception
(
SIGILL
,
&
info
,
regs
);
}
}
void
SingleStepException
(
struct
pt_regs
*
regs
)
{
siginfo_t
info
;
regs
->
msr
&=
~
MSR_SE
;
/* Turn off 'trace' bit */
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
if
(
debugger_sstep
(
regs
))
#ifdef CONFIG_DEBUGGER
if
(
debugger_sstep
&&
debugger_sstep
(
regs
))
return
;
#endif
_exception
(
SIGTRAP
,
regs
);
}
/* Dummy handler for Performance Monitor */
info
.
si_signo
=
SIGTRAP
;
info
.
si_errno
=
0
;
info
.
si_code
=
TRAP_TRACE
;
info
.
si_addr
=
(
void
*
)
regs
->
nip
;
_exception
(
SIGTRAP
,
&
info
,
regs
);
}
void
PerformanceMonitorException
(
struct
pt_regs
*
regs
)
{
_exception
(
SIGTRAP
,
regs
);
siginfo_t
info
;
info
.
si_signo
=
SIGTRAP
;
info
.
si_errno
=
0
;
info
.
si_code
=
TRAP_BRKPT
;
info
.
si_addr
=
0
;
_exception
(
SIGTRAP
,
&
info
,
regs
);
}
void
AlignmentException
(
struct
pt_regs
*
regs
)
{
int
fixed
;
siginfo_t
info
;
fixed
=
fix_alignment
(
regs
);
if
(
fixed
==
1
)
{
ifppcdebug
(
PPCDBG_ALIGNFIXUP
)
if
(
!
user_mode
(
regs
))
PPCDBG
(
PPCDBG_ALIGNFIXUP
,
"fix alignment at %lx
\n
"
,
regs
->
nip
);
PPCDBG
(
PPCDBG_ALIGNFIXUP
,
"fix alignment at %lx
\n
"
,
regs
->
nip
);
regs
->
nip
+=
4
;
/* skip over emulated instruction */
return
;
}
/* Operand address was bad */
if
(
fixed
==
-
EFAULT
)
{
/* fixed == -EFAULT means the operand address was bad */
if
(
user_mode
(
regs
))
force_sig
(
SIGSEGV
,
current
);
else
if
(
user_mode
(
regs
))
{
info
.
si_signo
=
SIGSEGV
;
info
.
si_errno
=
0
;
info
.
si_code
=
SEGV_MAPERR
;
info
.
si_addr
=
(
void
*
)
regs
->
dar
;
force_sig_info
(
SIGSEGV
,
&
info
,
current
);
}
else
{
/* Search exception table */
bad_page_fault
(
regs
,
regs
->
dar
);
}
return
;
}
_exception
(
SIGBUS
,
regs
);
info
.
si_signo
=
SIGBUS
;
info
.
si_errno
=
0
;
info
.
si_code
=
BUS_ADRALN
;
info
.
si_addr
=
(
void
*
)
regs
->
nip
;
_exception
(
SIGBUS
,
&
info
,
regs
);
}
void
__init
trap_init
(
void
)
...
...
arch/ppc64/mm/fault.c
View file @
ec5a5b68
...
...
@@ -45,9 +45,7 @@ extern int (*debugger_dabr_match)(struct pt_regs *);
int
debugger_kernel_faults
=
1
;
#endif
extern
void
die_if_kernel
(
char
*
,
struct
pt_regs
*
,
long
);
void
bad_page_fault
(
struct
pt_regs
*
,
unsigned
long
);
void
do_page_fault
(
struct
pt_regs
*
,
unsigned
long
,
unsigned
long
);
void
bad_page_fault
(
struct
pt_regs
*
,
unsigned
long
,
int
);
/*
* For 600- and 800-family processors, the error_code parameter is DSISR
...
...
@@ -86,7 +84,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
#endif
/* CONFIG_XMON || CONFIG_KGDB */
if
(
in_interrupt
()
||
mm
==
NULL
)
{
bad_page_fault
(
regs
,
address
);
bad_page_fault
(
regs
,
address
,
SIGSEGV
);
return
;
}
down_read
(
&
mm
->
mmap_sem
);
...
...
@@ -159,7 +157,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
return
;
}
bad_page_fault
(
regs
,
address
);
bad_page_fault
(
regs
,
address
,
SIGSEGV
);
return
;
/*
...
...
@@ -176,7 +174,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
printk
(
"VM: killing process %s
\n
"
,
current
->
comm
);
if
(
user_mode
(
regs
))
do_exit
(
SIGKILL
);
bad_page_fault
(
regs
,
address
);
bad_page_fault
(
regs
,
address
,
SIGKILL
);
return
;
do_sigbus:
...
...
@@ -187,7 +185,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
info
.
si_addr
=
(
void
*
)
address
;
force_sig_info
(
SIGBUS
,
&
info
,
current
);
if
(
!
user_mode
(
regs
))
bad_page_fault
(
regs
,
address
);
bad_page_fault
(
regs
,
address
,
SIGBUS
);
}
/*
...
...
@@ -196,8 +194,10 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
* in traps.c.
*/
void
bad_page_fault
(
struct
pt_regs
*
regs
,
unsigned
long
address
)
bad_page_fault
(
struct
pt_regs
*
regs
,
unsigned
long
address
,
int
sig
)
{
extern
void
die
(
const
char
*
,
struct
pt_regs
*
,
long
);
unsigned
long
fixup
;
/* Are we prepared to handle this fault? */
...
...
@@ -207,13 +207,10 @@ bad_page_fault(struct pt_regs *regs, unsigned long address)
}
/* kernel has accessed a bad area */
show_regs
(
regs
);
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
if
(
debugger_kernel_faults
)
debugger
(
regs
);
#endif
print_backtrace
(
(
unsigned
long
*
)
regs
->
gpr
[
1
]
);
panic
(
"kernel access of bad area pc %lx lr %lx address %lX tsk %s/%d"
,
regs
->
nip
,
regs
->
link
,
address
,
current
->
comm
,
current
->
pid
);
die
(
"Kernel access of bad area"
,
regs
,
sig
);
}
arch/ppc64/mm/init.c
View file @
ec5a5b68
...
...
@@ -247,6 +247,7 @@ static void map_io_page(unsigned long ea, unsigned long pa, int flags)
void
flush_tlb_mm
(
struct
mm_struct
*
mm
)
{
spin_lock
(
&
mm
->
page_table_lock
);
if
(
mm
->
map_count
)
{
struct
vm_area_struct
*
mp
;
for
(
mp
=
mm
->
mmap
;
mp
!=
NULL
;
mp
=
mp
->
vm_next
)
...
...
@@ -261,6 +262,7 @@ flush_tlb_mm(struct mm_struct *mm)
/* XXX are there races with checking cpu_vm_mask? - Anton */
mm
->
cpu_vm_mask
=
0
;
spin_unlock
(
&
mm
->
page_table_lock
);
}
/*
...
...
@@ -666,6 +668,8 @@ int __hash_page(unsigned long ea, unsigned long access, unsigned long vsid,
* fault has been handled by updating a PTE in the linux page tables.
* We use it to preload an HPTE into the hash table corresponding to
* the updated linux PTE.
*
* This must always be called with the mm->page_table_lock held
*/
void
update_mmu_cache
(
struct
vm_area_struct
*
vma
,
unsigned
long
ea
,
pte_t
pte
)
...
...
include/asm-ppc64/fcntl.h
View file @
ec5a5b68
...
...
@@ -26,7 +26,7 @@
#define O_DIRECTORY 040000
/* must be a directory */
#define O_NOFOLLOW 0100000
/* don't follow links */
#define O_LARGEFILE 0200000
#define O_DIRECT 0400000
/* direct disk access hint
- currently ignored
*/
#define O_DIRECT 0400000
/* direct disk access hint */
#define F_DUPFD 0
/* dup */
#define F_GETFD 1
/* get close_on_exec */
...
...
include/asm-ppc64/memory.h
View file @
ec5a5b68
...
...
@@ -50,7 +50,7 @@ static inline void isync(void)
#define HMT_LOW "\tor 1,1,1 # low priority\n"
#define HMT_MEDIUM "\tor 2,2,2 # medium priority\n"
#define HMT_
MEDIUM
"\tor 3,3,3 # high priority\n"
#define HMT_
HIGH
"\tor 3,3,3 # high priority\n"
#else
#define HMT_low() do { } while(0)
#define HMT_medium() do { } while(0)
...
...
include/asm-ppc64/mmu.h
View file @
ec5a5b68
...
...
@@ -211,18 +211,11 @@ static inline void _tlbie(unsigned long va, int large)
asm
volatile
(
"eieio; tlbsync; ptesync"
:
:
:
"memory"
);
}
static
inline
void
_tlbiel
(
unsigned
long
va
,
int
large
)
static
inline
void
_tlbiel
(
unsigned
long
va
)
{
asm
volatile
(
"ptesync"
:
:
:
"memory"
);
if
(
large
)
{
asm
volatile
(
"clrldi %0,%0,16
\n
\
tlbiel %0,1"
:
:
"r"
(
va
)
:
"memory"
);
}
else
{
asm
volatile
(
"clrldi %0,%0,16
\n
\
tlbiel %0,0"
:
:
"r"
(
va
)
:
"memory"
);
}
tlbiel %0"
:
:
"r"
(
va
)
:
"memory"
);
asm
volatile
(
"ptesync"
:
:
:
"memory"
);
}
...
...
include/asm-ppc64/page.h
View file @
ec5a5b68
...
...
@@ -215,9 +215,12 @@ static inline int get_order(unsigned long size)
#define __a2p(x) ((void *) absolute_to_phys(x))
#define __a2v(x) ((void *) __va(absolute_to_phys(x)))
#define virt_to_page(kaddr) (mem_map+(__pa((unsigned long)kaddr) >> PAGE_SHIFT))
#define pfn_to_page(pfn) (mem_map + (pfn))
#define page_to_pfn(pfn) ((unsigned long)((pfn) - mem_map))
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
#define VALID_PAGE(page) ((page - mem_map) < max_mapnr)
#define pfn_valid(pfn) ((pfn) < max_mapnr)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
#define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT)
...
...
include/asm-ppc64/pgtable.h
View file @
ec5a5b68
...
...
@@ -167,22 +167,14 @@ extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*
* mk_pte_phys takes a physical address as input
*
* mk_pte takes a (struct page *) as input
*/
#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
#define mk_pte_phys(physpage,pgprot) \
({ \
pte_t pte; \
pte_val(pte) = (((physpage)<<(PTE_SHIFT-PAGE_SHIFT)) | pgprot_val(pgprot)); \
pte; \
})
#define mk_pte(page,pgprot) \
#define pfn_pte(pfn,pgprot) \
({ \
pte_t pte; \
pte_val(pte) = ((unsigned long)(
(page) - mem_map) << PTE_SHIFT) |
\
pte_val(pte) = ((unsigned long)(
pfn) << PTE_SHIFT) |
\
pgprot_val(pgprot); \
pte; \
})
...
...
@@ -195,8 +187,8 @@ extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
/* pte_clear moved to later in this file */
#define pte_p
agenr
(x) ((unsigned long)((pte_val(x) >> PTE_SHIFT)))
#define pte_page(x)
(mem_map+pte_pagenr
(x))
#define pte_p
fn
(x) ((unsigned long)((pte_val(x) >> PTE_SHIFT)))
#define pte_page(x)
pfn_to_page(pte_pfn
(x))
#define pmd_set(pmdp, ptep) (pmd_val(*(pmdp)) = (__ba_to_bpn(ptep)))
#define pmd_none(pmd) (!pmd_val(pmd))
...
...
include/asm-ppc64/thread_info.h
View file @
ec5a5b68
...
...
@@ -65,6 +65,8 @@ static inline struct thread_info *current_thread_info(void)
#endif
/* __ASSEMBLY__ */
#define PREEMPT_ACTIVE 0x4000000
/*
* thread information flag bit numbers
*/
...
...
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