提交 41fc9e5e 创建 作者: Nickolai Zeldovich's avatar Nickolai Zeldovich

add local shootdown, and test case for remote shootdown (not working yet)

上级 06047fd7
...@@ -183,6 +183,7 @@ void switchkvm(void); ...@@ -183,6 +183,7 @@ 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(pde_t*, struct vmap *, uint, uint);
void clearpages(pde_t *pgdir, void *begin, void *end);
// number of elements in fixed-size array // number of elements in fixed-size array
#define NELEM(x) (sizeof(x)/sizeof((x)[0])) #define NELEM(x) (sizeof(x)/sizeof((x)[0]))
......
...@@ -5,31 +5,84 @@ ...@@ -5,31 +5,84 @@
#include "x86.h" #include "x86.h"
#include "uspinlock.h" #include "uspinlock.h"
static volatile char *p;
static struct uspinlock l;
static volatile uint state;
static void
spin(void)
{
volatile uint i;
for (i = 0; i < 10000; i++)
;
}
void
thr(void)
{
for (;;) {
acquire(&l);
if (state == 1) {
p[0] = 'x';
p[4096] = 'y';
state = 2;
}
if (state == 3) {
state = 4;
printf(1, "about to access after unmap\n");
release(&l);
p[0] = 'X';
p[4096] = 'Y';
acquire(&l);
printf(1, "still alive after unmap write\n");
exit();
}
release(&l);
spin();
}
}
int int
main(void) main(void)
{ {
volatile char *p = (char *) 0x80000; p = (char *) 0x80000;
if (map((void *) p, 8192) < 0) { if (map((void *) p, 8192) < 0) {
printf(1, "map failed\n"); printf(1, "map failed\n");
exit(); exit();
} }
p[0] = 'x'; sbrk(4096);
p[4096] = 'y'; forkt(sbrk(0), thr);
acquire(&l);
state = 1;
while (state != 2) {
release(&l);
spin();
acquire(&l);
}
if (p[0] != 'x' || p[4096] != 'y') { if (p[0] != 'x' || p[4096] != 'y') {
printf(1, "mismatch\n"); printf(1, "mismatch\n");
exit(); exit();
} }
printf(1, "shm ok\n");
if (unmap((void *) p, 8192) < 0) { if (unmap((void *) p, 8192) < 0) {
printf(1, "unmap failed\n"); printf(1, "unmap failed\n");
exit(); exit();
} }
p[0] = 'z'; state = 3;
if (p[0] == 'z') { printf(1, "waiting for unmap access\n");
printf(1, "still mapped\n"); while (state != 4) {
exit(); release(&l);
spin();
acquire(&l);
} }
exit(); exit();
......
...@@ -130,6 +130,11 @@ sys_unmap(void) ...@@ -130,6 +130,11 @@ sys_unmap(void)
return -1; return -1;
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,
(void*) (PGROUNDDOWN(addr)),
(void*) (PGROUNDDOWN(addr)+PGROUNDUP(len)));
lcr3(PADDR(proc->pgdir));
return 0; return 0;
} }
......
...@@ -104,7 +104,7 @@ mappages(pde_t *pgdir, void *la, uint size, uint pa, int perm) ...@@ -104,7 +104,7 @@ mappages(pde_t *pgdir, void *la, uint size, uint pa, int perm)
return 0; return 0;
} }
static int static void
updatepages(pde_t *pgdir, void *begin, void *end, int perm) updatepages(pde_t *pgdir, void *begin, void *end, int perm)
{ {
char *a, *last; char *a, *last;
...@@ -120,10 +120,9 @@ updatepages(pde_t *pgdir, void *begin, void *end, int perm) ...@@ -120,10 +120,9 @@ updatepages(pde_t *pgdir, void *begin, void *end, int perm)
break; break;
a += PGSIZE; a += PGSIZE;
} }
return 0;
} }
static int void
clearpages(pde_t *pgdir, void *begin, void *end) clearpages(pde_t *pgdir, void *begin, void *end)
{ {
char *a, *last; char *a, *last;
...@@ -139,7 +138,6 @@ clearpages(pde_t *pgdir, void *begin, void *end) ...@@ -139,7 +138,6 @@ clearpages(pde_t *pgdir, void *begin, void *end)
break; break;
a += PGSIZE; a += PGSIZE;
} }
return 0;
} }
// The mappings from logical to linear are one to one (i.e., // The mappings from logical to linear are one to one (i.e.,
...@@ -416,7 +414,7 @@ vmap_lookup(struct vmap *m, uint va) ...@@ -416,7 +414,7 @@ vmap_lookup(struct vmap *m, uint va)
acquire(&m->lock); acquire(&m->lock);
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++) {
struct vma *e = &m->e[i]; struct vma *e = &m->e[i];
if (va >= e->va_start && va < e->va_end) { if (e->n && va >= e->va_start && va < e->va_end) {
acquire(&e->lock); acquire(&e->lock);
release(&m->lock); release(&m->lock);
return e; return e;
...@@ -633,8 +631,10 @@ pagefault(pde_t *pgdir, struct vmap *vmap, uint va, uint err) ...@@ -633,8 +631,10 @@ pagefault(pde_t *pgdir, struct vmap *vmap, uint va, uint err)
*pte = PADDR(m->n->page[npg]) | PTE_P | PTE_U | PTE_COW; *pte = PADDR(m->n->page[npg]) | PTE_P | PTE_U | PTE_COW;
} else { } else {
// cprintf("fill in pte\n"); // cprintf("fill in pte\n");
if (m->n->ref > 1) if (m->n->ref > 1) {
cprintf("pagefault: va 0x%x\n", va);
panic("pagefault"); panic("pagefault");
}
*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(pgdir)); // Reload hardware page tables
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论