disp: msm: sde: validate plane mode and gem obj flags

Add changes to validate the plane fb_translation mode
and dma_buf flags of drm_gem_obj attached to plane. It
avoids device panic on S2 translation fault and fails the
drm_atomic_commit for which mismatch is detected. In
current codeflow, only S1 mappings are modified when dma_buf
is detached from Non_sec CB and attached to secure SB as part
of msm_gem_get_iova_locked API, but S2 mapping entries are
not modified and this crash is seen.

Change-Id: I6bced92994cd8681cf69231e41bec0c262dafd33
Signed-off-by: Jayaprakash Madisetty <quic_jmadiset@quicinc.com>
This commit is contained in:
Jayaprakash Madisetty 2022-02-19 12:39:41 +05:30
commit 3c0f029ebb
3 changed files with 74 additions and 0 deletions

View file

@ -1,4 +1,5 @@
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
@ -1128,6 +1129,8 @@ struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd);
struct drm_framebuffer * msm_alloc_stolen_fb(struct drm_device *dev,
int w, int h, int p, uint32_t format);
int msm_fb_obj_get_attrs(struct drm_gem_object *obj, int *fb_ns,
int *fb_sec, int *fb_sec_dir, unsigned long *flags);
struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev);
void msm_fbdev_free(struct drm_device *dev);

View file

@ -1,4 +1,5 @@
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
@ -16,6 +17,8 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/dma-buf.h>
#include <linux/msm_ion.h>
#include <drm/drm_crtc.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
@ -378,3 +381,32 @@ msm_alloc_stolen_fb(struct drm_device *dev, int w, int h, int p, uint32_t format
return fb;
}
int msm_fb_obj_get_attrs(struct drm_gem_object *obj, int *fb_ns,
int *fb_sec, int *fb_sec_dir, unsigned long *flags)
{
struct msm_gem_object *msm_obj = to_msm_bo(obj);
int ret = 0;
if (!obj->import_attach) {
DRM_DEBUG("NULL attachment in drm gem object flags:0x%x\n", msm_obj->flags);
return -EINVAL;
}
ret = dma_buf_get_flags(obj->import_attach->dmabuf, flags);
if (ret) {
DRM_ERROR("dma_buf_get_flags failure, err=%d\n", ret);
return ret;
}
if (!(*flags & ION_FLAG_SECURE))
*fb_ns = 1;
else if (*flags & ION_FLAG_CP_PIXEL)
*fb_sec = 1;
else if (*flags & (ION_FLAG_CP_SEC_DISPLAY |
ION_FLAG_CP_CAMERA_PREVIEW))
*fb_sec_dir = 1;
return ret;
}

View file

@ -1,4 +1,5 @@
/*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (C) 2014-2021 The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com>
@ -1962,6 +1963,39 @@ static void sde_plane_cleanup_fb(struct drm_plane *plane,
}
static int _sde_plane_validate_fb(struct sde_plane *psde,
struct drm_plane_state *state)
{
struct sde_plane_state *pstate;
struct drm_framebuffer *fb;
uint32_t fb_ns = 0, fb_sec = 0, fb_sec_dir = 0;
unsigned long flags = 0;
int mode, ret = 0, n, i;
pstate = to_sde_plane_state(state);
mode = sde_plane_get_property(pstate,
PLANE_PROP_FB_TRANSLATION_MODE);
fb = state->fb;
n = fb->format->num_planes;
for (i = 0; i < n; i++) {
ret = msm_fb_obj_get_attrs(fb->obj[i], &fb_ns, &fb_sec,
&fb_sec_dir, &flags);
if (!ret && ((fb_ns && (mode != SDE_DRM_FB_NON_SEC)) ||
(fb_sec && (mode != SDE_DRM_FB_SEC)) ||
(fb_sec_dir && (mode != SDE_DRM_FB_SEC_DIR_TRANS)))) {
SDE_ERROR_PLANE(psde, "mode:%d fb:%d dma_buf flags:0x%x rc:%d\n",
mode, fb->base.id, flags, ret);
SDE_EVT32(psde->base.base.id, fb->base.id, flags,
fb_ns, fb_sec, fb_sec_dir, ret, SDE_EVTLOG_ERROR);
return -EINVAL;
}
}
return 0;
}
static void _sde_plane_sspp_atomic_check_mode_changed(struct sde_plane *psde,
struct drm_plane_state *state,
struct drm_plane_state *old_state)
@ -2631,6 +2665,11 @@ static int sde_plane_sspp_atomic_check(struct drm_plane *plane,
return ret;
ret = _sde_plane_validate_shared_crtc(psde, state);
if (ret)
return ret;
ret = _sde_plane_validate_fb(psde, state);
if (ret)
return ret;