[v7,2/5] misc: fastrpc: Add CRC support for remote buffers

Message ID 20231121094844.5764-3-quic_ekangupt@quicinc.com
State New
Headers
Series Add multimode invoke request IOCTL support |

Commit Message

Ekansh Gupta Nov. 21, 2023, 9:48 a.m. UTC
  CRC check for input and output argument helps in ensuring data
consistency over a remote call. If user intends to enable CRC check,
first local user CRC is calculated at user end and a CRC buffer is
passed to DSP to capture remote CRC values. DSP is expected to
write to the remote CRC buffer which is then compared at user level
with the local CRC values.

Signed-off-by: Ekansh Gupta <quic_ekangupt@quicinc.com>
---
Changes in v7:
  - Rebase the patch to latest kernel version

 drivers/misc/fastrpc.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
  

Comments

Srinivas Kandagatla Nov. 24, 2023, 1:26 p.m. UTC | #1
On 21/11/2023 09:48, Ekansh Gupta wrote:
> CRC check for input and output argument helps in ensuring data
> consistency over a remote call. If user intends to enable CRC check,
> first local user CRC is calculated at user end and a CRC buffer is
> passed to DSP to capture remote CRC values. DSP is expected to
> write to the remote CRC buffer which is then compared at user level
> with the local CRC values.
> 
> Signed-off-by: Ekansh Gupta <quic_ekangupt@quicinc.com>
> ---
> Changes in v7:
>    - Rebase the patch to latest kernel version
> 
>   drivers/misc/fastrpc.c | 10 +++++++++-
>   1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
> index 265e34f53c4e..55f126c779cb 100644
> --- a/drivers/misc/fastrpc.c
> +++ b/drivers/misc/fastrpc.c
> @@ -611,6 +611,7 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc(
>   	/* Released in fastrpc_context_put() */
>   	fastrpc_channel_ctx_get(cctx);
>   
> +	ctx->crc = (u32 *)(uintptr_t)invoke->crc;
>   	ctx->sc = sc;
>   	ctx->retval = -1;
>   	ctx->pid = current->pid;
> @@ -1067,6 +1068,7 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx,
>   	struct fastrpc_invoke_buf *list;
>   	struct fastrpc_phy_page *pages;
>   	u64 *fdlist;
> +	u32 *crclist;
>   	int i, inbufs, outbufs, handles;
>   
>   	inbufs = REMOTE_SCALARS_INBUFS(ctx->sc);
> @@ -1074,7 +1076,8 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx,
>   	handles = REMOTE_SCALARS_INHANDLES(ctx->sc) + REMOTE_SCALARS_OUTHANDLES(ctx->sc);
>   	list = fastrpc_invoke_buf_start(rpra, ctx->nscalars);
>   	pages = fastrpc_phy_page_start(list, ctx->nscalars);
> -	fdlist = (uint64_t *)(pages + inbufs + outbufs + handles);
> +	fdlist = (u64 *)(pages + inbufs + outbufs + handles);
> +	crclist = (u32 *)(fdlist + FASTRPC_MAX_FDLIST);
>   
>   	for (i = inbufs; i < ctx->nbufs; ++i) {
>   		if (!ctx->maps[i]) {
> @@ -1099,6 +1102,10 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx,
>   			fastrpc_map_put(mmap);
>   	}
>   
> +	if (ctx->crc && crclist && rpra) {
> +		if (copy_to_user((void __user *)ctx->crc, crclist, FASTRPC_MAX_CRCLIST * sizeof(u32)))
> +			return -EFAULT;
> +	}
>   	return 0;
>   }
>   
> @@ -1719,6 +1726,7 @@ static int fastrpc_multimode_invoke(struct fastrpc_user *fl, char __user *argp)
>   
>   	switch (invoke.req) {
>   	case FASTRPC_INVOKE:
> +	case FASTRPC_INVOKE_ENHANCED:

Isn't this change part of 1/5 patch?



>   		/* nscalars is truncated here to max supported value */
>   		if (copy_from_user(&einv, (void __user *)(uintptr_t)invoke.invparam,
>   				   invoke.size))
  

Patch

diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 265e34f53c4e..55f126c779cb 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -611,6 +611,7 @@  static struct fastrpc_invoke_ctx *fastrpc_context_alloc(
 	/* Released in fastrpc_context_put() */
 	fastrpc_channel_ctx_get(cctx);
 
+	ctx->crc = (u32 *)(uintptr_t)invoke->crc;
 	ctx->sc = sc;
 	ctx->retval = -1;
 	ctx->pid = current->pid;
@@ -1067,6 +1068,7 @@  static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx,
 	struct fastrpc_invoke_buf *list;
 	struct fastrpc_phy_page *pages;
 	u64 *fdlist;
+	u32 *crclist;
 	int i, inbufs, outbufs, handles;
 
 	inbufs = REMOTE_SCALARS_INBUFS(ctx->sc);
@@ -1074,7 +1076,8 @@  static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx,
 	handles = REMOTE_SCALARS_INHANDLES(ctx->sc) + REMOTE_SCALARS_OUTHANDLES(ctx->sc);
 	list = fastrpc_invoke_buf_start(rpra, ctx->nscalars);
 	pages = fastrpc_phy_page_start(list, ctx->nscalars);
-	fdlist = (uint64_t *)(pages + inbufs + outbufs + handles);
+	fdlist = (u64 *)(pages + inbufs + outbufs + handles);
+	crclist = (u32 *)(fdlist + FASTRPC_MAX_FDLIST);
 
 	for (i = inbufs; i < ctx->nbufs; ++i) {
 		if (!ctx->maps[i]) {
@@ -1099,6 +1102,10 @@  static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx,
 			fastrpc_map_put(mmap);
 	}
 
+	if (ctx->crc && crclist && rpra) {
+		if (copy_to_user((void __user *)ctx->crc, crclist, FASTRPC_MAX_CRCLIST * sizeof(u32)))
+			return -EFAULT;
+	}
 	return 0;
 }
 
@@ -1719,6 +1726,7 @@  static int fastrpc_multimode_invoke(struct fastrpc_user *fl, char __user *argp)
 
 	switch (invoke.req) {
 	case FASTRPC_INVOKE:
+	case FASTRPC_INVOKE_ENHANCED:
 		/* nscalars is truncated here to max supported value */
 		if (copy_from_user(&einv, (void __user *)(uintptr_t)invoke.invparam,
 				   invoke.size))