From: Greg Kroah-Hartman Date: Wed, 3 Nov 2021 08:16:30 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v4.19.216~44 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=171af4e9470623708b9debf31cc78a5968cd0db3;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: scsi-core-put-lld-module-refcnt-after-scsi-device-is-released.patch --- diff --git a/queue-4.19/scsi-core-put-lld-module-refcnt-after-scsi-device-is-released.patch b/queue-4.19/scsi-core-put-lld-module-refcnt-after-scsi-device-is-released.patch new file mode 100644 index 00000000000..aafcaac29e1 --- /dev/null +++ b/queue-4.19/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 +@@ -575,8 +575,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 +@@ -431,9 +431,12 @@ static void scsi_device_dev_release_user + struct list_head *this, *tmp; + struct scsi_vpd *vpd_pg80 = NULL, *vpd_pg83 = NULL; + 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; +@@ -474,11 +477,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); + }