From mboxrd@z Thu Jan 1 00:00:00 1970 From: Brijesh Singh Subject: [PATCH v10 15/28] sev/i386: add command to create launch memory encryption context Date: Wed, 28 Feb 2018 15:10:15 -0600 Message-ID: <20180228211028.83970-16-brijesh.singh@amd.com> References: <20180228211028.83970-1-brijesh.singh@amd.com> Mime-Version: 1.0 Content-Type: text/plain Cc: Peter Maydell , Brijesh Singh , kvm@vger.kernel.org, "Michael S. Tsirkin" , Stefan Hajnoczi , Alexander Graf , "Edgar E. Iglesias" , Markus Armbruster , Bruce Rogers , Christian Borntraeger , Marcel Apfelbaum , Borislav Petkov , Thomas Lendacky , Eduardo Habkost , Richard Henderson , "Dr. David Alan Gilbert" , Alistair Francis , Cornelia Huck , Richard Henderson , Peter Crosthwaite , Paolo Bonzini To: qemu-devel@nongnu.org Return-path: In-Reply-To: <20180228211028.83970-1-brijesh.singh@amd.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+gceq-qemu-devel2=m.gmane.org@nongnu.org Sender: "Qemu-devel" List-Id: kvm.vger.kernel.org The KVM_SEV_LAUNCH_START command creates a new VM encryption key (VEK). The encryption key created with the command will be used for encrypting the bootstrap images (such as guest bios). Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Signed-off-by: Brijesh Singh --- target/i386/sev.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ target/i386/trace-events | 2 ++ 2 files changed, 88 insertions(+) diff --git a/target/i386/sev.c b/target/i386/sev.c index 8ee6159b2bfc..b867ffbc0eae 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -100,6 +100,17 @@ fw_error_to_str(int code) return sev_fw_errlist[code]; } +static void +sev_set_guest_state(SevState new_state) +{ + assert(new_state < SEV_STATE__MAX); + assert(sev_state); + + trace_kvm_sev_change_state(SevState_str(sev_state->state), + SevState_str(new_state)); + sev_state->state = new_state; +} + static void sev_ram_block_added(RAMBlockNotifier *n, void *host, size_t size) { @@ -400,6 +411,75 @@ sev_get_info(void) return info; } +static int +sev_read_file_base64(const char *filename, guchar **data, gsize *len) +{ + gsize sz; + gchar *base64; + GError *error = NULL; + + if (!g_file_get_contents(filename, &base64, &sz, &error)) { + error_report("failed to read '%s' (%s)", filename, error->message); + return -1; + } + + *data = g_base64_decode(base64, len); + return 0; +} + +static int +sev_launch_start(SEVState *s) +{ + gsize sz; + int ret = 1; + int fw_error; + QSevGuestInfo *sev = s->sev_info; + struct kvm_sev_launch_start *start; + guchar *session = NULL, *dh_cert = NULL; + + start = g_new0(struct kvm_sev_launch_start, 1); + + start->handle = object_property_get_int(OBJECT(sev), "handle", + &error_abort); + start->policy = object_property_get_int(OBJECT(sev), "policy", + &error_abort); + if (sev->session_file) { + if (sev_read_file_base64(sev->session_file, &session, &sz) < 0) { + return 1; + } + start->session_uaddr = (unsigned long)session; + start->session_len = sz; + } + + if (sev->dh_cert_file) { + if (sev_read_file_base64(sev->dh_cert_file, &dh_cert, &sz) < 0) { + return 1; + } + start->dh_uaddr = (unsigned long)dh_cert; + start->dh_len = sz; + } + + trace_kvm_sev_launch_start(start->policy, session, dh_cert); + ret = sev_ioctl(s->sev_fd, KVM_SEV_LAUNCH_START, start, &fw_error); + if (ret < 0) { + error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'", + __func__, ret, fw_error, fw_error_to_str(fw_error)); + return 1; + } + + object_property_set_int(OBJECT(sev), start->handle, "handle", + &error_abort); + sev_set_guest_state(SEV_STATE_LUPDATE); + s->handle = start->handle; + s->policy = start->policy; + + g_free(start); + g_free(session); + g_free(dh_cert); + + return 0; +} + void * sev_guest_init(const char *id) { @@ -473,6 +553,12 @@ sev_guest_init(const char *id) goto err; } + ret = sev_launch_start(s); + if (ret) { + error_report("%s: failed to create encryption context", __func__); + goto err; + } + ram_block_notifier_add(&sev_ram_notifier); return s; diff --git a/target/i386/trace-events b/target/i386/trace-events index ffa3d2250425..9402251e9991 100644 --- a/target/i386/trace-events +++ b/target/i386/trace-events @@ -10,3 +10,5 @@ kvm_x86_update_msi_routes(int num) "Updated %d MSI routes" kvm_sev_init(void) "" kvm_memcrypt_register_region(void *addr, size_t len) "addr %p len 0x%lu" kvm_memcrypt_unregister_region(void *addr, size_t len) "addr %p len 0x%lu" +kvm_sev_change_state(const char *old, const char *new) "%s -> %s" +kvm_sev_launch_start(int policy, void *session, void *pdh) "policy 0x%x session %p pdh %p" -- 2.14.3 From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53350) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1er90M-0001Mo-CK for qemu-devel@nongnu.org; Wed, 28 Feb 2018 16:11:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1er90I-0005pG-0s for qemu-devel@nongnu.org; Wed, 28 Feb 2018 16:11:14 -0500 Received: from mail-dm3nam03on0076.outbound.protection.outlook.com ([104.47.41.76]:5440 helo=NAM03-DM3-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1er90H-0005nz-A5 for qemu-devel@nongnu.org; Wed, 28 Feb 2018 16:11:09 -0500 From: Brijesh Singh Date: Wed, 28 Feb 2018 15:10:15 -0600 Message-Id: <20180228211028.83970-16-brijesh.singh@amd.com> In-Reply-To: <20180228211028.83970-1-brijesh.singh@amd.com> References: <20180228211028.83970-1-brijesh.singh@amd.com> MIME-Version: 1.0 Content-Type: text/plain Subject: [Qemu-devel] [PATCH v10 15/28] sev/i386: add command to create launch memory encryption context List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Alistair Francis , Christian Borntraeger , Cornelia Huck , "Daniel P . Berrange" , "Dr. David Alan Gilbert" , "Michael S. Tsirkin" , "Edgar E. Iglesias" , Eduardo Habkost , Eric Blake , kvm@vger.kernel.org, Marcel Apfelbaum , Markus Armbruster , Paolo Bonzini , Peter Crosthwaite , Peter Maydell , Richard Henderson , Stefan Hajnoczi , Thomas Lendacky , Borislav Petkov , Alexander Graf , Bruce Rogers , Brijesh Singh , Richard Henderson The KVM_SEV_LAUNCH_START command creates a new VM encryption key (VEK). The encryption key created with the command will be used for encrypting the bootstrap images (such as guest bios). Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Signed-off-by: Brijesh Singh --- target/i386/sev.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++ target/i386/trace-events | 2 ++ 2 files changed, 88 insertions(+) diff --git a/target/i386/sev.c b/target/i386/sev.c index 8ee6159b2bfc..b867ffbc0eae 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -100,6 +100,17 @@ fw_error_to_str(int code) return sev_fw_errlist[code]; } +static void +sev_set_guest_state(SevState new_state) +{ + assert(new_state < SEV_STATE__MAX); + assert(sev_state); + + trace_kvm_sev_change_state(SevState_str(sev_state->state), + SevState_str(new_state)); + sev_state->state = new_state; +} + static void sev_ram_block_added(RAMBlockNotifier *n, void *host, size_t size) { @@ -400,6 +411,75 @@ sev_get_info(void) return info; } +static int +sev_read_file_base64(const char *filename, guchar **data, gsize *len) +{ + gsize sz; + gchar *base64; + GError *error = NULL; + + if (!g_file_get_contents(filename, &base64, &sz, &error)) { + error_report("failed to read '%s' (%s)", filename, error->message); + return -1; + } + + *data = g_base64_decode(base64, len); + return 0; +} + +static int +sev_launch_start(SEVState *s) +{ + gsize sz; + int ret = 1; + int fw_error; + QSevGuestInfo *sev = s->sev_info; + struct kvm_sev_launch_start *start; + guchar *session = NULL, *dh_cert = NULL; + + start = g_new0(struct kvm_sev_launch_start, 1); + + start->handle = object_property_get_int(OBJECT(sev), "handle", + &error_abort); + start->policy = object_property_get_int(OBJECT(sev), "policy", + &error_abort); + if (sev->session_file) { + if (sev_read_file_base64(sev->session_file, &session, &sz) < 0) { + return 1; + } + start->session_uaddr = (unsigned long)session; + start->session_len = sz; + } + + if (sev->dh_cert_file) { + if (sev_read_file_base64(sev->dh_cert_file, &dh_cert, &sz) < 0) { + return 1; + } + start->dh_uaddr = (unsigned long)dh_cert; + start->dh_len = sz; + } + + trace_kvm_sev_launch_start(start->policy, session, dh_cert); + ret = sev_ioctl(s->sev_fd, KVM_SEV_LAUNCH_START, start, &fw_error); + if (ret < 0) { + error_report("%s: LAUNCH_START ret=%d fw_error=%d '%s'", + __func__, ret, fw_error, fw_error_to_str(fw_error)); + return 1; + } + + object_property_set_int(OBJECT(sev), start->handle, "handle", + &error_abort); + sev_set_guest_state(SEV_STATE_LUPDATE); + s->handle = start->handle; + s->policy = start->policy; + + g_free(start); + g_free(session); + g_free(dh_cert); + + return 0; +} + void * sev_guest_init(const char *id) { @@ -473,6 +553,12 @@ sev_guest_init(const char *id) goto err; } + ret = sev_launch_start(s); + if (ret) { + error_report("%s: failed to create encryption context", __func__); + goto err; + } + ram_block_notifier_add(&sev_ram_notifier); return s; diff --git a/target/i386/trace-events b/target/i386/trace-events index ffa3d2250425..9402251e9991 100644 --- a/target/i386/trace-events +++ b/target/i386/trace-events @@ -10,3 +10,5 @@ kvm_x86_update_msi_routes(int num) "Updated %d MSI routes" kvm_sev_init(void) "" kvm_memcrypt_register_region(void *addr, size_t len) "addr %p len 0x%lu" kvm_memcrypt_unregister_region(void *addr, size_t len) "addr %p len 0x%lu" +kvm_sev_change_state(const char *old, const char *new) "%s -> %s" +kvm_sev_launch_start(int policy, void *session, void *pdh) "policy 0x%x session %p pdh %p" -- 2.14.3