Commit 5d816c13 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvm-x86-mmu-6.16' of https://github.com/kvm-x86/linux into HEAD

KVM x86 MMU changes for 6.16:

 - Refine and harden handling of spurious faults.

 - Use kvm_x86_call() instead of open coding static_call().
parents ebd38b26 6a3d7049
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -3020,7 +3020,8 @@ static int mmu_set_spte(struct kvm_vcpu *vcpu, struct kvm_memory_slot *slot,
	}

	if (is_shadow_present_pte(*sptep)) {
		if (prefetch)
		if (prefetch && is_last_spte(*sptep, level) &&
		    pfn == spte_to_pfn(*sptep))
			return RET_PF_SPURIOUS;

		/*
@@ -3034,7 +3035,7 @@ static int mmu_set_spte(struct kvm_vcpu *vcpu, struct kvm_memory_slot *slot,
			child = spte_to_child_sp(pte);
			drop_parent_pte(vcpu->kvm, child, sptep);
			flush = true;
		} else if (pfn != spte_to_pfn(*sptep)) {
		} else if (WARN_ON_ONCE(pfn != spte_to_pfn(*sptep))) {
			drop_spte(vcpu->kvm, sptep);
			flush = true;
		} else
+9 −10
Original line number Diff line number Diff line
@@ -378,7 +378,7 @@ static void remove_external_spte(struct kvm *kvm, gfn_t gfn, u64 old_spte,
	/* Zapping leaf spte is allowed only when write lock is held. */
	lockdep_assert_held_write(&kvm->mmu_lock);
	/* Because write lock is held, operation should success. */
	ret = static_call(kvm_x86_remove_external_spte)(kvm, gfn, level, old_pfn);
	ret = kvm_x86_call(remove_external_spte)(kvm, gfn, level, old_pfn);
	KVM_BUG_ON(ret, kvm);
}

@@ -485,7 +485,7 @@ static void handle_removed_pt(struct kvm *kvm, tdp_ptep_t pt, bool shared)
	}

	if (is_mirror_sp(sp) &&
	    WARN_ON(static_call(kvm_x86_free_external_spt)(kvm, base_gfn, sp->role.level,
	    WARN_ON(kvm_x86_call(free_external_spt)(kvm, base_gfn, sp->role.level,
						    sp->external_spt))) {
		/*
		 * Failed to free page table page in mirror page table and
@@ -538,12 +538,12 @@ static int __must_check set_external_spte_present(struct kvm *kvm, tdp_ptep_t sp
	 * external page table, or leaf.
	 */
	if (is_leaf) {
		ret = static_call(kvm_x86_set_external_spte)(kvm, gfn, level, new_pfn);
		ret = kvm_x86_call(set_external_spte)(kvm, gfn, level, new_pfn);
	} else {
		void *external_spt = get_external_spt(gfn, new_spte, level);

		KVM_BUG_ON(!external_spt, kvm);
		ret = static_call(kvm_x86_link_external_spt)(kvm, gfn, level, external_spt);
		ret = kvm_x86_call(link_external_spt)(kvm, gfn, level, external_spt);
	}
	if (ret)
		__kvm_tdp_mmu_write_spte(sptep, old_spte);
@@ -1153,13 +1153,12 @@ static int tdp_mmu_map_handle_target_level(struct kvm_vcpu *vcpu,
	if (WARN_ON_ONCE(sp->role.level != fault->goal_level))
		return RET_PF_RETRY;

	if (fault->prefetch && is_shadow_present_pte(iter->old_spte))
		return RET_PF_SPURIOUS;

	if (is_shadow_present_pte(iter->old_spte) &&
	    is_access_allowed(fault, iter->old_spte) &&
	    is_last_spte(iter->old_spte, iter->level))
	    (fault->prefetch || is_access_allowed(fault, iter->old_spte)) &&
	    is_last_spte(iter->old_spte, iter->level)) {
		WARN_ON_ONCE(fault->pfn != spte_to_pfn(iter->old_spte));
		return RET_PF_SPURIOUS;
	}

	if (unlikely(!fault->slot))
		new_spte = make_mmio_spte(vcpu, iter->gfn, ACC_ALL);