DragonFly kernel List (threaded) for 2006-09
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]
New virtual page table system calls and page table format
I have made a few refinements to the format of the virtual page table,
added supporting system calls (extensions to madvise() called mcontrol()),
and cleaned up and expanded the test program. I also believe I made
it work properly with fork(). Here is a new test program.
-Matt
/*
* Test virtual page tables - by Matthew Dillon.
*
* sysctl vm.vkernel_enable=1
*/
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/vkernel.h>
#include <stdarg.h>
static void xprintf(const char *ctl, ...);
int
main(int ac, char **av)
{
char *ptr;
vpte_t *level1;
vpte_t *level2;
int ischild = 0;
ptr = mmap(NULL, 32*1024*1024, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANON|MAP_VPAGETABLE, -1, 0);
/*
* Set the root page directory entry to force a linear mapping
*/
if (mcontrol(ptr, 32*1024*1024, MADV_SETMAP, VPTE_PS|VPTE_V) < 0) {
perror("mcontrol");
exit(1);
}
/*
* Now create a two-level page table in the logical object using the
* first two pages of the object.
*/
level1 = (void *)ptr;
level1[0] = (1 << PAGE_SHIFT) | VPTE_V;
level2 = (void *)(ptr + PAGE_SIZE);
level2[0] = (2 << PAGE_SHIFT) | VPTE_V;
level2[1] = (2 << PAGE_SHIFT) | VPTE_V;
level2[2] = (3 << PAGE_SHIFT) | VPTE_V;
level2[3] = (3 << PAGE_SHIFT) | VPTE_V;
if (fork() == 0)
ischild = 100;
/*
* Self-map our second-level page table page at offset (PAGE_SIZE*4)
*/
level2[4] = (1 << PAGE_SHIFT) | VPTE_V;
/*
* Replace the linear map with our page table at logical page #0
*/
if (mcontrol(ptr, 32*1024*1024, MADV_SETMAP, 0|VPTE_V) < 0) {
perror("mcontrol");
exit(1);
}
/*
* We can access these via our self-map now
*/
level1 = NULL;
level2 = (vpte_t *)(ptr + 4*PAGE_SIZE);
xprintf("test array[0*PAGE_SIZE] = %d (should be 0)\n",
*(int *)(ptr + 0*PAGE_SIZE));
xprintf("test array[4*PAGE_SIZE] = %d (should be %d)\n",
level2[0], (2 << PAGE_SHIFT) | VPTE_V);
*(int *)(ptr + 0*PAGE_SIZE) = 23 + ischild;
*(int *)(ptr + 2*PAGE_SIZE) = 46 + ischild;
xprintf("test array[0*PAGE_SIZE] = %d (should be %d)\n",
*(int *)(ptr + 0*PAGE_SIZE), 23 + ischild);
xprintf("test array[1*PAGE_SIZE] = %d (should be %d)\n",
*(int *)(ptr + 1*PAGE_SIZE), 23 + ischild);
xprintf("test array[2*PAGE_SIZE] = %d (should be %d)\n",
*(int *)(ptr + 2*PAGE_SIZE), 46 + ischild);
xprintf("test array[3*PAGE_SIZE] = %d (should be %d)\n",
*(int *)(ptr + 3*PAGE_SIZE), 46 + ischild);
/*
* Now change virtual page 0 to point to logical page 20 (zero-fill)
*/
xprintf("remapping page 0 but not invalidating the real pmap\n");
level2[0] = (20 << PAGE_SHIFT) | VPTE_V;
xprintf("test array[0*PAGE_SIZE] = %d (should be %d)\n",
*(int *)(ptr + 0*PAGE_SIZE), 23 + ischild);
xprintf("invalidating the real pmap\n");
if (madvise(ptr, 32*1024*1024, MADV_INVAL) < 0) {
perror("madvise");
exit(1);
}
xprintf("test array[0*PAGE_SIZE] = %d (should be 0)\n",
*(int *)(ptr + 0*PAGE_SIZE));
/*
* Modify virtual address 0 -- it should be modifying logical
* page 20.
*/
*(int *)(ptr + 0*PAGE_SIZE) = 99 + ischild;
/*
* Go back to our linear mapping to check.
*/
xprintf("return to a linear mapping\n");
if (mcontrol(ptr, 32*1024*1024, MADV_SETMAP, VPTE_PS|VPTE_V) < 0) {
perror("mcontrol");
exit(1);
}
xprintf("test array[20*PAGE_SIZE] = %d (should be %d)\n",
*(int *)(ptr + 20*PAGE_SIZE), 99 + ischild);
if (ischild == 0) {
while (wait3(NULL, 0, NULL) > 0)
;
}
}
static
void
xprintf(const char *ctl, ...)
{
va_list va;
printf("pid %5d ", getpid());
va_start(va, ctl);
vprintf(ctl, va);
va_end(va);
}
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]