Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

hypermap.c File Reference

#include "mi.h"

Go to the source code of this file.

Functions

PVOID MiMapPageInHyperSpace (IN ULONG PageFrameIndex, IN PKIRQL OldIrql)
PVOID MiMapImageHeaderInHyperSpace (IN ULONG PageFrameIndex)
VOID MiUnmapImageHeaderInHyperSpace (VOID)
PVOID MiMapPageToZeroInHyperSpace (IN ULONG PageFrameIndex)


Function Documentation

PVOID MiMapImageHeaderInHyperSpace IN ULONG  PageFrameIndex  ) 
 

Definition at line 141 of file i386/hypermap.c.

References ASSERT, DbgPrint, Executive, FALSE, IMAGE_MAPPING_PTE, KeBugCheck(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KernelMode, KeWaitForSingleObject(), LOCK_PFN, MI_WRITE_VALID_PTE, MiGetPteAddress, MiGetVirtualAddressMappedByPte, MmImageMappingPteEvent, MmOneSecond, MmWorkingSetList, NULL, _MMPTE::u, UNLOCK_PFN, UNLOCK_PFN_AND_THEN_WAIT, ValidPtePte, and _MMWSL::WaitingForImageMapping.

00147 : 00148 00149 This procedure maps the specified physical page into the 00150 PTE within hyper space reserved explicitly for image page 00151 header mapping. By reserving an explicit PTE for mapping 00152 the PTE, page faults can occur while the PTE is mapped within 00153 hyperspace and no other hyperspace maps will affect this PTE. 00154 00155 Note that if another thread attempts to map an image at the 00156 same time, it will be forced into a wait state until the 00157 header is "unmapped". 00158 00159 Arguments: 00160 00161 PageFrameIndex - Supplies the physical page number to map. 00162 00163 Return Value: 00164 00165 Returns the virtual address where the specified physical page was 00166 mapped. 00167 00168 Environment: 00169 00170 Kernel mode. 00171 00172 --*/ 00173 00174 { 00175 MMPTE TempPte; 00176 PMMPTE PointerPte; 00177 KIRQL OldIrql; 00178 00179 #if DBG 00180 if (PageFrameIndex == 0) { 00181 DbgPrint("attempt to map physical page 0 in hyper space\n"); 00182 KeBugCheck (MEMORY_MANAGEMENT); 00183 } 00184 #endif //DBG 00185 00186 PointerPte = MiGetPteAddress (IMAGE_MAPPING_PTE); 00187 00188 LOCK_PFN (OldIrql); 00189 00190 while (PointerPte->u.Long) { 00191 00192 // 00193 // If there is no event specified, set one up. 00194 // 00195 00196 if (MmWorkingSetList->WaitingForImageMapping == (PKEVENT)NULL) { 00197 00198 // 00199 // Set the global event into the field and wait for it. 00200 // 00201 00202 MmWorkingSetList->WaitingForImageMapping = &MmImageMappingPteEvent; 00203 } 00204 00205 // 00206 // Release the PFN lock and wait on the event in an 00207 // atomic operation. 00208 // 00209 00210 KeEnterCriticalRegion(); 00211 UNLOCK_PFN_AND_THEN_WAIT(OldIrql); 00212 00213 KeWaitForSingleObject(MmWorkingSetList->WaitingForImageMapping, 00214 Executive, 00215 KernelMode, 00216 FALSE, 00217 &MmOneSecond); 00218 KeLeaveCriticalRegion(); 00219 00220 LOCK_PFN (OldIrql); 00221 } 00222 00223 ASSERT (PointerPte->u.Long == 0); 00224 00225 TempPte = ValidPtePte; 00226 TempPte.u.Hard.PageFrameNumber = PageFrameIndex; 00227 00228 MI_WRITE_VALID_PTE(PointerPte, TempPte); 00229 00230 UNLOCK_PFN (OldIrql); 00231 00232 return (PVOID)MiGetVirtualAddressMappedByPte (PointerPte); 00233 }

PVOID MiMapPageInHyperSpace IN ULONG  PageFrameIndex,
IN PKIRQL  OldIrql
 

Definition at line 26 of file i386/hypermap.c.

References ASSERT, DbgPrint, FALSE, KeBugCheck(), KeFlushEntireTb(), LOCK_HYPERSPACE, MI_GET_PAGE_FRAME_FROM_PTE, MI_MAKING_MULTIPLE_PTES_INVALID, MiGetVirtualAddressMappedByPte, MM_KSEG0_BASE, MmFirstReservedMappingPte, MmKseg2Frame, NUMBER_OF_MAPPING_PTES, PAGE_SHIFT, TRUE, _MMPTE::u, and ValidPtePte.

00033 : 00034 00035 This procedure maps the specified physical page into hyper space 00036 and returns the virtual address which maps the page. 00037 00038 ************************************ 00039 * * 00040 * Returns with a spin lock held!!! * 00041 * * 00042 ************************************ 00043 00044 Arguments: 00045 00046 PageFrameIndex - Supplies the physical page number to map. 00047 00048 00049 Return Value: 00050 00051 Returns the address where the requested page was mapped. 00052 00053 RETURNS WITH THE HYPERSPACE SPIN LOCK HELD!!!! 00054 00055 The routine MiUnmapHyperSpaceMap MUST be called to release the lock!!!! 00056 00057 Environment: 00058 00059 Kernel mode. 00060 00061 --*/ 00062 00063 { 00064 00065 MMPTE TempPte; 00066 PMMPTE PointerPte; 00067 ULONG offset; 00068 00069 #if DBG 00070 if (PageFrameIndex == 0) { 00071 DbgPrint("attempt to map physical page 0 in hyper space\n"); 00072 KeBugCheck (MEMORY_MANAGEMENT); 00073 } 00074 #endif //DBG 00075 00076 LOCK_HYPERSPACE(OldIrql); 00077 00078 if( PageFrameIndex < MmKseg2Frame){ 00079 return (PVOID)(MM_KSEG0_BASE + (PageFrameIndex << PAGE_SHIFT)); 00080 } 00081 00082 PointerPte = MmFirstReservedMappingPte; 00083 if (PointerPte->u.Hard.Valid == 1) { 00084 00085 // 00086 // All the reserved PTEs have been used, make 00087 // them all invalid. 00088 // 00089 00090 MI_MAKING_MULTIPLE_PTES_INVALID (FALSE); 00091 00092 RtlZeroMemory (MmFirstReservedMappingPte, 00093 (NUMBER_OF_MAPPING_PTES + 1) * sizeof(MMPTE)); 00094 00095 // 00096 // Use the page frame number field of the first PTE as an 00097 // offset into the available mapping PTEs. 00098 // 00099 00100 PointerPte->u.Hard.PageFrameNumber = NUMBER_OF_MAPPING_PTES; 00101 00102 // 00103 // Flush entire TB only on this processor. 00104 // 00105 00106 KeFlushEntireTb (TRUE, FALSE); 00107 } 00108 00109 // 00110 // Get offset to first free PTE. 00111 // 00112 00113 offset = MI_GET_PAGE_FRAME_FROM_PTE(PointerPte); 00114 00115 // 00116 // Change offset for next time through. 00117 // 00118 00119 PointerPte->u.Hard.PageFrameNumber = offset - 1; 00120 00121 // 00122 // Point to free entry and make it valid. 00123 // 00124 00125 PointerPte += offset; 00126 ASSERT (PointerPte->u.Hard.Valid == 0); 00127 00128 00129 TempPte = ValidPtePte; 00130 TempPte.u.Hard.PageFrameNumber = PageFrameIndex; 00131 *PointerPte = TempPte; 00132 00133 // 00134 // Return the VA that maps the page. 00135 // 00136 00137 return MiGetVirtualAddressMappedByPte (PointerPte); 00138 }

PVOID MiMapPageToZeroInHyperSpace IN ULONG  PageFrameIndex  ) 
 

Definition at line 305 of file i386/hypermap.c.

References DbgPrint, FALSE, KeBugCheck(), KeFlushSingleTb(), MiGetPteAddress, MiGetVirtualAddressMappedByPte, MM_KSEG0_BASE, MM_PFN_LOCK_ASSERT, MmKseg2Frame, PAGE_SHIFT, TRUE, _MMPTE::u, ValidPtePte, and ZEROING_PAGE_PTE.

00311 : 00312 00313 This procedure maps the specified physical page into hyper space 00314 and returns the virtual address which maps the page. 00315 00316 NOTE: it maps it into the same location reserved for zeroing operations. 00317 This is only to be used by the zeroing page thread. 00318 00319 Arguments: 00320 00321 PageFrameIndex - Supplies the physical page number to map. 00322 00323 Return Value: 00324 00325 Returns the virtual address where the specified physical page was 00326 mapped. 00327 00328 Environment: 00329 00330 Must be holding the PFN lock. 00331 00332 --*/ 00333 00334 { 00335 MMPTE TempPte; 00336 PMMPTE PointerPte; 00337 PVOID MappedAddress; 00338 00339 #if DBG 00340 if (PageFrameIndex == 0) { 00341 DbgPrint("attempt to map physical page 0 in hyper space\n"); 00342 KeBugCheck (MEMORY_MANAGEMENT); 00343 } 00344 #endif 00345 00346 MM_PFN_LOCK_ASSERT(); 00347 00348 if (PageFrameIndex < MmKseg2Frame) { 00349 return (PVOID)(MM_KSEG0_BASE + (PageFrameIndex << PAGE_SHIFT)); 00350 } 00351 00352 PointerPte = MiGetPteAddress (ZEROING_PAGE_PTE); 00353 00354 MappedAddress = MiGetVirtualAddressMappedByPte (PointerPte); 00355 00356 TempPte.u.Long = 0; 00357 00358 KeFlushSingleTb (MappedAddress, 00359 TRUE, 00360 FALSE, 00361 (PHARDWARE_PTE)PointerPte, 00362 TempPte.u.Flush); 00363 00364 TempPte = ValidPtePte; 00365 TempPte.u.Hard.PageFrameNumber = PageFrameIndex; 00366 00367 *PointerPte = TempPte; 00368 00369 return MappedAddress; 00370 } }

VOID MiUnmapImageHeaderInHyperSpace VOID   ) 
 

Definition at line 236 of file i386/hypermap.c.

References ASSERT, Event(), FALSE, IMAGE_MAPPING_PTE, KeFlushSingleTb(), KePulseEvent(), LOCK_PFN, MiGetPteAddress, MmWorkingSetList, NULL, TRUE, _MMPTE::u, UNLOCK_PFN, and _MMWSL::WaitingForImageMapping.

00242 : 00243 00244 This procedure unmaps the PTE reserved for mapping the image 00245 header, flushes the TB, and, if the WaitingForImageMapping field 00246 is not NULL, sets the specified event. 00247 00248 Arguments: 00249 00250 None. 00251 00252 Return Value: 00253 00254 None. 00255 00256 Environment: 00257 00258 Kernel mode. 00259 00260 --*/ 00261 00262 { 00263 MMPTE TempPte; 00264 PMMPTE PointerPte; 00265 KIRQL OldIrql; 00266 PKEVENT Event; 00267 00268 PointerPte = MiGetPteAddress (IMAGE_MAPPING_PTE); 00269 00270 TempPte.u.Long = 0; 00271 00272 LOCK_PFN (OldIrql); 00273 00274 // 00275 // Capture the current state of the event field and clear it out. 00276 // 00277 00278 Event = MmWorkingSetList->WaitingForImageMapping; 00279 00280 MmWorkingSetList->WaitingForImageMapping = (PKEVENT)NULL; 00281 00282 ASSERT (PointerPte->u.Long != 0); 00283 00284 KeFlushSingleTb (IMAGE_MAPPING_PTE, 00285 TRUE, 00286 FALSE, 00287 (PHARDWARE_PTE)PointerPte, 00288 TempPte.u.Flush); 00289 00290 UNLOCK_PFN (OldIrql); 00291 00292 if (Event != (PKEVENT)NULL) { 00293 00294 // 00295 // If there was an event specified, set the event. 00296 // 00297 00298 KePulseEvent (Event, 0, FALSE); 00299 } 00300 00301 return; 00302 }


Generated on Sat May 15 19:44:06 2004 for test by doxygen 1.3.7