Commit 7c5b95a2 authored by Yu Zhang's avatar Yu Zhang
Browse files

KVM: x86/mmu: Introduce the on_unlock hook to flush the cache for SEV

Intel inclusion
category: feature
bugzilla: https://gitee.com/openeuler/intel-kernel/issues/I7S3VQ


CVE: NA

----------------------------------------------------------------------

Add on_unlock in struct kvm_hva_range, which is initialized to
kvm_arch_guest_memory_reclaimed(), so that the CPU caches can be
flushed when memory is reclaimed from an SEV guest.

This is done in upstreaming commit 683412cc ("KVM: SEV: add cache
flush to solve SEV cache incoherency issues"), and backported into
openEuler without using the on_unlock hook in commit 5e0a0560,
supposedly due to the lack of a group of MMU notifier consolidation
and optimization patches - especially upstreaming commit f922bd9b
("KVM: Move MMU notifier's mmu_lock acquisition into common helper"),
and commit 8931a454 ("KVM: Take mmu_lock when handling MMU notifier
iff the hva hits a memslot").

With these 2 patches backported, we cook this seperate patch to align
with upstreaming methods to flush cache when page is reclaimed for SEV
guests.

Signed-off-by: default avatarYu Zhang <yu.c.zhang@linux.intel.com>
parent dea4c3b2
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -516,12 +516,15 @@ typedef bool (*hva_handler_t)(struct kvm *kvm, struct kvm_gfn_range *range);
typedef void (*on_lock_fn_t)(struct kvm *kvm, unsigned long start,
			     unsigned long end);

typedef void (*on_unlock_fn_t)(struct kvm *kvm);

struct kvm_hva_range {
	unsigned long start;
	unsigned long end;
	pte_t pte;
	hva_handler_t handler;
	on_lock_fn_t on_lock;
	on_unlock_fn_t on_unlock;
	bool flush_on_ret;
	bool may_block;
};
@@ -606,8 +609,12 @@ static __always_inline int __kvm_handle_hva_range(struct kvm *kvm,
		kvm_flush_remote_tlbs(kvm);

out_unlock:
	if (locked)
	if (locked) {
		KVM_MMU_UNLOCK(kvm);
		if (!IS_KVM_NULL_FN(range->on_unlock))
			range->on_unlock(kvm);

	}

	srcu_read_unlock(&kvm->srcu, idx);

@@ -628,6 +635,7 @@ static __always_inline int kvm_handle_hva_range(struct mmu_notifier *mn,
		.pte		= pte,
		.handler	= handler,
		.on_lock	= (void *)kvm_null_fn,
		.on_unlock      = (void *)kvm_null_fn,
		.flush_on_ret	= true,
		.may_block	= false,
	};
@@ -647,6 +655,7 @@ static __always_inline int kvm_handle_hva_range_no_flush(struct mmu_notifier *mn
		.pte		= __pte(0),
		.handler	= handler,
		.on_lock	= (void *)kvm_null_fn,
		.on_unlock      = (void *)kvm_null_fn,
		.flush_on_ret	= false,
		.may_block	= false,
	};
@@ -724,6 +733,7 @@ static int kvm_mmu_notifier_invalidate_range_start(struct mmu_notifier *mn,
		.pte		= __pte(0),
		.handler	= kvm_unmap_gfn_range,
		.on_lock	= kvm_inc_notifier_count,
		.on_unlock      = kvm_arch_guest_memory_reclaimed,
		.flush_on_ret	= true,
		.may_block	= mmu_notifier_range_blockable(range),
	};