diff options
-rw-r--r-- | drivers/crypto/ccp/dbc.c | 43 | ||||
-rw-r--r-- | drivers/crypto/ccp/dbc.h | 2 | ||||
-rw-r--r-- | drivers/crypto/ccp/psp-dev.c | 32 | ||||
-rw-r--r-- | drivers/crypto/ccp/psp-dev.h | 16 |
4 files changed, 64 insertions, 29 deletions
diff --git a/drivers/crypto/ccp/dbc.c b/drivers/crypto/ccp/dbc.c index ebd7279d4001..d373caab52f8 100644 --- a/drivers/crypto/ccp/dbc.c +++ b/drivers/crypto/ccp/dbc.c @@ -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) { diff --git a/drivers/crypto/ccp/dbc.h b/drivers/crypto/ccp/dbc.h index 184646ee55bb..e0fecbe92eb1 100644 --- a/drivers/crypto/ccp/dbc.h +++ b/drivers/crypto/ccp/dbc.h @@ -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); diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c index 5f61b23695d5..124a2e0c8999 100644 --- a/drivers/crypto/ccp/psp-dev.c +++ b/drivers/crypto/ccp/psp-dev.c @@ -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; } diff --git a/drivers/crypto/ccp/psp-dev.h b/drivers/crypto/ccp/psp-dev.h index 396a80d846c0..ae582ba63729 100644 --- a/drivers/crypto/ccp/psp-dev.h +++ b/drivers/crypto/ccp/psp-dev.h @@ -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 */ |