lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220617195141.2866706-1-pgonda@google.com>
Date:   Fri, 17 Jun 2022 12:51:41 -0700
From:   Peter Gonda <pgonda@...gle.com>
To:     kvm@...r.kernel.org
Cc:     Peter Gonda <pgonda@...gle.com>, Marc Orr <marcorr@...gle.com>,
        Paolo Bonzini <pbonzini@...hat.com>,
        Sean Christopherson <seanjc@...gle.com>,
        Tom Lendacky <thomas.lendacky@....com>,
        linux-kernel@...r.kernel.org
Subject: [PATCH] KVM: SEV: Init target VMCBs in sev_migrate_from

The target VMCBs during an intra-host migration need to correctly setup
for running SEV and SEV-ES guests. Use the sev_es_init_vmcb() to setup
the sev-es VMCBs and refactor out a new sev_init_vmcb() function to
handle SEV only migrations.

Fixes: 0b020f5af092 ("KVM: SEV: Add support for SEV-ES intra host migration")
Fixes: b56639318bb2 ("KVM: SEV: Add support for SEV intra host migration")

Signed-off-by: Peter Gonda <pgonda@...gle.com>
Cc: Marc Orr <marcorr@...gle.com>
Cc: Paolo Bonzini <pbonzini@...hat.com>
Cc: Sean Christopherson <seanjc@...gle.com>
Cc: Tom Lendacky <thomas.lendacky@....com>
Cc: kvm@...r.kernel.org
Cc: linux-kernel@...r.kernel.org

---

I had tested this with the selftests and by backporting patches to our
kernel fork and running on our Vanadium VMM internally. Doing that however
I dropped the requirement that SEV_INIT not be done on the target for
minimal changes to our VMM for testing. This lead to me missing this bug.

Tested by backporting back to our kernel fork and running our intra-host
migration test suite without SEV_INITing the target VM.

---
 arch/x86/kvm/svm/sev.c | 14 ++++++++++++++
 arch/x86/kvm/svm/svm.c |  3 +--
 arch/x86/kvm/svm/svm.h |  1 +
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 655770522471..d483f253fcf5 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -1666,6 +1666,8 @@ static void sev_migrate_from(struct kvm *dst_kvm, struct kvm *src_kvm)
 	struct kvm_sev_info *dst = &to_kvm_svm(dst_kvm)->sev_info;
 	struct kvm_sev_info *src = &to_kvm_svm(src_kvm)->sev_info;
 	struct kvm_sev_info *mirror;
+	struct kvm_vcpu *vcpu;
+	unsigned long i;
 
 	dst->active = true;
 	dst->asid = src->asid;
@@ -1681,6 +1683,10 @@ static void sev_migrate_from(struct kvm *dst_kvm, struct kvm *src_kvm)
 
 	list_cut_before(&dst->regions_list, &src->regions_list, &src->regions_list);
 
+	kvm_for_each_vcpu(i, vcpu, dst_kvm) {
+		sev_init_vmcb(to_svm(vcpu));
+	}
+
 	/*
 	 * If this VM has mirrors, "transfer" each mirror's refcount of the
 	 * source to the destination (this KVM).  The caller holds a reference
@@ -1739,6 +1745,8 @@ static int sev_es_migrate_from(struct kvm *dst, struct kvm *src)
 		src_svm->vmcb->control.ghcb_gpa = INVALID_PAGE;
 		src_svm->vmcb->control.vmsa_pa = INVALID_PAGE;
 		src_vcpu->arch.guest_state_protected = false;
+
+		sev_es_init_vmcb(dst_svm);
 	}
 	to_kvm_svm(src)->sev_info.es_active = false;
 	to_kvm_svm(dst)->sev_info.es_active = true;
@@ -2914,6 +2922,12 @@ int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in)
 				    count, in);
 }
 
+void sev_init_vmcb(struct vcpu_svm *svm)
+{
+	svm->vmcb->control.nested_ctl |= SVM_NESTED_CTL_SEV_ENABLE;
+	clr_exception_intercept(svm, UD_VECTOR);
+}
+
 void sev_es_init_vmcb(struct vcpu_svm *svm)
 {
 	struct kvm_vcpu *vcpu = &svm->vcpu;
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 12e792389e8b..9b9bbc228a69 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -1247,8 +1247,7 @@ static void init_vmcb(struct kvm_vcpu *vcpu)
 	}
 
 	if (sev_guest(vcpu->kvm)) {
-		svm->vmcb->control.nested_ctl |= SVM_NESTED_CTL_SEV_ENABLE;
-		clr_exception_intercept(svm, UD_VECTOR);
+		sev_init_vmcb(svm);
 
 		if (sev_es_guest(vcpu->kvm)) {
 			/* Perform SEV-ES specific VMCB updates */
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index cd92f4343753..33b6c6dd1a10 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -656,6 +656,7 @@ int sev_cpu_init(struct svm_cpu_data *sd);
 void sev_free_vcpu(struct kvm_vcpu *vcpu);
 int sev_handle_vmgexit(struct kvm_vcpu *vcpu);
 int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in);
+void sev_init_vmcb(struct vcpu_svm *svm);
 void sev_es_init_vmcb(struct vcpu_svm *svm);
 void sev_es_vcpu_reset(struct vcpu_svm *svm);
 void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector);
-- 
2.36.1.476.g0c4daa206d-goog

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ