The patch implements kvm_sev_get_ram_ops() which provides guest RAM read/write callback. Depending on the memory attributes and guest launch state, the callback will use SEV launch update or SEV debug commands to read/write into guest memory.
Signed-off-by: Brijesh Singh <brijesh.si...@amd.com> --- include/sysemu/sev.h | 8 ++++++++ sev.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h index e8fa62f..ec2dfde 100644 --- a/include/sysemu/sev.h +++ b/include/sysemu/sev.h @@ -15,6 +15,7 @@ #define QEMU_SEV_H #include "sysemu/kvm.h" +#include "exec/memory.h" typedef enum SevState { SEV_STATE_INVALID = 0x0, @@ -93,4 +94,11 @@ int kvm_sev_dbg_encrypt(uint8_t *dest, const uint8_t *src, uint32_t len); */ int kvm_sev_get_status(SevState *state, char *str); +/* + * kvm_sev_get_ram_ops - get MemoryRegionRW ops. + * + * Return NULL on failure. + */ +MemoryRegionRAMReadWriteOps *kvm_sev_get_ram_ops(void); + #endif diff --git a/sev.c b/sev.c index 508eff2..c1135c4 100644 --- a/sev.c +++ b/sev.c @@ -72,6 +72,8 @@ typedef struct SEVInfo SEVInfo; static SEVInfo *sev_info; static const char *cfg_file; +static MemoryRegionRAMReadWriteOps sev_ops; + enum { LAUNCH_OPTS = 0, }; @@ -512,3 +514,47 @@ int kvm_sev_get_status(SevState *state, char *msg) sev_state_msg[*state]); return 0; } + +static inline int sev_read(uint8_t *dst, const uint8_t *src, + uint32_t len, MemTxAttrs attrs) +{ + if (attrs.sev_debug) { + return kvm_sev_dbg_decrypt(dst, src, len); + } + + memcpy(dst, src, len); + return 0; +} + +static inline int sev_write(uint8_t *dst, const uint8_t *src, + uint32_t len, MemTxAttrs attrs) +{ + SEVInfo *s = sev_info; + + /* If we are in SEV launch stage then use launch_update command + * to copy and encrypt the data into guest memory. + */ + if (s->state == SEV_LAUNCH_START) { + memcpy(dst, src, len); /* copy data into guest memory */ + return sev_launch_update(dst, len); /* encrypt the data in-place */ + } + + if (attrs.sev_debug) { + return kvm_sev_dbg_encrypt(dst, src, len); + } + + memcpy(dst, src, len); + return 0; +} + +MemoryRegionRAMReadWriteOps *kvm_sev_get_ram_ops(void) +{ + if (!sev_info) { + return NULL; + } + + sev_ops.read = sev_read; + sev_ops.write = sev_write; + + return &sev_ops; +}