Message ID | 20190710202219.25939-3-brijesh.singh@amd.com |
---|---|
State | New |
Headers | show |
Series | Add SEV guest live migration support | expand |
* Singh, Brijesh (brijesh.singh@amd.com) wrote: > 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. > > Signed-off-by: Brijesh Singh <<brijesh.singh@amd.com>> > --- > accel/kvm/kvm-all.c | 27 +++++++++++++++++++++++++++ > accel/kvm/sev-stub.c | 11 +++++++++++ > accel/stubs/kvm-stub.c | 12 ++++++++++++ > include/sysemu/kvm.h | 12 ++++++++++++ > include/sysemu/sev.h | 3 +++ > 5 files changed, 65 insertions(+) > > diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c > index 3d86ae5052..162a2d5085 100644 > --- a/accel/kvm/kvm-all.c > +++ b/accel/kvm/kvm-all.c > @@ -110,6 +110,10 @@ 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); > }; > > KVMState *kvm_state; > @@ -165,6 +169,29 @@ 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; This needs to be commented saying what the return values mean. I'm not sure what '1' means for the case when this didn't have encryption support. > +} > + > +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; > +} > + > 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..c12a8e005e 100644 > --- a/accel/kvm/sev-stub.c > +++ b/accel/kvm/sev-stub.c > @@ -24,3 +24,14 @@ 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; > +} > diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c > index 6feb66ed80..e14b879531 100644 > --- a/accel/stubs/kvm-stub.c > +++ b/accel/stubs/kvm-stub.c > @@ -114,6 +114,18 @@ 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; > +} > + > + > #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 acd90aebb6..bb6bcc143c 100644 > --- a/include/sysemu/kvm.h > +++ b/include/sysemu/kvm.h > @@ -247,6 +247,18 @@ 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); > > #ifdef NEED_CPU_H > #include "cpu.h" > diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h > index 98c1ec8d38..752a71b1c0 100644 > --- a/include/sysemu/sev.h > +++ b/include/sysemu/sev.h > @@ -18,4 +18,7 @@ > > 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); > #endif > -- > 2.17.1 > -- Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
On 7/11/19 12:47 PM, Dr. David Alan Gilbert wrote: > * Singh, Brijesh (brijesh.singh@amd.com) wrote: >> 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. >> >> Signed-off-by: Brijesh Singh <<brijesh.singh@amd.com>> >> --- >> accel/kvm/kvm-all.c | 27 +++++++++++++++++++++++++++ >> accel/kvm/sev-stub.c | 11 +++++++++++ >> accel/stubs/kvm-stub.c | 12 ++++++++++++ >> include/sysemu/kvm.h | 12 ++++++++++++ >> include/sysemu/sev.h | 3 +++ >> 5 files changed, 65 insertions(+) >> >> diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c >> index 3d86ae5052..162a2d5085 100644 >> --- a/accel/kvm/kvm-all.c >> +++ b/accel/kvm/kvm-all.c >> @@ -110,6 +110,10 @@ 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); >> }; >> >> KVMState *kvm_state; >> @@ -165,6 +169,29 @@ 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; > > This needs to be commented saying what the return values mean. > I'm not sure what '1' means for the case when this didn't have > encryption support. > Agreed, I will add comment in API header about this. The value of zero means success and anything else is failure. >> +} >> + >> +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; >> +} >> + >> 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..c12a8e005e 100644 >> --- a/accel/kvm/sev-stub.c >> +++ b/accel/kvm/sev-stub.c >> @@ -24,3 +24,14 @@ 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; >> +} >> diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c >> index 6feb66ed80..e14b879531 100644 >> --- a/accel/stubs/kvm-stub.c >> +++ b/accel/stubs/kvm-stub.c >> @@ -114,6 +114,18 @@ 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; >> +} >> + >> + >> #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 acd90aebb6..bb6bcc143c 100644 >> --- a/include/sysemu/kvm.h >> +++ b/include/sysemu/kvm.h >> @@ -247,6 +247,18 @@ 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); >> >> #ifdef NEED_CPU_H >> #include "cpu.h" >> diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h >> index 98c1ec8d38..752a71b1c0 100644 >> --- a/include/sysemu/sev.h >> +++ b/include/sysemu/sev.h >> @@ -18,4 +18,7 @@ >> >> 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); >> #endif >> -- >> 2.17.1 >> > -- > Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK >
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 3d86ae5052..162a2d5085 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -110,6 +110,10 @@ 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); }; KVMState *kvm_state; @@ -165,6 +169,29 @@ 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; +} + 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..c12a8e005e 100644 --- a/accel/kvm/sev-stub.c +++ b/accel/kvm/sev-stub.c @@ -24,3 +24,14 @@ 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; +} diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c index 6feb66ed80..e14b879531 100644 --- a/accel/stubs/kvm-stub.c +++ b/accel/stubs/kvm-stub.c @@ -114,6 +114,18 @@ 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; +} + + #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 acd90aebb6..bb6bcc143c 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -247,6 +247,18 @@ 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); #ifdef NEED_CPU_H #include "cpu.h" diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h index 98c1ec8d38..752a71b1c0 100644 --- a/include/sysemu/sev.h +++ b/include/sysemu/sev.h @@ -18,4 +18,7 @@ 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); #endif
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. Signed-off-by: Brijesh Singh <<brijesh.singh@amd.com>> --- accel/kvm/kvm-all.c | 27 +++++++++++++++++++++++++++ accel/kvm/sev-stub.c | 11 +++++++++++ accel/stubs/kvm-stub.c | 12 ++++++++++++ include/sysemu/kvm.h | 12 ++++++++++++ include/sysemu/sev.h | 3 +++ 5 files changed, 65 insertions(+)