DragonFly BSD
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


From: Matthew Dillon <dillon@xxxxxxxxxxxxxxxxxxxx>
Date: Wed, 13 Sep 2006 11:19:06 -0700 (PDT)

    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]