From ce4b7e4bf43a5740f878de938275c4680abf3490 Mon Sep 17 00:00:00 2001 From: Sumit Semwal Date: Tue, 5 Jan 2021 15:22:31 +0530 Subject: [PATCH 01/44] dma-buf: Move dma_buf_release() from fops to dentry_ops commit 4ab59c3c638c6c8952bf07739805d20eb6358a4d upstream. Charan Teja reported a 'use-after-free' in dmabuffs_dname [1], which happens if the dma_buf_release() is called while the userspace is accessing the dma_buf pseudo fs's dmabuffs_dname() in another process, and dma_buf_release() releases the dmabuf object when the last reference to the struct file goes away. I discussed with Arnd Bergmann and he suggested that rather than tying the dma_buf_release() to the file_operations' release(), we can tie it to the dentry_operations' d_release(), which will be called when the last ref to the dentry is removed. The path exercised by __fput() calls f_op->release() first, and then calls dput, which eventually calls d_op->d_release(). In the 'normal' case, when no userspace access is happening via dma_buf pseudo fs, there should be exactly one fd, file, dentry and inode, so closing the fd will kill of everything right away. In the presented case, the dentry's d_release() will be called only when the dentry's last ref is released. Therefore, lets move dma_buf_release() from fops->release() to d_ops->d_release(). Many thanks to Arnd for his FS insights :). Reported-by: syzbot+3643a18836bce555bff6@syzkaller.appspotmail.com Cc: [5.3+] Cc: Arnd Bergmann Reported-by: Charan Teja Reddy Reviewed-by: Arnd Bergmann Signed-off-by: Sumit Semwal Tested-by: Charan Teja Reddy Link: https://patchwork.freedesktop.org/patch/msgid/20200611114418.19852-1-sumit.semwal@linaro.org Change-Id: Ief19296f201132c3e32b11958a857798c34f81fb Git-Commit: 4ab59c3c638c6c8952bf07739805d20eb6358a4d Git-Repo: git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git Signed-off-by: Greg Kroah-Hartman Signed-off-by: Kishor Krishna Bhat --- drivers/dma-buf/dma-buf.c | 49 ++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 62a9fa8b9019..174a8b308051 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -102,34 +102,11 @@ static char *dmabuffs_dname(struct dentry *dentry, char *buffer, int buflen) dentry->d_name.name, ret > 0 ? name : ""); } -static const struct dentry_operations dma_buf_dentry_ops = { - .d_dname = dmabuffs_dname, -}; - -static struct vfsmount *dma_buf_mnt; - -static struct dentry *dma_buf_fs_mount(struct file_system_type *fs_type, - int flags, const char *name, void *data) -{ - return mount_pseudo(fs_type, "dmabuf:", NULL, &dma_buf_dentry_ops, - DMA_BUF_MAGIC); -} - -static struct file_system_type dma_buf_fs_type = { - .name = "dmabuf", - .mount = dma_buf_fs_mount, - .kill_sb = kill_anon_super, -}; - -static int dma_buf_release(struct inode *inode, struct file *file) +static void dma_buf_release(struct dentry *dentry) { struct dma_buf *dmabuf; - struct dentry *dentry = file->f_path.dentry; - - if (!is_dma_buf_file(file)) - return -EINVAL; - dmabuf = file->private_data; + dmabuf = dentry->d_fsdata; spin_lock(&dentry->d_lock); dentry->d_fsdata = NULL; @@ -159,9 +136,28 @@ static int dma_buf_release(struct inode *inode, struct file *file) module_put(dmabuf->owner); dmabuf_dent_put(dmabuf); - return 0; } +static const struct dentry_operations dma_buf_dentry_ops = { + .d_dname = dmabuffs_dname, + .d_release = dma_buf_release, +}; + +static struct vfsmount *dma_buf_mnt; + +static struct dentry *dma_buf_fs_mount(struct file_system_type *fs_type, + int flags, const char *name, void *data) +{ + return mount_pseudo(fs_type, "dmabuf:", NULL, &dma_buf_dentry_ops, + DMA_BUF_MAGIC); +} + +static struct file_system_type dma_buf_fs_type = { + .name = "dmabuf", + .mount = dma_buf_fs_mount, + .kill_sb = kill_anon_super, +}; + static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma) { struct dma_buf *dmabuf; @@ -472,7 +468,6 @@ static void dma_buf_show_fdinfo(struct seq_file *m, struct file *file) } static const struct file_operations dma_buf_fops = { - .release = dma_buf_release, .mmap = dma_buf_mmap_internal, .llseek = dma_buf_llseek, .poll = dma_buf_poll, From d47e0b8ab870d5cc6f14131b950ea6cae4b15d3e Mon Sep 17 00:00:00 2001 From: Charan Teja Reddy Date: Tue, 5 Jan 2021 15:36:30 +0530 Subject: [PATCH 02/44] dmabuf: fix use-after-free of dmabuf's file->f_inode It is observed 'use-after-free' on the dmabuf's file->f_inode with the race between closing the dmabuf file and reading the dmabuf's debug info. Consider the below scenario where P1 is closing the dma_buf file and P2 is reading the dma_buf's debug info in the system: P1 P2 dma_buf_debug_show() dma_buf_put() __fput() file->f_op->release() dput() .... dentry_unlink_inode() iput(dentry->d_inode) (where the inode is freed) mutex_lock(&db_list.lock) read 'dma_buf->file->f_inode' (the same inode is freed by P1) mutex_unlock(&db_list.lock) dentry->d_op->d_release()--> dma_buf_release() ..... mutex_lock(&db_list.lock) removes the dmabuf from the list mutex_unlock(&db_list.lock) In the above scenario, when dma_buf_put() is called on a dma_buf, it first frees the dma_buf's file->f_inode(=dentry->d_inode) and then removes this dma_buf from the system db_list. In between P2 traversing the db_list tries to access this dma_buf's file->f_inode that was freed by P1 which is a use-after-free case. Since, __fput() calls f_op->release first and then later calls the d_op->d_release, move the dma_buf's db_list removal from d_release() to f_op->release(). This ensures that dma_buf's file->f_inode is not accessed after it is released. Change-Id: I83b7d284420bd26836a91c74bf814609c7aee220 Fixes: 4ab59c3c638c ("dma-buf: Move dma_buf_release() from fops to dentry_ops") Signed-off-by: Charan Teja Reddy Signed-off-by: Kishor Krishna Bhat --- drivers/dma-buf/dma-buf.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 174a8b308051..9a4ca5727a74 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -123,10 +123,6 @@ static void dma_buf_release(struct dentry *dentry) */ BUG_ON(dmabuf->cb_shared.active || dmabuf->cb_excl.active); - mutex_lock(&db_list.lock); - list_del(&dmabuf->list_node); - mutex_unlock(&db_list.lock); - dmabuf->ops->release(dmabuf); dma_buf_ref_destroy(dmabuf); @@ -138,6 +134,22 @@ static void dma_buf_release(struct dentry *dentry) dmabuf_dent_put(dmabuf); } +static int dma_buf_file_release(struct inode *inode, struct file *file) +{ + struct dma_buf *dmabuf; + + if (!is_dma_buf_file(file)) + return -EINVAL; + + dmabuf = file->private_data; + + mutex_lock(&db_list.lock); + list_del(&dmabuf->list_node); + mutex_unlock(&db_list.lock); + + return 0; +} + static const struct dentry_operations dma_buf_dentry_ops = { .d_dname = dmabuffs_dname, .d_release = dma_buf_release, @@ -468,6 +480,7 @@ static void dma_buf_show_fdinfo(struct seq_file *m, struct file *file) } static const struct file_operations dma_buf_fops = { + .release = dma_buf_file_release, .mmap = dma_buf_mmap_internal, .llseek = dma_buf_llseek, .poll = dma_buf_poll, From 6a32c317f1b36e76304d27f455990825a6330df6 Mon Sep 17 00:00:00 2001 From: Mahadevan Date: Fri, 23 Apr 2021 13:14:36 +0530 Subject: [PATCH 03/44] disp: msm: avoid deadlock by prepending connection_mutex Commit caused by dpms on may use extra modeset lock on connection_mutex before msm_atomic_commit, so to avoid such deadlock, make the modeset lock within prepare_fence callback to use before waiting for pending_crtcs_event. Change-Id: Iba05efae1bfab4f454083b6e462a59937d06a7e6 Signed-off-by: Mahadevan --- drivers/gpu/drm/msm/msm_atomic.c | 12 +++++++++++- drivers/gpu/drm/msm/sde/sde_kms.c | 13 ++----------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index a957598eb827..39f1e7c3b4c0 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2014 Red Hat * Author: Rob Clark * @@ -762,6 +762,16 @@ int msm_atomic_commit(struct drm_device *dev, c->plane_mask |= (1 << drm_plane_index(plane)); } + /* Protection for prepare_fence callback */ +retry: + ret = drm_modeset_lock(&state->dev->mode_config.connection_mutex, + state->acquire_ctx); + + if (ret == -EDEADLK) { + drm_modeset_backoff(state->acquire_ctx); + goto retry; + } + /* * Wait for pending updates on any of the same crtc's and then * mark our set of crtc's as busy: diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c index 9da771981d2e..4bf70772fafb 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.c +++ b/drivers/gpu/drm/msm/sde/sde_kms.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -1234,7 +1234,7 @@ static void sde_kms_prepare_fence(struct msm_kms *kms, { struct drm_crtc *crtc; struct drm_crtc_state *old_crtc_state; - int i, rc; + int i; if (!kms || !old_state || !old_state->dev || !old_state->acquire_ctx) { SDE_ERROR("invalid argument(s)\n"); @@ -1242,15 +1242,6 @@ static void sde_kms_prepare_fence(struct msm_kms *kms, } SDE_ATRACE_BEGIN("sde_kms_prepare_fence"); -retry: - /* attempt to acquire ww mutex for connection */ - rc = drm_modeset_lock(&old_state->dev->mode_config.connection_mutex, - old_state->acquire_ctx); - - if (rc == -EDEADLK) { - drm_modeset_backoff(old_state->acquire_ctx); - goto retry; - } /* old_state actually contains updated crtc pointers */ for_each_crtc_in_state(old_state, crtc, old_crtc_state, i) { From 1e2224613495714b811db22112280a183200fba0 Mon Sep 17 00:00:00 2001 From: Mahadevan Date: Fri, 23 Apr 2021 13:23:08 +0530 Subject: [PATCH 04/44] disp: msm: sde: add helper function for setting crtc to conn state Add changes to move the state operations for setting crtc to connector state to a helper api. This can be reused during preclose operation for issuing a drm commit. Change-Id: Ic29f86a75d8fe97178f86d8cbe12e7984f942deb Signed-off-by: Mahadevan --- drivers/gpu/drm/msm/sde/sde_kms.c | 68 +++++++++++++++++++------------ 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c index 4bf70772fafb..2647d07bf9a3 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.c +++ b/drivers/gpu/drm/msm/sde/sde_kms.c @@ -1994,6 +1994,46 @@ static void sde_kms_destroy(struct msm_kms *kms) kfree(sde_kms); } +static int sde_kms_set_crtc_for_conn(struct drm_device *dev, + struct drm_encoder *enc, struct drm_atomic_state *state) +{ + struct drm_connector *conn = NULL; + struct drm_connector *tmp_conn = NULL; + struct drm_connector_list_iter conn_iter; + struct drm_crtc_state *crtc_state = NULL; + struct drm_connector_state *conn_state = NULL; + int ret = 0; + + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(tmp_conn, &conn_iter) { + if (enc == tmp_conn->state->best_encoder) { + conn = tmp_conn; + break; + } + } + drm_connector_list_iter_end(&conn_iter); + + if (!conn) { + SDE_ERROR("error in finding conn for enc:%d\n", DRMID(enc)); + return -EINVAL; + } + + crtc_state = drm_atomic_get_crtc_state(state, enc->crtc); + conn_state = drm_atomic_get_connector_state(state, conn); + if (IS_ERR(conn_state)) { + SDE_ERROR("error %d getting connector %d state\n", + ret, DRMID(conn)); + return -EINVAL; + } + + crtc_state->active = true; + ret = drm_atomic_set_crtc_for_connector(conn_state, enc->crtc); + if (ret) + SDE_ERROR("error %d setting the crtc\n", ret); + + return 0; +} + static void _sde_kms_plane_force_remove(struct drm_plane *plane, struct drm_atomic_state *state) { @@ -2704,12 +2744,7 @@ static void _sde_kms_null_commit(struct drm_device *dev, struct drm_encoder *enc) { struct drm_modeset_acquire_ctx ctx; - struct drm_connector *conn = NULL; - struct drm_connector *tmp_conn = NULL; - struct drm_connector_list_iter conn_iter; struct drm_atomic_state *state = NULL; - struct drm_crtc_state *crtc_state = NULL; - struct drm_connector_state *conn_state = NULL; int retry_cnt = 0; int ret = 0; @@ -2733,30 +2768,11 @@ static void _sde_kms_null_commit(struct drm_device *dev, } state->acquire_ctx = &ctx; - drm_connector_list_iter_begin(dev, &conn_iter); - drm_for_each_connector_iter(tmp_conn, &conn_iter) { - if (enc == tmp_conn->state->best_encoder) { - conn = tmp_conn; - break; - } - } - drm_connector_list_iter_end(&conn_iter); - if (!conn) { - SDE_ERROR("error in finding conn for enc:%d\n", DRMID(enc)); - goto end; - } + ret = sde_kms_set_crtc_for_conn(dev, enc, state); - crtc_state = drm_atomic_get_crtc_state(state, enc->crtc); - conn_state = drm_atomic_get_connector_state(state, conn); - if (IS_ERR(conn_state)) { - SDE_ERROR("error %d getting connector %d state\n", - ret, DRMID(conn)); + if (ret) goto end; - } - - crtc_state->active = true; - drm_atomic_set_crtc_for_connector(conn_state, enc->crtc); drm_atomic_commit(state); end: From a37c0fada262ee6cf2463d9b92e6c2ced176fe78 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Mon, 19 Apr 2021 10:41:01 +0530 Subject: [PATCH 05/44] diag: Use valid data_source for a valid token For a valid token indicating remote proc use data_source to indicate packet originated from dci remote source. Change-Id: I01729a905d532fae7ea046acc143598eca04460b Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_dci.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index 25a1706b6508..2cbcecab1b53 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1061,6 +1061,11 @@ void extract_dci_pkt_rsp(unsigned char *buf, int len, int data_source, return; } + if (token != entry->client_info.token) { + mutex_unlock(&driver->dci_mutex); + return; + } + mutex_lock(&entry->buffers[data_source].buf_mutex); rsp_buf = entry->buffers[data_source].buf_cmd; From c6ccb86a14da4ff54b9e894f9a060ced0a904494 Mon Sep 17 00:00:00 2001 From: Mahadevan Date: Fri, 23 Apr 2021 14:02:27 +0530 Subject: [PATCH 06/44] disp: msm: sde: clear dim_layers as part of null commit Add changes to clear any dim_layers present in the crtc_state as part of null commit. Change-Id: I5a660b44334581bbace5ed1e06ed201a990d44fe Signed-off-by: Mahadevan --- drivers/gpu/drm/msm/sde/sde_crtc.c | 15 +++++++-------- drivers/gpu/drm/msm/sde/sde_crtc.h | 7 ++++++- drivers/gpu/drm/msm/sde/sde_kms.c | 2 ++ 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c index 663cb76b0c79..9dfa30582ccd 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.c +++ b/drivers/gpu/drm/msm/sde/sde_crtc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -3083,17 +3083,16 @@ static void _sde_crtc_set_input_fence_timeout(struct sde_crtc_state *cstate) cstate->input_fence_timeout_ns *= NSEC_PER_MSEC; } -/** - * _sde_crtc_clear_dim_layers_v1 - clear all dim layer settings - * @cstate: Pointer to sde crtc state - */ -static void _sde_crtc_clear_dim_layers_v1(struct sde_crtc_state *cstate) +void _sde_crtc_clear_dim_layers_v1(struct drm_crtc_state *state) { u32 i; + struct sde_crtc_state *cstate; - if (!cstate) + if (!state) return; + cstate = to_sde_crtc_state(state); + for (i = 0; i < cstate->num_dim_layers; i++) memset(&cstate->dim_layer[i], 0, sizeof(cstate->dim_layer[i])); @@ -3129,7 +3128,7 @@ static void _sde_crtc_set_dim_layer_v1(struct drm_crtc *crtc, if (!usr_ptr) { /* usr_ptr is null when setting the default property value */ - _sde_crtc_clear_dim_layers_v1(cstate); + _sde_crtc_clear_dim_layers_v1(&cstate->base); SDE_DEBUG("dim_layer data removed\n"); return; } diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.h b/drivers/gpu/drm/msm/sde/sde_crtc.h index 4676a140267c..d3dc1c8528a5 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.h +++ b/drivers/gpu/drm/msm/sde/sde_crtc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2021 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -859,4 +859,9 @@ int sde_crtc_calc_vpadding_param(struct drm_crtc_state *state, int sde_crtc_get_num_datapath(struct drm_crtc *crtc, struct drm_connector *connector); +/** + * _sde_crtc_clear_dim_layers_v1 - clear all dim layer settings + * @cstate: Pointer to drm crtc state + */ +void _sde_crtc_clear_dim_layers_v1(struct drm_crtc_state *state); #endif /* _SDE_CRTC_H_ */ diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c index 2647d07bf9a3..1cd60e8b363b 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.c +++ b/drivers/gpu/drm/msm/sde/sde_kms.c @@ -2031,6 +2031,8 @@ static int sde_kms_set_crtc_for_conn(struct drm_device *dev, if (ret) SDE_ERROR("error %d setting the crtc\n", ret); + _sde_crtc_clear_dim_layers_v1(crtc_state); + return 0; } From 27d53795d65b6083dcb94ce20c3ee966c213e9ad Mon Sep 17 00:00:00 2001 From: Mahadevan Date: Fri, 23 Apr 2021 14:11:04 +0530 Subject: [PATCH 07/44] disp: msm: sde: remove fb's attached to a drm_file in preclose Add changes to remove framebuffers attached to a drm_file in preclose whose refcount is not managed by composer kill and issue null flush to hardware in such cases. This will avoid upstream issuing drm_atomic_commit's in drm_fb_release which is leading to artifacts on screen or atomic_check failures due to atomically unstaging each fb from plane_state and committing remaining planes on hardware. Change-Id: I831bdff3b398f19d0b3ebb71aa630554034cf28e Signed-off-by: Mahadevan --- drivers/gpu/drm/msm/sde/sde_kms.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c index 1cd60e8b363b..f47bf72e9ba3 100644 --- a/drivers/gpu/drm/msm/sde/sde_kms.c +++ b/drivers/gpu/drm/msm/sde/sde_kms.c @@ -2070,8 +2070,9 @@ static int _sde_kms_remove_fbs(struct sde_kms *sde_kms, struct drm_file *file, struct drm_framebuffer *fb, *tfb; struct list_head fbs; struct drm_plane *plane; + struct drm_crtc *crtc = NULL; + unsigned int crtc_mask = 0; int ret = 0; - u32 plane_mask = 0; INIT_LIST_HEAD(&fbs); @@ -2080,9 +2081,11 @@ static int _sde_kms_remove_fbs(struct sde_kms *sde_kms, struct drm_file *file, list_move_tail(&fb->filp_head, &fbs); drm_for_each_plane(plane, dev) { - if (plane->fb == fb) { - plane_mask |= - 1 << drm_plane_index(plane); + if (plane->state && + plane->state->fb == fb) { + if (plane->state->crtc) + crtc_mask |= drm_crtc_mask( + plane->state->crtc); _sde_kms_plane_force_remove( plane, state); } @@ -2095,11 +2098,22 @@ static int _sde_kms_remove_fbs(struct sde_kms *sde_kms, struct drm_file *file, if (list_empty(&fbs)) { SDE_DEBUG("skip commit as no fb(s)\n"); - drm_atomic_state_put(state); return 0; } - SDE_DEBUG("committing after removing all the pipes\n"); + drm_for_each_crtc(crtc, dev) { + if ((crtc_mask & drm_crtc_mask(crtc)) && crtc->state->active) { + struct drm_encoder *drm_enc; + + drm_for_each_encoder_mask(drm_enc, crtc->dev, + crtc->state->encoder_mask) + ret = sde_kms_set_crtc_for_conn( + dev, drm_enc, state); + } + } + + SDE_EVT32(state, crtc_mask); + SDE_DEBUG("null commit after removing all the pipes\n"); ret = drm_atomic_commit(state); if (ret) { @@ -2122,8 +2136,6 @@ static int _sde_kms_remove_fbs(struct sde_kms *sde_kms, struct drm_file *file, } end: - drm_atomic_clean_old_fb(dev, plane_mask, ret); - return ret; } From 5e980c4a2938b70cff8585775c3883e52b8e6fb9 Mon Sep 17 00:00:00 2001 From: Mahadevan Date: Fri, 23 Apr 2021 14:17:44 +0530 Subject: [PATCH 08/44] disp: msm: sde: add msm_preclose operation as part of msm_release Add changes to handle msm_preclose as part of msm_release operation and remove preclose callback handler since legacy feature is not supported for msm_driver. Change-Id: Idbad514d601e431afef545008a6c79ee72e78270 Signed-off-by: Mahadevan --- drivers/gpu/drm/msm/msm_drv.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 35d108c991b1..e4c96c96c53c 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark * @@ -1538,6 +1538,13 @@ static int msm_release(struct inode *inode, struct file *filp) kfree(node); } + msm_preclose(dev, file_priv); + + /** + * Handle preclose operation here for removing fb's whose + * refcount > 1. This operation is not triggered from upstream + * drm as msm_driver does not support DRIVER_LEGACY feature. + */ return drm_release(inode, filp); } @@ -1692,7 +1699,6 @@ static struct drm_driver msm_driver = { DRIVER_ATOMIC | DRIVER_MODESET, .open = msm_open, - .preclose = msm_preclose, .postclose = msm_postclose, .lastclose = msm_lastclose, .irq_handler = msm_irq, From ec0aa6a6cb78a23de148cfb1c7177b1080a08e4f Mon Sep 17 00:00:00 2001 From: Jeya R Date: Sun, 2 May 2021 14:29:39 +0530 Subject: [PATCH 09/44] msm: adsprpc: vote for CPU to stay awake during RPC call Vote with PM for CPU to stay awake while processing RPC call and to relax when waiting for response from remote subsystem. Print error if the maximum remote session concurrency is hit. Change-Id: If39b7391fa4d20fb13f4de46c3c2d25b649e2b1f Acked-by: Thyagarajan Venkatanarayanan Acked-by: Maitreyi Gupta Signed-off-by: Jeya R --- drivers/char/adsprpc.c | 86 +++++++++++++++++++++++++++++------ drivers/char/adsprpc_shared.h | 18 ++++++-- 2 files changed, 85 insertions(+), 19 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index c8aa9f0901b4..fd9ca062600a 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -225,6 +225,7 @@ struct smq_invoke_ctx { struct fastrpc_buf *lbuf; size_t used; struct fastrpc_file *fl; + uint32_t handle; uint32_t sc; struct overlap *overs; struct overlap **overps; @@ -310,6 +311,8 @@ struct fastrpc_apps { spinlock_t ctxlock; struct smq_invoke_ctx *ctxtable[FASTRPC_CTX_MAX]; bool legacy_remote_heap; + struct wakeup_source *wake_source; + unsigned int wake_count; }; struct fastrpc_mmap { @@ -391,6 +394,8 @@ struct fastrpc_file { /* Identifies the device (MINOR_NUM_DEV / MINOR_NUM_SECURE_DEV) */ int dev_minor; char *debug_buf; + /* Flag to enable PM wake/relax voting for every remote invoke */ + int wake_enable; /* To indicate attempt has been made to allocate memory for debug_buf */ int debug_buf_alloced_attempted; }; @@ -1250,6 +1255,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel, goto bail; } ctx->crc = (uint32_t *)invokefd->crc; + ctx->handle = invoke->handle; ctx->sc = invoke->sc; if (bufs) { VERIFY(err, 0 == context_build_overlap(ctx)); @@ -1931,7 +1937,36 @@ static void fastrpc_init(struct fastrpc_apps *me) me->channel[CDSP_DOMAIN_ID].secure = NON_SECURE_CHANNEL; } -static int fastrpc_release_current_dsp_process(struct fastrpc_file *fl); +static inline void fastrpc_pm_awake(int fl_wake_enable, int *wake_enable) +{ + struct fastrpc_apps *me = &gfa; + + if (!fl_wake_enable) + return; + + spin_lock(&me->hlock); + if (!me->wake_count) + __pm_stay_awake(me->wake_source); + me->wake_count++; + spin_unlock(&me->hlock); + *wake_enable = 1; +} + +static inline void fastrpc_pm_relax(int *wake_enable) +{ + struct fastrpc_apps *me = &gfa; + + if (!(*wake_enable)) + return; + + spin_lock(&me->hlock); + if (me->wake_count) + me->wake_count--; + if (!me->wake_count) + __pm_relax(me->wake_source); + spin_unlock(&me->hlock); + *wake_enable = 0; +} static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, uint32_t kernel, @@ -1939,7 +1974,8 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, { struct smq_invoke_ctx *ctx = NULL; struct fastrpc_ioctl_invoke *invoke = &inv->inv; - int err = 0, cid = -1, interrupted = 0; + int err = 0, wake_enable = 0; + int cid = -1, interrupted = 0; struct timespec invoket = {0}; int64_t *perf_counter = NULL; @@ -1956,6 +1992,7 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, } perf_counter = getperfcounter(fl, PERF_COUNT); + fastrpc_pm_awake(fl->wake_enable, &wake_enable); if (fl->profile) getnstimeofday(&invoket); @@ -2006,14 +2043,16 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, if (err) goto bail; wait: + fastrpc_pm_relax(&wake_enable); if (kernel) wait_for_completion(&ctx->work); - else { + else interrupted = wait_for_completion_interruptible(&ctx->work); - VERIFY(err, 0 == (err = interrupted)); - if (err) - goto bail; - } + fastrpc_pm_awake(fl->wake_enable, &wake_enable); + VERIFY(err, 0 == (err = interrupted)); + if (err) + goto bail; + PERF(fl->profile, GET_COUNTER(perf_counter, PERF_INVARGS), if (!fl->sctx->smmu.coherent) @@ -2051,6 +2090,7 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, *count = *count+1; } } + fastrpc_pm_relax(&wake_enable); return err; } @@ -2837,9 +2877,12 @@ static int fastrpc_session_alloc_locked(struct fastrpc_channel_ctx *chan, break; } } - VERIFY(err, idx < chan->sesscount); - if (err) + if (idx >= chan->sesscount) { + err = -EUSERS; + pr_err("adsprpc: ERROR %d: %s: max concurrent sessions limit (%d) already reached on %s\n", + err, __func__, chan->sesscount, chan->subsys); goto bail; + } chan->session[idx].smmu.faults = 0; } else { VERIFY(err, me->dev != NULL); @@ -3294,7 +3337,7 @@ static int fastrpc_channel_open(struct fastrpc_file *fl) VERIFY(err, fl && fl->sctx && fl->cid >= 0 && fl->cid < NUM_CHANNELS); if (err) { - pr_err("adsprpc: ERROR: %s: user application %s domain is not set\n", + pr_err("adsprpc: ERROR: %s: kernel session not initialized yet for %s\n", __func__, current->comm); err = -EBADR; return err; @@ -3463,8 +3506,8 @@ static int fastrpc_get_info(struct fastrpc_file *fl, uint32_t *info) fl->cid = cid; fl->ssrcount = fl->apps->channel[cid].ssrcount; mutex_lock(&fl->apps->channel[cid].smd_mutex); - VERIFY(err, !fastrpc_session_alloc_locked( - &fl->apps->channel[cid], 0, &fl->sctx)); + err = fastrpc_session_alloc_locked(&fl->apps->channel[cid], + 0, &fl->sctx); mutex_unlock(&fl->apps->channel[cid].smd_mutex); if (err) goto bail; @@ -3509,8 +3552,11 @@ static int fastrpc_internal_control(struct fastrpc_file *fl, case FASTRPC_CONTROL_KALLOC: cp->kalloc.kalloc_support = 1; break; + case FASTRPC_CONTROL_WAKELOCK: + fl->wake_enable = cp->wp.enable; + break; default: - err = -ENOTTY; + err = -EBADRQC; break; } bail: @@ -4515,11 +4561,19 @@ static int __init fastrpc_device_init(void) err = register_rpmsg_driver(&fastrpc_rpmsg_client); if (err) { - pr_err("adsprpc: register_rpmsg_driver: failed with err %d\n", - err); + pr_err("adsprpc: %s: register_rpmsg_driver failed with err %d\n", + __func__, err); goto device_create_bail; } me->rpmsg_register = 1; + + me->wake_source = wakeup_source_register(dev, "adsprpc"); + VERIFY(err, !IS_ERR_OR_NULL(me->wake_source)); + if (err) { + pr_err("adsprpc: Error: %s: wakeup_source_register failed with err %d\n", + __func__, PTR_ERR(me->wake_source)); + goto device_create_bail; + } return 0; device_create_bail: for (i = 0; i < NUM_CHANNELS; i++) { @@ -4568,6 +4622,8 @@ static void __exit fastrpc_device_exit(void) unregister_chrdev_region(me->dev_no, NUM_CHANNELS); if (me->rpmsg_register == 1) unregister_rpmsg_driver(&fastrpc_rpmsg_client); + if (me->wake_source) + wakeup_source_unregister(me->wake_source); debugfs_remove_recursive(debugfs_root); } diff --git a/drivers/char/adsprpc_shared.h b/drivers/char/adsprpc_shared.h index 91ce793d00aa..d8d4dedf9a5c 100644 --- a/drivers/char/adsprpc_shared.h +++ b/drivers/char/adsprpc_shared.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2019, 2021 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -241,22 +241,32 @@ struct fastrpc_ioctl_perf { /* kernel performance data */ uintptr_t keys; }; -#define FASTRPC_CONTROL_LATENCY (1) +enum fastrpc_control_type { + FASTRPC_CONTROL_LATENCY = 1, + FASTRPC_CONTROL_SMMU = 2, + FASTRPC_CONTROL_KALLOC = 3, + FASTRPC_CONTROL_WAKELOCK = 4, +}; + struct fastrpc_ctrl_latency { uint32_t enable; /* latency control enable */ uint32_t level; /* level of control */ }; -#define FASTRPC_CONTROL_KALLOC (3) struct fastrpc_ctrl_kalloc { uint32_t kalloc_support; /* Remote memory allocation from kernel */ }; -/* FASTRPC_CONTROL value 2 is reserved in user space */ + +struct fastrpc_ctrl_wakelock { + uint32_t enable; /* wakelock control enable */ +}; + struct fastrpc_ioctl_control { uint32_t req; union { struct fastrpc_ctrl_latency lp; struct fastrpc_ctrl_kalloc kalloc; + struct fastrpc_ctrl_wakelock wp; }; }; From 28388e7c59ce9137c179748ab90623982b7d8fdd Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Thu, 3 Dec 2020 02:25:04 +0100 Subject: [PATCH 10/44] tty: Fix ->pgrp locking in tiocspgrp() tiocspgrp() takes two tty_struct pointers: One to the tty that userspace passed to ioctl() (`tty`) and one to the TTY being changed (`real_tty`). These pointers are different when ioctl() is called with a master fd. To properly lock real_tty->pgrp, we must take real_tty->ctrl_lock. This bug makes it possible for racing ioctl(TIOCSPGRP, ...) calls on both sides of a PTY pair to corrupt the refcount of `struct pid`, leading to use-after-free errors. Fixes: 47f86834bbd4 ("redo locking of tty->pgrp") CC: stable@kernel.org Signed-off-by: Jann Horn Reviewed-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman Change-Id: Id1dd23a85c063fdf23b50c53b65c4256803a7371 Git-commit: 54ffccbf053b5b6ca4f6e45094b942fab92a25fc Git-repo: https://android.googlesource.com/kernel/msm Signed-off-by: urevanth --- drivers/tty/tty_jobctrl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/tty/tty_jobctrl.c b/drivers/tty/tty_jobctrl.c index e7032309ee87..33dcd4eb92da 100644 --- a/drivers/tty/tty_jobctrl.c +++ b/drivers/tty/tty_jobctrl.c @@ -493,10 +493,10 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t if (session_of_pgrp(pgrp) != task_session(current)) goto out_unlock; retval = 0; - spin_lock_irq(&tty->ctrl_lock); + spin_lock_irq(&real_tty->ctrl_lock); put_pid(real_tty->pgrp); real_tty->pgrp = get_pid(pgrp); - spin_unlock_irq(&tty->ctrl_lock); + spin_unlock_irq(&real_tty->ctrl_lock); out_unlock: rcu_read_unlock(); return retval; From e198c123b41452670b4c67144c42dbd8fea7ebc5 Mon Sep 17 00:00:00 2001 From: Raviteja Tamatam Date: Thu, 22 Apr 2021 15:33:51 +0530 Subject: [PATCH 11/44] disp: msm: sde: update BW_INDICATION programing sequence BW_INDICATION indication must be programed before BWI_THRESHOLD. Otherwise, it will revert to legacy behaviour and rsc wakeup is delayed by one vsync causing janks. In current code BW_INDICATION is done after LM/SSPP programming and plane fence wait. Moved the perf_crtc_update before this and just after ctl prepare configuration to avoid chances of BW_INDICATION crossing BWI_THRESHOLD time. Change-Id: Ie976720910c34aaf140f1ce7daef38ba20bc10f5 Signed-off-by: Raviteja Tamatam --- drivers/gpu/drm/msm/sde/sde_crtc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c index 9dfa30582ccd..9972b84dc8eb 100644 --- a/drivers/gpu/drm/msm/sde/sde_crtc.c +++ b/drivers/gpu/drm/msm/sde/sde_crtc.c @@ -3753,6 +3753,9 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc, sde_encoder_trigger_kickoff_pending(encoder); } + /* update performance setting */ + sde_core_perf_crtc_update(crtc, 1, false); + /* * If no mixers have been allocated in sde_crtc_atomic_check(), * it means we are trying to flush a CRTC whose state is disabled: @@ -3899,9 +3902,6 @@ static void sde_crtc_atomic_flush(struct drm_crtc *crtc, cstate->rsc_update = true; } - /* update performance setting before crtc kickoff */ - sde_core_perf_crtc_update(crtc, 1, false); - /* * Final plane updates: Give each plane a chance to complete all * required writes/flushing before crtc's "flush From 5cdb3bae8e618e5a7b7d0e47e4af08e53e8f82c8 Mon Sep 17 00:00:00 2001 From: Mahadevan Date: Fri, 16 Apr 2021 13:45:32 +0530 Subject: [PATCH 12/44] disp: msm: update clk and cmd state switch sequence Disable double buffer vsync configuration while enabling clk and cmd state switch sequence. Leaving this configuration in enable state may cause different issues for different state switch. Clock state switch may see a vsync delay for solver disable. Command state switch may not update the vsync source. Change-Id: I30d1f02a9b1d0972acb1e0318b7f8d9f3a262a60 Signed-off-by: Mahadevan --- drivers/gpu/drm/msm/sde_rsc_hw_v3.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/sde_rsc_hw_v3.c b/drivers/gpu/drm/msm/sde_rsc_hw_v3.c index 40a930276107..2dcc0a947dc1 100644 --- a/drivers/gpu/drm/msm/sde_rsc_hw_v3.c +++ b/drivers/gpu/drm/msm/sde_rsc_hw_v3.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -404,6 +404,10 @@ static int sde_rsc_state_update_v3(struct sde_rsc_priv *rsc, case SDE_RSC_CMD_STATE: pr_debug("command mode handling\n"); + dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL, + 0x0, rsc->debug_mode); + wmb(); /* disable double buffer config before vsync select */ + dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL2, BIT(1) | BIT(2) | BIT(3), rsc->debug_mode); @@ -459,10 +463,17 @@ static int sde_rsc_state_update_v3(struct sde_rsc_priv *rsc, reg = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL, rsc->debug_mode); - reg &= ~BIT(0); + reg &= ~(BIT(0) | BIT(8)); dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL, reg, rsc->debug_mode); wmb(); /* make sure that solver mode is disabled */ + + reg = dss_reg_r(&rsc->wrapper_io, + SDE_RSCC_WRAPPER_OVERRIDE_CTRL, rsc->debug_mode); + reg |= BIT(8); + dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_OVERRIDE_CTRL, + reg, rsc->debug_mode); + wmb(); /* enable double buffer vsync configuration */ break; case SDE_RSC_IDLE_STATE: From 1e1be03fff68fed83fedecafe6f7adbba8cd5d64 Mon Sep 17 00:00:00 2001 From: Mahadevan Date: Tue, 20 Apr 2021 15:30:11 +0530 Subject: [PATCH 13/44] disp: msm: increase rsc min_threshold time Increase the rsc min_threshold time, so that it has sufficient time to complete the sequencer in rare cases. Increase the polling time for tcs ok from 1us to 3us to align with the min_threshold. Change-Id: I606f542fba319ec9373b5ff25fa1ab2ca9e1501d Signed-off-by: Mahadevan --- drivers/gpu/drm/msm/sde_rsc.c | 12 ++++++++++-- drivers/gpu/drm/msm/sde_rsc_hw.c | 21 +++++++++++++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/sde_rsc.c b/drivers/gpu/drm/msm/sde_rsc.c index c1d79c50e630..65bdc1a229b8 100644 --- a/drivers/gpu/drm/msm/sde_rsc.c +++ b/drivers/gpu/drm/msm/sde_rsc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -477,7 +477,15 @@ static u32 sde_rsc_timer_calculate(struct sde_rsc_priv *rsc, /* mode 2 is infinite */ rsc->timer_config.rsc_time_slot_2_ns = 0xFFFFFFFF; - rsc->timer_config.min_threshold_time_ns = MIN_THRESHOLD_OVERHEAD_TIME; + /** + * Program rsc_min_threshold with a higher value (3.3 ms), so it has + * sufficient time to complete the sequence for some targets. + */ + if (rsc->version >= SDE_RSC_REV_3) + rsc->timer_config.min_threshold_time_ns = 64; + else + rsc->timer_config.min_threshold_time_ns = + MIN_THRESHOLD_OVERHEAD_TIME; rsc->timer_config.bwi_threshold_time_ns = rsc->timer_config.rsc_time_slot_0_ns; diff --git a/drivers/gpu/drm/msm/sde_rsc_hw.c b/drivers/gpu/drm/msm/sde_rsc_hw.c index b37f28620583..89c6f67cf8a5 100644 --- a/drivers/gpu/drm/msm/sde_rsc_hw.c +++ b/drivers/gpu/drm/msm/sde_rsc_hw.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -866,7 +866,7 @@ bool rsc_hw_is_amc_mode(struct sde_rsc_priv *rsc) int rsc_hw_tcs_wait(struct sde_rsc_priv *rsc) { int rc = -EBUSY; - int count, seq_status; + int count, seq_status, loop_counter; dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL, 0x0, rsc->debug_mode); @@ -881,15 +881,28 @@ int rsc_hw_tcs_wait(struct sde_rsc_priv *rsc) 0x0, rsc->debug_mode); } + if (rsc->version >= SDE_RSC_REV_3) + loop_counter = MAX_CHECK_LOOPS / 4; + else + loop_counter = MAX_CHECK_LOOPS; /* check for sequence running status before exiting */ - for (count = MAX_CHECK_LOOPS; count > 0; count--) { + for (count = loop_counter; count > 0; count--) { seq_status = dss_reg_r(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL, rsc->debug_mode) & BIT(1); if (!seq_status) { rc = 0; break; } - usleep_range(1, 2); + + if (rsc->version >= SDE_RSC_REV_3) { + dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL, + 0x1, rsc->debug_mode); + usleep_range(3, 4); + dss_reg_w(&rsc->wrapper_io, SDE_RSCC_WRAPPER_CTRL, + 0x0, rsc->debug_mode); + } else { + usleep_range(1, 2); + } } return rc; From dbbaa4b292d3224474312abd63df6f9904cc3abc Mon Sep 17 00:00:00 2001 From: Dhaval Patel Date: Fri, 16 Apr 2021 14:30:17 +0530 Subject: [PATCH 14/44] disp: msm: avoid vsync wait during dms mode switch Add changes to avoid vsync wait during dms mode switch for targets which support rsc revision 3. Change-Id: I8e28d9b445264132f14d3edc3d6452827055f65a Signed-off-by: Jayaprakash --- drivers/gpu/drm/msm/sde_rsc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/sde_rsc.c b/drivers/gpu/drm/msm/sde_rsc.c index 65bdc1a229b8..913a4dc4783f 100644 --- a/drivers/gpu/drm/msm/sde_rsc.c +++ b/drivers/gpu/drm/msm/sde_rsc.c @@ -536,7 +536,7 @@ static int sde_rsc_switch_to_cmd_v3(struct sde_rsc_priv *rsc, */ if (rsc->current_state == SDE_RSC_CMD_STATE) { rc = 0; - if (config) + if (config && rsc->version < SDE_RSC_REV_3) goto vsync_wait; else goto end; @@ -800,7 +800,7 @@ static int sde_rsc_switch_to_vid_v3(struct sde_rsc_priv *rsc, */ if (rsc->current_state == SDE_RSC_VID_STATE) { rc = 0; - if (config) + if (config && rsc->version < SDE_RSC_REV_3) goto vsync_wait; else goto end; From 2efed28e8e957023256719d0c22b89c33962d34a Mon Sep 17 00:00:00 2001 From: Dhaval Patel Date: Fri, 16 Apr 2021 14:15:39 +0530 Subject: [PATCH 15/44] disp: msm: update min prefill lines for sde rsc rev3 Update minimum prefill lines for command mode displays based on system recommendation for different fps. Video mode display can support prefill lines based on panel porches. Change-Id: I52dc67035fa80668281926ce4d7dd1b292fbc3b7 Signed-off-by: Dhaval Patel --- drivers/gpu/drm/msm/sde_rsc.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/sde_rsc.c b/drivers/gpu/drm/msm/sde_rsc.c index 913a4dc4783f..224e837863a6 100644 --- a/drivers/gpu/drm/msm/sde_rsc.c +++ b/drivers/gpu/drm/msm/sde_rsc.c @@ -394,6 +394,7 @@ static u32 sde_rsc_timer_calculate(struct sde_rsc_priv *rsc, u64 pdc_backoff_time_ns; s64 total; int ret = 0; + u32 default_prefill_lines; if (cmd_config) memcpy(&rsc->cmd_config, cmd_config, sizeof(*cmd_config)); @@ -407,12 +408,23 @@ static u32 sde_rsc_timer_calculate(struct sde_rsc_priv *rsc, rsc->cmd_config.jitter_denom = DEFAULT_PANEL_JITTER_DENOMINATOR; if (!rsc->cmd_config.vtotal) rsc->cmd_config.vtotal = DEFAULT_PANEL_VTOTAL; - if (!rsc->cmd_config.prefill_lines) - rsc->cmd_config.prefill_lines = DEFAULT_PANEL_PREFILL_LINES; - if (rsc->cmd_config.prefill_lines > DEFAULT_PANEL_MAX_V_PREFILL) - rsc->cmd_config.prefill_lines = DEFAULT_PANEL_MAX_V_PREFILL; - if (rsc->cmd_config.prefill_lines < DEFAULT_PANEL_MIN_V_PREFILL) - rsc->cmd_config.prefill_lines = DEFAULT_PANEL_MIN_V_PREFILL; + + if (rsc->version < SDE_RSC_REV_3) { + default_prefill_lines = rsc->cmd_config.prefill_lines; + if (!default_prefill_lines) + default_prefill_lines = DEFAULT_PANEL_PREFILL_LINES; + if (default_prefill_lines > DEFAULT_PANEL_MAX_V_PREFILL) + default_prefill_lines = DEFAULT_PANEL_MAX_V_PREFILL; + if (default_prefill_lines < DEFAULT_PANEL_MIN_V_PREFILL) + default_prefill_lines = DEFAULT_PANEL_MIN_V_PREFILL; + rsc->cmd_config.prefill_lines = default_prefill_lines; + } else { + default_prefill_lines = (rsc->cmd_config.fps * + DEFAULT_PANEL_MIN_V_PREFILL) / DEFAULT_PANEL_FPS; + if ((state == SDE_RSC_CMD_STATE) || + (rsc->cmd_config.prefill_lines < default_prefill_lines)) + rsc->cmd_config.prefill_lines = default_prefill_lines; + } pr_debug("frame fps:%d jitter_numer:%d jitter_denom:%d vtotal:%d prefill lines:%d\n", rsc->cmd_config.fps, rsc->cmd_config.jitter_numer, rsc->cmd_config.jitter_denom, rsc->cmd_config.vtotal, From b006dcd289f8ac1bf89f63bf3847908e43b16056 Mon Sep 17 00:00:00 2001 From: Yashwanth Date: Fri, 16 Apr 2021 13:44:46 +0530 Subject: [PATCH 16/44] disp: msm: increase delay times while waiting to turn off rscc clocks RSC is timing out while checking for power control register, increasing wait times only after a poms, removes this issue. Change-Id: Idf18ae7a6a142a3f004013996a641d8bd7de94ff Signed-off-by: Yashwanth --- drivers/gpu/drm/msm/sde_rsc.c | 3 +++ drivers/gpu/drm/msm/sde_rsc_hw_v3.c | 9 ++++++++- drivers/gpu/drm/msm/sde_rsc_priv.h | 4 +++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/sde_rsc.c b/drivers/gpu/drm/msm/sde_rsc.c index 224e837863a6..022f9f953a71 100644 --- a/drivers/gpu/drm/msm/sde_rsc.c +++ b/drivers/gpu/drm/msm/sde_rsc.c @@ -570,6 +570,7 @@ static int sde_rsc_switch_to_cmd_v3(struct sde_rsc_priv *rsc, /* indicate wait for vsync for vid to cmd state switch & cfg update */ if (!rc && (rsc->current_state == SDE_RSC_VID_STATE || rsc->current_state == SDE_RSC_CMD_STATE)) { + rsc->post_poms = true; /* clear VSYNC timestamp for indication when update completes */ if (rsc->hw_ops.hw_vsync) rsc->hw_ops.hw_vsync(rsc, VSYNC_ENABLE, NULL, 0, 0); @@ -835,6 +836,7 @@ static int sde_rsc_switch_to_vid_v3(struct sde_rsc_priv *rsc, /* indicate wait for vsync for vid to cmd state switch & cfg update */ if (!rc && (rsc->current_state == SDE_RSC_VID_STATE || rsc->current_state == SDE_RSC_CMD_STATE)) { + rsc->post_poms = true; /* clear VSYNC timestamp for indication when update completes */ if (rsc->hw_ops.hw_vsync) rsc->hw_ops.hw_vsync(rsc, VSYNC_ENABLE, NULL, 0, 0); @@ -965,6 +967,7 @@ static int sde_rsc_switch_to_idle_v3(struct sde_rsc_priv *rsc, rc = CLK_MODE_SWITCH_SUCCESS; } else if (rsc->hw_ops.state_update) { rc = rsc->hw_ops.state_update(rsc, SDE_RSC_IDLE_STATE); + rsc->post_poms = false; if (!rc) rpmh_mode_solver_set(rsc->disp_rsc, true); } diff --git a/drivers/gpu/drm/msm/sde_rsc_hw_v3.c b/drivers/gpu/drm/msm/sde_rsc_hw_v3.c index 2dcc0a947dc1..9127f53c3381 100644 --- a/drivers/gpu/drm/msm/sde_rsc_hw_v3.c +++ b/drivers/gpu/drm/msm/sde_rsc_hw_v3.c @@ -282,7 +282,7 @@ static int sde_rsc_mode2_entry_trigger(struct sde_rsc_priv *rsc) rc = 0; break; } - usleep_range(10, 100); + usleep_range(50, 100); } return rc; @@ -347,6 +347,13 @@ static int sde_rsc_mode2_entry_v3(struct sde_rsc_priv *rsc) dss_reg_w(&rsc->drv_io, SDE_RSC_SOLVER_SOLVER_MODES_ENABLED_DRV0, 0x7, rsc->debug_mode); + /** + * increase delay time to wait before mode2 entry, + * longer time required subsequent to panel mode change + */ + if (rsc->post_poms) + usleep_range(750, 1000); + for (i = 0; i <= MAX_MODE2_ENTRY_TRY; i++) { rc = sde_rsc_mode2_entry_trigger(rsc); if (!rc) diff --git a/drivers/gpu/drm/msm/sde_rsc_priv.h b/drivers/gpu/drm/msm/sde_rsc_priv.h index 1e43eae8724d..c867b30f4736 100644 --- a/drivers/gpu/drm/msm/sde_rsc_priv.h +++ b/drivers/gpu/drm/msm/sde_rsc_priv.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -201,6 +201,7 @@ struct sde_rsc_bw_config { * rsc_vsync_wait: Refcount to indicate if we have to wait for the vsync. * rsc_vsync_waitq: Queue to wait for the vsync. * bw_config: check sde_rsc_bw_config structure description. + * post_poms: bool if a panel mode change occurred */ struct sde_rsc_priv { u32 version; @@ -242,6 +243,7 @@ struct sde_rsc_priv { wait_queue_head_t rsc_vsync_waitq; struct sde_rsc_bw_config bw_config; + bool post_poms; }; /** From ec021f6f09c29451fc660f92f20754175caf9bb5 Mon Sep 17 00:00:00 2001 From: Yashwanth Date: Fri, 16 Apr 2021 20:57:30 +0530 Subject: [PATCH 17/44] disp: msm: avoid removing BW vote when layers are staged In cases like doze suspend bandwidth values are received zero even though layers are staged. In such case previous bandwidth vote is retained to avoid removal of votes from display side. Change-Id: I6b84f11c716c0509e8970cf3c2955ce5f9f9dfb0 Signed-off-by: Yashwanth --- drivers/gpu/drm/msm/sde/sde_core_perf.c | 96 +++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/sde/sde_core_perf.c b/drivers/gpu/drm/msm/sde/sde_core_perf.c index 82e1a5a69046..520ca98521a7 100644 --- a/drivers/gpu/drm/msm/sde/sde_core_perf.c +++ b/drivers/gpu/drm/msm/sde/sde_core_perf.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -26,9 +26,13 @@ #include "sde_trace.h" #include "sde_crtc.h" #include "sde_core_perf.h" +#include "sde_connector.h" #define SDE_PERF_MODE_STRING_SIZE 128 +#define GET_H32(val) (val >> 32) +#define GET_L32(val) (val & 0xffffffff) + static DEFINE_MUTEX(sde_core_perf_lock); /** @@ -84,6 +88,69 @@ static bool _sde_core_perf_crtc_is_power_on(struct drm_crtc *crtc) return sde_crtc_is_enabled(crtc); } +static void _sde_core_perf_calc_doze_suspend(struct drm_crtc *crtc, + struct drm_crtc_state *state, + struct sde_core_perf_params *perf) +{ + struct sde_crtc_state *new_cstate, *old_cstate; + struct sde_core_perf_params *old_perf; + struct drm_connector *conn = NULL; + struct sde_connector *c_conn = NULL; + bool is_doze_suspend = false; + int i; + + if (!crtc || !crtc->state || !state) + return; + + old_cstate = to_sde_crtc_state(crtc->state); + new_cstate = to_sde_crtc_state(state); + old_perf = &old_cstate->new_perf; + + if (!old_perf) + return; + + if (!perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC] && + !perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_MNOC] && + state->plane_mask) { + + perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC] = + old_perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC]; + perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_MNOC] = + old_perf->max_per_pipe_ib + [SDE_POWER_HANDLE_DBUS_ID_MNOC]; + perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_LLCC] = + old_perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_LLCC]; + perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_LLCC] = + old_perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_LLCC]; + perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_EBI] = + old_perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_EBI]; + perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_EBI] = + old_perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_EBI]; + + if (!old_perf->core_clk_rate) + perf->core_clk_rate = old_perf->core_clk_rate; + + for (i = 0; i < new_cstate->num_connectors; i++) { + conn = new_cstate->connectors[i]; + if (!conn) + continue; + c_conn = to_sde_connector(conn); + if ((c_conn->dpms_mode == DRM_MODE_DPMS_ON) && + (sde_connector_get_lp(conn) == SDE_MODE_DPMS_LP2)) + is_doze_suspend = true; + } + + if (!is_doze_suspend && conn && c_conn) + SDE_ERROR("No BW, planes:%x dpms_mode:%d lpmode:%d\n", + state->plane_mask, c_conn->dpms_mode, + sde_connector_get_lp(conn)); + if (conn && c_conn) + SDE_EVT32(state->plane_mask, c_conn->dpms_mode, + sde_connector_get_lp(conn), is_doze_suspend, + SDE_EVTLOG_ERROR); + } +} + static void _sde_core_perf_calc_crtc(struct sde_kms *kms, struct drm_crtc *crtc, struct drm_crtc_state *state, @@ -128,6 +195,8 @@ static void _sde_core_perf_calc_crtc(struct sde_kms *kms, perf->core_clk_rate = sde_crtc_get_property(sde_cstate, CRTC_PROP_CORE_CLK); + _sde_core_perf_calc_doze_suspend(crtc, state, perf); + if (!sde_cstate->bw_control) { for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++) { perf->bw_ctl[i] = kms->catalog->perf.max_bw_high * @@ -143,13 +212,30 @@ static void _sde_core_perf_calc_crtc(struct sde_kms *kms, perf->core_clk_rate = 0; } else if (kms->perf.perf_tune.mode == SDE_PERF_MODE_FIXED) { for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX; i++) { - perf->bw_ctl[i] = kms->perf.fix_core_ab_vote; - perf->max_per_pipe_ib[i] = kms->perf.fix_core_ib_vote; + perf->bw_ctl[i] = max(kms->perf.fix_core_ab_vote, + perf->bw_ctl[i]); + perf->max_per_pipe_ib[i] = max( + kms->perf.fix_core_ib_vote, + perf->max_per_pipe_ib[i]); } - perf->core_clk_rate = kms->perf.fix_core_clk_rate; + perf->core_clk_rate = max(kms->perf.fix_core_clk_rate, + perf->core_clk_rate); } - SDE_EVT32(crtc->base.id, perf->core_clk_rate); + SDE_EVT32(DRMID(crtc), perf->core_clk_rate, + GET_H32(perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC]), + GET_L32(perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC]), + GET_H32(perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_LLCC]), + GET_L32(perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_LLCC]), + GET_H32(perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_EBI]), + GET_L32(perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_EBI])); + SDE_EVT32(DRMID(crtc), + GET_H32(perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_MNOC]), + GET_L32(perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_MNOC]), + GET_H32(perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_LLCC]), + GET_L32(perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_LLCC]), + GET_H32(perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_EBI]), + GET_L32(perf->max_per_pipe_ib[SDE_POWER_HANDLE_DBUS_ID_EBI])); trace_sde_perf_calc_crtc(crtc->base.id, perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_MNOC], perf->bw_ctl[SDE_POWER_HANDLE_DBUS_ID_LLCC], From 15c61ec4d6c1d9dc0fa16ed97d1cb4a717b3038f Mon Sep 17 00:00:00 2001 From: Elson Roy Serrao Date: Fri, 22 Nov 2019 10:36:37 -0800 Subject: [PATCH 18/44] usb: dwc3: Avoid resume_work flush in pm_suspend/pm_resume dwc3_resume_work is dependent on sm_work which is a freezable task. When control reaches pm_suspend or pm_resume sm_work is frozen at that point as part of freeze_processes() api which is called for system-wide suspend. If there is any pending work on sm_work & we try to flush when it is frozen we end up in a deadlock as the suspend/resume thread cannot progress. Avoid flushing this wq in pm_suspend/resume. Change-Id: I5eada1c3d11085fcd1b424a1bdb7e0c949f7ef42 Signed-off-by: Elson Roy Serrao --- drivers/usb/dwc3/dwc3-msm.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index db34620989cf..cce3189a7324 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -5138,8 +5138,6 @@ static int dwc3_msm_pm_suspend(struct device *dev) dev_dbg(dev, "dwc3-msm PM suspend\n"); dbg_event(0xFF, "PM Sus", 0); - flush_workqueue(mdwc->dwc3_wq); - /* * Check if pm_suspend can proceed irrespective of runtimePM state of * host. @@ -5171,8 +5169,6 @@ static int dwc3_msm_pm_resume(struct device *dev) dev_dbg(dev, "dwc3-msm PM resume\n"); dbg_event(0xFF, "PM Res", 0); - /* flush to avoid race in read/write of pm_suspended */ - flush_workqueue(mdwc->dwc3_wq); atomic_set(&mdwc->pm_suspended, 0); if (atomic_read(&dwc->in_lpm) && From 91a2d888e2d27964669c0299533870aa71655607 Mon Sep 17 00:00:00 2001 From: Rohith Kollalsi Date: Mon, 1 Mar 2021 20:46:50 +0530 Subject: [PATCH 19/44] usb: gadget: f_cdev: Fix use after free of port in f_cdev MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the configfs filesystem it’s possible to manipulate kernel object by creating/deleting folders into /config path. Here port object is created by a mkdir and leads to allocate this object, while the rmdir system call leads to free this object. If one thread does these two operations of creation and deletion of the folder and one tries to open it, it can lead to a race condition where port object can be freed by the time it is used in f_cdev_open leading to use after free error. Fix this by using embedded struct device and the refcounting mechanism built-in which increases and decreases refcount upon creation and deletion of port and port will be freed when reference count is zero ensuring that "port" object survives until the last user releases it. Change-Id: I88701ef161c9f3215631da81c3a8d4c980d12b25 Signed-off-by: Rohith Kollalsi --- drivers/usb/gadget/function/f_cdev.c | 56 ++++++++++++++-------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/usb/gadget/function/f_cdev.c b/drivers/usb/gadget/function/f_cdev.c index b0faafca4b1b..bb370bdb26cc 100644 --- a/drivers/usb/gadget/function/f_cdev.c +++ b/drivers/usb/gadget/function/f_cdev.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2013-2021, The Linux Foundation. All rights reserved. * Linux Foundation chooses to take subject only to the GPLv2 license terms, * and distributes only under these terms. * @@ -94,7 +94,7 @@ struct cserial { struct f_cdev { struct cdev fcdev_cdev; - struct device *dev; + struct device dev; unsigned int port_num; char name[sizeof(DEVICE_NAME) + 2]; int minor; @@ -953,13 +953,16 @@ static void cser_free_inst(struct usb_function_instance *fi) opts = container_of(fi, struct f_cdev_opts, func_inst); if (opts->port) { - device_destroy(fcdev_classp, MKDEV(major, opts->port->minor)); - cdev_del(&opts->port->fcdev_cdev); + cdev_device_del(&opts->port->fcdev_cdev, &opts->port->dev); + mutex_lock(&chardev_ida_lock); + ida_simple_remove(&chardev_ida, opts->port->minor); + mutex_unlock(&chardev_ida_lock); usb_cser_debugfs_exit(opts->port); + put_device(&opts->port->dev); } + usb_cser_chardev_deinit(); kfree(opts->func_name); - kfree(opts->port); kfree(opts); } @@ -1181,13 +1184,10 @@ int f_cdev_open(struct inode *inode, struct file *file) struct f_cdev *port; port = container_of(inode->i_cdev, struct f_cdev, fcdev_cdev); - if (!port) { - pr_err("Port is NULL.\n"); - return -EINVAL; - } - - if (port && port->port_open) { + get_device(&port->dev); + if (port->port_open) { pr_err("port is already opened.\n"); + put_device(&port->dev); return -EBUSY; } @@ -1197,6 +1197,7 @@ int f_cdev_open(struct inode *inode, struct file *file) port->is_connected); if (ret) { pr_debug("open interrupted.\n"); + put_device(&port->dev); return ret; } @@ -1216,16 +1217,12 @@ int f_cdev_release(struct inode *inode, struct file *file) struct f_cdev *port; port = file->private_data; - if (!port) { - pr_err("port is NULL.\n"); - return -EINVAL; - } - spin_lock_irqsave(&port->port_lock, flags); port->port_open = false; port->cbits_updated = false; spin_unlock_irqrestore(&port->port_lock, flags); pr_debug("port(%s)(%pK) is closed.\n", port->name, port); + put_device(&port->dev); return 0; } @@ -1830,11 +1827,17 @@ static void usb_cser_debugfs_exit(struct f_cdev *port) debugfs_remove_recursive(port->debugfs_root); } +static void cdev_device_release(struct device *dev) +{ + struct f_cdev *port = container_of(dev, struct f_cdev, dev); + + pr_debug("Free cdev port(%d)\n", port->port_num); + kfree(port); +} + static struct f_cdev *f_cdev_alloc(char *func_name, int portno) { int ret; - dev_t dev; - struct device *device; struct f_cdev *port; port = kzalloc(sizeof(struct f_cdev), GFP_KERNEL); @@ -1885,27 +1888,24 @@ static struct f_cdev *f_cdev_alloc(char *func_name, int portno) /* create char device */ cdev_init(&port->fcdev_cdev, &f_cdev_fops); - dev = MKDEV(major, port->minor); - ret = cdev_add(&port->fcdev_cdev, dev, 1); + device_initialize(&port->dev); + port->dev.class = fcdev_classp; + port->dev.parent = NULL; + port->dev.release = cdev_device_release; + port->dev.devt = MKDEV(major, port->minor); + dev_set_name(&port->dev, port->name); + ret = cdev_device_add(&port->fcdev_cdev, &port->dev); if (ret) { pr_err("Failed to add cdev for port(%s)\n", port->name); goto err_cdev_add; } - device = device_create(fcdev_classp, NULL, dev, NULL, port->name); - if (IS_ERR(device)) { - ret = PTR_ERR(device); - goto err_create_dev; - } - usb_cser_debugfs_init(port); pr_info("port_name:%s (%pK) portno:(%d)\n", port->name, port, port->port_num); return port; -err_create_dev: - cdev_del(&port->fcdev_cdev); err_cdev_add: destroy_workqueue(port->fcdev_wq); err_get_ida: From 61157228afac45004ff821f22e292a7402e839ab Mon Sep 17 00:00:00 2001 From: Kasin Li Date: Wed, 14 Apr 2021 02:08:09 +0800 Subject: [PATCH 20/44] soc: qcom: hgsl: Fix OOB Need check context index is valid or not before use it. Change-Id: Ifd4f5dffb3a9317e13516e4863059b087d39fc66 Signed-off-by: Kasin Li --- drivers/soc/qcom/hgsl/hgsl.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/soc/qcom/hgsl/hgsl.c b/drivers/soc/qcom/hgsl/hgsl.c index f459774e3911..df81bce30f19 100644 --- a/drivers/soc/qcom/hgsl/hgsl.c +++ b/drivers/soc/qcom/hgsl/hgsl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -688,7 +688,7 @@ static int hgsl_dbq_assign(struct file *filep, unsigned long arg) if (copy_from_user(&dbq_idx, USRPTR(arg), sizeof(dbq_idx))) return -EFAULT; - if (dbq_idx > MAX_DB_QUEUE) + if (dbq_idx >= MAX_DB_QUEUE) return -EINVAL; priv->dbq_idx = dbq_idx; @@ -1103,6 +1103,9 @@ static int hgsl_wait_timestamp(struct file *filep, unsigned long arg) timestamp = param.timestamp; + if (param.context_id >= HGSL_CONTEXT_NUM) + return -EINVAL; + read_lock(&hgsl->ctxt_lock); ctxt = hgsl->contexts[param.context_id]; if (ctxt == NULL) { From 1d10b6bcde0a34b6f1893290739fe6e1df6f8da7 Mon Sep 17 00:00:00 2001 From: Jeya R Date: Sun, 2 May 2021 15:03:49 +0530 Subject: [PATCH 21/44] msm: adsprpc: do pm stay awake vote in rpmsg callback Vote with PM to keep the CPU awake in the rpmsg interrupt callback itself, instead of voting from the fastrpc thread after it is woken up and scheduled, to handle race between actual remote subsystem response and context interruption because of CPU going into suspend. Change-Id: Ie97bf39e2ba0080cf738cc94cb65302acbd0f653 Acked-by: Thyagarajan Venkatanarayanan Acked-by: Maitreyi Gupta Signed-off-by: Jeya R --- drivers/char/adsprpc.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index fd9ca062600a..8a16287c7dbd 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -233,6 +233,7 @@ struct smq_invoke_ctx { uint32_t *crc; unsigned int magic; uint64_t ctxid; + bool pm_awake_voted; }; struct fastrpc_ctx_lst { @@ -455,6 +456,8 @@ static struct fastrpc_channel_ctx gcinfo[NUM_CHANNELS] = { static int hlosvm[1] = {VMID_HLOS}; static int hlosvmperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC}; +static void fastrpc_pm_awake(int fl_wake_enable, bool *pm_awake_voted); +static void fastrpc_pm_relax(bool *pm_awake_voted); static inline int64_t getnstimediff(struct timespec *start) { int64_t ns; @@ -1267,6 +1270,7 @@ static int context_alloc(struct fastrpc_file *fl, uint32_t kernel, ctx->tgid = fl->tgid; init_completion(&ctx->work); ctx->magic = FASTRPC_CTX_MAGIC; + ctx->pm_awake_voted = false; spin_lock(&fl->hlock); hlist_add_head(&ctx->hn, &clst->pending); @@ -1337,6 +1341,7 @@ static void context_free(struct smq_invoke_ctx *ctx) static void context_notify_user(struct smq_invoke_ctx *ctx, int retval) { ctx->retval = retval; + fastrpc_pm_awake(ctx->fl->wake_enable, &ctx->pm_awake_voted); complete(&ctx->work); } @@ -1937,7 +1942,7 @@ static void fastrpc_init(struct fastrpc_apps *me) me->channel[CDSP_DOMAIN_ID].secure = NON_SECURE_CHANNEL; } -static inline void fastrpc_pm_awake(int fl_wake_enable, int *wake_enable) +static inline void fastrpc_pm_awake(int fl_wake_enable, bool *pm_awake_voted) { struct fastrpc_apps *me = &gfa; @@ -1949,14 +1954,14 @@ static inline void fastrpc_pm_awake(int fl_wake_enable, int *wake_enable) __pm_stay_awake(me->wake_source); me->wake_count++; spin_unlock(&me->hlock); - *wake_enable = 1; + *pm_awake_voted = true; } -static inline void fastrpc_pm_relax(int *wake_enable) +static inline void fastrpc_pm_relax(bool *pm_awake_voted) { struct fastrpc_apps *me = &gfa; - if (!(*wake_enable)) + if (!(*pm_awake_voted)) return; spin_lock(&me->hlock); @@ -1965,7 +1970,7 @@ static inline void fastrpc_pm_relax(int *wake_enable) if (!me->wake_count) __pm_relax(me->wake_source); spin_unlock(&me->hlock); - *wake_enable = 0; + *pm_awake_voted = false; } static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, @@ -1974,10 +1979,10 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, { struct smq_invoke_ctx *ctx = NULL; struct fastrpc_ioctl_invoke *invoke = &inv->inv; - int err = 0, wake_enable = 0; - int cid = -1, interrupted = 0; + int err = 0, cid = -1, interrupted = 0; struct timespec invoket = {0}; int64_t *perf_counter = NULL; + bool pm_awake_voted; cid = fl->cid; VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS); @@ -1991,8 +1996,8 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, goto bail; } perf_counter = getperfcounter(fl, PERF_COUNT); - - fastrpc_pm_awake(fl->wake_enable, &wake_enable); + pm_awake_voted = false; + fastrpc_pm_awake(fl->wake_enable, &pm_awake_voted); if (fl->profile) getnstimeofday(&invoket); @@ -2043,12 +2048,13 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, if (err) goto bail; wait: - fastrpc_pm_relax(&wake_enable); + fastrpc_pm_relax(&pm_awake_voted); if (kernel) wait_for_completion(&ctx->work); else interrupted = wait_for_completion_interruptible(&ctx->work); - fastrpc_pm_awake(fl->wake_enable, &wake_enable); + + pm_awake_voted = ctx->pm_awake_voted; VERIFY(err, 0 == (err = interrupted)); if (err) goto bail; @@ -2090,7 +2096,7 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, *count = *count+1; } } - fastrpc_pm_relax(&wake_enable); + fastrpc_pm_relax(&pm_awake_voted); return err; } From a658eb20b743540ca107182b8fbc29e0b479520b Mon Sep 17 00:00:00 2001 From: Jeya R Date: Sun, 2 May 2021 15:12:49 +0530 Subject: [PATCH 22/44] msm: adsprpc: remove PM vote counter in fastrpc driver Remove PM vote counter in the fastrpc driver as the system wakeup events framework will keep track of CPU awake and relax votes from a specific client and handle it accordingly. Change-Id: If4828884f7c659e5a45fd40af954d8146e5cfb24 Acked-by: Thyagarajan Venkatanarayanan Acked-by: Maitreyi Gupta Signed-off-by: Jeya R --- drivers/char/adsprpc.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 8a16287c7dbd..3bc417a2c6e8 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -313,7 +313,6 @@ struct fastrpc_apps { struct smq_invoke_ctx *ctxtable[FASTRPC_CTX_MAX]; bool legacy_remote_heap; struct wakeup_source *wake_source; - unsigned int wake_count; }; struct fastrpc_mmap { @@ -1946,14 +1945,9 @@ static inline void fastrpc_pm_awake(int fl_wake_enable, bool *pm_awake_voted) { struct fastrpc_apps *me = &gfa; - if (!fl_wake_enable) + if (!fl_wake_enable || *pm_awake_voted) return; - - spin_lock(&me->hlock); - if (!me->wake_count) - __pm_stay_awake(me->wake_source); - me->wake_count++; - spin_unlock(&me->hlock); + __pm_stay_awake(me->wake_source); *pm_awake_voted = true; } @@ -1963,13 +1957,7 @@ static inline void fastrpc_pm_relax(bool *pm_awake_voted) if (!(*pm_awake_voted)) return; - - spin_lock(&me->hlock); - if (me->wake_count) - me->wake_count--; - if (!me->wake_count) - __pm_relax(me->wake_source); - spin_unlock(&me->hlock); + __pm_relax(me->wake_source); *pm_awake_voted = false; } From 82293b13f44ef4f8be1e850636b910233b145cc4 Mon Sep 17 00:00:00 2001 From: Jeya R Date: Sun, 2 May 2021 15:21:06 +0530 Subject: [PATCH 23/44] msm: adsprpc: fix compilation errors in fastrpc driver Update APIs used in fastrpc driver according to the new function implementation of wakeup_source_register. Change-Id: I278fb2e2954908001776240f6321c7de4deb3357 Acked-by: Maitreyi Gupta Signed-off-by: Jeya R --- drivers/char/adsprpc.c | 94 ++++++++++++++++++++++++------------------ 1 file changed, 54 insertions(+), 40 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 3bc417a2c6e8..90815de67b7c 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -113,10 +113,10 @@ #define PERF(enb, cnt, ff) \ {\ - struct timespec startT = {0};\ + struct timespec64 startT = {0};\ int64_t *counter = cnt;\ if (enb && counter) {\ - getnstimeofday(&startT);\ + ktime_get_real_ts64(&startT);\ } \ ff ;\ if (enb && counter) {\ @@ -312,6 +312,9 @@ struct fastrpc_apps { spinlock_t ctxlock; struct smq_invoke_ctx *ctxtable[FASTRPC_CTX_MAX]; bool legacy_remote_heap; + /* Secure subsystems like ADSP/SLPI will use secure client */ + struct wakeup_source *wake_source_secure; + /* Non-secure subsystem like CDSP will use regular client */ struct wakeup_source *wake_source; }; @@ -455,16 +458,18 @@ static struct fastrpc_channel_ctx gcinfo[NUM_CHANNELS] = { static int hlosvm[1] = {VMID_HLOS}; static int hlosvmperm[1] = {PERM_READ | PERM_WRITE | PERM_EXEC}; -static void fastrpc_pm_awake(int fl_wake_enable, bool *pm_awake_voted); -static void fastrpc_pm_relax(bool *pm_awake_voted); -static inline int64_t getnstimediff(struct timespec *start) +static void fastrpc_pm_awake(int fl_wake_enable, bool *pm_awake_voted, + int channel_type); +static void fastrpc_pm_relax(bool *pm_awake_voted, int channel_type); + +static inline int64_t getnstimediff(struct timespec64 *start) { int64_t ns; - struct timespec ts, b; + struct timespec64 ts, b; - getnstimeofday(&ts); - b = timespec_sub(ts, *start); - ns = timespec_to_ns(&b); + ktime_get_real_ts64(&ts); + b = timespec64_sub(ts, *start); + ns = timespec64_to_ns(&b); return ns; } @@ -1340,7 +1345,8 @@ static void context_free(struct smq_invoke_ctx *ctx) static void context_notify_user(struct smq_invoke_ctx *ctx, int retval) { ctx->retval = retval; - fastrpc_pm_awake(ctx->fl->wake_enable, &ctx->pm_awake_voted); + fastrpc_pm_awake(ctx->fl->wake_enable, &ctx->pm_awake_voted, + gcinfo[ctx->fl->cid].secure); complete(&ctx->work); } @@ -1704,10 +1710,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx) DMA_TO_DEVICE); dma_buf_end_cpu_access(map->buf, DMA_TO_DEVICE); - } else - dmac_flush_range(uint64_to_ptr(rpra[i].buf.pv), - uint64_to_ptr(rpra[i].buf.pv - + rpra[i].buf.len)); + } } } PERF_END); @@ -1811,10 +1814,7 @@ static void inv_args_pre(struct smq_invoke_ctx *ctx) DMA_BIDIRECTIONAL); dma_buf_end_cpu_access(map->buf, DMA_BIDIRECTIONAL); - } else - dmac_flush_range( - uint64_to_ptr(rpra[i].buf.pv), (char *) - uint64_to_ptr(rpra[i].buf.pv + 1)); + } } end = (uintptr_t)uint64_to_ptr(rpra[i].buf.pv + @@ -1825,9 +1825,7 @@ static void inv_args_pre(struct smq_invoke_ctx *ctx) DMA_BIDIRECTIONAL); dma_buf_end_cpu_access(map->buf, DMA_BIDIRECTIONAL); - } else - dmac_flush_range((char *)end, - (char *)end + 1); + } } } } @@ -1862,10 +1860,7 @@ static void inv_args(struct smq_invoke_ctx *ctx) DMA_FROM_DEVICE); dma_buf_end_cpu_access(map->buf, DMA_FROM_DEVICE); - } else - dmac_inv_range((char *)uint64_to_ptr(rpra[i].buf.pv), - (char *)uint64_to_ptr(rpra[i].buf.pv - + rpra[i].buf.len)); + } } } @@ -1941,23 +1936,30 @@ static void fastrpc_init(struct fastrpc_apps *me) me->channel[CDSP_DOMAIN_ID].secure = NON_SECURE_CHANNEL; } -static inline void fastrpc_pm_awake(int fl_wake_enable, bool *pm_awake_voted) +static inline void fastrpc_pm_awake(int fl_wake_enable, bool *pm_awake_voted, + int channel_type) { struct fastrpc_apps *me = &gfa; if (!fl_wake_enable || *pm_awake_voted) return; - __pm_stay_awake(me->wake_source); + if (channel_type == SECURE_CHANNEL) + __pm_stay_awake(me->wake_source_secure); + else if (channel_type == NON_SECURE_CHANNEL) + __pm_stay_awake(me->wake_source); *pm_awake_voted = true; } -static inline void fastrpc_pm_relax(bool *pm_awake_voted) +static inline void fastrpc_pm_relax(bool *pm_awake_voted, int channel_type) { struct fastrpc_apps *me = &gfa; if (!(*pm_awake_voted)) return; - __pm_relax(me->wake_source); + if (channel_type == SECURE_CHANNEL) + __pm_relax(me->wake_source_secure); + else if (channel_type == NON_SECURE_CHANNEL) + __pm_relax(me->wake_source); *pm_awake_voted = false; } @@ -1968,7 +1970,7 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, struct smq_invoke_ctx *ctx = NULL; struct fastrpc_ioctl_invoke *invoke = &inv->inv; int err = 0, cid = -1, interrupted = 0; - struct timespec invoket = {0}; + struct timespec64 invoket = {0}; int64_t *perf_counter = NULL; bool pm_awake_voted; @@ -1985,9 +1987,11 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, } perf_counter = getperfcounter(fl, PERF_COUNT); pm_awake_voted = false; - fastrpc_pm_awake(fl->wake_enable, &pm_awake_voted); + if (interrupted != -ERESTARTSYS) + fastrpc_pm_awake(fl->wake_enable, &pm_awake_voted, + gcinfo[cid].secure); if (fl->profile) - getnstimeofday(&invoket); + ktime_get_real_ts64(&invoket); if (!kernel) { VERIFY(err, invoke->handle != FASTRPC_STATIC_HANDLE_KERNEL); @@ -1999,8 +2003,7 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, } if (!kernel) { - VERIFY(err, 0 == context_restore_interrupted(fl, inv, - &ctx)); + err = context_restore_interrupted(fl, inv, &ctx); if (err) goto bail; if (fl->sctx->smmu.faults) @@ -2036,7 +2039,7 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, if (err) goto bail; wait: - fastrpc_pm_relax(&pm_awake_voted); + fastrpc_pm_relax(&pm_awake_voted, gcinfo[cid].secure); if (kernel) wait_for_completion(&ctx->work); else @@ -2047,7 +2050,6 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, if (err) goto bail; - PERF(fl->profile, GET_COUNTER(perf_counter, PERF_INVARGS), if (!fl->sctx->smmu.coherent) inv_args(ctx); @@ -2084,7 +2086,7 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, *count = *count+1; } } - fastrpc_pm_relax(&pm_awake_voted); + fastrpc_pm_relax(&pm_awake_voted, gcinfo[cid].secure); return err; } @@ -4561,11 +4563,21 @@ static int __init fastrpc_device_init(void) } me->rpmsg_register = 1; - me->wake_source = wakeup_source_register(dev, "adsprpc"); + me->wake_source = wakeup_source_register(dev, "adsprpc-non_secure"); VERIFY(err, !IS_ERR_OR_NULL(me->wake_source)); if (err) { - pr_err("adsprpc: Error: %s: wakeup_source_register failed with err %d\n", - __func__, PTR_ERR(me->wake_source)); + pr_err("adsprpc: Error: %s: wakeup_source_register failed for %s with err %ld\n", + __func__, dev_name(dev), PTR_ERR(me->wake_source)); + goto device_create_bail; + } + + me->wake_source_secure = wakeup_source_register(secure_dev, + "adsprpc-secure"); + VERIFY(err, !IS_ERR_OR_NULL(me->wake_source_secure)); + if (err) { + pr_err("adsprpc: Error: %s: wakeup_source_register failed for %s with err %ld\n", + __func__, dev_name(secure_dev), + PTR_ERR(me->wake_source_secure)); goto device_create_bail; } return 0; @@ -4618,6 +4630,8 @@ static void __exit fastrpc_device_exit(void) unregister_rpmsg_driver(&fastrpc_rpmsg_client); if (me->wake_source) wakeup_source_unregister(me->wake_source); + if (me->wake_source_secure) + wakeup_source_unregister(me->wake_source_secure); debugfs_remove_recursive(debugfs_root); } From 24929c28ea703f582aaaaa40e174e1cdc7d0881d Mon Sep 17 00:00:00 2001 From: Udipto Goswami Date: Mon, 11 Jan 2021 14:06:22 +0530 Subject: [PATCH 24/44] usb: dwc3: Avoid resume_work flush in pm_freeze/restore dwc3_resume_work is dependent on sm_work which is a freezable task. Therefore when control reaches pm_freeze/restore, sm_work is frozen as part of freeze_processes() called from system-wide suspend. So if any pending work on sm_work is there and we try to flush, it will end up in deadlock as freeze/restore cannot progress. Fix this be avoiding flush work during pm_freeze/restore. Change-Id: Icd19c6d9d53d5a804644c5584667d95929ecce6c Signed-off-by: Udipto Goswami --- drivers/usb/dwc3/dwc3-msm.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/usb/dwc3/dwc3-msm.c b/drivers/usb/dwc3/dwc3-msm.c index cce3189a7324..af9c698323ba 100644 --- a/drivers/usb/dwc3/dwc3-msm.c +++ b/drivers/usb/dwc3/dwc3-msm.c @@ -5205,8 +5205,6 @@ static int dwc3_msm_pm_freeze(struct device *dev) dev_dbg(dev, "dwc3-msm PM freeze\n"); dbg_event(0xFF, "PM Freeze", 0); - flush_workqueue(mdwc->dwc3_wq); - /* * Check if pm_freeze can proceed irrespective of runtimePM state of * host. @@ -5252,8 +5250,6 @@ static int dwc3_msm_pm_restore(struct device *dev) dev_dbg(dev, "dwc3-msm PM restore\n"); dbg_event(0xFF, "PM Restore", 0); - /* flush to avoid race in read/write of pm_suspended */ - flush_workqueue(mdwc->dwc3_wq); atomic_set(&mdwc->pm_suspended, 0); if (!dwc->ignore_wakeup_src_in_hostmode || !mdwc->in_host_mode) { From 2b1ebe19e1389e7afb848b94b9987f1d960cd7a2 Mon Sep 17 00:00:00 2001 From: Jeya R Date: Wed, 19 May 2021 13:30:14 +0530 Subject: [PATCH 25/44] msm: adsprpc: Clean buffers on remote invocation failure Current code doesn't clean up buffers and dma handles when failure is seen in the remote invocation to DSP. This will end up leaking buffers and also dma handles pointing to wrong memory in the fastrpc kernel. Clean buffers and dma handles even when remote invocation to DSP returns failure. Change-Id: I23998a1825f14a4c97380e284626df18f5045ed8 Signed-off-by: Jeya R --- drivers/char/adsprpc.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 90815de67b7c..6265fba5755a 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -2055,16 +2055,17 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, inv_args(ctx); PERF_END); - VERIFY(err, 0 == (err = ctx->retval)); - if (err) - goto bail; - PERF(fl->profile, GET_COUNTER(perf_counter, PERF_PUTARGS), VERIFY(err, 0 == put_args(kernel, ctx, invoke->pra)); PERF_END); if (err) goto bail; - bail: + + VERIFY(err, 0 == (err = ctx->retval)); + if (err) + goto bail; + +bail: if (ctx && interrupted == -ERESTARTSYS) context_save_interrupted(ctx); else if (ctx) From 71070edfaabc0a8a457f5c95a9c0b0a8524f67ca Mon Sep 17 00:00:00 2001 From: Pradeep P V K Date: Mon, 10 May 2021 15:30:56 +0530 Subject: [PATCH 26/44] fuse: Set fuse request error upon fuse abort connection There is a minor race in setting the fuse out request error between fuse_abort_conn() and fuse_dev_do_read() as explained below. Thread-1 Thread-2 ======== ======== ->fuse_simple_request() ->shutdown ->__fuse_request_send() ->queue_request() ->fuse_abort_conn() ->fuse_dev_do_read() ->acquire(fpq->lock) ->wait_for(fpq->lock) ->set err to all req's in fpq->io ->release(fpq->lock) ->acquire(fpq->lock) ->add req to fpq->io The above scenario may cause Thread-1 request to add into fpq->io list after Thread-2 sets -ECONNABORTED err to all its requests in fpq->io list. This leaves Thread-1 request with unset err and this further misleads as a completed request without an err set upon request_end(). Handle this by setting the err appropriately. Change-Id: I7961c421939423290f6b78a619490d2cc3fbcb33 Signed-off-by: Pradeep P V K --- fs/fuse/dev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index bfd6353ef7fa..59e9ceb138cd 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1313,6 +1313,7 @@ static ssize_t fuse_dev_do_read(struct fuse_dev *fud, struct file *file, clear_bit(FR_LOCKED, &req->flags); if (!fpq->connected) { err = -ENODEV; + req->out.h.error = err; goto out_end; } if (err) { From a60f96770fd03a77d28aff2c210f5edd68b3fbc9 Mon Sep 17 00:00:00 2001 From: Ahmad Masri Date: Tue, 15 Dec 2020 14:10:04 +0200 Subject: [PATCH 27/44] wil6210: AP should not forward eapol packets In AP mode, the driver checks each received frame, in case it is multicast or unicast packet targeted to one of the AP clients, the driver does the routing in L2 level. EAPOL packet is plaintext frame and it should not follow the above role. When AP receives an EAPOL packet that is multicast or targeted to a client in the AP network, the driver should not forward this packet immediately in L2. EAPOL packet should be indicated to the network stack which will check the packet validity and will decide if to forward the packet to its client or not. Change-Id: I0edf339c3be5a2300e7b8168866286e71045c0d5 Signed-off-by: Ahmad Masri --- drivers/net/wireless/ath/wil6210/txrx.c | 6 ++++-- drivers/net/wireless/ath/wil6210/txrx.h | 9 ++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index deb5688ca9ad..260e4ffbbcd2 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -792,7 +792,9 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) dev_kfree_skb(skb); goto stats; } - } else if (wdev->iftype == NL80211_IFTYPE_AP && !vif->ap_isolate) { + } else if (wdev->iftype == NL80211_IFTYPE_AP && !vif->ap_isolate && + /* pass EAPOL packets to local net stack only */ + (wil_skb_get_protocol(skb) != htons(ETH_P_PAE))) { if (mcast) { /* send multicast frames both to higher layers in * local net stack and back to the wireless medium diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h index 9d83be481839..a7ca5fd324ad 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.h +++ b/drivers/net/wireless/ath/wil6210/txrx.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2016 Qualcomm Atheros, Inc. - * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -560,6 +560,13 @@ static inline int wil_ring_is_full(struct wil_ring *ring) return wil_ring_next_tail(ring) == ring->swhead; } +static inline __be16 wil_skb_get_protocol(struct sk_buff *skb) +{ + struct ethhdr *eth = (void *)skb->data; + + return eth->h_proto; +} + static inline bool wil_need_txstat(struct sk_buff *skb) { struct ethhdr *eth = (void *)skb->data; From ff7ca53dc320b3db4cf3bd4a4d175784b2cf36d8 Mon Sep 17 00:00:00 2001 From: Ahmad Masri Date: Sun, 3 Jan 2021 10:27:49 +0200 Subject: [PATCH 28/44] wil6210: Drop plaintext frames on secure network On secure network, only eap frames are valid unencrypted frames and allowed to be indicated to the local network, any other unencrypted frame should be dropped immediately. Change-Id: Id9d97a4c0984f7bf2d7d6941c4c61e87bc2354cd Signed-off-by: Ahmad Masri --- drivers/net/wireless/ath/wil6210/txrx.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 260e4ffbbcd2..7cbdc38d172b 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -772,6 +772,18 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) skb_orphan(skb); + /* pass only EAPOL packets as plaintext */ + if (vif->privacy && !security && + wil_skb_get_protocol(skb) != htons(ETH_P_PAE)) { + wil_dbg_txrx(wil, + "Rx drop plaintext frame with %d bytes in secure network\n", + skb->len); + dev_kfree_skb(skb); + ndev->stats.rx_dropped++; + stats->rx_dropped++; + return; + } + if (security && (wil->txrx_ops.rx_crypto_check(wil, skb) != 0)) { rc = GRO_DROP; dev_kfree_skb(skb); From bc9269b8a4ec8e778708064d4a3052027e66b5c7 Mon Sep 17 00:00:00 2001 From: Ahmad Masri Date: Sun, 24 Mar 2019 19:24:13 +0200 Subject: [PATCH 29/44] wil6210: accessing 802.3 addresses via utility functions Rearrange the code by having functions to access 802.3 header members, source and destination addresses. Signed-off-by: Ahmad Masri Signed-off-by: Maya Erez Signed-off-by: Kalle Valo Git-commit: 6d1ba32c8070bf9e4088b16d3af1eb2b6f05543c Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git [merez@codeaurora.org: SPDX license conflict] Change-Id: Ib5417ce5ba77e5f96cb3b4d5d9cd322e78f39806 Signed-off-by: Maya Erez --- drivers/net/wireless/ath/wil6210/txrx.c | 34 ++++++++++++------------- drivers/net/wireless/ath/wil6210/txrx.h | 18 +++++++++++-- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 7cbdc38d172b..82bd6d9ea707 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -750,11 +750,11 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) unsigned int len = skb->len; int cid; int security; - struct ethhdr *eth = (void *)skb->data; + u8 *sa, *da = wil_skb_get_da(skb); /* here looking for DA, not A1, thus Rxdesc's 'mcast' indication * is not suitable, need to look at data */ - int mcast = is_multicast_ether_addr(eth->h_dest); + int mcast = is_multicast_ether_addr(da); struct wil_net_stats *stats; struct sk_buff *xmit_skb = NULL; static const char * const gro_res_str[] = { @@ -798,7 +798,8 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) } if (wdev->iftype == NL80211_IFTYPE_STATION) { - if (mcast && ether_addr_equal(eth->h_source, ndev->dev_addr)) { + sa = wil_skb_get_sa(skb); + if (mcast && ether_addr_equal(sa, ndev->dev_addr)) { /* mcast packet looped back to us */ rc = GRO_DROP; dev_kfree_skb(skb); @@ -813,8 +814,7 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) */ xmit_skb = skb_copy(skb, GFP_ATOMIC); } else { - int xmit_cid = wil_find_cid(wil, vif->mid, - eth->h_dest); + int xmit_cid = wil_find_cid(wil, vif->mid, da); if (xmit_cid >= 0) { /* The destination station is associated to @@ -1258,12 +1258,13 @@ static struct wil_ring *wil_find_tx_ucast(struct wil6210_priv *wil, struct wil6210_vif *vif, struct sk_buff *skb) { - int i; - struct ethhdr *eth = (void *)skb->data; - int cid = wil_find_cid(wil, vif->mid, eth->h_dest); + int i, cid; + const u8 *da = wil_skb_get_da(skb); int min_ring_id = wil_get_min_tx_ring_id(wil); - if (cid < 0) + cid = wil_find_cid(wil, vif->mid, da); + + if (cid < 0 || cid >= WIL6210_MAX_CID) return NULL; /* TODO: fix for multiple TID */ @@ -1276,7 +1277,7 @@ static struct wil_ring *wil_find_tx_ucast(struct wil6210_priv *wil, struct wil_ring_tx_data *txdata = &wil->ring_tx_data[i]; wil_dbg_txrx(wil, "find_tx_ucast: (%pM) -> [%d]\n", - eth->h_dest, i); + da, i); if (v->va && txdata->enabled) { return v; } else { @@ -1367,10 +1368,10 @@ static struct wil_ring *wil_find_tx_bcast_1(struct wil6210_priv *wil, static void wil_set_da_for_vring(struct wil6210_priv *wil, struct sk_buff *skb, int vring_index) { - struct ethhdr *eth = (void *)skb->data; + u8 *da = wil_skb_get_da(skb); int cid = wil->ring2cid_tid[vring_index][0]; - ether_addr_copy(eth->h_dest, wil->sta[cid].addr); + ether_addr_copy(da, wil->sta[cid].addr); } static struct wil_ring *wil_find_tx_bcast_2(struct wil6210_priv *wil, @@ -1381,8 +1382,7 @@ static struct wil_ring *wil_find_tx_bcast_2(struct wil6210_priv *wil, struct sk_buff *skb2; int i; u8 cid; - struct ethhdr *eth = (void *)skb->data; - char *src = eth->h_source; + const u8 *src = wil_skb_get_sa(skb); struct wil_ring_tx_data *txdata, *txdata2; int min_ring_id = wil_get_min_tx_ring_id(wil); @@ -2136,8 +2136,8 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) { struct wil6210_vif *vif = ndev_to_vif(ndev); struct wil6210_priv *wil = vif_to_wil(vif); - struct ethhdr *eth = (void *)skb->data; - bool bcast = is_multicast_ether_addr(eth->h_dest); + const u8 *da = wil_skb_get_da(skb); + bool bcast = is_multicast_ether_addr(da); struct wil_ring *ring; static bool pr_once_fw; int rc; @@ -2184,7 +2184,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) ring = wil_find_tx_ucast(wil, vif, skb); } if (unlikely(!ring)) { - wil_dbg_txrx(wil, "No Tx RING found for %pM\n", eth->h_dest); + wil_dbg_txrx(wil, "No Tx RING found for %pM\n", da); goto drop; } /* set up vring entry */ diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h index a7ca5fd324ad..a4d1d3c30709 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.h +++ b/drivers/net/wireless/ath/wil6210/txrx.h @@ -567,11 +567,25 @@ static inline __be16 wil_skb_get_protocol(struct sk_buff *skb) return eth->h_proto; } -static inline bool wil_need_txstat(struct sk_buff *skb) +static inline u8 *wil_skb_get_da(struct sk_buff *skb) +{ + struct ethhdr *eth = (void *)skb->data; + + return eth->h_dest; +} + +static inline u8 *wil_skb_get_sa(struct sk_buff *skb) { struct ethhdr *eth = (void *)skb->data; - return is_unicast_ether_addr(eth->h_dest) && skb->sk && + return eth->h_source; +} + +static inline bool wil_need_txstat(struct sk_buff *skb) +{ + const u8 *da = wil_skb_get_da(skb); + + return is_unicast_ether_addr(da) && skb->sk && (skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS); } From 28d78b4e430c23f2c2e6d277e903f48b139f2da1 Mon Sep 17 00:00:00 2001 From: Ahmad Masri Date: Sun, 15 Nov 2020 17:43:32 +0200 Subject: [PATCH 30/44] wil6210: check integrity of received AMSDU packets Check integrity of received AMSDU packet, 802.11ad QoS spec requires that AMSDU frame contains only MSDUs whose destination address (DA) and sender address (SA) parameter values map to the same receiver address (RA) and transmitter address (TA) values. wil6210 Talyn HW does not check this before it cuts the AMSDU frame into multiple received MSDU packets. Adding checks to wil6210 driver to enforce spec compliance behavior by checking all AMSDU sub frames if it complies with the following: 1- On AP, check packet SA is its client mac address, and on Client check that the DA is the local mac address. If not drop the packet 2- if AMSDU sub frame was dropped on item 1, drop all next sub frame of the AMSDU by checking it has same sn/tid. This patch drops all WDS frames before it checks valid AMSDU, WDS includes supporting MAC header with 4 addresses which is not supported yet, moreover, WDS implies different validity checks on AMSDU frame. Change-Id: I71a39f95c034f05023e0e7ae3ffb5d2b4f8c6b24 Signed-off-by: Ahmad Masri --- drivers/net/wireless/ath/wil6210/main.c | 10 ++- drivers/net/wireless/ath/wil6210/pcie_bus.c | 3 +- drivers/net/wireless/ath/wil6210/txrx_edma.c | 94 +++++++++++++++++++- drivers/net/wireless/ath/wil6210/txrx_edma.h | 20 ++++- drivers/net/wireless/ath/wil6210/wil6210.h | 9 +- drivers/net/wireless/ath/wil6210/wmi.c | 3 +- 6 files changed, 131 insertions(+), 8 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index f419f24611e3..394e1a026c3a 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -308,6 +308,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock) /* statistics */ memset(&sta->stats, 0, sizeof(sta->stats)); sta->stats.tx_latency_min_us = U32_MAX; + wil_sta_info_amsdu_init(sta); } static void _wil6210_disconnect_complete(struct wil6210_vif *vif, @@ -705,6 +706,13 @@ void wil_bcast_fini_all(struct wil6210_priv *wil) } } +void wil_sta_info_amsdu_init(struct wil_sta_info *sta) +{ + sta->amsdu_drop_sn = -1; + sta->amsdu_drop_tid = -1; + sta->amsdu_drop = 0; +} + int wil_priv_init(struct wil6210_priv *wil) { uint i; diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c index bb0d0c85a7b2..4cdd52c59b98 100644 --- a/drivers/net/wireless/ath/wil6210/pcie_bus.c +++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -112,7 +112,6 @@ int wil_set_capabilities(struct wil6210_priv *wil) set_bit(hw_capa_no_flash, wil->hw_capa); wil->use_enhanced_dma_hw = true; wil->use_rx_hw_reordering = true; - wil->use_compressed_rx_status = true; wil_fw_name = ftm_mode ? WIL_FW_NAME_FTM_TALYN : WIL_FW_NAME_TALYN; if (wil_fw_verify_file_exists(wil, wil_fw_name)) diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c index d860f0d59240..a7f9c1bfdde5 100644 --- a/drivers/net/wireless/ath/wil6210/txrx_edma.c +++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -755,6 +755,92 @@ static int wil_tx_ring_modify_edma(struct wil6210_vif *vif, int ring_id, return -EOPNOTSUPP; } +static int wil_check_amsdu(struct wil6210_priv *wil, void *msg, int cid, + struct wil_ring_rx_data *rxdata, + struct sk_buff *skb) +{ + u8 *sa, *da; + int mid, tid; + u16 seq; + struct wil6210_vif *vif; + struct net_device *ndev; + struct wil_sta_info *sta; + + /* drop all WDS packets - not supported */ + if (wil_rx_status_get_ds_type(wil, msg) == WIL_RX_EDMA_DS_TYPE_WDS) { + wil_dbg_txrx(wil, "WDS is not supported"); + return -EAGAIN; + } + + /* check amsdu packets */ + sta = &wil->sta[cid]; + if (!wil_rx_status_is_basic_amsdu(msg)) { + if (sta->amsdu_drop_sn != -1) + wil_sta_info_amsdu_init(sta); + return 0; + } + + mid = wil_rx_status_get_mid(msg); + tid = wil_rx_status_get_tid(msg); + seq = le16_to_cpu(wil_rx_status_get_seq(wil, msg)); + vif = wil->vifs[mid]; + + if (unlikely(!vif)) { + wil_dbg_txrx(wil, "amsdu with invalid mid %d", mid); + return -EAGAIN; + } + + if (unlikely(sta->amsdu_drop)) { + if (sta->amsdu_drop_sn == seq && sta->amsdu_drop_tid == tid) { + wil_dbg_txrx(wil, "Drop AMSDU sub frame, sn=%d\n", + seq); + return -EAGAIN; + } + + /* previous AMSDU finished - clear drop amsdu flag */ + sta->amsdu_drop = 0; + } + + da = wil_skb_get_da(skb); + /* for all sub frame of the AMSDU, check that the SA or DA are valid + * compared with client/AP mac addresses + */ + switch (vif->wdev.iftype) { + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + if (is_multicast_ether_addr(da)) + return 0; + + /* On client side, DA should be the client mac address */ + ndev = vif_to_ndev(vif); + if (ether_addr_equal(ndev->dev_addr, da)) + return 0; + break; + + case NL80211_IFTYPE_P2P_GO: + case NL80211_IFTYPE_AP: + sa = wil_skb_get_sa(skb); + /* On AP side, the packet SA should be the client mac address. + * check also the DA is not rfc 1042 header + */ + if (ether_addr_equal(sta->addr, sa) && + !ether_addr_equal(rfc1042_header, da)) + return 0; + break; + default: + return 0; + } + + sta->amsdu_drop_sn = seq; + sta->amsdu_drop_tid = tid; + sta->amsdu_drop = 1; + wil_dbg_txrx(wil, + "Drop AMSDU frame, sn=%d. Drop this and all next sub frames\n", + seq); + + return -EAGAIN; +} + /* This function is used only for RX SW reorder */ static int wil_check_bar(struct wil6210_priv *wil, void *msg, int cid, struct sk_buff *skb, struct wil_net_stats *stats) @@ -1063,6 +1149,12 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil, wil_hex_dump_txrx("Rx ", DUMP_PREFIX_OFFSET, 16, 1, skb->data, skb_headlen(skb), false); + if (!wil->use_compressed_rx_status && + wil_check_amsdu(wil, msg, cid, rxdata, skb)) { + kfree_skb(skb); + goto again; + } + /* Has to be done after dma_unmap_single as skb->cb is also * used for holding the pa */ diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.h b/drivers/net/wireless/ath/wil6210/txrx_edma.h index a055b7fb6868..de0688265959 100644 --- a/drivers/net/wireless/ath/wil6210/txrx_edma.h +++ b/drivers/net/wireless/ath/wil6210/txrx_edma.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2016,2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2016,2018-2021, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -59,6 +59,9 @@ #define WIL_RX_EDMA_MID_VALID_BIT BIT(22) +#define WIL_RX_EDMA_AMSDU_BASIC_MASK 0x1 +#define WIL_RX_EDMA_DS_TYPE_WDS 0x3 + #define WIL_EDMA_DESC_TX_MAC_CFG_0_QID_POS 16 #define WIL_EDMA_DESC_TX_MAC_CFG_0_QID_LEN 6 @@ -469,6 +472,21 @@ static inline int wil_rx_status_get_fc1(struct wil6210_priv *wil, void *msg) 0, 5) << 2; } +static inline int wil_rx_status_get_ds_type(struct wil6210_priv *wil, void *msg) +{ + if (wil->use_compressed_rx_status) + return 0; + + return WIL_GET_BITS(((struct wil_rx_status_extended *)msg)->ext.d0, + 19, 20); +} + +static inline int wil_rx_status_is_basic_amsdu(void *msg) +{ + return (WIL_GET_BITS(((struct wil_rx_status_compressed *)msg)->d1, + 28, 29) == WIL_RX_EDMA_AMSDU_BASIC_MASK); +} + static inline __le16 wil_rx_status_get_seq(struct wil6210_priv *wil, void *msg) { if (wil->use_compressed_rx_status) diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index 2992b694c71b..8f550ca039ab 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. - * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -763,6 +763,11 @@ struct wil_sta_info { struct wil_tid_crypto_rx group_crypto_rx; u8 aid; /* 1-254; 0 if unknown/not reported */ bool fst_link_loss; + + /* amsdu frame related info to check if the frame is valid */ + int amsdu_drop_sn; + int amsdu_drop_tid; + u8 amsdu_drop; }; enum { @@ -1472,5 +1477,5 @@ int wmi_addba_rx_resp_edma(struct wil6210_priv *wil, u8 mid, u8 cid, u16 agg_wsize, u16 timeout); void update_supported_bands(struct wil6210_priv *wil); - +void wil_sta_info_amsdu_init(struct wil_sta_info *sta); #endif /* __WIL6210_H__ */ diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 13ed315f1c5b..e986971f167b 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2012-2017 Qualcomm Atheros, Inc. - * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -1040,6 +1040,7 @@ static void wmi_evt_connect(struct wil6210_vif *vif, int id, void *d, int len) ether_addr_copy(wil->sta[evt->cid].addr, evt->bssid); wil->sta[evt->cid].mid = vif->mid; wil->sta[evt->cid].status = wil_sta_conn_pending; + wil_sta_info_amsdu_init(&wil->sta[evt->cid]); rc = wil_ring_init_tx(vif, evt->cid); if (rc) { From ebf0fb5f53cce8b676546346dfe42486503cc140 Mon Sep 17 00:00:00 2001 From: Manoj Prabhu B Date: Thu, 15 Apr 2021 16:23:09 +0530 Subject: [PATCH 31/44] diag: Prevent out of bound write while sending dci pkt to remote Sanitize user input length for the maximum buffer size before writing the dci packet to remote. Change-Id: I1f813a969fcce589f9e5024864ef4a650f2cf64e Signed-off-by: Manoj Prabhu B --- drivers/char/diag/diag_dci.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c index 2cbcecab1b53..8d0effb71dc3 100644 --- a/drivers/char/diag/diag_dci.c +++ b/drivers/char/diag/diag_dci.c @@ -1737,7 +1737,16 @@ static int diag_send_dci_pkt_remote(unsigned char *data, int len, int tag, write_len += dci_header_size; *(int *)(buf + write_len) = tag; write_len += sizeof(int); - memcpy(buf + write_len, data, len); + if ((write_len + len) < DIAG_MDM_BUF_SIZE) { + memcpy(buf + write_len, data, len); + } else { + pr_err("diag: skip writing invalid length packet, token: %d, pkt_len: %d\n", + token, (write_len + len)); + spin_lock_irqsave(&driver->dci_mempool_lock, flags); + diagmem_free(driver, buf, dci_ops_tbl[token].mempool); + spin_unlock_irqrestore(&driver->dci_mempool_lock, flags); + return -EAGAIN; + } write_len += len; *(buf + write_len) = CONTROL_CHAR; /* End Terminator */ write_len += sizeof(uint8_t); From c6888b038b5a98fd15c657270cc67ad29cee6ed0 Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Mon, 31 May 2021 20:54:25 +0530 Subject: [PATCH 32/44] drivers: thermal: Add a new DDR bus scaling cooling device Add a new DDR cooling device which can request for a DDR state as a part of cooling device request. This will help in the situation where DDR has to be kept at a specific state during thermally constrained situations. Change-Id: I7acb6ee387dd21281b6a221591a9d1f98a3bc011 Signed-off-by: Manaf Meethalavalappu Pallikunhi --- .../bindings/thermal/qti-ddr-cdev.txt | 65 +++++ drivers/thermal/qcom/Kconfig | 9 + drivers/thermal/qcom/Makefile | 1 + drivers/thermal/qcom/qti_bus_scaling_cdev.c | 227 ++++++++++++++++++ 4 files changed, 302 insertions(+) create mode 100644 Documentation/devicetree/bindings/thermal/qti-ddr-cdev.txt create mode 100644 drivers/thermal/qcom/qti_bus_scaling_cdev.c diff --git a/Documentation/devicetree/bindings/thermal/qti-ddr-cdev.txt b/Documentation/devicetree/bindings/thermal/qti-ddr-cdev.txt new file mode 100644 index 000000000000..14228543615e --- /dev/null +++ b/Documentation/devicetree/bindings/thermal/qti-ddr-cdev.txt @@ -0,0 +1,65 @@ +QTI DDR cooling device. + +The DDR cooling device will be used to place a DDR frequency vote. This +cooling device will be used in those cases where all the subsystem's are +thermally throttled and DDR has to be operated with a minimum performance +level. This cooling device vote can ensure the same. + +Properties: +- compatible: + Usage: required + Value type: + Definition: should be "qcom,ddr-cooling-device". + +Bus Scaling Data: +- qcom,msm-bus,name: + Usage: required + Value type: + Definition: String describing DDR cooling device client. It is defined + at Documentation/devicetree/bindings/arm/msm/msm_bus.txt. +- qcom,msm-bus,num-cases: + Usage: required + Value type: + Definition: This is the number of Bus Scaling use cases + defined in the vectors property. This must be set to more than + one for DDR cooling device based on different levels of DDR + frequency cooling support required. The use-case0 always should + be a vote to take off DDR cdev votes from the system. It is + defined at Documentation/devicetree/bindings/arm/msm/msm_bus.txt. +- qcom,msm-bus,active-only: + Usage: optional + Value type: + Definition: A boolean flag indicating if it is active only + bandwidth vote. It is defined at + Documentation/devicetree/bindings/arm/msm/msm_bus.txt. +- qcom,msm-bus,num-paths: + Usage: required + Value type: + Definition: This represents total number of master-slave pairs for + different usecases. It is defined at + Documentation/devicetree/bindings/arm/msm/msm_bus.txt. +- qcom,msm-bus,vectors-KBps: + Usage: required + Value type: + Definition: A series of 4 cell properties, with a format of + (src, dst, ab, ib). It is defined at + Documentation/devicetree/bindings/arm/msm/msm_bus.txt. + +Cooling Device Property: +- #cooling-cells: + Usage: required + Value type: + Definition: Must be 2. Needed for of_thermal as cooling device + identifier. Please refer to + for more + details. +Example: + qcom,ddr-cdev { + compatible = "qcom,ddr-cooling-device"; + qcom,msm-bus,name = "ddr-cdev"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = <1 512 0 0>, + <1 512 0 366000>; + #cooling-cells = <2>; + }; diff --git a/drivers/thermal/qcom/Kconfig b/drivers/thermal/qcom/Kconfig index 0efbe21ca006..611a93acafc7 100644 --- a/drivers/thermal/qcom/Kconfig +++ b/drivers/thermal/qcom/Kconfig @@ -134,3 +134,12 @@ config QTI_RPM_SMD_COOLING_DEVICE railway at predefined voltage corner using RPM hardware. If you want this support, you should say Y here. + +config QTI_BUS_SCALING_COOLING_DEVICE + tristate "QTI DDR bus scaling cooling device driver" + depends on THERMAL_OF && QCOM_BUS_SCALING + help + This enables the QTI DDR bus scaling cooling devices. These cooling + devices will be used by QTI chipset to place a DDR state request + to meet the performance requirement under thermally constrained + conditions. diff --git a/drivers/thermal/qcom/Makefile b/drivers/thermal/qcom/Makefile index 87e4a8694940..cf50284a749e 100644 --- a/drivers/thermal/qcom/Makefile +++ b/drivers/thermal/qcom/Makefile @@ -12,3 +12,4 @@ obj-$(CONFIG_QTI_BCL_SOC_DRIVER) += bcl_soc.o obj-$(CONFIG_QTI_ADC_TM) += adc-tm.o adc-tm-common.o adc-tm5.o obj-$(CONFIG_QTI_CX_IPEAK_COOLING_DEVICE) += cx_ipeak_cdev.o obj-$(CONFIG_QTI_RPM_SMD_COOLING_DEVICE) += rpm_smd_cooling_device.o +obj-$(CONFIG_QTI_BUS_SCALING_COOLING_DEVICE) += qti_bus_scaling_cdev.o diff --git a/drivers/thermal/qcom/qti_bus_scaling_cdev.c b/drivers/thermal/qcom/qti_bus_scaling_cdev.c new file mode 100644 index 000000000000..c014a72c5fcb --- /dev/null +++ b/drivers/thermal/qcom/qti_bus_scaling_cdev.c @@ -0,0 +1,227 @@ +/* Copyright (c) 2021, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) "%s:%s " fmt, KBUILD_MODNAME, __func__ + +#include +#include +#include +#include +#include + +#define DDR_CDEV_NAME "ddr-bus-scaling-cdev" + +struct ddr_cdev { + uint32_t cur_state; + uint32_t max_state; + uint32_t bus_clnt_handle; + struct thermal_cooling_device *cdev; + struct msm_bus_scale_pdata *ddr_bus_pdata; + struct device *dev; +}; + +/** + * ddr_set_cur_state - callback function to set the ddr state. + * @cdev: thermal cooling device pointer. + * @state: set this variable to the current cooling state. + * + * Callback for the thermal cooling device to change the + * DDR state. + * + * Return: 0 on success, an error code otherwise. + */ +static int ddr_set_cur_state(struct thermal_cooling_device *cdev, + unsigned long state) +{ + struct ddr_cdev *ddr_cdev = cdev->devdata; + int ret = 0; + + /* Request state should be less than max_level */ + if (state > ddr_cdev->max_state) + return -EINVAL; + + /* Check if the old cooling action is same as new cooling action */ + if (ddr_cdev->cur_state == state) + return 0; + + ret = msm_bus_scale_client_update_request(ddr_cdev->bus_clnt_handle, + state); + if (ret) { + dev_err(ddr_cdev->dev, + "Error placing DDR freq for idx:%d. err:%d\n", + state, ret); + return ret; + } + ddr_cdev->cur_state = state; + + dev_dbg(ddr_cdev->dev, "Requested DDR bus scaling state:%ld for %s\n", + state, ddr_cdev->cdev->type); + + return ret; +} + +/** + * ddr_get_cur_state - callback function to get the current cooling + * state. + * @cdev: thermal cooling device pointer. + * @state: fill this variable with the current cooling state. + * + * Callback for the thermal cooling device to return the + * current DDR state request. + * + * Return: 0 on success, an error code otherwise. + */ +static int ddr_get_cur_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct ddr_cdev *ddr_cdev = cdev->devdata; + *state = ddr_cdev->cur_state; + + return 0; +} + +/** + * ddr_get_max_state - callback function to get the max cooling state. + * @cdev: thermal cooling device pointer. + * @state: fill this variable with the max cooling state. + * + * Callback for the thermal cooling device to return the DDR + * max cooling state. + * + * Return: 0 on success, an error code otherwise. + */ +static int ddr_get_max_state(struct thermal_cooling_device *cdev, + unsigned long *state) +{ + struct ddr_cdev *ddr_cdev = cdev->devdata; + *state = ddr_cdev->max_state; + + return 0; +} + +static struct thermal_cooling_device_ops ddr_cdev_ops = { + .get_max_state = ddr_get_max_state, + .get_cur_state = ddr_get_cur_state, + .set_cur_state = ddr_set_cur_state, +}; + +static int ddr_cdev_probe(struct platform_device *pdev) +{ + int ret = 0; + struct ddr_cdev *ddr_cdev = NULL; + struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + char cdev_name[THERMAL_NAME_LENGTH] = DDR_CDEV_NAME; + + ddr_cdev = devm_kzalloc(dev, sizeof(*ddr_cdev), GFP_KERNEL); + if (!ddr_cdev) + return -ENOMEM; + + ddr_cdev->ddr_bus_pdata = msm_bus_cl_get_pdata(pdev); + if (!ddr_cdev->ddr_bus_pdata) { + ret = -EINVAL; + dev_err(dev, "Unable to get ddr cdev bus pdata: %d\n"); + return ret; + } + + if (ddr_cdev->ddr_bus_pdata->num_usecases < 2) { + dev_err(dev, "Invalid number of ddr cdev levels, num_path:%d\n", + ddr_cdev->ddr_bus_pdata->num_usecases); + goto err_exit; + } + + ddr_cdev->bus_clnt_handle = msm_bus_scale_register_client( + ddr_cdev->ddr_bus_pdata); + if (!ddr_cdev->bus_clnt_handle) { + dev_err(dev, "%s: Failed to register ddr cdev client", + __func__); + ret = -ENXIO; + goto err_exit; + } + + ddr_cdev->cur_state = 0; + /* max_state is index */ + ddr_cdev->max_state = ddr_cdev->ddr_bus_pdata->num_usecases - 1; + ddr_cdev->dev = dev; + + /* Set initial value */ + ret = msm_bus_scale_client_update_request(ddr_cdev->bus_clnt_handle, + ddr_cdev->cur_state); + if (ret) { + dev_err(dev, "Error placing DDR freq request, index:%d err:%d\n", + ddr_cdev->cur_state, ret); + goto err_exit; + } + + ddr_cdev->cdev = thermal_of_cooling_device_register(np, cdev_name, + ddr_cdev, &ddr_cdev_ops); + if (IS_ERR(ddr_cdev->cdev)) { + ret = PTR_ERR(ddr_cdev->cdev); + dev_err(dev, "Cdev register failed for %s, ret:%d\n", + cdev_name, ret); + ddr_cdev->cdev = NULL; + goto err_exit; + } + dev_dbg(dev, "Cooling device [%s] registered.\n", cdev_name); + dev_set_drvdata(dev, ddr_cdev); + + return 0; +err_exit: + if (ddr_cdev->bus_clnt_handle) { + msm_bus_scale_unregister_client(ddr_cdev->bus_clnt_handle); + ddr_cdev->bus_clnt_handle = 0; + } + if (ddr_cdev->ddr_bus_pdata) { + msm_bus_cl_clear_pdata(ddr_cdev->ddr_bus_pdata); + ddr_cdev->ddr_bus_pdata = NULL; + } + return ret; +} + +static int ddr_cdev_remove(struct platform_device *pdev) +{ + struct ddr_cdev *ddr_cdev = + (struct ddr_cdev *)dev_get_drvdata(&pdev->dev); + + if (ddr_cdev->cdev) { + thermal_cooling_device_unregister(ddr_cdev->cdev); + ddr_cdev->cdev = NULL; + } + if (ddr_cdev->bus_clnt_handle) { + msm_bus_scale_client_update_request( + ddr_cdev->bus_clnt_handle, 0); + msm_bus_scale_unregister_client(ddr_cdev->bus_clnt_handle); + ddr_cdev->bus_clnt_handle = 0; + } + if (ddr_cdev->ddr_bus_pdata) { + msm_bus_cl_clear_pdata(ddr_cdev->ddr_bus_pdata); + ddr_cdev->ddr_bus_pdata = NULL; + } + + return 0; +} + +static const struct of_device_id ddr_cdev_match[] = { + { .compatible = "qcom,ddr-cooling-device", }, + {}, +}; + +static struct platform_driver ddr_cdev_driver = { + .probe = ddr_cdev_probe, + .remove = ddr_cdev_remove, + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = ddr_cdev_match, + }, +}; +module_platform_driver(ddr_cdev_driver); +MODULE_LICENSE("GPL v2"); From 1201c6da3a393e29010013bc9f528b1feb87e539 Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Thu, 3 Jun 2021 23:08:20 +0530 Subject: [PATCH 33/44] defconfig: msm: Enable DDR bus scaling cooling device driver for mdm9607 Enable DDR cooling device driver for mdm9607. It places DDR frequency restriction during high temperature condition. Change-Id: I661d2818378ab3611eec834bcb2f1b7b671e99a9 Signed-off-by: Manaf Meethalavalappu Pallikunhi --- arch/arm/configs/vendor/mdm9607-128mb-perf_defconfig | 1 + arch/arm/configs/vendor/mdm9607-perf_defconfig | 1 + arch/arm/configs/vendor/mdm9607_defconfig | 1 + 3 files changed, 3 insertions(+) diff --git a/arch/arm/configs/vendor/mdm9607-128mb-perf_defconfig b/arch/arm/configs/vendor/mdm9607-128mb-perf_defconfig index d64f35cee387..364d7698d1b6 100644 --- a/arch/arm/configs/vendor/mdm9607-128mb-perf_defconfig +++ b/arch/arm/configs/vendor/mdm9607-128mb-perf_defconfig @@ -184,6 +184,7 @@ CONFIG_THERMAL_GOV_LOW_LIMITS=y CONFIG_CPU_THERMAL=y CONFIG_QTI_QMI_COOLING_DEVICE=y CONFIG_REGULATOR_COOLING_DEVICE=y +CONFIG_QTI_BUS_SCALING_COOLING_DEVICE=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_CPR=y CONFIG_REGULATOR_MEM_ACC=y diff --git a/arch/arm/configs/vendor/mdm9607-perf_defconfig b/arch/arm/configs/vendor/mdm9607-perf_defconfig index 7d244418a32e..89341248adff 100644 --- a/arch/arm/configs/vendor/mdm9607-perf_defconfig +++ b/arch/arm/configs/vendor/mdm9607-perf_defconfig @@ -215,6 +215,7 @@ CONFIG_THERMAL_TSENS=y CONFIG_QTI_QMI_COOLING_DEVICE=y CONFIG_REGULATOR_COOLING_DEVICE=y CONFIG_QTI_ADC_TM=y +CONFIG_QTI_BUS_SCALING_COOLING_DEVICE=y CONFIG_MFD_SPMI_PMIC=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_CPR=y diff --git a/arch/arm/configs/vendor/mdm9607_defconfig b/arch/arm/configs/vendor/mdm9607_defconfig index f69cdeb193ef..eb5e91ad4f1e 100644 --- a/arch/arm/configs/vendor/mdm9607_defconfig +++ b/arch/arm/configs/vendor/mdm9607_defconfig @@ -219,6 +219,7 @@ CONFIG_THERMAL_TSENS=y CONFIG_QTI_QMI_COOLING_DEVICE=y CONFIG_REGULATOR_COOLING_DEVICE=y CONFIG_QTI_ADC_TM=y +CONFIG_QTI_BUS_SCALING_COOLING_DEVICE=y CONFIG_MFD_SPMI_PMIC=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_CPR=y From be5496351520a3406b64550bdb317d26c0a59541 Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Mon, 31 May 2021 22:38:13 +0530 Subject: [PATCH 34/44] ARM: dts: msm: Enable DDR cooling device driver for mdm9607 Enable DDR cooling device driver for mdm9607. It places DDR frequency restriction during high temperature condition. Add thermal zone trip to enable DDR cooling device mitigation. Change-Id: I55db6866f8471db82c58929a602aee838e6efec4 Signed-off-by: Manaf Meethalavalappu Pallikunhi --- arch/arm64/boot/dts/qcom/mdm9607-thermal.dtsi | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/mdm9607-thermal.dtsi b/arch/arm64/boot/dts/qcom/mdm9607-thermal.dtsi index 6313e3cfbce1..4d5074578ac4 100644 --- a/arch/arm64/boot/dts/qcom/mdm9607-thermal.dtsi +++ b/arch/arm64/boot/dts/qcom/mdm9607-thermal.dtsi @@ -40,6 +40,16 @@ }; }; }; + + ddr_cdev: qcom,ddr-cdev { + compatible = "qcom,ddr-cooling-device"; + qcom,msm-bus,name = "ddr-cdev"; + qcom,msm-bus,num-cases = <2>; + qcom,msm-bus,num-paths = <1>; + qcom,msm-bus,vectors-KBps = <1 512 0 0>, + <1 512 0 366000>; + #cooling-cells = <2>; + }; }; &thermal_zones { @@ -174,6 +184,12 @@ thermal-governor = "step_wise"; wake-capable-sensor; trips { + cdev_trip: cdev-trip { + temperature = <78000>; + hysteresis = <8000>; + type = "passive"; + }; + modem_pa_trip0: modem_pa_trip0 { temperature = <95000>; hysteresis = <5000>; @@ -202,6 +218,11 @@ }; cooling-maps { + ddr_cdev0 { + trip = <&cdev_trip>; + cooling-device = <&ddr_cdev 1 1>; + }; + modem_pa0_cdev { trip = <&modem_pa_trip0>; cooling-device = <&modem_pa 1 1>; From 2fbc961fbed77ad4f1ac16b623b3289fb34cb54b Mon Sep 17 00:00:00 2001 From: Ahmad Masri Date: Sun, 7 Mar 2021 13:06:08 +0200 Subject: [PATCH 35/44] wil6210: Drop unicast sub frame if part of a multicast amsdu Check that for a given multicast amsdu frame, all its sub frames are multicast also, if not, means if found a unicast sub frame, drop it and all the next sub frames for the same multicast amsdu. Change-Id: Ib9bcc45d9fcafec11c9c2a786fcabf278a666cb4 Signed-off-by: Ahmad Masri --- drivers/net/wireless/ath/wil6210/txrx_edma.c | 16 ++++++++++++++-- drivers/net/wireless/ath/wil6210/txrx_edma.h | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c index a7f9c1bfdde5..e164c2ff8247 100644 --- a/drivers/net/wireless/ath/wil6210/txrx_edma.c +++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c @@ -808,9 +808,20 @@ static int wil_check_amsdu(struct wil6210_priv *wil, void *msg, int cid, switch (vif->wdev.iftype) { case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_P2P_CLIENT: + /* check if the MSDU (a sub-frame of AMSDU) is multicast */ if (is_multicast_ether_addr(da)) return 0; + /* check if the current AMSDU (MPDU) frame is a multicast. + * If so we have unicast sub frame as part of a multicast + * AMSDU. Current frame and all sub frames should be dropped. + */ + if (wil_rx_status_get_mcast(msg)) { + wil_dbg_txrx(wil, + "Found unicast sub frame in a multicast mpdu. Drop it\n"); + goto out; + } + /* On client side, DA should be the client mac address */ ndev = vif_to_ndev(vif); if (ether_addr_equal(ndev->dev_addr, da)) @@ -831,12 +842,13 @@ static int wil_check_amsdu(struct wil6210_priv *wil, void *msg, int cid, return 0; } +out: sta->amsdu_drop_sn = seq; sta->amsdu_drop_tid = tid; sta->amsdu_drop = 1; wil_dbg_txrx(wil, - "Drop AMSDU frame, sn=%d. Drop this and all next sub frames\n", - seq); + "Drop AMSDU frame, sn=%d tid=%d. Drop this and all next sub frames\n", + seq, tid); return -EAGAIN; } diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.h b/drivers/net/wireless/ath/wil6210/txrx_edma.h index de0688265959..5328972b02ed 100644 --- a/drivers/net/wireless/ath/wil6210/txrx_edma.h +++ b/drivers/net/wireless/ath/wil6210/txrx_edma.h @@ -378,7 +378,7 @@ static inline u16 wil_rx_status_get_flow_id(void *msg) static inline u8 wil_rx_status_get_mcast(void *msg) { return WIL_GET_BITS(((struct wil_rx_status_compressed *)msg)->d0, - 26, 26); + 25, 26); } /** From 6edf689b3105e820b1d0f3a2f3aff48c58bd79fa Mon Sep 17 00:00:00 2001 From: Vasily Averin Date: Tue, 9 Jun 2020 10:53:22 +0300 Subject: [PATCH 36/44] netfilter: nf_conntrack_h323: lost .data_len definition for Q.931/ipv6 Could you please push this patch into stable@? it fixes memory corruption in kernels v3.5 .. v4.10 Lost .data_len definition leads to write beyond end of struct nf_ct_h323_master. Usually it corrupts following struct nf_conn_nat, however if nat is not loaded it corrupts following slab object. In mainline this problem went away in v4.11, after commit 9f0f3ebeda47 ("netfilter: helpers: remove data_len usage for inkernel helpers") however many stable kernels are still affected. Fixes: 1afc56794e03 ("netfilter: nf_ct_helper: implement variable length helper private data") # v3.5 cc: stable@vger.kernel.org Reviewed-by: Florian Westphal Signed-off-by: Vasily Averin Signed-off-by: Greg Kroah-Hartman Change-Id: Ib717c2eadf6e8ed6f0334793ad8028069b7f4f7b Git-commit: 396ba2fc4f27ef6c44bbc0098bfddf4da76dc4c9 Git-repo: https://android.googlesource.com/kernel/msm Signed-off-by: Uppala Revanth Kumar --- net/netfilter/nf_conntrack_h323_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c index f71f0d2558fd..e0af58b6f312 100644 --- a/net/netfilter/nf_conntrack_h323_main.c +++ b/net/netfilter/nf_conntrack_h323_main.c @@ -1223,6 +1223,7 @@ static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = { { .name = "Q.931", .me = THIS_MODULE, + .data_len = sizeof(struct nf_ct_h323_master), .tuple.src.l3num = AF_INET6, .tuple.src.u.tcp.port = cpu_to_be16(Q931_PORT), .tuple.dst.protonum = IPPROTO_TCP, From 73e035aa373146b015db5933689f7a0e9bb737e2 Mon Sep 17 00:00:00 2001 From: Will McVicker Date: Sat, 5 Dec 2020 00:48:48 +0000 Subject: [PATCH 37/44] HID: make arrays usage and value to be the same The HID subsystem allows an "HID report field" to have a different number of "values" and "usages" when it is allocated. When a field struct is created, the size of the usage array is guaranteed to be at least as large as the values array, but it may be larger. This leads to a potential out-of-bounds write in __hidinput_change_resolution_multipliers() and an out-of-bounds read in hidinput_count_leds(). To fix this, let's make sure that both the usage and value arrays are the same size. Cc: stable@vger.kernel.org Signed-off-by: Will McVicker Signed-off-by: Jiri Kosina Change-Id: I2391dd3a1c7a3e9655dd0ac482ac5ee55f167745 Git-commit: ed9be64eefe26d7d8b0b5b9fa3ffdf425d87a01f Git-repo: https://android.googlesource.com/kernel/common Signed-off-by: Uppala Revanth Kumar --- drivers/hid/hid-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index b8ada634c977..aff716a9ff10 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -90,7 +90,7 @@ EXPORT_SYMBOL_GPL(hid_register_report); * Register a new field for this report. */ -static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) +static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages) { struct hid_field *field; @@ -101,7 +101,7 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned field = kzalloc((sizeof(struct hid_field) + usages * sizeof(struct hid_usage) + - values * sizeof(unsigned)), GFP_KERNEL); + usages * sizeof(unsigned)), GFP_KERNEL); if (!field) return NULL; @@ -280,7 +280,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign usages = max_t(unsigned, parser->local.usage_index, parser->global.report_count); - field = hid_register_field(report, usages, parser->global.report_count); + field = hid_register_field(report, usages); if (!field) return 0; From a338d17b7dbf7156b58a23b4a10ac81b3147d344 Mon Sep 17 00:00:00 2001 From: raghavendar rao l Date: Wed, 23 Dec 2020 14:48:05 +0530 Subject: [PATCH 38/44] msm: ipa3: Added pdn config type check Added check to verify pdn config type which may cause out-of-bounds read in wlan_msg_process. Change-Id: Idce7cb966a5a1c33d4f6b040f4f9d2ec4fb203be Signed-off-by: raghavendar rao l --- drivers/platform/msm/ipa/ipa_v3/ipa.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 7ee304336e91..587042d06d4a 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -584,6 +584,13 @@ static int ipa3_send_pdn_config_msg(unsigned long usr_param) msg_meta.msg_type = pdn_info->pdn_cfg_type; + if ((pdn_info->pdn_cfg_type < IPA_PDN_DEFAULT_MODE_CONFIG) || + (pdn_info->pdn_cfg_type >= IPA_PDN_CONFIG_EVENT_MAX)) { + IPAERR_RL("invalid pdn_cfg_type =%d", pdn_info->pdn_cfg_type); + kfree(pdn_info); + return -EINVAL; + } + IPADBG("type %d, interface name: %s, enable:%d\n", msg_meta.msg_type, pdn_info->dev_name, pdn_info->enable); From 69fc6c9bcf701f32426d30860170aa991c4363ff Mon Sep 17 00:00:00 2001 From: Jeff Vander Stoep Date: Thu, 23 Jan 2020 09:51:14 +0100 Subject: [PATCH 39/44] Revert "ANDROID: security,perf: Allow further restriction of perf_event_open" Unfork Android. This reverts commit 8e5e42d5ae20f0324170d01ccf374a1571e82d9b. Perf_event_paranoid=3 is no longer needed on Android. Access control of perf events is now done by selinux. See: https://patchwork.kernel.org/patch/11185793/. Bug: 120445712 Bug: 137092007 Signed-off-by: Jeff Vander Stoep Change-Id: Iba493424174b30baff460caaa25a54a472c87bd4 Git-commit: 44a6aea9c219f55862776435b918c539855a9e69 Git-repo: https://android.googlesource.com/kernel/common/ Signed-off-by: Srinivasarao P --- Documentation/sysctl/kernel.txt | 4 +--- arch/arm64/configs/cuttlefish_defconfig | 1 - arch/x86/configs/x86_64_cuttlefish_defconfig | 1 - include/linux/perf_event.h | 5 ----- kernel/events/core.c | 8 -------- security/Kconfig | 9 --------- 6 files changed, 1 insertion(+), 27 deletions(-) diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 559416c2034b..7fd7e8419c7f 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -678,8 +678,7 @@ allowed to execute. perf_event_paranoid: Controls use of the performance events system by unprivileged -users (without CAP_SYS_ADMIN). The default value is 3 if -CONFIG_SECURITY_PERF_EVENTS_RESTRICT is set, or 2 otherwise. +users (without CAP_SYS_ADMIN). The default value is 2. -1: Allow use of (almost) all events by all users Ignore mlock limit after perf_event_mlock_kb without CAP_IPC_LOCK @@ -687,7 +686,6 @@ CONFIG_SECURITY_PERF_EVENTS_RESTRICT is set, or 2 otherwise. Disallow raw tracepoint access by users without CAP_SYS_ADMIN >=1: Disallow CPU event access by users without CAP_SYS_ADMIN >=2: Disallow kernel profiling by users without CAP_SYS_ADMIN ->=3: Disallow all event access by users without CAP_SYS_ADMIN ============================================================== diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig index b753e71e4bd8..8c1f849bcb4f 100644 --- a/arch/arm64/configs/cuttlefish_defconfig +++ b/arch/arm64/configs/cuttlefish_defconfig @@ -470,7 +470,6 @@ CONFIG_SCHEDSTATS=y CONFIG_DEBUG_LIST=y CONFIG_RCU_CPU_STALL_TIMEOUT=60 CONFIG_ENABLE_DEFAULT_TRACERS=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_TEST_MEMINIT=y CONFIG_TEST_STACKINIT=y CONFIG_SECURITY=y diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig index a108576ac594..d4294036b8df 100644 --- a/arch/x86/configs/x86_64_cuttlefish_defconfig +++ b/arch/x86/configs/x86_64_cuttlefish_defconfig @@ -504,7 +504,6 @@ CONFIG_TEST_STACKINIT=y CONFIG_IO_DELAY_NONE=y CONFIG_OPTIMIZE_INLINING=y CONFIG_UNWINDER_FRAME_POINTER=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_PATH=y diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 621342fbb3b4..eae4331bb2d0 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -1207,11 +1207,6 @@ int perf_event_max_stack_handler(struct ctl_table *table, int write, #define PERF_SECURITY_KERNEL 2 #define PERF_SECURITY_TRACEPOINT 3 -static inline bool perf_paranoid_any(void) -{ - return sysctl_perf_event_paranoid > 2; -} - static inline int perf_is_paranoid(void) { return sysctl_perf_event_paranoid > -1; diff --git a/kernel/events/core.c b/kernel/events/core.c index 74eba84d363b..95239257bcf9 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -430,13 +430,8 @@ static cpumask_var_t perf_online_mask; * 0 - disallow raw tracepoint access for unpriv * 1 - disallow cpu events for unpriv * 2 - disallow kernel profiling for unpriv - * 3 - disallow all unpriv perf event use */ -#ifdef CONFIG_SECURITY_PERF_EVENTS_RESTRICT -int sysctl_perf_event_paranoid __read_mostly = 3; -#else int sysctl_perf_event_paranoid __read_mostly = 2; -#endif /* Minimum for 512 kiB + 1 user control page */ int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */ @@ -10421,9 +10416,6 @@ SYSCALL_DEFINE5(perf_event_open, if (flags & ~PERF_FLAG_ALL) return -EINVAL; - if (perf_paranoid_any() && !capable(CAP_SYS_ADMIN)) - return -EACCES; - /* Do we allow access to perf_event_open(2) ? */ err = security_perf_event_open(&attr, PERF_SECURITY_OPEN); if (err) diff --git a/security/Kconfig b/security/Kconfig index 8b6c5e9528e0..3a66cd8363c0 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -18,15 +18,6 @@ config SECURITY_DMESG_RESTRICT If you are unsure how to answer this question, answer N. -config SECURITY_PERF_EVENTS_RESTRICT - bool "Restrict unprivileged use of performance events" - depends on PERF_EVENTS - help - If you say Y here, the kernel.perf_event_paranoid sysctl - will be set to 3 by default, and no unprivileged use of the - perf_event_open syscall will be permitted unless it is - changed. - config SECURITY bool "Enable different security models" depends on SYSFS From 52b16502f1f59e13e3440fed83fb5d7d71653c73 Mon Sep 17 00:00:00 2001 From: Srinivasarao P Date: Thu, 13 May 2021 00:25:48 +0530 Subject: [PATCH 40/44] defconfig: remove CONFIG_SECURITY_PERF_EVENTS_RESTRICT deleting entries of CONFIG_SECURITY_PERF_EVENTS_RESTRICT from all defconfig files as this feature is removed. Change-Id: Ifd46126617ce5455e2010e8bde061854cbd3b82c Signed-off-by: Srinivasarao P --- arch/arm/configs/vendor/qcs403-perf_defconfig | 1 - arch/arm/configs/vendor/qcs403_defconfig | 1 - arch/arm/configs/vendor/qcs405-perf_defconfig | 1 - arch/arm/configs/vendor/qcs405_defconfig | 1 - arch/arm/configs/vendor/sa515m-perf_defconfig | 1 - arch/arm/configs/vendor/sa515m_defconfig | 1 - arch/arm/configs/vendor/sdm429-bg-perf_defconfig | 1 - arch/arm/configs/vendor/sdm429-bg_defconfig | 1 - arch/arm/configs/vendor/sdxprairie-perf_defconfig | 1 - arch/arm/configs/vendor/sdxprairie_defconfig | 1 - arch/arm/configs/vendor/trinket-perf_defconfig | 1 - arch/arm/configs/vendor/trinket_defconfig | 1 - arch/arm64/configs/vendor/atoll-perf_defconfig | 1 - arch/arm64/configs/vendor/atoll_defconfig | 1 - arch/arm64/configs/vendor/gen3auto-capture_defconfig | 1 - arch/arm64/configs/vendor/gen3auto-perf_defconfig | 1 - arch/arm64/configs/vendor/gen3auto_defconfig | 1 - arch/arm64/configs/vendor/qcs403-perf_defconfig | 1 - arch/arm64/configs/vendor/qcs403_defconfig | 1 - arch/arm64/configs/vendor/qcs405-perf_defconfig | 1 - arch/arm64/configs/vendor/qcs405_defconfig | 1 - arch/arm64/configs/vendor/qcs610-minimal-perf_defconfig | 1 - arch/arm64/configs/vendor/sa2150p-nand-perf_defconfig | 1 - arch/arm64/configs/vendor/sa2150p-nand_defconfig | 1 - arch/arm64/configs/vendor/sa2150p-perf_defconfig | 1 - arch/arm64/configs/vendor/sa2150p_defconfig | 1 - arch/arm64/configs/vendor/sa8155-perf_defconfig | 1 - arch/arm64/configs/vendor/sa8155_defconfig | 1 - arch/arm64/configs/vendor/sdm660-perf_defconfig | 1 - arch/arm64/configs/vendor/sdm660_defconfig | 1 - arch/arm64/configs/vendor/sdmshrike-perf_defconfig | 1 - arch/arm64/configs/vendor/sdmshrike_defconfig | 1 - arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig | 1 - arch/arm64/configs/vendor/sdmsteppe-auto_defconfig | 1 - arch/arm64/configs/vendor/sdmsteppe-perf_defconfig | 1 - arch/arm64/configs/vendor/sdmsteppe_defconfig | 1 - arch/arm64/configs/vendor/sm8150-perf_defconfig | 1 - arch/arm64/configs/vendor/sm8150_defconfig | 1 - arch/arm64/configs/vendor/trinket-perf_defconfig | 1 - arch/arm64/configs/vendor/trinket_defconfig | 1 - 40 files changed, 40 deletions(-) diff --git a/arch/arm/configs/vendor/qcs403-perf_defconfig b/arch/arm/configs/vendor/qcs403-perf_defconfig index 971d53d323b3..4563c4d6c6e1 100644 --- a/arch/arm/configs/vendor/qcs403-perf_defconfig +++ b/arch/arm/configs/vendor/qcs403-perf_defconfig @@ -351,7 +351,6 @@ CONFIG_PANIC_ON_OOPS=y CONFIG_PANIC_TIMEOUT=5 CONFIG_STACKTRACE=y # CONFIG_FTRACE is not set -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm/configs/vendor/qcs403_defconfig b/arch/arm/configs/vendor/qcs403_defconfig index 48a2bcc44225..67b5cf4ccc1e 100644 --- a/arch/arm/configs/vendor/qcs403_defconfig +++ b/arch/arm/configs/vendor/qcs403_defconfig @@ -561,7 +561,6 @@ CONFIG_CORESIGHT_DUMMY=y CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm/configs/vendor/qcs405-perf_defconfig b/arch/arm/configs/vendor/qcs405-perf_defconfig index c6940696defa..ab1b4283189b 100644 --- a/arch/arm/configs/vendor/qcs405-perf_defconfig +++ b/arch/arm/configs/vendor/qcs405-perf_defconfig @@ -351,7 +351,6 @@ CONFIG_PANIC_ON_OOPS=y CONFIG_PANIC_TIMEOUT=5 CONFIG_STACKTRACE=y # CONFIG_FTRACE is not set -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm/configs/vendor/qcs405_defconfig b/arch/arm/configs/vendor/qcs405_defconfig index e88d885441e0..755bcd1424da 100644 --- a/arch/arm/configs/vendor/qcs405_defconfig +++ b/arch/arm/configs/vendor/qcs405_defconfig @@ -561,7 +561,6 @@ CONFIG_CORESIGHT_DUMMY=y CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm/configs/vendor/sa515m-perf_defconfig b/arch/arm/configs/vendor/sa515m-perf_defconfig index f45e1a990e7f..906061337081 100644 --- a/arch/arm/configs/vendor/sa515m-perf_defconfig +++ b/arch/arm/configs/vendor/sa515m-perf_defconfig @@ -472,7 +472,6 @@ CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_TGU=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y diff --git a/arch/arm/configs/vendor/sa515m_defconfig b/arch/arm/configs/vendor/sa515m_defconfig index b6d9ef528291..9400998fd2a6 100644 --- a/arch/arm/configs/vendor/sa515m_defconfig +++ b/arch/arm/configs/vendor/sa515m_defconfig @@ -496,7 +496,6 @@ CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_TGU=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y diff --git a/arch/arm/configs/vendor/sdm429-bg-perf_defconfig b/arch/arm/configs/vendor/sdm429-bg-perf_defconfig index 909011ee39aa..72b1a9356d89 100644 --- a/arch/arm/configs/vendor/sdm429-bg-perf_defconfig +++ b/arch/arm/configs/vendor/sdm429-bg-perf_defconfig @@ -614,7 +614,6 @@ CONFIG_CORESIGHT_DUMMY=y CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_SECURITY_SELINUX=y diff --git a/arch/arm/configs/vendor/sdm429-bg_defconfig b/arch/arm/configs/vendor/sdm429-bg_defconfig index 73afce9ce37e..903a827ae43f 100644 --- a/arch/arm/configs/vendor/sdm429-bg_defconfig +++ b/arch/arm/configs/vendor/sdm429-bg_defconfig @@ -685,7 +685,6 @@ CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_TGU=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_HARDENED_USERCOPY_PAGESPAN=y diff --git a/arch/arm/configs/vendor/sdxprairie-perf_defconfig b/arch/arm/configs/vendor/sdxprairie-perf_defconfig index 1a298e1b24d2..60d6e81a0c71 100644 --- a/arch/arm/configs/vendor/sdxprairie-perf_defconfig +++ b/arch/arm/configs/vendor/sdxprairie-perf_defconfig @@ -462,7 +462,6 @@ CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_TGU=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y diff --git a/arch/arm/configs/vendor/sdxprairie_defconfig b/arch/arm/configs/vendor/sdxprairie_defconfig index 5f1f1cf780ae..1a73dc1bda4d 100644 --- a/arch/arm/configs/vendor/sdxprairie_defconfig +++ b/arch/arm/configs/vendor/sdxprairie_defconfig @@ -495,7 +495,6 @@ CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_TGU=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y diff --git a/arch/arm/configs/vendor/trinket-perf_defconfig b/arch/arm/configs/vendor/trinket-perf_defconfig index d50f0e7098f1..b2981e099d97 100644 --- a/arch/arm/configs/vendor/trinket-perf_defconfig +++ b/arch/arm/configs/vendor/trinket-perf_defconfig @@ -649,7 +649,6 @@ CONFIG_CORESIGHT_DUMMY=y CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_SECURITY_SELINUX=y diff --git a/arch/arm/configs/vendor/trinket_defconfig b/arch/arm/configs/vendor/trinket_defconfig index c941cc9f033c..c817111a1eb6 100644 --- a/arch/arm/configs/vendor/trinket_defconfig +++ b/arch/arm/configs/vendor/trinket_defconfig @@ -729,7 +729,6 @@ CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_TGU=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_HARDENED_USERCOPY_PAGESPAN=y diff --git a/arch/arm64/configs/vendor/atoll-perf_defconfig b/arch/arm64/configs/vendor/atoll-perf_defconfig index 43f173b37fa2..3725488ba327 100644 --- a/arch/arm64/configs/vendor/atoll-perf_defconfig +++ b/arch/arm64/configs/vendor/atoll-perf_defconfig @@ -725,7 +725,6 @@ CONFIG_CORESIGHT_DUMMY=y CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_FORTIFY_SOURCE=y diff --git a/arch/arm64/configs/vendor/atoll_defconfig b/arch/arm64/configs/vendor/atoll_defconfig index a41b458f2876..2a26b60748e5 100644 --- a/arch/arm64/configs/vendor/atoll_defconfig +++ b/arch/arm64/configs/vendor/atoll_defconfig @@ -810,7 +810,6 @@ CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_TGU=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_HARDENED_USERCOPY_PAGESPAN=y diff --git a/arch/arm64/configs/vendor/gen3auto-capture_defconfig b/arch/arm64/configs/vendor/gen3auto-capture_defconfig index a7090ced2af3..ea1fc76036a5 100644 --- a/arch/arm64/configs/vendor/gen3auto-capture_defconfig +++ b/arch/arm64/configs/vendor/gen3auto-capture_defconfig @@ -713,7 +713,6 @@ CONFIG_TEST_USER_COPY=m CONFIG_MEMTEST=y CONFIG_BUG_ON_DATA_CORRUPTION=y CONFIG_ARM64_STRICT_BREAK_BEFORE_MAKE=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_HARDENED_USERCOPY_PAGESPAN=y diff --git a/arch/arm64/configs/vendor/gen3auto-perf_defconfig b/arch/arm64/configs/vendor/gen3auto-perf_defconfig index 2b6d31b62d11..3b12c0b32ab5 100644 --- a/arch/arm64/configs/vendor/gen3auto-perf_defconfig +++ b/arch/arm64/configs/vendor/gen3auto-perf_defconfig @@ -649,7 +649,6 @@ CONFIG_SCHEDSTATS=y # CONFIG_DEBUG_PREEMPT is not set CONFIG_IPC_LOGGING=y CONFIG_DEBUG_ALIGN_RODATA=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_FORTIFY_SOURCE=y diff --git a/arch/arm64/configs/vendor/gen3auto_defconfig b/arch/arm64/configs/vendor/gen3auto_defconfig index e5ceb314d7c3..f565f54b18cd 100644 --- a/arch/arm64/configs/vendor/gen3auto_defconfig +++ b/arch/arm64/configs/vendor/gen3auto_defconfig @@ -750,7 +750,6 @@ CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_TGU=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_HARDENED_USERCOPY_PAGESPAN=y diff --git a/arch/arm64/configs/vendor/qcs403-perf_defconfig b/arch/arm64/configs/vendor/qcs403-perf_defconfig index c30b99e11678..88d2cc28e36c 100644 --- a/arch/arm64/configs/vendor/qcs403-perf_defconfig +++ b/arch/arm64/configs/vendor/qcs403-perf_defconfig @@ -535,7 +535,6 @@ CONFIG_CORESIGHT_TPDM=y CONFIG_CORESIGHT_HWEVENT=y CONFIG_CORESIGHT_DUMMY=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm64/configs/vendor/qcs403_defconfig b/arch/arm64/configs/vendor/qcs403_defconfig index 4d1ebdb00b84..487a82c33f22 100644 --- a/arch/arm64/configs/vendor/qcs403_defconfig +++ b/arch/arm64/configs/vendor/qcs403_defconfig @@ -585,7 +585,6 @@ CONFIG_CORESIGHT_DUMMY=y CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm64/configs/vendor/qcs405-perf_defconfig b/arch/arm64/configs/vendor/qcs405-perf_defconfig index cea1b6be7111..ef3c9ea62ab7 100644 --- a/arch/arm64/configs/vendor/qcs405-perf_defconfig +++ b/arch/arm64/configs/vendor/qcs405-perf_defconfig @@ -539,7 +539,6 @@ CONFIG_CORESIGHT_TPDM=y CONFIG_CORESIGHT_HWEVENT=y CONFIG_CORESIGHT_DUMMY=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_HARDENED_USERCOPY=y diff --git a/arch/arm64/configs/vendor/qcs405_defconfig b/arch/arm64/configs/vendor/qcs405_defconfig index ad4bfcca98ee..8fe0a34ca212 100644 --- a/arch/arm64/configs/vendor/qcs405_defconfig +++ b/arch/arm64/configs/vendor/qcs405_defconfig @@ -588,7 +588,6 @@ CONFIG_CORESIGHT_DUMMY=y CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_HARDENED_USERCOPY=y diff --git a/arch/arm64/configs/vendor/qcs610-minimal-perf_defconfig b/arch/arm64/configs/vendor/qcs610-minimal-perf_defconfig index ae508a225e02..77982bcbdd96 100644 --- a/arch/arm64/configs/vendor/qcs610-minimal-perf_defconfig +++ b/arch/arm64/configs/vendor/qcs610-minimal-perf_defconfig @@ -595,7 +595,6 @@ CONFIG_CORESIGHT_DUMMY=y CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_HARDENED_USERCOPY=y diff --git a/arch/arm64/configs/vendor/sa2150p-nand-perf_defconfig b/arch/arm64/configs/vendor/sa2150p-nand-perf_defconfig index 541675328ea6..7f69a1bc3ccb 100644 --- a/arch/arm64/configs/vendor/sa2150p-nand-perf_defconfig +++ b/arch/arm64/configs/vendor/sa2150p-nand-perf_defconfig @@ -478,7 +478,6 @@ CONFIG_CORESIGHT_TPDM=y CONFIG_CORESIGHT_HWEVENT=y CONFIG_CORESIGHT_DUMMY=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm64/configs/vendor/sa2150p-nand_defconfig b/arch/arm64/configs/vendor/sa2150p-nand_defconfig index 637543955dca..997249ec14fc 100644 --- a/arch/arm64/configs/vendor/sa2150p-nand_defconfig +++ b/arch/arm64/configs/vendor/sa2150p-nand_defconfig @@ -479,7 +479,6 @@ CONFIG_CORESIGHT_TPDM=y CONFIG_CORESIGHT_HWEVENT=y CONFIG_CORESIGHT_DUMMY=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm64/configs/vendor/sa2150p-perf_defconfig b/arch/arm64/configs/vendor/sa2150p-perf_defconfig index e0eab7c0dbd7..53b0002aca48 100644 --- a/arch/arm64/configs/vendor/sa2150p-perf_defconfig +++ b/arch/arm64/configs/vendor/sa2150p-perf_defconfig @@ -490,7 +490,6 @@ CONFIG_CORESIGHT_TPDM=y CONFIG_CORESIGHT_HWEVENT=y CONFIG_CORESIGHT_DUMMY=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm64/configs/vendor/sa2150p_defconfig b/arch/arm64/configs/vendor/sa2150p_defconfig index 351559aaa7e4..6430a186601c 100644 --- a/arch/arm64/configs/vendor/sa2150p_defconfig +++ b/arch/arm64/configs/vendor/sa2150p_defconfig @@ -491,7 +491,6 @@ CONFIG_CORESIGHT_TPDM=y CONFIG_CORESIGHT_HWEVENT=y CONFIG_CORESIGHT_DUMMY=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_SECURITY_NETWORK=y CONFIG_LSM_MMAP_MIN_ADDR=4096 diff --git a/arch/arm64/configs/vendor/sa8155-perf_defconfig b/arch/arm64/configs/vendor/sa8155-perf_defconfig index a8dd5c765037..696a3cca5cc4 100644 --- a/arch/arm64/configs/vendor/sa8155-perf_defconfig +++ b/arch/arm64/configs/vendor/sa8155-perf_defconfig @@ -639,7 +639,6 @@ CONFIG_SCHEDSTATS=y # CONFIG_DEBUG_PREEMPT is not set CONFIG_IPC_LOGGING=y CONFIG_DEBUG_ALIGN_RODATA=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_FORTIFY_SOURCE=y diff --git a/arch/arm64/configs/vendor/sa8155_defconfig b/arch/arm64/configs/vendor/sa8155_defconfig index 8e70cf7f02bc..62a6a1af41c8 100644 --- a/arch/arm64/configs/vendor/sa8155_defconfig +++ b/arch/arm64/configs/vendor/sa8155_defconfig @@ -737,7 +737,6 @@ CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_TGU=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_HARDENED_USERCOPY_PAGESPAN=y diff --git a/arch/arm64/configs/vendor/sdm660-perf_defconfig b/arch/arm64/configs/vendor/sdm660-perf_defconfig index 699621a225bb..a31fb6ceccd1 100644 --- a/arch/arm64/configs/vendor/sdm660-perf_defconfig +++ b/arch/arm64/configs/vendor/sdm660-perf_defconfig @@ -670,7 +670,6 @@ CONFIG_CORESIGHT_TPDM=y CONFIG_CORESIGHT_QPDI=y CONFIG_CORESIGHT_HWEVENT=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_FORTIFY_SOURCE=y diff --git a/arch/arm64/configs/vendor/sdm660_defconfig b/arch/arm64/configs/vendor/sdm660_defconfig index 901b1c3b70a7..e017eb599f53 100644 --- a/arch/arm64/configs/vendor/sdm660_defconfig +++ b/arch/arm64/configs/vendor/sdm660_defconfig @@ -759,7 +759,6 @@ CONFIG_CORESIGHT_HWEVENT=y CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_HARDENED_USERCOPY_PAGESPAN=y diff --git a/arch/arm64/configs/vendor/sdmshrike-perf_defconfig b/arch/arm64/configs/vendor/sdmshrike-perf_defconfig index 1e73e5fb6c3a..84a90bc3c4b2 100644 --- a/arch/arm64/configs/vendor/sdmshrike-perf_defconfig +++ b/arch/arm64/configs/vendor/sdmshrike-perf_defconfig @@ -651,7 +651,6 @@ CONFIG_CORESIGHT_DUMMY=y CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_SECURITY_SELINUX=y diff --git a/arch/arm64/configs/vendor/sdmshrike_defconfig b/arch/arm64/configs/vendor/sdmshrike_defconfig index 992d47e11b84..22c6017185d9 100644 --- a/arch/arm64/configs/vendor/sdmshrike_defconfig +++ b/arch/arm64/configs/vendor/sdmshrike_defconfig @@ -723,7 +723,6 @@ CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_TGU=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_SECURITY_SELINUX=y diff --git a/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig b/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig index 5bdacdb1a0ec..42dd45c4119c 100644 --- a/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe-auto-perf_defconfig @@ -676,7 +676,6 @@ CONFIG_SCHEDSTATS=y # CONFIG_DEBUG_PREEMPT is not set CONFIG_IPC_LOGGING=y CONFIG_DEBUG_ALIGN_RODATA=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_FORTIFY_SOURCE=y diff --git a/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig b/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig index fa9deae98f42..0b12db0fb847 100644 --- a/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe-auto_defconfig @@ -786,7 +786,6 @@ CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_TGU=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_HARDENED_USERCOPY_PAGESPAN=y diff --git a/arch/arm64/configs/vendor/sdmsteppe-perf_defconfig b/arch/arm64/configs/vendor/sdmsteppe-perf_defconfig index 91e6a3e337d7..f0d00e44ff7d 100644 --- a/arch/arm64/configs/vendor/sdmsteppe-perf_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe-perf_defconfig @@ -703,7 +703,6 @@ CONFIG_CORESIGHT_DUMMY=y CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_FORTIFY_SOURCE=y diff --git a/arch/arm64/configs/vendor/sdmsteppe_defconfig b/arch/arm64/configs/vendor/sdmsteppe_defconfig index 9166e37e6202..48dbf00e09b1 100644 --- a/arch/arm64/configs/vendor/sdmsteppe_defconfig +++ b/arch/arm64/configs/vendor/sdmsteppe_defconfig @@ -795,7 +795,6 @@ CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_TGU=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_HARDENED_USERCOPY_PAGESPAN=y diff --git a/arch/arm64/configs/vendor/sm8150-perf_defconfig b/arch/arm64/configs/vendor/sm8150-perf_defconfig index b09131f55f94..1b40639ad3de 100644 --- a/arch/arm64/configs/vendor/sm8150-perf_defconfig +++ b/arch/arm64/configs/vendor/sm8150-perf_defconfig @@ -711,7 +711,6 @@ CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_TGU=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_FORTIFY_SOURCE=y diff --git a/arch/arm64/configs/vendor/sm8150_defconfig b/arch/arm64/configs/vendor/sm8150_defconfig index b29c7fa37aa8..cc15e6f139d6 100644 --- a/arch/arm64/configs/vendor/sm8150_defconfig +++ b/arch/arm64/configs/vendor/sm8150_defconfig @@ -795,7 +795,6 @@ CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_TGU=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_HARDENED_USERCOPY_PAGESPAN=y diff --git a/arch/arm64/configs/vendor/trinket-perf_defconfig b/arch/arm64/configs/vendor/trinket-perf_defconfig index bf10f7e5461e..14bfcefa3772 100644 --- a/arch/arm64/configs/vendor/trinket-perf_defconfig +++ b/arch/arm64/configs/vendor/trinket-perf_defconfig @@ -689,7 +689,6 @@ CONFIG_CORESIGHT_DUMMY=y CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_FORTIFY_SOURCE=y diff --git a/arch/arm64/configs/vendor/trinket_defconfig b/arch/arm64/configs/vendor/trinket_defconfig index 456b1e7520be..a529ba57fcf1 100644 --- a/arch/arm64/configs/vendor/trinket_defconfig +++ b/arch/arm64/configs/vendor/trinket_defconfig @@ -774,7 +774,6 @@ CONFIG_CORESIGHT_REMOTE_ETM=y CONFIG_CORESIGHT_REMOTE_ETM_DEFAULT_ENABLE=0 CONFIG_CORESIGHT_TGU=y CONFIG_CORESIGHT_EVENT=y -CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y CONFIG_SECURITY=y CONFIG_HARDENED_USERCOPY=y CONFIG_HARDENED_USERCOPY_PAGESPAN=y From 218b8f07ea8d42b367c51840527485c3e7d2a350 Mon Sep 17 00:00:00 2001 From: Komal Bajaj Date: Thu, 22 Apr 2021 14:09:50 +0530 Subject: [PATCH 41/44] soc: qcom: Add check to handle out of bound access Adding check in msm_minidump_add_region() to handle scenarios for out of bound access while adding region in minidump table in SMEM. Change-Id: Ic20663dbd2fa8ae96899930a7f7ba79dc204ff5e Signed-off-by: Komal Bajaj Signed-off-by: Srinivasarao P --- drivers/soc/qcom/msm_minidump.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/soc/qcom/msm_minidump.c b/drivers/soc/qcom/msm_minidump.c index 38843f760c2e..acd3d71a7a28 100644 --- a/drivers/soc/qcom/msm_minidump.c +++ b/drivers/soc/qcom/msm_minidump.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017,2021, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -172,6 +172,7 @@ EXPORT_SYMBOL(msm_minidump_enabled); int msm_minidump_add_region(const struct md_region *entry) { u32 entries; + u32 toc_init; struct md_region *mdr; int ret = 0; @@ -197,6 +198,19 @@ int msm_minidump_add_region(const struct md_region *entry) return -ENOMEM; } + toc_init = 0; + if (minidump_table.md_ss_toc && + (minidump_table.md_ss_toc->md_ss_enable_status == + MD_SS_ENABLED)) { + toc_init = 1; + if (minidump_table.md_ss_toc->ss_region_count >= + MAX_NUM_ENTRIES) { + spin_unlock(&mdt_lock); + pr_err("Maximum regions in minidump table reached.\n"); + return -ENOMEM; + } + } + mdr = &minidump_table.entry[entries]; strlcpy(mdr->name, entry->name, sizeof(mdr->name)); mdr->virt_addr = entry->virt_addr; @@ -206,9 +220,7 @@ int msm_minidump_add_region(const struct md_region *entry) minidump_table.num_regions = entries + 1; - if (minidump_table.md_ss_toc && - (minidump_table.md_ss_toc->md_ss_enable_status == - MD_SS_ENABLED)) + if (toc_init) md_update_ss_toc(entry); else pendings++; From eece594678f618c964051092fa0dd470b26039b3 Mon Sep 17 00:00:00 2001 From: Trishansh Bhardwaj Date: Tue, 27 Apr 2021 13:32:04 +0530 Subject: [PATCH 42/44] msm: camera: icp: Enable hang dump on failure In case user does not set any dump lvl, KMD will set to dump on failure as default. Change-Id: If84f58daa3d36c707bc706dca86ccf9f10cf0bd2 Signed-off-by: Trishansh Bhardwaj --- .../msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index e3b5bb3d8902..c27aad7ef557 100644 --- a/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/drivers/media/platform/msm/camera/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1462,6 +1462,8 @@ static int cam_icp_hw_mgr_create_debugfs_entry(void) goto err; } + /* Set default hang dump lvl */ + icp_hw_mgr.a5_fw_dump_lvl = HFI_FW_DUMP_ON_FAILURE; return rc; err: debugfs_remove_recursive(icp_hw_mgr.dentry); From 7d249b536a1ff7e0bebe0b626c4268338deff141 Mon Sep 17 00:00:00 2001 From: Praveen Kurapati Date: Wed, 17 Jun 2020 12:08:29 -0700 Subject: [PATCH 43/44] msm: ipa: fix to check for ECONNRESET ECONNRESET is returned if Q6 QMI service is down. Make changes to check for ECONNRESET as well to detect SSR. Change-Id: I9a88b816618558123b3623396f38dde010d62abd Signed-off-by: Praveen Kurapati --- drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c index 266734f4ba9f..3701173d7f65 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_qmi_service.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2021, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1587,7 +1587,7 @@ static void ipa3_q6_clnt_svc_arrive(struct work_struct *work) /* Initialize modem IPA-driver */ IPAWANDBG("send ipa3_qmi_init_modem_send_sync_msg to modem\n"); rc = ipa3_qmi_init_modem_send_sync_msg(); - if ((rc == -ENETRESET) || (rc == -ENODEV)) { + if ((rc == -ENETRESET) || (rc == -ENODEV) || (rc == -ECONNRESET)) { IPAWANERR( "ipa3_qmi_init_modem_send_sync_msg failed due to SSR!\n"); /* Cleanup when ipa3_wwan_remove is called */ From 01aa9c579172b13c4fe325eb28906028824e6351 Mon Sep 17 00:00:00 2001 From: Jeya R Date: Thu, 10 Jun 2021 13:03:44 +0530 Subject: [PATCH 44/44] msm: adsprpc: Fix race condition in internal_control Protect add and update qos request with mutex to avoid race condition when multiple threads try to add or update request simultaneously. Change-Id: Id33b81bf85246ec69c72bad59cca068e627bb21d Acked-by: Deepika Singh Signed-off-by: Jeya R --- drivers/char/adsprpc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 6265fba5755a..4424755714a9 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -392,6 +392,7 @@ struct fastrpc_file { struct mutex perf_mutex; struct pm_qos_request pm_qos_req; int qos_request; + struct mutex pm_qos_mutex; struct mutex map_mutex; struct mutex internal_map_mutex; /* Identifies the device (MINOR_NUM_DEV / MINOR_NUM_SECURE_DEV) */ @@ -3078,6 +3079,7 @@ static int fastrpc_file_free(struct fastrpc_file *fl) mutex_destroy(&fl->perf_mutex); mutex_destroy(&fl->map_mutex); mutex_destroy(&fl->internal_map_mutex); + mutex_destroy(&fl->pm_qos_mutex); kfree(fl); return 0; } @@ -3426,6 +3428,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) hlist_add_head(&fl->hn, &me->drivers); spin_unlock(&me->hlock); mutex_init(&fl->perf_mutex); + mutex_init(&fl->pm_qos_mutex); return 0; } @@ -3539,12 +3542,14 @@ static int fastrpc_internal_control(struct fastrpc_file *fl, VERIFY(err, latency != 0); if (err) goto bail; + mutex_lock(&fl->pm_qos_mutex); if (!fl->qos_request) { pm_qos_add_request(&fl->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, latency); fl->qos_request = 1; } else pm_qos_update_request(&fl->pm_qos_req, latency); + mutex_unlock(&fl->pm_qos_mutex); break; case FASTRPC_CONTROL_KALLOC: cp->kalloc.kalloc_support = 1;