Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crypto: ccp: fix the sev_do_cmd panic on non-Hygon platforms #425

Merged
merged 1 commit into from
Sep 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 26 additions & 8 deletions drivers/crypto/ccp/hygon/csv-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ static long csv_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
if (input.cmd > CSV_MAX)
return -EINVAL;

if (is_vendor_hygon() && mutex_enabled) {
if (mutex_enabled) {
if (psp_mutex_lock_timeout(&hygon_psp_hooks.psp_misc->data_pg_aligned->mb_mutex,
PSP_MUTEX_TIMEOUT) != 1)
return -EBUSY;
Expand Down Expand Up @@ -245,7 +245,7 @@ static long csv_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
* Release the mutex before calling the native ioctl function
* because it will acquires the mutex.
*/
if (is_vendor_hygon() && mutex_enabled)
if (mutex_enabled)
psp_mutex_unlock(&hygon_psp_hooks.psp_misc->data_pg_aligned->mb_mutex);
else
mutex_unlock(hygon_psp_hooks.sev_cmd_mutex);
Expand All @@ -255,7 +255,7 @@ static long csv_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
if (copy_to_user(argp, &input, sizeof(struct sev_issue_cmd)))
ret = -EFAULT;

if (is_vendor_hygon() && mutex_enabled)
if (mutex_enabled)
psp_mutex_unlock(&hygon_psp_hooks.psp_misc->data_pg_aligned->mb_mutex);
else
mutex_unlock(hygon_psp_hooks.sev_cmd_mutex);
Expand Down Expand Up @@ -418,7 +418,7 @@ static int csv_do_ringbuf_cmds(int *psp_ret)
if (!hygon_psp_hooks.sev_dev_hooks_installed)
return -ENODEV;

if (is_vendor_hygon() && mutex_enabled) {
if (mutex_enabled) {
if (psp_mutex_lock_timeout(&hygon_psp_hooks.psp_misc->data_pg_aligned->mb_mutex,
PSP_MUTEX_TIMEOUT) != 1)
return -EBUSY;
Expand All @@ -437,7 +437,7 @@ static int csv_do_ringbuf_cmds(int *psp_ret)
csv_comm_mode = CSV_COMM_MAILBOX_ON;

cmd_unlock:
if (is_vendor_hygon() && mutex_enabled)
if (mutex_enabled)
psp_mutex_unlock(&hygon_psp_hooks.psp_misc->data_pg_aligned->mb_mutex);
else
mutex_unlock(hygon_psp_hooks.sev_cmd_mutex);
Expand Down Expand Up @@ -727,7 +727,10 @@ static int vpsp_psp_mutex_trylock(void)
{
int mutex_enabled = READ_ONCE(hygon_psp_hooks.psp_mutex_enabled);

if (is_vendor_hygon() && mutex_enabled)
if (!hygon_psp_hooks.sev_dev_hooks_installed)
return -ENODEV;

if (mutex_enabled)
return psp_mutex_trylock(&hygon_psp_hooks.psp_misc->data_pg_aligned->mb_mutex);
else
return mutex_trylock(hygon_psp_hooks.sev_cmd_mutex);
Expand All @@ -737,7 +740,10 @@ static int vpsp_psp_mutex_unlock(void)
{
int mutex_enabled = READ_ONCE(hygon_psp_hooks.psp_mutex_enabled);

if (is_vendor_hygon() && mutex_enabled)
if (!hygon_psp_hooks.sev_dev_hooks_installed)
return -ENODEV;

if (mutex_enabled)
psp_mutex_unlock(&hygon_psp_hooks.psp_misc->data_pg_aligned->mb_mutex);
else
mutex_unlock(hygon_psp_hooks.sev_cmd_mutex);
Expand All @@ -753,6 +759,9 @@ static int __vpsp_ring_buffer_enter_locked(int *error)
struct csv_ringbuffer_queue *hi_queue;
struct sev_device *sev = psp_master->sev_data;

if (!hygon_psp_hooks.sev_dev_hooks_installed)
return -ENODEV;

if (csv_comm_mode == CSV_COMM_RINGBUFFER_ON)
return -EEXIST;

Expand Down Expand Up @@ -789,7 +798,7 @@ static int __vpsp_do_ringbuf_cmds_locked(int *psp_ret, uint8_t prio, int index)
unsigned int rb_ctl;
struct sev_device *sev;

if (!psp)
if (!psp || !hygon_psp_hooks.sev_dev_hooks_installed)
return -ENODEV;

if (*hygon_psp_hooks.psp_dead)
Expand Down Expand Up @@ -852,6 +861,9 @@ static int vpsp_do_ringbuf_cmds_locked(int *psp_ret, uint8_t prio, int index)
struct sev_user_data_status data;
int rc;

if (!hygon_psp_hooks.sev_dev_hooks_installed)
return -ENODEV;

rc = __vpsp_ring_buffer_enter_locked(psp_ret);
if (rc)
goto end;
Expand Down Expand Up @@ -967,6 +979,9 @@ int vpsp_try_get_result(uint32_t vid, uint8_t prio, uint32_t index, void *data,
int ret = 0;
struct csv_cmdptr_entry cmd = {0};

if (!hygon_psp_hooks.sev_dev_hooks_installed)
return -ENODEV;

/* Get the retult directly if the command has been executed */
if (index >= 0 && vpsp_get_cmd_status(prio, index) !=
VPSP_CMD_STATUS_RUNNING) {
Expand Down Expand Up @@ -1032,6 +1047,9 @@ int vpsp_try_do_cmd(uint32_t vid, int cmd, void *data, struct vpsp_ret *psp_ret)
int index = -1;
uint8_t prio = CSV_COMMAND_PRIORITY_LOW;

if (!hygon_psp_hooks.sev_dev_hooks_installed)
return -ENODEV;

/* ringbuffer mode check and parse command prio*/
rb_supported = vpsp_rb_check_and_cmd_prio_parse(&prio,
(struct vpsp_cmd *)&cmd);
Expand Down
24 changes: 19 additions & 5 deletions drivers/crypto/ccp/hygon/psp-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,9 @@ static long ioctl_psp(struct file *file, unsigned int ioctl, unsigned long arg)
struct vpsp_dev_ctrl vpsp_ctrl_op;
int ret = -EFAULT;

if (!hygon_psp_hooks.sev_dev_hooks_installed)
return -ENODEV;

if (_IOC_TYPE(ioctl) != HYGON_PSP_IOC_TYPE) {
pr_info("%s: invalid ioctl type: 0x%x\n", __func__, _IOC_TYPE(ioctl));
return -EINVAL;
Expand Down Expand Up @@ -372,6 +375,9 @@ int hygon_psp_additional_setup(struct sp_device *sp)
struct device *dev = sp->dev;
int ret = 0;

if (!hygon_psp_hooks.sev_dev_hooks_installed)
return -ENODEV;

if (!psp_misc) {
struct miscdevice *misc;

Expand Down Expand Up @@ -500,7 +506,7 @@ int __vpsp_do_cmd_locked(uint32_t vid, int cmd, void *data, int *psp_ret)
unsigned int phys_lsb, phys_msb;
unsigned int reg, ret = 0;

if (!psp || !psp->sev_data)
if (!psp || !psp->sev_data || !hygon_psp_hooks.sev_dev_hooks_installed)
return -ENODEV;

if (*hygon_psp_hooks.psp_dead)
Expand Down Expand Up @@ -564,7 +570,10 @@ int vpsp_do_cmd(uint32_t vid, int cmd, void *data, int *psp_ret)
int rc;
int mutex_enabled = READ_ONCE(hygon_psp_hooks.psp_mutex_enabled);

if (is_vendor_hygon() && mutex_enabled) {
if (!hygon_psp_hooks.sev_dev_hooks_installed)
return -ENODEV;

if (mutex_enabled) {
if (psp_mutex_lock_timeout(&psp_misc->data_pg_aligned->mb_mutex,
PSP_MUTEX_TIMEOUT) != 1) {
return -EBUSY;
Expand All @@ -575,7 +584,7 @@ int vpsp_do_cmd(uint32_t vid, int cmd, void *data, int *psp_ret)

rc = __vpsp_do_cmd_locked(vid, cmd, data, psp_ret);

if (is_vendor_hygon() && mutex_enabled)
if (mutex_enabled)
psp_mutex_unlock(&psp_misc->data_pg_aligned->mb_mutex);
else
mutex_unlock(hygon_psp_hooks.sev_cmd_mutex);
Expand All @@ -586,7 +595,12 @@ int vpsp_do_cmd(uint32_t vid, int cmd, void *data, int *psp_ret)
int psp_do_cmd(int cmd, void *data, int *psp_ret)
{
int rc;
if (is_vendor_hygon()) {
int mutex_enabled = READ_ONCE(hygon_psp_hooks.psp_mutex_enabled);

if (!hygon_psp_hooks.sev_dev_hooks_installed)
return -ENODEV;

if (mutex_enabled) {
if (psp_mutex_lock_timeout(&hygon_psp_hooks.psp_misc->data_pg_aligned->mb_mutex,
PSP_MUTEX_TIMEOUT) != 1)
return -EBUSY;
Expand All @@ -595,7 +609,7 @@ int psp_do_cmd(int cmd, void *data, int *psp_ret)
}

rc = __psp_do_cmd_locked(cmd, data, psp_ret);
if (is_vendor_hygon())
if (mutex_enabled)
psp_mutex_unlock(&hygon_psp_hooks.psp_misc->data_pg_aligned->mb_mutex);
else
mutex_unlock(hygon_psp_hooks.sev_cmd_mutex);
Expand Down
17 changes: 12 additions & 5 deletions drivers/crypto/ccp/psp-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,6 @@ int psp_dev_init(struct sp_device *sp)

/* Request an irq */
if (is_vendor_hygon()) {
ret = hygon_psp_additional_setup(sp);
if (ret) {
dev_err(dev, "psp: unable to do additional setup\n");
goto e_err;
}
ret = sp_request_hygon_psp_irq(psp->sp, psp_irq_handler, psp->name, psp);
} else {
ret = sp_request_psp_irq(psp->sp, psp_irq_handler, psp->name, psp);
Expand All @@ -222,6 +217,18 @@ int psp_dev_init(struct sp_device *sp)
if (ret)
goto e_irq;

/**
* hygon_psp_additional_setup() needs to wait for
* sev_dev_install_hooks() to complete before it can be called.
*/
if (is_vendor_hygon()) {
ret = hygon_psp_additional_setup(sp);
if (ret) {
dev_err(dev, "psp: unable to do additional setup\n");
goto e_irq;
}
}

/* Enable interrupt */
iowrite32(-1, psp->io_regs + psp->vdata->inten_reg);

Expand Down
16 changes: 8 additions & 8 deletions drivers/crypto/ccp/sev-dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,13 +415,13 @@ static int sev_do_cmd(int cmd, void *data, int *psp_ret)
PSP_MUTEX_TIMEOUT) != 1)
return -EBUSY;
} else {
mutex_lock(hygon_psp_hooks.sev_cmd_mutex);
mutex_lock(&sev_cmd_mutex);
}
rc = __sev_do_cmd_locked(cmd, data, psp_ret);
if (is_vendor_hygon() && mutex_enabled)
psp_mutex_unlock(&hygon_psp_hooks.psp_misc->data_pg_aligned->mb_mutex);
else
mutex_unlock(hygon_psp_hooks.sev_cmd_mutex);
mutex_unlock(&sev_cmd_mutex);

return rc;
}
Expand Down Expand Up @@ -546,13 +546,13 @@ int sev_platform_init(int *error)
PSP_MUTEX_TIMEOUT) != 1)
return -EBUSY;
} else {
mutex_lock(hygon_psp_hooks.sev_cmd_mutex);
mutex_lock(&sev_cmd_mutex);
}
rc = __sev_platform_init_locked(error);
if (is_vendor_hygon() && mutex_enabled)
psp_mutex_unlock(&hygon_psp_hooks.psp_misc->data_pg_aligned->mb_mutex);
else
mutex_unlock(hygon_psp_hooks.sev_cmd_mutex);
mutex_unlock(&sev_cmd_mutex);

return rc;
}
Expand Down Expand Up @@ -596,13 +596,13 @@ static int sev_platform_shutdown(int *error)
PSP_MUTEX_TIMEOUT) != 1)
return -EBUSY;
} else {
mutex_lock(hygon_psp_hooks.sev_cmd_mutex);
mutex_lock(&sev_cmd_mutex);
}
rc = __sev_platform_shutdown_locked(NULL);
if (is_vendor_hygon() && mutex_enabled)
psp_mutex_unlock(&hygon_psp_hooks.psp_misc->data_pg_aligned->mb_mutex);
else
mutex_unlock(hygon_psp_hooks.sev_cmd_mutex);
mutex_unlock(&sev_cmd_mutex);

return rc;
}
Expand Down Expand Up @@ -1168,7 +1168,7 @@ static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
PSP_MUTEX_TIMEOUT) != 1)
return -EBUSY;
} else {
mutex_lock(hygon_psp_hooks.sev_cmd_mutex);
mutex_lock(&sev_cmd_mutex);
}

switch (input.cmd) {
Expand Down Expand Up @@ -1212,7 +1212,7 @@ static long sev_ioctl(struct file *file, unsigned int ioctl, unsigned long arg)
if (is_vendor_hygon() && mutex_enabled)
psp_mutex_unlock(&hygon_psp_hooks.psp_misc->data_pg_aligned->mb_mutex);
else
mutex_unlock(hygon_psp_hooks.sev_cmd_mutex);
mutex_unlock(&sev_cmd_mutex);

return ret;
}
Expand Down
Loading