From d582d74baffe5bfd74a3c7593ea40bab8b7b243f Mon Sep 17 00:00:00 2001 From: hanliyang Date: Sat, 18 Jan 2025 15:42:30 +0800 Subject: [PATCH] [bugfix]crypto: ccp: Fix mutex lock nesting in CSV DOWNLOAD_FIRMWARE ioctl handler The commit 326b87a888ab ("anolis: crypto: ccp: Get api version again when update Hygon CSV firmware at runtime") will get API version of the newer firmware if DOWNLOAD_FIRMWARE success. Calls to sev_get_api_version() will try to grab mutex lock which was not released in CSV DOWNLOAD_FIRMWARE ioctl handler. To address this issue, we provide csv_get_api_version_locked() and calls it instead of sev_get_api_version() in the CSV DOWNLOAD_FIRMWARE ioctl handler. Fixes: 326b87a888ab ("anolis: crypto: ccp: Get api version again when update Hygon CSV firmware at runtime") Change-Id: Ifdf98666c0a13d600a1c6fff341b0c6936939197 Signed-off-by: hanliyang --- drivers/crypto/ccp/sev-dev.c | 42 ++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index f81600ce6c77c..f4fecc84b3ec6 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -929,6 +929,33 @@ static int sev_get_api_version(void) return 0; } +static int csv_get_api_version_locked(void) +{ + struct sev_device *sev = psp_master->sev_data; + struct sev_user_data_status status; + int error = 0, ret; + + ret = __sev_do_cmd_locked(SEV_CMD_PLATFORM_STATUS, + &status, &error); + if (ret) { + dev_err(sev->dev, + "CSV: failed to get status. Error: %#x\n", error); + return ret; + } + + sev->api_major = status.api_major; + sev->api_minor = status.api_minor; + sev->build = status.build; + sev->state = status.state; + + /* + * The api version fields of HYGON CSV firmware are not consistent + * with AMD SEV firmware. + */ + csv_update_api_version(&status); + + return 0; +} static int sev_get_firmware(struct device *dev, const struct firmware **firmware) { @@ -1322,13 +1349,20 @@ static int csv_ioctl_do_download_firmware(struct sev_issue_cmd *argp) data->len = input.length; ret = __sev_do_cmd_locked(SEV_CMD_DOWNLOAD_FIRMWARE, data, &argp->error); - if (ret) + if (ret) { pr_err("Failed to update CSV firmware: %#x\n", argp->error); - else + goto err_free_page; + } else { pr_info("CSV firmware update successful\n"); + } - /* Sync api version status */ - sev_get_api_version(); + /* + * Synchronize API version status. The return value of csv_get_api_version + * will inform the user of any error encountered when attempting to + * communicate with the Hygon PSP after the DOWNLOAD_FIRMWARE API completes + * successfully. + */ + ret = csv_get_api_version_locked(); err_free_page: __free_pages(p, order); -- Gitee