From: Brijesh Singh <brijesh.singh@xxxxxxx> Add support to decrypt guest encrypted memory, these API interfaces can be used for example to dump VMCBs on SNP guest exit. Signed-off-by: Brijesh Singh <brijesh.singh@xxxxxxx> --- drivers/crypto/ccp/sev-dev.c | 33 ++++++++++++++++++++++++++++++--- include/linux/psp-sev.h | 6 +++--- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index f6306b820b86..9896350e7f56 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -1852,11 +1852,38 @@ int snp_guest_page_reclaim(struct sev_data_snp_page_reclaim *data, int *error) } EXPORT_SYMBOL_GPL(snp_guest_page_reclaim); -int snp_guest_dbg_decrypt(struct sev_data_snp_dbg *data, int *error) +int snp_guest_dbg_decrypt_page(u64 gctx_pfn, u64 src_pfn, u64 dst_pfn, int *error) { - return sev_do_cmd(SEV_CMD_SNP_DBG_DECRYPT, data, error); + struct sev_data_snp_dbg data = {0}; + struct sev_device *sev; + int ret; + + if (!psp_master || !psp_master->sev_data) + return -ENODEV; + + sev = psp_master->sev_data; + + if (!sev->snp_inited) + return -EINVAL; + + data.gctx_paddr = sme_me_mask | (gctx_pfn << PAGE_SHIFT); + data.src_addr = sme_me_mask | (src_pfn << PAGE_SHIFT); + data.dst_addr = sme_me_mask | (dst_pfn << PAGE_SHIFT); + data.len = PAGE_SIZE; + + /* The destination page must be in the firmware state. */ + if (snp_set_rmp_state(data.dst_addr, 1, true, false, false)) + return -EIO; + + ret = sev_do_cmd(SEV_CMD_SNP_DBG_DECRYPT, &data, error); + + /* Restore the page state */ + if (snp_set_rmp_state(data.dst_addr, 1, false, false, true)) + ret = -EIO; + + return ret; } -EXPORT_SYMBOL_GPL(snp_guest_dbg_decrypt); +EXPORT_SYMBOL_GPL(snp_guest_dbg_decrypt_page); int snp_guest_ext_guest_request(struct sev_data_snp_guest_request *data, unsigned long vaddr, unsigned long *npages, unsigned long *fw_err) diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h index cd37ccd1fa1f..8d2565c70c39 100644 --- a/include/linux/psp-sev.h +++ b/include/linux/psp-sev.h @@ -928,7 +928,7 @@ int snp_guest_decommission(struct sev_data_snp_decommission *data, int *error); int snp_guest_page_reclaim(struct sev_data_snp_page_reclaim *data, int *error); /** - * snp_guest_dbg_decrypt - perform SEV SNP_DBG_DECRYPT command + * snp_guest_dbg_decrypt_page - perform SEV SNP_DBG_DECRYPT command * * @sev_ret: sev command return code * @@ -939,7 +939,7 @@ int snp_guest_page_reclaim(struct sev_data_snp_page_reclaim *data, int *error); * -%ETIMEDOUT if the sev command timed out * -%EIO if the sev returned a non-zero return code */ -int snp_guest_dbg_decrypt(struct sev_data_snp_dbg *data, int *error); +int snp_guest_dbg_decrypt_page(u64 gctx_pfn, u64 src_pfn, u64 dst_pfn, int *error); void *psp_copy_user_blob(u64 uaddr, u32 len); void *snp_alloc_firmware_page(gfp_t mask); @@ -997,7 +997,7 @@ static inline int snp_guest_page_reclaim(struct sev_data_snp_page_reclaim *data, return -ENODEV; } -static inline int snp_guest_dbg_decrypt(struct sev_data_snp_dbg *data, int *error) +static inline int snp_guest_dbg_decrypt_page(u64 gctx_pfn, u64 src_pfn, u64 dst_pfn, int *error) { return -ENODEV; } -- 2.25.1