提交 51ace277 创建 作者: Nickolai Zeldovich's avatar Nickolai Zeldovich

anon memory map/unmap, without shootdown

上级 40ba7672
...@@ -174,6 +174,7 @@ UPROGS=\ ...@@ -174,6 +174,7 @@ UPROGS=\
_zombie\ _zombie\
_halt\ _halt\
_thrtest\ _thrtest\
_maptest\
fs.img: mkfs README $(UPROGS) fs.img: mkfs README $(UPROGS)
./mkfs fs.img README $(UPROGS) ./mkfs fs.img README $(UPROGS)
......
...@@ -172,6 +172,7 @@ int vmn_load(struct vmnode *, struct inode*, uint, uint); ...@@ -172,6 +172,7 @@ int vmn_load(struct vmnode *, struct inode*, uint, uint);
struct vmap * vmap_alloc(void); struct vmap * vmap_alloc(void);
void vmap_decref(struct vmap *); 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);
struct vma * vmap_lookup(struct vmap *, uint); struct vma * vmap_lookup(struct vmap *, uint);
struct vmap * vmap_copy(struct vmap *); struct vmap * vmap_copy(struct vmap *);
void freevm(pde_t*); void freevm(pde_t*);
......
#include "types.h"
#include "stat.h"
#include "user.h"
#include "xv6-mtrace.h"
#include "x86.h"
#include "uspinlock.h"
int
main(void)
{
volatile char *p = (char *) 0x80000;
if (map((void *) p, 8192) < 0) {
printf(1, "map failed\n");
exit();
}
p[0] = 'x';
p[4096] = 'y';
if (p[0] != 'x' || p[4096] != 'y') {
printf(1, "mismatch\n");
exit();
}
if (unmap((void *) p, 8192) < 0) {
printf(1, "unmap failed\n");
exit();
}
p[0] = 'z';
if (p[0] == 'z') {
printf(1, "still mapped\n");
exit();
}
exit();
}
...@@ -106,6 +106,8 @@ extern int sys_unlink(void); ...@@ -106,6 +106,8 @@ extern int sys_unlink(void);
extern int sys_wait(void); extern int sys_wait(void);
extern int sys_write(void); extern int sys_write(void);
extern int sys_uptime(void); extern int sys_uptime(void);
extern int sys_map(void);
extern int sys_unmap(void);
extern int sys_halt(void); extern int sys_halt(void);
static int (*syscalls[])(void) = { static int (*syscalls[])(void) = {
...@@ -130,6 +132,8 @@ static int (*syscalls[])(void) = { ...@@ -130,6 +132,8 @@ static int (*syscalls[])(void) = {
[SYS_wait] sys_wait, [SYS_wait] sys_wait,
[SYS_write] sys_write, [SYS_write] sys_write,
[SYS_uptime] sys_uptime, [SYS_uptime] sys_uptime,
[SYS_map] sys_map,
[SYS_unmap] sys_unmap,
[SYS_halt] sys_halt, [SYS_halt] sys_halt,
}; };
......
...@@ -96,6 +96,44 @@ sys_uptime(void) ...@@ -96,6 +96,44 @@ sys_uptime(void)
} }
int int
sys_map(void)
{
uint addr;
uint len;
if (argint(0, (int*) &addr) < 0)
return -1;
if (argint(1, (int*) &len) < 0)
return -1;
struct vmnode *vmn = vmn_allocpg(PGROUNDUP(len) / PGSIZE);
if (vmn == 0)
return -1;
if (vmap_insert(proc->vmap, vmn, PGROUNDDOWN(addr)) < 0) {
vmn_free(vmn);
return -1;
}
return 0;
}
int
sys_unmap(void)
{
uint addr;
uint len;
if (argint(0, (int*) &addr) < 0)
return -1;
if (argint(1, (int*) &len) < 0)
return -1;
if (vmap_remove(proc->vmap, PGROUNDDOWN(addr), PGROUNDUP(len)) < 0)
return -1;
return 0;
}
int
sys_halt(void) sys_halt(void)
{ {
int i; int i;
......
...@@ -22,6 +22,8 @@ int getpid(void); ...@@ -22,6 +22,8 @@ int getpid(void);
char* sbrk(int); char* sbrk(int);
int sleep(int); int sleep(int);
int uptime(void); int uptime(void);
int map(void *addr, int len);
int unmap(void *addr, int len);
void halt(void); void halt(void);
// ulib.c // ulib.c
......
...@@ -29,4 +29,6 @@ SYSCALL(getpid) ...@@ -29,4 +29,6 @@ SYSCALL(getpid)
SYSCALL(sbrk) SYSCALL(sbrk)
SYSCALL(sleep) SYSCALL(sleep)
SYSCALL(uptime) SYSCALL(uptime)
SYSCALL(map)
SYSCALL(unmap)
SYSCALL(halt) SYSCALL(halt)
...@@ -322,6 +322,27 @@ vmap_insert(struct vmap *m, struct vmnode *n, uint va_start) ...@@ -322,6 +322,27 @@ vmap_insert(struct vmap *m, struct vmnode *n, uint va_start)
return -1; return -1;
} }
int
vmap_remove(struct vmap *m, uint va_start, uint len)
{
acquire(&m->lock);
uint va_end = va_start + len;
for(uint i = 0; i < sizeof(m->e) / sizeof(m->e[0]); i++) {
if(m->e[i].n && (m->e[i].va_start < va_end && m->e[i].va_end > va_start)) {
if(m->e[i].va_start != va_start || m->e[i].va_end != va_end) {
release(&m->lock);
cprintf("vmap_remove: partial unmap unsupported\n");
return -1;
}
__sync_fetch_and_sub(&m->e[i].n->ref, 1);
m->e[i].n = 0;
}
}
release(&m->lock);
return 0;
}
struct vma * struct vma *
vmap_lookup(struct vmap *m, uint va) vmap_lookup(struct vmap *m, uint va)
{ {
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论