From: Bartosz Golaszewski <bartosz.golaszewski@xxxxxxxxxx> Drop the DMA mapping operations from qcom_scm_qseecom_app_send() and convert all users of it in the qseecom module to using the TZ allocator for creating SCM call buffers. As this is largely a module separate from the SCM driver, let's use a separate memory pool. Set the initial size to 4K and - if we run out - add twice the current amount to the pool. Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@xxxxxxxxxx> --- .../firmware/qcom/qcom_qseecom_uefisecapp.c | 47 ++++++++++++------- drivers/firmware/qcom/qcom_scm.c | 30 +++--------- include/linux/firmware/qcom/qcom_qseecom.h | 4 +- 3 files changed, 39 insertions(+), 42 deletions(-) diff --git a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c index 1f8c5efc2b5a..0bb13c8225c2 100644 --- a/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c +++ b/drivers/firmware/qcom/qcom_qseecom_uefisecapp.c @@ -14,11 +14,14 @@ #include <linux/mutex.h> #include <linux/of.h> #include <linux/platform_device.h> +#include <linux/sizes.h> #include <linux/slab.h> #include <linux/types.h> #include <linux/ucs2_string.h> #include <linux/firmware/qcom/qcom_qseecom.h> +#include <linux/firmware/qcom/qcom_scm.h> +#include <linux/firmware/qcom/qcom_tzmem.h> /* -- Qualcomm "uefisecapp" interface definitions. -------------------------- */ @@ -254,6 +257,7 @@ struct qsee_rsp_uefi_query_variable_info { struct qcuefi_client { struct qseecom_client *client; struct efivars efivars; + struct qcom_tzmem_pool *mempool; }; static struct device *qcuefi_dev(struct qcuefi_client *qcuefi) @@ -273,8 +277,8 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e const efi_guid_t *guid, u32 *attributes, unsigned long *data_size, void *data) { - struct qsee_req_uefi_get_variable *req_data __free(kfree) = NULL; - struct qsee_rsp_uefi_get_variable *rsp_data __free(kfree) = NULL; + struct qsee_req_uefi_get_variable *req_data __free(qcom_tzmem) = NULL; + struct qsee_rsp_uefi_get_variable *rsp_data __free(qcom_tzmem) = NULL; unsigned long buffer_size = *data_size; unsigned long name_length; efi_status_t efi_status; @@ -305,11 +309,11 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e __array(u8, buffer_size) ); - req_data = kzalloc(req_size, GFP_KERNEL); + req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL); if (!req_data) return EFI_OUT_OF_RESOURCES; - rsp_data = kzalloc(rsp_size, GFP_KERNEL); + rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL); if (!rsp_data) return EFI_OUT_OF_RESOURCES; @@ -394,8 +398,8 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e const efi_guid_t *guid, u32 attributes, unsigned long data_size, const void *data) { - struct qsee_req_uefi_set_variable *req_data __free(kfree) = NULL; - struct qsee_rsp_uefi_set_variable *rsp_data __free(kfree) = NULL; + struct qsee_req_uefi_set_variable *req_data __free(qcom_tzmem) = NULL; + struct qsee_rsp_uefi_set_variable *rsp_data __free(qcom_tzmem) = NULL; unsigned long name_length; size_t name_offs; size_t guid_offs; @@ -425,11 +429,11 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e __array_offs(u8, data_size, &data_offs) ); - req_data = kzalloc(req_size, GFP_KERNEL); + req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL); if (!req_data) return EFI_OUT_OF_RESOURCES; - rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL); + rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data), GFP_KERNEL); if (!rsp_data) return EFI_OUT_OF_RESOURCES; @@ -476,8 +480,8 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi, unsigned long *name_size, efi_char16_t *name, efi_guid_t *guid) { - struct qsee_req_uefi_get_next_variable *req_data __free(kfree) = NULL; - struct qsee_rsp_uefi_get_next_variable *rsp_data __free(kfree) = NULL; + struct qsee_req_uefi_get_next_variable *req_data __free(qcom_tzmem) = NULL; + struct qsee_rsp_uefi_get_next_variable *rsp_data __free(qcom_tzmem) = NULL; efi_status_t efi_status; size_t guid_offs; size_t name_offs; @@ -503,11 +507,11 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi, __array(*name, *name_size / sizeof(*name)) ); - req_data = kzalloc(req_size, GFP_KERNEL); + req_data = qcom_tzmem_alloc(qcuefi->mempool, req_size, GFP_KERNEL); if (!req_data) return EFI_OUT_OF_RESOURCES; - rsp_data = kzalloc(rsp_size, GFP_KERNEL); + rsp_data = qcom_tzmem_alloc(qcuefi->mempool, rsp_size, GFP_KERNEL); if (!rsp_data) return EFI_OUT_OF_RESOURCES; @@ -587,15 +591,15 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi, u64 *storage_space, u64 *remaining_space, u64 *max_variable_size) { - struct qsee_req_uefi_query_variable_info *req_data __free(kfree) = NULL; - struct qsee_rsp_uefi_query_variable_info *rsp_data __free(kfree) = NULL; + struct qsee_req_uefi_query_variable_info *req_data __free(qcom_tzmem) = NULL; + struct qsee_rsp_uefi_query_variable_info *rsp_data __free(qcom_tzmem) = NULL; int status; - req_data = kzalloc(sizeof(*req_data), GFP_KERNEL); + req_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*req_data), GFP_KERNEL); if (!req_data) return EFI_OUT_OF_RESOURCES; - rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL); + rsp_data = qcom_tzmem_alloc(qcuefi->mempool, sizeof(*rsp_data), GFP_KERNEL); if (!rsp_data) return EFI_OUT_OF_RESOURCES; @@ -740,6 +744,7 @@ static const struct efivar_operations qcom_efivar_ops = { static int qcom_uefisecapp_probe(struct auxiliary_device *aux_dev, const struct auxiliary_device_id *aux_dev_id) { + struct qcom_tzmem_pool_config pool_config; struct qcuefi_client *qcuefi; int status; @@ -758,6 +763,16 @@ static int qcom_uefisecapp_probe(struct auxiliary_device *aux_dev, if (status) qcuefi_set_reference(NULL); + memset(&pool_config, 0, sizeof(pool_config)); + pool_config.initial_size = SZ_4K; + pool_config.policy = QCOM_TZMEM_POLICY_MULTIPLIER; + pool_config.increment = 2; + pool_config.max_size = SZ_256K; + + qcuefi->mempool = devm_qcom_tzmem_pool_new(&aux_dev->dev, &pool_config); + if (IS_ERR(qcuefi->mempool)) + return PTR_ERR(qcuefi->mempool); + return status; } diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index d9b189632e61..f871af4af829 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -1570,9 +1570,9 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_get_id); /** * qcom_scm_qseecom_app_send() - Send to and receive data from a given QSEE app. * @app_id: The ID of the target app. - * @req: Request buffer sent to the app (must be DMA-mappable). + * @req: Request buffer sent to the app (must be TZ memory) * @req_size: Size of the request buffer. - * @rsp: Response buffer, written to by the app (must be DMA-mappable). + * @rsp: Response buffer, written to by the app (must be TZ memory) * @rsp_size: Size of the response buffer. * * Sends a request to the QSEE app associated with the given ID and read back @@ -1588,26 +1588,12 @@ int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp, { struct qcom_scm_qseecom_resp res = {}; struct qcom_scm_desc desc = {}; - dma_addr_t req_phys; - dma_addr_t rsp_phys; + phys_addr_t req_phys; + phys_addr_t rsp_phys; int status; - /* Map request buffer */ - req_phys = dma_map_single(__scm->dev, req, req_size, DMA_TO_DEVICE); - status = dma_mapping_error(__scm->dev, req_phys); - if (status) { - dev_err(__scm->dev, "qseecom: failed to map request buffer\n"); - return status; - } - - /* Map response buffer */ - rsp_phys = dma_map_single(__scm->dev, rsp, rsp_size, DMA_FROM_DEVICE); - status = dma_mapping_error(__scm->dev, rsp_phys); - if (status) { - dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE); - dev_err(__scm->dev, "qseecom: failed to map response buffer\n"); - return status; - } + req_phys = qcom_tzmem_to_phys(req); + rsp_phys = qcom_tzmem_to_phys(rsp); /* Set up SCM call data */ desc.owner = QSEECOM_TZ_OWNER_TZ_APPS; @@ -1625,10 +1611,6 @@ int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp, /* Perform call */ status = qcom_scm_qseecom_call(&desc, &res); - /* Unmap buffers */ - dma_unmap_single(__scm->dev, rsp_phys, rsp_size, DMA_FROM_DEVICE); - dma_unmap_single(__scm->dev, req_phys, req_size, DMA_TO_DEVICE); - if (status) return status; diff --git a/include/linux/firmware/qcom/qcom_qseecom.h b/include/linux/firmware/qcom/qcom_qseecom.h index 5c28298a98be..e868fac55675 100644 --- a/include/linux/firmware/qcom/qcom_qseecom.h +++ b/include/linux/firmware/qcom/qcom_qseecom.h @@ -27,9 +27,9 @@ struct qseecom_client { /** * qcom_qseecom_app_send() - Send to and receive data from a given QSEE app. * @client: The QSEECOM client associated with the target app. - * @req: Request buffer sent to the app (must be DMA-mappable). + * @req: Request buffer sent to the app (must be TZ memory). * @req_size: Size of the request buffer. - * @rsp: Response buffer, written to by the app (must be DMA-mappable). + * @rsp: Response buffer, written to by the app (must be TZ memory). * @rsp_size: Size of the response buffer. * * Sends a request to the QSEE app associated with the given client and read -- 2.40.1