1- use x86:: { segmentation, task} ;
1+ use x86:: segmentation:: SegmentSelector ;
2+ use x86:: { Ring , segmentation, task} ;
23use x86_64:: VirtAddr ;
34use x86_64:: instructions:: tables:: { lgdt, lidt, sidt} ;
4- use x86_64:: registers:: control:: { Cr0 , Cr0Flags , Cr3 , Cr3Flags , Cr4 , Cr4Flags } ;
5+ use x86_64:: registers:: control:: { Cr0 , Cr0Flags , Cr3 , Cr3Flags , Cr4 , Cr4Flags , Efer , EferFlags } ;
56use x86_64:: structures:: DescriptorTablePointer ;
67use x86_64:: { addr:: PhysAddr , structures:: paging:: PhysFrame } ;
78
@@ -38,7 +39,7 @@ pub struct LinuxContext {
3839 pub cr3 : u64 ,
3940 pub cr4 : Cr4Flags ,
4041
41- pub efer : u64 ,
42+ pub efer : EferFlags ,
4243 pub star : u64 ,
4344 pub lstar : u64 ,
4445 pub cstar : u64 ,
@@ -87,7 +88,7 @@ impl Default for LinuxContext {
8788 cr0 : Cr0Flags :: empty ( ) ,
8889 cr3 : 0 ,
8990 cr4 : Cr4Flags :: empty ( ) ,
90- efer : 0 ,
91+ efer : EferFlags :: empty ( ) ,
9192 star : 0 ,
9293 lstar : 0 ,
9394 cstar : 0 ,
@@ -146,7 +147,7 @@ impl LinuxContext {
146147 cr0 : Cr0 :: read ( ) ,
147148 cr3 : Cr3 :: read ( ) . 0 . start_address ( ) . as_u64 ( ) ,
148149 cr4 : Cr4 :: read ( ) ,
149- efer : Msr :: IA32_EFER . read ( ) ,
150+ efer : Efer :: read ( ) ,
150151 star : Msr :: IA32_STAR . read ( ) ,
151152 lstar : Msr :: IA32_LSTAR . read ( ) ,
152153 cstar : Msr :: IA32_CSTAR . read ( ) ,
@@ -161,14 +162,95 @@ impl LinuxContext {
161162 }
162163 }
163164
165+ pub fn construct_guest64 ( rip : u64 , cr3 : u64 ) -> Self {
166+ Self {
167+ rsp : 0 ,
168+ rip,
169+ r15 : 0 ,
170+ r14 : 0 ,
171+ r13 : 0 ,
172+ r12 : 0 ,
173+ rbx : 0 ,
174+ rbp : 0 ,
175+ es : Segment :: invalid ( ) ,
176+ cs : Segment {
177+ selector : SegmentSelector :: new ( 1 , Ring :: Ring0 ) ,
178+ base : 0 ,
179+ limit : 0xffff ,
180+ access_rights : SegmentAccessRights :: ACCESSED
181+ | SegmentAccessRights :: WRITABLE
182+ | SegmentAccessRights :: EXECUTABLE
183+ | SegmentAccessRights :: CODE_DATA
184+ | SegmentAccessRights :: PRESENT
185+ | SegmentAccessRights :: LONG_MODE
186+ | SegmentAccessRights :: GRANULARITY ,
187+ } ,
188+ ss : Segment {
189+ selector : SegmentSelector :: new ( 2 , Ring :: Ring0 ) ,
190+ base : 0 ,
191+ limit : 0xffff ,
192+ access_rights : SegmentAccessRights :: ACCESSED
193+ | SegmentAccessRights :: WRITABLE
194+ | SegmentAccessRights :: CODE_DATA
195+ | SegmentAccessRights :: PRESENT
196+ | SegmentAccessRights :: DB
197+ | SegmentAccessRights :: GRANULARITY ,
198+ } ,
199+ ds : Segment :: invalid ( ) ,
200+ fs : Segment :: invalid ( ) ,
201+ gs : Segment :: invalid ( ) ,
202+ tss : Segment {
203+ selector : SegmentSelector :: new ( 2 , Ring :: Ring0 ) ,
204+ base : 0 ,
205+ limit : 0 ,
206+ access_rights : SegmentAccessRights :: ACCESSED
207+ | SegmentAccessRights :: WRITABLE
208+ | SegmentAccessRights :: EXECUTABLE
209+ | SegmentAccessRights :: PRESENT ,
210+ } ,
211+ gdt : DescriptorTablePointer {
212+ limit : 0 ,
213+ base : VirtAddr :: zero ( ) ,
214+ } ,
215+ idt : DescriptorTablePointer {
216+ limit : 0 ,
217+ base : VirtAddr :: zero ( ) ,
218+ } ,
219+ cr0 : Cr0Flags :: PROTECTED_MODE_ENABLE
220+ | Cr0Flags :: MONITOR_COPROCESSOR
221+ | Cr0Flags :: EXTENSION_TYPE
222+ | Cr0Flags :: NUMERIC_ERROR
223+ | Cr0Flags :: WRITE_PROTECT
224+ | Cr0Flags :: ALIGNMENT_MASK
225+ | Cr0Flags :: PAGING ,
226+ cr3,
227+ cr4 : Cr4Flags :: PHYSICAL_ADDRESS_EXTENSION | Cr4Flags :: PAGE_GLOBAL ,
228+ efer : EferFlags :: LONG_MODE_ENABLE
229+ | EferFlags :: LONG_MODE_ACTIVE
230+ | EferFlags :: NO_EXECUTE_ENABLE
231+ | EferFlags :: SYSTEM_CALL_EXTENSIONS ,
232+ star : 0 ,
233+ lstar : 0 ,
234+ cstar : 0 ,
235+ fmask : 0 ,
236+ ia32_sysenter_cs : 0 ,
237+ ia32_sysenter_esp : 0 ,
238+ ia32_sysenter_eip : 0 ,
239+ kernel_gsbase : 0 ,
240+ pat : 0 ,
241+ mtrr_def_type : 0 ,
242+ xstate : XState :: default ( ) ,
243+ }
244+ }
245+
164246 /// Restore system registers.
165247 pub fn restore ( & self ) {
166248 unsafe {
167249 Msr :: IA32_SYSENTER_CS . write ( self . ia32_sysenter_cs ) ;
168250 Msr :: IA32_SYSENTER_ESP . write ( self . ia32_sysenter_esp ) ;
169251 Msr :: IA32_SYSENTER_EIP . write ( self . ia32_sysenter_eip ) ;
170252
171- Msr :: IA32_EFER . write ( self . efer ) ;
253+ Efer :: write ( self . efer ) ;
172254 Msr :: IA32_STAR . write ( self . star ) ;
173255 Msr :: IA32_LSTAR . write ( self . lstar ) ;
174256 Msr :: IA32_CSTAR . write ( self . cstar ) ;
0 commit comments