Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
um
kernel
skas
mmu.c
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3
* Licensed under the GPL
4
*/
5
6
#include <
linux/mm.h
>
7
#include <linux/sched.h>
8
#include <linux/slab.h>
9
#include <asm/pgalloc.h>
10
#include <asm/pgtable.h>
11
#include <
as-layout.h
>
12
#include <os.h>
13
#include <
skas.h
>
14
15
extern
int
__syscall_stub_start
;
16
17
static
int
init_stub_pte(
struct
mm_struct
*mm,
unsigned
long
proc,
18
unsigned
long
kernel)
19
{
20
pgd_t
*pgd;
21
pud_t
*pud;
22
pmd_t
*
pmd
;
23
pte_t
*
pte
;
24
25
pgd =
pgd_offset
(mm, proc);
26
pud =
pud_alloc
(mm, pgd, proc);
27
if
(!pud)
28
goto
out
;
29
30
pmd =
pmd_alloc
(mm, pud, proc);
31
if
(!pmd)
32
goto
out_pmd;
33
34
pte = pte_alloc_map(mm,
NULL
, pmd, proc);
35
if
(!pte)
36
goto
out_pte;
37
38
*pte =
mk_pte
(
virt_to_page
(kernel),
__pgprot
(
_PAGE_PRESENT
));
39
*pte =
pte_mkread
(*pte);
40
return
0;
41
42
out_pte:
43
pmd_free
(mm, pmd);
44
out_pmd:
45
pud_free
(mm, pud);
46
out
:
47
return
-
ENOMEM
;
48
}
49
50
int
init_new_context
(
struct
task_struct
*
task
,
struct
mm_struct
*mm)
51
{
52
struct
mm_context
*from_mm =
NULL
;
53
struct
mm_context
*to_mm = &mm->
context
;
54
unsigned
long
stack
= 0;
55
int
ret
= -
ENOMEM
;
56
57
if
(
skas_needs_stub
) {
58
stack =
get_zeroed_page
(
GFP_KERNEL
);
59
if
(stack == 0)
60
goto
out
;
61
}
62
63
to_mm->
id
.stack =
stack
;
64
if
(
current
->mm !=
NULL
&&
current
->mm != &
init_mm
)
65
from_mm = &
current
->mm->context;
66
67
if
(
proc_mm
) {
68
ret =
new_mm
(stack);
69
if
(ret < 0) {
70
printk
(
KERN_ERR
"init_new_context_skas - "
71
"new_mm failed, errno = %d\n"
, ret);
72
goto
out_free;
73
}
74
to_mm->
id
.u.mm_fd =
ret
;
75
}
76
else
{
77
if
(from_mm)
78
to_mm->
id
.u.pid =
copy_context_skas0
(stack,
79
from_mm->
id
.u.pid);
80
else
to_mm->
id
.u.pid =
start_userspace
(stack);
81
82
if
(to_mm->
id
.u.pid < 0) {
83
ret = to_mm->
id
.u.pid;
84
goto
out_free;
85
}
86
}
87
88
ret =
init_new_ldt
(to_mm, from_mm);
89
if
(ret < 0) {
90
printk
(
KERN_ERR
"init_new_context_skas - init_ldt"
91
" failed, errno = %d\n"
, ret);
92
goto
out_free;
93
}
94
95
return
0;
96
97
out_free:
98
if
(to_mm->
id
.stack != 0)
99
free_page
(to_mm->
id
.stack);
100
out
:
101
return
ret
;
102
}
103
104
void
uml_setup_stubs
(
struct
mm_struct
*mm)
105
{
106
int
err
,
ret
;
107
108
if
(!
skas_needs_stub
)
109
return
;
110
111
ret = init_stub_pte(mm,
STUB_CODE
,
112
(
unsigned
long
) &
__syscall_stub_start
);
113
if
(ret)
114
goto
out
;
115
116
ret = init_stub_pte(mm,
STUB_DATA
, mm->
context
.
id
.stack);
117
if
(ret)
118
goto
out
;
119
120
mm->
context
.stub_pages[0] =
virt_to_page
(&__syscall_stub_start);
121
mm->
context
.stub_pages[1] =
virt_to_page
(mm->
context
.
id
.stack);
122
123
/* dup_mmap already holds mmap_sem */
124
err =
install_special_mapping
(mm,
STUB_START
,
STUB_END
-
STUB_START
,
125
VM_READ | VM_MAYREAD | VM_EXEC |
126
VM_MAYEXEC | VM_DONTCOPY,
127
mm->
context
.stub_pages);
128
if
(err) {
129
printk
(
KERN_ERR
"install_special_mapping returned %d\n"
, err);
130
goto
out
;
131
}
132
return
;
133
134
out
:
135
force_sigsegv
(
SIGSEGV
,
current
);
136
}
137
138
void
arch_exit_mmap
(
struct
mm_struct
*mm)
139
{
140
pte_t
*
pte
;
141
142
pte =
virt_to_pte
(mm,
STUB_CODE
);
143
if
(pte !=
NULL
)
144
pte_clear
(mm,
STUB_CODE
, pte);
145
146
pte =
virt_to_pte
(mm,
STUB_DATA
);
147
if
(pte ==
NULL
)
148
return
;
149
150
pte_clear
(mm,
STUB_DATA
, pte);
151
}
152
153
void
destroy_context
(
struct
mm_struct
*mm)
154
{
155
struct
mm_context
*mmu = &mm->
context
;
156
157
if
(
proc_mm
)
158
os_close_file
(mmu->
id
.u.mm_fd);
159
else
{
160
/*
161
* If init_new_context wasn't called, this will be
162
* zero, resulting in a kill(0), which will result in the
163
* whole UML suddenly dying. Also, cover negative and
164
* 1 cases, since they shouldn't happen either.
165
*/
166
if
(mmu->
id
.u.pid < 2) {
167
printk
(
KERN_ERR
"corrupt mm_context - pid = %d\n"
,
168
mmu->
id
.u.pid);
169
return
;
170
}
171
os_kill_ptraced_process
(mmu->
id
.u.pid, 1);
172
}
173
174
if
(
skas_needs_stub
)
175
free_page
(mmu->
id
.stack);
176
177
free_ldt
(mmu);
178
}
Generated on Thu Jan 10 2013 13:02:51 for Linux Kernel by
1.8.2