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
db85be57
Commit
db85be57
authored
Mar 16, 2003
by
Paul Mackerras
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
PPC32: Better check for when we should expand the stack.
parent
e106935f
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
69 additions
and
0 deletions
+69
-0
arch/ppc/mm/fault.c
arch/ppc/mm/fault.c
+69
-0
No files found.
arch/ppc/mm/fault.c
View file @
db85be57
...
...
@@ -56,6 +56,41 @@ void bad_page_fault(struct pt_regs *, unsigned long, int sig);
void
do_page_fault
(
struct
pt_regs
*
,
unsigned
long
,
unsigned
long
);
extern
int
get_pteptr
(
struct
mm_struct
*
mm
,
unsigned
long
addr
,
pte_t
**
ptep
);
/*
* Check whether the instruction at regs->nip is a store using
* an update addressing form which will update r1.
*/
static
int
store_updates_sp
(
struct
pt_regs
*
regs
)
{
unsigned
int
inst
;
if
(
get_user
(
inst
,
(
unsigned
int
*
)
regs
->
nip
))
return
0
;
/* check for 1 in the rA field */
if
(((
inst
>>
16
)
&
0x1f
)
!=
1
)
return
0
;
/* check major opcode */
switch
(
inst
>>
26
)
{
case
37
:
/* stwu */
case
39
:
/* stbu */
case
45
:
/* sthu */
case
53
:
/* stfsu */
case
55
:
/* stfdu */
return
1
;
case
31
:
/* check minor opcode */
switch
((
inst
>>
1
)
&
0x3ff
)
{
case
183
:
/* stwux */
case
247
:
/* stbux */
case
439
:
/* sthux */
case
695
:
/* stfsux */
case
759
:
/* stfdux */
return
1
;
}
}
return
0
;
}
/*
* For 600- and 800-family processors, the error_code parameter is DSISR
* for a data fault, SRR1 for an instruction fault. For 400-family processors
...
...
@@ -112,6 +147,40 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
goto
good_area
;
if
(
!
(
vma
->
vm_flags
&
VM_GROWSDOWN
))
goto
bad_area
;
if
(
!
is_write
)
goto
bad_area
;
/*
* N.B. The rs6000/xcoff ABI allows programs to access up to
* a few hundred bytes below the stack pointer.
* The kernel signal delivery code writes up to about 1.5kB
* below the stack pointer (r1) before decrementing it.
* The exec code can write slightly over 640kB to the stack
* before setting the user r1. Thus we allow the stack to
* expand to 1MB without further checks.
*/
if
(
address
+
0x100000
<
vma
->
vm_end
)
{
/* get user regs even if this fault is in kernel mode */
struct
pt_regs
*
uregs
=
current
->
thread
.
regs
;
if
(
uregs
==
NULL
)
goto
bad_area
;
/*
* A user-mode access to an address a long way below
* the stack pointer is only valid if the instruction
* is one which would update the stack pointer to the
* address accessed if the instruction completed,
* i.e. either stwu rs,n(r1) or stwux rs,r1,rb
* (or the byte, halfword, float or double forms).
*
* If we don't check this then any write to the area
* between the last mapped region and the stack will
* expand the stack rather than segfaulting.
*/
if
(
address
+
2048
<
uregs
->
gpr
[
1
]
&&
(
!
user_mode
(
regs
)
||
!
store_updates_sp
(
regs
)))
goto
bad_area
;
}
if
(
expand_stack
(
vma
,
address
))
goto
bad_area
;
...
...
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