crypto: ccp - Add support for DBC over PSP mailbox

On some SOCs DBC is supported through the PSP mailbox instead of
the platform mailbox. This capability is advertised in the PSP
capabilities register. Allow using this communication path if
supported.

Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Mario Limonciello 2023-09-07 13:48:46 -05:00 committed by Herbert Xu
parent 3d5845e180
commit 0470bb1b71
4 changed files with 64 additions and 29 deletions

View file

@ -9,6 +9,7 @@
#include "dbc.h"
#define DBC_DEFAULT_TIMEOUT (10 * MSEC_PER_SEC)
struct error_map {
u32 psp;
int ret;
@ -37,13 +38,28 @@ static struct error_map error_codes[] = {
{0x0, 0x0},
};
static int send_dbc_cmd(struct psp_dbc_device *dbc_dev,
enum psp_platform_access_msg msg)
static inline int send_dbc_cmd_thru_ext(struct psp_dbc_device *dbc_dev, int msg)
{
dbc_dev->mbox->ext_req.header.sub_cmd_id = msg;
return psp_extended_mailbox_cmd(dbc_dev->psp,
DBC_DEFAULT_TIMEOUT,
(struct psp_ext_request *)dbc_dev->mbox);
}
static inline int send_dbc_cmd_thru_pa(struct psp_dbc_device *dbc_dev, int msg)
{
return psp_send_platform_access_msg(msg,
(struct psp_request *)dbc_dev->mbox);
}
static int send_dbc_cmd(struct psp_dbc_device *dbc_dev, int msg)
{
int ret;
*dbc_dev->result = 0;
ret = psp_send_platform_access_msg(msg, (struct psp_request *)dbc_dev->mbox);
ret = dbc_dev->use_ext ? send_dbc_cmd_thru_ext(dbc_dev, msg) :
send_dbc_cmd_thru_pa(dbc_dev, msg);
if (ret == -EIO) {
int i;
@ -192,9 +208,6 @@ int dbc_dev_init(struct psp_device *psp)
struct psp_dbc_device *dbc_dev;
int ret;
if (!PSP_FEATURE(psp, DBC))
return 0;
dbc_dev = devm_kzalloc(dev, sizeof(*dbc_dev), GFP_KERNEL);
if (!dbc_dev)
return -ENOMEM;
@ -208,10 +221,20 @@ int dbc_dev_init(struct psp_device *psp)
psp->dbc_data = dbc_dev;
dbc_dev->dev = dev;
dbc_dev->payload_size = &dbc_dev->mbox->pa_req.header.payload_size;
dbc_dev->result = &dbc_dev->mbox->pa_req.header.status;
dbc_dev->payload = &dbc_dev->mbox->pa_req.buf;
dbc_dev->header_size = sizeof(struct psp_req_buffer_hdr);
dbc_dev->psp = psp;
if (PSP_CAPABILITY(psp, DBC_THRU_EXT)) {
dbc_dev->use_ext = true;
dbc_dev->payload_size = &dbc_dev->mbox->ext_req.header.payload_size;
dbc_dev->result = &dbc_dev->mbox->ext_req.header.status;
dbc_dev->payload = &dbc_dev->mbox->ext_req.buf;
dbc_dev->header_size = sizeof(struct psp_ext_req_buffer_hdr);
} else {
dbc_dev->payload_size = &dbc_dev->mbox->pa_req.header.payload_size;
dbc_dev->result = &dbc_dev->mbox->pa_req.header.status;
dbc_dev->payload = &dbc_dev->mbox->pa_req.buf;
dbc_dev->header_size = sizeof(struct psp_req_buffer_hdr);
}
ret = send_dbc_nonce(dbc_dev);
if (ret == -EACCES) {

View file

@ -20,6 +20,7 @@
struct psp_dbc_device {
struct device *dev;
struct psp_device *psp;
union dbc_buffer *mbox;
@ -37,6 +38,7 @@ struct psp_dbc_device {
union dbc_buffer {
struct psp_request pa_req;
struct psp_ext_request ext_req;
};
void dbc_dev_destroy(struct psp_device *psp);

View file

@ -187,23 +187,6 @@ static int psp_check_tee_support(struct psp_device *psp)
return 0;
}
static void psp_init_platform_access(struct psp_device *psp)
{
int ret;
ret = platform_access_dev_init(psp);
if (ret) {
dev_warn(psp->dev, "platform access init failed: %d\n", ret);
return;
}
/* dbc must come after platform access as it tests the feature */
ret = dbc_dev_init(psp);
if (ret)
dev_warn(psp->dev, "failed to init dynamic boost control: %d\n",
ret);
}
static int psp_init(struct psp_device *psp)
{
int ret;
@ -220,8 +203,19 @@ static int psp_init(struct psp_device *psp)
return ret;
}
if (psp->vdata->platform_access)
psp_init_platform_access(psp);
if (psp->vdata->platform_access) {
ret = platform_access_dev_init(psp);
if (ret)
return ret;
}
/* dbc must come after platform access as it tests the feature */
if (PSP_FEATURE(psp, DBC) ||
PSP_CAPABILITY(psp, DBC_THRU_EXT)) {
ret = dbc_dev_init(psp);
if (ret)
return ret;
}
return 0;
}

View file

@ -16,6 +16,7 @@
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/psp.h>
#include <linux/psp-platform-access.h>
#include "sp-dev.h"
@ -56,6 +57,7 @@ struct psp_device *psp_get_master_device(void);
#define PSP_CAPABILITY_SEV BIT(0)
#define PSP_CAPABILITY_TEE BIT(1)
#define PSP_CAPABILITY_DBC_THRU_EXT BIT(2)
#define PSP_CAPABILITY_PSP_SECURITY_REPORTING BIT(7)
#define PSP_CAPABILITY_PSP_SECURITY_OFFSET 8
@ -108,6 +110,20 @@ struct psp_ext_request {
void *buf;
} __packed;
/**
* enum psp_sub_cmd - PSP mailbox sub commands
* @PSP_SUB_CMD_DBC_GET_NONCE: Get nonce from DBC
* @PSP_SUB_CMD_DBC_SET_UID: Set UID for DBC
* @PSP_SUB_CMD_DBC_GET_PARAMETER: Get parameter from DBC
* @PSP_SUB_CMD_DBC_SET_PARAMETER: Set parameter for DBC
*/
enum psp_sub_cmd {
PSP_SUB_CMD_DBC_GET_NONCE = PSP_DYNAMIC_BOOST_GET_NONCE,
PSP_SUB_CMD_DBC_SET_UID = PSP_DYNAMIC_BOOST_SET_UID,
PSP_SUB_CMD_DBC_GET_PARAMETER = PSP_DYNAMIC_BOOST_GET_PARAMETER,
PSP_SUB_CMD_DBC_SET_PARAMETER = PSP_DYNAMIC_BOOST_SET_PARAMETER,
};
int psp_extended_mailbox_cmd(struct psp_device *psp, unsigned int timeout_msecs,
struct psp_ext_request *req);
#endif /* __PSP_DEV_H */