From: "Singh, Brijesh" <brijesh.singh@amd.com>
To: "qemu-devel@nongnu.org" <qemu-devel@nongnu.org>
Cc: "Lendacky, Thomas" <Thomas.Lendacky@amd.com>,
"Singh, Brijesh" <brijesh.singh@amd.com>,
"kvm@vger.kernel.org" <kvm@vger.kernel.org>
Subject: [Qemu-devel] [RFC PATCH v1 11/12] migration: add support to migrate page encryption bitmap
Date: Thu, 20 Jun 2019 18:03:22 +0000 [thread overview]
Message-ID: <20190620180247.8825-12-brijesh.singh@amd.com> (raw)
In-Reply-To: <20190620180247.8825-1-brijesh.singh@amd.com>
When memory encryption is enabled, the hypervisor maintains a page
encryption bitmap which is referred by hypervisor during migratoin to check
if page is private or shared. The bitmap is built during the VM bootup and
must be migrated to the target host so that hypervisor on target host can
use it for future migration.
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
accel/kvm/kvm-all.c | 4 +++
migration/ram.c | 43 +++++++++++++++++++++++++++++-
target/i386/sev.c | 56 ++++++++++++++++++++++++++++++++++++++++
target/i386/trace-events | 3 +++
4 files changed, 105 insertions(+), 1 deletion(-)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index fe65c8eb5d..0d75ad94f8 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -1786,6 +1786,10 @@ static int kvm_init(MachineState *ms)
kvm_state->memcrypt_sync_page_enc_bitmap = sev_sync_page_enc_bitmap;
kvm_state->memcrypt_save_outgoing_page = sev_save_outgoing_page;
kvm_state->memcrypt_load_incoming_page = sev_load_incoming_page;
+ kvm_state->memcrypt_load_incoming_page_enc_bitmap =
+ sev_load_incoming_page_enc_bitmap;
+ kvm_state->memcrypt_save_outgoing_page_enc_bitmap =
+ sev_save_outgoing_page_enc_bitmap;
}
ret = kvm_arch_init(ms, s);
diff --git a/migration/ram.c b/migration/ram.c
index a8631c0896..5c8403588f 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -78,6 +78,7 @@
/* 0x80 is reserved in migration.h start with 0x100 next */
#define RAM_SAVE_FLAG_COMPRESS_PAGE 0x100
#define RAM_SAVE_FLAG_ENCRYPTED_PAGE 0x200
+#define RAM_SAVE_FLAG_PAGE_ENCRYPTED_BITMAP 0x400
static inline bool is_zero_range(uint8_t *p, uint64_t size)
{
@@ -3551,6 +3552,35 @@ out:
return done;
}
+/**
+ * migration_save_page_enc_bitmap: function to send the page enc bitmap
+ *
+ * Returns zero to indicate success or negative on error
+ */
+static int migration_save_page_enc_bitmap(QEMUFile *f, RAMState *rs)
+{
+ int r;
+ RAMBlock *block;
+
+ RAMBLOCK_FOREACH_MIGRATABLE(block) {
+ /* ROM region does not encrypted data, skip sending the bitmap */
+ if (memory_region_is_rom(block->mr)) {
+ continue;
+ }
+
+ qemu_put_be64(f, RAM_SAVE_FLAG_PAGE_ENCRYPTED_BITMAP);
+ qemu_put_byte(f, strlen(block->idstr));
+ qemu_put_buffer(f, (uint8_t *)block->idstr, strlen(block->idstr));
+ r = kvm_memcrypt_save_outgoing_page_enc_bitmap(f, block->host,
+ block->max_length, block->encbmap);
+ if (r) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
/**
* ram_save_complete: function called to send the remaining amount of ram
*
@@ -3595,6 +3625,10 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
flush_compressed_data(rs);
ram_control_after_iterate(f, RAM_CONTROL_FINISH);
+ if (kvm_memcrypt_enabled()) {
+ ret = migration_save_page_enc_bitmap(f, rs);
+ }
+
rcu_read_unlock();
multifd_send_sync_main();
@@ -4343,7 +4377,8 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE |
RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE |
- RAM_SAVE_FLAG_ENCRYPTED_PAGE)) {
+ RAM_SAVE_FLAG_ENCRYPTED_PAGE |
+ RAM_SAVE_FLAG_PAGE_ENCRYPTED_BITMAP)) {
RAMBlock *block = ram_block_from_stream(f, flags);
/*
@@ -4469,6 +4504,12 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
ret = -EINVAL;
}
break;
+ case RAM_SAVE_FLAG_PAGE_ENCRYPTED_BITMAP:
+ if (kvm_memcrypt_load_incoming_page_enc_bitmap(f)) {
+ error_report("Failed to load page enc bitmap");
+ ret = -EINVAL;
+ }
+ break;
case RAM_SAVE_FLAG_EOS:
/* normal exit */
multifd_recv_sync_main();
diff --git a/target/i386/sev.c b/target/i386/sev.c
index b7feedce7d..dc1e974d93 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -896,6 +896,8 @@ int sev_sync_page_enc_bitmap(void *handle, uint8_t *host, uint64_t size,
return 1;
}
+ trace_kvm_sev_sync_page_enc_bitmap(base_gpa, size);
+
e.enc_bitmap = bitmap;
e.start = base_gpa >> TARGET_PAGE_BITS;
e.num_pages = pages;
@@ -1216,6 +1218,60 @@ int sev_load_incoming_page(void *handle, QEMUFile *f, uint8_t *ptr)
return sev_receive_update_data(f, ptr);
}
+int sev_load_incoming_page_enc_bitmap(void *handle, QEMUFile *f)
+{
+ void *bmap;
+ unsigned long pages, length;
+ unsigned long bmap_size, base_gpa;
+ struct kvm_page_enc_bitmap e = {};
+
+ base_gpa = qemu_get_be64(f);
+ length = qemu_get_be64(f);
+ pages = length >> TARGET_PAGE_BITS;
+
+ bmap_size = BITS_TO_LONGS(pages) * sizeof(unsigned long);
+ bmap = g_malloc0(bmap_size);
+ qemu_get_buffer(f, (uint8_t *)bmap, bmap_size);
+
+ trace_kvm_sev_load_page_enc_bitmap(base_gpa, length);
+
+ e.start = base_gpa >> TARGET_PAGE_BITS;
+ e.num_pages = pages;
+ e.enc_bitmap = bmap;
+ if (kvm_vm_ioctl(kvm_state, KVM_SET_PAGE_ENC_BITMAP, &e) == -1) {
+ error_report("KVM_SET_PAGE_ENC_BITMAP ioctl failed %d", errno);
+ g_free(bmap);
+ return 1;
+ }
+
+ g_free(bmap);
+
+ return 0;
+}
+
+int sev_save_outgoing_page_enc_bitmap(void *handle, QEMUFile *f,
+ uint8_t *host, uint64_t length,
+ unsigned long *bmap)
+{
+ int r;
+ unsigned long base_gpa;
+ unsigned long pages = length >> TARGET_PAGE_BITS;
+ unsigned long bmap_sz = BITS_TO_LONGS(pages) * sizeof(unsigned long);
+
+ r = kvm_physical_memory_addr_from_host(kvm_state, host, &base_gpa);
+ if (!r) {
+ return 1;
+ }
+
+ trace_kvm_sev_save_page_enc_bitmap(base_gpa, length);
+
+ qemu_put_be64(f, base_gpa);
+ qemu_put_be64(f, length);
+ qemu_put_buffer(f, (uint8_t *)bmap, bmap_sz);
+
+ return 0;
+}
+
static void
sev_register_types(void)
{
diff --git a/target/i386/trace-events b/target/i386/trace-events
index 609752cca7..fe914c9048 100644
--- a/target/i386/trace-events
+++ b/target/i386/trace-events
@@ -21,3 +21,6 @@ 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) ""
+kvm_sev_sync_page_enc_bitmap(uint64_t start, uint64_t len) "start 0x%" PRIx64 " len 0x%" PRIx64
+kvm_sev_save_page_enc_bitmap(uint64_t start, uint64_t len) "start 0x%" PRIx64 " len 0x%" PRIx64
+kvm_sev_load_page_enc_bitmap(uint64_t start, uint64_t len) "start 0x%" PRIx64 " len 0x%" PRIx64
--
2.17.1
next prev parent reply other threads:[~2019-06-20 18:50 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-06-20 18:03 [Qemu-devel] [RFC PATCH v1 00/12] Add SEV guest live migration support Singh, Brijesh
2019-06-20 18:03 ` [Qemu-devel] [RFC PATCH v1 02/12] kvm: introduce high-level API to support encrypted guest migration Singh, Brijesh
2019-06-20 18:03 ` [Qemu-devel] [RFC PATCH v1 01/12] linux-headers: update kernel header to include SEV migration commands Singh, Brijesh
2019-06-20 18:03 ` [Qemu-devel] [RFC PATCH v1 03/12] migration/ram: add support to send encrypted pages Singh, Brijesh
2019-06-20 18:03 ` [Qemu-devel] [RFC PATCH v1 04/12] kvm: add support to sync the page encryption state bitmap Singh, Brijesh
2019-06-20 18:03 ` [Qemu-devel] [RFC PATCH v1 05/12] doc: update AMD SEV API spec web link Singh, Brijesh
2019-06-20 18:03 ` [Qemu-devel] [RFC PATCH v1 07/12] target/i386: sev: do not create launch context for an incoming guest Singh, Brijesh
2019-06-20 18:03 ` [Qemu-devel] [RFC PATCH v1 06/12] doc: update AMD SEV to include Live migration flow Singh, Brijesh
2019-06-20 18:03 ` [Qemu-devel] [RFC PATCH v1 08/12] target.json: add migrate-set-sev-info command Singh, Brijesh
2019-06-20 19:13 ` Eric Blake
2019-06-20 19:18 ` Singh, Brijesh
2019-06-20 18:03 ` [Qemu-devel] [RFC PATCH v1 10/12] target/i386: sev: add support to load incoming encrypted page Singh, Brijesh
2019-06-20 18:03 ` [Qemu-devel] [RFC PATCH v1 09/12] target/i386: sev: add support to encrypt the outgoing page Singh, Brijesh
2019-06-20 18:03 ` Singh, Brijesh [this message]
2019-06-20 18:03 ` [Qemu-devel] [RFC PATCH v1 12/12] 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=20190620180247.8825-12-brijesh.singh@amd.com \
--to=brijesh.singh@amd.com \
--cc=Thomas.Lendacky@amd.com \
--cc=kvm@vger.kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).