Commit 14672a9b authored by Arnd Bergmann's avatar Arnd Bergmann

Merge tag 'qcom-drivers-fixes-for-6.9' of...

Merge tag 'qcom-drivers-fixes-for-6.9' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into for-next

Qualcomm driver fix for v6.9

This reworks the memory layout of the argument buffers passed to trusted
applications in QSEECOM, to avoid failures and system crashes.

* tag 'qcom-drivers-fixes-for-6.9' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux:
  firmware: qcom: uefisecapp: Fix memory related IO errors and crashes

Link: https://lore.kernel.org/r/20240420163816.1133528-1-andersson@kernel.orgSigned-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 7e685383 ed09f81e
...@@ -221,6 +221,19 @@ struct qsee_rsp_uefi_query_variable_info { ...@@ -221,6 +221,19 @@ struct qsee_rsp_uefi_query_variable_info {
* alignment of 8 bytes (64 bits) for GUIDs. Our definition of efi_guid_t, * alignment of 8 bytes (64 bits) for GUIDs. Our definition of efi_guid_t,
* however, has an alignment of 4 byte (32 bits). So far, this seems to work * however, has an alignment of 4 byte (32 bits). So far, this seems to work
* fine here. See also the comment on the typedef of efi_guid_t. * fine here. See also the comment on the typedef of efi_guid_t.
*
* Note: It looks like uefisecapp is quite picky about how the memory passed to
* it is structured and aligned. In particular the request/response setup used
* for QSEE_CMD_UEFI_GET_VARIABLE. While qcom_qseecom_app_send(), in theory,
* accepts separate buffers/addresses for the request and response parts, in
* practice, however, it seems to expect them to be both part of a larger
* contiguous block. We initially allocated separate buffers for the request
* and response but this caused the QSEE_CMD_UEFI_GET_VARIABLE command to
* either not write any response to the response buffer or outright crash the
* device. Therefore, we now allocate a single contiguous block of DMA memory
* for both and properly align the data using the macros below. In particular,
* request and response structs are aligned at 8 byte (via __reqdata_offs()),
* following the driver that this has been reverse-engineered from.
*/ */
#define qcuefi_buf_align_fields(fields...) \ #define qcuefi_buf_align_fields(fields...) \
({ \ ({ \
...@@ -244,6 +257,12 @@ struct qsee_rsp_uefi_query_variable_info { ...@@ -244,6 +257,12 @@ struct qsee_rsp_uefi_query_variable_info {
#define __array_offs(type, count, offset) \ #define __array_offs(type, count, offset) \
__field_impl(sizeof(type) * (count), __alignof__(type), offset) __field_impl(sizeof(type) * (count), __alignof__(type), offset)
#define __array_offs_aligned(type, count, align, offset) \
__field_impl(sizeof(type) * (count), align, offset)
#define __reqdata_offs(size, offset) \
__array_offs_aligned(u8, size, 8, offset)
#define __array(type, count) __array_offs(type, count, NULL) #define __array(type, count) __array_offs(type, count, NULL)
#define __field_offs(type, offset) __array_offs(type, 1, offset) #define __field_offs(type, offset) __array_offs(type, 1, offset)
#define __field(type) __array_offs(type, 1, NULL) #define __field(type) __array_offs(type, 1, NULL)
...@@ -277,10 +296,15 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e ...@@ -277,10 +296,15 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
unsigned long buffer_size = *data_size; unsigned long buffer_size = *data_size;
efi_status_t efi_status = EFI_SUCCESS; efi_status_t efi_status = EFI_SUCCESS;
unsigned long name_length; unsigned long name_length;
dma_addr_t cmd_buf_dma;
size_t cmd_buf_size;
void *cmd_buf;
size_t guid_offs; size_t guid_offs;
size_t name_offs; size_t name_offs;
size_t req_size; size_t req_size;
size_t rsp_size; size_t rsp_size;
size_t req_offs;
size_t rsp_offs;
ssize_t status; ssize_t status;
if (!name || !guid) if (!name || !guid)
...@@ -304,17 +328,19 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e ...@@ -304,17 +328,19 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
__array(u8, buffer_size) __array(u8, buffer_size)
); );
req_data = kzalloc(req_size, GFP_KERNEL); cmd_buf_size = qcuefi_buf_align_fields(
if (!req_data) { __reqdata_offs(req_size, &req_offs)
__reqdata_offs(rsp_size, &rsp_offs)
);
cmd_buf = qseecom_dma_alloc(qcuefi->client, cmd_buf_size, &cmd_buf_dma, GFP_KERNEL);
if (!cmd_buf) {
efi_status = EFI_OUT_OF_RESOURCES; efi_status = EFI_OUT_OF_RESOURCES;
goto out; goto out;
} }
rsp_data = kzalloc(rsp_size, GFP_KERNEL); req_data = cmd_buf + req_offs;
if (!rsp_data) { rsp_data = cmd_buf + rsp_offs;
efi_status = EFI_OUT_OF_RESOURCES;
goto out_free_req;
}
req_data->command_id = QSEE_CMD_UEFI_GET_VARIABLE; req_data->command_id = QSEE_CMD_UEFI_GET_VARIABLE;
req_data->data_size = buffer_size; req_data->data_size = buffer_size;
...@@ -332,7 +358,9 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e ...@@ -332,7 +358,9 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size); memcpy(((void *)req_data) + req_data->guid_offset, guid, req_data->guid_size);
status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size); status = qcom_qseecom_app_send(qcuefi->client,
cmd_buf_dma + req_offs, req_size,
cmd_buf_dma + rsp_offs, rsp_size);
if (status) { if (status) {
efi_status = EFI_DEVICE_ERROR; efi_status = EFI_DEVICE_ERROR;
goto out_free; goto out_free;
...@@ -407,9 +435,7 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e ...@@ -407,9 +435,7 @@ static efi_status_t qsee_uefi_get_variable(struct qcuefi_client *qcuefi, const e
memcpy(data, ((void *)rsp_data) + rsp_data->data_offset, rsp_data->data_size); memcpy(data, ((void *)rsp_data) + rsp_data->data_offset, rsp_data->data_size);
out_free: out_free:
kfree(rsp_data); qseecom_dma_free(qcuefi->client, cmd_buf_size, cmd_buf, cmd_buf_dma);
out_free_req:
kfree(req_data);
out: out:
return efi_status; return efi_status;
} }
...@@ -422,10 +448,15 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e ...@@ -422,10 +448,15 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
struct qsee_rsp_uefi_set_variable *rsp_data; struct qsee_rsp_uefi_set_variable *rsp_data;
efi_status_t efi_status = EFI_SUCCESS; efi_status_t efi_status = EFI_SUCCESS;
unsigned long name_length; unsigned long name_length;
dma_addr_t cmd_buf_dma;
size_t cmd_buf_size;
void *cmd_buf;
size_t name_offs; size_t name_offs;
size_t guid_offs; size_t guid_offs;
size_t data_offs; size_t data_offs;
size_t req_size; size_t req_size;
size_t req_offs;
size_t rsp_offs;
ssize_t status; ssize_t status;
if (!name || !guid) if (!name || !guid)
...@@ -450,17 +481,19 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e ...@@ -450,17 +481,19 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
__array_offs(u8, data_size, &data_offs) __array_offs(u8, data_size, &data_offs)
); );
req_data = kzalloc(req_size, GFP_KERNEL); cmd_buf_size = qcuefi_buf_align_fields(
if (!req_data) { __reqdata_offs(req_size, &req_offs)
__reqdata_offs(sizeof(*rsp_data), &rsp_offs)
);
cmd_buf = qseecom_dma_alloc(qcuefi->client, cmd_buf_size, &cmd_buf_dma, GFP_KERNEL);
if (!cmd_buf) {
efi_status = EFI_OUT_OF_RESOURCES; efi_status = EFI_OUT_OF_RESOURCES;
goto out; goto out;
} }
rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL); req_data = cmd_buf + req_offs;
if (!rsp_data) { rsp_data = cmd_buf + rsp_offs;
efi_status = EFI_OUT_OF_RESOURCES;
goto out_free_req;
}
req_data->command_id = QSEE_CMD_UEFI_SET_VARIABLE; req_data->command_id = QSEE_CMD_UEFI_SET_VARIABLE;
req_data->attributes = attributes; req_data->attributes = attributes;
...@@ -483,8 +516,9 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e ...@@ -483,8 +516,9 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
if (data_size) if (data_size)
memcpy(((void *)req_data) + req_data->data_offset, data, req_data->data_size); memcpy(((void *)req_data) + req_data->data_offset, data, req_data->data_size);
status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, status = qcom_qseecom_app_send(qcuefi->client,
sizeof(*rsp_data)); cmd_buf_dma + req_offs, req_size,
cmd_buf_dma + rsp_offs, sizeof(*rsp_data));
if (status) { if (status) {
efi_status = EFI_DEVICE_ERROR; efi_status = EFI_DEVICE_ERROR;
goto out_free; goto out_free;
...@@ -507,9 +541,7 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e ...@@ -507,9 +541,7 @@ static efi_status_t qsee_uefi_set_variable(struct qcuefi_client *qcuefi, const e
} }
out_free: out_free:
kfree(rsp_data); qseecom_dma_free(qcuefi->client, cmd_buf_size, cmd_buf, cmd_buf_dma);
out_free_req:
kfree(req_data);
out: out:
return efi_status; return efi_status;
} }
...@@ -521,10 +553,15 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi, ...@@ -521,10 +553,15 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
struct qsee_req_uefi_get_next_variable *req_data; struct qsee_req_uefi_get_next_variable *req_data;
struct qsee_rsp_uefi_get_next_variable *rsp_data; struct qsee_rsp_uefi_get_next_variable *rsp_data;
efi_status_t efi_status = EFI_SUCCESS; efi_status_t efi_status = EFI_SUCCESS;
dma_addr_t cmd_buf_dma;
size_t cmd_buf_size;
void *cmd_buf;
size_t guid_offs; size_t guid_offs;
size_t name_offs; size_t name_offs;
size_t req_size; size_t req_size;
size_t rsp_size; size_t rsp_size;
size_t req_offs;
size_t rsp_offs;
ssize_t status; ssize_t status;
if (!name_size || !name || !guid) if (!name_size || !name || !guid)
...@@ -545,17 +582,19 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi, ...@@ -545,17 +582,19 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
__array(*name, *name_size / sizeof(*name)) __array(*name, *name_size / sizeof(*name))
); );
req_data = kzalloc(req_size, GFP_KERNEL); cmd_buf_size = qcuefi_buf_align_fields(
if (!req_data) { __reqdata_offs(req_size, &req_offs)
__reqdata_offs(rsp_size, &rsp_offs)
);
cmd_buf = qseecom_dma_alloc(qcuefi->client, cmd_buf_size, &cmd_buf_dma, GFP_KERNEL);
if (!cmd_buf) {
efi_status = EFI_OUT_OF_RESOURCES; efi_status = EFI_OUT_OF_RESOURCES;
goto out; goto out;
} }
rsp_data = kzalloc(rsp_size, GFP_KERNEL); req_data = cmd_buf + req_offs;
if (!rsp_data) { rsp_data = cmd_buf + rsp_offs;
efi_status = EFI_OUT_OF_RESOURCES;
goto out_free_req;
}
req_data->command_id = QSEE_CMD_UEFI_GET_NEXT_VARIABLE; req_data->command_id = QSEE_CMD_UEFI_GET_NEXT_VARIABLE;
req_data->guid_offset = guid_offs; req_data->guid_offset = guid_offs;
...@@ -572,7 +611,9 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi, ...@@ -572,7 +611,9 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
goto out_free; goto out_free;
} }
status = qcom_qseecom_app_send(qcuefi->client, req_data, req_size, rsp_data, rsp_size); status = qcom_qseecom_app_send(qcuefi->client,
cmd_buf_dma + req_offs, req_size,
cmd_buf_dma + rsp_offs, rsp_size);
if (status) { if (status) {
efi_status = EFI_DEVICE_ERROR; efi_status = EFI_DEVICE_ERROR;
goto out_free; goto out_free;
...@@ -645,9 +686,7 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi, ...@@ -645,9 +686,7 @@ static efi_status_t qsee_uefi_get_next_variable(struct qcuefi_client *qcuefi,
} }
out_free: out_free:
kfree(rsp_data); qseecom_dma_free(qcuefi->client, cmd_buf_size, cmd_buf, cmd_buf_dma);
out_free_req:
kfree(req_data);
out: out:
return efi_status; return efi_status;
} }
...@@ -659,26 +698,34 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi, ...@@ -659,26 +698,34 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi,
struct qsee_req_uefi_query_variable_info *req_data; struct qsee_req_uefi_query_variable_info *req_data;
struct qsee_rsp_uefi_query_variable_info *rsp_data; struct qsee_rsp_uefi_query_variable_info *rsp_data;
efi_status_t efi_status = EFI_SUCCESS; efi_status_t efi_status = EFI_SUCCESS;
dma_addr_t cmd_buf_dma;
size_t cmd_buf_size;
void *cmd_buf;
size_t req_offs;
size_t rsp_offs;
int status; int status;
req_data = kzalloc(sizeof(*req_data), GFP_KERNEL); cmd_buf_size = qcuefi_buf_align_fields(
if (!req_data) { __reqdata_offs(sizeof(*req_data), &req_offs)
__reqdata_offs(sizeof(*rsp_data), &rsp_offs)
);
cmd_buf = qseecom_dma_alloc(qcuefi->client, cmd_buf_size, &cmd_buf_dma, GFP_KERNEL);
if (!cmd_buf) {
efi_status = EFI_OUT_OF_RESOURCES; efi_status = EFI_OUT_OF_RESOURCES;
goto out; goto out;
} }
rsp_data = kzalloc(sizeof(*rsp_data), GFP_KERNEL); req_data = cmd_buf + req_offs;
if (!rsp_data) { rsp_data = cmd_buf + rsp_offs;
efi_status = EFI_OUT_OF_RESOURCES;
goto out_free_req;
}
req_data->command_id = QSEE_CMD_UEFI_QUERY_VARIABLE_INFO; req_data->command_id = QSEE_CMD_UEFI_QUERY_VARIABLE_INFO;
req_data->attributes = attr; req_data->attributes = attr;
req_data->length = sizeof(*req_data); req_data->length = sizeof(*req_data);
status = qcom_qseecom_app_send(qcuefi->client, req_data, sizeof(*req_data), rsp_data, status = qcom_qseecom_app_send(qcuefi->client,
sizeof(*rsp_data)); cmd_buf_dma + req_offs, sizeof(*req_data),
cmd_buf_dma + rsp_offs, sizeof(*rsp_data));
if (status) { if (status) {
efi_status = EFI_DEVICE_ERROR; efi_status = EFI_DEVICE_ERROR;
goto out_free; goto out_free;
...@@ -711,9 +758,7 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi, ...@@ -711,9 +758,7 @@ static efi_status_t qsee_uefi_query_variable_info(struct qcuefi_client *qcuefi,
*max_variable_size = rsp_data->max_variable_size; *max_variable_size = rsp_data->max_variable_size;
out_free: out_free:
kfree(rsp_data); qseecom_dma_free(qcuefi->client, cmd_buf_size, cmd_buf, cmd_buf_dma);
out_free_req:
kfree(req_data);
out: out:
return efi_status; return efi_status;
} }
......
...@@ -1576,9 +1576,9 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_get_id); ...@@ -1576,9 +1576,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. * qcom_scm_qseecom_app_send() - Send to and receive data from a given QSEE app.
* @app_id: The ID of the target app. * @app_id: The ID of the target app.
* @req: Request buffer sent to the app (must be DMA-mappable). * @req: DMA address of the request buffer sent to the app.
* @req_size: Size of the request buffer. * @req_size: Size of the request buffer.
* @rsp: Response buffer, written to by the app (must be DMA-mappable). * @rsp: DMA address of the response buffer, written to by the app.
* @rsp_size: Size of the response buffer. * @rsp_size: Size of the response buffer.
* *
* Sends a request to the QSEE app associated with the given ID and read back * Sends a request to the QSEE app associated with the given ID and read back
...@@ -1589,33 +1589,13 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_get_id); ...@@ -1589,33 +1589,13 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_get_id);
* *
* Return: Zero on success, nonzero on failure. * Return: Zero on success, nonzero on failure.
*/ */
int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp, int qcom_scm_qseecom_app_send(u32 app_id, dma_addr_t req, size_t req_size,
size_t rsp_size) dma_addr_t rsp, size_t rsp_size)
{ {
struct qcom_scm_qseecom_resp res = {}; struct qcom_scm_qseecom_resp res = {};
struct qcom_scm_desc desc = {}; struct qcom_scm_desc desc = {};
dma_addr_t req_phys;
dma_addr_t rsp_phys;
int status; 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;
}
/* Set up SCM call data */
desc.owner = QSEECOM_TZ_OWNER_TZ_APPS; desc.owner = QSEECOM_TZ_OWNER_TZ_APPS;
desc.svc = QSEECOM_TZ_SVC_APP_ID_PLACEHOLDER; desc.svc = QSEECOM_TZ_SVC_APP_ID_PLACEHOLDER;
desc.cmd = QSEECOM_TZ_CMD_APP_SEND; desc.cmd = QSEECOM_TZ_CMD_APP_SEND;
...@@ -1623,18 +1603,13 @@ int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp, ...@@ -1623,18 +1603,13 @@ int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp,
QCOM_SCM_RW, QCOM_SCM_VAL, QCOM_SCM_RW, QCOM_SCM_VAL,
QCOM_SCM_RW, QCOM_SCM_VAL); QCOM_SCM_RW, QCOM_SCM_VAL);
desc.args[0] = app_id; desc.args[0] = app_id;
desc.args[1] = req_phys; desc.args[1] = req;
desc.args[2] = req_size; desc.args[2] = req_size;
desc.args[3] = rsp_phys; desc.args[3] = rsp;
desc.args[4] = rsp_size; desc.args[4] = rsp_size;
/* Perform call */
status = qcom_scm_qseecom_call(&desc, &res); 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) if (status)
return status; return status;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define __QCOM_QSEECOM_H #define __QCOM_QSEECOM_H
#include <linux/auxiliary_bus.h> #include <linux/auxiliary_bus.h>
#include <linux/dma-mapping.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/firmware/qcom/qcom_scm.h> #include <linux/firmware/qcom/qcom_scm.h>
...@@ -24,12 +25,57 @@ struct qseecom_client { ...@@ -24,12 +25,57 @@ struct qseecom_client {
u32 app_id; u32 app_id;
}; };
/**
* qseecom_scm_dev() - Get the SCM device associated with the QSEECOM client.
* @client: The QSEECOM client device.
*
* Returns the SCM device under which the provided QSEECOM client device
* operates. This function is intended to be used for DMA allocations.
*/
static inline struct device *qseecom_scm_dev(struct qseecom_client *client)
{
return client->aux_dev.dev.parent->parent;
}
/**
* qseecom_dma_alloc() - Allocate DMA memory for a QSEECOM client.
* @client: The QSEECOM client to allocate the memory for.
* @size: The number of bytes to allocate.
* @dma_handle: Pointer to where the DMA address should be stored.
* @gfp: Allocation flags.
*
* Wrapper function for dma_alloc_coherent(), allocating DMA memory usable for
* TZ/QSEECOM communication. Refer to dma_alloc_coherent() for details.
*/
static inline void *qseecom_dma_alloc(struct qseecom_client *client, size_t size,
dma_addr_t *dma_handle, gfp_t gfp)
{
return dma_alloc_coherent(qseecom_scm_dev(client), size, dma_handle, gfp);
}
/**
* dma_free_coherent() - Free QSEECOM DMA memory.
* @client: The QSEECOM client for which the memory has been allocated.
* @size: The number of bytes allocated.
* @cpu_addr: Virtual memory address to free.
* @dma_handle: DMA memory address to free.
*
* Wrapper function for dma_free_coherent(), freeing memory previously
* allocated with qseecom_dma_alloc(). Refer to dma_free_coherent() for
* details.
*/
static inline void qseecom_dma_free(struct qseecom_client *client, size_t size,
void *cpu_addr, dma_addr_t dma_handle)
{
return dma_free_coherent(qseecom_scm_dev(client), size, cpu_addr, dma_handle);
}
/** /**
* qcom_qseecom_app_send() - Send to and receive data from a given QSEE app. * qcom_qseecom_app_send() - Send to and receive data from a given QSEE app.
* @client: The QSEECOM client associated with the target app. * @client: The QSEECOM client associated with the target app.
* @req: Request buffer sent to the app (must be DMA-mappable). * @req: DMA address of the request buffer sent to the app.
* @req_size: Size of the request buffer. * @req_size: Size of the request buffer.
* @rsp: Response buffer, written to by the app (must be DMA-mappable). * @rsp: DMA address of the response buffer, written to by the app.
* @rsp_size: Size of the response buffer. * @rsp_size: Size of the response buffer.
* *
* Sends a request to the QSEE app associated with the given client and read * Sends a request to the QSEE app associated with the given client and read
...@@ -43,8 +89,9 @@ struct qseecom_client { ...@@ -43,8 +89,9 @@ struct qseecom_client {
* *
* Return: Zero on success, nonzero on failure. * Return: Zero on success, nonzero on failure.
*/ */
static inline int qcom_qseecom_app_send(struct qseecom_client *client, void *req, size_t req_size, static inline int qcom_qseecom_app_send(struct qseecom_client *client,
void *rsp, size_t rsp_size) dma_addr_t req, size_t req_size,
dma_addr_t rsp, size_t rsp_size)
{ {
return qcom_scm_qseecom_app_send(client->app_id, req, req_size, rsp, rsp_size); return qcom_scm_qseecom_app_send(client->app_id, req, req_size, rsp, rsp_size);
} }
......
...@@ -118,8 +118,8 @@ bool qcom_scm_lmh_dcvsh_available(void); ...@@ -118,8 +118,8 @@ bool qcom_scm_lmh_dcvsh_available(void);
#ifdef CONFIG_QCOM_QSEECOM #ifdef CONFIG_QCOM_QSEECOM
int qcom_scm_qseecom_app_get_id(const char *app_name, u32 *app_id); int qcom_scm_qseecom_app_get_id(const char *app_name, u32 *app_id);
int qcom_scm_qseecom_app_send(u32 app_id, void *req, size_t req_size, void *rsp, int qcom_scm_qseecom_app_send(u32 app_id, dma_addr_t req, size_t req_size,
size_t rsp_size); dma_addr_t rsp, size_t rsp_size);
#else /* CONFIG_QCOM_QSEECOM */ #else /* CONFIG_QCOM_QSEECOM */
...@@ -128,9 +128,9 @@ static inline int qcom_scm_qseecom_app_get_id(const char *app_name, u32 *app_id) ...@@ -128,9 +128,9 @@ static inline int qcom_scm_qseecom_app_get_id(const char *app_name, u32 *app_id)
return -EINVAL; return -EINVAL;
} }
static inline int qcom_scm_qseecom_app_send(u32 app_id, void *req, static inline int qcom_scm_qseecom_app_send(u32 app_id,
size_t req_size, void *rsp, dma_addr_t req, size_t req_size,
size_t rsp_size) dma_addr_t rsp, size_t rsp_size)
{ {
return -EINVAL; return -EINVAL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment