Commit 459a38af authored by hanliyang's avatar hanliyang
Browse files

KVM: SVM: Force flush caches before reboot CSV guest

hygon inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I98WBH


CVE: NA

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

For memory encrypted guest, its pages' encrypt status will changed at
runtime. When user reboot the guest, the pages' encrypt status during
last boot were ignored. So during the boot flow of reboot, there may
be 2 versions of memory data lies in cache as follows:

                  +--------+        |              |
                  |        |        +--------------+  --+
                  |        |        |              |     \
                  |________|        |              |      \
cacheline for  -> |________| <-+    |              |       \
 pa1(c=0)         |        |    \   |______________|        \
                  |        |     \_ 64 bytes aligned <- pa1  \
                  |        |      _ |______________|           4K
                  |        |     /  |              |           page
cacheline for     |________|    /   |              |         /
 pa1(c=1)      -> |________| <-+    |              |        /
                  |        |        |              |       /
                  |        |        |              |      /
                  |        |        |              |     /
                  |        |        +--------------+  --+
                  |        |        |              |

If the older version cache was flushed after that of newer version, and
guest read the memory again, then it will get corrupted data and may
lead to crash.

In this change, for any memory encrypted guest, the cache is forcibly
flushed to memory before the next boot flow, which ensures that memory
access is up-to-date.

Signed-off-by: default avatarhanliyang <hanliyang@hygon.cn>
parent 8a2683e1
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -1028,12 +1028,15 @@ static int csv_control_post_system_reset(struct kvm *kvm)
	unsigned long i;
	int ret;

	if (!sev_es_guest(kvm))
	if (!sev_guest(kvm))
		return 0;

	/* Flush both host and guest caches of VMSA */
	/* Flush both host and guest caches before next boot flow */
	wbinvd_on_all_cpus();

	if (!sev_es_guest(kvm))
		return 0;

	kvm_for_each_vcpu(i, vcpu, kvm) {
		struct vcpu_svm *svm = to_svm(vcpu);