diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index a33767bff3..405929d100 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -119,72 +119,6 @@ struct eva_kmd_client_data { __u32 client_data1; __u32 client_data2; }; -struct cvp_buf_type { - __s32 fd; - __u32 size; - __u32 offset; - __u32 flags; - __u32 reserved1; - __u32 reserved2; - __u32 fence_type; - __u32 input_handle; - __u32 output_handle; - __u32 debug_flags; - __u32 crc; -}; - -/** - * Structures and macros for Out-of-Band (OOB) buffer - * that may accompany HFI packet data - */ - -#define EVA_KMD_WNCC_MAX_LAYERS 4 -#define EVA_KMD_WNCC_MAX_ADDRESSES 4095 -#define EVA_KMD_WNCC_MAX_SRC_BUFS 2400 -#define EVA_KMD_WNCC_SRC_BUF_ID_OFFSET 1 - -/** - * Macro to get Meta Data Buffer Offset from the HFI Packet - * The number 15 denotes the position of the first Meta Data Buffer with respect to other fields - * If the WARPNCC HFI Frame Packet changes, this macro definition also has to be revised - */ - -#define EVA_KMD_WNCC_HFI_METADATA_BUFS_OFFSET (15 + sizeof(struct cvp_buf_type) / sizeof(__u32) * 5) - -struct eva_kmd_wncc_metadata { - __u64 loc_x_dec : 12; - __u64 loc_x_frac : 9; - __u64 loc_y_dec : 12; - __u64 loc_y_frac : 9; - __u64 iova_lsb : 22; /* Populated in KMD */ - __u64 iova_msb : 10; /* Populated in KMD */ - __u64 scale_idx : 2; - __s64 aff_coeff_3 : 13; - __s64 aff_coeff_2 : 13; - __s64 aff_coeff_1 : 13; - __s64 aff_coeff_0 : 13; -}; - -struct eva_kmd_oob_wncc { - __u32 num_layers; - struct eva_kmd_wncc_layer { - __u32 num_addrs; - struct eva_kmd_wncc_addr { - __u32 buffer_id; - __u32 offset; - } addrs[EVA_KMD_WNCC_MAX_ADDRESSES]; - } layers[EVA_KMD_WNCC_MAX_LAYERS]; -}; - -#define EVA_KMD_OOB_INVALID 0 -#define EVA_KMD_OOB_WNCC 1 - -struct eva_kmd_oob_buf { - __u32 oob_type; - union { - struct eva_kmd_oob_wncc wncc; - }; -}; /** * Structures and macros for KMD arg data @@ -194,7 +128,7 @@ struct eva_kmd_oob_buf { struct eva_kmd_hfi_packet { __u32 pkt_data[MAX_HFI_PKT_SIZE]; - struct eva_kmd_oob_buf *oob_buf; + void *oob_buf; }; #define EVA_KMD_PROP_HFI_VERSION 1 diff --git a/msm/eva/eva_shared_def.h b/msm/eva/eva_shared_def.h new file mode 100644 index 0000000000..b2a41c722e --- /dev/null +++ b/msm/eva/eva_shared_def.h @@ -0,0 +1,86 @@ +/** + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +/** + * This file contains definitions that are common to UMD and KMD + * but shall not be added to the UAPI to allow for better UAPI + * backward compatibility. Identical copies of this file must be + * used by both UMD and KMD for desired functioning. + */ + +#ifndef _EVA_SHARED_DEF_H_ +#define _EVA_SHARED_DEF_H_ + +/** + * Structure corresponding to HFI_CVP_BUFFER_TYPE + */ + +struct cvp_buf_type { + __s32 fd; + __u32 size; + __u32 offset; + __u32 flags; + __u32 reserved1; + __u32 reserved2; + __u32 fence_type; + __u32 input_handle; + __u32 output_handle; + __u32 debug_flags; + __u32 crc; +}; + +/** + * Structures and macros for Warp-NCC Out-of-Band (OOB) buffer + */ + +#define EVA_KMD_WNCC_MAX_LAYERS 4 +#define EVA_KMD_WNCC_MAX_ADDRESSES 4095 +#define EVA_KMD_WNCC_MAX_SRC_BUFS 2400 +#define EVA_KMD_WNCC_SRC_BUF_ID_OFFSET 1 + +struct eva_kmd_wncc_metadata { + __u64 loc_x_dec : 12; + __u64 loc_x_frac : 9; + __u64 loc_y_dec : 12; + __u64 loc_y_frac : 9; + __u64 iova_lsb : 22; /* Populated in KMD */ + __u64 iova_msb : 10; /* Populated in KMD */ + __u64 scale_idx : 2; + __s64 aff_coeff_3 : 13; + __s64 aff_coeff_2 : 13; + __s64 aff_coeff_1 : 13; + __s64 aff_coeff_0 : 13; +}; + +struct eva_kmd_oob_wncc { + __u32 metadata_bufs_offset; + __u32 num_layers; + struct eva_kmd_wncc_layer { + __u32 num_addrs; + struct eva_kmd_wncc_addr { + __u32 buffer_id; + __u32 offset; + } addrs[EVA_KMD_WNCC_MAX_ADDRESSES]; + } layers[EVA_KMD_WNCC_MAX_LAYERS]; +}; + +/** + * Structure and macros for Out-of-Band (OOB) buffer + * that may accompany HFI packet data + */ + +#define EVA_KMD_OOB_INVALID 0 +#define EVA_KMD_OOB_WNCC 1 + +struct eva_kmd_oob_buf { + __u32 oob_type; + union { + struct eva_kmd_oob_wncc wncc; + }; +}; + +#endif diff --git a/msm/eva/msm_cvp.h b/msm/eva/msm_cvp.h index eab8e0a3e9..4f78e5327e 100644 --- a/msm/eva/msm_cvp.h +++ b/msm/eva/msm_cvp.h @@ -11,6 +11,7 @@ #include "msm_cvp_clocks.h" #include "msm_cvp_debug.h" #include "msm_cvp_dsp.h" +#include "eva_shared_def.h" static inline bool is_buf_param_valid(u32 buf_num, u32 offset) { diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 491bf2bc4e..83ea6fadad 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -15,6 +15,7 @@ #include "msm_cvp_debug.h" #include "msm_cvp_core.h" #include "msm_cvp_dsp.h" +#include "eva_shared_def.h" #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)) #define eva_buf_map dma_buf_map @@ -42,7 +43,8 @@ static void _wncc_print_cvpwnccbufs_table(struct msm_cvp_inst* inst); static int _wncc_unmap_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, - unsigned int num_layers, struct eva_kmd_wncc_metadata** wncc_metadata); + unsigned int num_layers, unsigned int metadata_bufs_offset, + struct eva_kmd_wncc_metadata** wncc_metadata); void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log); @@ -750,6 +752,7 @@ static int _wncc_copy_oob_from_user(struct eva_kmd_hfi_packet* in_pkt, { int rc = 0; u32 oob_type; + struct eva_kmd_oob_buf* oob_buf_u; struct eva_kmd_oob_wncc* wncc_oob_u; struct eva_kmd_oob_wncc* wncc_oob_k; unsigned int i; @@ -760,12 +763,13 @@ static int _wncc_copy_oob_from_user(struct eva_kmd_hfi_packet* in_pkt, return -EINVAL; } - if (!access_ok(in_pkt->oob_buf, sizeof(*in_pkt->oob_buf))) { + oob_buf_u = in_pkt->oob_buf; + if (!access_ok(oob_buf_u, sizeof(*oob_buf_u))) { dprintk(CVP_ERR, "%s: invalid OOB buf pointer", __func__); return -EINVAL; } - rc = get_user(oob_type, &in_pkt->oob_buf->oob_type); + rc = get_user(oob_type, &oob_buf_u->oob_type); if (rc) return rc; if (oob_type != EVA_KMD_OOB_WNCC) { @@ -774,9 +778,20 @@ static int _wncc_copy_oob_from_user(struct eva_kmd_hfi_packet* in_pkt, return -EINVAL; } - wncc_oob_u = &in_pkt->oob_buf->wncc; + wncc_oob_u = &oob_buf_u->wncc; wncc_oob_k = wncc_oob; + rc = get_user(wncc_oob_k->metadata_bufs_offset, + &wncc_oob_u->metadata_bufs_offset); + if (rc) + return rc; + if (wncc_oob_k->metadata_bufs_offset > ((sizeof(in_pkt->pkt_data) + - sizeof(struct cvp_buf_type)) / sizeof(__u32))) { + dprintk(CVP_ERR, "%s: invalid wncc metadata bufs offset", + __func__); + return -EINVAL; + } + rc = get_user(wncc_oob_k->num_layers, &wncc_oob_u->num_layers); if (rc) return rc; @@ -817,7 +832,8 @@ static int _wncc_copy_oob_from_user(struct eva_kmd_hfi_packet* in_pkt, } static int _wncc_map_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, - unsigned int num_layers, struct eva_kmd_wncc_metadata** wncc_metadata) + unsigned int num_layers, unsigned int metadata_bufs_offset, + struct eva_kmd_wncc_metadata** wncc_metadata) { int rc = 0, i; struct cvp_buf_type* wncc_metadata_bufs; @@ -829,9 +845,15 @@ static int _wncc_map_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, dprintk(CVP_ERR, "%s: invalid params", __func__); return -EINVAL; } + if (metadata_bufs_offset > ((sizeof(in_pkt->pkt_data) + - sizeof(struct cvp_buf_type)) / sizeof(__u32))) { + dprintk(CVP_ERR, "%s: invalid wncc metadata bufs offset", + __func__); + return -EINVAL; + } wncc_metadata_bufs = (struct cvp_buf_type*) - &in_pkt->pkt_data[EVA_KMD_WNCC_HFI_METADATA_BUFS_OFFSET]; + &in_pkt->pkt_data[metadata_bufs_offset]; for (i = 0; i < num_layers; i++) { dmabuf = dma_buf_get(wncc_metadata_bufs[i].fd); if (IS_ERR(dmabuf)) { @@ -872,13 +894,15 @@ static int _wncc_map_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, } if (rc) - _wncc_unmap_metadata_bufs(in_pkt, i, wncc_metadata); + _wncc_unmap_metadata_bufs(in_pkt, i, metadata_bufs_offset, + wncc_metadata); return rc; } static int _wncc_unmap_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, - unsigned int num_layers, struct eva_kmd_wncc_metadata** wncc_metadata) + unsigned int num_layers, unsigned int metadata_bufs_offset, + struct eva_kmd_wncc_metadata** wncc_metadata) { int rc = 0, i; struct cvp_buf_type* wncc_metadata_bufs; @@ -890,9 +914,15 @@ static int _wncc_unmap_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, dprintk(CVP_ERR, "%s: invalid params", __func__); return -EINVAL; } + if (metadata_bufs_offset > ((sizeof(in_pkt->pkt_data) + - sizeof(struct cvp_buf_type)) / sizeof(__u32))) { + dprintk(CVP_ERR, "%s: invalid wncc metadata bufs offset", + __func__); + return -EINVAL; + } wncc_metadata_bufs = (struct cvp_buf_type*) - &in_pkt->pkt_data[EVA_KMD_WNCC_HFI_METADATA_BUFS_OFFSET]; + &in_pkt->pkt_data[metadata_bufs_offset]; for (i = 0; i < num_layers; i++) { if (!wncc_metadata[i]) { rc = -EINVAL; @@ -944,8 +974,10 @@ static int msm_cvp_proc_oob_wncc(struct msm_cvp_inst* inst, wncc_oob = (struct eva_kmd_oob_wncc*)kzalloc( sizeof(struct eva_kmd_oob_wncc), GFP_KERNEL); - if (!wncc_oob) + if (!wncc_oob) { + dprintk(CVP_ERR, "%s: OOB buf allocation failed", __func__); return -ENOMEM; + } rc = _wncc_copy_oob_from_user(in_pkt, wncc_oob); if (rc) { dprintk(CVP_ERR, "%s: OOB buf copying failed", __func__); @@ -953,7 +985,8 @@ static int msm_cvp_proc_oob_wncc(struct msm_cvp_inst* inst, } rc = _wncc_map_metadata_bufs(in_pkt, - wncc_oob->num_layers, wncc_metadata); + wncc_oob->num_layers, wncc_oob->metadata_bufs_offset, + wncc_metadata); if (rc) { dprintk(CVP_ERR, "%s: failed to map wncc metadata bufs", __func__); @@ -1022,7 +1055,8 @@ static int msm_cvp_proc_oob_wncc(struct msm_cvp_inst* inst, wncc_oob->layers[0].num_addrs, wncc_metadata); if (_wncc_unmap_metadata_bufs(in_pkt, - wncc_oob->num_layers, wncc_metadata)) { + wncc_oob->num_layers, wncc_oob->metadata_bufs_offset, + wncc_metadata)) { dprintk(CVP_ERR, "%s: failed to unmap wncc metadata bufs", __func__); }