00001 /***************************************************************************************** 00002 Copyright (c) 2002 The UbixOS Project 00003 All rights reserved. 00004 00005 Redistribution and use in source and binary forms, with or without modification, are 00006 permitted provided that the following conditions are met: 00007 00008 Redistributions of source code must retain the above copyright notice, this list of 00009 conditions, the following disclaimer and the list of authors. Redistributions in binary 00010 form must reproduce the above copyright notice, this list of conditions, the following 00011 disclaimer and the list of authors in the documentation and/or other materials provided 00012 with the distribution. Neither the name of the UbixOS Project nor the names of its 00013 contributors may be used to endorse or promote products derived from this software 00014 without specific prior written permission. 00015 00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 00017 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00018 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 00019 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00020 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00021 OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00022 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 00023 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00024 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00025 00026 $Id: pagefault_8c-source.html 88 2016-01-12 00:11:29Z reddawg $ 00027 00028 *****************************************************************************************/ 00029 00030 #include <vmm/vmm.h> 00031 #include <ubixos/sched.h> 00032 #include <ubixos/kpanic.h> 00033 #include <ubixos/spinlock.h> 00034 #include <lib/kprintf.h> 00035 00036 static spinLock_t pageFaultSpinLock = SPIN_LOCK_INITIALIZER; 00037 00038 /***************************************************************************************** 00039 00040 Function: void vmm_pageFault(uInt32 memAddr,uInt32 eip,uInt32 esp); 00041 Description: This is the page fault handler, it will handle COW and trap all other 00042 exceptions and segfault the thread. 00043 00044 Notes: 00045 00046 07/30/02 - Fixed COW However I Need To Think Of A Way To Impliment 00047 A Paging System Also Start To Add Security Levels 00048 00049 07/27/04 - Added spin locking to ensure that we are thread safe. I know that spining a 00050 cpu is a waste of resources but for now it prevents errors. 00051 00052 *****************************************************************************************/ 00053 void vmm_pageFault(uInt32 memAddr,uInt32 eip,uInt32 esp) { 00054 uInt32 i = 0x0, pageTableIndex = 0x0,pageDirectoryIndex = 0x0; 00055 uInt32 *pageDir = 0x0,*pageTable = 0x0; 00056 uInt32 *src = 0x0,*dst = 0x0; 00057 00058 /* Try to aquire lock otherwise spin till we do */ 00059 spinLock(&pageFaultSpinLock); 00060 00061 /* Set page dir pointer to the address of the visable page directory */ 00062 pageDir = (uInt32 *)parentPageDirAddr; 00063 00064 /* UBU - This is a temp panic for 0x0 read write later on I will handle this differently */ 00065 if (memAddr == 0x0) { 00066 kprintf("Segfault At Address: [0x%X][0x%X][%i][0x%X]\n",memAddr,esp,_current->id,eip); 00067 kpanic("Error We Wrote To 0x0\n"); 00068 } 00069 00070 /* Calculate The Page Directory Index */ 00071 pageDirectoryIndex = (memAddr >> 22); 00072 00073 /* Calculate The Page Table Index */ 00074 pageTableIndex = ((memAddr >> 12) & 0x3FF); 00075 00076 /* UBU - This is a temporary routine for handling access to a page of a non existant page table */ 00077 if (pageDir[pageDirectoryIndex] == 0x0) { 00078 kprintf("Segfault At Address: [0x%X][0x%X][%i][0x%X], Not A Valid Page Table\n",memAddr,esp,_current->id,eip); 00079 spinUnlock(&pageFaultSpinLock); 00080 endTask(_current->id); 00081 } 00082 else { 00083 /* Set pageTable To Point To Virtual Address Of Page Table */ 00084 pageTable = (uInt32 *)(tablesBaseAddress + (0x1000 * pageDirectoryIndex)); 00085 00086 /* Test if this is a COW on page */ 00087 if (((uInt32)pageTable[pageTableIndex] & PAGE_COW) == PAGE_COW) { 00088 /* Set Src To Base Address Of Page To Copy */ 00089 src = (uInt32 *)(memAddr & 0xFFFFF000); 00090 /* Allocate A Free Page For Destination */ 00091 /* USE vmInfo */ 00092 dst = (uInt32 *) vmmGetFreeVirtualPage(_current->id,1,0x1); 00093 /* Copy Memory */ 00094 for (i=0;i<pageEntries;i++) { 00095 dst[i] = src[i]; 00096 } 00097 /* Adjust The COW Counter For Physical Page */ 00098 adjustCowCounter(((uInt32)pageTable[pageTableIndex] & 0xFFFFF000),-1); 00099 /* Remap In New Page */ 00100 pageTable[pageTableIndex] = (uInt32)(vmm_getPhysicalAddr((uInt32)dst)|(memAddr & 0xFFF)); 00101 /* Unlink From Memory Map Allocated Page */ 00102 vmmUnmapPage((uInt32)dst,1); 00103 } 00104 else if (pageTable[pageTableIndex] != 0x0) { 00105 kprintf("Security failed pagetable not user permission\n"); 00106 kprintf("pageTable: [0x%X:0x%X:0x%X:0x%X]\n",pageTable[pageTableIndex],pageTableIndex,pageDirectoryIndex,eip); 00107 kprintf("Segfault At Address: [0x%X][0x%X][%i][0x%X] Non Mapped\n",memAddr,esp,_current->id,eip); 00108 spinUnlock(&pageFaultSpinLock); 00109 endTask(_current->id); 00110 } 00111 else if (memAddr < (_current->td.vm_dsize + _current->td.vm_daddr)) { 00112 pageTable[pageTableIndex] = (uInt32)vmmFindFreePage(_current->id) | PAGE_DEFAULT; 00113 } 00114 else { 00115 spinUnlock(&pageFaultSpinLock); 00116 /* Need To Create A Routine For Attempting To Access Non Mapped Memory */ 00117 kprintf("Segfault At Address: [0x%X][0x%X][%i][0x%X] Non Mapped\n",memAddr,esp,_current->id,eip); 00118 kprintf("Out Of Stack Space: [0x%X]\n",memAddr & 0xFF0000); 00119 spinUnlock(&pageFaultSpinLock); 00120 endTask(_current->id); 00121 } 00122 } 00123 asm volatile( 00124 "movl %cr3,%eax\n" 00125 "movl %eax,%cr3\n" 00126 ); 00127 00128 /* Release the spin lock */ 00129 spinUnlock(&pageFaultSpinLock); 00130 return; 00131 } 00132 00133 /*** 00134 $Log: pagefault_8c-source.html,v $ 00134 Revision 1.7 2006/12/15 17:47:06 reddawg 00134 Updates 00134 00135 Revision 1.6 2006/12/05 14:10:21 reddawg 00136 Workign Distro 00137 00138 Revision 1.5 2006/12/01 05:12:35 reddawg 00139 We're almost there... :) 00140 00141 Revision 1.4 2006/11/21 13:25:49 reddawg 00142 A handful of changes ;) 00143 00144 Revision 1.3 2006/11/06 19:10:12 reddawg 00145 Lots Of Updates... Still having issues with brk(); 00146 00147 Revision 1.2 2006/10/31 20:44:19 reddawg 00148 Lots of changes 00149 00150 Revision 1.1.1.1 2006/06/01 12:46:13 reddawg 00151 ubix2 00152 00153 Revision 1.2 2005/10/12 00:13:38 reddawg 00154 Removed 00155 00156 Revision 1.1.1.1 2005/09/26 17:24:52 reddawg 00157 no message 00158 00159 Revision 1.14 2004/08/25 22:02:41 reddawg 00160 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 00161 00162 Revision 1.13 2004/08/24 05:24:37 reddawg 00163 TCA Is A BONER!!!! 00164 00165 Revision 1.12 2004/08/14 11:23:03 reddawg 00166 Changes 00167 00168 Revision 1.11 2004/07/28 15:05:43 reddawg 00169 Major: 00170 Pages now have strict security enforcement. 00171 Many null dereferences have been resolved. 00172 When apps loaded permissions set for pages rw and ro 00173 00174 Revision 1.10 2004/07/28 00:22:56 reddawg 00175 bah 00176 00177 Revision 1.9 2004/07/28 00:17:05 reddawg 00178 Major: 00179 Disconnected page 0x0 from the system... Unfortunately this broke many things 00180 all of which have been fixed. This was good because nothing deferences NULL 00181 any more. 00182 00183 Things affected: 00184 malloc,kmalloc,getfreepage,getfreevirtualpage,pagefault,fork,exec,ld,ld.so,exec,file 00185 00186 Revision 1.8 2004/07/27 07:09:38 reddawg 00187 Put in a test for 0x0 00188 00189 Revision 1.7 2004/07/26 19:15:49 reddawg 00190 test code, fixes and the like 00191 00192 Revision 1.6 2004/07/24 23:04:44 reddawg 00193 Changes... mark let me know if you fault at pid 185 when you type stress 00194 00195 Revision 1.5 2004/07/24 20:00:51 reddawg 00196 Lots of changes to the vmm subsystem.... Page faults have been adjust to now be blocking on a per thread basis not system wide. This has resulted in no more deadlocks.. also the addition of per thread locking has removed segfaults as a result of COW in which two tasks fault the same COW page and try to modify it. 00197 00198 Revision 1.4 2004/07/24 17:47:28 reddawg 00199 vmm_pageFault: deadlock resolved thanks to a propper solution suggested by geist 00200 00201 Revision 1.3 2004/07/19 02:05:26 reddawg 00202 vmmPageFault: had a potential memory leak here for one page it was still using sysID on certain COW scenarios 00203 00204 Revision 1.2 2004/06/10 22:23:56 reddawg 00205 Volatiles 00206 00207 Revision 1.1.1.1 2004/04/15 12:06:52 reddawg 00208 UbixOS v1.0 00209 00210 Revision 1.4 2004/04/13 16:36:34 reddawg 00211 Changed our copyright, it is all now under a BSD-Style license 00212 00213 END 00214 ***/