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

ldtsup.c File Reference

#include "ki.h"

Go to the source code of this file.

Functions

VOID KiLoadLdtr (VOID)
VOID KiFlushDescriptors (VOID)
VOID Ki386LoadTargetLdtr (IN PKIPI_CONTEXT SignalDone, IN PVOID Parameter1, IN PVOID Parameter2, IN PVOID Parameter3)
VOID Ki386FlushTargetDescriptors (IN PKIPI_CONTEXT SignalDone, IN PVOID Parameter1, IN PVOID Parameter2, IN PVOID Parameter3)
VOID Ke386SetLdtProcess (IN PKPROCESS Process, IN PLDT_ENTRY Ldt, IN ULONG Limit)
VOID Ke386SetDescriptorProcess (IN PKPROCESS Process, IN ULONG Offset, IN LDT_ENTRY LdtEntry)


Function Documentation

VOID Ke386SetDescriptorProcess IN PKPROCESS  Process,
IN ULONG  Offset,
IN LDT_ENTRY  LdtEntry
 

Definition at line 255 of file i386/ldtsup.c.

References KeGetCurrentPrcb, Ki386FlushTargetDescriptors(), KiIpiStallOnPacketTargets(), KiLockContextSwap, KiUnlockContextSwap, MmLockPagedPool(), MmUnlockPagedPool(), NULL, and Offset.

Referenced by NtSetLdtEntries(), and PspSetLdtInformation().

00262 : 00263 00264 The specified LdtEntry (which could be 0, not present, etc) will be 00265 edited into the specified Offset in the Ldt of the specified Process. 00266 This will be synchronzied accross all the processors executing the 00267 process. The edit will take affect on all processors before the call 00268 returns. 00269 00270 N.B. 00271 00272 Editing an Ldt descriptor requires stalling all processors active 00273 for the process, to prevent accidental loading of descriptors in 00274 an inconsistent state. 00275 00276 Arguments: 00277 00278 Process - Pointer to KPROCESS object describing the process for 00279 which the descriptor edit is to be performed. 00280 00281 Offset - Byte offset into the Ldt of the descriptor to edit. 00282 Must be 0 mod 8. 00283 00284 LdtEntry - Value to edit into the descriptor in hardware format. 00285 No checking is done on the validity of this item. 00286 00287 Return Value: 00288 00289 none. 00290 00291 --*/ 00292 00293 { 00294 00295 PLDT_ENTRY Ldt; 00296 KIRQL OldIrql; 00297 PKPRCB Prcb; 00298 KAFFINITY TargetProcessors; 00299 00300 // 00301 // Compute address of descriptor to edit. 00302 // 00303 00304 Ldt = 00305 (PLDT_ENTRY) 00306 ((Process->LdtDescriptor.HighWord.Bytes.BaseHi << 24) | 00307 ((Process->LdtDescriptor.HighWord.Bytes.BaseMid << 16) & 0xff0000) | 00308 (Process->LdtDescriptor.BaseLow & 0xffff)); 00309 Offset = Offset / 8; 00310 MmLockPagedPool(&Ldt[Offset], sizeof(LDT_ENTRY)); 00311 KiLockContextSwap(&OldIrql); 00312 00313 #ifdef NT_UP 00314 00315 // 00316 // Edit the Ldt. 00317 // 00318 00319 Ldt[Offset] = LdtEntry; 00320 00321 #else 00322 00323 Prcb = KeGetCurrentPrcb(); 00324 TargetProcessors = Process->ActiveProcessors & ~Prcb->SetMember; 00325 if (TargetProcessors != 0) { 00326 KiIpiSendSynchronousPacket( 00327 Prcb, 00328 TargetProcessors, 00329 Ki386FlushTargetDescriptors, 00330 (PVOID)&Prcb->ReverseStall, 00331 NULL, 00332 NULL); 00333 00334 KiIpiStallOnPacketTargets(TargetProcessors); 00335 } 00336 00337 // 00338 // All target processors have flushed the segment descriptors and 00339 // are waiting to proceed. Edit the ldt on the current processor, 00340 // then continue the execution of target processors. 00341 // 00342 00343 Ldt[Offset] = LdtEntry; 00344 if (TargetProcessors != 0) { 00345 Prcb->ReverseStall += 1; 00346 } 00347 00348 #endif 00349 00350 // 00351 // Restore IRQL and release the context swap lock. 00352 // 00353 00354 KiUnlockContextSwap(OldIrql); 00355 MmUnlockPagedPool(&Ldt[Offset], sizeof(LDT_ENTRY)); 00356 return; 00357 }

VOID Ke386SetLdtProcess IN PKPROCESS  Process,
IN PLDT_ENTRY  Ldt,
IN ULONG  Limit
 

Definition at line 63 of file i386/ldtsup.c.

References KeGetCurrentPrcb, Ki386LoadTargetLdtr(), KiIpiSendPacket(), KiIpiStallOnPacketTargets(), KiLoadLdtr(), KiLockContextSwap, KiUnlockContextSwap, NULL, and USHORT.

Referenced by NtSetLdtEntries(), PspSetLdtInformation(), and PspSetLdtSize().

00070 : 00071 00072 The specified LDT (which may be null) will be made the active Ldt of 00073 the specified process, for all threads thereof, on whichever 00074 processors they are running. The change will take effect before the 00075 call returns. 00076 00077 An Ldt address of NULL or a Limit of 0 will cause the process to 00078 receive the NULL Ldt. 00079 00080 This function only exists on i386 and i386 compatible processors. 00081 00082 No checking is done on the validity of Ldt entries. 00083 00084 00085 N.B. 00086 00087 While a single Ldt structure can be shared amoung processes, any 00088 edits to the Ldt of one of those processes will only be synchronized 00089 for that process. Thus, processes other than the one the change is 00090 applied to may not see the change correctly. 00091 00092 Arguments: 00093 00094 Process - Pointer to KPROCESS object describing the process for 00095 which the Ldt is to be set. 00096 00097 Ldt - Pointer to an array of LDT_ENTRYs (that is, a pointer to an 00098 Ldt.) 00099 00100 Limit - Ldt limit (must be 0 mod 8) 00101 00102 Return Value: 00103 00104 None. 00105 00106 --*/ 00107 00108 { 00109 00110 KGDTENTRY LdtDescriptor; 00111 BOOLEAN LocalProcessor; 00112 KIRQL OldIrql; 00113 PKPRCB Prcb; 00114 KAFFINITY TargetProcessors; 00115 00116 // 00117 // Compute the contents of the Ldt descriptor 00118 // 00119 00120 if ((Ldt == NULL) || (Limit == 0)) { 00121 00122 // 00123 // Set up an empty descriptor 00124 // 00125 00126 LdtDescriptor.LimitLow = 0; 00127 LdtDescriptor.BaseLow = 0; 00128 LdtDescriptor.HighWord.Bytes.BaseMid = 0; 00129 LdtDescriptor.HighWord.Bytes.Flags1 = 0; 00130 LdtDescriptor.HighWord.Bytes.Flags2 = 0; 00131 LdtDescriptor.HighWord.Bytes.BaseHi = 0; 00132 00133 } else { 00134 00135 // 00136 // Insure that the unfilled fields of the selector are zero 00137 // N.B. If this is not done, random values appear in the high 00138 // portion of the Ldt limit. 00139 // 00140 00141 LdtDescriptor.HighWord.Bytes.Flags1 = 0; 00142 LdtDescriptor.HighWord.Bytes.Flags2 = 0; 00143 00144 // 00145 // Set the limit and base 00146 // 00147 00148 LdtDescriptor.LimitLow = (USHORT) ((ULONG) Limit - 1); 00149 LdtDescriptor.BaseLow = (USHORT) ((ULONG) Ldt & 0xffff); 00150 LdtDescriptor.HighWord.Bytes.BaseMid = (UCHAR) (((ULONG)Ldt & 0xff0000) >> 16); 00151 LdtDescriptor.HighWord.Bytes.BaseHi = (UCHAR) (((ULONG)Ldt & 0xff000000) >> 24); 00152 00153 // 00154 // Type is LDT, DPL = 0 00155 // 00156 00157 LdtDescriptor.HighWord.Bits.Type = TYPE_LDT; 00158 LdtDescriptor.HighWord.Bits.Dpl = DPL_SYSTEM; 00159 00160 // 00161 // Make it present 00162 // 00163 00164 LdtDescriptor.HighWord.Bits.Pres = 1; 00165 00166 } 00167 00168 // 00169 // Acquire the context swap lock so a context switch cannot occur. 00170 // 00171 00172 KiLockContextSwap(&OldIrql); 00173 00174 // 00175 // Set the Ldt fields in the process object. 00176 // 00177 00178 Process->LdtDescriptor = LdtDescriptor; 00179 00180 // 00181 // Tell all processors active for this process to reload their LDTs 00182 // 00183 00184 #ifdef NT_UP 00185 00186 KiLoadLdtr(); 00187 00188 #else 00189 00190 Prcb = KeGetCurrentPrcb(); 00191 TargetProcessors = Process->ActiveProcessors & ~Prcb->SetMember; 00192 if (TargetProcessors != 0) { 00193 KiIpiSendPacket(TargetProcessors, 00194 Ki386LoadTargetLdtr, 00195 NULL, 00196 NULL, 00197 NULL); 00198 } 00199 00200 KiLoadLdtr(); 00201 if (TargetProcessors != 0) { 00202 00203 // 00204 // Stall until target processor(s) release us 00205 // 00206 00207 KiIpiStallOnPacketTargets(TargetProcessors); 00208 } 00209 00210 #endif 00211 00212 // 00213 // Restore IRQL and release the context swap lock. 00214 // 00215 00216 KiUnlockContextSwap(OldIrql); 00217 return; 00218 }

VOID Ki386FlushTargetDescriptors IN PKIPI_CONTEXT  SignalDone,
IN PVOID  Parameter1,
IN PVOID  Parameter2,
IN PVOID  Parameter3
 

Definition at line 360 of file i386/ldtsup.c.

References KiFlushDescriptors().

Referenced by Ke386SetDescriptorProcess().

00369 : 00370 00371 This function flushes the segment descriptors on the current processor. 00372 00373 Arguments: 00374 00375 Argument - pointer to a _KIPI_FLUSH_DESCRIPTOR structure. 00376 00377 ReadyFlag - pointer to flag to syncroize with 00378 00379 Return Value: 00380 00381 none. 00382 00383 --*/ 00384 00385 { 00386 // 00387 // Flush the segment descriptors on the current processor and signal that 00388 // the descriptors have been flushed. 00389 // 00390 00391 KiFlushDescriptors(); 00392 KiIpiSignalPacketDoneAndStall (SignalDone, Proceed); 00393 return; 00394 } }

VOID Ki386LoadTargetLdtr IN PKIPI_CONTEXT  SignalDone,
IN PVOID  Parameter1,
IN PVOID  Parameter2,
IN PVOID  Parameter3
 

Definition at line 221 of file i386/ldtsup.c.

References KiIpiSignalPacketDone(), and KiLoadLdtr().

Referenced by Ke386SetLdtProcess().

00229 : 00230 00231 Reload local Ldt register and clear signal bit in TargetProcessor mask 00232 00233 Arguments: 00234 00235 Argument - pointer to a ipi packet structure. 00236 ReadyFlag - Pointer to flag to be set once LDTR has been reloaded 00237 00238 Return Value: 00239 00240 none. 00241 00242 --*/ 00243 { 00244 00245 // 00246 // Reload the LDTR register from currently active process object 00247 // 00248 00249 KiLoadLdtr(); 00250 KiIpiSignalPacketDone(SignalDone); 00251 return; 00252 }

VOID KiFlushDescriptors VOID   ) 
 

Referenced by Ki386FlushTargetDescriptors().

VOID KiLoadLdtr VOID   ) 
 

Referenced by Ke386SetLdtProcess(), and Ki386LoadTargetLdtr().


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