Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
98ae7c9c
提交
98ae7c9c
5月 16, 2011
创建
作者:
Nickolai Zeldovich
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fold pgdir into vmap, so threads share hw pt, and unmap shootdown works
上级
1b93142d
隐藏空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
53 行增加
和
71 行删除
+53
-71
defs.h
defs.h
+2
-4
exec.c
exec.c
+0
-10
proc.c
proc.c
+1
-12
proc.h
proc.h
+1
-1
syscall.c
syscall.c
+4
-4
sysproc.c
sysproc.c
+2
-2
trap.c
trap.c
+1
-1
vm.c
vm.c
+42
-37
没有找到文件。
defs.h
浏览文件 @
98ae7c9c
...
@@ -166,7 +166,6 @@ void uartputc(int);
...
@@ -166,7 +166,6 @@ void uartputc(int);
void
seginit
(
void
);
void
seginit
(
void
);
void
kvmalloc
(
void
);
void
kvmalloc
(
void
);
void
vmenable
(
void
);
void
vmenable
(
void
);
pde_t
*
setupkvm
(
void
);
char
*
uva2ka
(
pde_t
*
,
char
*
);
char
*
uva2ka
(
pde_t
*
,
char
*
);
struct
vmnode
*
vmn_alloc
(
uint
,
uint
);
struct
vmnode
*
vmn_alloc
(
uint
,
uint
);
struct
vmnode
*
vmn_allocpg
(
uint
);
struct
vmnode
*
vmn_allocpg
(
uint
);
...
@@ -177,13 +176,12 @@ void vmap_decref(struct vmap *);
...
@@ -177,13 +176,12 @@ void vmap_decref(struct vmap *);
int
vmap_insert
(
struct
vmap
*
,
struct
vmnode
*
n
,
uint
);
int
vmap_insert
(
struct
vmap
*
,
struct
vmnode
*
n
,
uint
);
int
vmap_remove
(
struct
vmap
*
,
uint
va_start
,
uint
len
);
int
vmap_remove
(
struct
vmap
*
,
uint
va_start
,
uint
len
);
struct
vma
*
vmap_lookup
(
struct
vmap
*
,
uint
);
struct
vma
*
vmap_lookup
(
struct
vmap
*
,
uint
);
struct
vmap
*
vmap_copy
(
struct
vmap
*
,
pde_t
*
,
int
);
struct
vmap
*
vmap_copy
(
struct
vmap
*
,
int
);
void
freevm
(
pde_t
*
);
void
switchuvm
(
struct
proc
*
);
void
switchuvm
(
struct
proc
*
);
void
switchkvm
(
void
);
void
switchkvm
(
void
);
int
copyout
(
struct
vmap
*
,
uint
,
void
*
,
uint
);
int
copyout
(
struct
vmap
*
,
uint
,
void
*
,
uint
);
int
copyin
(
struct
vmap
*
,
uint
,
void
*
,
uint
);
int
copyin
(
struct
vmap
*
,
uint
,
void
*
,
uint
);
int
pagefault
(
pde_t
*
,
struct
vmap
*
,
uint
,
uint
);
int
pagefault
(
struct
vmap
*
,
uint
,
uint
);
void
clearpages
(
pde_t
*
pgdir
,
void
*
begin
,
void
*
end
);
void
clearpages
(
pde_t
*
pgdir
,
void
*
begin
,
void
*
end
);
// number of elements in fixed-size array
// number of elements in fixed-size array
...
...
exec.c
浏览文件 @
98ae7c9c
...
@@ -18,7 +18,6 @@ exec(char *path, char **argv)
...
@@ -18,7 +18,6 @@ exec(char *path, char **argv)
struct
elfhdr
elf
;
struct
elfhdr
elf
;
struct
inode
*
ip
=
0
;
struct
inode
*
ip
=
0
;
struct
proghdr
ph
;
struct
proghdr
ph
;
pde_t
*
pgdir
=
0
,
*
oldpgdir
;
struct
vmap
*
vmap
=
0
,
*
oldvmap
;
struct
vmap
*
vmap
=
0
,
*
oldvmap
;
struct
vmnode
*
vmn
=
0
;
struct
vmnode
*
vmn
=
0
;
int
odp
=
1
;
int
odp
=
1
;
...
@@ -26,7 +25,6 @@ exec(char *path, char **argv)
...
@@ -26,7 +25,6 @@ exec(char *path, char **argv)
if
((
ip
=
namei
(
path
))
==
0
)
if
((
ip
=
namei
(
path
))
==
0
)
return
-
1
;
return
-
1
;
ilock
(
ip
);
ilock
(
ip
);
pgdir
=
0
;
// Check ELF header
// Check ELF header
if
(
readi
(
ip
,
(
char
*
)
&
elf
,
0
,
sizeof
(
elf
))
<
sizeof
(
elf
))
if
(
readi
(
ip
,
(
char
*
)
&
elf
,
0
,
sizeof
(
elf
))
<
sizeof
(
elf
))
...
@@ -34,9 +32,6 @@ exec(char *path, char **argv)
...
@@ -34,9 +32,6 @@ exec(char *path, char **argv)
if
(
elf
.
magic
!=
ELF_MAGIC
)
if
(
elf
.
magic
!=
ELF_MAGIC
)
goto
bad
;
goto
bad
;
if
((
pgdir
=
setupkvm
())
==
0
)
goto
bad
;
if
((
vmap
=
vmap_alloc
())
==
0
)
if
((
vmap
=
vmap_alloc
())
==
0
)
goto
bad
;
goto
bad
;
...
@@ -122,23 +117,18 @@ exec(char *path, char **argv)
...
@@ -122,23 +117,18 @@ exec(char *path, char **argv)
safestrcpy
(
proc
->
name
,
last
,
sizeof
(
proc
->
name
));
safestrcpy
(
proc
->
name
,
last
,
sizeof
(
proc
->
name
));
// Commit to the user image.
// Commit to the user image.
oldpgdir
=
proc
->
pgdir
;
oldvmap
=
proc
->
vmap
;
oldvmap
=
proc
->
vmap
;
proc
->
pgdir
=
pgdir
;
proc
->
vmap
=
vmap
;
proc
->
vmap
=
vmap
;
proc
->
brk
=
brk
+
4
;
// XXX so that brk-1 points within heap vma..
proc
->
brk
=
brk
+
4
;
// XXX so that brk-1 points within heap vma..
proc
->
tf
->
eip
=
elf
.
entry
;
// main
proc
->
tf
->
eip
=
elf
.
entry
;
// main
proc
->
tf
->
esp
=
sp
;
proc
->
tf
->
esp
=
sp
;
switchuvm
(
proc
);
switchuvm
(
proc
);
freevm
(
oldpgdir
);
vmap_decref
(
oldvmap
);
vmap_decref
(
oldvmap
);
return
0
;
return
0
;
bad:
bad:
cprintf
(
"exec failed
\n
"
);
cprintf
(
"exec failed
\n
"
);
if
(
pgdir
)
freevm
(
pgdir
);
if
(
ip
)
if
(
ip
)
iunlockput
(
ip
);
iunlockput
(
ip
);
if
(
vmap
)
if
(
vmap
)
...
...
proc.c
浏览文件 @
98ae7c9c
...
@@ -145,8 +145,6 @@ userinit(void)
...
@@ -145,8 +145,6 @@ userinit(void)
p
=
allocproc
();
p
=
allocproc
();
initproc
=
p
;
initproc
=
p
;
if
((
p
->
pgdir
=
setupkvm
())
==
0
)
panic
(
"userinit: out of memory?"
);
if
((
p
->
vmap
=
vmap_alloc
())
==
0
)
if
((
p
->
vmap
=
vmap_alloc
())
==
0
)
panic
(
"userinit: out of vmaps?"
);
panic
(
"userinit: out of vmaps?"
);
struct
vmnode
*
vmn
=
vmn_allocpg
(
PGROUNDUP
((
int
)
_binary_initcode_size
)
/
PGSIZE
);
struct
vmnode
*
vmn
=
vmn_allocpg
(
PGROUNDUP
((
int
)
_binary_initcode_size
)
/
PGSIZE
);
...
@@ -211,17 +209,9 @@ fork(int flags)
...
@@ -211,17 +209,9 @@ fork(int flags)
if
((
np
=
allocproc
())
==
0
)
if
((
np
=
allocproc
())
==
0
)
return
-
1
;
return
-
1
;
if
((
np
->
pgdir
=
setupkvm
())
==
0
){
kfree
(
np
->
kstack
);
np
->
kstack
=
0
;
np
->
state
=
UNUSED
;
return
-
1
;
}
if
(
flags
==
0
)
{
if
(
flags
==
0
)
{
// Copy process state from p.
// Copy process state from p.
if
((
np
->
vmap
=
vmap_copy
(
proc
->
vmap
,
proc
->
pgdir
,
cow
))
==
0
){
if
((
np
->
vmap
=
vmap_copy
(
proc
->
vmap
,
cow
))
==
0
){
freevm
(
np
->
pgdir
);
kfree
(
np
->
kstack
);
kfree
(
np
->
kstack
);
np
->
kstack
=
0
;
np
->
kstack
=
0
;
np
->
state
=
UNUSED
;
np
->
state
=
UNUSED
;
...
@@ -328,7 +318,6 @@ wait(void)
...
@@ -328,7 +318,6 @@ wait(void)
SLIST_REMOVE
(
&
proc
->
childq
,
p
,
proc
,
child_next
);
SLIST_REMOVE
(
&
proc
->
childq
,
p
,
proc
,
child_next
);
kfree
(
p
->
kstack
);
kfree
(
p
->
kstack
);
p
->
kstack
=
0
;
p
->
kstack
=
0
;
freevm
(
p
->
pgdir
);
vmap_decref
(
p
->
vmap
);
vmap_decref
(
p
->
vmap
);
p
->
state
=
UNUSED
;
p
->
state
=
UNUSED
;
p
->
pid
=
0
;
p
->
pid
=
0
;
...
...
proc.h
浏览文件 @
98ae7c9c
...
@@ -58,12 +58,12 @@ struct vmap {
...
@@ -58,12 +58,12 @@ struct vmap {
struct
spinlock
lock
;
// serialize map/lookup/unmap
struct
spinlock
lock
;
// serialize map/lookup/unmap
uint
ref
;
uint
ref
;
uint
alloc
;
uint
alloc
;
pde_t
*
pgdir
;
// Page table
};
};
// Per-process state
// Per-process state
struct
proc
{
struct
proc
{
struct
vmap
*
vmap
;
// va -> vma
struct
vmap
*
vmap
;
// va -> vma
pde_t
*
pgdir
;
// Page table
uint
brk
;
// Top of heap
uint
brk
;
// Top of heap
char
*
kstack
;
// Bottom of kernel stack for this process
char
*
kstack
;
// Bottom of kernel stack for this process
enum
procstate
state
;
// Process state
enum
procstate
state
;
// Process state
...
...
syscall.c
浏览文件 @
98ae7c9c
...
@@ -20,9 +20,9 @@
...
@@ -20,9 +20,9 @@
int
int
fetchint
(
uint
addr
,
int
*
ip
)
fetchint
(
uint
addr
,
int
*
ip
)
{
{
if
(
pagefault
(
proc
->
pgdir
,
proc
->
vmap
,
addr
,
0
)
<
0
)
if
(
pagefault
(
proc
->
vmap
,
addr
,
0
)
<
0
)
return
-
1
;
return
-
1
;
if
(
pagefault
(
proc
->
pgdir
,
proc
->
vmap
,
addr
+
3
,
0
)
<
0
)
if
(
pagefault
(
proc
->
vmap
,
addr
+
3
,
0
)
<
0
)
return
-
1
;
return
-
1
;
*
ip
=
*
(
int
*
)(
addr
);
*
ip
=
*
(
int
*
)(
addr
);
return
0
;
return
0
;
...
@@ -37,7 +37,7 @@ fetchstr(uint addr, char **pp)
...
@@ -37,7 +37,7 @@ fetchstr(uint addr, char **pp)
char
*
s
=
(
char
*
)
addr
;
char
*
s
=
(
char
*
)
addr
;
while
(
1
){
while
(
1
){
if
(
pagefault
(
proc
->
pgdir
,
proc
->
vmap
,
(
uint
)
s
,
0
)
<
0
)
if
(
pagefault
(
proc
->
vmap
,
(
uint
)
s
,
0
)
<
0
)
return
-
1
;
return
-
1
;
if
(
*
s
==
0
){
if
(
*
s
==
0
){
*
pp
=
(
char
*
)
addr
;
*
pp
=
(
char
*
)
addr
;
...
@@ -66,7 +66,7 @@ argptr(int n, char **pp, int size)
...
@@ -66,7 +66,7 @@ argptr(int n, char **pp, int size)
if
(
argint
(
n
,
&
i
)
<
0
)
if
(
argint
(
n
,
&
i
)
<
0
)
return
-
1
;
return
-
1
;
for
(
uint
va
=
PGROUNDDOWN
(
i
);
va
<
i
+
size
;
va
=
va
+
PGSIZE
)
for
(
uint
va
=
PGROUNDDOWN
(
i
);
va
<
i
+
size
;
va
=
va
+
PGSIZE
)
if
(
pagefault
(
proc
->
pgdir
,
proc
->
vmap
,
va
,
0
)
<
0
)
if
(
pagefault
(
proc
->
vmap
,
va
,
0
)
<
0
)
return
-
1
;
return
-
1
;
*
pp
=
(
char
*
)
i
;
*
pp
=
(
char
*
)
i
;
return
0
;
return
0
;
...
...
sysproc.c
浏览文件 @
98ae7c9c
...
@@ -131,11 +131,11 @@ sys_unmap(void)
...
@@ -131,11 +131,11 @@ sys_unmap(void)
if
(
vmap_remove
(
proc
->
vmap
,
PGROUNDDOWN
(
addr
),
PGROUNDUP
(
len
))
<
0
)
if
(
vmap_remove
(
proc
->
vmap
,
PGROUNDDOWN
(
addr
),
PGROUNDUP
(
len
))
<
0
)
return
-
1
;
return
-
1
;
clearpages
(
proc
->
pgdir
,
clearpages
(
proc
->
vmap
->
pgdir
,
(
void
*
)
(
PGROUNDDOWN
(
addr
)),
(
void
*
)
(
PGROUNDDOWN
(
addr
)),
(
void
*
)
(
PGROUNDDOWN
(
addr
)
+
PGROUNDUP
(
len
)));
(
void
*
)
(
PGROUNDDOWN
(
addr
)
+
PGROUNDUP
(
len
)));
cli
();
cli
();
lcr3
(
PADDR
(
proc
->
pgdir
));
lcr3
(
PADDR
(
proc
->
vmap
->
pgdir
));
for
(
uint
i
=
0
;
i
<
ncpu
;
i
++
)
for
(
uint
i
=
0
;
i
<
ncpu
;
i
++
)
if
(
i
!=
cpu
->
id
)
if
(
i
!=
cpu
->
id
)
lapic_tlbflush
(
i
);
lapic_tlbflush
(
i
);
...
...
trap.c
浏览文件 @
98ae7c9c
...
@@ -94,7 +94,7 @@ trap(struct trapframe *tf)
...
@@ -94,7 +94,7 @@ trap(struct trapframe *tf)
}
}
if
(
tf
->
trapno
==
T_PGFLT
){
if
(
tf
->
trapno
==
T_PGFLT
){
if
(
pagefault
(
proc
->
pgdir
,
proc
->
vmap
,
rcr2
(),
tf
->
err
)
>=
0
){
if
(
pagefault
(
proc
->
vmap
,
rcr2
(),
tf
->
err
)
>=
0
){
return
;
return
;
}
}
}
}
...
...
vm.c
浏览文件 @
98ae7c9c
...
@@ -14,14 +14,6 @@ extern char data[]; // defined in data.S
...
@@ -14,14 +14,6 @@ extern char data[]; // defined in data.S
static
pde_t
*
kpgdir
;
// for use in scheduler()
static
pde_t
*
kpgdir
;
// for use in scheduler()
// Allocate one page table for the machine for the kernel address
// space for scheduler processes.
void
kvmalloc
(
void
)
{
kpgdir
=
setupkvm
();
}
// Set up CPU's kernel segment descriptors.
// Set up CPU's kernel segment descriptors.
// Run once at boot time on each CPU.
// Run once at boot time on each CPU.
void
void
...
@@ -179,7 +171,7 @@ static struct kmap {
...
@@ -179,7 +171,7 @@ static struct kmap {
};
};
// Set up kernel part of a page table.
// Set up kernel part of a page table.
pde_t
*
static
pde_t
*
setupkvm
(
void
)
setupkvm
(
void
)
{
{
pde_t
*
pgdir
;
pde_t
*
pgdir
;
...
@@ -196,6 +188,14 @@ setupkvm(void)
...
@@ -196,6 +188,14 @@ setupkvm(void)
return
pgdir
;
return
pgdir
;
}
}
// Allocate one page table for the machine for the kernel address
// space for scheduler processes.
void
kvmalloc
(
void
)
{
kpgdir
=
setupkvm
();
}
// Turn on paging.
// Turn on paging.
void
void
vmenable
(
void
)
vmenable
(
void
)
...
@@ -226,12 +226,28 @@ switchuvm(struct proc *p)
...
@@ -226,12 +226,28 @@ switchuvm(struct proc *p)
cpu
->
ts
.
ss0
=
SEG_KDATA
<<
3
;
cpu
->
ts
.
ss0
=
SEG_KDATA
<<
3
;
cpu
->
ts
.
esp0
=
(
uint
)
proc
->
kstack
+
KSTACKSIZE
;
cpu
->
ts
.
esp0
=
(
uint
)
proc
->
kstack
+
KSTACKSIZE
;
ltr
(
SEG_TSS
<<
3
);
ltr
(
SEG_TSS
<<
3
);
if
(
p
->
pgdir
==
0
)
if
(
p
->
vmap
==
0
||
p
->
vmap
->
pgdir
==
0
)
panic
(
"switchuvm: no pgdir"
);
panic
(
"switchuvm: no
vmap/
pgdir"
);
lcr3
(
PADDR
(
p
->
pgdir
));
// switch to new address space
lcr3
(
PADDR
(
p
->
vmap
->
pgdir
));
// switch to new address space
popcli
();
popcli
();
}
}
// Free a page table and all the physical memory pages
// in the user part.
static
void
freevm
(
pde_t
*
pgdir
)
{
uint
i
;
if
(
pgdir
==
0
)
panic
(
"freevm: no pgdir"
);
for
(
i
=
0
;
i
<
NPDENTRIES
;
i
++
){
if
(
pgdir
[
i
]
&
PTE_P
)
kfree
((
char
*
)
PTE_ADDR
(
pgdir
[
i
]));
}
kfree
((
char
*
)
pgdir
);
}
struct
{
struct
{
struct
vmnode
n
[
1024
];
struct
vmnode
n
[
1024
];
}
vmnodes
;
}
vmnodes
;
...
@@ -341,6 +357,9 @@ vmap_alloc(void)
...
@@ -341,6 +357,9 @@ vmap_alloc(void)
}
}
m
->
lock
.
name
=
"vmap"
;
m
->
lock
.
name
=
"vmap"
;
m
->
ref
=
1
;
m
->
ref
=
1
;
m
->
pgdir
=
setupkvm
();
if
(
m
->
pgdir
==
0
)
panic
(
"vmap_alloc: setupkvm out of memory"
);
return
m
;
return
m
;
}
}
}
}
...
@@ -353,6 +372,8 @@ vmap_free(struct vmap *m)
...
@@ -353,6 +372,8 @@ vmap_free(struct vmap *m)
for
(
uint
i
=
0
;
i
<
sizeof
(
m
->
e
)
/
sizeof
(
m
->
e
[
0
]);
i
++
)
for
(
uint
i
=
0
;
i
<
sizeof
(
m
->
e
)
/
sizeof
(
m
->
e
[
0
]);
i
++
)
if
(
m
->
e
[
i
].
n
)
if
(
m
->
e
[
i
].
n
)
vmn_decref
(
m
->
e
[
i
].
n
);
vmn_decref
(
m
->
e
[
i
].
n
);
freevm
(
m
->
pgdir
);
m
->
pgdir
=
0
;
m
->
alloc
=
0
;
m
->
alloc
=
0
;
}
}
...
@@ -430,7 +451,7 @@ vmap_lookup(struct vmap *m, uint va)
...
@@ -430,7 +451,7 @@ vmap_lookup(struct vmap *m, uint va)
}
}
struct
vmap
*
struct
vmap
*
vmap_copy
(
struct
vmap
*
m
,
pde_t
*
pgdir
,
int
share
)
vmap_copy
(
struct
vmap
*
m
,
int
share
)
{
{
struct
vmap
*
c
=
vmap_alloc
();
struct
vmap
*
c
=
vmap_alloc
();
if
(
c
==
0
)
if
(
c
==
0
)
...
@@ -446,7 +467,7 @@ vmap_copy(struct vmap *m, pde_t* pgdir, int share)
...
@@ -446,7 +467,7 @@ vmap_copy(struct vmap *m, pde_t* pgdir, int share)
c
->
e
[
i
].
n
=
m
->
e
[
i
].
n
;
c
->
e
[
i
].
n
=
m
->
e
[
i
].
n
;
c
->
e
[
i
].
va_type
=
COW
;
c
->
e
[
i
].
va_type
=
COW
;
m
->
e
[
i
].
va_type
=
COW
;
m
->
e
[
i
].
va_type
=
COW
;
updatepages
(
pgdir
,
(
void
*
)
(
m
->
e
[
i
].
va_start
),
(
void
*
)
(
m
->
e
[
i
].
va_end
),
PTE_COW
);
updatepages
(
m
->
pgdir
,
(
void
*
)
(
m
->
e
[
i
].
va_start
),
(
void
*
)
(
m
->
e
[
i
].
va_end
),
PTE_COW
);
}
else
{
}
else
{
c
->
e
[
i
].
n
=
vmn_copy
(
m
->
e
[
i
].
n
);
c
->
e
[
i
].
n
=
vmn_copy
(
m
->
e
[
i
].
n
);
c
->
e
[
i
].
va_type
=
m
->
e
[
i
].
va_type
;
c
->
e
[
i
].
va_type
=
m
->
e
[
i
].
va_type
;
...
@@ -459,7 +480,7 @@ vmap_copy(struct vmap *m, pde_t* pgdir, int share)
...
@@ -459,7 +480,7 @@ vmap_copy(struct vmap *m, pde_t* pgdir, int share)
__sync_fetch_and_add
(
&
c
->
e
[
i
].
n
->
ref
,
1
);
__sync_fetch_and_add
(
&
c
->
e
[
i
].
n
->
ref
,
1
);
}
}
if
(
share
)
if
(
share
)
lcr3
(
PADDR
(
pgdir
));
// Reload hardware page table
lcr3
(
PADDR
(
m
->
pgdir
));
// Reload hardware page table
release
(
&
m
->
lock
);
release
(
&
m
->
lock
);
return
c
;
return
c
;
...
@@ -495,22 +516,6 @@ vmn_load(struct vmnode *vmn, struct inode *ip, uint offset, uint sz)
...
@@ -495,22 +516,6 @@ vmn_load(struct vmnode *vmn, struct inode *ip, uint offset, uint sz)
}
}
}
}
// Free a page table and all the physical memory pages
// in the user part.
void
freevm
(
pde_t
*
pgdir
)
{
uint
i
;
if
(
pgdir
==
0
)
panic
(
"freevm: no pgdir"
);
for
(
i
=
0
;
i
<
NPDENTRIES
;
i
++
){
if
(
pgdir
[
i
]
&
PTE_P
)
kfree
((
char
*
)
PTE_ADDR
(
pgdir
[
i
]));
}
kfree
((
char
*
)
pgdir
);
}
//PAGEBREAK!
//PAGEBREAK!
// Map user virtual address to kernel physical address.
// Map user virtual address to kernel physical address.
char
*
char
*
...
@@ -581,10 +586,10 @@ copyin(struct vmap *vmap, uint va, void *p, uint len)
...
@@ -581,10 +586,10 @@ copyin(struct vmap *vmap, uint va, void *p, uint len)
}
}
int
int
pagefault
(
pde_t
*
pgdir
,
struct
vmap
*
vmap
,
uint
va
,
uint
err
)
pagefault
(
struct
vmap
*
vmap
,
uint
va
,
uint
err
)
{
{
pte_t
*
pte
=
walkpgdir
(
pgdir
,
(
const
void
*
)
va
,
1
);
pte_t
*
pte
=
walkpgdir
(
vmap
->
pgdir
,
(
const
void
*
)
va
,
1
);
if
((
*
pte
&
(
PTE_P
|
PTE_U
|
PTE_W
))
==
(
PTE_P
|
PTE_U
|
PTE_W
))
if
((
*
pte
&
(
PTE_P
|
PTE_U
|
PTE_W
))
==
(
PTE_P
|
PTE_U
|
PTE_W
))
return
0
;
return
0
;
...
@@ -606,7 +611,7 @@ pagefault(pde_t *pgdir, struct vmap *vmap, uint va, uint err)
...
@@ -606,7 +611,7 @@ pagefault(pde_t *pgdir, struct vmap *vmap, uint va, uint err)
panic
(
"pagefault: couldn't load"
);
panic
(
"pagefault: couldn't load"
);
}
}
acquire
(
&
m
->
lock
);
acquire
(
&
m
->
lock
);
pte
=
walkpgdir
(
pgdir
,
(
const
void
*
)
va
,
0
);
pte
=
walkpgdir
(
vmap
->
pgdir
,
(
const
void
*
)
va
,
0
);
if
(
pte
==
0x0
)
if
(
pte
==
0x0
)
panic
(
"pagefault: not paged in???"
);
panic
(
"pagefault: not paged in???"
);
// cprintf("ODP done\n");
// cprintf("ODP done\n");
...
@@ -627,8 +632,8 @@ pagefault(pde_t *pgdir, struct vmap *vmap, uint va, uint err)
...
@@ -627,8 +632,8 @@ pagefault(pde_t *pgdir, struct vmap *vmap, uint va, uint err)
m
->
va_type
=
PRIVATE
;
m
->
va_type
=
PRIVATE
;
m
->
n
=
c
;
m
->
n
=
c
;
// Update the hardware page tables to reflect the change to the vma
// Update the hardware page tables to reflect the change to the vma
clearpages
(
pgdir
,
(
void
*
)
m
->
va_start
,
(
void
*
)
m
->
va_end
);
clearpages
(
vmap
->
pgdir
,
(
void
*
)
m
->
va_start
,
(
void
*
)
m
->
va_end
);
pte
=
walkpgdir
(
pgdir
,
(
const
void
*
)
va
,
0
);
pte
=
walkpgdir
(
vmap
->
pgdir
,
(
const
void
*
)
va
,
0
);
*
pte
=
PADDR
(
m
->
n
->
page
[
npg
])
|
PTE_P
|
PTE_U
|
PTE_W
;
*
pte
=
PADDR
(
m
->
n
->
page
[
npg
])
|
PTE_P
|
PTE_U
|
PTE_W
;
}
}
}
else
if
(
m
->
va_type
==
COW
)
{
}
else
if
(
m
->
va_type
==
COW
)
{
...
@@ -642,7 +647,7 @@ pagefault(pde_t *pgdir, struct vmap *vmap, uint va, uint err)
...
@@ -642,7 +647,7 @@ pagefault(pde_t *pgdir, struct vmap *vmap, uint va, uint err)
}
}
*
pte
=
PADDR
(
m
->
n
->
page
[
npg
])
|
PTE_P
|
PTE_U
|
PTE_W
;
*
pte
=
PADDR
(
m
->
n
->
page
[
npg
])
|
PTE_P
|
PTE_U
|
PTE_W
;
}
}
lcr3
(
PADDR
(
pgdir
));
// Reload hardware page tables
lcr3
(
PADDR
(
vmap
->
pgdir
));
// Reload hardware page tables
release
(
&
m
->
lock
);
release
(
&
m
->
lock
);
return
1
;
return
1
;
}
}
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论