diff --git a/msm/msm_drv.c b/msm/msm_drv.c index a48f0121..06b84bdd 100644 --- a/msm/msm_drv.c +++ b/msm/msm_drv.c @@ -1627,6 +1627,7 @@ int msm_ioctl_display_hint_ops(struct drm_device *dev, void *data, SDE_EVT32(display_hint->hint_flags); + /* Any new hint added will require a check for VM ownership before HW is accessed */ if (display_hint->hint_flags == DRM_MSM_DISPLAY_EARLY_WAKEUP_HINT) { if (!display_hint->data) { DRM_ERROR("early_wakeup: wrong parameter\n"); diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 1fe64d66..23a64dbb 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -4046,9 +4046,15 @@ static void sde_encoder_early_wakeup_work_handler(struct kthread_work *work) { struct sde_encoder_virt *sde_enc = container_of(work, struct sde_encoder_virt, early_wakeup_work); + struct sde_vm_ops *vm_ops; + struct sde_kms *sde_kms = to_sde_kms(ddev_to_msm_kms(sde_enc->base.dev)); - if (!sde_enc) { - SDE_ERROR("invalid sde encoder\n"); + vm_ops = sde_vm_get_ops(sde_kms); + sde_vm_lock(sde_kms); + if (vm_ops && vm_ops->vm_owns_hw && !vm_ops->vm_owns_hw(sde_kms)) { + sde_vm_unlock(sde_kms); + SDE_DEBUG("skip early wakeup for ENC-%d, HW is owned by other VM\n", + DRMID(&sde_enc->base)); return; } @@ -4056,6 +4062,7 @@ static void sde_encoder_early_wakeup_work_handler(struct kthread_work *work) sde_encoder_resource_control(&sde_enc->base, SDE_ENC_RC_EVENT_EARLY_WAKEUP); SDE_ATRACE_END("encoder_early_wakeup"); + sde_vm_unlock(sde_kms); } void sde_encoder_early_wakeup(struct drm_encoder *drm_enc) diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 1ff25f18..cb89349f 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -5062,9 +5062,9 @@ static int _sde_kms_register_events(struct msm_kms *kms, struct drm_mode_object *obj, u32 event, bool en) { int ret = 0; - struct drm_crtc *crtc = NULL; - struct drm_connector *conn = NULL; - struct sde_kms *sde_kms = NULL; + struct drm_crtc *crtc; + struct drm_connector *conn; + struct sde_kms *sde_kms; struct sde_vm_ops *vm_ops; if (!kms || !obj) { @@ -5073,24 +5073,19 @@ static int _sde_kms_register_events(struct msm_kms *kms, } sde_kms = to_sde_kms(kms); + vm_ops = sde_vm_get_ops(sde_kms); + sde_vm_lock(sde_kms); + if (vm_ops && vm_ops->vm_owns_hw && !vm_ops->vm_owns_hw(sde_kms)) { + sde_vm_unlock(sde_kms); + SDE_DEBUG("HW is owned by other VM\n"); + return -EACCES; + } /* check vm ownership, if event registration requires HW access */ switch (obj->type) { case DRM_MODE_OBJECT_CRTC: - vm_ops = sde_vm_get_ops(sde_kms); - sde_vm_lock(sde_kms); - - if (vm_ops && vm_ops->vm_owns_hw - && !vm_ops->vm_owns_hw(sde_kms)) { - sde_vm_unlock(sde_kms); - SDE_DEBUG("HW is owned by other VM\n"); - return -EACCES; - } - crtc = obj_to_crtc(obj); ret = sde_crtc_register_custom_event(sde_kms, crtc, event, en); - - sde_vm_unlock(sde_kms); break; case DRM_MODE_OBJECT_CONNECTOR: conn = obj_to_connector(obj); @@ -5099,6 +5094,8 @@ static int _sde_kms_register_events(struct msm_kms *kms, break; } + sde_vm_unlock(sde_kms); + return ret; }