Skip to content

Commit

Permalink
crypto: ccp: Add SET_SMR/SET_SMCR commands for CSV3
Browse files Browse the repository at this point in the history
hygon inclusion
category: feature
CVE: NA

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

Set guest memory regions in hygon hardware with SET_SMR command.
Secure memory control region(SMCR) is a special memory region which
is dedicated for CSV3 guest's meta data. SET_SMCR command is used to
set SMCR memory in hygon hardware. Both SET_SMR and SET_SMCR should
be issued early during platform initialization.

Signed-off-by: Xin Jiang <jiangxin@hygon.cn>
Signed-off-by: hanliyang <hanliyang@hygon.cn>
  • Loading branch information
Xin Jiang authored and Avenger-285714 committed Aug 19, 2024
1 parent 207ab26 commit b822465
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 0 deletions.
100 changes: 100 additions & 0 deletions drivers/crypto/ccp/hygon/csv-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <linux/psp-hygon.h>
#include <uapi/linux/psp-hygon.h>

#include <asm/csv.h>

#include "psp-dev.h"
#include "csv-dev.h"
#include "ring-buffer.h"
Expand Down Expand Up @@ -567,3 +569,101 @@ int csv_check_stat_queue_status(int *psp_ret)
return 0;
}
EXPORT_SYMBOL_GPL(csv_check_stat_queue_status);

#ifdef CONFIG_HYGON_CSV

int csv_platform_cmd_set_secure_memory_region(struct sev_device *sev, int *error)
{
int ret = 0;
unsigned int i = 0;
struct csv3_data_set_smr *cmd_set_smr;
struct csv3_data_set_smcr *cmd_set_smcr;
struct csv3_data_memory_region *smr_regions;

if (!hygon_psp_hooks.sev_dev_hooks_installed) {
ret = -ENODEV;
goto l_end;
}

if (!csv_smr || !csv_smr_num) {
ret = -EINVAL;
goto l_end;
}

cmd_set_smr = kzalloc(sizeof(*cmd_set_smr), GFP_KERNEL);
if (!cmd_set_smr) {
ret = -ENOMEM;
goto l_end;
}

smr_regions = kcalloc(csv_smr_num, sizeof(*smr_regions), GFP_KERNEL);
if (!smr_regions) {
ret = -ENOMEM;
goto e_free_cmd_set_smr;
}

for (i = 0; i < csv_smr_num; i++) {
smr_regions[i].base_address = csv_smr[i].start;
smr_regions[i].size = csv_smr[i].size;
}
cmd_set_smr->smr_entry_size = 1 << csv_get_smr_entry_shift();
cmd_set_smr->regions_paddr = __psp_pa(smr_regions);
cmd_set_smr->nregions = csv_smr_num;
ret = hygon_psp_hooks.sev_do_cmd(CSV3_CMD_SET_SMR, cmd_set_smr, error);
if (ret) {
pr_err("Fail to set SMR, ret %#x, error %#x\n", ret, *error);
goto e_free_smr_area;
}

cmd_set_smcr = kzalloc(sizeof(*cmd_set_smcr), GFP_KERNEL);
if (!cmd_set_smcr) {
ret = -ENOMEM;
goto e_free_smr_area;
}

cmd_set_smcr->base_address = csv_alloc_from_contiguous(1UL << CSV_MR_ALIGN_BITS,
&node_online_map,
get_order(1 << CSV_MR_ALIGN_BITS));
if (!cmd_set_smcr->base_address) {
pr_err("Fail to alloc SMCR memory\n");
ret = -ENOMEM;
goto e_free_cmd_set_smcr;
}

cmd_set_smcr->size = 1UL << CSV_MR_ALIGN_BITS;
ret = hygon_psp_hooks.sev_do_cmd(CSV3_CMD_SET_SMCR, cmd_set_smcr, error);
if (ret) {
if (*error == SEV_RET_INVALID_COMMAND)
ret = 0;
else
pr_err("set smcr ret %#x, error %#x\n", ret, *error);

csv_release_to_contiguous(cmd_set_smcr->base_address,
1UL << CSV_MR_ALIGN_BITS);
}

e_free_cmd_set_smcr:
kfree((void *)cmd_set_smcr);
e_free_smr_area:
kfree((void *)smr_regions);
e_free_cmd_set_smr:
kfree((void *)cmd_set_smr);

l_end:
if (ret)
dev_warn(sev->dev,
"CSV3: fail to set secure memory region, CSV3 support unavailable\n");

return ret;
}

#else /* !CONFIG_HYGON_CSV */

int csv_platform_cmd_set_secure_memory_region(struct sev_device *sev, int *error)
{
dev_warn(sev->dev,
"CSV3: needs CONFIG_HYGON_CSV, CSV3 support unavailable\n");
return -EFAULT;
}

#endif /* CONFIG_HYGON_CSV */
1 change: 1 addition & 0 deletions drivers/crypto/ccp/hygon/csv-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ extern const struct file_operations csv_fops;
void csv_update_api_version(struct sev_user_data_status *status);
int csv_cmd_buffer_len(int cmd);
void csv_restore_mailbox_mode_postprocess(void);
int csv_platform_cmd_set_secure_memory_region(struct sev_device *sev, int *error);

static inline bool csv_version_greater_or_equal(u32 build)
{
Expand Down
1 change: 1 addition & 0 deletions drivers/crypto/ccp/hygon/psp-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ extern struct hygon_psp_hooks_table {
int (*__sev_platform_shutdown_locked)(int *error);
int (*sev_wait_cmd_ioc)(struct sev_device *sev,
unsigned int *reg, unsigned int timeout);
int (*sev_do_cmd)(int cmd, void *data, int *psp_ret);
long (*sev_ioctl)(struct file *file, unsigned int ioctl, unsigned long arg);
} hygon_psp_hooks;

Expand Down
5 changes: 5 additions & 0 deletions drivers/crypto/ccp/sev-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,7 @@ static void sev_dev_install_hooks(void)
hygon_psp_hooks.__sev_do_cmd_locked = __sev_do_cmd_locked;
hygon_psp_hooks.__sev_platform_init_locked = __sev_platform_init_locked;
hygon_psp_hooks.__sev_platform_shutdown_locked = __sev_platform_shutdown_locked;
hygon_psp_hooks.sev_do_cmd = sev_do_cmd;
hygon_psp_hooks.sev_wait_cmd_ioc = sev_wait_cmd_ioc;
hygon_psp_hooks.sev_ioctl = sev_ioctl;

Expand Down Expand Up @@ -1431,6 +1432,10 @@ void sev_pci_init(void)
if (!psp_init_on_probe)
return;

/* Set SMR for HYGON CSV3 */
if (is_vendor_hygon() && boot_cpu_has(X86_FEATURE_CSV3))
csv_platform_cmd_set_secure_memory_region(sev, &error);

/* Initialize the platform */
rc = sev_platform_init(&error);
if (rc)
Expand Down

0 comments on commit b822465

Please sign in to comment.