crypto: ccp - simplify sev_update_firmware()

sev_do_cmd() has its own command buffer (sev->cmd_buf) with the correct
alignment, perms, etc. that it copies the command into, so prepending it to
the firmware data is unnecessary.

Switch sev_update_firmware() to using a stack allocated command in light of
this copy, and drop all of the resulting pointer math.

Signed-off-by: Tycho Andersen (AMD) <tycho@kernel.org>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Tycho Andersen (AMD)
2026-03-02 08:02:23 -07:00
committed by Herbert Xu
parent d23cf35880
commit 35a89319f6

View File

@@ -1965,11 +1965,11 @@ static int sev_get_firmware(struct device *dev,
/* Don't fail if SEV FW couldn't be updated. Continue with existing SEV FW */
static int sev_update_firmware(struct device *dev)
{
struct sev_data_download_firmware *data;
struct sev_data_download_firmware data;
const struct firmware *firmware;
int ret, error, order;
struct page *p;
u64 data_size;
void *fw_blob;
if (!sev_version_greater_or_equal(0, 15)) {
dev_dbg(dev, "DOWNLOAD_FIRMWARE not supported\n");
@@ -1981,16 +1981,7 @@ static int sev_update_firmware(struct device *dev)
return -1;
}
/*
* SEV FW expects the physical address given to it to be 32
* byte aligned. Memory allocated has structure placed at the
* beginning followed by the firmware being passed to the SEV
* FW. Allocate enough memory for data structure + alignment
* padding + SEV FW.
*/
data_size = ALIGN(sizeof(struct sev_data_download_firmware), 32);
order = get_order(firmware->size + data_size);
order = get_order(firmware->size);
p = alloc_pages(GFP_KERNEL, order);
if (!p) {
ret = -1;
@@ -2001,20 +1992,20 @@ static int sev_update_firmware(struct device *dev)
* Copy firmware data to a kernel allocated contiguous
* memory region.
*/
data = page_address(p);
memcpy(page_address(p) + data_size, firmware->data, firmware->size);
fw_blob = page_address(p);
memcpy(fw_blob, firmware->data, firmware->size);
data->address = __psp_pa(page_address(p) + data_size);
data->len = firmware->size;
data.address = __psp_pa(fw_blob);
data.len = firmware->size;
ret = sev_do_cmd(SEV_CMD_DOWNLOAD_FIRMWARE, data, &error);
ret = sev_do_cmd(SEV_CMD_DOWNLOAD_FIRMWARE, &data, &error);
/*
* A quirk for fixing the committed TCB version, when upgrading from
* earlier firmware version than 1.50.
*/
if (!ret && !sev_version_greater_or_equal(1, 50))
ret = sev_do_cmd(SEV_CMD_DOWNLOAD_FIRMWARE, data, &error);
ret = sev_do_cmd(SEV_CMD_DOWNLOAD_FIRMWARE, &data, &error);
if (ret)
dev_dbg(dev, "Failed to update SEV firmware: %#x\n", error);