Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
8133aaa1
Commit
8133aaa1
authored
Nov 21, 2002
by
Jeff Dike
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
A number of small fixes for the uaccess merge.
parent
3817da13
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
82 additions
and
70 deletions
+82
-70
arch/um/include/kern_util.h
arch/um/include/kern_util.h
+2
-3
arch/um/include/um_uaccess.h
arch/um/include/um_uaccess.h
+1
-1
arch/um/kernel/Makefile
arch/um/kernel/Makefile
+1
-1
arch/um/kernel/process_kern.c
arch/um/kernel/process_kern.c
+13
-9
arch/um/kernel/skas/include/uaccess.h
arch/um/kernel/skas/include/uaccess.h
+1
-5
arch/um/kernel/trap_kern.c
arch/um/kernel/trap_kern.c
+63
-50
arch/um/kernel/tt/include/uaccess.h
arch/um/kernel/tt/include/uaccess.h
+1
-1
No files found.
arch/um/include/kern_util.h
View file @
8133aaa1
...
...
@@ -33,9 +33,8 @@ extern int do_signal(int error);
extern
int
is_stack_fault
(
unsigned
long
sp
);
extern
unsigned
long
segv
(
unsigned
long
address
,
unsigned
long
ip
,
int
is_write
,
int
is_user
,
void
*
sc
);
extern
unsigned
long
handle_page_fault
(
unsigned
long
address
,
unsigned
long
ip
,
int
is_write
,
int
is_user
,
int
*
code_out
);
extern
int
handle_page_fault
(
unsigned
long
address
,
unsigned
long
ip
,
int
is_write
,
int
is_user
,
int
*
code_out
);
extern
void
syscall_ready
(
void
);
extern
void
set_tracing
(
void
*
t
,
int
tracing
);
extern
int
is_tracing
(
void
*
task
);
...
...
arch/um/include/um_uaccess.h
View file @
8133aaa1
...
...
@@ -54,7 +54,7 @@ static inline int clear_user(void *mem, int len)
return
(
CHOOSE_MODE_PROC
(
clear_user_tt
,
clear_user_skas
,
mem
,
len
));
}
static
inline
int
strnlen_user
(
void
*
str
,
int
len
)
static
inline
int
strnlen_user
(
const
void
*
str
,
int
len
)
{
return
(
CHOOSE_MODE_PROC
(
strnlen_user_tt
,
strnlen_user_skas
,
str
,
len
));
}
...
...
arch/um/kernel/Makefile
View file @
8133aaa1
...
...
@@ -10,7 +10,7 @@ obj-y = config.o exec_kern.o exitcode.o frame_kern.o frame.o helper.o \
process_kern.o ptrace.o reboot.o resource.o sigio_user.o
\
sigio_kern.o signal_kern.o signal_user.o smp.o syscall_kern.o
\
syscall_user.o sysrq.o sys_call_table.o tempfile.o time.o
\
time_kern.o tlb.o trap_kern.o trap_user.o u
access_user.o u
m_arch.o
\
time_kern.o tlb.o trap_kern.o trap_user.o um_arch.o
\
umid.o user_util.o
obj-$(CONFIG_BLK_DEV_INITRD)
+=
initrd_kern.o initrd_user.o
...
...
arch/um/kernel/process_kern.c
View file @
8133aaa1
...
...
@@ -222,21 +222,25 @@ int page_mask(void)
return
(
PAGE_MASK
);
}
unsigned
long
um_virt_to_phys
(
void
*
t
,
unsigned
long
addr
)
void
*
um_virt_to_phys
(
struct
task_struct
*
task
,
unsigned
long
addr
,
pte_t
*
pte_out
)
{
struct
task_struct
*
task
;
pgd_t
*
pgd
;
pmd_t
*
pmd
;
pte_t
*
pte
;
task
=
t
;
if
(
task
->
mm
==
NULL
)
return
(
0xffffffff
);
if
(
task
->
mm
==
NULL
)
return
(
ERR_PTR
(
-
EINVAL
)
);
pgd
=
pgd_offset
(
task
->
mm
,
addr
);
pmd
=
pmd_offset
(
pgd
,
addr
);
if
(
!
pmd_present
(
*
pmd
))
return
(
0xffffffff
);
if
(
!
pmd_present
(
*
pmd
))
return
(
ERR_PTR
(
-
EINVAL
));
pte
=
pte_offset_kernel
(
pmd
,
addr
);
if
(
!
pte_present
(
*
pte
))
return
(
0xffffffff
);
return
((
pte_val
(
*
pte
)
&
PAGE_MASK
)
+
(
addr
&
~
PAGE_MASK
));
if
(
!
pte_present
(
*
pte
))
return
(
ERR_PTR
(
-
EINVAL
));
if
(
pte_out
!=
NULL
)
*
pte_out
=
*
pte
;
return
((
void
*
)
(
pte_val
(
*
pte
)
&
PAGE_MASK
)
+
(
addr
&
~
PAGE_MASK
));
}
char
*
current_cmd
(
void
)
...
...
@@ -244,8 +248,8 @@ char *current_cmd(void)
#if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM)
return
(
"(Unknown)"
);
#else
unsigned
long
addr
=
um_virt_to_phys
(
current
,
current
->
mm
->
arg_start
);
return
addr
==
0xffffffff
?
"(Unknown)"
:
__va
(
addr
);
void
*
addr
=
um_virt_to_phys
(
current
,
current
->
mm
->
arg_start
,
NULL
);
return
IS_ERR
(
addr
)
?
"(Unknown)"
:
__va
((
unsigned
long
)
addr
);
#endif
}
...
...
arch/um/kernel/skas/include/uaccess.h
View file @
8133aaa1
...
...
@@ -26,10 +26,6 @@ static inline int verify_area_skas(int type, const void * addr,
return
(
access_ok_skas
(
type
,
addr
,
size
)
?
0
:
-
EFAULT
);
}
extern
unsigned
long
handle_page_fault
(
unsigned
long
address
,
unsigned
long
ip
,
int
is_write
,
int
is_user
,
int
*
code_out
);
extern
void
*
um_virt_to_phys
(
struct
task_struct
*
task
,
unsigned
long
virt
,
pte_t
*
pte_out
);
...
...
@@ -212,7 +208,7 @@ static inline int strnlen_chunk(unsigned long str, int len, void *arg)
return
(
0
);
}
static
inline
int
strnlen_user_skas
(
void
*
str
,
int
len
)
static
inline
int
strnlen_user_skas
(
const
void
*
str
,
int
len
)
{
int
count
=
0
,
n
;
...
...
arch/um/kernel/trap_kern.c
View file @
8133aaa1
...
...
@@ -4,6 +4,7 @@
*/
#include "linux/kernel.h"
#include "asm/errno.h"
#include "linux/sched.h"
#include "linux/mm.h"
#include "linux/spinlock.h"
...
...
@@ -19,41 +20,36 @@
#include "kern_util.h"
#include "kern.h"
#include "chan_kern.h"
#include "debug.h"
#include "mconsole_kern.h"
#include "2_5compat.h"
extern
int
nsyscalls
;
unsigned
long
segv
(
unsigned
long
address
,
unsigned
long
ip
,
int
is_write
,
int
is_user
,
void
*
sc
)
int
handle_page_fault
(
unsigned
long
address
,
unsigned
long
ip
,
int
is_write
,
int
is_user
,
int
*
code_out
)
{
struct
mm_struct
*
mm
=
current
->
mm
;
struct
vm_area_struct
*
vma
;
struct
siginfo
si
;
void
*
catcher
;
pgd_t
*
pgd
;
pmd_t
*
pmd
;
pte_t
*
pte
;
unsigned
long
page
;
int
err
=
-
EFAULT
;
if
((
address
>=
start_vm
)
&&
(
address
<
end_vm
)){
flush_tlb_kernel_vm
();
return
(
0
);
}
if
(
mm
==
NULL
)
panic
(
"Segfault with no mm"
);
catcher
=
current
->
thread
.
fault_catcher
;
si
.
si_code
=
SEGV_MAPERR
;
*
code_out
=
SEGV_MAPERR
;
down_read
(
&
mm
->
mmap_sem
);
vma
=
find_vma
(
mm
,
address
);
if
(
!
vma
)
goto
bad
;
else
if
(
vma
->
vm_start
<=
address
)
goto
good_area
;
else
if
(
!
(
vma
->
vm_flags
&
VM_GROWSDOWN
))
goto
bad
;
else
if
(
expand_stack
(
vma
,
address
))
goto
bad
;
if
(
!
vma
)
goto
out
;
else
if
(
vma
->
vm_start
<=
address
)
goto
good_area
;
else
if
(
!
(
vma
->
vm_flags
&
VM_GROWSDOWN
))
goto
out
;
else
if
(
expand_stack
(
vma
,
address
))
goto
out
;
good_area:
si
.
si_code
=
SEGV_ACCERR
;
if
(
is_write
&&
!
(
vma
->
vm_flags
&
VM_WRITE
))
goto
bad
;
*
code_out
=
SEGV_ACCERR
;
if
(
is_write
&&
!
(
vma
->
vm_flags
&
VM_WRITE
))
goto
out
;
page
=
address
&
PAGE_MASK
;
if
(
page
==
(
unsigned
long
)
current
->
thread_info
+
PAGE_SIZE
)
panic
(
"Kernel stack overflow"
);
...
...
@@ -69,8 +65,10 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write,
current
->
maj_flt
++
;
break
;
case
VM_FAULT_SIGBUS
:
goto
do_sigbus
;
err
=
-
EACCES
;
goto
out
;
case
VM_FAULT_OOM
:
err
=
-
ENOMEM
;
goto
out_of_memory
;
default:
BUG
();
...
...
@@ -80,43 +78,45 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write,
*
pte
=
pte_mkyoung
(
*
pte
);
if
(
pte_write
(
*
pte
))
*
pte
=
pte_mkdirty
(
*
pte
);
flush_tlb_page
(
vma
,
page
);
err
=
0
;
out:
up_read
(
&
mm
->
mmap_sem
);
return
(
0
);
do_sigbus:
up_read
(
&
mm
->
mmap_sem
);
return
(
err
);
/*
* Send a sigbus, regardless of whether we were in kernel
* or user mode.
*/
si
.
si_signo
=
SIGBUS
;
si
.
si_errno
=
0
;
si
.
si_code
=
BUS_ADRERR
;
si
.
si_addr
=
(
void
*
)
address
;
force_sig_info
(
SIGBUS
,
&
si
,
current
);
if
(
!
is_user
)
goto
bad
;
return
(
0
);
/*
* We ran out of memory, or some other thing happened to us that made
* us unable to handle the page fault gracefully.
*/
out_of_memory:
up_read
(
&
mm
->
mmap_sem
);
if
(
current
->
pid
==
1
)
{
up_read
(
&
mm
->
mmap_sem
);
yield
();
down_read
(
&
mm
->
mmap_sem
);
goto
survive
;
}
printk
(
"VM: killing process %s
\n
"
,
current
->
comm
);
if
(
is_user
)
do_exit
(
SIGKILL
);
err
=
-
ENOMEM
;
goto
out
;
}
unsigned
long
segv
(
unsigned
long
address
,
unsigned
long
ip
,
int
is_write
,
int
is_user
,
void
*
sc
)
{
struct
siginfo
si
;
void
*
catcher
;
int
err
;
/* Fall through to bad */
if
(
!
is_user
&&
(
address
>=
start_vm
)
&&
(
address
<
end_vm
)){
flush_tlb_kernel_vm
();
return
(
0
);
}
if
(
current
->
mm
==
NULL
)
panic
(
"Segfault with no mm"
);
err
=
handle_page_fault
(
address
,
ip
,
is_write
,
is_user
,
&
si
.
si_code
);
bad:
if
(
catcher
!=
NULL
){
catcher
=
current
->
thread
.
fault_catcher
;
if
(
!
err
)
return
(
0
);
else
if
(
catcher
!=
NULL
){
current
->
thread
.
fault_addr
=
(
void
*
)
address
;
up_read
(
&
mm
->
mmap_sem
);
do_longjmp
(
catcher
,
1
);
}
else
if
(
current
->
thread
.
fault_addr
!=
NULL
){
...
...
@@ -125,15 +125,28 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write,
else
if
(
arch_fixup
(
ip
,
sc
))
return
(
0
);
if
(
!
is_user
)
if
(
!
is_user
)
panic
(
"Kernel mode fault at addr 0x%lx, ip 0x%lx"
,
address
,
ip
);
si
.
si_signo
=
SIGSEGV
;
si
.
si_addr
=
(
void
*
)
address
;
current
->
thread
.
cr2
=
address
;
current
->
thread
.
err
=
is_write
;
force_sig_info
(
SIGSEGV
,
&
si
,
current
);
up_read
(
&
mm
->
mmap_sem
);
if
(
err
==
-
EACCES
){
si
.
si_signo
=
SIGBUS
;
si
.
si_errno
=
0
;
si
.
si_code
=
BUS_ADRERR
;
si
.
si_addr
=
(
void
*
)
address
;
force_sig_info
(
SIGBUS
,
&
si
,
current
);
}
else
if
(
err
==
-
ENOMEM
){
printk
(
"VM: killing process %s
\n
"
,
current
->
comm
);
do_exit
(
SIGKILL
);
}
else
{
si
.
si_signo
=
SIGSEGV
;
si
.
si_addr
=
(
void
*
)
address
;
current
->
thread
.
cr2
=
address
;
current
->
thread
.
err
=
is_write
;
force_sig_info
(
SIGSEGV
,
&
si
,
current
);
}
return
(
0
);
}
...
...
arch/um/kernel/tt/include/uaccess.h
View file @
8133aaa1
...
...
@@ -98,7 +98,7 @@ static inline int clear_user_tt(void *mem, int len)
extern
int
__do_strnlen_user
(
const
char
*
str
,
unsigned
long
n
,
void
**
fault_addr
,
void
**
fault_catcher
);
static
inline
int
strnlen_user_tt
(
void
*
str
,
int
len
)
static
inline
int
strnlen_user_tt
(
const
void
*
str
,
int
len
)
{
return
(
__do_strnlen_user
(
str
,
len
,
&
current
->
thread
.
fault_addr
,
...
...
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