diff --git a/msm/msm_drv.h b/msm/msm_drv.h index ec2a4e2d..1f79a3fa 100644 --- a/msm/msm_drv.h +++ b/msm/msm_drv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -1271,6 +1271,9 @@ int msm_framebuffer_set_cache_hint(struct drm_framebuffer *fb, int msm_framebuffer_get_cache_hint(struct drm_framebuffer *fb, u32 *flags, u32 *rd_type, u32 *wr_type); +int msm_fb_obj_get_attrs(struct drm_gem_object *obj, + int *fb_ns, int *fb_sec, int *fb_sec_dir); + struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev); void msm_fbdev_free(struct drm_device *dev); diff --git a/msm/msm_fb.c b/msm/msm_fb.c index ee6a4755..5a612152 100644 --- a/msm/msm_fb.c +++ b/msm/msm_fb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include "msm_drv.h" #include "msm_kms.h" @@ -316,3 +318,53 @@ int msm_framebuffer_get_cache_hint(struct drm_framebuffer *fb, return 0; } + +int msm_fb_obj_get_attrs(struct drm_gem_object *obj, + int *fb_ns, int *fb_sec, int *fb_sec_dir) +{ + struct msm_gem_object *msm_obj = to_msm_bo(obj); + struct dma_buf *dma_buf; + int *vmid_list, *perms_list; + int nelems = 0; + int i, ret = 0; + + if (!(msm_obj->flags & MSM_BO_EXTBUF)) + return 0; + + if (!obj->import_attach) { + DRM_DEBUG("NULL attachment in drm gem object flags:0x%x\n", + msm_obj->flags); + return -EINVAL; + } + + dma_buf = obj->import_attach->dmabuf; + if (!dma_buf) { + DRM_DEBUG("dma_buf NULL in drm gem object\n"); + return -EINVAL; + } + + ret = mem_buf_dma_buf_copy_vmperm(dma_buf, &vmid_list, + &perms_list, &nelems); + if (ret) { + DRM_ERROR("mem_buf_dma_buf_copy_vmperm failure, err=%d\n", ret); + return ret; + } + + /* obtain the VMIDs of a buffer */ + if (mem_buf_dma_buf_exclusive_owner(dma_buf)) + *fb_ns = 1; + else { + for (i = 0; i < nelems; i++) { + if (vmid_list[i] == VMID_CP_PIXEL) + *fb_sec = 1; + else if (vmid_list[i] & (VMID_CP_SEC_DISPLAY | + VMID_CP_CAMERA_PREVIEW)) + *fb_sec_dir = 1; + } + } + + kfree(vmid_list); + kfree(perms_list); + + return ret; +} diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index d0365522..c379d2cf 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -29,6 +29,7 @@ #include "msm_drv.h" #include "sde_kms.h" +#include "sde_vm.h" #include "sde_fence.h" #include "sde_formats.h" #include "sde_hw_sspp.h" @@ -2064,6 +2065,55 @@ 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 sde_kms *sde_kms; + struct drm_framebuffer *fb; + int fb_ns = 0, fb_sec = 0, fb_sec_dir = 0; + int mode, num_planes; + int i, ret; + + pstate = to_sde_plane_state(state); + mode = sde_plane_get_property(pstate, + PLANE_PROP_FB_TRANSLATION_MODE); + + fb = state->fb; + if (!fb) { + SDE_ERROR("invalid drm_framebuffer\n"); + return -EINVAL; + } + num_planes = fb->format->num_planes; + + sde_kms = _sde_plane_get_kms(&psde->base); + if (!sde_kms) { + SDE_ERROR("invalid kms\n"); + return -EINVAL; + } + + if (sde_in_trusted_vm(sde_kms)) + return 0; + + for (i = 0; i < num_planes; i++) { + ret = msm_fb_obj_get_attrs(fb->obj[i], &fb_ns, &fb_sec, + &fb_sec_dir); + if (ret != 0 || ((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 rc:%d\n", mode, + fb->base.id, ret); + SDE_EVT32(psde->base.base.id, fb->base.id, + fb_ns, fb_sec, fb_sec_dir, ret, + SDE_EVTLOG_ERROR); + return ret; + } + } + + 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) @@ -2733,6 +2783,10 @@ static int sde_plane_sspp_atomic_check(struct drm_plane *plane, if (ret) return ret; + ret = _sde_plane_validate_fb(psde, state); + if (ret) + return ret; + pstate->const_alpha_en = fmt->alpha_enable && (SDE_DRM_BLEND_OP_OPAQUE != sde_plane_get_property(pstate, PLANE_PROP_BLEND_OP)) &&