diff --git a/src/sys/vmm/copyvirtualspace.c b/src/sys/vmm/copyvirtualspace.c index 9fdcdb8..bee6ec7 100644 --- a/src/sys/vmm/copyvirtualspace.c +++ b/src/sys/vmm/copyvirtualspace.c @@ -52,179 +52,153 @@ void * vmmCopyVirtualSpace(pidType pid) { - void *newPageDirectoryAddress = 0x0; - uInt32 *parentPageDirectory = 0x0, *newPageDirectory = 0x0; - uInt32 *parentPageTable = 0x0, *newPageTable = 0x0; - uInt32 *parentStackPage = 0x0, *newStackPage = 0x0; - uInt16 x = 0, i = 0, s = 0; + void *newPageDirectoryAddress = 0x0; + uInt32 *parentPageDirectory = 0x0, *newPageDirectory = 0x0; + uInt32 *parentPageTable = 0x0, *newPageTable = 0x0; + uInt32 *parentStackPage = 0x0, *newStackPage = 0x0; + uInt16 x = 0, i = 0, s = 0; - spinLock(&cvsSpinLock); + spinLock(&cvsSpinLock); - /* Set Address Of Parent Page Directory */ - - parentPageDirectory = (uInt32 *) parentPageDirAddr; - - /* Allocate A New Page For The New Page Directory */ - if ((newPageDirectory = (uInt32 *) vmmGetFreeKernelPage(pid,1)) == 0x0) - kpanic("Error: newPageDirectory == NULL, File: %s, Line: %i\n",__FILE__,__LINE__); + /* Set Address Of Parent Page Directory */ + parentPageDirectory = (uInt32 *) parentPageDirAddr; + /* Allocate A New Page For The New Page Directory */ + if ((newPageDirectory = (uInt32 *) vmmGetFreeKernelPage(pid,1)) == 0x0) + kpanic("Error: newPageDirectory == NULL, File: %s, Line: %i\n",__FILE__,__LINE__); - /* Set newPageDirectoryAddress To The Newly Created Page Directories Page */ - newPageDirectoryAddress = (void *)vmm_getPhysicalAddr((uInt32) newPageDirectory); + /* Set newPageDirectoryAddress To The Newly Created Page Directories Page */ + newPageDirectoryAddress = (void *)vmm_getPhysicalAddr((uInt32) newPageDirectory); - /* First Set Up A Flushed Page Directory */ - memset(newPageDirectory,0x0,0x1000); + /* First Set Up A Flushed Page Directory */ + memset(newPageDirectory,0x0,0x1000); - /* Map The Top 1GB Region Of The VM Space */ - for (x = 768; x < pageEntries; x++) - newPageDirectory[x] = parentPageDirectory[x]; - /* - * Now For The Fun Stuff For Page Tables 1-766 We Must Map These And Set - * The Permissions On Every Mapped Pages To COW This Will Conserve Memory - * Because The Two VM Spaces Will Be Sharing Some Pages - */ - for (x = 1; x <= 766; x++) - { - /* If Page Table Exists Map It */ - if (parentPageDirectory[x] != 0) - { - /* Set Parent To Propper Page Table */ - parentPageTable = (uInt32 *) (tablesBaseAddress + (0x1000 * x)); + /* Map The Top 1GB Region Of The VM Space */ + for (x = 768; x < pageEntries; x++) { + newPageDirectory[x] = parentPageDirectory[x]; + } + + /* + * Now For The Fun Stuff For Page Tables 1-766 We Must Map These And Set + * The Permissions On Every Mapped Pages To COW This Will Conserve Memory + * Because The Two VM Spaces Will Be Sharing Some Pages + */ + for (x = 1; x <= 766; x++) { + /* If Page Table Exists Map It */ + if (parentPageDirectory[x] != 0) { + /* Set Parent To Propper Page Table */ + parentPageTable = (uInt32 *) (tablesBaseAddress + (0x1000 * x)); + /* Allocate A New Page Table */ + if ((newPageTable = (uInt32 *) vmmGetFreeKernelPage(pid,1)) == 0x0) + kpanic("Error: newPageTable == NULL, File: %s, Line: %i\n",__FILE__,__LINE__); - /* Allocate A New Page Table */ - if ((newPageTable = (uInt32 *) vmmGetFreeKernelPage(pid,1)) == 0x0) - kpanic("Error: newPageTable == NULL, File: %s, Line: %i\n",__FILE__,__LINE__); - - /* Set Parent And New Pages To COW */ - for (i = 0; i < pageEntries; i++) - { + /* Set Parent And New Pages To COW */ + for (i = 0; i < pageEntries; i++) { - /* If Page Is Mapped */ - if ((parentPageTable[i] & 0xFFFFF000) != 0x0) - { - /* Check To See If Its A Stack Page */ - if (((uInt32) parentPageTable[i] & PAGE_STACK) == PAGE_STACK) - { - /* Alloc A New Page For This Stack Page */ - if ((newStackPage = (uInt32 *) vmmGetFreeKernelPage(pid,1)) == 0x0) - kpanic("Error: newStackPage == NULL, File: %s, Line: %i\n",__FILE__,__LINE__); + /* If Page Is Mapped */ + if ((parentPageTable[i] & 0xFFFFF000) != 0x0) { + /* Check To See If Its A Stack Page */ + if (((uInt32) parentPageTable[i] & PAGE_STACK) == PAGE_STACK) { + /* Alloc A New Page For This Stack Page */ + if ((newStackPage = (uInt32 *) vmmGetFreeKernelPage(pid,1)) == 0x0) + kpanic("Error: newStackPage == NULL, File: %s, Line: %i\n",__FILE__,__LINE__); - /* Set Pointer To Parents Stack Page */ - parentStackPage = (uInt32 *) (((1024 * 4096) * x) + (4096 * i)); + /* Set Pointer To Parents Stack Page */ + parentStackPage = (uInt32 *) (((1024 * 4096) * x) + (4096 * i)); - /* Copy The Tack Byte For Byte (I Should Find A Faster Way) */ - for (s = 0x0; s < pageEntries; s++) - { - newStackPage[s] = parentStackPage[s]; - } - - /* Insert New Stack Into Page Table */ - newPageTable[i] = (vmm_getPhysicalAddr((uInt32) newStackPage) | PAGE_DEFAULT | PAGE_STACK); - - /* Unmap From Kernel Space */ - vmmUnmapPage((uInt32) newStackPage, 1); - } - else - { - /* Set Page To COW In Parent And Child Space */ - newPageTable[i] = (((uInt32) parentPageTable[i] & 0xFFFFF000) | (PAGE_DEFAULT | pageCow)); - - /* Increment The COW Counter For This Page */ - if (((uInt32) parentPageTable[i] & pageCow) == pageCow) - adjustCowCounter(((uInt32) parentPageTable[i] & 0xFFFFF000), 1); - else - { - adjustCowCounter(((uInt32) parentPageTable[i] & 0xFFFFF000), 2); - parentPageTable[i] = newPageTable[i]; - } - } - } - else - newPageTable[i] = (uInt32) 0x0; - } - /* Put New Page Table Into New Page Directory */ - newPageDirectory[x] = (vmm_getPhysicalAddr((uInt32) newPageTable) | PAGE_DEFAULT); - - /* Unmap Page From Kernel Space But Keep It Marked As Not Avail */ - vmmUnmapPage((uInt32) newPageTable, 1); - } - else - newPageDirectory[x] = (uInt32) 0x0; + /* Copy The Tack Byte For Byte (I Should Find A Faster Way) */ + for (s = 0x0; s < pageEntries; s++) { + newStackPage[s] = parentStackPage[s]; + } + /* Insert New Stack Into Page Table */ + newPageTable[i] = (vmm_getPhysicalAddr((uInt32) newStackPage) | PAGE_DEFAULT | PAGE_STACK); + /* Unmap From Kernel Space */ + vmmUnmapPage((uInt32) newStackPage, 1); + } else { + /* Set Page To COW In Parent And Child Space */ + newPageTable[i] = (((uInt32) parentPageTable[i] & 0xFFFFF000) | (PAGE_DEFAULT | pageCow)); + /* Increment The COW Counter For This Page */ + if (((uInt32) parentPageTable[i] & pageCow) == pageCow) { + adjustCowCounter(((uInt32) parentPageTable[i] & 0xFFFFF000), 1); + } else { + adjustCowCounter(((uInt32) parentPageTable[i] & 0xFFFFF000), 2); + parentPageTable[i] = newPageTable[i]; + } + } + } else { + newPageTable[i] = (uInt32) 0x0; } - /* - * Allocate A New Page For The The First Page Table Where We Will Map The - * Lower Region - */ - - if ((newPageTable = (uInt32 *) vmmGetFreeKernelPage(pid,1)) == 0x0) - kpanic("Error: newPageTable == NULL, File: %s, Line: %i\n",__FILE__,__LINE__); + } + /* Put New Page Table Into New Page Directory */ + newPageDirectory[x] = (vmm_getPhysicalAddr((uInt32) newPageTable) | PAGE_DEFAULT); + /* Unmap Page From Kernel Space But Keep It Marked As Not Avail */ + vmmUnmapPage((uInt32) newPageTable, 1); + } else { + newPageDirectory[x] = (uInt32) 0x0; + } + } + /* + * Allocate A New Page For The The First Page Table Where We Will Map The + * Lower Region + */ + if ((newPageTable = (uInt32 *) vmmGetFreeKernelPage(pid,1)) == 0x0) + kpanic("Error: newPageTable == NULL, File: %s, Line: %i\n",__FILE__,__LINE__); - /* Flush The Page From Garbage In Memory */ - memset(newPageTable,0x0,0x1000); + /* Flush The Page From Garbage In Memory */ + memset(newPageTable,0x0,0x1000); - /* Map This Into The Page Directory */ - newPageDirectory[0] = (vmm_getPhysicalAddr((uInt32) newPageTable) | PAGE_DEFAULT); + /* Map This Into The Page Directory */ + newPageDirectory[0] = (vmm_getPhysicalAddr((uInt32) newPageTable) | PAGE_DEFAULT); + /* Set Address Of Parents Page Table */ + parentPageTable = (uInt32 *) tablesBaseAddress; + /* Map The First 1MB Worth Of Pages */ + for (x = 0; x < (pageEntries / 4); x++) { + newPageTable[x] = parentPageTable[x]; + } + /* Map The Next 3MB Worth Of Pages But Make Them COW */ + for (x = (pageEntries / 4) + 1; x < pageEntries; x++) { + /* If Page Is Avaiable Map It */ + if ((parentPageTable[x] & 0xFFFFF000) != 0x0) { + /* Set Pages To COW */ + newPageTable[x] = (((uInt32) parentPageTable[x] & 0xFFFFF000) | (PAGE_DEFAULT | pageCow)); + /* Increment The COW Counter For This Page */ + if (((uInt32) parentPageTable[x] & pageCow) == pageCow) { + adjustCowCounter(((uInt32) parentPageTable[x] & 0xFFFFF000), 1); + } else { + adjustCowCounter(((uInt32) parentPageTable[x] & 0xFFFFF000), 2); + parentPageTable[x] = newPageTable[x]; + } + } else { + newPageTable[x] = (uInt32) 0x0; + } + } + /* Set Virtual Mapping For Page Directory */ + newPageTable[256] = (vmm_getPhysicalAddr((uInt32) newPageDirectory) | PAGE_DEFAULT); - /* Set Address Of Parents Page Table */ - parentPageTable = (uInt32 *) tablesBaseAddress; - - /* Map The First 1MB Worth Of Pages */ - for (x = 0; x < (pageEntries / 4); x++) - newPageTable[x] = parentPageTable[x]; - - /* Map The Next 3MB Worth Of Pages But Make Them COW */ - for (x = (pageEntries / 4) + 1; x < pageEntries; x++) - { - /* If Page Is Avaiable Map It */ - if ((parentPageTable[x] & 0xFFFFF000) != 0x0) - { - /* Set Pages To COW */ - newPageTable[x] = (((uInt32) parentPageTable[x] & 0xFFFFF000) | (PAGE_DEFAULT | pageCow)); - - /* Increment The COW Counter For This Page */ - if (((uInt32) parentPageTable[x] & pageCow) == pageCow) - adjustCowCounter(((uInt32) parentPageTable[x] & 0xFFFFF000), 1); - else - { - adjustCowCounter(((uInt32) parentPageTable[x] & 0xFFFFF000), 2); - parentPageTable[x] = newPageTable[x]; - } - } - else - newPageTable[x] = (uInt32) 0x0; - } - - /* Set Virtual Mapping For Page Directory */ - newPageTable[256] = (vmm_getPhysicalAddr((uInt32) newPageDirectory) | PAGE_DEFAULT); - - /* - * Now The Fun Stuff Build The Initial Virtual Page Space So We Don't Have - * To Worry About Mapping Them In Later How Ever I'm Concerned This May - * Become A Security Issue - */ - /* First Lets Unmap The Previously Allocated Page Table */ - vmmUnmapPage((uInt32) newPageTable, 1); - - /* Allocate A New Page Table */ - if ((newPageTable = (uInt32 *) vmmGetFreeKernelPage(pid,1)) == 0x0) - kpanic("Error: newPageTable == NULL, File: %s, Line: %i\n",__FILE__,__LINE__); - - /* First Set Our Page Directory To Contain This */ - newPageDirectory[767] = vmm_getPhysicalAddr((uInt32) newPageTable) | PAGE_DEFAULT; - - /* Now Lets Build The Page Table */ - for (x = 0; x < pageEntries; x++) - newPageTable[x] = newPageDirectory[x]; - - /* Now We Are Done So Lets Unmap This Page */ - vmmUnmapPage((uInt32) newPageTable, 1); - - /* Now We Are Done With The Page Directory So Lets Unmap That Too */ - vmmUnmapPage((uInt32) newPageDirectory, 1); + /* + * Now The Fun Stuff Build The Initial Virtual Page Space So We Don't Have + * To Worry About Mapping Them In Later How Ever I'm Concerned This May + * Become A Security Issue + */ + /* First Lets Unmap The Previously Allocated Page Table */ + vmmUnmapPage((uInt32) newPageTable, 1); + /* Allocate A New Page Table */ + if ((newPageTable = (uInt32 *) vmmGetFreeKernelPage(pid,1)) == 0x0) + kpanic("Error: newPageTable == NULL, File: %s, Line: %i\n",__FILE__,__LINE__); + /* First Set Our Page Directory To Contain This */ + newPageDirectory[767] = vmm_getPhysicalAddr((uInt32) newPageTable) | PAGE_DEFAULT; + /* Now Lets Build The Page Table */ + for (x = 0; x < pageEntries; x++) { + newPageTable[x] = newPageDirectory[x]; + } + /* Now We Are Done So Lets Unmap This Page */ + vmmUnmapPage((uInt32) newPageTable, 1); + /* Now We Are Done With The Page Directory So Lets Unmap That Too */ + vmmUnmapPage((uInt32) newPageDirectory, 1); - spinUnlock(&cvsSpinLock); + spinUnlock(&cvsSpinLock); - /* Return Physical Address Of Page Directory */ - return (newPageDirectoryAddress); + /* Return Physical Address Of Page Directory */ + return (newPageDirectoryAddress); } /*** diff --git a/src/sys/vmm/createvirtualspace.c b/src/sys/vmm/createvirtualspace.c index ab307b0..84319ea 100644 --- a/src/sys/vmm/createvirtualspace.c +++ b/src/sys/vmm/createvirtualspace.c @@ -1,3 +1,47 @@ +/***************************************************************************************** + Copyright (c) 2002 The UbixOS Project + All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are +permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of +conditions, the following disclaimer and the list of authors. Redistributions in binary +form must reproduce the above copyright notice, this list of conditions, the following +disclaimer and the list of authors in the documentation and/or other materials provided +with the distribution. Neither the name of the UbixOS Project nor the names of its +contributors may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + $Log$ + Revision 1.2 2004/07/28 15:05:43 reddawg + Major: + Pages now have strict security enforcement. + Many null dereferences have been resolved. + When apps loaded permissions set for pages rw and ro + + Revision 1.1.1.1 2004/04/15 12:06:51 reddawg + UbixOS v1.0 + + Revision 1.8 2004/04/13 16:36:34 reddawg + Changed our copyright, it is all now under a BSD-Style license + + + + $Id$ + +*****************************************************************************************/ + #include @@ -89,4 +133,7 @@ return (newPageDirectoryAddress); } +/*** + END + ***/ diff --git a/src/sys/vmm/getfreepage.c b/src/sys/vmm/getfreepage.c index f1dc839..f4706ed 100644 --- a/src/sys/vmm/getfreepage.c +++ b/src/sys/vmm/getfreepage.c @@ -47,45 +47,33 @@ void * vmmGetFreePage(pidType pid) { - uInt16 x = 0x0; - uInt16 y = 0x0; - uInt32 *pageTableSrc = 0x0; + uInt16 x = 0x0, y = 0x0; + uInt32 *pageTableSrc = 0x0; + + spinLock(&vmmGFPlock); + + /* Lets Search For A Free Page */ + for (x = 768; x < 1024; x++) { - spinLock(&vmmGFPlock); - - /* Lets Search For A Free Page */ - for (x = 768; x < 1024; x++) { - /* Set Page Table Address */ - pageTableSrc = (uInt32 *) (tablesBaseAddress + (0x1000 * x)); - - for (y = 0x0; y < 1024; y++) { - /* - * Loop Through The Page Table Find An UnAllocated - * Page - */ - if ((uInt32) pageTableSrc[y] == (uInt32) 0x0) { - /* Map A Physical Page To The Virtual Page */ - if ((vmm_remapPage(vmmFindFreePage(pid), ((x * 0x400000) + (y * 0x1000)), KERNEL_PAGE_DEFAULT)) == 0x0) - kpanic("vmmRemapPage: vmmGetFreePage\n"); - - /* Clear This Page So No Garbage Is There */ - vmmClearVirtualPage((uInt32) ((x * 0x400000) + (y * 0x1000))); - - spinUnlock(&vmmGFPlock); - - /* - * Return The Address Of The Newly Allocate - * Page - */ - return ((void *)((x * 0x400000) + (y * 0x1000))); - } - } - } + /* Set Page Table Address */ + pageTableSrc = (uInt32 *) (tablesBaseAddress + (0x1000 * x)); + for (y = 0x0; y < 1024; y++) { + /* Loop Through The Page Table Find An UnAllocated Page */ + if ((uInt32) pageTableSrc[y] == (uInt32) 0x0) { + /* Map A Physical Page To The Virtual Page */ + if ((vmm_remapPage(vmmFindFreePage(pid), ((x * 0x400000) + (y * 0x1000)),KERNEL_PAGE_DEFAULT)) == 0x0) + kpanic("vmmRemapPage: vmmGetFreePage\n"); + /* Clear This Page So No Garbage Is There */ + vmmClearVirtualPage((uInt32) ((x * 0x400000) + (y * 0x1000))); + /* Return The Address Of The Newly Allocate Page */ spinUnlock(&vmmGFPlock); - - /* If No Free Page Was Found Return NULL */ - kpanic("No free pages!\n"); - return (0x0); + return ((void *)((x * 0x400000) + (y * 0x1000))); + } + } + } + /* If No Free Page Was Found Return NULL */ + spinUnlock(&vmmGFPlock); + return (0x0); } /*** diff --git a/src/sys/vmm/getfreevirtualpage.c b/src/sys/vmm/getfreevirtualpage.c index 519596c..f65f05f 100644 --- a/src/sys/vmm/getfreevirtualpage.c +++ b/src/sys/vmm/getfreevirtualpage.c @@ -55,94 +55,71 @@ pageDir = (uInt32 *) parentPageDirAddr; /* Lets Search For A Free Page */ - if (_current->oInfo.vmStart <= 0x100000) - kpanic("Invalid vmStart\n"); + if (_current->oInfo.vmStart <= 0x100000) + kpanic("Invalid vmStart\n"); + for (x = (_current->oInfo.vmStart / (1024 * 4096)); x < 1024; x++) { + /* Set Page Table Address */ + if ((pageDir[x] & PAGE_PRESENT) != PAGE_PRESENT) { + /* If Page Table Is Non Existant Then Set It Up */ + pageDir[x] = (uInt32) vmmFindFreePage(_current->id) | PAGE_DEFAULT; + /* Also Add It To Virtual Space So We Can Make Changes Later */ + pageTableSrc = (uInt32 *) (tablesBaseAddress + (4096 * 767)); + pageTableSrc[x] = pageDir[x]; + y = 1; + /* Reload Page Directory */ + asm( + "movl %cr3,%eax\n" + "movl %eax,%cr3\n" + ); + } + pageTableSrc = (uInt32 *) (tablesBaseAddress + (0x1000 * x)); + if (y != 0x0) { + for (y = 0x0;y 0x1) { + for (c = 0; c < count; c++) { + if (y + c < 1024) { + if ((uInt32) pageTableSrc[y + c] != (uInt32) 0x0) { + c = -1; + break; + } + } + } + if (c != -1) { + for (c = 0; c < count; c++) { + if ((vmm_remapPage((uInt32) vmmFindFreePage(pid), ((x * (1024 * 4096)) + ((y + c) * 4096)),PAGE_DEFAULT)) == 0x0) + kpanic("vmmRemapPage: getFreeVirtualPage-1: [0x%X]\n",((x * (1024 * 4096)) + ((y + c) * 4096))); + vmmClearVirtualPage((uInt32) ((x * (1024 * 4096)) + ((y + c) * 4096))); + } + spinUnlock(&fvpSpinLock); + return ((void *)((x * (1024 * 4096)) + (y * 4096))); + } + } else { + /* Map A Physical Page To The Virtual Page */ - for (x = (_current->oInfo.vmStart / (1024 * 4096)); x < 1024; x++) - { - - /* Set Page Table Address */ - if ((pageDir[x] & PAGE_PRESENT) != PAGE_PRESENT) - { - /* If Page Table Is Non Existant Then Set It Up */ - pageDir[x] = (uInt32) vmmFindFreePage(_current->id) | PAGE_DEFAULT; - - /* Also Add It To Virtual Space So We Can Make Changes Later */ - pageTableSrc = (uInt32 *) (tablesBaseAddress + (4096 * 767)); - pageTableSrc[x] = pageDir[x]; - y = 1; - - /* Reload Page Directory */ - asm( - "movl %cr3,%eax\n" - "movl %eax,%cr3\n" - ); - } - - pageTableSrc = (uInt32 *) (tablesBaseAddress + (0x1000 * x)); - if (y != 0x0) - { - for (y = 0x0;y 0x1) - { - for (c = 0; c < count; c++) - { - if (y + c < 1024) - { - if ((uInt32) pageTableSrc[y + c] != (uInt32) 0x0) - { - c = -1; - break; - } - } - } - if (c != -1) - { - for (c = 0; c < count; c++) - { - if ((vmm_remapPage((uInt32) vmmFindFreePage(pid), ((x * (1024 * 4096)) + ((y + c) * 4096)),PAGE_DEFAULT)) == 0x0) - kpanic("vmmRemapPage: getFreeVirtualPage-1: [0x%X]\n",((x * (1024 * 4096)) + ((y + c) * 4096))); - vmmClearVirtualPage((uInt32) ((x * (1024 * 4096)) + ((y + c) * 4096))); - } - spinUnlock(&fvpSpinLock); - return ((void *)((x * (1024 * 4096)) + (y * 4096))); - } - } - else - { - /* Map A Physical Page To The Virtual Page */ - - /* - * remapPage((uInt32)vmmFindFreePage(pid),((x*(1024*4096))+(y*4096)) - * ,pid); - */ - if ((vmm_remapPage((uInt32) vmmFindFreePage(pid), ((x * (1024 * 4096)) + (y * 4096)),PAGE_DEFAULT)) == 0x0) - kpanic("vmmRemapPage: getFreeVirtualPage-2\n"); - - /* Clear This Page So No Garbage Is There */ - vmmClearVirtualPage((uInt32) ((x * (1024 * 4096)) + (y * 4096))); - - spinUnlock(&fvpSpinLock); - /* Return The Address Of The Newly Allocate Page */ - return ((void *)((x * (1024 * 4096)) + (y * 4096))); - } - } - } + /* + * remapPage((uInt32)vmmFindFreePage(pid),((x*(1024*4096))+(y*4096)) + * ,pid); + */ + if ((vmm_remapPage((uInt32) vmmFindFreePage(pid), ((x * (1024 * 4096)) + (y * 4096)),PAGE_DEFAULT)) == 0x0) + kpanic("vmmRemapPage: getFreeVirtualPage-2\n"); + /* Clear This Page So No Garbage Is There */ + vmmClearVirtualPage((uInt32) ((x * (1024 * 4096)) + (y * 4096))); + /* Return The Address Of The Newly Allocate Page */ + spinUnlock(&fvpSpinLock); + return ((void *)((x * (1024 * 4096)) + (y * 4096))); } - spinUnlock(&fvpSpinLock); - - /* If No Free Page Was Found Return NULL */ - return (0x0); + } + } + } + /* If No Free Page Was Found Return NULL */ + spinUnlock(&fvpSpinLock); + return (0x0); } /*** diff --git a/src/sys/vmm/getphysicaladdr.c b/src/sys/vmm/getphysicaladdr.c index 363288a..260c568 100644 --- a/src/sys/vmm/getphysicaladdr.c +++ b/src/sys/vmm/getphysicaladdr.c @@ -35,30 +35,24 @@ Notes: ************************************************************************/ -uInt32 -vmm_getPhysicalAddr(uInt32 pageAddr) -{ - uInt32 pageDirectoryIndex = 0x0; - uInt32 pageTableIndex = 0x0; - uInt32 *pageTable = 0x0; +uInt32 vmm_getPhysicalAddr(uInt32 pageAddr) { + int pageDirectoryIndex = 0x0, pageTableIndex = 0x0; + uInt32 *pageTable = 0x0; - //Calculate The Page Directory Index - pageDirectoryIndex = (pageAddr >> 22); - - //Calculate The Page Table Index - pageTableIndex = ((pageAddr >> 12) & 0x3FF); - - /* Set pageTable To The Virtual Address Of Table */ - pageTable = (uInt32 *) (tablesBaseAddress + (0x1000 * pageDirectoryIndex)); - /* Return The Physical Address Of The Page */ - return ((uInt32) (pageTable[pageTableIndex] & 0xFFFFF000)); -} + //Calculate The Page Directory Index + pageDirectoryIndex = (pageAddr >> 22); + + //Calculate The Page Table Index + pageTableIndex = ((pageAddr >> 12) & 0x3FF); + + /* Set pageTable To The Virtual Address Of Table */ + pageTable = (uInt32 *) (tablesBaseAddress + (0x1000 * pageDirectoryIndex)); + /* Return The Physical Address Of The Page */ + return ((uInt32)(pageTable[pageTableIndex] & 0xFFFFF000)); + } /*** $Log$ - Revision 1.5 2005/08/06 11:43:45 fsdfs - code clean up - Revision 1.4 2004/07/28 15:05:43 reddawg Major: Pages now have strict security enforcement. diff --git a/src/sys/vmm/memory.c b/src/sys/vmm/memory.c index 380c1f7..3b55edb 100644 --- a/src/sys/vmm/memory.c +++ b/src/sys/vmm/memory.c @@ -57,7 +57,6 @@ int vmmMemMapInit() { int i = 0x0; int memStart = 0x0; - uInt32 MB1, MB2; /* Count System Memory */ numPages = countMemory(); @@ -66,7 +65,7 @@ vmmMemoryMap = (mMap *) 0x101000; /* Initialize Map Make All Pages Not Available */ - for (i = 0; i < numPages; i++) { + for (i = 0x0; i < numPages; i++) { vmmMemoryMap[i].cowCounter = 0x0; vmmMemoryMap[i].status = memNotavail; vmmMemoryMap[i].pid = vmmID; @@ -85,11 +84,9 @@ freePages++; } - MB1 = ((numPages * 4096 ) / 1024 ) / 1024; - MB2 = ((freePages * 4096 ) / 1024) / 1024; - - kprintf("Real Memory: %d MB\n", MB1); - kprintf("Available Memory: %d MB\n", MB2); + /* Print Out Amount Of Memory */ + kprintf("Real Memory: %iKB\n", numPages * 4); + kprintf("Available Memory: %iKB\n", freePages * 4); /* Return */ return (0); @@ -336,9 +333,6 @@ /*** $Log$ - Revision 1.16 2005/08/08 21:33:44 fsdfs - new scheduler! - Revision 1.15 2004/09/11 23:39:31 reddawg ok time for bed diff --git a/src/sys/vmm/page_fault.S b/src/sys/vmm/page_fault.S index bc6b281..736d3dd 100644 --- a/src/sys/vmm/page_fault.S +++ b/src/sys/vmm/page_fault.S @@ -56,5 +56,19 @@ /*** + $Log$ + Revision 1.4 2004/08/14 11:23:03 reddawg + Changes + + Revision 1.3 2004/07/28 22:23:02 reddawg + make sure it still works before I goto bed + + Revision 1.2 2004/07/26 19:15:49 reddawg + test code, fixes and the like + + Revision 1.1 2004/07/24 23:13:21 reddawg + Oh yeah try this one + END ***/ + diff --git a/src/sys/vmm/pagefault.c b/src/sys/vmm/pagefault.c index 20e7247..c7b59c8 100644 --- a/src/sys/vmm/pagefault.c +++ b/src/sys/vmm/pagefault.c @@ -50,101 +50,83 @@ cpu is a waste of resources but for now it prevents errors. *****************************************************************************************/ -void vmm_pageFault(uInt32 memAddr,uInt32 eip,uInt32 esp) -{ - uInt32 i = 0x0; - uInt32 pageTableIndex = 0x0; - uInt32 pageDirectoryIndex = 0x0; - uInt32 *pageDir = 0x0; - uInt32 *pageTable = 0x0; - uInt32 *src = 0x0; - uInt32 *dst = 0x0; +void vmm_pageFault(uInt32 memAddr,uInt32 eip,uInt32 esp) { + uInt32 i = 0x0, pageTableIndex = 0x0,pageDirectoryIndex = 0x0; + uInt32 *pageDir = 0x0,*pageTable = 0x0; + uInt32 *src = 0x0,*dst = 0x0; - /* Try to aquire lock otherwise spin till we do */ - spinLock(&pageFaultSpinLock); + /* Try to aquire lock otherwise spin till we do */ + spinLock(&pageFaultSpinLock); - /* Set page dir pointer to the address of the visable page directory */ - pageDir = (uInt32 *)parentPageDirAddr; + /* Set page dir pointer to the address of the visable page directory */ + pageDir = (uInt32 *)parentPageDirAddr; - /* UBU - This is a temp panic for 0x0 read write later on I will handle this differently */ - if (memAddr == 0x0) - { - spinUnlock(&pageFaultSpinLock); - kprintf("Segfault At Address: [0x%X][0x%X][%i][0x%X]\n",memAddr,esp,_current->id,eip); - kpanic("Error We Wrote To 0x0\n"); - } + /* UBU - This is a temp panic for 0x0 read write later on I will handle this differently */ + if (memAddr == 0x0) { + kprintf("Segfault At Address: [0x%X][0x%X][%i][0x%X]\n",memAddr,esp,_current->id,eip); + kpanic("Error We Wrote To 0x0\n"); + } - /* Calculate The Page Directory Index */ - pageDirectoryIndex = (memAddr >> 22); + /* Calculate The Page Directory Index */ + pageDirectoryIndex = (memAddr >> 22); - /* Calculate The Page Table Index */ - pageTableIndex = ((memAddr >> 12) & 0x3FF); + /* Calculate The Page Table Index */ + pageTableIndex = ((memAddr >> 12) & 0x3FF); - /* UBU - This is a temporary routine for handling access to a page of a non existant page table */ - if (pageDir[pageDirectoryIndex] == 0x0) - { - spinUnlock(&pageFaultSpinLock); - kprintf("Segfault At Address: [0x%X][0x%X][%i][0x%X], Not A Valid Page Table\n",memAddr,esp,_current->id,eip); - endTask2(_current); - } - else - { - /* Set pageTable To Point To Virtual Address Of Page Table */ - pageTable = (uInt32 *)(tablesBaseAddress + (0x1000 * pageDirectoryIndex)); + /* UBU - This is a temporary routine for handling access to a page of a non existant page table */ + if (pageDir[pageDirectoryIndex] == 0x0) { + kprintf("Segfault At Address: [0x%X][0x%X][%i][0x%X], Not A Valid Page Table\n",memAddr,esp,_current->id,eip); + spinUnlock(&pageFaultSpinLock); + endTask(_current->id); + } + else { + /* Set pageTable To Point To Virtual Address Of Page Table */ + pageTable = (uInt32 *)(tablesBaseAddress + (0x1000 * pageDirectoryIndex)); - /* Test if this is a COW on page */ - if (((uInt32)pageTable[pageTableIndex] & pageCow) == pageCow) - { - /* Set Src To Base Address Of Page To Copy */ - src = (uInt32 *)(memAddr & 0xFFFFF000); - /* Allocate A Free Page For Destination */ - dst = (uInt32 *) vmmGetFreeVirtualPage(_current->id,1); - /* Copy Memory */ - for (i=0;iid,eip); - spinUnlock(&pageFaultSpinLock); - endTask2(_current); - } - else - { - /* Need To Create A Routine For Attempting To Access Non Mapped Memory */ - kprintf("Segfault At Address: [0x%X][0x%X][%i][0x%X] Non Mapped\n",memAddr,esp,_current->id,eip); - spinUnlock(&pageFaultSpinLock); - endTask2(_current); - } - } - asm volatile( - "movl %cr3,%eax\n" - "movl %eax,%cr3\n" - ); + /* Test if this is a COW on page */ + if (((uInt32)pageTable[pageTableIndex] & pageCow) == pageCow) { + /* Set Src To Base Address Of Page To Copy */ + src = (uInt32 *)(memAddr & 0xFFFFF000); + /* Allocate A Free Page For Destination */ + dst = (uInt32 *) vmmGetFreeVirtualPage(_current->id,1); + /* Copy Memory */ + for (i=0;iid,eip); + spinUnlock(&pageFaultSpinLock); + endTask(_current->id); + } + else { + spinUnlock(&pageFaultSpinLock); + /* Need To Create A Routine For Attempting To Access Non Mapped Memory */ + kprintf("Segfault At Address: [0x%X][0x%X][%i][0x%X] Non Mapped\n",memAddr,esp,_current->id,eip); + spinUnlock(&pageFaultSpinLock); + endTask(_current->id); + } + } + asm volatile( + "movl %cr3,%eax\n" + "movl %eax,%cr3\n" + ); - /* Release the spin lock */ - spinUnlock(&pageFaultSpinLock); - return; -} + /* Release the spin lock */ + spinUnlock(&pageFaultSpinLock); + return; + } /*** $Log$ - Revision 1.15 2005/08/06 11:43:45 fsdfs - code clean up - Revision 1.14 2004/08/25 22:02:41 reddawg task switching - We now are using software switching to be consistant with the rest of the world because all of this open source freaks gave me a hard time about something I liked. There doesn't seem to be any gain in performance but it is working fine and flawlessly diff --git a/src/sys/vmm/paging.c b/src/sys/vmm/paging.c index 4087a8b..ddfa336 100644 --- a/src/sys/vmm/paging.c +++ b/src/sys/vmm/paging.c @@ -1,29 +1,29 @@ -/***************************************************************************************** -Copyright (c) 2002-2004 The UbixOS Project -All rights reserved. + /***************************************************************************************** + Copyright (c) 2002-2004 The UbixOS Project + All rights reserved. -Redistribution and use in source and binary forms, with or without modification, are -permitted provided that the following conditions are met: + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: -Redistributions of source code must retain the above copyright notice, this list of -conditions, the following disclaimer and the list of authors. Redistributions in binary -form must reproduce the above copyright notice, this list of conditions, the following -disclaimer and the list of authors in the documentation and/or other materials provided -with the distribution. Neither the name of the UbixOS Project nor the names of its -contributors may be used to endorse or promote products derived from this software -without specific prior written permission. + Redistributions of source code must retain the above copyright notice, this list of + conditions, the following disclaimer and the list of authors. Redistributions in binary + form must reproduce the above copyright notice, this list of conditions, the following + disclaimer and the list of authors in the documentation and/or other materials provided + with the distribution. Neither the name of the UbixOS Project nor the names of its + contributors may be used to endorse or promote products derived from this software + without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -$Id$ + $Id$ *****************************************************************************************/ @@ -56,175 +56,172 @@ *****************************************************************************************/ -int -vmm_pagingInit() -{ - uInt32 i = 0x0; - uInt32 *pageTable = 0x0; +int vmm_pagingInit(){ + uInt32 i = 0x0; + uInt32 *pageTable = 0x0; - /* Allocate A Page Of Memory For Kernels Page Directory */ - kernelPageDirectory = (uInt32 *) vmmFindFreePage(sysID); - if (kernelPageDirectory == 0x0) { - kpanic("Error: vmmFindFreePage Failed"); - return (0x1); - } /* end if */ - /* Clear The Memory To Ensure There Is No Garbage */ - for (i = 0; i < pageEntries; i++) { - (uInt32) kernelPageDirectory[i] = (uInt32) 0x0; - } /* end for */ + /* Allocate A Page Of Memory For Kernels Page Directory */ + kernelPageDirectory = (uInt32 *) vmmFindFreePage(sysID); + if (kernelPageDirectory == 0x0) { + kpanic("Error: vmmFindFreePage Failed"); + return (0x1); + } /* end if */ + + /* Clear The Memory To Ensure There Is No Garbage */ + for (i = 0; i < pageEntries; i++) { + (uInt32) kernelPageDirectory[i] = (uInt32) 0x0; + } /* end for */ + + /* Allocate a page for the first 4MB of memory */ + if ((pageTable = (uInt32 *) vmmFindFreePage(sysID)) == 0x0) + kpanic("Error: vmmFindFreePage Failed"); + kernelPageDirectory[0] = (uInt32) ((uInt32) (pageTable) | KERNEL_PAGE_DEFAULT); + + /* Make Sure The Page Table Is Clean */ + memset(pageTable,0x0,0x1000); + + /* + * Map the first 1MB of Memory to the kernel MM space because our kernel starts + * at 0x30000 + * Do not map page at address 0x0 this is reserved for null... + */ + for (i = 0x1; i < (pageEntries / 0x4); i++) { + pageTable[i] = (uInt32) ((i * 0x1000) | KERNEL_PAGE_DEFAULT); + } /* end for */ - /* Allocate a page for the first 4MB of memory */ - if ((pageTable = (uInt32 *) vmmFindFreePage(sysID)) == 0x0) - kpanic("Error: vmmFindFreePage Failed"); - kernelPageDirectory[0] = (uInt32) ((uInt32) (pageTable) | KERNEL_PAGE_DEFAULT); + /* + * Create page tables for the top 1GB of VM space. This space is set aside + * for kernel space and will be shared with each process + */ + for (i = 768; i < pageEntries; i++) { + if ((pageTable = (uInt32 *) vmmFindFreePage(sysID)) == 0x0) + kpanic("Error: vmmFindFreePage Failed"); + + /* Make Sure The Page Table Is Clean */ + memset(pageTable,0x0,0x1000); - /* Make Sure The Page Table Is Clean */ - memset(pageTable, 0x0, 0x1000); + /* Map In The Page Directory */ + kernelPageDirectory[i] = (uInt32) ((uInt32) (pageTable) | KERNEL_PAGE_DEFAULT); + } /* end for */ + + /* Set Up Memory To Be All The Allocated Page Directories */ + if ((pageTable = (uInt32 *) vmmFindFreePage(sysID)) == 0x0) + kpanic("Error: vmmFindFreePage Failed"); + + /* Clean Page Table */ + memset(pageTable,0x0,0x1000); + + kernelPageDirectory[767] = ((uInt32) pageTable | KERNEL_PAGE_DEFAULT); + for (i = 0; i < pageEntries; i++) { + pageTable[i] = kernelPageDirectory[i]; + } /* end for */ + + /* Also Set Up Page Directory To Be The The First Page In 0xE0400000 */ + pageTable = (uInt32 *) (kernelPageDirectory[0] & 0xFFFFF000); + pageTable[256] = (uInt32) ((uInt32) (kernelPageDirectory) | KERNEL_PAGE_DEFAULT); - /* - * Map the first 1MB of Memory to the kernel MM space because our - * kernel starts at 0x30000 Do not map page at address 0x0 this is - * reserved for null... - */ - for (i = 0x1; i < (pageEntries / 0x4); i++) { - pageTable[i] = (uInt32) ((i * 0x1000) | KERNEL_PAGE_DEFAULT); - } /* end for */ + /* Now Lets Turn On Paging With This Initial Page Table */ + asm volatile( + "movl %0,%%eax \n" + "movl %%eax,%%cr3 \n" + "movl %%cr0,%%eax \n" + "orl $0x80010000,%%eax \n" /* Turn on memory protection */ + "movl %%eax,%%cr0 \n" + : + : "d"((uInt32 *) (kernelPageDirectory)) + ); - /* - * Create page tables for the top 1GB of VM space. This space is set - * aside for kernel space and will be shared with each process - */ - for (i = 768; i < pageEntries; i++) { - if ((pageTable = (uInt32 *) vmmFindFreePage(sysID)) == 0x0) - kpanic("Error: vmmFindFreePage Failed"); + /* Remap The Memory List */ + for (i = 0x101000; i <= (0x101000 + (numPages * sizeof(mMap))); i += 0x1000) { + if ((vmm_remapPage(i, (vmmMemoryMapAddr + (i - 0x101000)),KERNEL_PAGE_DEFAULT)) == 0x0) + kpanic("vmmRemapPage failed\n"); + } + /* Set New Address For Memory Map Since Its Relocation */ + vmmMemoryMap = (mMap *) vmmMemoryMapAddr; - /* Make Sure The Page Table Is Clean */ - memset(pageTable, 0x0, 0x1000); + /* Print information on paging */ + kprintf("paging0 - Address: [0x%X], PagingISR Address: [0x%X]\n", kernelPageDirectory, &_vmm_pageFault); - /* Map In The Page Directory */ - kernelPageDirectory[i] = (uInt32) ((uInt32) (pageTable) | KERNEL_PAGE_DEFAULT); - } /* end for */ - - /* Set Up Memory To Be All The Allocated Page Directories */ - if ((pageTable = (uInt32 *) vmmFindFreePage(sysID)) == 0x0) - kpanic("Error: vmmFindFreePage Failed"); - - /* Clean Page Table */ - memset(pageTable, 0x0, 0x1000); - - kernelPageDirectory[767] = ((uInt32) pageTable | KERNEL_PAGE_DEFAULT); - for (i = 0; i < pageEntries; i++) { - pageTable[i] = kernelPageDirectory[i]; - } /* end for */ - - /* Also Set Up Page Directory To Be The The First Page In 0xE0400000 */ - pageTable = (uInt32 *) (kernelPageDirectory[0] & 0xFFFFF000); - pageTable[256] = (uInt32) ((uInt32) (kernelPageDirectory) | KERNEL_PAGE_DEFAULT); - - /* Now Lets Turn On Paging With This Initial Page Table */ - asm volatile ( - "movl %0,%%eax \n" - "movl %%eax,%%cr3 \n" - "movl %%cr0,%%eax \n" - "orl $0x80010000,%%eax \n" /* Turn on memory - * protection */ - "movl %%eax,%%cr0 \n" - : - : "d" ((uInt32 *) (kernelPageDirectory)) - ); - - /* Remap The Memory List */ - for (i = 0x101000; i <= (0x101000 + (numPages * sizeof(mMap))); i += 0x1000) { - if ((vmm_remapPage(i, (vmmMemoryMapAddr + (i - 0x101000)), KERNEL_PAGE_DEFAULT)) == 0x0) - kpanic("vmmRemapPage failed\n"); - } - /* Set New Address For Memory Map Since Its Relocation */ - vmmMemoryMap = (mMap *) vmmMemoryMapAddr; - - /* Print information on paging */ - kprintf("paging0 - Address: [0x%X], PagingISR Address: [0x%X]\n", kernelPageDirectory, &_vmm_pageFault); - - /* Return so we know everything went well */ - return (0x0); -} /* END */ + /* Return so we know everything went well */ + return (0x0); + } /* END */ /***************************************************************************************** Function: int vmmRemapPage(Physical Source,Virtual Destination) - + Description: This Function Will Remap A Physical Page Into Virtual Space - + Notes: 07/29/02 - Rewrote This To Work With Our New Paging System 07/30/02 - Changed Address Of Page Tables And Page Directory 07/28/04 - If perms == 0x0 set to PAGE_DEFAULT *****************************************************************************************/ -int -vmm_remapPage(uInt32 source, uInt32 dest, uInt16 perms) +int vmm_remapPage(uInt32 source,uInt32 dest,uInt16 perms) { - uInt16 destPageDirectoryIndex = 0x0, destPageTableIndex = 0x0; - uInt32 *pageDir = 0x0, *pageTable = 0x0; - short i = 0x0; + uInt16 destPageDirectoryIndex = 0x0, destPageTableIndex = 0x0; + uInt32 *pageDir = 0x0, *pageTable = 0x0; + short i = 0x0; - spinLock(&rmpSpinLock); + spinLock(&rmpSpinLock); + + if (perms == 0x0) + perms = KERNEL_PAGE_DEFAULT; - if (perms == 0x0) - perms = KERNEL_PAGE_DEFAULT; + /* + * Set Pointer pageDirectory To Point To The Virtual Mapping Of The Page + * Directory + */ + pageDir = (uInt32 *) parentPageDirAddr; + /* Check To See If Page Table Exists */ + if (dest == 0x0) + return(0x0); + + /* Get Index Into The Page Directory */ + destPageDirectoryIndex = (dest / 0x400000); + + if ((pageDir[destPageDirectoryIndex] & PAGE_PRESENT) != PAGE_PRESENT) { + /* If Page Table Is Non Existant Then Set It Up */ + /* UBU Why does the page table need to be user writable? */ + pageDir[destPageDirectoryIndex] = (uInt32) vmmFindFreePage(_current->id) | PAGE_DEFAULT; + + /* Also Add It To Virtual Space So We Can Make Changes Later */ + pageTable = (uInt32 *) (tablesBaseAddress + 0x2FF000); + pageTable[destPageDirectoryIndex] = pageDir[destPageDirectoryIndex]; + /* Reload Page Directory */ + asm volatile( + "push %eax \n" + "mov %cr3,%eax \n" + "mov %eax,%cr3 \n" + "pop %eax \n" + ); + pageTable = (uInt32 *) (tablesBaseAddress + (0x1000 * destPageDirectoryIndex)); + for (i = 0x0;i < pageEntries;i++) + pageTable[i] = 0x0; + } + /* Set Address To Page Table */ + pageTable = (uInt32 *) (tablesBaseAddress + (0x1000 * destPageDirectoryIndex)); - /* - * Set Pointer pageDirectory To Point To The Virtual Mapping Of The - * Page Directory - */ - pageDir = (uInt32 *) parentPageDirAddr; - /* Check To See If Page Table Exists */ - if (dest == 0x0) - return (0x0); - - /* Get Index Into The Page Directory */ - destPageDirectoryIndex = (dest / 0x400000); - - if ((pageDir[destPageDirectoryIndex] & PAGE_PRESENT) != PAGE_PRESENT) { - /* If Page Table Is Non Existant Then Set It Up */ - /* UBU Why does the page table need to be user writable? */ - pageDir[destPageDirectoryIndex] = (uInt32) vmmFindFreePage(_current->id) | PAGE_DEFAULT; - - /* Also Add It To Virtual Space So We Can Make Changes Later */ - pageTable = (uInt32 *) (tablesBaseAddress + 0x2FF000); - pageTable[destPageDirectoryIndex] = pageDir[destPageDirectoryIndex]; - /* Reload Page Directory */ - asm volatile ( - "push %eax \n" - "mov %cr3,%eax \n" - "mov %eax,%cr3 \n" - "pop %eax \n" - ); - pageTable = (uInt32 *) (tablesBaseAddress + (0x1000 * destPageDirectoryIndex)); - for (i = 0x0; i < pageEntries; i++) - pageTable[i] = 0x0; - } - /* Set Address To Page Table */ - pageTable = (uInt32 *) (tablesBaseAddress + (0x1000 * destPageDirectoryIndex)); - - /* Get The Index To The Page Table */ - destPageTableIndex = ((dest - (destPageDirectoryIndex * 0x400000)) / 0x1000); - /* If The Page Is Mapped In Free It Before We Remap */ - if ((pageTable[destPageTableIndex] & PAGE_PRESENT) == PAGE_PRESENT) { - /* Clear The Page First For Security Reasons */ - freePage(((uInt32) pageTable[destPageTableIndex] & 0xFFFFF000)); - } - /* Set The Source Address In The Destination */ - pageTable[destPageTableIndex] = (uInt32) (source | perms); - //kprintf("[0x%X]", pageTable[destPageTableIndex]); - /* Reload The Page Table; */ - asm volatile ( - "push %eax \n" - "movl %cr3,%eax\n" - "movl %eax,%cr3\n" - "pop %eax \n" - ); - /* Return */ - spinUnlock(&rmpSpinLock); - return (source); + /* Get The Index To The Page Table */ + destPageTableIndex = ((dest - (destPageDirectoryIndex * 0x400000)) / 0x1000); + /* If The Page Is Mapped In Free It Before We Remap */ + if ((pageTable[destPageTableIndex] & PAGE_PRESENT) == PAGE_PRESENT) { + /* Clear The Page First For Security Reasons */ + freePage(((uInt32) pageTable[destPageTableIndex] & 0xFFFFF000)); + } + /* Set The Source Address In The Destination */ + pageTable[destPageTableIndex] = (uInt32) (source | perms); + //kprintf("[0x%X]",pageTable[destPageTableIndex]); + /* Reload The Page Table; */ + asm volatile( + "push %eax \n" + "movl %cr3,%eax\n" + "movl %eax,%cr3\n" + "pop %eax \n" + ); + /* Return */ + spinUnlock(&rmpSpinLock); + return (source); } /************************************************************************ @@ -239,64 +236,52 @@ void * vmmGetFreeKernelPage(pidType pid, uInt16 count) { - int x = 0, y = 0, c = 0; - uInt32 *pageTableSrc = 0x0; + int x = 0, y = 0, c = 0; + uInt32 *pageTableSrc = 0x0; - spinLock(&fkpSpinLock); - /* Lets Search For A Free Page */ - for (x = 768; x < 1024; x++) { - /* Set Page Table Address */ - pageTableSrc = (uInt32 *) (tablesBaseAddress + (4096 * x)); - for (y = 0; y < 1024; y++) { - /* - * Loop Through The Page Table Find An UnAllocated - * Page - */ - if ((uInt32) pageTableSrc[y] == (uInt32) 0x0) { - if (count > 1) { - for (c = 0; c < count; c++) { - if (y + c < 1024) { - if ((uInt32) pageTableSrc[y + c] != (uInt32) 0x0) { - c = -1; - break; - } - } - } - if (c != -1) { - for (c = 0; c < count; c++) { - if ((vmm_remapPage((uInt32) vmmFindFreePage(pid), ((x * (1024 * 4096)) + ((y + c) * 4096)), KERNEL_PAGE_DEFAULT)) == 0x0) - kpanic("vmmRemapPage failed: gfkp-1\n"); - vmmClearVirtualPage((uInt32) ((x * (1024 * 4096)) + ((y + c) * 4096))); - } - spinUnlock(&fkpSpinLock); - return ((void *)((x * (1024 * 4096)) + (y * 4096))); - } - } else { - /* - * Map A Physical Page To The Virtual - * Page - */ + spinLock(&fkpSpinLock); + /* Lets Search For A Free Page */ + for (x = 768; x < 1024; x++) { + /* Set Page Table Address */ + pageTableSrc = (uInt32 *) (tablesBaseAddress + (4096 * x)); + for (y = 0; y < 1024; y++) { + /* Loop Through The Page Table Find An UnAllocated Page */ + if ((uInt32) pageTableSrc[y] == (uInt32) 0x0) { + if (count > 1) { + for (c = 0; c < count; c++) { + if (y + c < 1024) { + if ((uInt32) pageTableSrc[y + c] != (uInt32) 0x0) { + c = -1; + break; + } + } + } + if (c != -1) { + for (c = 0; c < count; c++) { + if ((vmm_remapPage((uInt32) vmmFindFreePage(pid), ((x * (1024 * 4096)) + ((y + c) * 4096)),KERNEL_PAGE_DEFAULT)) == 0x0) + kpanic("vmmRemapPage failed: gfkp-1\n"); + vmmClearVirtualPage((uInt32) ((x * (1024 * 4096)) + ((y + c) * 4096))); + } + spinUnlock(&fkpSpinLock); + return ((void *)((x * (1024 * 4096)) + (y * 4096))); + } + } else { + /* Map A Physical Page To The Virtual Page */ - if ((vmm_remapPage((uInt32) vmmFindFreePage(pid), ((x * (1024 * 4096)) + (y * 4096)), KERNEL_PAGE_DEFAULT)) == 0x0) - kpanic("vmmRemapPage failed: gfkp-2\n"); - /* - * Clear This Page So No Garbage Is - * There - */ - vmmClearVirtualPage((uInt32) ((x * (1024 * 4096)) + (y * 4096))); - /* - * Return The Address Of The Newly - * Allocate Page - */ - spinUnlock(&fkpSpinLock); - return ((void *)((x * (1024 * 4096)) + (y * 4096))); - } - } - } + if ((vmm_remapPage((uInt32) vmmFindFreePage(pid), ((x * (1024 * 4096)) + (y * 4096)),KERNEL_PAGE_DEFAULT)) == 0x0) + kpanic("vmmRemapPage failed: gfkp-2\n"); + /* Clear This Page So No Garbage Is There */ + vmmClearVirtualPage((uInt32) ((x * (1024 * 4096)) + (y * 4096))); + /* Return The Address Of The Newly Allocate Page */ + spinUnlock(&fkpSpinLock); + return ((void *)((x * (1024 * 4096)) + (y * 4096))); } - /* If No Free Page Was Found Return NULL */ - spinUnlock(&fkpSpinLock); - return (0x0); + } + } + } + /* If No Free Page Was Found Return NULL */ + spinUnlock(&fkpSpinLock); + return (0x0); } @@ -309,149 +294,135 @@ Notes: ************************************************************************/ -int +int vmmClearVirtualPage(uInt32 pageAddr) { - uInt32 *src = 0x0; - int counter = 0x0; + uInt32 *src = 0x0; + int counter = 0x0; - /* Set Source Pointer To Virtual Page Address */ - src = (uInt32 *) pageAddr; + /* Set Source Pointer To Virtual Page Address */ + src = (uInt32 *) pageAddr; - /* Clear Out The Page */ - for (counter = 0x0; counter < pageEntries; counter++) - (uInt32) src[counter] = (uInt32) 0x0; + /* Clear Out The Page */ + for (counter = 0x0; counter < pageEntries; counter++) { + (uInt32) src[counter] = (uInt32) 0x0; + } - return (0x0); + /* Return */ + return (0x0); } -void * -vmmMapFromTask(pidType pid, void *ptr, uInt32 size) -{ - kTask_t *child = 0x0; - uInt32 i = 0x0, x = 0x0, y = 0x0, count = ((size + 4095) / 0x1000), - c = 0x0; - uInt16 dI = 0x0, tI = 0x0; - uInt32 baseAddr = 0x0, offset = 0x0; - uInt32 *childPageDir = (uInt32 *) 0x5A00000; - uInt32 *childPageTable = 0x0; - uInt32 *pageTableSrc = 0x0; - offset = (uInt32) ptr & 0xFFF; - baseAddr = (uInt32) ptr & 0xFFFFF000; - child = schedFindTask(pid); - //Calculate The Page Table Index And Page Directory Index - dI = (baseAddr / (1024 * 4096)); - tI = ((baseAddr - (dI * (1024 * 4096))) / 4096); - vmm_remapPage(child->tss.cr3, 0x5A00000, KERNEL_PAGE_DEFAULT); - for (i = 0; i < 0x1000; i++) { - vmm_remapPage(childPageDir[i], 0x5A01000 + (i * 0x1000), KERNEL_PAGE_DEFAULT); - } - for (x = (_current->oInfo.vmStart / (1024 * 4096)); x < 1024; x++) { - pageTableSrc = (uInt32 *) (tablesBaseAddress + (4096 * x)); - for (y = 0; y < 1024; y++) { - //Loop Through The Page Table Find An UnAllocated Page - if ((uInt32) pageTableSrc[y] == (uInt32) 0x0) { - if (count > 1) { - for (c = 0; ((c < count) && (y + c < 1024)); c++) { - if ((uInt32) pageTableSrc[y + c] != (uInt32) 0x0) { - c = -1; - break; - } - } - if (c != -1) { - for (c = 0; c < count; c++) { - if ((tI + c) >= 0x1000) { - dI++; - tI = 0 - c; - } - childPageTable = (uInt32 *) (0x5A01000 + (0x1000 * dI)); - vmm_remapPage(childPageTable[tI + c], ((x * (1024 * 4096)) + ((y + c) * 4096)), KERNEL_PAGE_DEFAULT); - } - vmmUnmapPage(0x5A00000, 1); - for (i = 0; i < 0x1000; i++) { - vmmUnmapPage((0x5A01000 + (i * 0x1000)), 1); - } - return ((void *)((x * (1024 * 4096)) + (y * 4096) + offset)); - } - } else { - //Map A Physical Page To The Virtual Page - childPageTable = (uInt32 *) (0x5A01000 + (0x1000 * dI)); - vmm_remapPage(childPageTable[tI], ((x * (1024 * 4096)) + (y * 4096)), KERNEL_PAGE_DEFAULT); - //Return The Address Of The Mapped In Memory - vmmUnmapPage(0x5A00000, 1); - for (i = 0; i < 0x1000; i++) { - vmmUnmapPage((0x5A01000 + (i * 0x1000)), 1); - } - return ((void *)((x * (1024 * 4096)) + (y * 4096) + offset)); - } - } - } - } - return (0x0); +void *vmmMapFromTask(pidType pid,void *ptr,uInt32 size) { + kTask_t *child = 0x0; + uInt32 i = 0x0,x = 0x0,y = 0x0,count = ((size+4095)/0x1000),c = 0x0; + uInt16 dI = 0x0,tI = 0x0; + uInt32 baseAddr = 0x0,offset = 0x0; + uInt32 *childPageDir = (uInt32 *)0x5A00000; + uInt32 *childPageTable = 0x0; + uInt32 *pageTableSrc = 0x0; + offset = (uInt32)ptr & 0xFFF; + baseAddr = (uInt32)ptr & 0xFFFFF000; + child = schedFindTask(pid); + //Calculate The Page Table Index And Page Directory Index + dI = (baseAddr/(1024*4096)); + tI = ((baseAddr-(dI*(1024*4096)))/4096); + vmm_remapPage(child->tss.cr3,0x5A00000,KERNEL_PAGE_DEFAULT); + for (i=0;i<0x1000;i++) { + vmm_remapPage(childPageDir[i],0x5A01000 + (i * 0x1000),KERNEL_PAGE_DEFAULT); + } + for (x=(_current->oInfo.vmStart/(1024*4096));x<1024;x++) { + pageTableSrc = (uInt32 *)(tablesBaseAddress + (4096*x)); + for (y=0;y<1024;y++) { + //Loop Through The Page Table Find An UnAllocated Page + if ((uInt32)pageTableSrc[y] == (uInt32)0x0) { + if (count > 1) { + for (c=0;((c= 0x1000) { + dI++; + tI = 0-c; + } + childPageTable = (uInt32 *)(0x5A01000 + (0x1000 * dI)); + vmm_remapPage(childPageTable[tI+c],((x*(1024*4096))+((y+c)*4096)),KERNEL_PAGE_DEFAULT); + } + vmmUnmapPage(0x5A00000,1); + for (i=0;i<0x1000;i++) { + vmmUnmapPage((0x5A01000 + (i*0x1000)),1); + } + return((void *)((x*(1024*4096))+(y*4096)+offset)); + } + } + else { + //Map A Physical Page To The Virtual Page + childPageTable = (uInt32 *)(0x5A01000 + (0x1000 * dI)); + vmm_remapPage(childPageTable[tI],((x*(1024*4096))+(y*4096)),KERNEL_PAGE_DEFAULT); + //Return The Address Of The Mapped In Memory + vmmUnmapPage(0x5A00000,1); + for (i=0;i<0x1000;i++) { + vmmUnmapPage((0x5A01000 + (i*0x1000)),1); + } + return((void *)((x*(1024*4096))+(y*4096)+offset)); + } + } + } + } + return(0x0); + } + +void *vmm_getFreeMallocPage(uInt16 count) { + uInt16 x = 0x0, y = 0x0; + int c = 0x0; + uInt32 *pageTableSrc = 0x0; + + spinLock(&fkpSpinLock); + /* Lets Search For A Free Page */ + for (x = 960; x < 1024; x++) { + /* Set Page Table Address */ + pageTableSrc = (uInt32 *) (tablesBaseAddress + (0x1000 * x)); + for (y = 0; y < 1024; y++) { + /* Loop Through The Page Table Find An UnAllocated Page */ + if ((uInt32) pageTableSrc[y] == (uInt32) 0x0) { + if (count > 1) { + for (c = 0; c < count; c++) { + if (y + c < 1024) { + if ((uInt32) pageTableSrc[y + c] != (uInt32) 0x0) { + c = -1; + break; + } + } + } + if (c != -1) { + for (c = 0; c < count; c++) { + vmm_remapPage((uInt32) vmmFindFreePage(sysID), ((x * 0x400000) + ((y + c) * 0x1000)),KERNEL_PAGE_DEFAULT); + vmmClearVirtualPage((uInt32) ((x * 0x400000) + ((y + c) * 0x1000))); + } + spinUnlock(&fkpSpinLock); + return ((void *)((x * 0x400000) + (y * 0x1000))); + } + } else { + /* Map A Physical Page To The Virtual Page */ + vmm_remapPage((uInt32) vmmFindFreePage(sysID), ((x * 0x400000) + (y * 0x1000)),KERNEL_PAGE_DEFAULT); + /* Clear This Page So No Garbage Is There */ + vmmClearVirtualPage((uInt32) ((x * 0x400000) + (y * 0x1000))); + /* Return The Address Of The Newly Allocate Page */ + spinUnlock(&fkpSpinLock); + return ((void *)((x * 0x400000) + (y * 0x1000))); + } + } + } + } + /* If No Free Page Was Found Return NULL */ + spinUnlock(&fkpSpinLock); + return (0x0); } - -void * -vmm_getFreeMallocPage(uInt16 count) -{ - uInt16 x = 0x0, y = 0x0; - int c = 0x0; - uInt32 *pageTableSrc = 0x0; - - spinLock(&fkpSpinLock); - /* Lets Search For A Free Page */ - for (x = 960; x < 1024; x++) { - /* Set Page Table Address */ - pageTableSrc = (uInt32 *) (tablesBaseAddress + (0x1000 * x)); - for (y = 0; y < 1024; y++) { - /* - * Loop Through The Page Table Find An UnAllocated - * Page - */ - if ((uInt32) pageTableSrc[y] == (uInt32) 0x0) { - if (count > 1) { - for (c = 0; c < count; c++) { - if (y + c < 1024) { - if ((uInt32) pageTableSrc[y + c] != (uInt32) 0x0) { - c = -1; - break; - } - } - } - if (c != -1) { - for (c = 0; c < count; c++) { - vmm_remapPage((uInt32) vmmFindFreePage(sysID), ((x * 0x400000) + ((y + c) * 0x1000)), KERNEL_PAGE_DEFAULT); - vmmClearVirtualPage((uInt32) ((x * 0x400000) + ((y + c) * 0x1000))); - } - spinUnlock(&fkpSpinLock); - return ((void *)((x * 0x400000) + (y * 0x1000))); - } - } else { - /* - * Map A Physical Page To The Virtual - * Page - */ - vmm_remapPage((uInt32) vmmFindFreePage(sysID), ((x * 0x400000) + (y * 0x1000)), KERNEL_PAGE_DEFAULT); - /* - * Clear This Page So No Garbage Is - * There - */ - vmmClearVirtualPage((uInt32) ((x * 0x400000) + (y * 0x1000))); - /* - * Return The Address Of The Newly - * Allocate Page - */ - spinUnlock(&fkpSpinLock); - return ((void *)((x * 0x400000) + (y * 0x1000))); - } - } - } - } - /* If No Free Page Was Found Return NULL */ - spinUnlock(&fkpSpinLock); - return (0x0); -} - + /*** $Log$ Revision 1.18 2004/09/07 21:54:38 reddawg diff --git a/src/sys/vmm/setpageattributes.c b/src/sys/vmm/setpageattributes.c index 018800d..a1e3d3f 100644 --- a/src/sys/vmm/setpageattributes.c +++ b/src/sys/vmm/setpageattributes.c @@ -35,11 +35,8 @@ Function: void vmmSetPageAttributes(uInt32 pageAddr,int attributes; Description: This Function Will Set The Page Attributes Such As A Read Only Page, Stack Page, COW Page, ETC. - - READ - WRITE - EXECUTE Notes: + ************************************************************************/ int vmm_setPageAttributes(uInt32 memAddr,uInt16 attributes) { uInt16 directoryIndex = 0x0, tableIndex = 0x0; diff --git a/src/sys/vmm/vmminit.c b/src/sys/vmm/vmminit.c index 2f22090..adc3105 100644 --- a/src/sys/vmm/vmminit.c +++ b/src/sys/vmm/vmminit.c @@ -37,21 +37,18 @@ Notes: *****************************************************************************************/ -int -vmm_init() -{ - if (vmmMemMapInit() != 0x0) - return (0x1); - if (vmm_pagingInit() != 0x0) - return (0x1); - return (0x0); -} +int vmm_init() { + if (vmmMemMapInit() != 0x0) { + return (0x1); + } + if (vmm_pagingInit() != 0x0) { + return (0x1); + } + return (0x0); + } /*** $Log$ - Revision 1.5 2005/08/06 11:43:45 fsdfs - code clean up - Revision 1.4 2004/07/28 15:05:43 reddawg Major: Pages now have strict security enforcement. @@ -72,3 +69,4 @@ END ***/ +