Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3c0f029e authored by Jayaprakash Madisetty's avatar Jayaprakash Madisetty
Browse files

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: default avatarJayaprakash Madisetty <quic_jmadiset@quicinc.com>
parent 1f5cc03a
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
/*
 * 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);
+32 −0
Original line number Diff line number Diff line
/*
 * 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;
}
+39 −0
Original line number Diff line number Diff line
/*
 * 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;