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
48822524
Commit
48822524
authored
Feb 21, 2002
by
Anton Blanchard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rework kernel stack usage
remove old ioctls
parent
efe80e09
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
88 additions
and
116 deletions
+88
-116
arch/ppc64/kernel/entry.S
arch/ppc64/kernel/entry.S
+28
-22
arch/ppc64/kernel/ioctl32.c
arch/ppc64/kernel/ioctl32.c
+0
-4
arch/ppc64/kernel/misc.S
arch/ppc64/kernel/misc.S
+3
-13
arch/ppc64/kernel/mk_defs.c
arch/ppc64/kernel/mk_defs.c
+4
-2
arch/ppc64/kernel/process.c
arch/ppc64/kernel/process.c
+53
-75
No files found.
arch/ppc64/kernel/entry.S
View file @
48822524
...
...
@@ -42,10 +42,19 @@ show_syscalls_task:
.
long
-
1
#endif
.
section
".toc"
,
"aw"
.
SYS_CALL_TABLE
:
.
tc
.
sys_call_table
[
TC
],
.
sys_call_table
.
SYS_CALL_TABLE32
:
.
tc
.
sys_call_table32
[
TC
],
.
sys_call_table32
.
section
".text"
.
align
3
/*
*
Handle
a
system
call
.
*/
.
text
_GLOBAL
(
DoSyscall
)
std
r0
,
THREAD
+
LAST_SYSCALL
(
r13
)
ld
r11
,
_CCR
(
r1
)
/*
Clear
SO
bit
in
CR
*/
...
...
@@ -94,7 +103,7 @@ _GLOBAL(DoSyscall)
#ifdef CONFIG_BINFMT_ELF32
andi
.
r11
,
r10
,
_TIF_32BIT
beq
-
15
f
LOADADDR
(
r10
,.
sys_call_table3
2
)
ld
r10
,
.
SYS_CALL_TABLE32
@
toc
(
2
)
/*
*
Now
mung
the
first
4
parameters
into
shape
,
by
making
certain
that
*
the
high
bits
(
most
significant
32
bits
in
64
bit
reg
)
are
0
...
...
@@ -111,7 +120,7 @@ _GLOBAL(DoSyscall)
b
17
f
15
:
#endif
LOADADDR
(
r10
,.
sys_call_table
)
ld
r10
,
.
SYS_CALL_TABLE
@
toc
(
2
)
17
:
slwi
r0
,
r0
,
3
ldx
r10
,
r10
,
r0
/*
Fetch
system
call
handler
[
ptr
]
*/
mtlr
r10
...
...
@@ -167,7 +176,7 @@ _GLOBAL(ret_from_syscall_1)
ld
r10
,
TI_FLAGS
(
r10
)
andi
.
r11
,
r10
,
_TIF_32BIT
beq
-
55
f
LOADADDR
(
r10
,.
sys_call_table3
2
)
ld
r10
,
.
SYS_CALL_TABLE32
@
toc
(
2
)
/*
*
Now
mung
the
first
4
parameters
into
shape
,
by
making
certain
that
*
the
high
bits
(
most
significant
32
bits
in
64
bit
reg
)
are
0
...
...
@@ -184,7 +193,7 @@ _GLOBAL(ret_from_syscall_1)
b
57
f
55
:
#endif
LOADADDR
(
r10
,.
sys_call_table
)
ld
r10
,
.
SYS_CALL_TABLE
@
toc
(
2
)
57
:
slwi
r0
,
r0
,
3
ldx
r10
,
r10
,
r0
/*
Fetch
system
call
handler
[
ptr
]
*/
...
...
@@ -255,38 +264,33 @@ _GLOBAL(ppc64_rt_sigreturn)
*
Note
:
there
are
two
ways
to
get
to
the
"going out"
portion
*
of
this
code
; either by coming in via the entry (_switch)
*
or
via
"fork"
which
must
set
up
an
environment
equivalent
*
to
the
"_switch"
path
.
If
you
change
this
(
or
in
particular
,
th
e
*
SAVE_REGS
macro
),
you
'll have to change
the fork code also.
*
to
the
"_switch"
path
.
If
you
change
this
you
'll have to chang
e
*
the
fork
code
also
.
*
*
The
code
which
creates
the
new
task
context
is
in
'copy_thread'
*
in
arch
/
ppc
/
kernel
/
process
.
c
*
in
arch
/
ppc
64
/
kernel
/
process
.
c
*/
_GLOBAL
(
_switch
)
stdu
r1
,-
INT_FRAME_SIZE
(
r1
)
ld
r6
,
0
(
r1
)
std
r6
,
GPR1
(
r1
)
mflr
r0
std
r0
,
16
(
r1
)
std
u
r1
,-
SWITCH_FRAME_SIZE
(
r1
)
/
*
r3
-
r13
are
caller
saved
--
Cort
*/
SAVE_GPR
(2,
r1
)
SAVE_8GPRS
(14,
r1
)
SAVE_10GPRS
(22,
r1
)
mflr
r20
/*
Return
to
switch
caller
*/
mfmsr
r22
andi
.
r21
,
r22
,
MSR_FP
beq
+
1
f
li
r6
,
MSR_FP
/*
Disable
floating
-
point
*/
andc
r22
,
r22
,
r6
mtmsrd
r22
isync
std
r20
,
_NIP
(
r1
)
std
r22
,
_MSR
(
r1
)
std
r20
,
_LINK
(
r1
)
mfcr
r20
std
r20
,
_CCR
(
r1
)
li
r6
,
0x0ff0
std
r6
,
TRAP
(
r1
)
1
:
std
r20
,
_NIP
(
r1
)
mfcr
r23
std
r23
,
_CCR
(
r1
)
std
r1
,
KSP
(
r3
)
/*
Set
old
stack
pointer
*/
mfspr
r5
,
SPRG3
/*
Get
Paca
*/
/
*
XXX
remove
-
Anton
*/
addi
r3
,
r3
,-
THREAD
/*
old
'current'
for
return
value
*/
addi
r13
,
r4
,-
THREAD
/*
Convert
THREAD
to
'current'
*/
std
r13
,
PACACURRENT
(
r5
)
/*
Set
new
'current'
*/
...
...
@@ -298,6 +302,7 @@ _GLOBAL(_switch)
insrdi
r9
,
r7
,
1
,
63
/*
Insert
run
light
into
CTRL
*/
mtspr
CTRLT
,
r9
#endif
ld
r1
,
KSP
(
r4
)
/*
Load
new
stack
pointer
*/
ld
r6
,
_CCR
(
r1
)
mtcrf
0xFF
,
r6
...
...
@@ -306,8 +311,8 @@ _GLOBAL(_switch)
REST_10GPRS
(22,
r1
)
ld
r7
,
_NIP
(
r1
)
/*
Return
to
_switch
caller
in
new
task
*/
ld
r1
,
GPR1
(
r1
)
mtlr
r7
addi
r1
,
r1
,
SWITCH_FRAME_SIZE
blr
_GLOBAL
(
ret_from_fork
)
...
...
@@ -377,6 +382,7 @@ restore:
mtlr
r0
ld
r3
,
_XER
(
r1
)
mtspr
XER
,
r3
REST_8GPRS
(5,
r1
)
REST_10GPRS
(14,
r1
)
REST_8GPRS
(24,
r1
)
...
...
arch/ppc64/kernel/ioctl32.c
View file @
48822524
...
...
@@ -3737,8 +3737,6 @@ COMPATIBLE_IOCTL(BLKROSET),
COMPATIBLE_IOCTL
(
BLKROGET
),
COMPATIBLE_IOCTL
(
BLKRRPART
),
COMPATIBLE_IOCTL
(
BLKFLSBUF
),
COMPATIBLE_IOCTL
(
BLKRASET
),
COMPATIBLE_IOCTL
(
BLKFRASET
),
COMPATIBLE_IOCTL
(
BLKSECTSET
),
COMPATIBLE_IOCTL
(
BLKSSZGET
),
COMPATIBLE_IOCTL
(
BLKBSZGET
),
...
...
@@ -4311,10 +4309,8 @@ HANDLE_IOCTL(SIOCDELRT, routing_ioctl),
HANDLE_IOCTL
(
SIOCRTMSG
,
ret_einval
),
HANDLE_IOCTL
(
SIOCGSTAMP
,
do_siocgstamp
),
HANDLE_IOCTL
(
HDIO_GETGEO
,
hdio_getgeo
),
HANDLE_IOCTL
(
BLKRAGET
,
w_long
),
HANDLE_IOCTL
(
BLKGETSIZE
,
w_long
),
HANDLE_IOCTL
(
0x1260
,
broken_blkgetsize
),
HANDLE_IOCTL
(
BLKFRAGET
,
w_long
),
HANDLE_IOCTL
(
BLKSECTGET
,
w_long
),
HANDLE_IOCTL
(
BLKPG
,
blkpg_ioctl_trans
),
HANDLE_IOCTL
(
HDIO_GET_KEEPSETTINGS
,
hdio_ioctl_trans
),
...
...
arch/ppc64/kernel/misc.S
View file @
48822524
...
...
@@ -496,25 +496,15 @@ _GLOBAL(cvt_df)
*
kernel_thread
(
fn
,
arg
,
flags
)
*/
_GLOBAL
(
kernel_thread
)
/
*
XXX
fix
this
when
we
optimise
syscall
entry
to
not
save
volatiles
*/
mr
r6
,
r3
/*
function
*/
ori
r3
,
r5
,
CLONE_VM
/*
flags
*/
li
r0
,
__NR_clone
sc
cmpi
0
,
r3
,
0
/*
parent
or
child
?
*/
bnelr
/*
return
if
parent
*/
li
r0
,
0
/*
clear
out
p
->
thread
.
regs
*/
std
r0
,
THREAD
+
PT_REGS
(
r13
)
/*
since
we
don
't have user ctx */
clrrdi
r5
,
r1
,
THREAD_SHIFT
ld
r0
,
TI_FLAGS
(
r5
)
li
r7
,
_TIF_32BIT
andc
r0
,
r0
,
r7
#ifdef CONFIG_PPC_ISERIES
ori
r0
,
r0
,
_TIF_RUN_LIGHT
/*
Run
light
on
*/
#endif
std
r0
,
TI_FLAGS
(
r5
)
li
r0
,
0
stdu
r0
,-
STACK_FRAME_OVERHEAD
(
r1
)
ld
r2
,
8
(
r6
)
ld
r6
,
0
(
r6
)
mtlr
r6
/*
fn
addr
in
lr
*/
...
...
arch/ppc64/kernel/mk_defs.c
View file @
48822524
...
...
@@ -115,12 +115,14 @@ main(void)
/* Interrupt register frame */
DEFINE
(
STACK_FRAME_OVERHEAD
,
STACK_FRAME_OVERHEAD
);
DEFINE
(
SWITCH_FRAME_SIZE
,
STACK_FRAME_OVERHEAD
+
sizeof
(
struct
pt_regs
));
/* 288 = # of volatile regs, int & fp, for leaf routines */
/* which do not stack a frame. See the PPC64 ABI. */
DEFINE
(
INT_FRAME_SIZE
,
STACK_FRAME_OVERHEAD
+
sizeof
(
struct
pt_regs
)
+
288
);
/* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */
DEFINE
(
PROM_FRAME_SIZE
,
STACK_FRAME_OVERHEAD
+
sizeof
(
struct
pt_regs
)
+
16
+
288
);
DEFINE
(
RTAS_FRAME_SIZE
,
STACK_FRAME_OVERHEAD
+
sizeof
(
struct
pt_regs
)
+
16
+
288
);
DEFINE
(
PROM_FRAME_SIZE
,
STACK_FRAME_OVERHEAD
+
sizeof
(
struct
pt_regs
)
+
16
);
DEFINE
(
RTAS_FRAME_SIZE
,
STACK_FRAME_OVERHEAD
+
sizeof
(
struct
pt_regs
)
+
16
);
DEFINE
(
GPR0
,
STACK_FRAME_OVERHEAD
+
offsetof
(
struct
pt_regs
,
gpr
[
0
]));
DEFINE
(
GPR1
,
STACK_FRAME_OVERHEAD
+
offsetof
(
struct
pt_regs
,
gpr
[
1
]));
DEFINE
(
GPR2
,
STACK_FRAME_OVERHEAD
+
offsetof
(
struct
pt_regs
,
gpr
[
2
]));
...
...
arch/ppc64/kernel/process.c
View file @
48822524
/*
* linux/arch/ppc/kernel/process.c
* linux/arch/ppc
64
/kernel/process.c
*
* Derived from "arch/i386/kernel/process.c"
* Copyright (C) 1995 Linus Torvalds
...
...
@@ -45,19 +45,18 @@
#include <asm/iSeries/HvCallHpt.h>
#include <asm/Naca.h>
#include "ppc_defs.h"
int
dump_fpu
(
struct
pt_regs
*
regs
,
elf_fpregset_t
*
fpregs
);
extern
unsigned
long
_get_SP
(
void
);
struct
task_struct
*
last_task_used_math
=
NULL
;
struct
mm_struct
ioremap_mm
=
{
pgd
:
ioremap_dir
,
page_table_lock
:
SPIN_LOCK_UNLOCKED
};
char
*
sysmap
=
NULL
;
char
*
sysmap
=
NULL
;
unsigned
long
sysmap_size
=
0
;
extern
char
__toc_start
;
void
enable_kernel_fp
(
void
)
{
...
...
@@ -84,10 +83,7 @@ void
_switch_to
(
struct
task_struct
*
prev
,
struct
task_struct
*
new
)
{
struct
thread_struct
*
new_thread
,
*
old_thread
;
unsigned
long
s
;
__save_flags
(
s
);
__cli
();
unsigned
long
flags
;
#ifdef CONFIG_SMP
/* avoid complexity of lazy save/restore of fpu
...
...
@@ -99,14 +95,16 @@ _switch_to(struct task_struct *prev, struct task_struct *new)
* every switch, just a save.
* -- Cort
*/
if
(
prev
->
thread
.
regs
&&
(
prev
->
thread
.
regs
->
msr
&
MSR_FP
)
)
if
(
prev
->
thread
.
regs
&&
(
prev
->
thread
.
regs
->
msr
&
MSR_FP
)
)
giveup_fpu
(
prev
);
#endif
/* CONFIG_SMP */
new_thread
=
&
new
->
thread
;
old_thread
=
&
current
->
thread
;
__save_and_cli
(
flags
);
_switch
(
old_thread
,
new_thread
);
__restore_flags
(
s
);
__restore_flags
(
flag
s
);
}
void
show_regs
(
struct
pt_regs
*
regs
)
...
...
@@ -172,45 +170,50 @@ release_thread(struct task_struct *t)
int
copy_thread
(
int
nr
,
unsigned
long
clone_flags
,
unsigned
long
usp
,
unsigned
long
unused
,
struct
task_struct
*
p
,
struct
pt_regs
*
regs
)
struct
task_struct
*
p
,
struct
pt_regs
*
regs
)
{
unsigned
long
msr
;
struct
pt_regs
*
childregs
,
*
kregs
;
extern
void
ret_from_fork
(
void
);
/* XXX get rid of the -2 Anton */
unsigned
long
sp
=
(
unsigned
long
)
p
->
thread_info
+
THREAD_SIZE
;
/* Copy registers */
childregs
=
((
struct
pt_regs
*
)
((
unsigned
long
)
p
->
thread_info
+
THREAD_SIZE
-
STACK_FRAME_OVERHEAD
))
-
2
;
sp
-=
sizeof
(
struct
pt_regs
);
childregs
=
(
struct
pt_regs
*
)
sp
;
*
childregs
=
*
regs
;
if
((
childregs
->
msr
&
MSR_PR
)
==
0
)
{
/* for kernel thread, set `current' and stackptr in new task */
childregs
->
gpr
[
1
]
=
sp
+
sizeof
(
struct
pt_regs
);
childregs
->
gpr
[
13
]
=
(
unsigned
long
)
p
;
p
->
thread
.
regs
=
NULL
;
/* no user register state */
clear_ti_thread_flag
(
p
->
thread_info
,
TIF_32BIT
);
#ifdef CONFIG_PPC_ISERIES
set_ti_thread_flag
(
p
->
thread_info
,
TIF_RUN_LIGHT
);
#endif
}
else
p
->
thread
.
regs
=
childregs
;
childregs
->
gpr
[
3
]
=
0
;
/* Result from fork() */
p
->
thread
.
regs
=
childregs
;
p
->
thread
.
ksp
=
(
unsigned
long
)
childregs
-
STACK_FRAME_OVERHEAD
;
p
->
thread
.
ksp
-=
sizeof
(
struct
pt_regs
)
+
STACK_FRAME_OVERHEAD
;
kregs
=
(
struct
pt_regs
*
)(
p
->
thread
.
ksp
+
STACK_FRAME_OVERHEAD
);
/* The PPC64 compiler makes use of a TOC to contain function
sp
-=
STACK_FRAME_OVERHEAD
;
/*
* The way this works is that at some point in the future
* some task will call _switch to switch to the new task.
* That will pop off the stack frame created below and start
* the new task running at ret_from_fork. The new task will
* do some house keeping and then return from the fork or clone
* system call, using the stack frame created above.
*/
sp
-=
sizeof
(
struct
pt_regs
);
kregs
=
(
struct
pt_regs
*
)
sp
;
sp
-=
STACK_FRAME_OVERHEAD
;
p
->
thread
.
ksp
=
sp
;
/*
* The PPC64 ABI makes use of a TOC to contain function
* pointers. The function (ret_from_except) is actually a pointer
* to the TOC entry. The first entry is a pointer to the actual
* function.
*/
kregs
->
nip
=
*
((
unsigned
long
*
)
ret_from_fork
);
asm
volatile
(
"mfmsr %0"
:
"=r"
(
msr
)
:
);
kregs
->
msr
=
msr
;
kregs
->
gpr
[
1
]
=
(
unsigned
long
)
childregs
-
STACK_FRAME_OVERHEAD
;
kregs
->
gpr
[
2
]
=
(((
unsigned
long
)
&
__toc_start
)
+
0x8000
);
if
(
usp
>=
(
unsigned
long
)
regs
)
{
/* Stack is in kernel space - must adjust */
childregs
->
gpr
[
1
]
=
(
unsigned
long
)(
childregs
+
1
);
*
((
unsigned
long
*
)
childregs
->
gpr
[
1
])
=
0
;
childregs
->
gpr
[
13
]
=
(
unsigned
long
)
p
;
}
else
{
/* Provided stack is in user space */
childregs
->
gpr
[
1
]
=
usp
;
}
p
->
thread
.
last_syscall
=
-
1
;
/*
* copy fpu info - assume lazy fpu switch now always
...
...
@@ -223,6 +226,8 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
memcpy
(
&
p
->
thread
.
fpr
,
&
current
->
thread
.
fpr
,
sizeof
(
p
->
thread
.
fpr
));
p
->
thread
.
fpscr
=
current
->
thread
.
fpscr
;
p
->
thread
.
last_syscall
=
-
1
;
return
0
;
}
...
...
@@ -239,7 +244,6 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp)
unsigned
long
*
entry
=
(
unsigned
long
*
)
nip
;
unsigned
long
*
toc
=
entry
+
1
;
set_fs
(
USER_DS
);
memset
(
regs
->
gpr
,
0
,
sizeof
(
regs
->
gpr
));
memset
(
&
regs
->
ctr
,
0
,
4
*
sizeof
(
regs
->
ctr
));
...
...
@@ -252,53 +256,27 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp)
current
->
thread
.
fpscr
=
0
;
}
asmlinkage
int
sys_clone
(
int
p1
,
int
p2
,
int
p3
,
int
p4
,
int
p5
,
int
p6
,
struct
pt_regs
*
regs
)
int
sys_clone
(
int
p1
,
int
p2
,
int
p3
,
int
p4
,
int
p5
,
int
p6
,
struct
pt_regs
*
regs
)
{
unsigned
long
clone_flags
=
p1
;
int
res
;
res
=
do_fork
(
clone_flags
,
regs
->
gpr
[
1
],
regs
,
0
);
#ifdef CONFIG_SMP
/* When we clone the idle task we keep the same pid but
* the return value of 0 for both causes problems.
* -- Cort
*/
if
((
current
->
pid
==
0
)
&&
(
current
==
&
init_task
))
res
=
1
;
#endif
/* CONFIG_SMP */
return
res
;
return
do_fork
(
p1
,
regs
->
gpr
[
1
],
regs
,
0
);
}
asmlinkage
int
sys_fork
(
int
p1
,
int
p2
,
int
p3
,
int
p4
,
int
p5
,
int
p6
,
struct
pt_regs
*
regs
)
int
sys_fork
(
int
p1
,
int
p2
,
int
p3
,
int
p4
,
int
p5
,
int
p6
,
struct
pt_regs
*
regs
)
{
int
res
;
res
=
do_fork
(
SIGCHLD
,
regs
->
gpr
[
1
],
regs
,
0
);
#ifdef CONFIG_SMP
/* When we clone the idle task we keep the same pid but
* the return value of 0 for both causes problems.
* -- Cort
*/
if
((
current
->
pid
==
0
)
&&
(
current
==
&
init_task
))
res
=
1
;
#endif
/* CONFIG_SMP */
return
res
;
return
do_fork
(
SIGCHLD
,
regs
->
gpr
[
1
],
regs
,
0
);
}
asmlinkage
int
sys_vfork
(
int
p1
,
int
p2
,
int
p3
,
int
p4
,
int
p5
,
int
p6
,
int
sys_vfork
(
int
p1
,
int
p2
,
int
p3
,
int
p4
,
int
p5
,
int
p6
,
struct
pt_regs
*
regs
)
{
return
do_fork
(
CLONE_VFORK
|
CLONE_VM
|
SIGCHLD
,
regs
->
gpr
[
1
],
regs
,
0
);
}
asmlinkage
int
sys_execve
(
unsigned
long
a0
,
unsigned
long
a1
,
unsigned
long
a2
,
unsigned
long
a3
,
unsigned
long
a4
,
unsigned
long
a5
,
struct
pt_regs
*
regs
)
int
sys_execve
(
unsigned
long
a0
,
unsigned
long
a1
,
unsigned
long
a2
,
unsigned
long
a3
,
unsigned
long
a4
,
unsigned
long
a5
,
struct
pt_regs
*
regs
)
{
int
error
;
char
*
filename
;
...
...
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