All of lore.kernel.org
 help / color / mirror / Atom feed
From: Brijesh Singh <brijesh.singh@amd.com>
To: kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: bp@alien8.de, "Brijesh Singh" <brijesh.singh@amd.com>,
	"Thomas Gleixner" <tglx@linutronix.de>,
	"Ingo Molnar" <mingo@redhat.com>,
	"H. Peter Anvin" <hpa@zytor.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"Radim Krčmář" <rkrcmar@redhat.com>,
	"Joerg Roedel" <joro@8bytes.org>, "Borislav Petkov" <bp@suse.de>,
	"Tom Lendacky" <thomas.lendacky@amd.com>,
	x86@kernel.org
Subject: [Part2 PATCH v8 27/38] KVM: SVM: Add support for KVM_SEV_LAUNCH_START command
Date: Mon,  6 Nov 2017 12:11:19 -0600	[thread overview]
Message-ID: <20171106181130.68491-28-brijesh.singh@amd.com> (raw)
In-Reply-To: <20171106181130.68491-1-brijesh.singh@amd.com>

The KVM_SEV_LAUNCH_START command is used to create a memory encryption
context within the SEV firmware. In order to do so, the guest owner
should provide the guest's policy, its public Diffie-Hellman (PDH) key
and session information. The command implements the LAUNCH_START flow
defined in SEV spec Section 6.2.

Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: "Radim Krčmář" <rkrcmar@redhat.com>
Cc: Joerg Roedel <joro@8bytes.org>
Cc: Borislav Petkov <bp@suse.de>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: x86@kernel.org
Cc: kvm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Improvements-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Reviewed-by: Borislav Petkov <bp@suse.de>
---
 arch/x86/include/asm/kvm_host.h |   2 +
 arch/x86/kvm/svm.c              | 153 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 155 insertions(+)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 1841fe960888..b58d9ebc2081 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -750,6 +750,8 @@ enum kvm_irqchip_mode {
 struct kvm_sev_info {
 	bool active;		/* SEV enabled guest */
 	unsigned int asid;	/* ASID used for this guest */
+	unsigned int handle;	/* SEV firmware handle */
+	int fd;			/* SEV device fd */
 };
 
 struct kvm_arch {
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 9d04cc8fbbf9..aa90a27976f6 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1508,11 +1508,45 @@ static void sev_asid_free(struct kvm *kvm)
 	__sev_asid_free(sev->asid);
 }
 
+static void sev_unbind_asid(struct kvm *kvm, unsigned int handle)
+{
+	struct sev_data_decommission *decommission;
+	struct sev_data_deactivate *data;
+
+	if (!handle)
+		return;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return;
+
+	/* deactivate handle */
+	data->handle = handle;
+	sev_guest_deactivate(data, NULL);
+
+	wbinvd_on_all_cpus();
+	sev_guest_df_flush(NULL);
+	kfree(data);
+
+	decommission = kzalloc(sizeof(*decommission), GFP_KERNEL);
+	if (!decommission)
+		return;
+
+	/* decommission handle */
+	decommission->handle = handle;
+	sev_guest_decommission(decommission, NULL);
+
+	kfree(decommission);
+}
+
 static void sev_vm_destroy(struct kvm *kvm)
 {
+	struct kvm_sev_info *sev = &kvm->arch.sev_info;
+
 	if (!sev_guest(kvm))
 		return;
 
+	sev_unbind_asid(kvm, sev->handle);
 	sev_asid_free(kvm);
 }
 
@@ -5668,6 +5702,122 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp)
 	return ret;
 }
 
+static int sev_bind_asid(struct kvm *kvm, unsigned int handle, int *error)
+{
+	struct sev_data_activate *data;
+	int asid = sev_get_asid(kvm);
+	int ret;
+
+	wbinvd_on_all_cpus();
+
+	ret = sev_guest_df_flush(error);
+	if (ret)
+		return ret;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	/* activate ASID on the given handle */
+	data->handle = handle;
+	data->asid   = asid;
+	ret = sev_guest_activate(data, error);
+	kfree(data);
+
+	return ret;
+}
+
+static int sev_issue_cmd(int fd, int id, void *data, int *error)
+{
+	struct fd f;
+	int ret;
+
+	f = fdget(fd);
+	if (!f.file)
+		return -EBADF;
+
+	ret = sev_issue_cmd_external_user(f.file, id, data, error);
+
+	fdput(f);
+	return ret;
+}
+
+static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
+{
+	struct kvm_sev_info *sev = &kvm->arch.sev_info;
+	struct sev_data_launch_start *start;
+	struct kvm_sev_launch_start params;
+	void *dh_blob, *session_blob;
+	int *error = &argp->error;
+	int ret;
+
+	if (!sev_guest(kvm))
+		return -ENOTTY;
+
+	if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data, sizeof(params)))
+		return -EFAULT;
+
+	start = kzalloc(sizeof(*start), GFP_KERNEL);
+	if (!start)
+		return -ENOMEM;
+
+	dh_blob = NULL;
+	if (params.dh_uaddr) {
+		dh_blob = psp_copy_user_blob(params.dh_uaddr, params.dh_len);
+		if (IS_ERR(dh_blob)) {
+			ret = PTR_ERR(dh_blob);
+			goto e_free;
+		}
+
+		start->dh_cert_address = __sme_set(__pa(dh_blob));
+		start->dh_cert_len = params.dh_len;
+	}
+
+	session_blob = NULL;
+	if (params.session_uaddr) {
+		session_blob = psp_copy_user_blob(params.session_uaddr, params.session_len);
+		if (IS_ERR(session_blob)) {
+			ret = PTR_ERR(session_blob);
+			goto e_free_dh;
+		}
+
+		start->session_address = __sme_set(__pa(session_blob));
+		start->session_len = params.session_len;
+	}
+
+	start->handle = params.handle;
+	start->policy = params.policy;
+
+	/* create memory encryption context */
+	ret = sev_issue_cmd(argp->sev_fd, SEV_CMD_LAUNCH_START, start, error);
+	if (ret)
+		goto e_free_session;
+
+	/* Bind ASID to this guest */
+	ret = sev_bind_asid(kvm, start->handle, error);
+	if (ret)
+		goto e_free_session;
+
+	/* return handle to userspace */
+	params.handle = start->handle;
+	if (copy_to_user((void __user *)(uintptr_t)argp->data, &params, sizeof(params))) {
+		sev_unbind_asid(kvm, start->handle);
+		ret = -EFAULT;
+		goto e_free_session;
+	}
+
+	sev->handle = start->handle;
+	sev->fd = argp->sev_fd;
+
+e_free_session:
+	kfree(session_blob);
+e_free_dh:
+	kfree(dh_blob);
+e_free:
+	kfree(start);
+	return ret;
+}
+
 static int svm_mem_enc_op(struct kvm *kvm, void __user *argp)
 {
 	struct kvm_sev_cmd sev_cmd;
@@ -5685,6 +5835,9 @@ static int svm_mem_enc_op(struct kvm *kvm, void __user *argp)
 	case KVM_SEV_INIT:
 		r = sev_guest_init(kvm, &sev_cmd);
 		break;
+	case KVM_SEV_LAUNCH_START:
+		r = sev_launch_start(kvm, &sev_cmd);
+		break;
 	default:
 		r = -EINVAL;
 		goto out;
-- 
2.9.5

  parent reply	other threads:[~2017-11-06 18:12 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-06 18:10 [Part2 PATCH v8 00/38] x86: Secure Encrypted Virtualization (AMD) Brijesh Singh
2017-11-06 18:10 ` [Part2 PATCH v8 01/38] Documentation/virtual/kvm: Add AMD Secure Encrypted Virtualization (SEV) Brijesh Singh
2017-11-06 18:10 ` [Part2 PATCH v8 02/38] x86/CPU/AMD: Add the Secure Encrypted Virtualization CPU feature Brijesh Singh
2017-11-06 18:10 ` [Part2 PATCH v8 03/38] kvm: svm: prepare for new bit definition in nested_ctl Brijesh Singh
2017-11-06 18:10 ` [Part2 PATCH v8 04/38] kvm: svm: Add SEV feature definitions to KVM Brijesh Singh
2017-11-06 18:10 ` [Part2 PATCH v8 05/38] KVM: SVM: Prepare to reserve asid for SEV guest Brijesh Singh
2017-11-06 18:10 ` [Part2 PATCH v8 06/38] KVM: X86: Extend CPUID range to include new leaf Brijesh Singh
2017-11-06 18:10 ` [Part2 PATCH v8 07/38] KVM: Introduce KVM_MEMORY_ENCRYPT_OP ioctl Brijesh Singh
2017-11-06 18:11 ` [Part2 PATCH v8 08/38] KVM: Introduce KVM_MEMORY_ENCRYPT_{UN,}REG_REGION ioctl Brijesh Singh
2017-11-06 18:11 ` [Part2 PATCH v8 09/38] crypto: ccp: Build the AMD secure processor driver only with AMD CPU support Brijesh Singh
2017-11-06 18:11 ` [Part2 PATCH v8 10/38] crypto: ccp: Define SEV userspace ioctl and command id Brijesh Singh
2017-11-06 18:11 ` [Part2 PATCH v8 11/38] crypto: ccp: Define SEV key management " Brijesh Singh
2017-11-06 18:11 ` [Part2 PATCH v8 12/38] crypto: ccp: Add Platform Security Processor (PSP) device support Brijesh Singh
2017-11-07 15:42   ` Gary R Hook
2017-11-06 18:11 ` [Part2 PATCH v8 13/38] crypto: ccp: Add Secure Encrypted Virtualization (SEV) command support Brijesh Singh
2017-11-07 15:47   ` Gary R Hook
2017-11-06 18:11 ` [Part2 PATCH v8 14/38] crypto: ccp: Implement SEV_FACTORY_RESET ioctl command Brijesh Singh
2017-11-07 15:47   ` Gary R Hook
2017-11-06 18:11 ` [Part2 PATCH v8 15/38] crypto: ccp: Implement SEV_PLATFORM_STATUS " Brijesh Singh
2017-11-06 18:11 ` [Part2 PATCH v8 16/38] crypto: ccp: Implement SEV_PEK_GEN " Brijesh Singh
2017-11-06 18:11 ` [Part2 PATCH v8 17/38] crypto: ccp: Implement SEV_PDH_GEN " Brijesh Singh
2017-11-06 18:11 ` [Part2 PATCH v8 18/38] crypto: ccp: Implement SEV_PEK_CSR " Brijesh Singh
2017-11-06 18:11 ` [Part2 PATCH v8 19/38] crypto: ccp: Implement SEV_PEK_CERT_IMPORT " Brijesh Singh
2017-11-06 18:11 ` [Part2 PATCH v8 20/38] crypto: ccp: Implement SEV_PDH_CERT_EXPORT " Brijesh Singh
2017-11-06 18:11 ` [Part2 PATCH v8 21/38] KVM: X86: Add CONFIG_KVM_AMD_SEV Brijesh Singh
2017-11-06 18:11 ` [Part2 PATCH v8 22/38] KVM: SVM: Reserve ASID range for SEV guest Brijesh Singh
2017-11-06 18:11 ` [Part2 PATCH v8 23/38] KVM: SVM: Add sev module_param Brijesh Singh
2017-11-06 18:11 ` [Part2 PATCH v8 24/38] KVM: Define SEV key management command id Brijesh Singh
2017-11-06 18:11 ` [Part2 PATCH v8 25/38] KVM: SVM: Add KVM_SEV_INIT command Brijesh Singh
2017-11-06 18:11 ` [Part2 PATCH v8 26/38] KVM: SVM: VMRUN should use associated ASID when SEV is enabled Brijesh Singh
2017-11-06 18:11 ` Brijesh Singh [this message]
2017-11-06 18:11 ` [Part2 PATCH v8 28/38] KVM: SVM: Add support for KVM_SEV_LAUNCH_UPDATE_DATA command Brijesh Singh
2017-11-06 18:11 ` [Part2 PATCH v8 29/38] KVM: SVM: Add support for KVM_SEV_LAUNCH_MEASURE command Brijesh Singh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171106181130.68491-28-brijesh.singh@amd.com \
    --to=brijesh.singh@amd.com \
    --cc=bp@alien8.de \
    --cc=bp@suse.de \
    --cc=hpa@zytor.com \
    --cc=joro@8bytes.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=rkrcmar@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=thomas.lendacky@amd.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.