1
- use x86:: { segmentation, task} ;
1
+ use x86:: segmentation:: SegmentSelector ;
2
+ use x86:: { Ring , segmentation, task} ;
2
3
use x86_64:: VirtAddr ;
3
4
use 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 } ;
5
6
use x86_64:: structures:: DescriptorTablePointer ;
6
7
use x86_64:: { addr:: PhysAddr , structures:: paging:: PhysFrame } ;
7
8
@@ -38,7 +39,7 @@ pub struct LinuxContext {
38
39
pub cr3 : u64 ,
39
40
pub cr4 : Cr4Flags ,
40
41
41
- pub efer : u64 ,
42
+ pub efer : EferFlags ,
42
43
pub star : u64 ,
43
44
pub lstar : u64 ,
44
45
pub cstar : u64 ,
@@ -87,7 +88,7 @@ impl Default for LinuxContext {
87
88
cr0 : Cr0Flags :: empty ( ) ,
88
89
cr3 : 0 ,
89
90
cr4 : Cr4Flags :: empty ( ) ,
90
- efer : 0 ,
91
+ efer : EferFlags :: empty ( ) ,
91
92
star : 0 ,
92
93
lstar : 0 ,
93
94
cstar : 0 ,
@@ -146,7 +147,7 @@ impl LinuxContext {
146
147
cr0 : Cr0 :: read ( ) ,
147
148
cr3 : Cr3 :: read ( ) . 0 . start_address ( ) . as_u64 ( ) ,
148
149
cr4 : Cr4 :: read ( ) ,
149
- efer : Msr :: IA32_EFER . read ( ) ,
150
+ efer : Efer :: read ( ) ,
150
151
star : Msr :: IA32_STAR . read ( ) ,
151
152
lstar : Msr :: IA32_LSTAR . read ( ) ,
152
153
cstar : Msr :: IA32_CSTAR . read ( ) ,
@@ -161,14 +162,95 @@ impl LinuxContext {
161
162
}
162
163
}
163
164
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
+
164
246
/// Restore system registers.
165
247
pub fn restore ( & self ) {
166
248
unsafe {
167
249
Msr :: IA32_SYSENTER_CS . write ( self . ia32_sysenter_cs ) ;
168
250
Msr :: IA32_SYSENTER_ESP . write ( self . ia32_sysenter_esp ) ;
169
251
Msr :: IA32_SYSENTER_EIP . write ( self . ia32_sysenter_eip ) ;
170
252
171
- Msr :: IA32_EFER . write ( self . efer ) ;
253
+ Efer :: write ( self . efer ) ;
172
254
Msr :: IA32_STAR . write ( self . star ) ;
173
255
Msr :: IA32_LSTAR . write ( self . lstar ) ;
174
256
Msr :: IA32_CSTAR . write ( self . cstar ) ;
0 commit comments