X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=target%2Flinux%2Fbrcm2708%2Fpatches-4.19%2F950-0553-staging-vcsm-cma-Add-cache-control-ioctls.patch;fp=target%2Flinux%2Fbrcm2708%2Fpatches-4.19%2F950-0553-staging-vcsm-cma-Add-cache-control-ioctls.patch;h=500ec5f0bcca92614603bfa6f86863a405fdb49b;hb=c2308a7e4adbb2acc8ff149f91d1ca46801c135e;hp=0000000000000000000000000000000000000000;hpb=67dcc43f3a22dc3a7ac07a7065971b426feeb043;p=openwrt%2Fopenwrt.git diff --git a/target/linux/brcm2708/patches-4.19/950-0553-staging-vcsm-cma-Add-cache-control-ioctls.patch b/target/linux/brcm2708/patches-4.19/950-0553-staging-vcsm-cma-Add-cache-control-ioctls.patch new file mode 100644 index 0000000000..500ec5f0bc --- /dev/null +++ b/target/linux/brcm2708/patches-4.19/950-0553-staging-vcsm-cma-Add-cache-control-ioctls.patch @@ -0,0 +1,245 @@ +From b17f6dc1d79ae057294ac2d8d824aa2258ab09a8 Mon Sep 17 00:00:00 2001 +From: Dave Stevenson +Date: Wed, 20 Mar 2019 10:40:00 +0000 +Subject: [PATCH] staging: vcsm-cma: Add cache control ioctls + +The old driver allowed for direct cache manipulation and that +was used by various clients. Replicate here. + +Signed-off-by: Dave Stevenson +--- + .../staging/vc04_services/vc-sm-cma/vc_sm.c | 141 +++++++++++++++++- + include/linux/broadcom/vc_sm_cma_ioctl.h | 27 ++++ + 2 files changed, 165 insertions(+), 3 deletions(-) + +--- a/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c ++++ b/drivers/staging/vc04_services/vc-sm-cma/vc_sm.c +@@ -46,6 +46,7 @@ + #include + #include + #include ++#include + + #include "vchiq_connected.h" + #include "vc_sm_cma_vchi.h" +@@ -1258,6 +1259,99 @@ error: + return ret; + } + ++/* Converts VCSM_CACHE_OP_* to an operating function. */ ++static void (*cache_op_to_func(const unsigned int cache_op)) ++ (const void*, const void*) ++{ ++ switch (cache_op) { ++ case VC_SM_CACHE_OP_NOP: ++ return NULL; ++ ++ case VC_SM_CACHE_OP_INV: ++ return dmac_inv_range; ++ ++ case VC_SM_CACHE_OP_CLEAN: ++ return dmac_clean_range; ++ ++ case VC_SM_CACHE_OP_FLUSH: ++ return dmac_flush_range; ++ ++ default: ++ pr_err("[%s]: Invalid cache_op: 0x%08x\n", __func__, cache_op); ++ return NULL; ++ } ++} ++ ++/* ++ * Clean/invalid/flush cache of which buffer is already pinned (i.e. accessed). ++ */ ++static int clean_invalid_contig_2d(const void __user *addr, ++ const size_t block_count, ++ const size_t block_size, ++ const size_t stride, ++ const unsigned int cache_op) ++{ ++ size_t i; ++ void (*op_fn)(const void *start, const void *end); ++ ++ if (!block_size) { ++ pr_err("[%s]: size cannot be 0\n", __func__); ++ return -EINVAL; ++ } ++ ++ op_fn = cache_op_to_func(cache_op); ++ if (!op_fn) ++ return -EINVAL; ++ ++ for (i = 0; i < block_count; i ++, addr += stride) ++ op_fn(addr, addr + block_size); ++ ++ return 0; ++} ++ ++static int vc_sm_cma_clean_invalid2(unsigned int cmdnr, unsigned long arg) ++{ ++ struct vc_sm_cma_ioctl_clean_invalid2 ioparam; ++ struct vc_sm_cma_ioctl_clean_invalid_block *block = NULL; ++ int i, ret = 0; ++ ++ /* Get parameter data. */ ++ if (copy_from_user(&ioparam, (void *)arg, sizeof(ioparam))) { ++ pr_err("[%s]: failed to copy-from-user header for cmd %x\n", ++ __func__, cmdnr); ++ return -EFAULT; ++ } ++ block = kmalloc(ioparam.op_count * sizeof(*block), GFP_KERNEL); ++ if (!block) ++ return -EFAULT; ++ ++ if (copy_from_user(block, (void *)(arg + sizeof(ioparam)), ++ ioparam.op_count * sizeof(*block)) != 0) { ++ pr_err("[%s]: failed to copy-from-user payload for cmd %x\n", ++ __func__, cmdnr); ++ ret = -EFAULT; ++ goto out; ++ } ++ ++ for (i = 0; i < ioparam.op_count; i++) { ++ const struct vc_sm_cma_ioctl_clean_invalid_block * const op = block + i; ++ ++ if (op->invalidate_mode == VC_SM_CACHE_OP_NOP) ++ continue; ++ ++ ret = clean_invalid_contig_2d((void __user *)op->start_address, ++ op->block_count, op->block_size, ++ op->inter_block_stride, ++ op->invalidate_mode); ++ if (ret) ++ break; ++ } ++out: ++ kfree(block); ++ ++ return ret; ++} ++ + static long vc_sm_cma_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) + { +@@ -1272,9 +1366,6 @@ static long vc_sm_cma_ioctl(struct file + return -EPERM; + } + +- pr_debug("[%s]: cmd %x tgid %u, owner %u\n", __func__, cmdnr, +- current->tgid, file_data->pid); +- + /* Action is a re-post of a previously interrupted action? */ + if (file_data->restart_sys == -EINTR) { + struct vc_sm_action_clean_t action_clean; +@@ -1357,7 +1448,18 @@ static long vc_sm_cma_ioctl(struct file + break; + } + ++ /* ++ * Flush/Invalidate the cache for a given mapping. ++ * Blocks must be pinned (i.e. accessed) before this call. ++ */ ++ case VC_SM_CMA_CMD_CLEAN_INVALID2: ++ ret = vc_sm_cma_clean_invalid2(cmdnr, arg); ++ break; ++ + default: ++ pr_debug("[%s]: cmd %x tgid %u, owner %u\n", __func__, cmdnr, ++ current->tgid, file_data->pid); ++ + ret = -EINVAL; + break; + } +@@ -1365,10 +1467,43 @@ static long vc_sm_cma_ioctl(struct file + return ret; + } + ++#ifdef CONFIG_COMPAT ++struct vc_sm_cma_ioctl_clean_invalid2_32 { ++ u32 op_count; ++ struct vc_sm_cma_ioctl_clean_invalid_block { ++ u16 invalidate_mode; ++ u16 block_count; ++ compat_uptr_t start_address; ++ u32 block_size; ++ u32 inter_block_stride; ++ } s[0]; ++}; ++ ++#define VC_SM_CMA_CMD_CLEAN_INVALID2_32\ ++ _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_CLEAN_INVALID2,\ ++ struct vc_sm_cma_ioctl_clean_invalid2) ++ ++static long vc_sm_cma_compat_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ switch (cmd) { ++ case VC_SM_CMA_CMD_CLEAN_INVALID2_32: ++ /* FIXME */ ++ break; ++ ++ default: ++ return vc_sm_cma_compat_ioctl(file, cmd, arg); ++ } ++} ++#endif ++ + /* Device operations that we managed in this driver. */ + static const struct file_operations vc_sm_ops = { + .owner = THIS_MODULE, + .unlocked_ioctl = vc_sm_cma_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = vc_sm_cma_compat_ioctl, ++#endif + .open = vc_sm_cma_open, + .release = vc_sm_cma_release, + }; +--- a/include/linux/broadcom/vc_sm_cma_ioctl.h ++++ b/include/linux/broadcom/vc_sm_cma_ioctl.h +@@ -33,6 +33,8 @@ enum vc_sm_cma_cmd_e { + + VC_SM_CMA_CMD_IMPORT_DMABUF, + ++ VC_SM_CMA_CMD_CLEAN_INVALID2, ++ + VC_SM_CMA_CMD_LAST /* Do not delete */ + }; + +@@ -75,6 +77,27 @@ struct vc_sm_cma_ioctl_import_dmabuf { + __u64 dma_addr; + }; + ++/* ++ * Cache functions to be set to struct vc_sm_cma_ioctl_clean_invalid2 ++ * invalidate_mode. ++ */ ++#define VC_SM_CACHE_OP_NOP 0x00 ++#define VC_SM_CACHE_OP_INV 0x01 ++#define VC_SM_CACHE_OP_CLEAN 0x02 ++#define VC_SM_CACHE_OP_FLUSH 0x03 ++ ++struct vc_sm_cma_ioctl_clean_invalid2 { ++ __u32 op_count; ++ __u32 pad; ++ struct vc_sm_cma_ioctl_clean_invalid_block { ++ __u32 invalidate_mode; ++ __u32 block_count; ++ void * __user start_address; ++ __u32 block_size; ++ __u32 inter_block_stride; ++ } s[0]; ++}; ++ + /* IOCTL numbers */ + #define VC_SM_CMA_IOCTL_MEM_ALLOC\ + _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_ALLOC,\ +@@ -84,4 +107,8 @@ struct vc_sm_cma_ioctl_import_dmabuf { + _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_IMPORT_DMABUF,\ + struct vc_sm_cma_ioctl_import_dmabuf) + ++#define VC_SM_CMA_IOCTL_MEM_CLEAN_INVALID2\ ++ _IOR(VC_SM_CMA_MAGIC_TYPE, VC_SM_CMA_CMD_CLEAN_INVALID2,\ ++ struct vc_sm_cma_ioctl_clean_invalid2) ++ + #endif /* __VC_SM_CMA_IOCTL_H */