@@ -107,7 +107,7 @@ static void handle_machine_check(struct vcpu_t *vcpu);
107107
108108static void handle_cpuid_virtual (struct vcpu_t * vcpu , uint32_t eax , uint32_t ecx );
109109static void handle_mem_fault (struct vcpu_t * vcpu , struct hax_tunnel * htun );
110- static void check_flush (struct vcpu_t * vcpu , uint32_t bits );
110+ static void check_flush (struct vcpu_t * vcpu , int cr , uint32_t bits );
111111static void vmwrite_efer (struct vcpu_t * vcpu );
112112
113113static int handle_msr_read (struct vcpu_t * vcpu , uint32_t msr , uint64_t * val );
@@ -1272,8 +1272,6 @@ void vcpu_save_host_state(struct vcpu_t *vcpu)
12721272 vmwrite (vcpu , HOST_IDTR_BASE , get_kernel_idtr_base ());
12731273
12741274 // Handle SYSENTER/SYSEXIT MSR
1275- vmwrite (vcpu , HOST_SYSENTER_CS , ia32_rdmsr (IA32_SYSENTER_CS ));
1276- vmwrite (vcpu , HOST_SYSENTER_EIP , ia32_rdmsr (IA32_SYSENTER_EIP ));
12771275 vmwrite (vcpu , HOST_SYSENTER_ESP , ia32_rdmsr (IA32_SYSENTER_ESP ));
12781276
12791277 // LDTR is unusable from spec, do we need ldt for host?
@@ -1414,6 +1412,9 @@ static void fill_common_vmcs(struct vcpu_t *vcpu)
14141412 vmwrite (vcpu , HOST_GDTR_BASE , get_kernel_gdtr_base ());
14151413 vmwrite (vcpu , HOST_IDTR_BASE , get_kernel_idtr_base ());
14161414
1415+ vmwrite (vcpu , HOST_SYSENTER_CS , ia32_rdmsr (IA32_SYSENTER_CS ));
1416+ vmwrite (vcpu , HOST_SYSENTER_EIP , ia32_rdmsr (IA32_SYSENTER_EIP ));
1417+
14171418 // The host RIP, used during VM-exit events, is only updated if HAXM
14181419 // is reloaded. Thus never changes during the lifetime of the VCPU.
14191420 vmwrite (vcpu , HOST_RIP , (mword )vmx_get_rip ());
@@ -1744,7 +1745,7 @@ int vtlb_active(struct vcpu_t *vcpu)
17441745static void advance_rip (struct vcpu_t * vcpu )
17451746{
17461747 struct vcpu_state_t * state = vcpu -> state ;
1747- uint32_t interruptibility = vmx (vcpu , interruptibility_state ). raw ;
1748+ uint32_t interruptibility = vmcs_read (vcpu , GUEST_INTERRUPTIBILITY ) ;
17481749
17491750 if (interruptibility & 3u ) {
17501751 interruptibility &= ~3u ;
@@ -2320,6 +2321,8 @@ static void vcpu_init_emulator(struct vcpu_t *vcpu)
23202321static int exit_exc_nmi (struct vcpu_t * vcpu , struct hax_tunnel * htun )
23212322{
23222323 struct vcpu_state_t * state = vcpu -> state ;
2324+ exit_qualification_t qual = { .raw =
2325+ vmcs_read (vcpu , VM_EXIT_INFO_QUALIFICATION ) };
23232326 interruption_info_t exit_intr_info ;
23242327
23252328 exit_intr_info .raw = vmcs_read (vcpu , VM_EXIT_INFO_INTERRUPT_INFO );
@@ -2333,7 +2336,7 @@ static int exit_exc_nmi(struct vcpu_t *vcpu, struct hax_tunnel *htun)
23332336 }
23342337 case VECTOR_PF : {
23352338 if (vtlb_active (vcpu )) {
2336- if (handle_vtlb (vcpu ))
2339+ if (handle_vtlb (vcpu , qual . address ))
23372340 return HAX_RESUME ;
23382341
23392342 return vcpu_emulate_insn (vcpu );
@@ -2358,7 +2361,7 @@ static int exit_exc_nmi(struct vcpu_t *vcpu, struct hax_tunnel *htun)
23582361 case VECTOR_DB : {
23592362 htun -> _exit_status = HAX_EXIT_DEBUG ;
23602363 htun -> debug .rip = vcpu_get_rip (vcpu );
2361- htun -> debug .dr6 = vmx ( vcpu , exit_qualification ) .raw ;
2364+ htun -> debug .dr6 = qual .raw ;
23622365 htun -> debug .dr7 = vmread (vcpu , GUEST_DR7 );
23632366 return HAX_EXIT ;
23642367 }
@@ -2372,7 +2375,7 @@ static int exit_exc_nmi(struct vcpu_t *vcpu, struct hax_tunnel *htun)
23722375 }
23732376
23742377 if (exit_intr_info .vector == VECTOR_PF ) {
2375- state -> _cr2 = vmx ( vcpu , exit_qualification .address ) ;
2378+ state -> _cr2 = qual .address ;
23762379 }
23772380
23782381 return HAX_RESUME ;
@@ -2738,8 +2741,11 @@ static int exit_hlt(struct vcpu_t *vcpu, struct hax_tunnel *htun)
27382741
27392742static int exit_invlpg (struct vcpu_t * vcpu , struct hax_tunnel * htun )
27402743{
2744+ exit_qualification_t qual = { .raw =
2745+ vmcs_read (vcpu , VM_EXIT_INFO_QUALIFICATION ) };
2746+
27412747 advance_rip (vcpu );
2742- vcpu_invalidate_tlb_addr (vcpu , vmx ( vcpu , exit_qualification ) .address );
2748+ vcpu_invalidate_tlb_addr (vcpu , qual .address );
27432749 htun -> _exit_reason = vmx (vcpu , exit_reason ).basic_reason ;
27442750 return HAX_RESUME ;
27452751}
@@ -2750,9 +2756,9 @@ static int exit_rdtsc(struct vcpu_t *vcpu, struct hax_tunnel *htun)
27502756 return HAX_RESUME ;
27512757}
27522758
2753- static void check_flush (struct vcpu_t * vcpu , uint32_t bits )
2759+ static void check_flush (struct vcpu_t * vcpu , int cr , uint32_t bits )
27542760{
2755- switch (vmx ( vcpu , exit_qualification ). cr . creg ) {
2761+ switch (cr ) {
27562762 case 0 : {
27572763 if (bits & (CR0_PE | CR0_PG )) {
27582764 vcpu_invalidate_tlb (vcpu , 1 );
@@ -2783,18 +2789,20 @@ static int exit_cr_access(struct vcpu_t *vcpu, struct hax_tunnel *htun)
27832789 uint64_t cr_ptr ;
27842790 int cr ;
27852791 struct vcpu_state_t * state = vcpu -> state ;
2792+ exit_qualification_t qual = { .raw =
2793+ vmcs_read (vcpu , VM_EXIT_INFO_QUALIFICATION ) };
27862794 bool is_ept_pae = false;
27872795 preempt_flag flags ;
27882796 uint32_t vmcs_err = 0 ;
27892797
27902798 htun -> _exit_reason = vmx (vcpu , exit_reason ).basic_reason ;
27912799
2792- cr = vmx ( vcpu , exit_qualification ) .cr .creg ;
2800+ cr = qual .cr .creg ;
27932801 cr_ptr = vcpu_read_cr (state , cr );
27942802
2795- switch (vmx ( vcpu , exit_qualification ) .cr .type ) {
2803+ switch (qual .cr .type ) {
27962804 case 0 : { // MOV CR <- GPR
2797- uint64_t val = state -> _regs [( vmx ( vcpu , exit_qualification ) .cr .gpr ) ];
2805+ uint64_t val = state -> _regs [qual .cr .gpr ];
27982806
27992807 hax_debug ("cr_access W CR%d: %08llx -> %08llx\n" , cr , cr_ptr , val );
28002808 if (cr == 0 ) {
@@ -2859,7 +2867,7 @@ static int exit_cr_access(struct vcpu_t *vcpu, struct hax_tunnel *htun)
28592867 hax_error ("Unsupported CR%d access\n" , cr );
28602868 break ;
28612869 }
2862- check_flush (vcpu , cr_ptr ^ val );
2870+ check_flush (vcpu , cr , cr_ptr ^ val );
28632871 vcpu_write_cr (state , cr , val );
28642872
28652873 if (is_ept_pae ) {
@@ -2899,7 +2907,7 @@ static int exit_cr_access(struct vcpu_t *vcpu, struct hax_tunnel *htun)
28992907 case 1 : { // MOV CR -> GPR
29002908 hax_info ("cr_access R CR%d\n" , cr );
29012909
2902- state -> _regs [vmx ( vcpu , exit_qualification ) .cr .gpr ] = cr_ptr ;
2910+ state -> _regs [qual .cr .gpr ] = cr_ptr ;
29032911 if (cr == 8 ) {
29042912 hax_info ("Unsupported CR%d access\n" , cr );
29052913 break ;
@@ -2926,7 +2934,7 @@ static int exit_cr_access(struct vcpu_t *vcpu, struct hax_tunnel *htun)
29262934 case 3 : { // LMSW
29272935 hax_info ("LMSW\n" );
29282936 state -> _cr0 = (state -> _cr0 & ~0xfULL ) |
2929- (vmx ( vcpu , exit_qualification ) .cr .lmsw_source & 0xf );
2937+ (qual .cr .lmsw_source & 0xf );
29302938 if ((vmcs_err = load_vmcs (vcpu , & flags ))) {
29312939 hax_panic_vcpu (vcpu , "load_vmcs failed while LMSW %x\n" ,
29322940 vmcs_err );
@@ -2954,8 +2962,10 @@ static int exit_cr_access(struct vcpu_t *vcpu, struct hax_tunnel *htun)
29542962static int exit_dr_access (struct vcpu_t * vcpu , struct hax_tunnel * htun )
29552963{
29562964 uint64_t * dr = NULL ;
2957- int dreg = vmx (vcpu , exit_qualification .dr .dreg );
2958- int gpr_reg = vmx (vcpu , exit_qualification ).dr .gpr ;
2965+ exit_qualification_t qual = { .raw =
2966+ vmcs_read (vcpu , VM_EXIT_INFO_QUALIFICATION ) };
2967+ int dreg = qual .dr .dreg ;
2968+ int gpr_reg = qual .dr .gpr ;
29592969 bool hbreak_enabled = !!(vcpu -> debug_control & HAX_DEBUG_USE_HW_BP );
29602970 struct vcpu_state_t * state = vcpu -> state ;
29612971
@@ -3017,7 +3027,7 @@ static int exit_dr_access(struct vcpu_t *vcpu, struct hax_tunnel *htun)
30173027 }
30183028 }
30193029
3020- if (vmx ( vcpu , exit_qualification .dr .direction ) ) {
3030+ if (qual .dr .direction ) {
30213031 // MOV DR -> GPR
30223032 if (hbreak_enabled ) {
30233033 // HAX hardware breakpoint enabled, return dr default value
@@ -3046,7 +3056,7 @@ static int exit_dr_access(struct vcpu_t *vcpu, struct hax_tunnel *htun)
30463056 return HAX_RESUME ;
30473057}
30483058
3049- static int handle_string_io (struct vcpu_t * vcpu , exit_qualification_t * qual ,
3059+ static int handle_string_io (struct vcpu_t * vcpu , exit_qualification_t qual ,
30503060 struct hax_tunnel * htun )
30513061{
30523062 struct vcpu_state_t * state = vcpu -> state ;
@@ -3058,7 +3068,7 @@ static int handle_string_io(struct vcpu_t *vcpu, exit_qualification_t *qual,
30583068 // 1 indicates string I/O (i.e. OUTS or INS)
30593069 htun -> io ._flags = 1 ;
30603070
3061- count = qual -> io .rep ? state -> _rcx : 1 ;
3071+ count = qual . io .rep ? state -> _rcx : 1 ;
30623072 elem_size = htun -> io ._size ;
30633073 total_size = count * elem_size ;
30643074
@@ -3086,7 +3096,7 @@ static int handle_string_io(struct vcpu_t *vcpu, exit_qualification_t *qual,
30863096 // For INS (see handle_io_post())
30873097 htun -> io ._vaddr = start_gva ;
30883098
3089- if (qual -> io .direction == HAX_IO_OUT ) {
3099+ if (qual . io .direction == HAX_IO_OUT ) {
30903100 if (!vcpu_read_guest_virtual (vcpu , start_gva , vcpu -> io_buf ,
30913101 IOS_MAX_BUFFER , copy_size , 0 )) {
30923102 hax_panic_vcpu (vcpu , "%s: vcpu_read_guest_virtual() failed,"
@@ -3103,13 +3113,13 @@ static int handle_string_io(struct vcpu_t *vcpu, exit_qualification_t *qual,
31033113 }
31043114
31053115 if (rflags & EFLAGS_DF ) {
3106- if (qual -> io .direction == HAX_IO_OUT ) {
3116+ if (qual . io .direction == HAX_IO_OUT ) {
31073117 state -> _rsi -= copy_size ;
31083118 } else {
31093119 state -> _rdi -= copy_size ;
31103120 }
31113121 } else {
3112- if (qual -> io .direction == HAX_IO_OUT ) {
3122+ if (qual . io .direction == HAX_IO_OUT ) {
31133123 state -> _rsi += copy_size ;
31143124 } else {
31153125 state -> _rdi += copy_size ;
@@ -3120,15 +3130,15 @@ static int handle_string_io(struct vcpu_t *vcpu, exit_qualification_t *qual,
31203130 return HAX_EXIT ;
31213131}
31223132
3123- static int handle_io (struct vcpu_t * vcpu , exit_qualification_t * qual ,
3133+ static int handle_io (struct vcpu_t * vcpu , exit_qualification_t qual ,
31243134 struct hax_tunnel * htun )
31253135{
31263136 struct vcpu_state_t * state = vcpu -> state ;
31273137 htun -> io ._count = 1 ;
31283138 htun -> io ._flags = 0 ;
31293139
3130- if (qual -> io .direction == HAX_IO_OUT ) {
3131- switch (qual -> io .size + 1 ) {
3140+ if (qual . io .direction == HAX_IO_OUT ) {
3141+ switch (qual . io .size + 1 ) {
31323142 case 1 : {
31333143 * ((uint8_t * )vcpu -> io_buf ) = state -> _al ;
31343144 break ;
@@ -3154,7 +3164,8 @@ static int handle_io(struct vcpu_t *vcpu, exit_qualification_t *qual,
31543164static int exit_io_access (struct vcpu_t * vcpu , struct hax_tunnel * htun )
31553165{
31563166 struct vcpu_state_t * state = vcpu -> state ;
3157- exit_qualification_t * qual = & vmx (vcpu , exit_qualification );
3167+ exit_qualification_t qual = { .raw =
3168+ vmcs_read (vcpu , VM_EXIT_INFO_QUALIFICATION ) };
31583169
31593170 htun -> _exit_reason = vmx (vcpu , exit_reason ).basic_reason ;
31603171
@@ -3165,14 +3176,14 @@ static int exit_io_access(struct vcpu_t *vcpu, struct hax_tunnel *htun)
31653176 htun -> io ._size = 0 ;
31663177 htun -> io ._count = 0 ;
31673178
3168- htun -> io ._port = qual -> io .encoding ? qual -> io .port : state -> _dx ;
3169- htun -> io ._size = qual -> io .size + 1 ;
3170- htun -> io ._direction = qual -> io .direction ;
3179+ htun -> io ._port = qual . io .encoding ? qual . io .port : state -> _dx ;
3180+ htun -> io ._size = qual . io .size + 1 ;
3181+ htun -> io ._direction = qual . io .direction ;
31713182
31723183 hax_debug ("exit_io_access port %x, size %d\n" , htun -> io ._port ,
31733184 htun -> io ._size );
31743185
3175- if (qual -> io .string )
3186+ if (qual . io .string )
31763187 return handle_string_io (vcpu , qual , htun );
31773188
31783189 return handle_io (vcpu , qual , htun );
@@ -3700,7 +3711,8 @@ static int exit_ept_misconfiguration(struct vcpu_t *vcpu,
37003711
37013712static int exit_ept_violation (struct vcpu_t * vcpu , struct hax_tunnel * htun )
37023713{
3703- exit_qualification_t * qual = & vmx (vcpu , exit_qualification );
3714+ exit_qualification_t qual = { .raw =
3715+ vmcs_read (vcpu , VM_EXIT_INFO_QUALIFICATION ) };
37043716 hax_paddr_t gpa ;
37053717 int ret = 0 ;
37063718#ifdef CONFIG_HAX_EPT2
@@ -3709,7 +3721,7 @@ static int exit_ept_violation(struct vcpu_t *vcpu, struct hax_tunnel *htun)
37093721
37103722 htun -> _exit_reason = vmx (vcpu , exit_reason ).basic_reason ;
37113723
3712- if (qual -> ept .gla1 == 0 && qual -> ept .gla2 == 1 ) {
3724+ if (qual . ept .gla1 == 0 && qual . ept .gla2 == 1 ) {
37133725 hax_panic_vcpu (vcpu , "Incorrect EPT seting\n" );
37143726 dump_vmcs (vcpu );
37153727 return HAX_RESUME ;
@@ -3719,12 +3731,12 @@ static int exit_ept_violation(struct vcpu_t *vcpu, struct hax_tunnel *htun)
37193731
37203732#ifdef CONFIG_HAX_EPT2
37213733 ret = ept_handle_access_violation (& vcpu -> vm -> gpa_space , & vcpu -> vm -> ept_tree ,
3722- * qual , gpa , & fault_gfn );
3734+ qual , gpa , & fault_gfn );
37233735 if (ret == - EFAULT ) {
37243736 // Extract bits 5..0 from Exit Qualification. They indicate the type of
37253737 // the faulting access (HAX_PAGEFAULT_ACC_R/W/X) and the types of access
37263738 // allowed (HAX_PAGEFAULT_PERM_R/W/X).
3727- htun -> pagefault .flags = qual -> raw & 0x3f ;
3739+ htun -> pagefault .flags = qual . raw & 0x3f ;
37283740 htun -> pagefault .gpa = fault_gfn << PG_ORDER_4K ;
37293741 htun -> pagefault .reserved1 = 0 ;
37303742 htun -> pagefault .reserved2 = 0 ;
0 commit comments