@@ -2921,8 +2921,23 @@ int vmx_check_processor_compat(void)
29212921 }
29222922 if (nested )
29232923 nested_vmx_setup_ctls_msrs (& vmcs_conf , vmx_cap .ept );
2924+
29242925 if (memcmp (& vmcs_config , & vmcs_conf , sizeof (struct vmcs_config ))) {
2925- pr_err ("Inconsistent VMCS config on CPU %d\n" , cpu );
2926+ u32 * gold = (void * )& vmcs_config ;
2927+ u32 * mine = (void * )& vmcs_conf ;
2928+ int i ;
2929+
2930+ BUILD_BUG_ON (sizeof (struct vmcs_config ) % sizeof (u32 ));
2931+
2932+ pr_err ("VMCS config on CPU %d doesn't match reference config:" , cpu );
2933+ for (i = 0 ; i < sizeof (struct vmcs_config ) / sizeof (u32 ); i ++ ) {
2934+ if (gold [i ] == mine [i ])
2935+ continue ;
2936+
2937+ pr_cont ("\n Offset %u REF = 0x%08x, CPU%u = 0x%08x, mismatch = 0x%08x" ,
2938+ i * (int )sizeof (u32 ), gold [i ], cpu , mine [i ], gold [i ] ^ mine [i ]);
2939+ }
2940+ pr_cont ("\n" );
29262941 return - EIO ;
29272942 }
29282943 return 0 ;
@@ -5303,12 +5318,53 @@ static bool is_xfd_nm_fault(struct kvm_vcpu *vcpu)
53035318 !kvm_is_cr0_bit_set (vcpu , X86_CR0_TS );
53045319}
53055320
5321+ static int vmx_handle_page_fault (struct kvm_vcpu * vcpu , u32 error_code )
5322+ {
5323+ unsigned long cr2 = vmx_get_exit_qual (vcpu );
5324+
5325+ if (vcpu -> arch .apf .host_apf_flags )
5326+ goto handle_pf ;
5327+
5328+ /* When using EPT, KVM intercepts #PF only to detect illegal GPAs. */
5329+ WARN_ON_ONCE (enable_ept && !allow_smaller_maxphyaddr );
5330+
5331+ /*
5332+ * On SGX2 hardware, EPCM violations are delivered as #PF with the SGX
5333+ * flag set in the error code (SGX1 hardware generates #GP(0)). EPCM
5334+ * violations have nothing to do with shadow paging and can never be
5335+ * resolved by KVM; always reflect them into the guest.
5336+ */
5337+ if (error_code & PFERR_SGX_MASK ) {
5338+ WARN_ON_ONCE (!IS_ENABLED (CONFIG_X86_SGX_KVM ) ||
5339+ !cpu_feature_enabled (X86_FEATURE_SGX2 ));
5340+
5341+ if (guest_cpu_cap_has (vcpu , X86_FEATURE_SGX2 ))
5342+ kvm_fixup_and_inject_pf_error (vcpu , cr2 , error_code );
5343+ else
5344+ kvm_inject_gp (vcpu , 0 );
5345+ return 1 ;
5346+ }
5347+
5348+ /*
5349+ * If EPT is enabled, fixup and inject the #PF. KVM intercepts #PFs
5350+ * only to set PFERR_RSVD as appropriate (hardware won't set RSVD due
5351+ * to the GPA being legal with respect to host.MAXPHYADDR).
5352+ */
5353+ if (enable_ept ) {
5354+ kvm_fixup_and_inject_pf_error (vcpu , cr2 , error_code );
5355+ return 1 ;
5356+ }
5357+
5358+ handle_pf :
5359+ return kvm_handle_page_fault (vcpu , error_code , cr2 , NULL , 0 );
5360+ }
5361+
53065362static int handle_exception_nmi (struct kvm_vcpu * vcpu )
53075363{
53085364 struct vcpu_vmx * vmx = to_vmx (vcpu );
53095365 struct kvm_run * kvm_run = vcpu -> run ;
53105366 u32 intr_info , ex_no , error_code ;
5311- unsigned long cr2 , dr6 ;
5367+ unsigned long dr6 ;
53125368 u32 vect_info ;
53135369
53145370 vect_info = vmx -> idt_vectoring_info ;
@@ -5383,19 +5439,8 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu)
53835439 return 0 ;
53845440 }
53855441
5386- if (is_page_fault (intr_info )) {
5387- cr2 = vmx_get_exit_qual (vcpu );
5388- if (enable_ept && !vcpu -> arch .apf .host_apf_flags ) {
5389- /*
5390- * EPT will cause page fault only if we need to
5391- * detect illegal GPAs.
5392- */
5393- WARN_ON_ONCE (!allow_smaller_maxphyaddr );
5394- kvm_fixup_and_inject_pf_error (vcpu , cr2 , error_code );
5395- return 1 ;
5396- } else
5397- return kvm_handle_page_fault (vcpu , error_code , cr2 , NULL , 0 );
5398- }
5442+ if (is_page_fault (intr_info ))
5443+ return vmx_handle_page_fault (vcpu , error_code );
53995444
54005445 ex_no = intr_info & INTR_INFO_VECTOR_MASK ;
54015446
@@ -8672,16 +8717,14 @@ __init int vmx_hardware_setup(void)
86728717 * can hide/show features based on kvm_cpu_cap_has().
86738718 */
86748719 if (nested ) {
8675- nested_vmx_setup_ctls_msrs (& vmcs_config , vmx_capability .ept );
8676-
86778720 r = nested_vmx_hardware_setup (kvm_vmx_exit_handlers );
86788721 if (r )
86798722 return r ;
86808723 }
86818724
86828725 r = alloc_kvm_area ();
8683- if (r && nested )
8684- nested_vmx_hardware_unsetup () ;
8726+ if (r )
8727+ goto err_kvm_area ;
86858728
86868729 kvm_set_posted_intr_wakeup_handler (pi_wakeup_handler );
86878730
@@ -8708,6 +8751,11 @@ __init int vmx_hardware_setup(void)
87088751
87098752 kvm_caps .inapplicable_quirks &= ~KVM_X86_QUIRK_IGNORE_GUEST_PAT ;
87108753
8754+ return 0 ;
8755+
8756+ err_kvm_area :
8757+ if (nested )
8758+ nested_vmx_hardware_unsetup ();
87118759 return r ;
87128760}
87138761
0 commit comments