9
9
paging:: BASE_PAGE_SIZE ,
10
10
rflags,
11
11
} ,
12
- controlregs , dtables , msr,
13
- segmentation:: { cs, ds, es, fs, gs, SegmentSelector , ss} ,
12
+ msr,
13
+ segmentation:: { cs, ds, es, fs, gs, ss} ,
14
14
vmx:: vmcs,
15
15
debugregs:: dr7,
16
16
} ,
@@ -22,12 +22,12 @@ use {
22
22
controls:: { adjust_vmx_controls, VmxControl } ,
23
23
descriptor:: Descriptors ,
24
24
paging:: PageTables ,
25
- segmentation:: SegmentDescriptor ,
26
25
shared_data:: SharedData ,
27
- support:: { rdmsr, sidt, vmread, vmwrite} ,
26
+ support:: { rdmsr, sidt, vmread, vmwrite, cr0 , cr3 } ,
28
27
invvpid:: { invvpid_single_context, VPID_TAG } ,
29
28
invept:: invept_single_context,
30
29
page:: Page ,
30
+ segmentation:: { access_rights_from_native, lar, lsl} ,
31
31
} ,
32
32
} ,
33
33
} ;
@@ -71,8 +71,8 @@ impl Vmcs {
71
71
72
72
let idtr = sidt ( ) ;
73
73
74
- unsafe { vmwrite ( vmcs:: guest:: CR0 , controlregs :: cr0 ( ) . bits ( ) as u64 ) } ;
75
- unsafe { vmwrite ( vmcs:: guest:: CR3 , controlregs :: cr3 ( ) ) } ;
74
+ vmwrite ( vmcs:: guest:: CR0 , cr0 ( ) . bits ( ) as u64 ) ;
75
+ vmwrite ( vmcs:: guest:: CR3 , cr3 ( ) ) ;
76
76
vmwrite ( vmcs:: guest:: CR4 , Cr4 :: read_raw ( ) ) ;
77
77
78
78
vmwrite ( vmcs:: guest:: DR7 , unsafe { dr7 ( ) . 0 as u64 } ) ;
@@ -88,48 +88,38 @@ impl Vmcs {
88
88
vmwrite ( vmcs:: guest:: FS_SELECTOR , fs ( ) . bits ( ) ) ;
89
89
vmwrite ( vmcs:: guest:: GS_SELECTOR , gs ( ) . bits ( ) ) ;
90
90
91
- vmwrite ( vmcs:: guest:: LDTR_SELECTOR , 0u16 ) ; // this is not 0 in Hypervisor-101-in-Rust but is in Hello-VT-rp
91
+ vmwrite ( vmcs:: guest:: LDTR_SELECTOR , 0u16 ) ;
92
92
vmwrite ( vmcs:: guest:: TR_SELECTOR , guest_descriptor. tr . bits ( ) ) ;
93
93
94
- unsafe { vmwrite ( vmcs:: guest:: FS_BASE , msr:: rdmsr ( msr:: IA32_FS_BASE ) ) } ;
95
- unsafe { vmwrite ( vmcs:: guest:: GS_BASE , msr:: rdmsr ( msr:: IA32_GS_BASE ) ) } ;
96
- unsafe { vmwrite ( vmcs:: guest:: LDTR_BASE , SegmentDescriptor :: from_selector ( SegmentSelector :: from_raw ( dtables:: ldtr ( ) . bits ( ) ) , & guest_descriptor. gdtr ) . base_address ) } ;
94
+ // All segment base registers are assumed to be zero, except that of TR.
97
95
vmwrite ( vmcs:: guest:: TR_BASE , guest_descriptor. tss . base ) ;
98
96
99
- vmwrite ( vmcs:: guest:: CS_LIMIT , SegmentDescriptor :: from_selector ( SegmentSelector :: from_raw ( ss ( ) . bits ( ) ) , & guest_descriptor. gdtr ) . segment_limit ) ;
100
- vmwrite ( vmcs:: guest:: SS_LIMIT , SegmentDescriptor :: from_selector ( SegmentSelector :: from_raw ( ss ( ) . bits ( ) ) , & guest_descriptor. gdtr ) . segment_limit ) ;
101
- vmwrite ( vmcs:: guest:: DS_LIMIT , SegmentDescriptor :: from_selector ( SegmentSelector :: from_raw ( ds ( ) . bits ( ) ) , & guest_descriptor. gdtr ) . segment_limit ) ;
102
- vmwrite ( vmcs:: guest:: ES_LIMIT , SegmentDescriptor :: from_selector ( SegmentSelector :: from_raw ( es ( ) . bits ( ) ) , & guest_descriptor. gdtr ) . segment_limit ) ;
103
- vmwrite ( vmcs:: guest:: FS_LIMIT , SegmentDescriptor :: from_selector ( SegmentSelector :: from_raw ( fs ( ) . bits ( ) ) , & guest_descriptor. gdtr ) . segment_limit ) ;
104
- vmwrite ( vmcs:: guest:: GS_LIMIT , SegmentDescriptor :: from_selector ( SegmentSelector :: from_raw ( gs ( ) . bits ( ) ) , & guest_descriptor. gdtr ) . segment_limit ) ;
105
-
106
- vmwrite ( vmcs:: guest:: LDTR_LIMIT , 0u32 ) ; // this is not 0 in Hypervisor-101-in-Rust but is in Hello-VT-rp
97
+ vmwrite ( vmcs:: guest:: CS_LIMIT , lsl ( ss ( ) ) ) ;
98
+ vmwrite ( vmcs:: guest:: SS_LIMIT , lsl ( ss ( ) ) ) ;
99
+ vmwrite ( vmcs:: guest:: DS_LIMIT , lsl ( ds ( ) ) ) ;
100
+ vmwrite ( vmcs:: guest:: ES_LIMIT , lsl ( es ( ) ) ) ;
101
+ vmwrite ( vmcs:: guest:: FS_LIMIT , lsl ( fs ( ) ) ) ;
102
+ vmwrite ( vmcs:: guest:: GS_LIMIT , lsl ( gs ( ) ) ) ;
103
+ vmwrite ( vmcs:: guest:: LDTR_LIMIT , 0u32 ) ;
107
104
vmwrite ( vmcs:: guest:: TR_LIMIT , guest_descriptor. tr . bits ( ) ) ;
108
105
109
- vmwrite ( vmcs:: guest:: CS_ACCESS_RIGHTS , SegmentDescriptor :: from_selector ( SegmentSelector :: from_raw ( cs ( ) . bits ( ) ) , & guest_descriptor. gdtr ) . access_rights . bits ( ) ) ;
110
- vmwrite ( vmcs:: guest:: SS_ACCESS_RIGHTS , SegmentDescriptor :: from_selector ( SegmentSelector :: from_raw ( ss ( ) . bits ( ) ) , & guest_descriptor. gdtr ) . access_rights . bits ( ) ) ;
111
- vmwrite ( vmcs:: guest:: DS_ACCESS_RIGHTS , SegmentDescriptor :: from_selector ( SegmentSelector :: from_raw ( ds ( ) . bits ( ) ) , & guest_descriptor. gdtr ) . access_rights . bits ( ) ) ;
112
- vmwrite ( vmcs:: guest:: ES_ACCESS_RIGHTS , SegmentDescriptor :: from_selector ( SegmentSelector :: from_raw ( es ( ) . bits ( ) ) , & guest_descriptor. gdtr ) . access_rights . bits ( ) ) ;
113
- vmwrite ( vmcs:: guest:: FS_ACCESS_RIGHTS , SegmentDescriptor :: from_selector ( SegmentSelector :: from_raw ( fs ( ) . bits ( ) ) , & guest_descriptor. gdtr ) . access_rights . bits ( ) ) ;
114
- vmwrite ( vmcs:: guest:: GS_ACCESS_RIGHTS , SegmentDescriptor :: from_selector ( SegmentSelector :: from_raw ( gs ( ) . bits ( ) ) , & guest_descriptor. gdtr ) . access_rights . bits ( ) ) ;
115
-
116
- // https://github.com/tandasat/Hello-VT-rp/blob/main/hypervisor/src/intel_vt/vm.rs#L93-L97
117
- vmwrite ( vmcs:: guest:: LDTR_ACCESS_RIGHTS , SegmentDescriptor :: from_selector ( SegmentSelector :: from_raw ( 0 ) , & guest_descriptor. gdtr ) . access_rights . bits ( ) ) ;
118
- vmwrite ( vmcs:: guest:: TR_ACCESS_RIGHTS , SegmentDescriptor :: from_selector ( SegmentSelector :: from_raw ( guest_descriptor. tss . ar as u16 ) , & guest_descriptor. gdtr ) . access_rights . bits ( ) ) ;
106
+ vmwrite ( vmcs:: guest:: CS_ACCESS_RIGHTS , access_rights_from_native ( lar ( cs ( ) ) ) as u64 ) ;
107
+ vmwrite ( vmcs:: guest:: SS_ACCESS_RIGHTS , access_rights_from_native ( lar ( ss ( ) ) ) as u64 ) ;
108
+ vmwrite ( vmcs:: guest:: DS_ACCESS_RIGHTS , access_rights_from_native ( lar ( ds ( ) ) ) as u64 ) ;
109
+ vmwrite ( vmcs:: guest:: ES_ACCESS_RIGHTS , access_rights_from_native ( lar ( es ( ) ) ) as u64 ) ;
110
+ vmwrite ( vmcs:: guest:: FS_ACCESS_RIGHTS , access_rights_from_native ( lar ( fs ( ) ) ) as u64 ) ;
111
+ vmwrite ( vmcs:: guest:: GS_ACCESS_RIGHTS , access_rights_from_native ( lar ( gs ( ) ) ) as u64 ) ;
112
+ vmwrite ( vmcs:: guest:: LDTR_ACCESS_RIGHTS , access_rights_from_native ( 0u32 ) ) ;
113
+ vmwrite ( vmcs:: guest:: TR_ACCESS_RIGHTS , access_rights_from_native ( guest_descriptor. tss . ar ) ) ;
119
114
120
115
vmwrite ( vmcs:: guest:: GDTR_BASE , guest_descriptor. gdtr . base as u64 ) ;
121
116
vmwrite ( vmcs:: guest:: IDTR_BASE , idtr. base as u64 ) ;
122
117
123
118
vmwrite ( vmcs:: guest:: GDTR_LIMIT , guest_descriptor. gdtr . limit as u64 ) ;
124
119
vmwrite ( vmcs:: guest:: IDTR_LIMIT , idtr. limit as u64 ) ;
125
120
126
- unsafe {
127
- vmwrite ( vmcs:: guest:: IA32_DEBUGCTL_FULL , msr:: rdmsr ( msr:: IA32_DEBUGCTL ) ) ;
128
- vmwrite ( vmcs:: guest:: IA32_SYSENTER_CS , msr:: rdmsr ( msr:: IA32_SYSENTER_CS ) ) ;
129
- vmwrite ( vmcs:: guest:: IA32_SYSENTER_ESP , msr:: rdmsr ( msr:: IA32_SYSENTER_ESP ) ) ;
130
- vmwrite ( vmcs:: guest:: IA32_SYSENTER_EIP , msr:: rdmsr ( msr:: IA32_SYSENTER_EIP ) ) ;
131
- vmwrite ( vmcs:: guest:: LINK_PTR_FULL , u64:: MAX ) ;
132
- }
121
+ vmwrite ( vmcs:: guest:: LINK_PTR_FULL , u64:: MAX ) ;
122
+
133
123
134
124
// Note: VMCS does not manage all registers; some require manual intervention for saving and loading.
135
125
// This includes general-purpose registers and xmm registers, which must be explicitly preserved and restored by the software.
@@ -185,9 +175,9 @@ impl Vmcs {
185
175
186
176
let pml4_pa = host_paging. get_pml4_pa ( ) ?;
187
177
188
- unsafe { vmwrite ( vmcs:: host:: CR0 , controlregs :: cr0 ( ) . bits ( ) as u64 ) } ;
178
+ vmwrite ( vmcs:: host:: CR0 , cr0 ( ) . bits ( ) as u64 ) ;
189
179
vmwrite ( vmcs:: host:: CR3 , pml4_pa) ;
190
- unsafe { vmwrite ( vmcs:: host:: CR4 , controlregs :: cr4 ( ) . bits ( ) as u64 ) } ;
180
+ vmwrite ( vmcs:: host:: CR4 , Cr4 :: read_raw ( ) ) ;
191
181
192
182
vmwrite ( vmcs:: host:: CS_SELECTOR , host_descriptor. cs . bits ( ) ) ;
193
183
vmwrite ( vmcs:: host:: TR_SELECTOR , host_descriptor. tr . bits ( ) ) ;
@@ -231,10 +221,8 @@ impl Vmcs {
231
221
vmwrite ( vmcs:: control:: VMEXIT_CONTROLS , adjust_vmx_controls ( VmxControl :: VmExit , EXIT_CTL ) ) ;
232
222
vmwrite ( vmcs:: control:: PINBASED_EXEC_CONTROLS , adjust_vmx_controls ( VmxControl :: PinBased , PINBASED_CTL ) ) ;
233
223
234
- unsafe {
235
- vmwrite ( vmcs:: control:: CR0_READ_SHADOW , controlregs:: cr0 ( ) . bits ( ) as u64 ) ;
236
- vmwrite ( vmcs:: control:: CR4_READ_SHADOW , controlregs:: cr4 ( ) . bits ( ) as u64 ) ;
237
- } ;
224
+ vmwrite ( vmcs:: control:: CR0_READ_SHADOW , cr0 ( ) . bits ( ) as u64 ) ;
225
+ vmwrite ( vmcs:: control:: CR4_READ_SHADOW , Cr4 :: read_raw ( ) ) ;
238
226
239
227
vmwrite ( vmcs:: control:: MSR_BITMAPS_ADDR_FULL , msr_bitmap. as_ref ( ) as * const _ as u64 ) ;
240
228
//vmwrite(vmcs::control::EXCEPTION_BITMAP, 1u64 << (ExceptionInterrupt::Breakpoint as u32));
0 commit comments