[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH v1 02/12] kvm: introduce high-level API to suppo
From: |
Singh, Brijesh |
Subject: |
[Qemu-devel] [RFC PATCH v1 02/12] kvm: introduce high-level API to support encrypted guest migration |
Date: |
Thu, 20 Jun 2019 18:03:06 +0000 |
When memory encryption is enabled in VM, the guest pages will be
encrypted with the guest-specific key, to protect the confidentiality
of data in transit. To support the live migration we need to use
platform specific hooks to access the guest memory.
The kvm_memcrypt_save_outgoing_page() can be used by the sender to write
the encrypted pages and metadata associated with it on the socket.
The kvm_memcrypt_load_incoming_page() can be used by receiver to read the
incoming encrypted pages from the socket and load into the guest memory.
Encrypted VMs have concept of private and shared memory. The private
memory is encrypted with the guest-specific key, while shared memory
may be encrypted with hyperivosr key. The KVM_{SET,GET}_PAGE_ENC_BITMAP
ioctl can be used to get/set the bitmap from/to the hypervisor.
The kvm_memcrypt_sync_page_enc_bitmap() can be used by the sender to get
the page encryption bitmap. The bitmap is used to determine the page state
(private or shared).
The kvm_memcrypt_send_outgoing_page_enc_bitmap() can be used by the sender
to write the page encryption bitmap on the socket.
The kvm_memcrypt_load_incoming_page_enc_bitmap() can be used by the
receiver to read the page encryption bitmap from the socket.
Signed-off-by: Brijesh Singh <<address@hidden>>
---
accel/kvm/kvm-all.c | 68 ++++++++++++++++++++++++++++++++++++++++++
accel/kvm/sev-stub.c | 28 +++++++++++++++++
accel/stubs/kvm-stub.c | 30 +++++++++++++++++++
include/sysemu/kvm.h | 33 ++++++++++++++++++++
include/sysemu/sev.h | 9 ++++++
5 files changed, 168 insertions(+)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index b0c4bed6e3..4d5ff8b9f5 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -109,6 +109,15 @@ struct KVMState
/* memory encryption */
void *memcrypt_handle;
int (*memcrypt_encrypt_data)(void *handle, uint8_t *ptr, uint64_t len);
+ int (*memcrypt_save_outgoing_page)(void *ehandle, QEMUFile *f,
+ uint8_t *ptr, uint32_t sz, uint64_t *bytes_sent);
+ int (*memcrypt_load_incoming_page)(void *ehandle, QEMUFile *f,
+ uint8_t *ptr);
+ int (*memcrypt_load_incoming_page_enc_bitmap)(void *ehandle, QEMUFile *f);
+ int (*memcrypt_save_outgoing_page_enc_bitmap)(void *ehandle, QEMUFile *f,
+ uint8_t *host, uint64_t length, unsigned long *bmap);
+ int (*memcrypt_sync_page_enc_bitmap)(void *ehandle, uint8_t *host,
+ uint64_t length, unsigned long *bmap);
};
KVMState *kvm_state;
@@ -164,6 +173,65 @@ int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len)
return 1;
}
+int kvm_memcrypt_save_outgoing_page(QEMUFile *f, uint8_t *ptr,
+ uint32_t size, uint64_t *bytes_sent)
+{
+ if (kvm_state->memcrypt_handle &&
+ kvm_state->memcrypt_save_outgoing_page) {
+ return
kvm_state->memcrypt_save_outgoing_page(kvm_state->memcrypt_handle,
+ f, ptr, size, bytes_sent);
+ }
+
+ return 1;
+}
+
+int kvm_memcrypt_load_incoming_page(QEMUFile *f, uint8_t *ptr)
+{
+ if (kvm_state->memcrypt_handle &&
+ kvm_state->memcrypt_load_incoming_page) {
+ return
kvm_state->memcrypt_load_incoming_page(kvm_state->memcrypt_handle,
+ f, ptr);
+ }
+
+ return 1;
+}
+
+int kvm_memcrypt_load_incoming_page_enc_bitmap(QEMUFile *f)
+{
+ if (kvm_state->memcrypt_handle &&
+ kvm_state->memcrypt_load_incoming_page_enc_bitmap) {
+ return kvm_state->memcrypt_load_incoming_page_enc_bitmap(
+ kvm_state->memcrypt_handle, f);
+ }
+
+ return 1;
+}
+
+int kvm_memcrypt_save_outgoing_page_enc_bitmap(QEMUFile *f, uint8_t *host,
+ uint64_t length,
+ unsigned long *bmap)
+{
+ if (kvm_state->memcrypt_handle &&
+ kvm_state->memcrypt_save_outgoing_page_enc_bitmap) {
+ return kvm_state->memcrypt_save_outgoing_page_enc_bitmap(
+ kvm_state->memcrypt_handle, f, host, length, bmap);
+ }
+
+ return 1;
+}
+
+int kvm_memcrypt_sync_page_enc_bitmap(uint8_t *host, uint64_t length,
+ unsigned long *bmap)
+{
+ if (kvm_state->memcrypt_handle &&
+ kvm_state->memcrypt_sync_page_enc_bitmap) {
+ return kvm_state->memcrypt_sync_page_enc_bitmap(
+ kvm_state->memcrypt_handle, host, length, bmap);
+ }
+
+ return 1;
+}
+
static KVMSlot *kvm_get_free_slot(KVMMemoryListener *kml)
{
KVMState *s = kvm_state;
diff --git a/accel/kvm/sev-stub.c b/accel/kvm/sev-stub.c
index 4f97452585..5d8c3f2ecd 100644
--- a/accel/kvm/sev-stub.c
+++ b/accel/kvm/sev-stub.c
@@ -24,3 +24,31 @@ void *sev_guest_init(const char *id)
{
return NULL;
}
+
+int sev_save_outgoing_page(void *handle, QEMUFile *f, uint8_t *ptr,
+ uint32_t size, uint64_t *bytes_sent)
+{
+ return 1;
+}
+
+int sev_load_incoming_page(void *handle, QEMUFile *f, uint8_t *ptr)
+{
+ return 1;
+}
+
+int sev_load_incoming_page_enc_bitmap(void *handle, QEMUFile *f)
+{
+ return 1;
+}
+
+int sev_save_outgoing_page_enc_bitmap(void *handle, QEMUFile *f,
+ unsigned long *bmap)
+{
+ return 1;
+}
+
+int sev_sync_page_enc_bitmap(void *handle, uint8_t *host, uint64_t size,
+ unsigned long *bitmap)
+{
+ return 1;
+}
diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c
index 6feb66ed80..bef7376985 100644
--- a/accel/stubs/kvm-stub.c
+++ b/accel/stubs/kvm-stub.c
@@ -114,6 +114,36 @@ int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len)
return 1;
}
+int kvm_memcrypt_save_outgoing_page(QEMUFile *f, uint8_t *ptr,
+ uint32_t size, uint64_t *bytes_sent)
+{
+ return 1;
+}
+
+int kvm_memcrypt_load_incoming_page(QEMUFile *f, uint8_t *ptr)
+{
+ return 1;
+}
+
+int kvm_memcrypt_load_incoming_page_enc_bitmap(QEMUFile *f)
+{
+ return 1;
+}
+
+int kvm_memcrypt_save_outgoing_page_enc_bitmap(QEMUFile *f, uint8_t *host,
+ uint64_t length,
+ unsigned long *bmap)
+{
+ return 1;
+}
+
+int kvm_memcrypt_sync_page_enc_bitmap(uint8_t *host, uint64_t size,
+ unsigned long *bitmap)
+{
+ return 1;
+}
+
+
#ifndef CONFIG_USER_ONLY
int kvm_irqchip_add_msi_route(KVMState *s, int vector, PCIDevice *dev)
{
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index a6d1cd190f..f85a60e411 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -246,6 +246,39 @@ bool kvm_memcrypt_enabled(void);
*/
int kvm_memcrypt_encrypt_data(uint8_t *ptr, uint64_t len);
+/**
+ * kvm_memcrypt_save_outgoing_buffer - encrypt the outgoing buffer
+ * and write to the wire.
+ */
+int kvm_memcrypt_save_outgoing_page(QEMUFile *f, uint8_t *ptr, uint32_t size,
+ uint64_t *bytes_sent);
+
+/**
+ * kvm_memcrypt_load_incoming_buffer - read the encrypt incoming buffer and
copy
+ * the buffer into the guest memory space.
+ */
+int kvm_memcrypt_load_incoming_page(QEMUFile *f, uint8_t *ptr);
+
+/**
+ * kvm_memcrypt_load_incoming_page_enc_bitmap: read the page encryption bitmap
+ * from the socket and pass it to the hypervisor.
+ */
+int kvm_memcrypt_load_incoming_page_enc_bitmap(QEMUFile *f);
+
+/**
+ * kvm_memcrypt_sync_page_enc_bitmap: sync the page encryption bitmap
+ * The caller is responsible to allocate/free the bitmap.
+ */
+int kvm_memcrypt_sync_page_enc_bitmap(uint8_t *host, uint64_t size,
+ unsigned long *bitmap);
+
+/**
+ * kvm_memcrypt_save_outgoing_page_enc_bitmap: write the page encryption bitmap
+ * on socket.
+ */
+int kvm_memcrypt_save_outgoing_page_enc_bitmap(QEMUFile *f, uint8_t *host,
+ uint64_t length,
+ unsigned long *bmap);
#ifdef NEED_CPU_H
#include "cpu.h"
diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h
index 98c1ec8d38..009be45230 100644
--- a/include/sysemu/sev.h
+++ b/include/sysemu/sev.h
@@ -18,4 +18,13 @@
void *sev_guest_init(const char *id);
int sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len);
+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);
+int sev_load_incoming_page_enc_bitmap(void *handle, QEMUFile *f);
+int sev_save_outgoing_page_enc_bitmap(void *handle, QEMUFile *f,
+ uint8_t *host, uint64_t length,
+ unsigned long *bmap);
+int sev_sync_page_enc_bitmap(void *handle, uint8_t *host, uint64_t size,
+ unsigned long *bitmap);
#endif
--
2.17.1
- [Qemu-devel] [RFC PATCH v1 00/12] Add SEV guest live migration support, Singh, Brijesh, 2019/06/20
- [Qemu-devel] [RFC PATCH v1 04/12] kvm: add support to sync the page encryption state bitmap, Singh, Brijesh, 2019/06/20
- [Qemu-devel] [RFC PATCH v1 11/12] migration: add support to migrate page encryption bitmap, Singh, Brijesh, 2019/06/20
- [Qemu-devel] [RFC PATCH v1 09/12] target/i386: sev: add support to encrypt the outgoing page, Singh, Brijesh, 2019/06/20
- [Qemu-devel] [RFC PATCH v1 06/12] doc: update AMD SEV to include Live migration flow, Singh, Brijesh, 2019/06/20
- [Qemu-devel] [RFC PATCH v1 01/12] linux-headers: update kernel header to include SEV migration commands, Singh, Brijesh, 2019/06/20
- [Qemu-devel] [RFC PATCH v1 08/12] target.json: add migrate-set-sev-info command, Singh, Brijesh, 2019/06/20
- [Qemu-devel] [RFC PATCH v1 12/12] target/i386: sev: remove migration blocker, Singh, Brijesh, 2019/06/20
- [Qemu-devel] [RFC PATCH v1 02/12] kvm: introduce high-level API to support encrypted guest migration,
Singh, Brijesh <=
- [Qemu-devel] [RFC PATCH v1 05/12] doc: update AMD SEV API spec web link, Singh, Brijesh, 2019/06/20
- [Qemu-devel] [RFC PATCH v1 07/12] target/i386: sev: do not create launch context for an incoming guest, Singh, Brijesh, 2019/06/20
- [Qemu-devel] [RFC PATCH v1 10/12] target/i386: sev: add support to load incoming encrypted page, Singh, Brijesh, 2019/06/20
- [Qemu-devel] [RFC PATCH v1 03/12] migration/ram: add support to send encrypted pages, Singh, Brijesh, 2019/06/20