Blob Blame History Raw
From: Hang Yuan <hang.yuan@linux.intel.com>
Date: Mon, 23 Jul 2018 20:15:46 +0800
Subject: drm/i915/gvt: fix cleanup sequence in intel_gvt_clean_device
Git-commit: 3fd34ac02ae8cc20d78e3aed2cf6e67f0ae109ea
Patch-mainline: v4.19-rc1
References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166

Create one vGPU and then unbind IGD device from i915 driver. The following
oops will happen. This patch will free vgpu resource first and then gvt
resource to remove these oops.

BUG: unable to handle kernel NULL pointer dereference at       00000000000000a8
  PGD 80000003c9d2c067 P4D 80000003c9d2c067 PUD 3c817c067 P      MD 0
  Oops: 0002 [#1] SMP PTI
  RIP: 0010:down_write+0x1b/0x40
Call Trace:
  debugfs_remove_recursive+0x46/0x1a0
  intel_gvt_debugfs_remove_vgpu+0x15/0x30 [i915]
  intel_gvt_destroy_vgpu+0x2d/0xf0 [i915]
  intel_vgpu_remove+0x2c/0x30 [kvmgt]
  mdev_device_remove_ops+0x23/0x50 [mdev]
  mdev_device_remove+0xdb/0x190 [mdev]
  mdev_device_remove+0x190/0x190 [mdev]
  device_for_each_child+0x47/0x90
  mdev_unregister_device+0xd5/0x120 [mdev]
  intel_gvt_clean_device+0x91/0x120 [i915]
  i915_driver_unload+0x9d/0x120 [i915]
  i915_pci_remove+0x15/0x20 [i915]
  pci_device_remove+0x3b/0xc0
  device_release_driver_internal+0x157/0x230
  unbind_store+0xfc/0x150
  kernfs_fop_write+0x10f/0x180
  __vfs_write+0x36/0x180
  ? common_file_perm+0x41/0x130
  ? _cond_resched+0x16/0x40
  vfs_write+0xb3/0x1a0
  ksys_write+0x52/0xc0
  do_syscall_64+0x55/0x100
  entry_SYSCALL_64_after_hwframe+0x44/0xa9

BUG: unable to handle kernel NULL pointer dereference at 0      000000000000038
  PGD 8000000405bce067 P4D 8000000405bce067 PUD 405bcd067 PM      D 0
  Oops: 0000 [#1] SMP PTI
  RIP: 0010:hrtimer_active+0x5/0x40
Call Trace:
  hrtimer_try_to_cancel+0x25/0x120
  ? tbs_sched_clean_vgpu+0x1f/0x50 [i915]
  hrtimer_cancel+0x15/0x20
  intel_gvt_destroy_vgpu+0x4c/0xf0 [i915]
  intel_vgpu_remove+0x2c/0x30 [kvmgt]
  mdev_device_remove_ops+0x23/0x50 [mdev]
  mdev_device_remove+0xdb/0x190 [mdev]
  ? mdev_device_remove+0x190/0x190 [mdev]
  device_for_each_child+0x47/0x90
  mdev_unregister_device+0xd5/0x120 [mdev]
  intel_gvt_clean_device+0x89/0x120 [i915]
  i915_driver_unload+0x9d/0x120 [i915]
  i915_pci_remove+0x15/0x20 [i915]
  pci_device_remove+0x3b/0xc0
  device_release_driver_internal+0x157/0x230
  unbind_store+0xfc/0x150
  kernfs_fop_write+0x10f/0x180
  __vfs_write+0x36/0x180
  ? common_file_perm+0x41/0x130
  ? _cond_resched+0x16/0x40
  vfs_write+0xb3/0x1a0
  ksys_write+0x52/0xc0
  do_syscall_64+0x55/0x100
  entry_SYSCALL_64_after_hwframe+0x44/0xa9

Fixes: bc7b0be316ae("drm/i915/gvt: Add basic debugfs infrastructure")
Fixes: afe04fbe6c52("drm/i915/gvt: create an idle vGPU")
Signed-off-by: Hang Yuan <hang.yuan@linux.intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 drivers/gpu/drm/i915/gvt/gvt.c |   14 ++++++--------
 1 file changed, 6 insertions(+), 8 deletions(-)

--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -316,6 +316,11 @@ void intel_gvt_clean_device(struct drm_i
 	if (WARN_ON(!gvt))
 		return;
 
+	intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
+	intel_gvt_hypervisor_host_exit(&dev_priv->drm.pdev->dev, gvt);
+	intel_gvt_cleanup_vgpu_type_groups(gvt);
+	intel_gvt_clean_vgpu_types(gvt);
+
 	intel_gvt_debugfs_clean(gvt);
 	clean_service_thread(gvt);
 	intel_gvt_clean_cmd_parser(gvt);
@@ -323,17 +328,10 @@ void intel_gvt_clean_device(struct drm_i
 	intel_gvt_clean_workload_scheduler(gvt);
 	intel_gvt_clean_gtt(gvt);
 	intel_gvt_clean_irq(gvt);
-	intel_gvt_clean_mmio_info(gvt);
 	intel_gvt_free_firmware(gvt);
-
-	intel_gvt_hypervisor_host_exit(&dev_priv->drm.pdev->dev, gvt);
-	intel_gvt_cleanup_vgpu_type_groups(gvt);
-	intel_gvt_clean_vgpu_types(gvt);
-
+	intel_gvt_clean_mmio_info(gvt);
 	idr_destroy(&gvt->vgpu_idr);
 
-	intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
-
 	kfree(dev_priv->gvt);
 	dev_priv->gvt = NULL;
 }