Skip to content

Commit

Permalink
crypto: ccp: Implement CSV_DOWNLOAD_FIRMWARE ioctl command
Browse files Browse the repository at this point in the history
hygon inclusion
category: feature
CVE: NA

---------------------------

The CSV_DOWNLOAD_FIRMWARE command can be used by the platform owner to
updating CSV firmware.

Signed-off-by: hanliyang <hanliyang@hygon.cn>
  • Loading branch information
hanliyang authored and Avenger-285714 committed Aug 7, 2024
1 parent 48cd5d8 commit 0aa9a16
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 0 deletions.
71 changes: 71 additions & 0 deletions drivers/crypto/ccp/hygon/csv-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,74 @@ static int csv_ioctl_do_hgsc_import(struct sev_issue_cmd *argp)
return ret;
}

static int csv_ioctl_do_download_firmware(struct sev_issue_cmd *argp)
{
struct sev_data_download_firmware *data = NULL;
struct csv_user_data_download_firmware input;
int ret, order;
struct page *p;
u64 data_size;

/* Only support DOWNLOAD_FIRMWARE if build greater or equal 1667 */
if (!csv_version_greater_or_equal(1667)) {
pr_err("DOWNLOAD_FIRMWARE not supported\n");
return -EIO;
}

if (copy_from_user(&input, (void __user *)argp->data, sizeof(input)))
return -EFAULT;

if (!input.address) {
argp->error = SEV_RET_INVALID_ADDRESS;
return -EINVAL;
}

if (!input.length || input.length > CSV_FW_MAX_SIZE) {
argp->error = SEV_RET_INVALID_LEN;
return -EINVAL;
}

/*
* CSV 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 CSV
* FW. Allocate enough memory for data structure + alignment
* padding + CSV FW.
*/
data_size = ALIGN(sizeof(struct sev_data_download_firmware), 32);

order = get_order(input.length + data_size);
p = alloc_pages(GFP_KERNEL, order);
if (!p)
return -ENOMEM;

/*
* Copy firmware data to a kernel allocated contiguous
* memory region.
*/
data = page_address(p);
if (copy_from_user((void *)(page_address(p) + data_size),
(void *)input.address, input.length)) {
ret = -EFAULT;
goto err_free_page;
}

data->address = __psp_pa(page_address(p) + data_size);
data->len = input.length;

ret = hygon_psp_hooks.__sev_do_cmd_locked(SEV_CMD_DOWNLOAD_FIRMWARE,
data, &argp->error);
if (ret)
pr_err("Failed to update CSV firmware: %#x\n", argp->error);
else
pr_info("CSV firmware update successful\n");

err_free_page:
__free_pages(p, order);

return ret;
}

static long csv_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
{
void __user *argp = (void __user *)arg;
Expand Down Expand Up @@ -124,6 +192,9 @@ static long csv_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
case CSV_PLATFORM_SHUTDOWN:
ret = hygon_psp_hooks.__sev_platform_shutdown_locked(&input.error);
break;
case CSV_DOWNLOAD_FIRMWARE:
ret = csv_ioctl_do_download_firmware(&input);
break;
default:
/*
* If the command is compatible between CSV and SEV, the
Expand Down
2 changes: 2 additions & 0 deletions include/linux/psp-hygon.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
/***************************** CSV interface *********************************/
/*****************************************************************************/

#define CSV_FW_MAX_SIZE 0x80000 /* 512KB */

/**
* Guest/platform management commands for CSV
*/
Expand Down
12 changes: 12 additions & 0 deletions include/uapi/linux/psp-hygon.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
enum {
CSV_PLATFORM_INIT = 101,
CSV_PLATFORM_SHUTDOWN = 102,
CSV_DOWNLOAD_FIRMWARE = 128,
CSV_HGSC_CERT_IMPORT = 201,

CSV_MAX,
Expand All @@ -43,4 +44,15 @@ struct csv_user_data_hgsc_cert_import {
__u32 hgsc_cert_len; /* In */
} __packed;

/**
* struct csv_user_data_download_firmware - DOWNLOAD_FIRMWARE command parameters
*
* @address: physical address of CSV firmware image
* @length: length of the CSV firmware image
*/
struct csv_user_data_download_firmware {
__u64 address; /* In */
__u32 length; /* In */
} __packed;

#endif /* __PSP_HYGON_USER_H__ */

0 comments on commit 0aa9a16

Please sign in to comment.