@@ -3384,15 +3384,15 @@ static bool vmx_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
33843384
33853385void vmx_set_cr4 (struct kvm_vcpu * vcpu , unsigned long cr4 )
33863386{
3387- unsigned long old_cr4 = vcpu -> arch . cr4 ;
3387+ unsigned long old_cr4 = kvm_read_cr4 ( vcpu ) ;
33883388 struct vcpu_vmx * vmx = to_vmx (vcpu );
3389+ unsigned long hw_cr4 ;
3390+
33893391 /*
33903392 * Pass through host's Machine Check Enable value to hw_cr4, which
33913393 * is in force while we are in guest mode. Do not let guests control
33923394 * this bit, even if host CR4.MCE == 0.
33933395 */
3394- unsigned long hw_cr4 ;
3395-
33963396 hw_cr4 = (cr4_read_shadow () & X86_CR4_MCE ) | (cr4 & ~X86_CR4_MCE );
33973397 if (is_unrestricted_guest (vcpu ))
33983398 hw_cr4 |= KVM_VM_CR4_ALWAYS_ON_UNRESTRICTED_GUEST ;
@@ -3401,7 +3401,7 @@ void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
34013401 else
34023402 hw_cr4 |= KVM_PMODE_VM_CR4_ALWAYS_ON ;
34033403
3404- if (! boot_cpu_has ( X86_FEATURE_UMIP ) && vmx_umip_emulated ()) {
3404+ if (vmx_umip_emulated ()) {
34053405 if (cr4 & X86_CR4_UMIP ) {
34063406 secondary_exec_controls_setbit (vmx , SECONDARY_EXEC_DESC );
34073407 hw_cr4 &= ~X86_CR4_UMIP ;
@@ -5399,7 +5399,13 @@ static int handle_set_cr4(struct kvm_vcpu *vcpu, unsigned long val)
53995399
54005400static int handle_desc (struct kvm_vcpu * vcpu )
54015401{
5402- WARN_ON (!(vcpu -> arch .cr4 & X86_CR4_UMIP ));
5402+ /*
5403+ * UMIP emulation relies on intercepting writes to CR4.UMIP, i.e. this
5404+ * and other code needs to be updated if UMIP can be guest owned.
5405+ */
5406+ BUILD_BUG_ON (KVM_POSSIBLE_CR4_GUEST_BITS & X86_CR4_UMIP );
5407+
5408+ WARN_ON_ONCE (!kvm_is_cr4_bit_set (vcpu , X86_CR4_UMIP ));
54035409 return kvm_emulate_instruction (vcpu , 0 );
54045410}
54055411
@@ -6705,7 +6711,12 @@ void vmx_set_virtual_apic_mode(struct kvm_vcpu *vcpu)
67056711
67066712static void vmx_set_apic_access_page_addr (struct kvm_vcpu * vcpu )
67076713{
6708- struct page * page ;
6714+ const gfn_t gfn = APIC_DEFAULT_PHYS_BASE >> PAGE_SHIFT ;
6715+ struct kvm * kvm = vcpu -> kvm ;
6716+ struct kvm_memslots * slots = kvm_memslots (kvm );
6717+ struct kvm_memory_slot * slot ;
6718+ unsigned long mmu_seq ;
6719+ kvm_pfn_t pfn ;
67096720
67106721 /* Defer reload until vmcs01 is the current VMCS. */
67116722 if (is_guest_mode (vcpu )) {
@@ -6717,18 +6728,53 @@ static void vmx_set_apic_access_page_addr(struct kvm_vcpu *vcpu)
67176728 SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES ))
67186729 return ;
67196730
6720- page = gfn_to_page (vcpu -> kvm , APIC_DEFAULT_PHYS_BASE >> PAGE_SHIFT );
6721- if (is_error_page (page ))
6731+ /*
6732+ * Grab the memslot so that the hva lookup for the mmu_notifier retry
6733+ * is guaranteed to use the same memslot as the pfn lookup, i.e. rely
6734+ * on the pfn lookup's validation of the memslot to ensure a valid hva
6735+ * is used for the retry check.
6736+ */
6737+ slot = id_to_memslot (slots , APIC_ACCESS_PAGE_PRIVATE_MEMSLOT );
6738+ if (!slot || slot -> flags & KVM_MEMSLOT_INVALID )
67226739 return ;
67236740
6724- vmcs_write64 (APIC_ACCESS_ADDR , page_to_phys (page ));
6741+ /*
6742+ * Ensure that the mmu_notifier sequence count is read before KVM
6743+ * retrieves the pfn from the primary MMU. Note, the memslot is
6744+ * protected by SRCU, not the mmu_notifier. Pairs with the smp_wmb()
6745+ * in kvm_mmu_invalidate_end().
6746+ */
6747+ mmu_seq = kvm -> mmu_invalidate_seq ;
6748+ smp_rmb ();
6749+
6750+ /*
6751+ * No need to retry if the memslot does not exist or is invalid. KVM
6752+ * controls the APIC-access page memslot, and only deletes the memslot
6753+ * if APICv is permanently inhibited, i.e. the memslot won't reappear.
6754+ */
6755+ pfn = gfn_to_pfn_memslot (slot , gfn );
6756+ if (is_error_noslot_pfn (pfn ))
6757+ return ;
6758+
6759+ read_lock (& vcpu -> kvm -> mmu_lock );
6760+ if (mmu_invalidate_retry_hva (kvm , mmu_seq ,
6761+ gfn_to_hva_memslot (slot , gfn ))) {
6762+ kvm_make_request (KVM_REQ_APIC_PAGE_RELOAD , vcpu );
6763+ read_unlock (& vcpu -> kvm -> mmu_lock );
6764+ goto out ;
6765+ }
6766+
6767+ vmcs_write64 (APIC_ACCESS_ADDR , pfn_to_hpa (pfn ));
6768+ read_unlock (& vcpu -> kvm -> mmu_lock );
6769+
67256770 vmx_flush_tlb_current (vcpu );
67266771
6772+ out :
67276773 /*
67286774 * Do not pin apic access page in memory, the MMU notifier
67296775 * will call us again if it is migrated or swapped out.
67306776 */
6731- put_page ( page );
6777+ kvm_release_pfn_clean ( pfn );
67326778}
67336779
67346780static void vmx_hwapic_isr_update (int max_isr )
0 commit comments