10
10
#include <Hypervisor/hv_vmx.h>
11
11
12
12
#define SEGM_SIZE 0xFFFF // size of real-mode segment
13
- #define CTRL_UNRSTR (1<<7) // To execute real-mode code
13
+
14
+ /* primary processor-based ctrl */
14
15
#define CTRL_HALT_INSTR (1<<7) // VM exit when guest executes halt instruction
15
- #define CTRL_UNCON_IO (1<<24) // VM exit when guest executes IO instruction
16
+ #define CTRL_CR8_LOAD (1<<19)
17
+ #define CTRL_CR8_STORE (1<<20)
16
18
#define CTRL_SECOND (1<<31) // enable secondary processor controls
17
19
#define PRI_DEF1 (0x401E172) // default1's for primary
20
+ #define PROC1_BITMAP (PRI_DEF1 | CTRL_HALT_INSTR | CTRL_UNCON_IO | CTRL_SECOND | CTRL_CR8_LOAD | CTRL_CR8_STORE)
21
+
22
+ /* secondary processor-based ctrl */
23
+ #define CTRL_UNRSTR (1<<7) // To execute real-mode code
24
+ #define PROC2_BITMAP CTRL_UNRSTR
25
+
26
+ /* pin-based ctrl */
27
+ #define CTRL_UNCON_IO (1<<24) // VM exit when guest executes IO instruction
18
28
#define PIN_DEF1 (0x16)
19
29
#define PIN_BITMAP (PIN_DEF1 | 0x1)
20
- #define PROC1_BITMAP (PRI_DEF1 | CTRL_HALT_INSTR | CTRL_UNCON_IO | CTRL_SECOND) // primary processor-based ctrl
21
- #define PROC2_BITMAP CTRL_UNRSTR
22
30
31
+ /* map guest physical address to host virtual address */
23
32
#define VM_MEM_MAP (uva , gpa , size , flags ) \
24
33
if ( (ret = hv_vm_map(uva, gpa, size, flags) != HV_SUCCESS)) { \
25
34
print_err(ret); \
26
35
exit(0); \
27
36
}
28
37
38
+ /* execute vm represented by vcpu */
29
39
#define HV_EXEC (vcpu ) \
30
40
if ( (ret = hv_vcpu_run(*vcpu)) != HV_SUCCESS) { \
31
41
print_err(ret); \
@@ -93,7 +103,7 @@ static void vmcs_init_ctrl(hv_vcpuid_t *vcpu)
93
103
/* set default1 bits and some capabilities */
94
104
95
105
read_caps (HV_VMX_CAP_PINBASED , & cap );
96
- write_vmcs (vcpu , VMCS_CTRL_PIN_BASED , PIN_BITMAP | ((cap & 0xffffffff ) & (cap >> 32 ))); // VM-exit on external interrupts
106
+ write_vmcs (vcpu , VMCS_CTRL_PIN_BASED , PIN_BITMAP | ((cap & 0xffffffff ) & (cap >> 32 )));
97
107
98
108
read_caps (HV_VMX_CAP_PROCBASED , & cap );
99
109
write_vmcs (vcpu , VMCS_CTRL_CPU_BASED , (PROC1_BITMAP | (cap & 0xffffffff )) & (cap >> 32 ));
@@ -108,7 +118,6 @@ static void vmcs_init_ctrl(hv_vcpuid_t *vcpu)
108
118
write_vmcs (vcpu , VMCS_CTRL_VMEXIT_CONTROLS , (0x36dff | (cap & 0xffffffff )) & (cap >> 32 ));
109
119
}
110
120
111
- /* incomplete */
112
121
static void vmcs_init_guest (hv_vcpuid_t * vcpu )
113
122
{
114
123
write_vmcs (vcpu , VMCS_GUEST_RIP , 0x100 ); // load program segment at segment:offset -> 0x0:0x100
@@ -150,15 +159,20 @@ static void vmcs_init_guest(hv_vcpuid_t *vcpu)
150
159
write_vmcs (vcpu , VMCS_GUEST_LDTR_LIMIT , SEGM_SIZE );
151
160
write_vmcs (vcpu , VMCS_GUEST_LDTR_AR , 0x82 );
152
161
write_vmcs (vcpu , VMCS_GUEST_GDTR_BASE , 0 );
162
+ write_vmcs (vcpu , VMCS_GUEST_GDTR_LIMIT , SEGM_SIZE );
153
163
write_vmcs (vcpu , VMCS_GUEST_IDTR_BASE , 0 );
164
+ write_vmcs (vcpu , VMCS_GUEST_IDTR_LIMIT , SEGM_SIZE );
154
165
155
- write_vmcs (vcpu , VMCS_GUEST_CR0 , 0x60000010 ); // in particular, PE and PG disabled; execute in real-mode
166
+ write_vmcs (vcpu , VMCS_GUEST_CR0 , 0x20 ); // in particular, PE and PG disabled; execute in real-mode
156
167
write_vmcs (vcpu , VMCS_GUEST_CR3 , 0x0 );
157
168
write_vmcs (vcpu , VMCS_GUEST_DR7 , 0x0 );
158
- write_vmcs (vcpu , VMCS_GUEST_SYSENTER_EIP , 0x6826 );
159
- write_vmcs (vcpu , VMCS_GUEST_SYSENTER_ESP , 0x6824 );
160
169
write_vmcs (vcpu , VMCS_GUEST_CR4 , 1L <<13 );
161
170
171
+ write_vmcs (vcpu , VMCS_CTRL_EXC_BITMAP , 0xffffffff );
172
+ write_vmcs (vcpu , VMCS_CTRL_CR0_MASK , 0x60000000 );
173
+ write_vmcs (vcpu , VMCS_CTRL_CR0_SHADOW , 0x0 );
174
+ write_vmcs (vcpu , VMCS_CTRL_CR4_MASK , 0x0 );
175
+ write_vmcs (vcpu , VMCS_CTRL_CR4_SHADOW , 0x0 );
162
176
}
163
177
164
178
int main (int argc , char * argv [])
@@ -205,18 +219,20 @@ int main(int argc, char *argv[])
205
219
206
220
/* Main loop: execute guest until VM exit */
207
221
uint64_t exit_reas , err ;
208
- while (1 ) {
222
+ int stop = 0 ;
223
+ while (!stop ) {
209
224
HV_EXEC (& vcpu );
210
225
read_vmcs (& vcpu , VMCS_RO_EXIT_REASON , & exit_reas );
211
- //read_vmcs(&vcpu, VMCS_RO_EXIT_QUALIFIC, &exit_reas); // for debugging
212
- //read_vmcs(&vcpu, VMCS_RO_GUEST_LIN_ADDR, &exit_reas); // for debugging
213
226
switch (exit_reas ) {
214
227
case VMX_REASON_HLT :
215
- ;
216
- case VMX_REASON_IO :
217
- ;
228
+ printf ("HLT\n" );
229
+ stop = 1 ;
230
+ break ;
231
+ case VMX_REASON_IRQ :
232
+ printf ("INTERRUPT\n" );
233
+ break ;
218
234
case VMX_REASON_EPT_VIOLATION :
219
- hv_vm_protect ( 0x100 , 0x100 , HV_MEMORY_EXEC ) ;
235
+ ;
220
236
default :
221
237
;
222
238
}
0 commit comments