From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
To: "Singh, Brijesh" <brijesh.singh@amd.com>
Cc: "pbonzini@redhat.com" <pbonzini@redhat.com>,
"Lendacky, Thomas" <Thomas.Lendacky@amd.com>,
"qemu-devel@nongnu.org" <qemu-devel@nongnu.org>,
"ehabkost@redhat.com" <ehabkost@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v3 10/14] target/i386: sev: add support to load incoming encrypted page
Date: Tue, 13 Aug 2019 18:38:55 +0100 [thread overview]
Message-ID: <20190813173855.GI2763@work-vm> (raw)
In-Reply-To: <20190806165429.19327-11-brijesh.singh@amd.com>
* Singh, Brijesh (brijesh.singh@amd.com) wrote:
> The sev_load_incoming_page() provide the implementation to read the
> incoming guest private pages from the socket and load it into the guest
> memory. The routines uses the RECEIVE_START command to create the
> incoming encryption context on the first call then uses the
> RECEIEVE_UPDATE_DATA command to load the encrypted pages into the guest
> memory. After migration is completed, we issue the RECEIVE_FINISH command
> to transition the SEV guest to the runnable state so that it can be
> executed.
>
> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
OK, some comments about the return values of the functions would help,
but other than that.
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> ---
> accel/kvm/kvm-all.c | 6 ++
> accel/kvm/sev-stub.c | 5 ++
> include/sysemu/sev.h | 1 +
> target/i386/sev.c | 137 ++++++++++++++++++++++++++++++++++++++-
> target/i386/trace-events | 3 +
> 5 files changed, 151 insertions(+), 1 deletion(-)
>
> diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
> index a5b0ae9363..ba0e7fa2be 100644
> --- a/accel/kvm/kvm-all.c
> +++ b/accel/kvm/kvm-all.c
> @@ -180,9 +180,15 @@ static int kvm_memcrypt_save_outgoing_page(QEMUFile *f, uint8_t *ptr,
> bytes_sent);
> }
>
> +static int kvm_memcrypt_load_incoming_page(QEMUFile *f, uint8_t *ptr)
> +{
> + return sev_load_incoming_page(kvm_state->memcrypt_handle, f, ptr);
> +}
> +
> static struct MachineMemoryEncryptionOps sev_memory_encryption_ops = {
> .save_setup = kvm_memcrypt_save_setup,
> .save_outgoing_page = kvm_memcrypt_save_outgoing_page,
> + .load_incoming_page = kvm_memcrypt_load_incoming_page,
> };
>
> int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len)
> diff --git a/accel/kvm/sev-stub.c b/accel/kvm/sev-stub.c
> index 51b17b8141..1b6773ef72 100644
> --- a/accel/kvm/sev-stub.c
> +++ b/accel/kvm/sev-stub.c
> @@ -36,3 +36,8 @@ int sev_save_outgoing_page(void *handle, QEMUFile *f, uint8_t *ptr,
> {
> return 1;
> }
> +
> +int sev_load_incoming_page(void *handle, QEMUFile *f, uint8_t *ptr)
> +{
> + return 1;
> +}
> diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
> index f06fd203cd..e9371bd2dd 100644
> --- a/include/sysemu/sev.h
> +++ b/include/sysemu/sev.h
> @@ -22,4 +22,5 @@ int sev_save_setup(void *handle, const char *pdh, const char *plat_cert,
> const char *amd_cert);
> int sev_save_outgoing_page(void *handle, QEMUFile *f, uint8_t *ptr,
> uint32_t size, uint64_t *bytes_sent);
> +int sev_load_incoming_page(void *handle, QEMUFile *f, uint8_t *ptr);
> #endif
> diff --git a/target/i386/sev.c b/target/i386/sev.c
> index 1820c62a71..a689011991 100644
> --- a/target/i386/sev.c
> +++ b/target/i386/sev.c
> @@ -721,13 +721,34 @@ sev_launch_finish(SEVState *s)
> }
> }
>
> +static int
> +sev_receive_finish(SEVState *s)
> +{
> + int error, ret = 1;
> +
> + trace_kvm_sev_receive_finish();
> + ret = sev_ioctl(s->sev_fd, KVM_SEV_RECEIVE_FINISH, 0, &error);
> + if (ret) {
> + error_report("%s: RECEIVE_FINISH ret=%d fw_error=%d '%s'",
> + __func__, ret, error, fw_error_to_str(error));
> + goto err;
> + }
> +
> + sev_set_guest_state(SEV_STATE_RUNNING);
> +err:
> + return ret;
> +}
> +
> +
> static void
> sev_vm_state_change(void *opaque, int running, RunState state)
> {
> SEVState *s = opaque;
>
> if (running) {
> - if (!sev_check_state(SEV_STATE_RUNNING)) {
> + if (sev_check_state(SEV_STATE_RECEIVE_UPDATE)) {
> + sev_receive_finish(s);
> + } else if (!sev_check_state(SEV_STATE_RUNNING)) {
> sev_launch_finish(s);
> }
> }
> @@ -1097,6 +1118,120 @@ int sev_save_outgoing_page(void *handle, QEMUFile *f, uint8_t *ptr,
> return sev_send_update_data(s, f, ptr, sz, bytes_sent);
> }
>
> +static int
> +sev_receive_start(QSevGuestInfo *sev, QEMUFile *f)
> +{
> + int ret = 1;
> + int fw_error;
> + struct kvm_sev_receive_start start = { };
> + gchar *session = NULL, *pdh_cert = NULL;
> +
> + /* get SEV guest handle */
> + start.handle = object_property_get_int(OBJECT(sev), "handle",
> + &error_abort);
> +
> + /* get the source policy */
> + start.policy = qemu_get_be32(f);
> +
> + /* get source PDH key */
> + start.pdh_len = qemu_get_be32(f);
> + if (!check_blob_length(start.pdh_len)) {
> + return 1;
> + }
> +
> + pdh_cert = g_new(gchar, start.pdh_len);
> + qemu_get_buffer(f, (uint8_t *)pdh_cert, start.pdh_len);
> + start.pdh_uaddr = (uintptr_t)pdh_cert;
> +
> + /* get source session data */
> + start.session_len = qemu_get_be32(f);
> + if (!check_blob_length(start.session_len)) {
> + return 1;
> + }
> + session = g_new(gchar, start.session_len);
> + qemu_get_buffer(f, (uint8_t *)session, start.session_len);
> + start.session_uaddr = (uintptr_t)session;
> +
> + trace_kvm_sev_receive_start(start.policy, session, pdh_cert);
> +
> + ret = sev_ioctl(sev_state->sev_fd, KVM_SEV_RECEIVE_START,
> + &start, &fw_error);
> + if (ret < 0) {
> + error_report("Error RECEIVE_START ret=%d fw_error=%d '%s'",
> + ret, fw_error, fw_error_to_str(fw_error));
> + goto err;
> + }
> +
> + object_property_set_int(OBJECT(sev), start.handle, "handle", &error_abort);
> + sev_set_guest_state(SEV_STATE_RECEIVE_UPDATE);
> +err:
> + g_free(session);
> + g_free(pdh_cert);
> +
> + return ret;
> +}
> +
> +static int sev_receive_update_data(QEMUFile *f, uint8_t *ptr)
> +{
> + int ret = 1, fw_error = 0;
> + gchar *hdr = NULL, *trans = NULL;
> + struct kvm_sev_receive_update_data update = {};
> +
> + /* get packet header */
> + update.hdr_len = qemu_get_be32(f);
> + if (!check_blob_length(update.hdr_len)) {
> + return 1;
> + }
> +
> + hdr = g_new(gchar, update.hdr_len);
> + qemu_get_buffer(f, (uint8_t *)hdr, update.hdr_len);
> + update.hdr_uaddr = (uintptr_t)hdr;
> +
> + /* get transport buffer */
> + update.trans_len = qemu_get_be32(f);
> + if (!check_blob_length(update.trans_len)) {
> + goto err;
> + }
> +
> + trans = g_new(gchar, update.trans_len);
> + update.trans_uaddr = (uintptr_t)trans;
> + qemu_get_buffer(f, (uint8_t *)update.trans_uaddr, update.trans_len);
> +
> + update.guest_uaddr = (uintptr_t) ptr;
> + update.guest_len = update.trans_len;
> +
> + trace_kvm_sev_receive_update_data(trans, ptr, update.guest_len,
> + hdr, update.hdr_len);
> +
> + ret = sev_ioctl(sev_state->sev_fd, KVM_SEV_RECEIVE_UPDATE_DATA,
> + &update, &fw_error);
> + if (ret) {
> + error_report("Error RECEIVE_UPDATE_DATA ret=%d fw_error=%d '%s'",
> + ret, fw_error, fw_error_to_str(fw_error));
> + goto err;
> + }
> +err:
> + g_free(trans);
> + g_free(hdr);
> + return ret;
> +}
> +
> +int sev_load_incoming_page(void *handle, QEMUFile *f, uint8_t *ptr)
> +{
> + SEVState *s = (SEVState *)handle;
> +
> + /*
> + * If this is first buffer and SEV is not in recieiving state then
> + * use RECEIVE_START command to create a encryption context.
> + */
> + if (!sev_check_state(SEV_STATE_RECEIVE_UPDATE) &&
> + sev_receive_start(s->sev_info, f)) {
> + return 1;
> + }
> +
> + return sev_receive_update_data(f, ptr);
> +}
> +
> static void
> sev_register_types(void)
> {
> diff --git a/target/i386/trace-events b/target/i386/trace-events
> index b41516cf9f..609752cca7 100644
> --- a/target/i386/trace-events
> +++ b/target/i386/trace-events
> @@ -18,3 +18,6 @@ kvm_sev_launch_finish(void) ""
> kvm_sev_send_start(uint64_t pdh, int l1, uint64_t plat, int l2, uint64_t amd, int l3) "pdh 0x%" PRIx64 " len %d plat 0x%" PRIx64 " len %d amd 0x%" PRIx64 " len %d"
> kvm_sev_send_update_data(void *src, void *dst, int len) "guest %p trans %p len %d"
> kvm_sev_send_finish(void) ""
> +kvm_sev_receive_start(int policy, void *session, void *pdh) "policy 0x%x session %p pdh %p"
> +kvm_sev_receive_update_data(void *src, void *dst, int len, void *hdr, int hdr_len) "guest %p trans %p len %d hdr %p hdr_len %d"
> +kvm_sev_receive_finish(void) ""
> --
> 2.17.1
>
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
next prev parent reply other threads:[~2019-08-13 17:39 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-06 16:54 [Qemu-devel] [PATCH v3 00/14] Add SEV guest live migration support Singh, Brijesh
2019-08-06 16:54 ` [Qemu-devel] [PATCH v3 01/14] doc: update AMD SEV API spec web link Singh, Brijesh
2019-08-06 19:00 ` Dr. David Alan Gilbert
2019-08-06 16:54 ` [Qemu-devel] [PATCH v3 02/14] doc: update AMD SEV to include Live migration flow Singh, Brijesh
2019-08-07 11:01 ` Dr. David Alan Gilbert
2019-08-06 16:54 ` [Qemu-devel] [PATCH v3 03/14] migration.json: add AMD SEV specific migration parameters Singh, Brijesh
2019-08-07 11:06 ` Dr. David Alan Gilbert
2019-08-08 2:25 ` Singh, Brijesh
2019-08-08 10:48 ` Dr. David Alan Gilbert
2019-08-09 20:00 ` Singh, Brijesh
2019-08-06 16:54 ` [Qemu-devel] [PATCH v3 04/14] linux-headers: update kernel header to include SEV migration commands Singh, Brijesh
2019-08-06 16:54 ` [Qemu-devel] [PATCH v3 05/14] hw/machine: add helper to query the memory encryption state Singh, Brijesh
2019-08-07 16:14 ` Dr. David Alan Gilbert
2019-08-08 2:25 ` Singh, Brijesh
2019-08-06 16:54 ` [Qemu-devel] [PATCH v3 06/14] hw/machine: introduce MachineMemoryEncryptionOps for encrypted VMs Singh, Brijesh
2019-08-07 16:36 ` Dr. David Alan Gilbert
2019-08-06 16:54 ` [Qemu-devel] [PATCH v3 08/14] target/i386: sev: do not create launch context for an incoming guest Singh, Brijesh
2019-08-06 16:54 ` [Qemu-devel] [PATCH v3 07/14] target/i386: sev: provide callback to setup outgoing context Singh, Brijesh
2019-08-08 11:19 ` Dr. David Alan Gilbert
2019-08-06 16:54 ` [Qemu-devel] [PATCH v3 09/14] target/i386: sev: add support to encrypt the outgoing page Singh, Brijesh
2019-08-09 18:54 ` Dr. David Alan Gilbert
2019-08-06 16:54 ` [Qemu-devel] [PATCH v3 10/14] target/i386: sev: add support to load incoming encrypted page Singh, Brijesh
2019-08-13 17:38 ` Dr. David Alan Gilbert [this message]
2019-08-06 16:54 ` [Qemu-devel] [PATCH v3 11/14] migration: add support to migrate page encryption bitmap Singh, Brijesh
2019-08-13 18:57 ` Dr. David Alan Gilbert
2019-08-06 16:54 ` [Qemu-devel] [PATCH v3 13/14] migration/ram: add support to send encrypted pages Singh, Brijesh
2019-08-14 16:37 ` Dr. David Alan Gilbert
2019-08-06 16:54 ` [Qemu-devel] [PATCH v3 12/14] kvm: add support to sync the page encryption state bitmap Singh, Brijesh
2019-08-06 16:54 ` [Qemu-devel] [PATCH v3 14/14] target/i386: sev: remove migration blocker Singh, Brijesh
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=20190813173855.GI2763@work-vm \
--to=dgilbert@redhat.com \
--cc=Thomas.Lendacky@amd.com \
--cc=brijesh.singh@amd.com \
--cc=ehabkost@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.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.