Commit 4522ad76 authored by Stanislaw Gruszka's avatar Stanislaw Gruszka Committed by Jacek Lawrynowicz

accel/ivpu: Do not access HW registers after unbind

We should not access hardware after we unbind from the bus.

Use drm_dev_enter() / drm_dev_exit() to mark code sections where
hardware is accessed (and not already protected by other locks)
and drm_dev_unplug() to mark device is gone.

Fixes: 35b13763 ("accel/ivpu: Introduce a new DRM driver for Intel VPU")
Signed-off-by: default avatarStanislaw Gruszka <stanislaw.gruszka@linux.intel.com>
Reviewed-by: default avatarJeffrey Hugo <quic_jhugo@quicinc.com>
Signed-off-by: default avatarJacek Lawrynowicz <jacek.lawrynowicz@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230323125504.2586442-2-stanislaw.gruszka@linux.intel.com
parent 1a70ca89
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <drm/drm_accel.h> #include <drm/drm_accel.h>
#include <drm/drm_drv.h>
#include <drm/drm_file.h> #include <drm/drm_file.h>
#include <drm/drm_gem.h> #include <drm/drm_gem.h>
#include <drm/drm_ioctl.h> #include <drm/drm_ioctl.h>
...@@ -118,6 +117,10 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f ...@@ -118,6 +117,10 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
struct pci_dev *pdev = to_pci_dev(vdev->drm.dev); struct pci_dev *pdev = to_pci_dev(vdev->drm.dev);
struct drm_ivpu_param *args = data; struct drm_ivpu_param *args = data;
int ret = 0; int ret = 0;
int idx;
if (!drm_dev_enter(dev, &idx))
return -ENODEV;
switch (args->param) { switch (args->param) {
case DRM_IVPU_PARAM_DEVICE_ID: case DRM_IVPU_PARAM_DEVICE_ID:
...@@ -171,6 +174,7 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f ...@@ -171,6 +174,7 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f
break; break;
} }
drm_dev_exit(idx);
return ret; return ret;
} }
...@@ -622,7 +626,7 @@ static void ivpu_remove(struct pci_dev *pdev) ...@@ -622,7 +626,7 @@ static void ivpu_remove(struct pci_dev *pdev)
{ {
struct ivpu_device *vdev = pci_get_drvdata(pdev); struct ivpu_device *vdev = pci_get_drvdata(pdev);
drm_dev_unregister(&vdev->drm); drm_dev_unplug(&vdev->drm);
ivpu_dev_fini(vdev); ivpu_dev_fini(vdev);
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#define __IVPU_DRV_H__ #define __IVPU_DRV_H__
#include <drm/drm_device.h> #include <drm/drm_device.h>
#include <drm/drm_drv.h>
#include <drm/drm_managed.h> #include <drm/drm_managed.h>
#include <drm/drm_mm.h> #include <drm/drm_mm.h>
#include <drm/drm_print.h> #include <drm/drm_print.h>
......
...@@ -489,12 +489,12 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32 ...@@ -489,12 +489,12 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32
int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file) int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
{ {
int ret = 0;
struct ivpu_file_priv *file_priv = file->driver_priv; struct ivpu_file_priv *file_priv = file->driver_priv;
struct ivpu_device *vdev = file_priv->vdev; struct ivpu_device *vdev = file_priv->vdev;
struct drm_ivpu_submit *params = data; struct drm_ivpu_submit *params = data;
struct ivpu_job *job; struct ivpu_job *job;
u32 *buf_handles; u32 *buf_handles;
int idx, ret;
if (params->engine > DRM_IVPU_ENGINE_COPY) if (params->engine > DRM_IVPU_ENGINE_COPY)
return -EINVAL; return -EINVAL;
...@@ -523,6 +523,11 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file) ...@@ -523,6 +523,11 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
goto free_handles; goto free_handles;
} }
if (!drm_dev_enter(&vdev->drm, &idx)) {
ret = -ENODEV;
goto free_handles;
}
ivpu_dbg(vdev, JOB, "Submit ioctl: ctx %u buf_count %u\n", ivpu_dbg(vdev, JOB, "Submit ioctl: ctx %u buf_count %u\n",
file_priv->ctx.id, params->buffer_count); file_priv->ctx.id, params->buffer_count);
...@@ -530,7 +535,7 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file) ...@@ -530,7 +535,7 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
if (!job) { if (!job) {
ivpu_err(vdev, "Failed to create job\n"); ivpu_err(vdev, "Failed to create job\n");
ret = -ENOMEM; ret = -ENOMEM;
goto free_handles; goto dev_exit;
} }
ret = ivpu_job_prepare_bos_for_submit(file, job, buf_handles, params->buffer_count, ret = ivpu_job_prepare_bos_for_submit(file, job, buf_handles, params->buffer_count,
...@@ -548,6 +553,8 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file) ...@@ -548,6 +553,8 @@ int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
job_put: job_put:
job_put(job); job_put(job);
dev_exit:
drm_dev_exit(idx);
free_handles: free_handles:
kfree(buf_handles); kfree(buf_handles);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment