diff --git a/src/kernel/vm2/area.C b/src/kernel/vm2/area.C index 0f226ea5d3..43771d1cc5 100644 --- a/src/kernel/vm2/area.C +++ b/src/kernel/vm2/area.C @@ -180,7 +180,7 @@ status_t area::getInfo(area_info *dest) { bool area::contains(const void *address) { unsigned long base=(unsigned long)(address); - error ("area::contains: looking for %d in %d -- %d, value = %d\n",base,start_address,end_address, ((start_address<=base) && (end_address>=base))); +// error ("area::contains: looking for %d in %d -- %d, value = %d\n",base,start_address,end_address, ((start_address<=base) && (end_address>=base))); return ((start_address<=base) && (base<=end_address)); } @@ -223,8 +223,10 @@ status_t area::resize(size_t newSize) { // When the protection for the area changes, the protection for every one of the pages must change status_t area::setProtection(protectType prot) { + dump(); for (hashIterate hi(vpages);node *cur=hi.get();) { vpage *page=(vpage *)cur; + error ("setting protection on %x\n",page); page->setProtection(prot); } protection=prot; diff --git a/src/kernel/vm2/areaManager.C b/src/kernel/vm2/areaManager.C index be76a95435..99945f5d8a 100644 --- a/src/kernel/vm2/areaManager.C +++ b/src/kernel/vm2/areaManager.C @@ -249,12 +249,13 @@ void areaManager::setByte(unsigned long address,char value) { } void areaManager::setInt(unsigned long address,int value) { - error ("areaManager::setInt starting to set on address %lx, value = %d\n",address,value); +// error ("areaManager::setInt starting to set on address %lx, value = %d\n",address,value); area *myArea; lock(); - error ("areaManager::setInt locked\n"); +// error ("areaManager::setInt locked\n"); myArea=findArea((void *)address); - error ("areaManager::setInt area %s found\n",((myArea)?"":" not ")); +// error ("areaManager::setInt area %s found\n",((myArea)?"":" not ")); + try { if (myArea) myArea->setInt(address,value); else { @@ -263,7 +264,10 @@ void areaManager::setInt(unsigned long address,int value) { unlock(); throw (temp); } - error ("areaManager::setInt unlocking\n"); + } + catch (const char *t) { unlock();throw t;} + catch (char *t) { unlock();throw t;} +// error ("areaManager::setInt unlocking\n"); unlock(); } @@ -303,28 +307,29 @@ void *areaManager::mmap(void *addr, size_t len, int prot, int flags, int fd, off protType=(prot&PROT_WRITE)?writable:(prot&(PROT_READ|PROT_EXEC))?readable:none; //error ("flags = %x, anon = %x\n",flags,MAP_ANON); lock(); - if (flags & MAP_ANON) { + if (flags & MAP_ANON) createArea(name,(int)((len+PAGE_SIZE-1)/PAGE_SIZE),&addr, addType ,LAZY,protType); - return addr; + else { + int shareCount=0; + mmapSharing share; + if (flags & MAP_SHARED) { share=SHARED;shareCount++;} + if (flags & MAP_PRIVATE) { share=PRIVATE;shareCount++;} + if (flags & MAP_COPY){ share=COPY;shareCount++;} + if (shareCount!=1) + addr=NULL; + else { + area *newArea = new (vmBlock->areaPool->get()) area; + newArea->setup(this); + //error ("area = %x, start = %x\n",newArea, newArea->getStartAddress()); + newArea->createAreaMappingFile(name,(int)((len+PAGE_SIZE-1)/PAGE_SIZE),&addr,addType,LAZY,protType,fd,offset,share); + atomic_add(&nextAreaID,1); + newArea->setAreaID(nextAreaID); + addArea(newArea); + newArea->getAreaID(); + //pageMan.dump(); + //newArea->dump(); } - - int shareCount=0; - mmapSharing share; - if (flags & MAP_SHARED) { share=SHARED;shareCount++;} - if (flags & MAP_PRIVATE) { share=PRIVATE;shareCount++;} - if (flags & MAP_COPY){ share=COPY;shareCount++;} - if (shareCount!=1) - return NULL; - area *newArea = new (vmBlock->areaPool->get()) area; - newArea->setup(this); - //error ("area = %x, start = %x\n",newArea, newArea->getStartAddress()); - newArea->createAreaMappingFile(name,(int)((len+PAGE_SIZE-1)/PAGE_SIZE),&addr,addType,LAZY,protType,fd,offset,share); - atomic_add(&nextAreaID,1); - newArea->setAreaID(nextAreaID); - addArea(newArea); - newArea->getAreaID(); - //pageMan.dump(); - //newArea->dump(); + } unlock(); return addr; } diff --git a/src/kernel/vm2/areaManager.h b/src/kernel/vm2/areaManager.h index 4c563c6957..8642a6df6d 100644 --- a/src/kernel/vm2/areaManager.h +++ b/src/kernel/vm2/areaManager.h @@ -53,13 +53,16 @@ class areaManager // One of these per process area *findAreaLock(area_id id); status_t setProtection(int areaID,protectType prot) { status_t retVal; + error ("area::setProtection about to lock\n"); lock(); + error ("area::setProtection locked\n"); area *myArea=findArea(areaID); if (myArea) retVal= myArea->setProtection(prot); else retVal= B_ERROR; unlock(); + error ("area::setProtection unlocked\n"); return retVal; } status_t resizeArea(int Area,size_t size) { diff --git a/src/kernel/vm2/list.h b/src/kernel/vm2/list.h index 43898f9c69..e42cb9ab6d 100644 --- a/src/kernel/vm2/list.h +++ b/src/kernel/vm2/list.h @@ -46,6 +46,8 @@ class list { nodeCount--; done=true; } + if (!done) + throw ("list::remove failed to find node %x\n",toNuke); } //error ("list::remove ending: \n"); //dump(); diff --git a/src/kernel/vm2/vpage.C b/src/kernel/vm2/vpage.C index 71c5d0564e..33428aafcf 100644 --- a/src/kernel/vm2/vpage.C +++ b/src/kernel/vm2/vpage.C @@ -120,14 +120,14 @@ void vpage::setProtection(protectType prot) { // This is dispatched by the real interrupt handler, who locates us // true = OK, false = panic. bool vpage::fault(void *fault_address, bool writeError, int &in_count) { - error ("vpage::fault: virtual address = %lx, write = %s\n",(unsigned long) fault_address,((writeError)?"true":"false")); +// error ("vpage::fault: virtual address = %lx, write = %s\n",(unsigned long) fault_address,((writeError)?"true":"false")); if (writeError && protection != copyOnWrite && protection != writable) return false; if (writeError && physPage) { // If we already have a page and this is a write, it is either a copy on write or a "dirty" notice dirty=true; if (protection==copyOnWrite) { // Else, this was just a "let me know when I am dirty"... page *newPhysPage=vmBlock->pageMan->getPage(); - error ("vpage::fault - copy on write allocated page %x\n",newPhysPage); +// error ("vpage::fault - copy on write allocated page %x\n",newPhysPage); memcpy((void *)(newPhysPage->getAddress()),(void *)(physPage->getAddress()),PAGE_SIZE); physPage=newPhysPage; protection=writable; @@ -140,10 +140,10 @@ bool vpage::fault(void *fault_address, bool writeError, int &in_count) { } // Guess this is the real deal. Get a physical page. physPage=vmBlock->pageMan->getPage(); - error ("vpage::fault - regular - allocated page %x\n",physPage); +// error ("vpage::fault - regular - allocated page %x\n",physPage); if (!physPage) // No room at the inn return false; - error ("vpage::fault: New page allocated! new physical address = %x vnode.fd=%d, vnode.offset=%d, \n",physPage->getAddress(),((backingNode)?backingNode->fd:0),((backingNode)?backingNode->offset:0)); +// error ("vpage::fault: New page allocated! new physical address = %x vnode.fd=%d, vnode.offset=%d, \n",physPage->getAddress(),((backingNode)?backingNode->fd:0),((backingNode)?backingNode->offset:0)); // Update the architecture specific stuff here... // This refresh is unneeded if the data was never written out... // dump(); @@ -186,7 +186,10 @@ void vpage::setByte(unsigned long address,char value,areaManager *manager) { if (!physPage) if (!manager->fault((void *)(address),true)) throw ("vpage::setByte"); - *((char *)(address-start_address+physPage->getAddress()))=value; + if (protection>=writable) + *((char *)(address-start_address+physPage->getAddress()))=value; + else + throw ("vpage::setByte - no permission to write"); // error ("vpage::setByte: physical address = %d, value = %d\n",physPage->getAddress(), *((char *)(physPage->getAddress()))); } @@ -201,12 +204,15 @@ int vpage::getInt(unsigned long address,areaManager *manager) { } void vpage::setInt(unsigned long address,int value,areaManager *manager) { - error ("vpage::setInt: here I am!\n"); +// error ("vpage::setInt: here I am!\n"); if (!physPage) if (!manager->fault((void *)(address),true)) throw ("vpage::setInt"); - *((int *)(address-start_address+physPage->getAddress()))=value; - error ("vpage::setInt: leaving!\n"); + if (protection>=writable) + *((int *)(address-start_address+physPage->getAddress()))=value; + else + throw ("vpage::setInt - no permission to write"); +// error ("vpage::setInt: leaving!\n"); } // Swaps pages out where necessary.