- simplify findhole() for use for 1 page only
- do WMF_FREE - added WMF_VERIFY to check page table contents - randomize address space usage in vm self
This commit is contained in:
parent
9e53925504
commit
4c11d7e6f5
@ -14,7 +14,6 @@ CFLAGS = $(CPROFILE) $(CPPFLAGS)
|
|||||||
# build local binary
|
# build local binary
|
||||||
|
|
||||||
all build install: $(SERVER)
|
all build install: $(SERVER)
|
||||||
install -S 100k $(SERVER)
|
|
||||||
|
|
||||||
$(SERVER): $(OBJ) phony
|
$(SERVER): $(OBJ) phony
|
||||||
cd $(ARCH) && $(MAKE)
|
cd $(ARCH) && $(MAKE)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
#define _SYSTEM 1
|
#define _SYSTEM 1
|
||||||
|
#define _POSIX_SOURCE 1
|
||||||
|
|
||||||
#define VERBOSE 0
|
#define VERBOSE 0
|
||||||
|
|
||||||
@ -20,6 +21,7 @@
|
|||||||
#include <minix/bitmap.h>
|
#include <minix/bitmap.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <env.h>
|
#include <env.h>
|
||||||
@ -51,7 +53,7 @@ struct vmproc *vmp = &vmproc[VM_PROC_NR];
|
|||||||
* circular dependency on allocating memory and writing it into VM's
|
* circular dependency on allocating memory and writing it into VM's
|
||||||
* page table.
|
* page table.
|
||||||
*/
|
*/
|
||||||
#define SPAREPAGES 5
|
#define SPAREPAGES 25
|
||||||
int missing_spares = SPAREPAGES;
|
int missing_spares = SPAREPAGES;
|
||||||
PRIVATE struct {
|
PRIVATE struct {
|
||||||
void *page;
|
void *page;
|
||||||
@ -124,7 +126,7 @@ PUBLIC void pt_sanitycheck(pt_t *pt, char *file, int line)
|
|||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PRIVATE void *aalloc(size_t bytes)
|
PRIVATE void *aalloc(size_t bytes)
|
||||||
{
|
{
|
||||||
/* Page-aligned malloc(). only used if vm_allocpages can't be used. */
|
/* Page-aligned malloc(). only used if vm_allocpage can't be used. */
|
||||||
u32_t b;
|
u32_t b;
|
||||||
|
|
||||||
b = (u32_t) malloc(I386_PAGE_SIZE + bytes);
|
b = (u32_t) malloc(I386_PAGE_SIZE + bytes);
|
||||||
@ -137,11 +139,11 @@ PRIVATE void *aalloc(size_t bytes)
|
|||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* findhole *
|
* findhole *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PRIVATE u32_t findhole(pt_t *pt, u32_t virbytes, u32_t vmin, u32_t vmax)
|
PRIVATE u32_t findhole(pt_t *pt, u32_t vmin, u32_t vmax)
|
||||||
{
|
{
|
||||||
/* Find a space in the virtual address space of pageteble 'pt',
|
/* Find a space in the virtual address space of pageteble 'pt',
|
||||||
* between page-aligned BYTE offsets vmin and vmax, to fit
|
* between page-aligned BYTE offsets vmin and vmax, to fit
|
||||||
* 'virbytes' in. Return byte offset.
|
* a page in. Return byte offset.
|
||||||
*
|
*
|
||||||
* As a simple way to speed up the search a bit, we start searching
|
* As a simple way to speed up the search a bit, we start searching
|
||||||
* after the location we found the previous hole, if that's in range.
|
* after the location we found the previous hole, if that's in range.
|
||||||
@ -149,63 +151,36 @@ PRIVATE u32_t findhole(pt_t *pt, u32_t virbytes, u32_t vmin, u32_t vmax)
|
|||||||
* range (as well). try_restart controls whether we have to restart
|
* range (as well). try_restart controls whether we have to restart
|
||||||
* the search if it fails. (Just once of course.)
|
* the search if it fails. (Just once of course.)
|
||||||
*/
|
*/
|
||||||
u32_t freeneeded, freefound = 0, freestart = 0, curv;
|
u32_t freefound = 0, curv;
|
||||||
int pde = 0, try_restart;
|
int pde = 0, try_restart;
|
||||||
|
|
||||||
/* Input sanity check. */
|
/* Input sanity check. */
|
||||||
vm_assert(vmin + virbytes >= vmin);
|
vm_assert(vmin + I386_PAGE_SIZE >= vmin);
|
||||||
vm_assert(vmax >= vmin + virbytes);
|
vm_assert(vmax >= vmin + I386_PAGE_SIZE);
|
||||||
vm_assert((virbytes % I386_PAGE_SIZE) == 0);
|
|
||||||
vm_assert((vmin % I386_PAGE_SIZE) == 0);
|
vm_assert((vmin % I386_PAGE_SIZE) == 0);
|
||||||
vm_assert((vmax % I386_PAGE_SIZE) == 0);
|
vm_assert((vmax % I386_PAGE_SIZE) == 0);
|
||||||
|
|
||||||
/* How many pages do we need? */
|
curv = ((u32_t) random()) % ((vmax - vmin)/I386_PAGE_SIZE);
|
||||||
freeneeded = virbytes / I386_PAGE_SIZE;
|
curv *= I386_PAGE_SIZE;
|
||||||
|
curv += vmin;
|
||||||
|
try_restart = 1;
|
||||||
|
|
||||||
if(pt->pt_virtop >= vmin && pt->pt_virtop <= vmax - virbytes) {
|
/* Start looking for a free page starting at vmin. */
|
||||||
curv = pt->pt_virtop;
|
while(curv < vmax) {
|
||||||
try_restart = 1;
|
|
||||||
} else {
|
|
||||||
curv = vmin;
|
|
||||||
try_restart = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Start looking for a consecutive block of free pages
|
|
||||||
* starting at vmin.
|
|
||||||
*/
|
|
||||||
for(freestart = curv; curv < vmax; ) {
|
|
||||||
int pte;
|
int pte;
|
||||||
|
|
||||||
|
vm_assert(curv >= vmin);
|
||||||
|
vm_assert(curv < vmax);
|
||||||
|
|
||||||
pde = I386_VM_PDE(curv);
|
pde = I386_VM_PDE(curv);
|
||||||
pte = I386_VM_PTE(curv);
|
pte = I386_VM_PTE(curv);
|
||||||
|
|
||||||
if(!(pt->pt_dir[pde] & I386_VM_PRESENT)) {
|
if(!(pt->pt_dir[pde] & I386_VM_PRESENT) ||
|
||||||
int rempte;
|
!(pt->pt_pt[pde][pte] & I386_VM_PRESENT)) {
|
||||||
rempte = I386_VM_PT_ENTRIES - pte;
|
return curv;
|
||||||
freefound += rempte;
|
|
||||||
curv += rempte * I386_PAGE_SIZE;
|
|
||||||
} else {
|
|
||||||
if(pt->pt_pt[pde][pte] & I386_VM_PRESENT) {
|
|
||||||
freefound = 0;
|
|
||||||
freestart = curv + I386_PAGE_SIZE;
|
|
||||||
} else {
|
|
||||||
freefound++;
|
|
||||||
}
|
|
||||||
curv+=I386_PAGE_SIZE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(freefound >= freeneeded) {
|
curv+=I386_PAGE_SIZE;
|
||||||
u32_t v;
|
|
||||||
v = freestart;
|
|
||||||
vm_assert(v != NO_MEM);
|
|
||||||
vm_assert(v >= vmin);
|
|
||||||
vm_assert(v < vmax);
|
|
||||||
|
|
||||||
/* Next time, start looking here. */
|
|
||||||
pt->pt_virtop = v + virbytes;
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(curv >= vmax && try_restart) {
|
if(curv >= vmax && try_restart) {
|
||||||
curv = vmin;
|
curv = vmin;
|
||||||
@ -213,7 +188,7 @@ PRIVATE u32_t findhole(pt_t *pt, u32_t virbytes, u32_t vmin, u32_t vmax)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("VM: out of virtual address space in a process\n");
|
printf("VM: out of virtual address space in vm\n");
|
||||||
|
|
||||||
return NO_MEM;
|
return NO_MEM;
|
||||||
}
|
}
|
||||||
@ -270,7 +245,7 @@ PRIVATE void *vm_checkspares(void)
|
|||||||
for(s = 0; s < SPAREPAGES && missing_spares > 0; s++)
|
for(s = 0; s < SPAREPAGES && missing_spares > 0; s++)
|
||||||
if(!sparepages[s].page) {
|
if(!sparepages[s].page) {
|
||||||
n++;
|
n++;
|
||||||
if((sparepages[s].page = vm_allocpages(&sparepages[s].phys, 1,
|
if((sparepages[s].page = vm_allocpage(&sparepages[s].phys,
|
||||||
VMP_SPARE))) {
|
VMP_SPARE))) {
|
||||||
missing_spares--;
|
missing_spares--;
|
||||||
vm_assert(missing_spares >= 0);
|
vm_assert(missing_spares >= 0);
|
||||||
@ -284,25 +259,22 @@ PRIVATE void *vm_checkspares(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* vm_allocpages *
|
* vm_allocpage *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PUBLIC void *vm_allocpages(phys_bytes *phys, int pages, int reason)
|
PUBLIC void *vm_allocpage(phys_bytes *phys, int reason)
|
||||||
{
|
{
|
||||||
/* Allocate a number of pages for use by VM itself. */
|
/* Allocate a page for use by VM itself. */
|
||||||
phys_bytes newpage;
|
phys_bytes newpage;
|
||||||
vir_bytes loc;
|
vir_bytes loc;
|
||||||
pt_t *pt;
|
pt_t *pt;
|
||||||
int r;
|
int r;
|
||||||
vir_bytes bytes = pages * I386_PAGE_SIZE;
|
|
||||||
static int level = 0;
|
static int level = 0;
|
||||||
#define MAXDEPTH 10
|
void *ret;
|
||||||
static int reasons[MAXDEPTH];
|
|
||||||
|
|
||||||
pt = &vmp->vm_pt;
|
pt = &vmp->vm_pt;
|
||||||
vm_assert(reason >= 0 && reason < VMP_CATEGORIES);
|
vm_assert(reason >= 0 && reason < VMP_CATEGORIES);
|
||||||
vm_assert(pages > 0);
|
|
||||||
|
|
||||||
reasons[level++] = reason;
|
level++;
|
||||||
|
|
||||||
vm_assert(level >= 1);
|
vm_assert(level >= 1);
|
||||||
vm_assert(level <= 2);
|
vm_assert(level <= 2);
|
||||||
@ -310,44 +282,54 @@ PUBLIC void *vm_allocpages(phys_bytes *phys, int pages, int reason)
|
|||||||
if(level > 1 || !(vmp->vm_flags & VMF_HASPT) || !meminit_done) {
|
if(level > 1 || !(vmp->vm_flags & VMF_HASPT) || !meminit_done) {
|
||||||
int r;
|
int r;
|
||||||
void *s;
|
void *s;
|
||||||
vm_assert(pages == 1);
|
|
||||||
s=vm_getsparepage(phys);
|
s=vm_getsparepage(phys);
|
||||||
level--;
|
level--;
|
||||||
|
if(!s) {
|
||||||
|
printf("VM: warning: out of spare pages\n");
|
||||||
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* VM does have a pagetable, so get a page and map it in there.
|
/* VM does have a pagetable, so get a page and map it in there.
|
||||||
* Where in our virtual address space can we put it?
|
* Where in our virtual address space can we put it?
|
||||||
*/
|
*/
|
||||||
loc = findhole(pt, I386_PAGE_SIZE * pages,
|
loc = findhole(pt, arch_vir2map(vmp, vmp->vm_stacktop),
|
||||||
arch_vir2map(vmp, vmp->vm_stacktop),
|
|
||||||
vmp->vm_arch.vm_data_top);
|
vmp->vm_arch.vm_data_top);
|
||||||
if(loc == NO_MEM) {
|
if(loc == NO_MEM) {
|
||||||
level--;
|
level--;
|
||||||
|
printf("VM: vm_allocpage: findhole failed\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate 'pages' pages of memory for use by VM. As VM
|
/* Allocate page of memory for use by VM. As VM
|
||||||
* is trusted, we don't have to pre-clear it.
|
* is trusted, we don't have to pre-clear it.
|
||||||
*/
|
*/
|
||||||
if((newpage = ALLOC_MEM(CLICKSPERPAGE * pages, 0)) == NO_MEM) {
|
if((newpage = ALLOC_MEM(CLICKSPERPAGE, 0)) == NO_MEM) {
|
||||||
level--;
|
level--;
|
||||||
|
printf("VM: vm_allocpage: ALLOC_MEM failed\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
*phys = CLICK2ABS(newpage);
|
*phys = CLICK2ABS(newpage);
|
||||||
|
|
||||||
/* Map this page into our address space. */
|
/* Map this page into our address space. */
|
||||||
if((r=pt_writemap(pt, loc, *phys, bytes,
|
if((r=pt_writemap(pt, loc, *phys, I386_PAGE_SIZE,
|
||||||
I386_VM_PRESENT | I386_VM_USER | I386_VM_WRITE, 0)) != OK) {
|
I386_VM_PRESENT | I386_VM_USER | I386_VM_WRITE, 0)) != OK) {
|
||||||
FREE_MEM(newpage, CLICKSPERPAGE * pages / I386_PAGE_SIZE);
|
FREE_MEM(newpage, CLICKSPERPAGE);
|
||||||
|
printf("vm_allocpage writemap failed\n", ret);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((r=sys_vmctl(SELF, VMCTL_FLUSHTLB, 0)) != OK) {
|
||||||
|
vm_panic("VMCTL_FLUSHTLB failed", r);
|
||||||
|
}
|
||||||
|
|
||||||
level--;
|
level--;
|
||||||
|
|
||||||
/* Return user-space-ready pointer to it. */
|
/* Return user-space-ready pointer to it. */
|
||||||
return (void *) arch_map2vir(vmp, loc);
|
ret = (void *) arch_map2vir(vmp, loc);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
@ -355,7 +337,7 @@ PUBLIC void *vm_allocpages(phys_bytes *phys, int pages, int reason)
|
|||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
PUBLIC void vm_pagelock(void *vir, int lockflag)
|
PUBLIC void vm_pagelock(void *vir, int lockflag)
|
||||||
{
|
{
|
||||||
/* Mark a page allocated by vm_allocpages() unwritable, i.e. only for VM. */
|
/* Mark a page allocated by vm_allocpage() unwritable, i.e. only for VM. */
|
||||||
vir_bytes m;
|
vir_bytes m;
|
||||||
int r;
|
int r;
|
||||||
u32_t flags = I386_VM_PRESENT | I386_VM_USER;
|
u32_t flags = I386_VM_PRESENT | I386_VM_USER;
|
||||||
@ -402,7 +384,7 @@ PRIVATE int pt_ptalloc(pt_t *pt, int pde, u32_t flags)
|
|||||||
vm_assert(!pt->pt_pt[pde]);
|
vm_assert(!pt->pt_pt[pde]);
|
||||||
|
|
||||||
/* Get storage for the page table. */
|
/* Get storage for the page table. */
|
||||||
if(!(pt->pt_pt[pde] = vm_allocpages(&pt_phys, 1, VMP_PAGETABLE)))
|
if(!(pt->pt_pt[pde] = vm_allocpage(&pt_phys, VMP_PAGETABLE)))
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
|
|
||||||
for(i = 0; i < I386_VM_PT_ENTRIES; i++)
|
for(i = 0; i < I386_VM_PT_ENTRIES; i++)
|
||||||
@ -429,6 +411,10 @@ PUBLIC int pt_writemap(pt_t *pt, vir_bytes v, phys_bytes physaddr,
|
|||||||
/* Page directory and table entries for this virtual address. */
|
/* Page directory and table entries for this virtual address. */
|
||||||
int p, pages, pde;
|
int p, pages, pde;
|
||||||
int finalpde;
|
int finalpde;
|
||||||
|
int verify = 0;
|
||||||
|
|
||||||
|
if(writemapflags & WMF_VERIFY)
|
||||||
|
verify = 1;
|
||||||
|
|
||||||
vm_assert(!(bytes % I386_PAGE_SIZE));
|
vm_assert(!(bytes % I386_PAGE_SIZE));
|
||||||
vm_assert(!(flags & ~(PTF_ALLFLAGS)));
|
vm_assert(!(flags & ~(PTF_ALLFLAGS)));
|
||||||
@ -464,6 +450,10 @@ PUBLIC int pt_writemap(pt_t *pt, vir_bytes v, phys_bytes physaddr,
|
|||||||
}
|
}
|
||||||
if(!(pt->pt_dir[pde] & I386_VM_PRESENT)) {
|
if(!(pt->pt_dir[pde] & I386_VM_PRESENT)) {
|
||||||
int r;
|
int r;
|
||||||
|
if(verify) {
|
||||||
|
printf("pt_writemap verify: no pde %d\n", pde);
|
||||||
|
return EFAULT;
|
||||||
|
}
|
||||||
vm_assert(!pt->pt_dir[pde]);
|
vm_assert(!pt->pt_dir[pde]);
|
||||||
if((r=pt_ptalloc(pt, pde, flags)) != OK) {
|
if((r=pt_ptalloc(pt, pde, flags)) != OK) {
|
||||||
/* Couldn't do (complete) mapping.
|
/* Couldn't do (complete) mapping.
|
||||||
@ -473,6 +463,7 @@ PUBLIC int pt_writemap(pt_t *pt, vir_bytes v, phys_bytes physaddr,
|
|||||||
* and pt_ptalloc leaves the directory
|
* and pt_ptalloc leaves the directory
|
||||||
* and other data in a consistent state.
|
* and other data in a consistent state.
|
||||||
*/
|
*/
|
||||||
|
printf("pt_writemap: pt_ptalloc failed\n", pde);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -481,6 +472,7 @@ PUBLIC int pt_writemap(pt_t *pt, vir_bytes v, phys_bytes physaddr,
|
|||||||
|
|
||||||
/* Now write in them. */
|
/* Now write in them. */
|
||||||
for(p = 0; p < pages; p++) {
|
for(p = 0; p < pages; p++) {
|
||||||
|
u32_t entry;
|
||||||
int pde = I386_VM_PDE(v);
|
int pde = I386_VM_PDE(v);
|
||||||
int pte = I386_VM_PTE(v);
|
int pte = I386_VM_PTE(v);
|
||||||
|
|
||||||
@ -498,19 +490,34 @@ PUBLIC int pt_writemap(pt_t *pt, vir_bytes v, phys_bytes physaddr,
|
|||||||
|
|
||||||
#if SANITYCHECKS
|
#if SANITYCHECKS
|
||||||
/* We don't expect to overwrite a page. */
|
/* We don't expect to overwrite a page. */
|
||||||
if(!(writemapflags & WMF_OVERWRITE))
|
if(!(writemapflags & (WMF_OVERWRITE|WMF_VERIFY)))
|
||||||
vm_assert(!(pt->pt_pt[pde][pte] & I386_VM_PRESENT));
|
vm_assert(!(pt->pt_pt[pde][pte] & I386_VM_PRESENT));
|
||||||
#endif
|
#endif
|
||||||
if(writemapflags & WMF_WRITEFLAGSONLY) {
|
if(writemapflags & (WMF_WRITEFLAGSONLY|WMF_FREE)) {
|
||||||
physaddr = pt->pt_pt[pde][pte] & I386_VM_ADDR_MASK;
|
physaddr = pt->pt_pt[pde][pte] & I386_VM_ADDR_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(writemapflags & WMF_FREE) {
|
if(writemapflags & WMF_FREE) {
|
||||||
printf("pt_writemap: should free 0x%lx\n", physaddr);
|
FREE_MEM(ABS2CLICK(physaddr), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write pagetable entry. */
|
/* Entry we will write. */
|
||||||
pt->pt_pt[pde][pte] = (physaddr & I386_VM_ADDR_MASK) | flags;
|
entry = (physaddr & I386_VM_ADDR_MASK) | flags;
|
||||||
|
|
||||||
|
if(verify) {
|
||||||
|
u32_t maskedentry;
|
||||||
|
maskedentry = pt->pt_pt[pde][pte];
|
||||||
|
maskedentry &= ~(I386_VM_ACC|I386_VM_DIRTY);
|
||||||
|
/* Verify pagetable entry. */
|
||||||
|
if(maskedentry != entry) {
|
||||||
|
printf("pt_writemap: 0x%lx found, masked 0x%lx, 0x%lx expected\n",
|
||||||
|
pt->pt_pt[pde][pte], maskedentry, entry);
|
||||||
|
return EFAULT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Write pagetable entry. */
|
||||||
|
pt->pt_pt[pde][pte] = entry;
|
||||||
|
}
|
||||||
|
|
||||||
physaddr += I386_PAGE_SIZE;
|
physaddr += I386_PAGE_SIZE;
|
||||||
v += I386_PAGE_SIZE;
|
v += I386_PAGE_SIZE;
|
||||||
@ -538,7 +545,7 @@ PUBLIC int pt_new(pt_t *pt)
|
|||||||
* the page directories (the page_directories data).
|
* the page directories (the page_directories data).
|
||||||
*/
|
*/
|
||||||
if(!pt->pt_dir &&
|
if(!pt->pt_dir &&
|
||||||
!(pt->pt_dir = vm_allocpages(&pt->pt_dir_phys, 1, VMP_PAGEDIR))) {
|
!(pt->pt_dir = vm_allocpage(&pt->pt_dir_phys, VMP_PAGEDIR))) {
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -578,17 +585,22 @@ PUBLIC void pt_init(void)
|
|||||||
int free_pde;
|
int free_pde;
|
||||||
int p;
|
int p;
|
||||||
vir_bytes kernlimit;
|
vir_bytes kernlimit;
|
||||||
|
vir_bytes sparepages_mem;
|
||||||
|
phys_bytes sparepages_ph;
|
||||||
|
|
||||||
/* Shorthand. */
|
/* Shorthand. */
|
||||||
newpt = &vmp->vm_pt;
|
newpt = &vmp->vm_pt;
|
||||||
|
|
||||||
/* Get ourselves a spare page. */
|
/* Get ourselves spare pages. */
|
||||||
|
if(!(sparepages_mem = (vir_bytes) aalloc(I386_PAGE_SIZE*SPAREPAGES)))
|
||||||
|
vm_panic("pt_init: aalloc for spare failed", NO_NUM);
|
||||||
|
if((r=sys_umap(SELF, VM_D, (vir_bytes) sparepages_mem,
|
||||||
|
I386_PAGE_SIZE*SPAREPAGES, &sparepages_ph)) != OK)
|
||||||
|
vm_panic("pt_init: sys_umap failed", r);
|
||||||
|
|
||||||
for(s = 0; s < SPAREPAGES; s++) {
|
for(s = 0; s < SPAREPAGES; s++) {
|
||||||
if(!(sparepages[s].page = aalloc(I386_PAGE_SIZE)))
|
sparepages[s].page = (void *) (sparepages_mem + s*I386_PAGE_SIZE);
|
||||||
vm_panic("pt_init: aalloc for spare failed", NO_NUM);
|
sparepages[s].phys = sparepages_ph + s*I386_PAGE_SIZE;
|
||||||
if((r=sys_umap(SELF, VM_D, (vir_bytes) sparepages[s].page,
|
|
||||||
I386_PAGE_SIZE, &sparepages[s].phys)) != OK)
|
|
||||||
vm_panic("pt_init: sys_umap failed", r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
missing_spares = 0;
|
missing_spares = 0;
|
||||||
@ -669,8 +681,8 @@ PUBLIC void pt_init(void)
|
|||||||
/* Allocate us a page table in which to remember page directory
|
/* Allocate us a page table in which to remember page directory
|
||||||
* pointers.
|
* pointers.
|
||||||
*/
|
*/
|
||||||
if(!(page_directories = vm_allocpages(&page_directories_phys,
|
if(!(page_directories = vm_allocpage(&page_directories_phys,
|
||||||
1, VMP_PAGETABLE)))
|
VMP_PAGETABLE)))
|
||||||
vm_panic("no virt addr for vm mappings", NO_NUM);
|
vm_panic("no virt addr for vm mappings", NO_NUM);
|
||||||
|
|
||||||
memset(page_directories, 0, I386_PAGE_SIZE);
|
memset(page_directories, 0, I386_PAGE_SIZE);
|
||||||
|
@ -103,7 +103,7 @@ _PROTOTYPE( void pt_freerange, (pt_t *pt, vir_bytes lo, vir_bytes hi) );
|
|||||||
_PROTOTYPE( int pt_writemap, (pt_t *pt, vir_bytes v, phys_bytes physaddr,
|
_PROTOTYPE( int pt_writemap, (pt_t *pt, vir_bytes v, phys_bytes physaddr,
|
||||||
size_t bytes, u32_t flags, u32_t writemapflags));
|
size_t bytes, u32_t flags, u32_t writemapflags));
|
||||||
_PROTOTYPE( int pt_bind, (pt_t *pt, struct vmproc *who) );
|
_PROTOTYPE( int pt_bind, (pt_t *pt, struct vmproc *who) );
|
||||||
_PROTOTYPE( void *vm_allocpages, (phys_bytes *p, int pages, int cat));
|
_PROTOTYPE( void *vm_allocpage, (phys_bytes *p, int cat));
|
||||||
_PROTOTYPE( void pt_cycle, (void));
|
_PROTOTYPE( void pt_cycle, (void));
|
||||||
_PROTOTYPE( int pt_mapkernel, (pt_t *pt));
|
_PROTOTYPE( int pt_mapkernel, (pt_t *pt));
|
||||||
_PROTOTYPE( void vm_pagelock, (void *vir, int lockflag) );
|
_PROTOTYPE( void vm_pagelock, (void *vir, int lockflag) );
|
||||||
|
@ -95,6 +95,27 @@ struct vmproc *vmp;
|
|||||||
#if SANITYCHECKS
|
#if SANITYCHECKS
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* map_sanitycheck_pt *
|
||||||
|
*===========================================================================*/
|
||||||
|
PRIVATE int map_sanitycheck_pt(struct vmproc *vmp,
|
||||||
|
struct vir_region *vr, struct phys_region *pr)
|
||||||
|
{
|
||||||
|
struct phys_block *pb = pr->ph;
|
||||||
|
int rw;
|
||||||
|
|
||||||
|
if(!(vmp->vm_flags & VMF_HASPT))
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
if(WRITABLE(vr, pb))
|
||||||
|
rw = PTF_WRITE;
|
||||||
|
else
|
||||||
|
rw = 0;
|
||||||
|
|
||||||
|
return pt_writemap(&vmp->vm_pt, vr->vaddr + pr->offset,
|
||||||
|
pb->phys, pb->length, PTF_PRESENT | PTF_USER | rw, WMF_VERIFY);
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* map_sanitycheck *
|
* map_sanitycheck *
|
||||||
*===========================================================================*/
|
*===========================================================================*/
|
||||||
@ -172,7 +193,7 @@ PUBLIC void map_sanitycheck(char *file, int line)
|
|||||||
MYASSERT(pr->ph->refcount == pr->ph->seencount);
|
MYASSERT(pr->ph->refcount == pr->ph->seencount);
|
||||||
MYASSERT(!(pr->offset % VM_PAGE_SIZE));
|
MYASSERT(!(pr->offset % VM_PAGE_SIZE));
|
||||||
MYASSERT(!(pr->ph->length % VM_PAGE_SIZE)););
|
MYASSERT(!(pr->ph->length % VM_PAGE_SIZE)););
|
||||||
|
ALLREGIONS(,MYASSERT(map_sanitycheck_pt(vmp, vr, pr) == OK));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -492,6 +513,8 @@ PRIVATE int map_subfree(struct vmproc *vmp,
|
|||||||
vm_assert(len < pr->offset + pr->ph->length);
|
vm_assert(len < pr->offset + pr->ph->length);
|
||||||
vm_assert(pr->ph->refcount > 0);
|
vm_assert(pr->ph->refcount > 0);
|
||||||
sublen = len - pr->offset;
|
sublen = len - pr->offset;
|
||||||
|
vm_assert(!(sublen % VM_PAGE_SIZE));
|
||||||
|
vm_assert(sublen < pr->ph->length);
|
||||||
if(pr->ph->refcount > 1) {
|
if(pr->ph->refcount > 1) {
|
||||||
int r;
|
int r;
|
||||||
r = map_copy_ph_block(vmp, region, pr);
|
r = map_copy_ph_block(vmp, region, pr);
|
||||||
@ -506,6 +529,9 @@ PRIVATE int map_subfree(struct vmproc *vmp,
|
|||||||
USE(pr->ph,
|
USE(pr->ph,
|
||||||
pr->ph->phys += sublen;
|
pr->ph->phys += sublen;
|
||||||
pr->ph->length -= sublen;);
|
pr->ph->length -= sublen;);
|
||||||
|
vm_assert(!(pr->offset % VM_PAGE_SIZE));
|
||||||
|
vm_assert(!(pr->ph->phys % VM_PAGE_SIZE));
|
||||||
|
vm_assert(!(pr->ph->length % VM_PAGE_SIZE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,8 +186,10 @@ struct slabdata *newslabdata(int list)
|
|||||||
|
|
||||||
vm_assert(sizeof(*n) == VM_PAGE_SIZE);
|
vm_assert(sizeof(*n) == VM_PAGE_SIZE);
|
||||||
|
|
||||||
if(!(n = vm_allocpages(&p, 1, VMP_SLAB)))
|
if(!(n = vm_allocpage(&p, VMP_SLAB))) {
|
||||||
|
printf("newslabdata: vm_allocpage failed\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
memset(n->sdh.usebits, 0, sizeof(n->sdh.usebits));
|
memset(n->sdh.usebits, 0, sizeof(n->sdh.usebits));
|
||||||
pages++;
|
pages++;
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
#define WMF_OVERWRITE 0x01 /* Caller knows map may overwrite. */
|
#define WMF_OVERWRITE 0x01 /* Caller knows map may overwrite. */
|
||||||
#define WMF_WRITEFLAGSONLY 0x02 /* Copy physaddr and update flags. */
|
#define WMF_WRITEFLAGSONLY 0x02 /* Copy physaddr and update flags. */
|
||||||
#define WMF_FREE 0x04 /* Free pages overwritten. */
|
#define WMF_FREE 0x04 /* Free pages overwritten. */
|
||||||
|
#define WMF_VERIFY 0x08 /* Check pagetable contents. */
|
||||||
|
|
||||||
#define MAP_NONE 0xFFFFFFFE
|
#define MAP_NONE 0xFFFFFFFE
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user