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
20237c4d
Commit
20237c4d
authored
Jun 07, 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
50da7d0e
dfe6d4c0
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
220 additions
and
292 deletions
+220
-292
arch/ppc64/kernel/eeh.c
arch/ppc64/kernel/eeh.c
+8
-7
arch/ppc64/kernel/entry.S
arch/ppc64/kernel/entry.S
+2
-2
arch/ppc64/kernel/htab.c
arch/ppc64/kernel/htab.c
+0
-4
arch/ppc64/kernel/proc_pmc.c
arch/ppc64/kernel/proc_pmc.c
+0
-3
arch/ppc64/kernel/signal.c
arch/ppc64/kernel/signal.c
+80
-78
arch/ppc64/kernel/signal32.c
arch/ppc64/kernel/signal32.c
+106
-152
arch/ppc64/mm/init.c
arch/ppc64/mm/init.c
+19
-44
include/asm-ppc64/page.h
include/asm-ppc64/page.h
+2
-2
include/asm-ppc64/pgalloc.h
include/asm-ppc64/pgalloc.h
+3
-0
No files found.
arch/ppc64/kernel/eeh.c
View file @
20237c4d
...
...
@@ -59,15 +59,14 @@ unsigned long eeh_token(unsigned long phb, unsigned long bus, unsigned long devf
return
((
IO_UNMAPPED_REGION_ID
<<
60
)
|
(
phb
<<
48UL
)
|
((
bus
&
0xff
)
<<
40UL
)
|
(
devfn
<<
32UL
)
|
(
offset
&
0xffffffff
));
}
int
eeh_get_state
(
unsigned
long
ea
)
{
int
eeh_get_state
(
unsigned
long
ea
)
{
return
0
;
}
/* Check for an eeh failure at the given token address.
* The given value has been read and it should be 1's (0xff, 0xffff or 0xffffffff).
* The given value has been read and it should be 1's (0xff, 0xffff or
* 0xffffffff).
*
* Probe to determine if an error actually occurred. If not return val.
* Otherwise panic.
...
...
@@ -113,7 +112,8 @@ unsigned long eeh_check_failure(void *token, unsigned long val)
return
val
;
/* good case */
}
void
eeh_init
(
void
)
{
void
eeh_init
(
void
)
{
extern
char
cmd_line
[];
/* Very early cmd line parse. Cheap, but works. */
char
*
eeh_force_off
=
strstr
(
cmd_line
,
"eeh-force-off"
);
char
*
eeh_force_on
=
strstr
(
cmd_line
,
"eeh-force-on"
);
...
...
@@ -121,7 +121,7 @@ void eeh_init(void) {
ibm_set_eeh_option
=
rtas_token
(
"ibm,set-eeh-option"
);
ibm_set_slot_reset
=
rtas_token
(
"ibm,set-slot-reset"
);
ibm_read_slot_reset_state
=
rtas_token
(
"ibm,read-slot-reset-state"
);
if
(
ibm_set_eeh_option
!=
RTAS_UNKNOWN_SERVICE
&&
naca
->
platform
==
PLATFORM_PSERIES_LPAR
)
if
(
ibm_set_eeh_option
!=
RTAS_UNKNOWN_SERVICE
)
eeh_implemented
=
1
;
if
(
eeh_force_off
>
eeh_force_on
)
{
...
...
@@ -334,6 +334,7 @@ static int __init eehoff_parm(char *str)
{
return
eeh_parm
(
str
,
0
);
}
static
int
__init
eehon_parm
(
char
*
str
)
{
return
eeh_parm
(
str
,
1
);
...
...
arch/ppc64/kernel/entry.S
View file @
20237c4d
...
...
@@ -353,7 +353,7 @@ recheck:
li
r4
,
0
ori
r4
,
r4
,
MSR_EE
|
MSR_RI
andc
r10
,
r10
,
r4
/*
clear
MSR_EE
and
MSR_RI
*/
mtmsrd
r10
/*
Update
machine
state
*/
mtmsrd
r10
,
1
/*
Update
machine
state
*/
#ifdef CONFIG_PPC_ISERIES
#error fix iSeries soft disable
...
...
@@ -411,7 +411,7 @@ restore:
do_work
:
/
*
Enable
interrupts
*/
ori
r10
,
r10
,
MSR_EE
|
MSR_RI
mtmsrd
r10
mtmsrd
r10
,
1
andi
.
r0
,
r3
,
_TIF_NEED_RESCHED
beq
1
f
...
...
arch/ppc64/kernel/htab.c
View file @
20237c4d
...
...
@@ -45,9 +45,7 @@
#include <asm/lmb.h>
#include <asm/abs_addr.h>
#include <asm/tlbflush.h>
#ifdef CONFIG_PPC_EEH
#include <asm/eeh.h>
#endif
/*
* Note: pte --> Linux PTE
...
...
@@ -346,13 +344,11 @@ int hash_page(unsigned long ea, unsigned long access)
mm
=
&
init_mm
;
vsid
=
get_kernel_vsid
(
ea
);
break
;
#ifdef CONFIG_PPC_EEH
case
IO_UNMAPPED_REGION_ID
:
udbg_printf
(
"EEH Error ea = 0x%lx
\n
"
,
ea
);
PPCDBG_ENTER_DEBUGGER
();
panic
(
"EEH Error ea = 0x%lx
\n
"
,
ea
);
break
;
#endif
case
KERNEL_REGION_ID
:
/*
* As htab_initialize is now, we shouldn't ever get here since
...
...
arch/ppc64/kernel/proc_pmc.c
View file @
20237c4d
...
...
@@ -100,9 +100,6 @@ void proc_ppc64_init(void)
if
(
!
proc_ppc64_root
)
return
;
spin_unlock
(
&
proc_ppc64_lock
);
#ifdef CONFIG_PPC_EEH
eeh_init_proc
(
proc_ppc64_root
);
#endif
proc_ppc64_pmc_root
=
proc_mkdir
(
"pmc"
,
proc_ppc64_root
);
...
...
arch/ppc64/kernel/signal.c
View file @
20237c4d
...
...
@@ -26,8 +26,6 @@
#include <linux/unistd.h>
#include <linux/stddef.h>
#include <linux/elf.h>
#include <linux/tty.h>
#include <linux/binfmts.h>
#include <asm/ppc32.h>
#include <asm/sigcontext.h>
#include <asm/ucontext.h>
...
...
@@ -59,9 +57,36 @@
*/
#define MSR_USERCHANGE (MSR_FE0 | MSR_FE1)
int
do_signal
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
);
extern
long
sys_wait4
(
pid_t
pid
,
unsigned
int
*
stat_addr
,
int
options
,
/*unsigned long*/
struct
rusage
*
ru
);
/*
* 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 with
* a gap of __SIGNAL_FRAMESIZE bytes
*
* Each of these things must be a multiple of 16 bytes in size.
*
*/
struct
sigregs
{
elf_gregset_t
gp_regs
;
double
fp_regs
[
ELF_NFPREG
];
unsigned
int
tramp
[
2
];
/* 64 bit API allows for 288 bytes below sp before
decrementing it. */
int
abigap
[
72
];
};
struct
rt_sigframe
{
unsigned
long
_unused
[
2
];
struct
siginfo
*
pinfo
;
void
*
puc
;
struct
siginfo
info
;
struct
ucontext
uc
;
};
extern
int
do_signal
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
);
/*
* Atomically swap in the new signal mask, and wait for a signal.
...
...
@@ -127,7 +152,7 @@ long sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int
long
sys_sigaltstack
(
const
stack_t
*
uss
,
stack_t
*
uoss
)
{
struct
pt_regs
*
regs
=
(
struct
pt_regs
*
)
&
uss
;
struct
pt_regs
*
regs
=
(
struct
pt_regs
*
)
&
uss
;
return
do_sigaltstack
(
uss
,
uoss
,
regs
->
gpr
[
1
]);
}
...
...
@@ -139,6 +164,7 @@ long sys_sigaction(int sig, const struct old_sigaction *act,
if
(
act
)
{
old_sigset_t
mask
;
if
(
verify_area
(
VERIFY_READ
,
act
,
sizeof
(
*
act
))
||
__get_user
(
new_ka
.
sa
.
sa_handler
,
&
act
->
sa_handler
)
||
__get_user
(
new_ka
.
sa
.
sa_restorer
,
&
act
->
sa_restorer
))
...
...
@@ -148,8 +174,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
))
||
__put_user
(
old_ka
.
sa
.
sa_handler
,
&
oact
->
sa_handler
)
||
...
...
@@ -162,35 +187,6 @@ long sys_sigaction(int sig, const struct old_sigaction *act,
return
ret
;
}
/*
* 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 with
* a gap of __SIGNAL_FRAMESIZE bytes
*
* Each of these things must be a multiple of 16 bytes in size.
*
*/
struct
sigregs
{
elf_gregset_t
gp_regs
;
double
fp_regs
[
ELF_NFPREG
];
unsigned
int
tramp
[
2
];
/* 64 bit API allows for 288 bytes below sp before
decrementing it. */
int
abigap
[
72
];
};
struct
rt_sigframe
{
unsigned
long
_unused
[
2
];
struct
siginfo
*
pinfo
;
void
*
puc
;
struct
siginfo
info
;
struct
ucontext
uc
;
};
/*
* When we have rt signals to deliver, we set up on the
* user stack, going down from the original stack pointer:
...
...
@@ -231,7 +227,7 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
* preamble frame (where registers are stored)
* see handle_signal()
*/
sr
=
(
struct
sigregs
*
)
sigctx
.
regs
;
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
)
...
...
@@ -251,11 +247,10 @@ int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
do_exit
(
SIGSEGV
);
}
static
void
setup_rt_frame
(
struct
pt_regs
*
regs
,
struct
sigregs
*
frame
,
static
void
setup_rt_frame
(
struct
pt_regs
*
regs
,
struct
sigregs
*
frame
,
signed
long
newsp
)
{
struct
rt_sigframe
*
rt_sf
=
(
struct
rt_sigframe
*
)
newsp
;
struct
rt_sigframe
*
rt_sf
=
(
struct
rt_sigframe
*
)
newsp
;
/* Handler is *really* a pointer to the function descriptor for
* the signal routine. The first entry in the function
* descriptor is the entry address of signal and the second
...
...
@@ -277,11 +272,13 @@ setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
if
(
__copy_to_user
(
&
frame
->
gp_regs
,
regs
,
GP_REGS_SIZE
)
||
__copy_to_user
(
&
frame
->
fp_regs
,
current
->
thread
.
fpr
,
ELF_NFPREG
*
sizeof
(
double
))
||
__put_user
(
0x38000000UL
+
__NR_rt_sigreturn
,
&
frame
->
tramp
[
0
])
/* li r0, __NR_rt_sigreturn */
||
__put_user
(
0x44000002UL
,
&
frame
->
tramp
[
1
]))
/* sc */
/* li r0, __NR_rt_sigreturn */
||
__put_user
(
0x38000000UL
+
__NR_rt_sigreturn
,
&
frame
->
tramp
[
0
])
/* sc */
||
__put_user
(
0x44000002UL
,
&
frame
->
tramp
[
1
]))
goto
badframe
;
flush_icache_range
((
unsigned
long
)
&
frame
->
tramp
[
0
],
(
unsigned
long
)
&
frame
->
tramp
[
2
]);
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
...
...
@@ -289,11 +286,11 @@ setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
*/
newsp
-=
__SIGNAL_FRAMESIZE
;
if
(
get_user
(
temp_ptr
,
&
rt_sf
->
uc
.
uc_mcontext
.
handler
))
{
if
(
get_user
(
temp_ptr
,
&
rt_sf
->
uc
.
uc_mcontext
.
handler
))
{
goto
badframe
;
}
funct_desc_ptr
=
(
struct
funct_descr_entry
*
)
temp_ptr
;
funct_desc_ptr
=
(
struct
funct_descr_entry
*
)
temp_ptr
;
if
(
put_user
(
regs
->
gpr
[
1
],
(
unsigned
long
*
)
newsp
)
||
get_user
(
regs
->
nip
,
&
funct_desc_ptr
->
entry
)
...
...
@@ -304,8 +301,8 @@ setup_rt_frame(struct pt_regs *regs, struct sigregs *frame,
goto
badframe
;
regs
->
gpr
[
1
]
=
newsp
;
regs
->
gpr
[
6
]
=
(
unsigned
long
)
rt_sf
;
regs
->
link
=
(
unsigned
long
)
frame
->
tramp
;
regs
->
gpr
[
6
]
=
(
unsigned
long
)
rt_sf
;
regs
->
link
=
(
unsigned
long
)
frame
->
tramp
;
return
;
...
...
@@ -342,11 +339,11 @@ long sys_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
)
if
(
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
current
);
/* restore registers */
sr
=
(
struct
sigregs
*
)
sigctx
.
regs
;
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
)
...
...
@@ -367,8 +364,7 @@ long sys_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
/*
* Set up a signal frame.
*/
static
void
setup_frame
(
struct
pt_regs
*
regs
,
struct
sigregs
*
frame
,
static
void
setup_frame
(
struct
pt_regs
*
regs
,
struct
sigregs
*
frame
,
unsigned
long
newsp
)
{
...
...
@@ -385,7 +381,7 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame,
struct
funct_descr_entry
*
funct_desc_ptr
;
unsigned
long
temp_ptr
;
struct
sigcontext_struct
*
sc
=
(
struct
sigcontext_struct
*
)
newsp
;
struct
sigcontext_struct
*
sc
=
(
struct
sigcontext_struct
*
)
newsp
;
if
(
verify_area
(
VERIFY_WRITE
,
frame
,
sizeof
(
*
frame
)))
goto
badframe
;
...
...
@@ -394,27 +390,29 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame,
if
(
__copy_to_user
(
&
frame
->
gp_regs
,
regs
,
GP_REGS_SIZE
)
||
__copy_to_user
(
&
frame
->
fp_regs
,
current
->
thread
.
fpr
,
ELF_NFPREG
*
sizeof
(
double
))
||
__put_user
(
0x38000000UL
+
__NR_sigreturn
,
&
frame
->
tramp
[
0
])
/* li r0, __NR_sigreturn */
||
__put_user
(
0x44000002UL
,
&
frame
->
tramp
[
1
]))
/* sc */
/* li r0, __NR_sigreturn */
||
__put_user
(
0x38000000UL
+
__NR_sigreturn
,
&
frame
->
tramp
[
0
])
/* sc */
||
__put_user
(
0x44000002UL
,
&
frame
->
tramp
[
1
]))
goto
badframe
;
flush_icache_range
((
unsigned
long
)
&
frame
->
tramp
[
0
],
(
unsigned
long
)
&
frame
->
tramp
[
2
]);
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
))
if
(
get_user
(
temp_ptr
,
&
sc
->
handler
))
goto
badframe
;
funct_desc_ptr
=
(
struct
funct_descr_entry
*
)
temp_ptr
;
funct_desc_ptr
=
(
struct
funct_descr_entry
*
)
temp_ptr
;
if
(
put_user
(
regs
->
gpr
[
1
],
(
unsigned
long
*
)
newsp
)
||
get_user
(
regs
->
nip
,
&
funct_desc_ptr
->
entry
)
||
get_user
(
regs
->
gpr
[
2
],
&
funct_desc_ptr
->
toc
)
||
get_user
(
regs
->
nip
,
&
funct_desc_ptr
->
entry
)
||
get_user
(
regs
->
gpr
[
2
],
&
funct_desc_ptr
->
toc
)
||
get_user
(
regs
->
gpr
[
3
],
&
sc
->
signal
))
goto
badframe
;
regs
->
gpr
[
1
]
=
newsp
;
regs
->
gpr
[
4
]
=
(
unsigned
long
)
sc
;
regs
->
link
=
(
unsigned
long
)
frame
->
tramp
;
regs
->
gpr
[
4
]
=
(
unsigned
long
)
sc
;
regs
->
link
=
(
unsigned
long
)
frame
->
tramp
;
return
;
...
...
@@ -429,8 +427,7 @@ setup_frame(struct pt_regs *regs, struct sigregs *frame,
/*
* OK, we're invoking a handler
*/
static
void
handle_signal
(
unsigned
long
sig
,
siginfo_t
*
info
,
sigset_t
*
oldset
,
static
void
handle_signal
(
unsigned
long
sig
,
siginfo_t
*
info
,
sigset_t
*
oldset
,
struct
pt_regs
*
regs
,
unsigned
long
*
newspp
,
unsigned
long
frame
)
{
struct
sigcontext_struct
*
sc
;
...
...
@@ -447,11 +444,12 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
if
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
{
/* Put a Real Time Context onto stack */
*
newspp
-=
sizeof
(
*
rt_sf
);
rt_sf
=
(
struct
rt_sigframe
*
)
*
newspp
;
rt_sf
=
(
struct
rt_sigframe
*
)
*
newspp
;
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
)
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
)
/* Put the siginfo */
...
...
@@ -461,9 +459,11 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
||
__put_user
(
0
,
&
rt_sf
->
uc
.
uc_link
)
||
__put_user
(
current
->
sas_ss_sp
,
&
rt_sf
->
uc
.
uc_stack
.
ss_sp
)
||
__put_user
(
sas_ss_flags
(
regs
->
gpr
[
1
]),
&
rt_sf
->
uc
.
uc_stack
.
ss_flags
)
||
__put_user
(
current
->
sas_ss_size
,
&
rt_sf
->
uc
.
uc_stack
.
ss_size
)
||
__copy_to_user
(
&
rt_sf
->
uc
.
uc_sigmask
,
oldset
,
sizeof
(
*
oldset
))
&
rt_sf
->
uc
.
uc_stack
.
ss_flags
)
||
__put_user
(
current
->
sas_ss_size
,
&
rt_sf
->
uc
.
uc_stack
.
ss_size
)
||
__copy_to_user
(
&
rt_sf
->
uc
.
uc_sigmask
,
oldset
,
sizeof
(
*
oldset
))
/* mcontext.regs points to preamble register frame */
||
__put_user
((
struct
pt_regs
*
)
frame
,
&
rt_sf
->
uc
.
uc_mcontext
.
regs
)
||
__put_user
(
sig
,
&
rt_sf
->
uc
.
uc_mcontext
.
signal
))
...
...
@@ -471,11 +471,11 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
}
else
{
/* Put a sigcontext on the stack */
*
newspp
-=
sizeof
(
*
sc
);
sc
=
(
struct
sigcontext_struct
*
)
*
newspp
;
sc
=
(
struct
sigcontext_struct
*
)
*
newspp
;
if
(
verify_area
(
VERIFY_WRITE
,
sc
,
sizeof
(
*
sc
)))
goto
badframe
;
if
(
__put_user
((
unsigned
long
)
ka
->
sa
.
sa_handler
,
&
sc
->
handler
)
if
(
__put_user
((
unsigned
long
)
ka
->
sa
.
sa_handler
,
&
sc
->
handler
)
||
__put_user
(
oldset
->
sig
[
0
],
&
sc
->
oldmask
)
#if _NSIG_WORDS > 1
||
__put_user
(
oldset
->
sig
[
1
],
&
sc
->
_unused
[
3
])
...
...
@@ -512,6 +512,7 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset,
* mistake.
*/
extern
int
do_signal32
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
);
int
do_signal
(
sigset_t
*
oldset
,
struct
pt_regs
*
regs
)
{
siginfo_t
info
;
...
...
@@ -526,7 +527,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
if
(
test_thread_flag
(
TIF_32BIT
))
return
do_signal32
(
oldset
,
regs
);
if
(
!
oldset
)
if
(
!
oldset
)
oldset
=
&
current
->
blocked
;
newsp
=
frame
=
0
;
...
...
@@ -534,8 +535,8 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
signr
=
get_signal_to_deliver
(
&
info
,
regs
);
if
(
signr
>
0
)
{
ka
=
&
current
->
sig
->
action
[
signr
-
1
];
if
(
(
ka
->
sa
.
sa_flags
&
SA_ONSTACK
)
&&
(
!
on_sig_stack
(
regs
->
gpr
[
1
])))
if
((
ka
->
sa
.
sa_flags
&
SA_ONSTACK
)
&&
(
!
on_sig_stack
(
regs
->
gpr
[
1
])))
newsp
=
(
current
->
sas_ss_sp
+
current
->
sas_ss_size
);
else
newsp
=
regs
->
gpr
[
1
];
...
...
@@ -557,9 +558,10 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
if
(
newsp
==
frame
)
return
0
;
/* no signals delivered */
/* Invoke correct stack setup routine */
if
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
setup_rt_frame
(
regs
,
(
struct
sigregs
*
)
frame
,
newsp
);
setup_rt_frame
(
regs
,
(
struct
sigregs
*
)
frame
,
newsp
);
else
setup_frame
(
regs
,
(
struct
sigregs
*
)
frame
,
newsp
);
setup_frame
(
regs
,
(
struct
sigregs
*
)
frame
,
newsp
);
return
1
;
}
arch/ppc64/kernel/signal32.c
View file @
20237c4d
...
...
@@ -14,43 +14,19 @@
* 2 of the License, or (at your option) any later version.
*/
#include <asm/ptrace.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/file.h>
#include <linux/signal.h>
#include <linux/utime.h>
#include <linux/resource.h>
#include <linux/times.h>
#include <linux/utsname.h>
#include <linux/timex.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/slab.h>
#include <linux/uio.h>
#include <linux/nfs_fs.h>
#include <linux/smb_fs.h>
#include <linux/smb_mount.h>
#include <linux/ncp_fs.h>
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/personality.h>
#include <linux/stat.h>
#include <linux/filter.h>
#include <linux/tty.h>
#include <linux/binfmts.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/elf.h>
#include <asm/types.h>
#include <asm/ipc.h>
#include <asm/uaccess.h>
#include <asm/ppc32.h>
#include <asm/uaccess.h>
#include <asm/ppcdebug.h>
#include <asm/unistd.h>
#include <asm/cacheflush.h>
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
/*
...
...
@@ -112,9 +88,6 @@ struct rt_sigframe_32 {
};
extern
asmlinkage
long
sys_wait4
(
pid_t
pid
,
unsigned
int
*
stat_addr
,
int
options
,
struct
rusage
*
ru
);
/*
* Start of nonRT signal support
...
...
@@ -133,7 +106,7 @@ extern asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr,
* setup_frame32
*/
asmlinkage
long
sys32_sigaction
(
int
sig
,
struct
old_sigaction32
*
act
,
long
sys32_sigaction
(
int
sig
,
struct
old_sigaction32
*
act
,
struct
old_sigaction32
*
oact
)
{
struct
k_sigaction
new_ka
,
old_ka
;
...
...
@@ -145,32 +118,30 @@ asmlinkage long sys32_sigaction(int sig, struct old_sigaction32 *act,
if
(
act
)
{
old_sigset_t32
mask
;
ret
=
get_user
((
long
)
new_ka
.
sa
.
sa_handler
,
&
act
->
sa_handler
);
ret
|=
__get_user
((
long
)
new_ka
.
sa
.
sa_restorer
,
&
act
->
sa_restorer
);
ret
|=
__get_user
(
new_ka
.
sa
.
sa_flags
,
&
act
->
sa_flags
);
ret
|=
__get_user
(
mask
,
&
act
->
sa_mask
);
if
(
ret
)
return
ret
;
if
(
get_user
((
long
)
new_ka
.
sa
.
sa_handler
,
&
act
->
sa_handler
)
||
__get_user
((
long
)
new_ka
.
sa
.
sa_restorer
,
&
act
->
sa_restorer
)
||
__get_user
(
new_ka
.
sa
.
sa_flags
,
&
act
->
sa_flags
)
||
__get_user
(
mask
,
&
act
->
sa_mask
))
return
-
EFAULT
;
siginitset
(
&
new_ka
.
sa
.
sa_mask
,
mask
);
}
ret
=
do_sigaction
(
sig
,
act
?
&
new_ka
:
NULL
,
oact
?
&
old_ka
:
NULL
);
if
(
!
ret
&&
oact
)
{
ret
=
put_user
((
long
)
old_ka
.
sa
.
sa_handler
,
&
oact
->
sa_handler
);
ret
|=
__put_user
((
long
)
old_ka
.
sa
.
sa_restorer
,
&
oact
->
sa_restorer
);
ret
|=
__put_user
(
old_ka
.
sa
.
sa_flags
,
&
oact
->
sa_flags
);
ret
|=
__put_user
(
old_ka
.
sa
.
sa_mask
.
sig
[
0
],
&
oact
->
sa_mask
);
if
(
put_user
((
long
)
old_ka
.
sa
.
sa_handler
,
&
oact
->
sa_handler
)
||
__put_user
((
long
)
old_ka
.
sa
.
sa_restorer
,
&
oact
->
sa_restorer
)
||
__put_user
(
old_ka
.
sa
.
sa_flags
,
&
oact
->
sa_flags
)
||
__put_user
(
old_ka
.
sa
.
sa_mask
.
sig
[
0
],
&
oact
->
sa_mask
))
return
-
EFAULT
;
}
return
ret
;
}
extern
long
sys_sigpending
(
old_sigset_t
*
set
);
extern
asmlinkage
long
sys_sigpending
(
old_sigset_t
*
set
);
asmlinkage
long
sys32_sigpending
(
old_sigset_t32
*
set
)
long
sys32_sigpending
(
old_sigset_t32
*
set
)
{
old_sigset_t
s
;
int
ret
;
...
...
@@ -185,9 +156,7 @@ asmlinkage long sys32_sigpending(old_sigset_t32 *set)
}
extern
asmlinkage
long
sys_sigprocmask
(
int
how
,
old_sigset_t
*
set
,
extern
long
sys_sigprocmask
(
int
how
,
old_sigset_t
*
set
,
old_sigset_t
*
oset
);
/*
...
...
@@ -197,7 +166,7 @@ extern asmlinkage long sys_sigprocmask(int how, old_sigset_t *set,
* of a signed int (msr in 32-bit mode) and the register representation
* of a signed int (msr in 64-bit mode) is performed.
*/
asmlinkage
long
sys32_sigprocmask
(
u32
how
,
old_sigset_t32
*
set
,
long
sys32_sigprocmask
(
u32
how
,
old_sigset_t32
*
set
,
old_sigset_t32
*
oset
)
{
old_sigset_t
s
;
...
...
@@ -252,23 +221,21 @@ long sys32_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
* Note that PPC32 puts the upper 32 bits of the sigmask in the
* unused part of the signal stackframe
*/
set
.
sig
[
0
]
=
sigctx
.
oldmask
+
((
long
)(
sigctx
.
_unused
[
3
])
<<
32
);
set
.
sig
[
0
]
=
sigctx
.
oldmask
+
((
long
)(
sigctx
.
_unused
[
3
])
<<
32
);
sigdelsetmask
(
&
set
,
~
_BLOCKABLE
);
spin_lock_irq
(
&
current
->
sigmask_lock
);
current
->
blocked
=
set
;
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sigmask_lock
);
/* Last stacked signal - restore registers */
sr
=
(
struct
sigregs32
*
)(
u64
)
sigctx
.
regs
;
if
(
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
current
);
/* Last stacked signal - restore registers */
sr
=
(
struct
sigregs32
*
)(
u64
)
sigctx
.
regs
;
/*
* copy the 32 bit register values off the user stack
* into the 32 bit register area
*/
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
;
/*
* The saved reg structure in the frame is an elf_grepset_t32,
...
...
@@ -323,7 +290,6 @@ long sys32_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
goto
badframe
;
ret
=
regs
->
result
;
return
ret
;
badframe:
...
...
@@ -387,12 +353,13 @@ static void setup_frame32(struct pt_regs *regs, struct sigregs32 *frame,
*/
if
(
__copy_to_user
(
&
frame
->
fp_regs
,
current
->
thread
.
fpr
,
ELF_NFPREG
*
sizeof
(
double
))
||
__put_user
(
0x38000000U
+
__NR_sigreturn
,
&
frame
->
tramp
[
0
])
/* li r0, __NR_sigreturn */
||
__put_user
(
0x44000002U
,
&
frame
->
tramp
[
1
]))
/* sc */
/* li r0, __NR_sigreturn */
||
__put_user
(
0x38000000U
+
__NR_sigreturn
,
&
frame
->
tramp
[
0
])
/* sc */
||
__put_user
(
0x44000002U
,
&
frame
->
tramp
[
1
]))
goto
badframe
;
flush_icache_range
((
unsigned
long
)
&
frame
->
tramp
[
0
],
(
unsigned
long
)
&
frame
->
tramp
[
2
]);
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
;
...
...
@@ -438,7 +405,7 @@ static void setup_frame32(struct pt_regs *regs, struct sigregs32 *frame,
*
* Other routines
* setup_rt_frame32
*
siginfo64to
32
*
copy_siginfo_to_user
32
* siginfo32to64
*/
...
...
@@ -451,50 +418,45 @@ long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned
long
r6
,
unsigned
long
r7
,
unsigned
long
r8
,
struct
pt_regs
*
regs
)
{
struct
rt_sigframe_32
*
rt_s
tack_frame
;
struct
rt_sigframe_32
*
rt_s
f
;
struct
sigcontext32_struct
sigctx
;
struct
sigregs32
*
s
ignalregs
;
struct
sigregs32
*
s
r
;
int
ret
;
elf_gregset_t32
saved_regs
;
/* an array of 32 bit register values */
sigset_t
s
ignal_s
et
;
stack_t
st
ack
;
sigset_t
set
;
stack_t
st
;
int
i
;
ret
=
0
;
/* Adjust the inputted reg1 to point to the first rt signal frame */
rt_s
tack_frame
=
(
struct
rt_sigframe_32
*
)(
regs
->
gpr
[
1
]
+
__SIGNAL_FRAMESIZE32
);
rt_s
f
=
(
struct
rt_sigframe_32
*
)(
regs
->
gpr
[
1
]
+
__SIGNAL_FRAMESIZE32
);
/* Copy the information from the user stack */
if
(
copy_from_user
(
&
sigctx
,
&
rt_stack_frame
->
uc
.
uc_mcontext
,
sizeof
(
sigctx
))
||
copy_from_user
(
&
signal_set
,
&
rt_stack_frame
->
uc
.
uc_sigmask
,
sizeof
(
signal_set
))
||
copy_from_user
(
&
stack
,
&
rt_stack_frame
->
uc
.
uc_stack
,
sizeof
(
stack
)))
if
(
copy_from_user
(
&
sigctx
,
&
rt_sf
->
uc
.
uc_mcontext
,
sizeof
(
sigctx
))
||
copy_from_user
(
&
set
,
&
rt_sf
->
uc
.
uc_sigmask
,
sizeof
(
set
))
||
copy_from_user
(
&
st
,
&
rt_sf
->
uc
.
uc_stack
,
sizeof
(
st
)))
goto
badframe
;
/*
* Unblock the signal that was processed
* After a signal handler runs -
* if the signal is blockable - the signal will be unblocked
* (
sigkill and sigstop are not blockable)
* (sigkill and sigstop are not blockable)
*/
sigdelsetmask
(
&
s
ignal_s
et
,
~
_BLOCKABLE
);
sigdelsetmask
(
&
set
,
~
_BLOCKABLE
);
/* update the current based on the sigmask found in the rt_stackframe */
spin_lock_irq
(
&
current
->
sigmask_lock
);
current
->
blocked
=
s
ignal_s
et
;
current
->
blocked
=
set
;
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sigmask_lock
);
/* If currently owning the floating point - give them up */
if
(
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
current
);
/*
* Set to point to the next rt_sigframe - this is used to
* determine whether this is the last signal to process
*/
signalregs
=
(
struct
sigregs32
*
)
(
u64
)
sigctx
.
regs
;
/* If currently owning the floating point - give them up */
if
(
regs
->
msr
&
MSR_FP
)
giveup_fpu
(
current
);
if
(
copy_from_user
(
saved_regs
,
&
signalregs
->
gp_regs
,
sizeof
(
signalregs
->
gp_regs
)))
sr
=
(
struct
sigregs32
*
)(
u64
)
sigctx
.
regs
;
if
(
copy_from_user
(
saved_regs
,
&
sr
->
gp_regs
,
sizeof
(
sr
->
gp_regs
)))
goto
badframe
;
/*
* The saved reg structure in the frame is an elf_grepset_t32,
...
...
@@ -544,7 +506,7 @@ long sys32_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
asmlinkage
long
sys32_rt_sigaction
(
int
sig
,
const
struct
sigaction32
*
act
,
long
sys32_rt_sigaction
(
int
sig
,
const
struct
sigaction32
*
act
,
struct
sigaction32
*
oact
,
size_t
sigsetsize
)
{
struct
k_sigaction
new_ka
,
old_ka
;
...
...
@@ -599,7 +561,7 @@ asmlinkage long sys32_rt_sigaction(int sig, const struct sigaction32 *act,
}
extern
asmlinkage
long
sys_rt_sigprocmask
(
int
how
,
sigset_t
*
set
,
extern
long
sys_rt_sigprocmask
(
int
how
,
sigset_t
*
set
,
sigset_t
*
oset
,
size_t
sigsetsize
);
/*
...
...
@@ -609,7 +571,7 @@ extern asmlinkage long sys_rt_sigprocmask(int how, sigset_t *set,
* of a signed int (msr in 32-bit mode) and the register representation
* of a signed int (msr in 64-bit mode) is performed.
*/
asmlinkage
long
sys32_rt_sigprocmask
(
u32
how
,
sigset32_t
*
set
,
long
sys32_rt_sigprocmask
(
u32
how
,
sigset32_t
*
set
,
sigset32_t
*
oset
,
size_t
sigsetsize
)
{
sigset_t
s
;
...
...
@@ -649,10 +611,10 @@ asmlinkage long sys32_rt_sigprocmask(u32 how, sigset32_t *set,
}
extern
asmlinkage
long
sys_rt_sigpending
(
sigset_t
*
set
,
size_t
sigsetsize
);
extern
long
sys_rt_sigpending
(
sigset_t
*
set
,
size_t
sigsetsize
);
asmlinkage
long
sys32_rt_sigpending
(
sigset32_t
*
set
,
long
sys32_rt_sigpending
(
sigset32_t
*
set
,
__kernel_size_t32
sigsetsize
)
{
sigset_t
s
;
...
...
@@ -677,50 +639,54 @@ asmlinkage long sys32_rt_sigpending(sigset32_t *set,
}
s
iginfo_t32
*
siginfo64to
32
(
siginfo_t32
*
d
,
siginfo_t
*
s
)
s
tatic
int
copy_siginfo_to_user
32
(
siginfo_t32
*
d
,
siginfo_t
*
s
)
{
memset
(
d
,
0
,
sizeof
(
siginfo_t32
));
d
->
si_signo
=
s
->
si_signo
;
d
->
si_errno
=
s
->
si_errno
;
/* XXX why dont we just implement copy_siginfo_to_user32? - Anton */
d
->
si_code
=
s
->
si_code
&
0xffff
;
int
err
;
if
(
!
access_ok
(
VERIFY_WRITE
,
d
,
sizeof
(
*
d
)))
return
-
EFAULT
;
err
=
__put_user
(
s
->
si_signo
,
&
d
->
si_signo
);
err
|=
__put_user
(
s
->
si_errno
,
&
d
->
si_errno
);
err
|=
__put_user
((
short
)
s
->
si_code
,
&
d
->
si_code
);
if
(
s
->
si_signo
>=
SIGRTMIN
)
{
d
->
si_pid
=
s
->
si_pid
;
d
->
si_uid
=
s
->
si_uid
;
d
->
si_int
=
s
->
si_int
;
err
|=
__put_user
(
s
->
si_pid
,
&
d
->
si_pid
)
;
err
|=
__put_user
(
s
->
si_uid
,
&
d
->
si_uid
)
;
err
|=
__put_user
(
s
->
si_int
,
&
d
->
si_int
)
;
}
else
{
switch
(
s
->
si_signo
)
{
/* XXX: What about POSIX1.b timers */
case
SIGCHLD
:
d
->
si_pid
=
s
->
si_pid
;
d
->
si_status
=
s
->
si_status
;
d
->
si_utime
=
s
->
si_utime
;
d
->
si_stime
=
s
->
si_stime
;
err
|=
__put_user
(
s
->
si_pid
,
&
d
->
si_pid
)
;
err
|=
__put_user
(
s
->
si_status
,
&
d
->
si_status
)
;
err
|=
__put_user
(
s
->
si_utime
,
&
d
->
si_utime
)
;
err
|=
__put_user
(
s
->
si_stime
,
&
d
->
si_stime
)
;
break
;
case
SIGSEGV
:
case
SIGBUS
:
case
SIGFPE
:
case
SIGILL
:
d
->
si_addr
=
(
long
)(
s
->
si_addr
);
err
|=
__put_user
((
long
)(
s
->
si_addr
),
&
d
->
si_addr
);
break
;
case
SIGPOLL
:
d
->
si_band
=
s
->
si_band
;
d
->
si_fd
=
s
->
si_fd
;
err
|=
__put_user
(
s
->
si_band
,
&
d
->
si_band
)
;
err
|=
__put_user
(
s
->
si_fd
,
&
d
->
si_fd
)
;
break
;
default:
d
->
si_pid
=
s
->
si_pid
;
d
->
si_uid
=
s
->
si_uid
;
err
|=
__put_user
(
s
->
si_pid
,
&
d
->
si_pid
)
;
err
|=
__put_user
(
s
->
si_uid
,
&
d
->
si_uid
)
;
break
;
}
}
return
d
;
return
err
;
}
extern
asmlinkage
long
sys_rt_sigtimedwait
(
const
sigset_t
*
uthese
,
extern
long
sys_rt_sigtimedwait
(
const
sigset_t
*
uthese
,
siginfo_t
*
uinfo
,
const
struct
timespec
*
uts
,
size_t
sigsetsize
);
asmlinkage
long
sys32_rt_sigtimedwait
(
sigset32_t
*
uthese
,
siginfo_t32
*
uinfo
,
long
sys32_rt_sigtimedwait
(
sigset32_t
*
uthese
,
siginfo_t32
*
uinfo
,
struct
timespec32
*
uts
,
__kernel_size_t32
sigsetsize
)
{
sigset_t
s
;
...
...
@@ -729,8 +695,7 @@ asmlinkage long sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,
int
ret
;
mm_segment_t
old_fs
=
get_fs
();
siginfo_t
info
;
siginfo_t32
info32
;
if
(
copy_from_user
(
&
s32
,
uthese
,
sizeof
(
sigset32_t
)))
return
-
EFAULT
;
switch
(
_NSIG_WORDS
)
{
...
...
@@ -753,8 +718,7 @@ asmlinkage long sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,
sigsetsize
);
set_fs
(
old_fs
);
if
(
ret
>=
0
&&
uinfo
)
{
if
(
copy_to_user
(
uinfo
,
siginfo64to32
(
&
info32
,
&
info
),
sizeof
(
siginfo_t32
)))
if
(
copy_siginfo_to_user32
(
uinfo
,
&
info
))
return
-
EFAULT
;
}
return
ret
;
...
...
@@ -762,7 +726,7 @@ asmlinkage long sys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,
siginfo_t
*
siginfo32to64
(
siginfo_t
*
d
,
siginfo_t32
*
s
)
s
tatic
s
iginfo_t
*
siginfo32to64
(
siginfo_t
*
d
,
siginfo_t32
*
s
)
{
d
->
si_signo
=
s
->
si_signo
;
d
->
si_errno
=
s
->
si_errno
;
...
...
@@ -800,7 +764,7 @@ siginfo_t * siginfo32to64(siginfo_t *d, siginfo_t32 *s)
}
extern
asmlinkage
long
sys_rt_sigqueueinfo
(
int
pid
,
int
sig
,
siginfo_t
*
uinfo
);
extern
long
sys_rt_sigqueueinfo
(
int
pid
,
int
sig
,
siginfo_t
*
uinfo
);
/*
* Note: it is necessary to treat pid and sig as unsigned ints, with the
...
...
@@ -809,7 +773,7 @@ extern asmlinkage long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);
* (msr in 32-bit mode) and the register representation of a signed int
* (msr in 64-bit mode) is performed.
*/
asmlinkage
long
sys32_rt_sigqueueinfo
(
u32
pid
,
u32
sig
,
siginfo_t32
*
uinfo
)
long
sys32_rt_sigqueueinfo
(
u32
pid
,
u32
sig
,
siginfo_t32
*
uinfo
)
{
siginfo_t
info
;
siginfo_t32
info32
;
...
...
@@ -974,8 +938,7 @@ static void handle_signal32(unsigned long sig, siginfo_t *info,
unsigned
int
frame
)
{
struct
sigcontext32_struct
*
sc
;
struct
rt_sigframe_32
*
rt_stack_frame
;
siginfo_t32
siginfo32bit
;
struct
rt_sigframe_32
*
rt_sf
;
struct
k_sigaction
*
ka
=
&
current
->
sig
->
action
[
sig
-
1
];
if
(
regs
->
trap
==
0x0C00
/* System Call! */
...
...
@@ -986,42 +949,35 @@ static void handle_signal32(unsigned long sig, siginfo_t *info,
/*
* Set up the signal frame
* Determine if a
n real time frame - siginfo
required
* Determine if a
real time frame and a siginfo is
required
*/
if
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
{
siginfo64to32
(
&
siginfo32bit
,
info
);
*
newspp
-=
sizeof
(
*
rt_stack_frame
);
rt_stack_frame
=
(
struct
rt_sigframe_32
*
)(
u64
)(
*
newspp
);
if
(
verify_area
(
VERIFY_WRITE
,
rt_stack_frame
,
sizeof
(
*
rt_stack_frame
)))
*
newspp
-=
sizeof
(
*
rt_sf
);
rt_sf
=
(
struct
rt_sigframe_32
*
)(
u64
)(
*
newspp
);
if
(
verify_area
(
VERIFY_WRITE
,
rt_sf
,
sizeof
(
*
rt_sf
)))
goto
badframe
;
if
(
__put_user
((
u32
)(
u64
)
ka
->
sa
.
sa_handler
,
&
rt_stack_frame
->
uc
.
uc_mcontext
.
handler
)
||
__put_user
((
u32
)(
u64
)
&
rt_stack_frame
->
info
,
&
rt_stack_frame
->
pinfo
)
||
__put_user
((
u32
)(
u64
)
&
rt_stack_frame
->
uc
,
&
rt_stack_frame
->
puc
)
&
rt_sf
->
uc
.
uc_mcontext
.
handler
)
||
__put_user
((
u32
)(
u64
)
&
rt_sf
->
info
,
&
rt_sf
->
pinfo
)
||
__put_user
((
u32
)(
u64
)
&
rt_sf
->
uc
,
&
rt_sf
->
puc
)
/* put the siginfo on the user stack */
||
__copy_to_user
(
&
rt_stack_frame
->
info
,
&
siginfo32bit
,
sizeof
(
siginfo32bit
))
||
copy_siginfo_to_user32
(
&
rt_sf
->
info
,
info
)
/* set the ucontext on the user stack */
||
__put_user
(
0
,
&
rt_stack_frame
->
uc
.
uc_flags
)
||
__put_user
(
0
,
&
rt_stack_frame
->
uc
.
uc_link
)
||
__put_user
(
current
->
sas_ss_sp
,
&
rt_stack_frame
->
uc
.
uc_stack
.
ss_sp
)
||
__put_user
(
0
,
&
rt_sf
->
uc
.
uc_flags
)
||
__put_user
(
0
,
&
rt_sf
->
uc
.
uc_link
)
||
__put_user
(
current
->
sas_ss_sp
,
&
rt_sf
->
uc
.
uc_stack
.
ss_sp
)
||
__put_user
(
sas_ss_flags
(
regs
->
gpr
[
1
]),
&
rt_s
tack_frame
->
uc
.
uc_stack
.
ss_flags
)
&
rt_s
f
->
uc
.
uc_stack
.
ss_flags
)
||
__put_user
(
current
->
sas_ss_size
,
&
rt_s
tack_frame
->
uc
.
uc_stack
.
ss_size
)
||
__copy_to_user
(
&
rt_s
tack_frame
->
uc
.
uc_sigmask
,
&
rt_s
f
->
uc
.
uc_stack
.
ss_size
)
||
__copy_to_user
(
&
rt_s
f
->
uc
.
uc_sigmask
,
oldset
,
sizeof
(
*
oldset
))
/* point the mcontext.regs to the pramble register frame */
||
__put_user
(
frame
,
&
rt_s
tack_frame
->
uc
.
uc_mcontext
.
regs
)
||
__put_user
(
sig
,
&
rt_s
tack_frame
->
uc
.
uc_mcontext
.
signal
))
||
__put_user
(
frame
,
&
rt_s
f
->
uc
.
uc_mcontext
.
regs
)
||
__put_user
(
sig
,
&
rt_s
f
->
uc
.
uc_mcontext
.
signal
))
goto
badframe
;
}
else
{
/* Put a
nother
sigcontext on the stack */
/* Put a sigcontext on the stack */
*
newspp
-=
sizeof
(
*
sc
);
sc
=
(
struct
sigcontext32_struct
*
)(
u64
)
*
newspp
;
if
(
verify_area
(
VERIFY_WRITE
,
sc
,
sizeof
(
*
sc
)))
...
...
@@ -1048,7 +1004,6 @@ static void handle_signal32(unsigned long sig, siginfo_t *info,
recalc_sigpending
();
spin_unlock_irq
(
&
current
->
sigmask_lock
);
}
return
;
badframe:
...
...
@@ -1068,7 +1023,7 @@ static void handle_signal32(unsigned long sig, siginfo_t *info,
* sigaltatck sys32_sigaltstack
*/
asmlinkage
int
sys32_sigaltstack
(
u32
newstack
,
u32
oldstack
,
int
p3
,
int
sys32_sigaltstack
(
u32
newstack
,
u32
oldstack
,
int
p3
,
int
p4
,
int
p6
,
int
p7
,
struct
pt_regs
*
regs
)
{
stack_t
uss
,
uoss
;
...
...
@@ -1114,7 +1069,7 @@ asmlinkage int sys32_sigaltstack(u32 newstack, u32 oldstack, int p3,
/*
* Start of do_signal32 routine
*
* This routine gets control when a pe
m
ding signal needs to be processed
* This routine gets control when a pe
n
ding signal needs to be processed
* in the 32 bit target thread -
*
* It handles both rt and non-rt signals
...
...
@@ -1141,13 +1096,13 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
signr
=
get_signal_to_deliver
(
&
info
,
regs
);
if
(
signr
>
0
)
{
ka
=
&
current
->
sig
->
action
[
signr
-
1
];
if
((
ka
->
sa
.
sa_flags
&
SA_ONSTACK
)
&&
(
!
on_sig_stack
(
regs
->
gpr
[
1
])))
if
((
ka
->
sa
.
sa_flags
&
SA_ONSTACK
)
&&
(
!
on_sig_stack
(
regs
->
gpr
[
1
])))
newsp
=
(
current
->
sas_ss_sp
+
current
->
sas_ss_size
);
else
newsp
=
regs
->
gpr
[
1
];
newsp
=
frame
=
newsp
-
sizeof
(
struct
sigregs32
);
/* Whee! Actually deliver the signal. */
handle_signal32
(
signr
,
&
info
,
oldset
,
regs
,
&
newsp
,
frame
);
}
...
...
@@ -1165,10 +1120,9 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs)
return
0
;
/* no signals delivered */
/* Invoke correct stack setup routine */
if
(
ka
->
sa
.
sa_flags
&
SA_SIGINFO
)
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/mm/init.c
View file @
20237c4d
/*
*
*
* PowerPC version
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
*
...
...
@@ -62,8 +60,6 @@
#include <asm/ppcdebug.h>
#define PGTOKB(pages) (((pages) * PAGE_SIZE) >> 10)
#ifdef CONFIG_PPC_ISERIES
#include <asm/iSeries/iSeries_dma.h>
#endif
...
...
@@ -78,13 +74,10 @@ extern pgd_t swapper_pg_dir[];
extern
char
__init_begin
,
__init_end
;
extern
char
__chrp_begin
,
__chrp_end
;
extern
char
__openfirmware_begin
,
__openfirmware_end
;
extern
struct
_of_tce_table
of_tce_table
[];
extern
char
_start
[],
_end
[];
extern
char
_stext
[],
etext
[];
extern
struct
task_struct
*
current_set
[
NR_CPUS
];
void
mm_init_ppc64
(
void
);
extern
pgd_t
ioremap_dir
[];
pgd_t
*
ioremap_pgd
=
(
pgd_t
*
)
&
ioremap_dir
;
...
...
@@ -179,7 +172,7 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags)
else
{
ea
=
ioremap_bot
;
ioremap_bot
+=
size
;
}
}
if
((
flags
&
_PAGE_PRESENT
)
==
0
)
flags
|=
pgprot_val
(
PAGE_KERNEL
);
...
...
@@ -196,9 +189,9 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags)
void
iounmap
(
void
*
addr
)
{
#ifdef CONFIG_PPC_ISERIES
/* iSeries I/O Remap is a noop */
/* iSeries I/O Remap is a noop */
return
;
#else
#else
/* DRENG / PPPBBB todo */
return
;
#endif
...
...
@@ -229,7 +222,7 @@ static void map_io_page(unsigned long ea, unsigned long pa, int flags)
/* If the mm subsystem is not fully up, we cannot create a
* linux page table entry for this mapping. Simply bolt an
* entry in the hardware page table.
*/
*/
vsid
=
get_kernel_vsid
(
ea
);
ppc_md
.
make_pte
(
htab_data
.
htab
,
(
vsid
<<
28
)
|
(
ea
&
0xFFFFFFF
),
// va (NOT the ea)
...
...
@@ -435,12 +428,12 @@ void __init mm_init_ppc64(void)
* The range of contexts [FIRST_USER_CONTEXT, NUM_USER_CONTEXT)
* are stored on a stack/queue for easy allocation and deallocation.
*/
mmu_context_queue
.
lock
=
SPIN_LOCK_UNLOCKED
;
mmu_context_queue
.
head
=
0
;
mmu_context_queue
.
tail
=
NUM_USER_CONTEXT
-
1
;
mmu_context_queue
.
size
=
NUM_USER_CONTEXT
;
mmu_context_queue
.
lock
=
SPIN_LOCK_UNLOCKED
;
mmu_context_queue
.
head
=
0
;
mmu_context_queue
.
tail
=
NUM_USER_CONTEXT
-
1
;
mmu_context_queue
.
size
=
NUM_USER_CONTEXT
;
for
(
index
=
0
;
index
<
NUM_USER_CONTEXT
;
index
++
)
{
mmu_context_queue
.
elements
[
index
]
=
index
+
FIRST_USER_CONTEXT
;
mmu_context_queue
.
elements
[
index
]
=
index
+
FIRST_USER_CONTEXT
;
}
/* Setup guard pages for the Paca's */
...
...
@@ -463,7 +456,6 @@ void __init do_init_bootmem(void)
unsigned
long
start
,
bootmap_pages
;
unsigned
long
total_pages
=
lmb_end_of_DRAM
()
>>
PAGE_SHIFT
;
PPCDBG
(
PPCDBG_MMINIT
,
"do_init_bootmem: start
\n
"
);
/*
* Find an area to use for the bootmem bitmap. Calculate the size of
* bitmap required as (Total Memory) / PAGE_SIZE / BITS_PER_BYTE.
...
...
@@ -472,21 +464,16 @@ void __init do_init_bootmem(void)
bootmap_pages
=
bootmem_bootmap_pages
(
total_pages
);
start
=
(
unsigned
long
)
__a2p
(
lmb_alloc
(
bootmap_pages
<<
PAGE_SHIFT
,
PAGE_SIZE
));
if
(
start
==
0
)
{
if
(
start
==
0
)
{
udbg_printf
(
"do_init_bootmem: failed to allocate a bitmap.
\n
"
);
udbg_printf
(
"
\t
bootmap_pages = 0x%lx.
\n
"
,
bootmap_pages
);
PPCDBG_ENTER_DEBUGGER
();
}
PPCDBG
(
PPCDBG_MMINIT
,
"
\t
start = 0x%lx
\n
"
,
start
);
PPCDBG
(
PPCDBG_MMINIT
,
"
\t
bootmap_pages = 0x%lx
\n
"
,
bootmap_pages
);
PPCDBG
(
PPCDBG_MMINIT
,
"
\t
physicalMemorySize = 0x%lx
\n
"
,
naca
->
physicalMemorySize
);
boot_mapsize
=
init_bootmem
(
start
>>
PAGE_SHIFT
,
total_pages
);
PPCDBG
(
PPCDBG_MMINIT
,
"
\t
boot_mapsize = 0x%lx
\n
"
,
boot_mapsize
);
/* add all physical memory to the bootmem map */
for
(
i
=
0
;
i
<
lmb
.
memory
.
cnt
;
i
++
)
{
for
(
i
=
0
;
i
<
lmb
.
memory
.
cnt
;
i
++
)
{
unsigned
long
physbase
,
size
;
unsigned
long
type
=
lmb
.
memory
.
region
[
i
].
type
;
...
...
@@ -497,19 +484,14 @@ void __init do_init_bootmem(void)
size
=
lmb
.
memory
.
region
[
i
].
size
;
free_bootmem
(
physbase
,
size
);
}
/* reserve the sections we're already using */
for
(
i
=
0
;
i
<
lmb
.
reserved
.
cnt
;
i
++
)
{
for
(
i
=
0
;
i
<
lmb
.
reserved
.
cnt
;
i
++
)
{
unsigned
long
physbase
=
lmb
.
reserved
.
region
[
i
].
physbase
;
unsigned
long
size
=
lmb
.
reserved
.
region
[
i
].
size
;
#if 0 /* PPPBBB */
if ( (physbase == 0) && (size < (16<<20)) ) {
size = 16 << 20;
}
#endif
reserve_bootmem
(
physbase
,
size
);
}
PPCDBG
(
PPCDBG_MMINIT
,
"do_init_bootmem: end
\n
"
);
}
/*
...
...
@@ -522,7 +504,7 @@ void __init paging_init(void)
/*
* All pages are DMA-able so we put them all in the DMA zone.
*/
zones_size
[
0
]
=
lmb_end_of_DRAM
()
>>
PAGE_SHIFT
;
zones_size
[
ZONE_DMA
]
=
lmb_end_of_DRAM
()
>>
PAGE_SHIFT
;
for
(
i
=
1
;
i
<
MAX_NR_ZONES
;
i
++
)
zones_size
[
i
]
=
0
;
free_area_init
(
zones_size
);
...
...
@@ -554,14 +536,6 @@ void __init mem_init(void)
totalram_pages
+=
free_all_bootmem
();
ifppcdebug
(
PPCDBG_MMINIT
)
{
udbg_printf
(
"mem_init: totalram_pages = 0x%lx
\n
"
,
totalram_pages
);
udbg_printf
(
"mem_init: va_rtas_base = 0x%lx
\n
"
,
va_rtas_base
);
udbg_printf
(
"mem_init: va_rtas_end = 0x%lx
\n
"
,
PAGE_ALIGN
(
va_rtas_base
+
rtas
.
size
));
udbg_printf
(
"mem_init: pinned start = 0x%lx
\n
"
,
__va
(
0
));
udbg_printf
(
"mem_init: pinned end = 0x%lx
\n
"
,
PAGE_ALIGN
(
klimit
));
}
if
(
sysmap_size
)
for
(
addr
=
(
unsigned
long
)
sysmap
;
addr
<
PAGE_ALIGN
((
unsigned
long
)
sysmap
+
sysmap_size
)
;
...
...
@@ -582,7 +556,7 @@ void __init mem_init(void)
datapages
++
;
}
printk
(
"Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08lx,%08lx]
\n
"
,
printk
(
"Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08lx,%08lx]
\n
"
,
(
unsigned
long
)
nr_free_pages
()
<<
(
PAGE_SHIFT
-
10
),
codepages
<<
(
PAGE_SHIFT
-
10
),
datapages
<<
(
PAGE_SHIFT
-
10
),
initpages
<<
(
PAGE_SHIFT
-
10
),
...
...
@@ -620,12 +594,13 @@ void flush_icache_page(struct vm_area_struct *vma, struct page *page)
}
}
void
clear_user_page
(
void
*
page
,
unsigned
long
vaddr
)
void
clear_user_page
(
void
*
page
,
unsigned
long
vaddr
,
struct
page
*
pg
)
{
clear_page
(
page
);
}
void
copy_user_page
(
void
*
vto
,
void
*
vfrom
,
unsigned
long
vaddr
)
void
copy_user_page
(
void
*
vto
,
void
*
vfrom
,
unsigned
long
vaddr
,
struct
page
*
pg
)
{
copy_page
(
vto
,
vfrom
);
__flush_dcache_icache
(
vto
);
...
...
include/asm-ppc64/page.h
View file @
20237c4d
...
...
@@ -70,8 +70,8 @@ static __inline__ void clear_page(void *addr)
extern
void
copy_page
(
void
*
to
,
void
*
from
);
struct
page
;
extern
void
clear_user_page
(
void
*
page
,
unsigned
long
vaddr
);
extern
void
copy_user_page
(
void
*
to
,
void
*
from
,
unsigned
long
vaddr
);
extern
void
clear_user_page
(
void
*
page
,
unsigned
long
vaddr
,
struct
page
*
pg
);
extern
void
copy_user_page
(
void
*
to
,
void
*
from
,
unsigned
long
vaddr
,
struct
page
*
p
);
#ifdef STRICT_MM_TYPECHECKS
/*
...
...
include/asm-ppc64/pgalloc.h
View file @
20237c4d
...
...
@@ -53,6 +53,8 @@ pmd_free(pmd_t *pmd)
free_page
((
unsigned
long
)
pmd
);
}
#define pmd_free_tlb(tlb, pmd) pmd_free(pmd)
#define pmd_populate_kernel(mm, pmd, pte) pmd_set(pmd, pte)
#define pmd_populate(mm, pmd, pte_page) \
pmd_populate_kernel(mm, pmd, page_address(pte_page))
...
...
@@ -86,6 +88,7 @@ pte_free_kernel(pte_t *pte)
}
#define pte_free(pte_page) pte_free_kernel(page_address(pte_page))
#define pte_free_tlb(tlb, pte) pte_free(pte)
#define check_pgt_cache() do { } while (0)
...
...
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