From: Greg Kroah-Hartman Date: Wed, 3 Nov 2021 08:15:53 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.19.216~46 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a3504640410f081bd79ec5800277483bf8fbf721;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: scsi-core-put-lld-module-refcnt-after-scsi-device-is-released.patch --- diff --git a/queue-4.9/scsi-core-put-lld-module-refcnt-after-scsi-device-is-released.patch b/queue-4.9/scsi-core-put-lld-module-refcnt-after-scsi-device-is-released.patch new file mode 100644 index 00000000000..ffe8e21e2cf --- /dev/null +++ b/queue-4.9/scsi-core-put-lld-module-refcnt-after-scsi-device-is-released.patch @@ -0,0 +1,79 @@ +From f2b85040acec9a928b4eb1b57a989324e8e38d3f Mon Sep 17 00:00:00 2001 +From: Ming Lei +Date: Fri, 8 Oct 2021 13:01:18 +0800 +Subject: scsi: core: Put LLD module refcnt after SCSI device is released + +From: Ming Lei + +commit f2b85040acec9a928b4eb1b57a989324e8e38d3f upstream. + +SCSI host release is triggered when SCSI device is freed. We have to make +sure that the low-level device driver module won't be unloaded before SCSI +host instance is released because shost->hostt is required in the release +handler. + +Make sure to put LLD module refcnt after SCSI device is released. + +Fixes a kernel panic of 'BUG: unable to handle page fault for address' +reported by Changhui and Yi. + +Link: https://lore.kernel.org/r/20211008050118.1440686-1-ming.lei@redhat.com +Cc: Greg Kroah-Hartman +Reported-by: Changhui Zhong +Reported-by: Yi Zhang +Tested-by: Yi Zhang +Signed-off-by: Ming Lei +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/scsi.c | 4 +++- + drivers/scsi/scsi_sysfs.c | 9 +++++++++ + 2 files changed, 12 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/scsi.c ++++ b/drivers/scsi/scsi.c +@@ -951,8 +951,10 @@ EXPORT_SYMBOL(scsi_device_get); + */ + void scsi_device_put(struct scsi_device *sdev) + { +- module_put(sdev->host->hostt->module); ++ struct module *mod = sdev->host->hostt->module; ++ + put_device(&sdev->sdev_gendev); ++ module_put(mod); + } + EXPORT_SYMBOL(scsi_device_put); + +--- a/drivers/scsi/scsi_sysfs.c ++++ b/drivers/scsi/scsi_sysfs.c +@@ -427,9 +427,12 @@ static void scsi_device_dev_release_user + struct device *parent; + struct list_head *this, *tmp; + unsigned long flags; ++ struct module *mod; + + sdev = container_of(work, struct scsi_device, ew.work); + ++ mod = sdev->host->hostt->module; ++ + scsi_dh_release_device(sdev); + + parent = sdev->sdev_gendev.parent; +@@ -461,11 +464,17 @@ static void scsi_device_dev_release_user + + if (parent) + put_device(parent); ++ module_put(mod); + } + + static void scsi_device_dev_release(struct device *dev) + { + struct scsi_device *sdp = to_scsi_device(dev); ++ ++ /* Set module pointer as NULL in case of module unloading */ ++ if (!try_module_get(sdp->host->hostt->module)) ++ sdp->host->hostt->module = NULL; ++ + execute_in_process_context(scsi_device_dev_release_usercontext, + &sdp->ew); + }