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

ldtsup.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1991 Microsoft Corporation 00004 00005 Module Name: 00006 00007 ldtsup.c 00008 00009 Abstract: 00010 00011 This module implements interfaces that support manipulation of i386 Ldts. 00012 These entry points only exist on i386 and EM machines. 00013 00014 Author: 00015 00016 Bryan M. Willman (bryanwi) 14-May-1991 00017 00018 Environment: 00019 00020 Kernel mode only. 00021 00022 Revision History: 00023 Charles Spirakis (intel) 5 Jan 1996 - Make sure when the LDT is set, 00024 that the address pointed to is part of the current process. This is 00025 needed for MIXISA support. 00026 --*/ 00027 00028 #include "ki.h" 00029 00030 // 00031 // Low level assembler support procedures 00032 // 00033 00034 00035 VOID 00036 KeIA32SetLdtProcess ( 00037 PKPROCESS Process, 00038 PLDT_ENTRY Ldt, 00039 ULONG Limit 00040 ) 00041 /*++ 00042 00043 Routine Description: 00044 00045 The specified LDT (which may be null) will be made the active Ldt of 00046 the specified process, for all threads thereof, on whichever 00047 processors they are running. The change will take effect before the 00048 call returns. 00049 00050 An Ldt address of NULL or a Limit of 0 will cause the process to 00051 receive the NULL Ldt. 00052 00053 This function only exists on i386 and i386 compatible processors. 00054 00055 No checking is done on the validity of Ldt entries. 00056 00057 00058 Arguments: 00059 00060 Process - Pointer to KPROCESS object describing the process for 00061 which the Ldt is to be set. 00062 00063 Ldt - Pointer to an array of LDT_ENTRYs (that is, a pointer to an 00064 Ldt.) 00065 00066 Limit - Ldt limit (must be 0 mod 8) 00067 00068 Return Value: 00069 00070 None. 00071 00072 --*/ 00073 00074 { 00075 #if 0 00076 KGDTENTRY LdtDescriptor; 00077 KXDESCRIPTOR XDescriptor; 00078 PTEB Teb; 00079 00080 00081 // 00082 // Compute the contents of the Ldt descriptor 00083 // 00084 00085 if ((Ldt == NULL) || (Limit == 0)) { 00086 00087 // 00088 // Set up an empty descriptor 00089 // 00090 00091 LdtDescriptor.LimitLow = 0; 00092 LdtDescriptor.BaseLow = 0; 00093 LdtDescriptor.HighWord.Bytes.BaseMid = 0; 00094 LdtDescriptor.HighWord.Bytes.Flags1 = 0; 00095 LdtDescriptor.HighWord.Bytes.Flags2 = 0; 00096 LdtDescriptor.HighWord.Bytes.BaseHi = 0; 00097 00098 XDescriptor.Words.DescriptorWords = (ULONGLONG) 0; 00099 00100 } else { 00101 00102 // 00103 // Insure that the unfilled fields of the selector are zero 00104 // N.B. If this is not done, random values appear in the high 00105 // portion of the Ldt limit. 00106 // 00107 00108 LdtDescriptor.HighWord.Bytes.Flags1 = 0; 00109 LdtDescriptor.HighWord.Bytes.Flags2 = 0; 00110 00111 // 00112 // Set the limit and base 00113 // 00114 00115 LdtDescriptor.LimitLow = (USHORT) ((ULONG) Limit - 1); 00116 LdtDescriptor.BaseLow = (USHORT) ((ULONG_PTR) Ldt & (ULONG_PTR)0xffff); 00117 LdtDescriptor.HighWord.Bytes.BaseMid = (UCHAR) (((ULONG_PTR)Ldt & (ULONG_PTR)0xff0000) >> 16); 00118 LdtDescriptor.HighWord.Bytes.BaseHi = (UCHAR) (((ULONG_PTR)Ldt & (ULONG_PTR)0xff000000) >> 24); 00119 00120 // 00121 // Type is LDT, DPL = 0 00122 // 00123 00124 LdtDescriptor.HighWord.Bits.Type = TYPE_LDT; 00125 LdtDescriptor.HighWord.Bits.Dpl = DPL_SYSTEM; 00126 00127 // 00128 // Make it present 00129 // 00130 00131 LdtDescriptor.HighWord.Bits.Pres = 1; 00132 00133 // 00134 // Handcraft an unscrambled format that matches the above information 00135 // 00136 XDescriptor.Words.DescriptorWords = (ULONGLONG) 0; 00137 XDescriptor.Words.Bits.Base = (ULONG_PTR) Ldt; 00138 XDescriptor.Words.Bits.Limit = Limit - 1; 00139 XDescriptor.Words.Bits.Type = TYPE_LDT; 00140 XDescriptor.Words.Bits.Dpl = DPL_USER; 00141 XDescriptor.Words.Bits.Pres = 1; 00142 00143 } 00144 00145 // 00146 // Set the Ldt fields (scrambled and unscrambled) in the process object 00147 // 00148 00149 Process->LdtDescriptor = LdtDescriptor; 00150 Process->UnscrambledLdtDescriptor = XDescriptor.Words.DescriptorWords; 00151 00152 // 00153 // If it isn't for the current process, we have a problem 00154 // as we need to update the thread's copy of the GDT. For the IA64 00155 // version of VDM support, we can make sure that only the current 00156 // process touches it's own LDT (and that the first thread of the 00157 // process creates the LDT), but it would be safer to write 00158 // the general purpose case... 00159 // 00160 00161 ASSERT (Process == &(PsGetCurrentProcess()->Pcb)); 00162 00163 // 00164 // Put LdtDescriptor into Gdt table of current thread 00165 // (a better algorithm would be to put the LDT descriptor into 00166 // all of the GDT's for the passed in PROCESS, but for IA64, 00167 // that is overkill (unless it's easy to do))... 00168 // 00169 00170 Teb = PsGetCurrentThread()->Tcb.Teb; 00171 *(KGDTENTRY *)(&Teb->Gdt[KGDT_LDT>3]) = LdtDescriptor; 00172 00173 // 00174 // And update the LDTR field used by ISA transition stub routines 00175 // 00176 Teb->LdtDescriptor = XDescriptor.Words.DescriptorWords; 00177 00178 return; 00179 #endif 00180 }

Generated on Sat May 15 19:40:38 2004 for test by doxygen 1.3.7