@@ -194,7 +194,7 @@ static uint64_t vcpu_read_cr(struct vcpu_state_t *state, uint32_t n)
194194 break ;
195195 }
196196 default : {
197- hax_error ( "Unsupported CR%d access \n" , n );
197+ hax_warning ( "Ignored unsupported CR%d read, returning 0 \n" , n );
198198 break ;
199199 }
200200 }
@@ -1324,7 +1324,7 @@ static void fill_common_vmcs(struct vcpu_t *vcpu)
13241324
13251325 pcpu_ctls = IO_BITMAP_ACTIVE | MSR_BITMAP_ACTIVE | DR_EXITING |
13261326 INTERRUPT_WINDOW_EXITING | USE_TSC_OFFSETTING | HLT_EXITING |
1327- SECONDARY_CONTROLS ;
1327+ CR8_LOAD_EXITING | CR8_STORE_EXITING | SECONDARY_CONTROLS ;
13281328
13291329 scpu_ctls = ENABLE_EPT ;
13301330
@@ -2778,7 +2778,6 @@ static void check_flush(struct vcpu_t *vcpu, uint32_t bits)
27782778
27792779static int exit_cr_access (struct vcpu_t * vcpu , struct hax_tunnel * htun )
27802780{
2781- uint64_t cr_ptr ;
27822781 int cr ;
27832782 struct vcpu_state_t * state = vcpu -> state ;
27842783 bool is_ept_pae = false;
@@ -2788,19 +2787,25 @@ static int exit_cr_access(struct vcpu_t *vcpu, struct hax_tunnel *htun)
27882787 htun -> _exit_reason = vmx (vcpu , exit_reason ).basic_reason ;
27892788
27902789 cr = vmx (vcpu , exit_qualification ).cr .creg ;
2791- cr_ptr = vcpu_read_cr (state , cr );
27922790
27932791 switch (vmx (vcpu , exit_qualification ).cr .type ) {
27942792 case 0 : { // MOV CR <- GPR
27952793 uint64_t val = state -> _regs [(vmx (vcpu , exit_qualification ).cr .gpr )];
2794+ uint64_t old_val = 0 ;
27962795
2797- hax_debug ("cr_access W CR%d: %08llx -> %08llx\n" , cr , cr_ptr , val );
2796+ if (cr == 8 ) {
2797+ // TODO: Redirect CR8 write to user space (emulated APIC.TPR)
2798+ hax_warning ("Ignored guest CR8 write, val=0x%llx\n" , val );
2799+ break ;
2800+ }
2801+
2802+ old_val = vcpu_read_cr (state , cr );
27982803 if (cr == 0 ) {
27992804 uint64_t cr0_pae_triggers ;
28002805
28012806 hax_info ("Guest writing to CR0[%u]: 0x%llx -> 0x%llx,"
28022807 " _cr4=0x%llx, _efer=0x%x\n" , vcpu -> vcpu_id ,
2803- state -> _cr0 , val , state -> _cr4 , state -> _efer );
2808+ old_val , val , state -> _cr4 , state -> _efer );
28042809 if ((val & CR0_PG ) && !(val & CR0_PE )) {
28052810 hax_inject_exception (vcpu , VECTOR_GP , 0 );
28062811 return HAX_RESUME ;
@@ -2812,7 +2817,7 @@ static int exit_cr_access(struct vcpu_t *vcpu, struct hax_tunnel *htun)
28122817 return HAX_RESUME ;
28132818 }
28142819 }
2815- if (!hax -> ug_enable_flag && (cr_ptr & CR0_PE ) &&
2820+ if (!hax -> ug_enable_flag && (old_val & CR0_PE ) &&
28162821 !(val & CR0_PE )) {
28172822 htun -> _exit_status = HAX_EXIT_REALMODE ;
28182823 hax_debug ("Enter NON-PE from PE\n" );
@@ -2823,19 +2828,17 @@ static int exit_cr_access(struct vcpu_t *vcpu, struct hax_tunnel *htun)
28232828 cr0_pae_triggers = CR0_CD | CR0_NW | CR0_PG ;
28242829 if ((val & CR0_PG ) && (state -> _cr4 & CR4_PAE ) &&
28252830 !(state -> _efer & IA32_EFER_LME ) && !vtlb_active (vcpu ) &&
2826- ((val ^ cr_ptr ) & cr0_pae_triggers )) {
2831+ ((val ^ old_val ) & cr0_pae_triggers )) {
28272832 hax_info ("%s: vCPU #%u triggers PDPT (re)load for EPT+PAE"
28282833 " mode (CR0 path)\n" , __func__ , vcpu -> vcpu_id );
28292834 is_ept_pae = true;
28302835 }
2831- }
2832-
2833- if (cr == 4 ) {
2836+ } else if (cr == 4 ) {
28342837 uint64_t cr4_pae_triggers ;
28352838
28362839 hax_info ("Guest writing to CR4[%u]: 0x%llx -> 0x%llx,"
28372840 "_cr0=0x%llx, _efer=0x%x\n" , vcpu -> vcpu_id ,
2838- state -> _cr4 , val , state -> _cr0 , state -> _efer );
2841+ old_val , val , state -> _cr0 , state -> _efer );
28392842 if ((state -> _efer & IA32_EFER_LMA ) && !(val & CR4_PAE )) {
28402843 hax_inject_exception (vcpu , VECTOR_GP , 0 );
28412844 return HAX_RESUME ;
@@ -2846,18 +2849,16 @@ static int exit_cr_access(struct vcpu_t *vcpu, struct hax_tunnel *htun)
28462849 cr4_pae_triggers = CR4_PAE | CR4_PGE | CR4_PSE ;
28472850 if ((val & CR4_PAE ) && (state -> _cr0 & CR0_PG ) &&
28482851 !(state -> _efer & IA32_EFER_LME ) && !vtlb_active (vcpu ) &&
2849- ((val ^ cr_ptr ) & cr4_pae_triggers )) {
2852+ ((val ^ old_val ) & cr4_pae_triggers )) {
28502853 hax_info ("%s: vCPU #%u triggers PDPT (re)load for EPT+PAE"
28512854 " mode (CR4 path)\n" , __func__ , vcpu -> vcpu_id );
28522855 is_ept_pae = true;
28532856 }
2854- }
2855-
2856- if (cr == 8 ) {
2857- hax_error ("Unsupported CR%d access\n" , cr );
2857+ } else {
2858+ hax_error ("Unsupported CR%d write, val=0x%llx\n" , cr , val );
28582859 break ;
28592860 }
2860- check_flush (vcpu , cr_ptr ^ val );
2861+ check_flush (vcpu , old_val ^ val );
28612862 vcpu_write_cr (state , cr , val );
28622863
28632864 if (is_ept_pae ) {
@@ -2895,13 +2896,13 @@ static int exit_cr_access(struct vcpu_t *vcpu, struct hax_tunnel *htun)
28952896 break ;
28962897 }
28972898 case 1 : { // MOV CR -> GPR
2899+ uint64_t val ;
2900+
28982901 hax_info ("cr_access R CR%d\n" , cr );
28992902
2900- state -> _regs [vmx (vcpu , exit_qualification ).cr .gpr ] = cr_ptr ;
2901- if (cr == 8 ) {
2902- hax_info ("Unsupported CR%d access\n" , cr );
2903- break ;
2904- }
2903+ val = vcpu_read_cr (state , cr );
2904+ // TODO: Redirect CR8 read to user space (emulated APIC.TPR)
2905+ state -> _regs [vmx (vcpu , exit_qualification ).cr .gpr ] = val ;
29052906 break ;
29062907 }
29072908 case 2 : { // CLTS
0 commit comments