qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
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 04/12] kvm: add support to sync the page encryption state bitmap
Date: Thu, 20 Jun 2019 18:03:15 +0000	[thread overview]
Message-ID: <20190620180247.8825-5-brijesh.singh@amd.com> (raw)
In-Reply-To: <20190620180247.8825-1-brijesh.singh@amd.com>

The SEV VMs have concept of private and shared memory. The private memory
is encrypted with guest-specific key, while shared memory may be encrypted
with hyperivosr key. The KVM_GET_PAGE_ENC_BITMAP can be used to get a
bitmap indicating whether the guest page is private or shared. A private
page must be transmitted using the SEV migration commands.

Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
---
 accel/kvm/kvm-all.c     |  1 +
 include/exec/ram_addr.h |  2 ++
 migration/ram.c         | 28 +++++++++++++++++++++++++++-
 target/i386/sev.c       | 27 +++++++++++++++++++++++++++
 4 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 4d5ff8b9f5..0654d9a7cd 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -1783,6 +1783,7 @@ static int kvm_init(MachineState *ms)
         }
 
         kvm_state->memcrypt_encrypt_data = sev_encrypt_data;
+        kvm_state->memcrypt_sync_page_enc_bitmap = sev_sync_page_enc_bitmap;
     }
 
     ret = kvm_arch_init(ms, s);
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index f96777bb99..2145059afc 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -51,6 +51,8 @@ struct RAMBlock {
     unsigned long *unsentmap;
     /* bitmap of already received pages in postcopy */
     unsigned long *receivedmap;
+    /* bitmap of page encryption state for an encrypted guest */
+    unsigned long *encbmap;
 };
 
 static inline bool offset_in_ramblock(RAMBlock *b, ram_addr_t offset)
diff --git a/migration/ram.c b/migration/ram.c
index 3c8977d508..a8631c0896 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -1680,6 +1680,9 @@ static void migration_bitmap_sync_range(RAMState *rs, RAMBlock *rb,
     rs->migration_dirty_pages +=
         cpu_physical_memory_sync_dirty_bitmap(rb, 0, length,
                                               &rs->num_dirty_pages_period);
+    if (kvm_memcrypt_enabled()) {
+        kvm_memcrypt_sync_page_enc_bitmap(rb->host, length, rb->encbmap);
+    }
 }
 
 /**
@@ -2465,6 +2468,22 @@ static bool save_compress_page(RAMState *rs, RAMBlock *block, ram_addr_t offset)
     return false;
 }
 
+/**
+ * encrypted_test_bitmap: check if the page is encrypted
+ *
+ * Returns a bool indicating whether the page is encrypted.
+ */
+static bool encrypted_test_bitmap(RAMState *rs, RAMBlock *block,
+                                  unsigned long page)
+{
+    /* ROM devices contains the unencrypted data */
+    if (memory_region_is_rom(block->mr)) {
+        return false;
+    }
+
+    return test_bit(page, block->encbmap);
+}
+
 /**
  * ram_save_target_page: save one target page
  *
@@ -2491,7 +2510,8 @@ static int ram_save_target_page(RAMState *rs, PageSearchStatus *pss,
      * will take care of accessing the guest memory and re-encrypt it
      * for the transport purposes.
      */
-     if (kvm_memcrypt_enabled()) {
+     if (kvm_memcrypt_enabled() &&
+         encrypted_test_bitmap(rs, pss->block, pss->page)) {
         return ram_save_encrypted_page(rs, pss, last_stage);
      }
 
@@ -2724,6 +2744,8 @@ static void ram_save_cleanup(void *opaque)
         block->bmap = NULL;
         g_free(block->unsentmap);
         block->unsentmap = NULL;
+        g_free(block->encbmap);
+        block->encbmap = NULL;
     }
 
     xbzrle_cleanup();
@@ -3251,6 +3273,10 @@ static void ram_list_init_bitmaps(void)
                 block->unsentmap = bitmap_new(pages);
                 bitmap_set(block->unsentmap, 0, pages);
             }
+            if (kvm_memcrypt_enabled()) {
+                block->encbmap = bitmap_new(pages);
+                bitmap_set(block->encbmap, 0, pages);
+            }
         }
     }
 }
diff --git a/target/i386/sev.c b/target/i386/sev.c
index 6dbdc3cdf1..dd3814e25f 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -819,6 +819,33 @@ sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len)
     return 0;
 }
 
+int sev_sync_page_enc_bitmap(void *handle, uint8_t *host, uint64_t size,
+                            unsigned long *bitmap)
+{
+    int r;
+    unsigned long base_gpa;
+    KVMState *s = kvm_state;
+    struct kvm_page_enc_bitmap e = {};
+    unsigned long pages = size >> TARGET_PAGE_BITS;
+
+    r = kvm_physical_memory_addr_from_host(kvm_state, host, &base_gpa);
+    if (!r) {
+        return 1;
+    }
+
+    e.enc_bitmap = bitmap;
+    e.start = base_gpa >> TARGET_PAGE_BITS;
+    e.num_pages = pages;
+
+    if (kvm_vm_ioctl(s, KVM_GET_PAGE_ENC_BITMAP, &e) == -1) {
+        error_report("%s: get page_enc bitmap start 0x%llx pages 0x%llx",
+                __func__, e.start, e.num_pages);
+        return 1;
+    }
+
+    return 0;
+}
+
 static void
 sev_register_types(void)
 {
-- 
2.17.1


  parent reply	other threads:[~2019-06-20 18:35 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 ` Singh, Brijesh [this message]
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 ` [Qemu-devel] [RFC PATCH v1 11/12] migration: add support to migrate page encryption bitmap Singh, Brijesh
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-5-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).