[RFC v1 4/6] crypto/ccp: Reclaim command buffer when the PSP dies
From: Tycho Andersen
Date: Thu Apr 30 2026 - 12:15:05 EST
From: "Tycho Andersen (AMD)" <tycho@xxxxxxxxxx>
When the PSP dies due to timeout the psp_dead flag is set, but the
buffer-in-use flag was not unset, and the pages were not reclaimed for
legacy commands.
In preparation for a firmware quirk where updates time out but the
situation is recoverable, move the reclamation before the error checking
and handling. Be sure to only copy the output buffer when the command has
not timed out, i.e. when there is sensible output in the buffer.
Signed-off-by: Tycho Andersen (AMD) <tycho@xxxxxxxxxx>
---
drivers/crypto/ccp/sev-dev.c | 60 +++++++++++++++++++-----------------
1 file changed, 32 insertions(+), 28 deletions(-)
diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
index defdc1bc226e..2df621b9f6e2 100644
--- a/drivers/crypto/ccp/sev-dev.c
+++ b/drivers/crypto/ccp/sev-dev.c
@@ -948,6 +948,38 @@ int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
/* wait for command completion */
ret = sev_wait_cmd_ioc(sev, ®, psp_timeout);
+
+ /*
+ * Copy potential output from the PSP back to data. Do this even on
+ * failure in case the caller wants to glean something from the error,
+ * unless the operation timed out, in which case there is nothing to
+ * copy back.
+ */
+ if (data) {
+ int ret_reclaim;
+ /*
+ * Restore the page state after the command completes.
+ */
+ ret_reclaim = snp_reclaim_cmd_buf(cmd, cmd_buf);
+ if (ret_reclaim) {
+ dev_err(sev->dev,
+ "SEV: failed to reclaim buffer for legacy command %#x. Error: %d\n",
+ cmd, ret_reclaim);
+ return ret_reclaim;
+ }
+
+ if (ret != -ETIMEDOUT)
+ memcpy(data, cmd_buf, buf_len);
+
+ if (sev->cmd_buf_backup_active)
+ sev->cmd_buf_backup_active = false;
+ else
+ sev->cmd_buf_active = false;
+
+ if (snp_unmap_cmd_buf_desc_list(desc_list))
+ return -EFAULT;
+ }
+
if (ret) {
if (psp_ret)
*psp_ret = 0;
@@ -984,34 +1016,6 @@ int __sev_do_cmd_locked(int cmd, void *data, int *psp_ret)
ret = sev_write_init_ex_file_if_required(cmd);
}
- /*
- * Copy potential output from the PSP back to data. Do this even on
- * failure in case the caller wants to glean something from the error.
- */
- if (data) {
- int ret_reclaim;
- /*
- * Restore the page state after the command completes.
- */
- ret_reclaim = snp_reclaim_cmd_buf(cmd, cmd_buf);
- if (ret_reclaim) {
- dev_err(sev->dev,
- "SEV: failed to reclaim buffer for legacy command %#x. Error: %d\n",
- cmd, ret_reclaim);
- return ret_reclaim;
- }
-
- memcpy(data, cmd_buf, buf_len);
-
- if (sev->cmd_buf_backup_active)
- sev->cmd_buf_backup_active = false;
- else
- sev->cmd_buf_active = false;
-
- if (snp_unmap_cmd_buf_desc_list(desc_list))
- return -EFAULT;
- }
-
print_hex_dump_debug("(out): ", DUMP_PREFIX_OFFSET, 16, 2, data,
buf_len, false);
--
2.54.0