From: Greg Kroah-Hartman Date: Sat, 13 Nov 2021 11:38:47 +0000 (+0100) Subject: 5.15-stable patches X-Git-Tag: v5.4.160~159 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e2caaf41b786fef412a641b006967f8344405596;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: ce-gf100-fix-incorrect-ce0-address-calculation-on-some-gpus.patch char-xillybus-fix-msg_ep-uaf-in-xillyusb_probe.patch input-elantench-fix-misreporting-trackpoint-coordinates.patch input-i8042-add-quirk-for-fujitsu-lifebook-t725.patch input-iforce-fix-control-message-timeout.patch libata-fix-read-log-timeout-value.patch ocfs2-fix-data-corruption-on-truncate.patch scsi-core-avoid-leaving-shost-last_reset-with-stale-value-if-eh-does-not-run.patch scsi-core-remove-command-size-deduction-from-scsi_setup_scsi_cmnd.patch scsi-lpfc-don-t-release-final-kref-on-fport-node-while-abts-outstanding.patch scsi-lpfc-fix-fcp-i-o-flush-functionality-for-tmf-routines.patch scsi-qla2xxx-fix-crash-in-nvme-abort-path.patch scsi-qla2xxx-fix-kernel-crash-when-accessing-port_speed-sysfs-file.patch scsi-qla2xxx-fix-use-after-free-in-eh_abort-path.patch scsi-scsi_ioctl-validate-command-size.patch --- diff --git a/queue-5.15/ce-gf100-fix-incorrect-ce0-address-calculation-on-some-gpus.patch b/queue-5.15/ce-gf100-fix-incorrect-ce0-address-calculation-on-some-gpus.patch new file mode 100644 index 00000000000..966905754dc --- /dev/null +++ b/queue-5.15/ce-gf100-fix-incorrect-ce0-address-calculation-on-some-gpus.patch @@ -0,0 +1,60 @@ +From 93f43ed81abec8c805e1b77eb1d20dbc51a24dc4 Mon Sep 17 00:00:00 2001 +From: Ben Skeggs +Date: Wed, 3 Nov 2021 11:10:57 +1000 +Subject: ce/gf100: fix incorrect CE0 address calculation on some GPUs + +From: Ben Skeggs + +commit 93f43ed81abec8c805e1b77eb1d20dbc51a24dc4 upstream. + +The code which constructs the modules for each engine present on the GPU +passes -1 for 'instance' on non-instanced engines, which affects how the +name for a sub-device is generated. This is then stored as 'instance 0' +in nvkm_subdev.inst, so code can potentially be shared with earlier GPUs +that only had a single instance of an engine. + +However, GF100's CE constructor uses this value to calculate the address +of its falcon before it's translated, resulting in CE0 getting the wrong +address. + +This slightly modifies the approach, always passing a valid instance for +engines that *can* have multiple copies, and having the code for earlier +GPUs explicitly ask for non-instanced name generation. + +Bug: https://gitlab.freedesktop.org/drm/nouveau/-/issues/91 + +Fixes: 50551b15c760 ("drm/nouveau/ce: switch to instanced constructor") +Cc: # v5.12+ +Signed-off-by: Ben Skeggs +Reviewed-by: Karol Herbst +Tested-by: Karol Herbst +Signed-off-by: Karol Herbst +Link: https://patchwork.freedesktop.org/patch/msgid/20211103011057.15344-1-skeggsb@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c | 2 +- + drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 3 +-- + 2 files changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c +@@ -78,6 +78,6 @@ int + gt215_ce_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, + struct nvkm_engine **pengine) + { +- return nvkm_falcon_new_(>215_ce, device, type, inst, ++ return nvkm_falcon_new_(>215_ce, device, type, -1, + (device->chipset != 0xaf), 0x104000, pengine); + } +--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +@@ -3147,8 +3147,7 @@ nvkm_device_ctor(const struct nvkm_devic + WARN_ON(device->chip->ptr.inst & ~((1 << ARRAY_SIZE(device->ptr)) - 1)); \ + for (j = 0; device->chip->ptr.inst && j < ARRAY_SIZE(device->ptr); j++) { \ + if ((device->chip->ptr.inst & BIT(j)) && (subdev_mask & BIT_ULL(type))) { \ +- int inst = (device->chip->ptr.inst == 1) ? -1 : (j); \ +- ret = device->chip->ptr.ctor(device, (type), inst, &device->ptr[j]); \ ++ ret = device->chip->ptr.ctor(device, (type), (j), &device->ptr[j]); \ + subdev = nvkm_device_subdev(device, (type), (j)); \ + if (ret) { \ + nvkm_subdev_del(&subdev); \ diff --git a/queue-5.15/char-xillybus-fix-msg_ep-uaf-in-xillyusb_probe.patch b/queue-5.15/char-xillybus-fix-msg_ep-uaf-in-xillyusb_probe.patch new file mode 100644 index 00000000000..a3e0dab7ab6 --- /dev/null +++ b/queue-5.15/char-xillybus-fix-msg_ep-uaf-in-xillyusb_probe.patch @@ -0,0 +1,64 @@ +From 15c9a359094ec6251578b02387436bc64f11a477 Mon Sep 17 00:00:00 2001 +From: Ziyang Xuan +Date: Sat, 16 Oct 2021 13:20:47 +0800 +Subject: char: xillybus: fix msg_ep UAF in xillyusb_probe() + +From: Ziyang Xuan + +commit 15c9a359094ec6251578b02387436bc64f11a477 upstream. + +When endpoint_alloc() return failed in xillyusb_setup_base_eps(), +'xdev->msg_ep' will be freed but not set to NULL. That lets program +enter fail handling to cleanup_dev() in xillyusb_probe(). Check for +'xdev->msg_ep' is invalid in cleanup_dev() because 'xdev->msg_ep' did +not set to NULL when was freed. So the UAF problem for 'xdev->msg_ep' +is triggered. + +================================================================== +BUG: KASAN: use-after-free in fifo_mem_release+0x1f4/0x210 +CPU: 0 PID: 166 Comm: kworker/0:2 Not tainted 5.15.0-rc5+ #19 +Call Trace: + dump_stack_lvl+0xe2/0x152 + print_address_description.constprop.0+0x21/0x140 + ? fifo_mem_release+0x1f4/0x210 + kasan_report.cold+0x7f/0x11b + ? xillyusb_probe+0x530/0x700 + ? fifo_mem_release+0x1f4/0x210 + fifo_mem_release+0x1f4/0x210 + ? __sanitizer_cov_trace_pc+0x1d/0x50 + endpoint_dealloc+0x35/0x2b0 + cleanup_dev+0x90/0x120 + xillyusb_probe+0x59a/0x700 +... + +Freed by task 166: + kasan_save_stack+0x1b/0x40 + kasan_set_track+0x1c/0x30 + kasan_set_free_info+0x20/0x30 + __kasan_slab_free+0x109/0x140 + kfree+0x117/0x4c0 + xillyusb_probe+0x606/0x700 + +Set 'xdev->msg_ep' to NULL after being freed in xillyusb_setup_base_eps() +to fix the UAF problem. + +Fixes: a53d1202aef1 ("char: xillybus: Add driver for XillyUSB (Xillybus variant for USB)") +Cc: stable +Acked-by: Eli Billauer +Signed-off-by: Ziyang Xuan +Link: https://lore.kernel.org/r/20211016052047.1611983-1-william.xuanziyang@huawei.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/char/xillybus/xillyusb.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/char/xillybus/xillyusb.c ++++ b/drivers/char/xillybus/xillyusb.c +@@ -1912,6 +1912,7 @@ static int xillyusb_setup_base_eps(struc + + dealloc: + endpoint_dealloc(xdev->msg_ep); /* Also frees FIFO mem if allocated */ ++ xdev->msg_ep = NULL; + return -ENOMEM; + } + diff --git a/queue-5.15/input-elantench-fix-misreporting-trackpoint-coordinates.patch b/queue-5.15/input-elantench-fix-misreporting-trackpoint-coordinates.patch new file mode 100644 index 00000000000..24cc2e1e293 --- /dev/null +++ b/queue-5.15/input-elantench-fix-misreporting-trackpoint-coordinates.patch @@ -0,0 +1,45 @@ +From be896bd3b72b44126c55768f14c22a8729b0992e Mon Sep 17 00:00:00 2001 +From: Phoenix Huang +Date: Sun, 7 Nov 2021 22:00:03 -0800 +Subject: Input: elantench - fix misreporting trackpoint coordinates + +From: Phoenix Huang + +commit be896bd3b72b44126c55768f14c22a8729b0992e upstream. + +Some firmwares occasionally report bogus data from trackpoint, with X or Y +displacement being too large (outside of [-127, 127] range). Let's drop such +packets so that we do not generate jumps. + +Signed-off-by: Phoenix Huang +Tested-by: Yufei Du +Link: https://lore.kernel.org/r/20210729010940.5752-1-phoenix@emc.com.tw +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/mouse/elantech.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -517,6 +517,19 @@ static void elantech_report_trackpoint(s + case 0x16008020U: + case 0x26800010U: + case 0x36808000U: ++ ++ /* ++ * This firmware misreport coordinates for trackpoint ++ * occasionally. Discard packets outside of [-127, 127] range ++ * to prevent cursor jumps. ++ */ ++ if (packet[4] == 0x80 || packet[5] == 0x80 || ++ packet[1] >> 7 == packet[4] >> 7 || ++ packet[2] >> 7 == packet[5] >> 7) { ++ elantech_debug("discarding packet [%6ph]\n", packet); ++ break; ++ ++ } + x = packet[4] - (int)((packet[1]^0x80) << 1); + y = (int)((packet[2]^0x80) << 1) - packet[5]; + diff --git a/queue-5.15/input-i8042-add-quirk-for-fujitsu-lifebook-t725.patch b/queue-5.15/input-i8042-add-quirk-for-fujitsu-lifebook-t725.patch new file mode 100644 index 00000000000..4feebb4deaf --- /dev/null +++ b/queue-5.15/input-i8042-add-quirk-for-fujitsu-lifebook-t725.patch @@ -0,0 +1,54 @@ +From 16e28abb7290c4ca3b3a0f333ba067f34bb18c86 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Wed, 3 Nov 2021 08:00:19 +0100 +Subject: Input: i8042 - Add quirk for Fujitsu Lifebook T725 + +From: Takashi Iwai + +commit 16e28abb7290c4ca3b3a0f333ba067f34bb18c86 upstream. + +Fujitsu Lifebook T725 laptop requires, like a few other similar +models, the nomux and notimeout options to probe the touchpad +properly. This patch adds the corresponding quirk entries. + +BugLink: https://bugzilla.suse.com/show_bug.cgi?id=1191980 +Tested-by: Neal Gompa +Cc: +Signed-off-by: Takashi Iwai +Link: https://lore.kernel.org/r/20211103070019.13374-1-tiwai@suse.de +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/serio/i8042-x86ia64io.h | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ b/drivers/input/serio/i8042-x86ia64io.h +@@ -273,6 +273,13 @@ static const struct dmi_system_id __init + }, + }, + { ++ /* Fujitsu Lifebook T725 laptop */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T725"), ++ }, ++ }, ++ { + /* Fujitsu Lifebook U745 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), +@@ -841,6 +848,13 @@ static const struct dmi_system_id __init + }, + }, + { ++ /* Fujitsu Lifebook T725 laptop */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK T725"), ++ }, ++ }, ++ { + /* Fujitsu U574 laptop */ + /* https://bugzilla.kernel.org/show_bug.cgi?id=69731 */ + .matches = { diff --git a/queue-5.15/input-iforce-fix-control-message-timeout.patch b/queue-5.15/input-iforce-fix-control-message-timeout.patch new file mode 100644 index 00000000000..492c9e73839 --- /dev/null +++ b/queue-5.15/input-iforce-fix-control-message-timeout.patch @@ -0,0 +1,33 @@ +From 744d0090a5f6dfa4c81b53402ccdf08313100429 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Tue, 9 Nov 2021 22:58:01 -0800 +Subject: Input: iforce - fix control-message timeout + +From: Johan Hovold + +commit 744d0090a5f6dfa4c81b53402ccdf08313100429 upstream. + +USB control-message timeouts are specified in milliseconds and should +specifically not vary with CONFIG_HZ. + +Fixes: 487358627825 ("Input: iforce - use DMA-safe buffer when getting IDs from USB") +Signed-off-by: Johan Hovold +Cc: stable@vger.kernel.org # 5.3 +Link: https://lore.kernel.org/r/20211025115501.5190-1-johan@kernel.org +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/joystick/iforce/iforce-usb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/input/joystick/iforce/iforce-usb.c ++++ b/drivers/input/joystick/iforce/iforce-usb.c +@@ -92,7 +92,7 @@ static int iforce_usb_get_id(struct ifor + id, + USB_TYPE_VENDOR | USB_DIR_IN | + USB_RECIP_INTERFACE, +- 0, 0, buf, IFORCE_MAX_LENGTH, HZ); ++ 0, 0, buf, IFORCE_MAX_LENGTH, 1000); + if (status < 0) { + dev_err(&iforce_usb->intf->dev, + "usb_submit_urb failed: %d\n", status); diff --git a/queue-5.15/libata-fix-read-log-timeout-value.patch b/queue-5.15/libata-fix-read-log-timeout-value.patch new file mode 100644 index 00000000000..c9d649baa2d --- /dev/null +++ b/queue-5.15/libata-fix-read-log-timeout-value.patch @@ -0,0 +1,88 @@ +From 68dbbe7d5b4fde736d104cbbc9a2fce875562012 Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Thu, 4 Nov 2021 17:31:58 +0900 +Subject: libata: fix read log timeout value + +From: Damien Le Moal + +commit 68dbbe7d5b4fde736d104cbbc9a2fce875562012 upstream. + +Some ATA drives are very slow to respond to READ_LOG_EXT and +READ_LOG_DMA_EXT commands issued from ata_dev_configure() when the +device is revalidated right after resuming a system or inserting the +ATA adapter driver (e.g. ahci). The default 5s timeout +(ATA_EH_CMD_DFL_TIMEOUT) used for these commands is too short, causing +errors during the device configuration. Ex: + +... +ata9: SATA max UDMA/133 abar m524288@0x9d200000 port 0x9d200400 irq 209 +ata9: SATA link up 6.0 Gbps (SStatus 133 SControl 300) +ata9.00: ATA-9: XXX XXXXXXXXXXXXXXX, XXXXXXXX, max UDMA/133 +ata9.00: qc timeout (cmd 0x2f) +ata9.00: Read log page 0x00 failed, Emask 0x4 +ata9.00: Read log page 0x00 failed, Emask 0x40 +ata9.00: NCQ Send/Recv Log not supported +ata9.00: Read log page 0x08 failed, Emask 0x40 +ata9.00: 27344764928 sectors, multi 16: LBA48 NCQ (depth 32), AA +ata9.00: Read log page 0x00 failed, Emask 0x40 +ata9.00: ATA Identify Device Log not supported +ata9.00: failed to set xfermode (err_mask=0x40) +ata9: SATA link up 6.0 Gbps (SStatus 133 SControl 300) +ata9.00: configured for UDMA/133 +... + +The timeout error causes a soft reset of the drive link, followed in +most cases by a successful revalidation as that give enough time to the +drive to become fully ready to quickly process the read log commands. +However, in some cases, this also fails resulting in the device being +dropped. + +Fix this by using adding the ata_eh_revalidate_timeouts entries for the +READ_LOG_EXT and READ_LOG_DMA_EXT commands. This defines a timeout +increased to 15s, retriable one time. + +Reported-by: Geert Uytterhoeven +Tested-by: Geert Uytterhoeven +Cc: stable@vger.kernel.org +Signed-off-by: Damien Le Moal +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ata/libata-eh.c | 8 ++++++++ + include/linux/libata.h | 2 +- + 2 files changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/ata/libata-eh.c ++++ b/drivers/ata/libata-eh.c +@@ -93,6 +93,12 @@ static const unsigned long ata_eh_identi + ULONG_MAX, + }; + ++static const unsigned long ata_eh_revalidate_timeouts[] = { ++ 15000, /* Some drives are slow to read log pages when waking-up */ ++ 15000, /* combined time till here is enough even for media access */ ++ ULONG_MAX, ++}; ++ + static const unsigned long ata_eh_flush_timeouts[] = { + 15000, /* be generous with flush */ + 15000, /* ditto */ +@@ -129,6 +135,8 @@ static const struct ata_eh_cmd_timeout_e + ata_eh_cmd_timeout_table[ATA_EH_CMD_TIMEOUT_TABLE_SIZE] = { + { .commands = CMDS(ATA_CMD_ID_ATA, ATA_CMD_ID_ATAPI), + .timeouts = ata_eh_identify_timeouts, }, ++ { .commands = CMDS(ATA_CMD_READ_LOG_EXT, ATA_CMD_READ_LOG_DMA_EXT), ++ .timeouts = ata_eh_revalidate_timeouts, }, + { .commands = CMDS(ATA_CMD_READ_NATIVE_MAX, ATA_CMD_READ_NATIVE_MAX_EXT), + .timeouts = ata_eh_other_timeouts, }, + { .commands = CMDS(ATA_CMD_SET_MAX, ATA_CMD_SET_MAX_EXT), +--- a/include/linux/libata.h ++++ b/include/linux/libata.h +@@ -394,7 +394,7 @@ enum { + /* This should match the actual table size of + * ata_eh_cmd_timeout_table in libata-eh.c. + */ +- ATA_EH_CMD_TIMEOUT_TABLE_SIZE = 6, ++ ATA_EH_CMD_TIMEOUT_TABLE_SIZE = 7, + + /* Horkage types. May be set by libata or controller on drives + (some horkage may be drive/controller pair dependent */ diff --git a/queue-5.15/ocfs2-fix-data-corruption-on-truncate.patch b/queue-5.15/ocfs2-fix-data-corruption-on-truncate.patch new file mode 100644 index 00000000000..439432cff10 --- /dev/null +++ b/queue-5.15/ocfs2-fix-data-corruption-on-truncate.patch @@ -0,0 +1,91 @@ +From 839b63860eb3835da165642923120d305925561d Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Fri, 5 Nov 2021 13:34:55 -0700 +Subject: ocfs2: fix data corruption on truncate + +From: Jan Kara + +commit 839b63860eb3835da165642923120d305925561d upstream. + +Patch series "ocfs2: Truncate data corruption fix". + +As further testing has shown, commit 5314454ea3f ("ocfs2: fix data +corruption after conversion from inline format") didn't fix all the data +corruption issues the customer started observing after 6dbf7bb55598 +("fs: Don't invalidate page buffers in block_write_full_page()") This +time I have tracked them down to two bugs in ocfs2 truncation code. + +One bug (truncating page cache before clearing tail cluster and setting +i_size) could cause data corruption even before 6dbf7bb55598, but before +that commit it needed a race with page fault, after 6dbf7bb55598 it +started to be pretty deterministic. + +Another bug (zeroing pages beyond old i_size) used to be harmless +inefficiency before commit 6dbf7bb55598. But after commit 6dbf7bb55598 +in combination with the first bug it resulted in deterministic data +corruption. + +Although fixing only the first problem is needed to stop data +corruption, I've fixed both issues to make the code more robust. + +This patch (of 2): + +ocfs2_truncate_file() did unmap invalidate page cache pages before +zeroing partial tail cluster and setting i_size. Thus some pages could +be left (and likely have left if the cluster zeroing happened) in the +page cache beyond i_size after truncate finished letting user possibly +see stale data once the file was extended again. Also the tail cluster +zeroing was not guaranteed to finish before truncate finished causing +possible stale data exposure. The problem started to be particularly +easy to hit after commit 6dbf7bb55598 "fs: Don't invalidate page buffers +in block_write_full_page()" stopped invalidation of pages beyond i_size +from page writeback path. + +Fix these problems by unmapping and invalidating pages in the page cache +after the i_size is reduced and tail cluster is zeroed out. + +Link: https://lkml.kernel.org/r/20211025150008.29002-1-jack@suse.cz +Link: https://lkml.kernel.org/r/20211025151332.11301-1-jack@suse.cz +Fixes: ccd979bdbce9 ("[PATCH] OCFS2: The Second Oracle Cluster Filesystem") +Signed-off-by: Jan Kara +Reviewed-by: Joseph Qi +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Junxiao Bi +Cc: Changwei Ge +Cc: Gang He +Cc: Jun Piao +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + fs/ocfs2/file.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/fs/ocfs2/file.c ++++ b/fs/ocfs2/file.c +@@ -476,10 +476,11 @@ int ocfs2_truncate_file(struct inode *in + * greater than page size, so we have to truncate them + * anyway. + */ +- unmap_mapping_range(inode->i_mapping, new_i_size + PAGE_SIZE - 1, 0, 1); +- truncate_inode_pages(inode->i_mapping, new_i_size); + + if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) { ++ unmap_mapping_range(inode->i_mapping, ++ new_i_size + PAGE_SIZE - 1, 0, 1); ++ truncate_inode_pages(inode->i_mapping, new_i_size); + status = ocfs2_truncate_inline(inode, di_bh, new_i_size, + i_size_read(inode), 1); + if (status) +@@ -498,6 +499,9 @@ int ocfs2_truncate_file(struct inode *in + goto bail_unlock_sem; + } + ++ unmap_mapping_range(inode->i_mapping, new_i_size + PAGE_SIZE - 1, 0, 1); ++ truncate_inode_pages(inode->i_mapping, new_i_size); ++ + status = ocfs2_commit_truncate(osb, inode, di_bh); + if (status < 0) { + mlog_errno(status); diff --git a/queue-5.15/scsi-core-avoid-leaving-shost-last_reset-with-stale-value-if-eh-does-not-run.patch b/queue-5.15/scsi-core-avoid-leaving-shost-last_reset-with-stale-value-if-eh-does-not-run.patch new file mode 100644 index 00000000000..f6e77f796fc --- /dev/null +++ b/queue-5.15/scsi-core-avoid-leaving-shost-last_reset-with-stale-value-if-eh-does-not-run.patch @@ -0,0 +1,148 @@ +From 5ae17501bc62a49b0b193dcce003f16375f16654 Mon Sep 17 00:00:00 2001 +From: "Ewan D. Milne" +Date: Fri, 29 Oct 2021 15:43:10 -0400 +Subject: scsi: core: Avoid leaving shost->last_reset with stale value if EH does not run + +From: Ewan D. Milne + +commit 5ae17501bc62a49b0b193dcce003f16375f16654 upstream. + +The changes to issue the abort from the scmd->abort_work instead of the EH +thread introduced a problem if eh_deadline is used. If aborting the +command(s) is successful, and there are never any scmds added to the +shost->eh_cmd_q, there is no code path which will reset the ->last_reset +value back to zero. + +The effect of this is that after a successful abort with no EH thread +activity, a subsequent timeout, perhaps a long time later, might +immediately be considered past a user-set eh_deadline time, and the host +will be reset with no attempt at recovery. + +Fix this by resetting ->last_reset back to zero in scmd_eh_abort_handler() +if it is determined that the EH thread will not run to do this. + +Thanks to Gopinath Marappan for investigating this problem. + +Link: https://lore.kernel.org/r/20211029194311.17504-2-emilne@redhat.com +Fixes: e494f6a72839 ("[SCSI] improved eh timeout handler") +Cc: stable@vger.kernel.org +Signed-off-by: Ewan D. Milne +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/hosts.c | 1 + + drivers/scsi/scsi_error.c | 25 +++++++++++++++++++++++++ + drivers/scsi/scsi_lib.c | 1 + + include/scsi/scsi_cmnd.h | 2 +- + include/scsi/scsi_host.h | 1 + + 5 files changed, 29 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/hosts.c ++++ b/drivers/scsi/hosts.c +@@ -388,6 +388,7 @@ struct Scsi_Host *scsi_host_alloc(struct + shost->shost_state = SHOST_CREATED; + INIT_LIST_HEAD(&shost->__devices); + INIT_LIST_HEAD(&shost->__targets); ++ INIT_LIST_HEAD(&shost->eh_abort_list); + INIT_LIST_HEAD(&shost->eh_cmd_q); + INIT_LIST_HEAD(&shost->starved_list); + init_waitqueue_head(&shost->host_wait); +--- a/drivers/scsi/scsi_error.c ++++ b/drivers/scsi/scsi_error.c +@@ -135,6 +135,23 @@ static bool scsi_eh_should_retry_cmd(str + return true; + } + ++static void scsi_eh_complete_abort(struct scsi_cmnd *scmd, struct Scsi_Host *shost) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(shost->host_lock, flags); ++ list_del_init(&scmd->eh_entry); ++ /* ++ * If the abort succeeds, and there is no further ++ * EH action, clear the ->last_reset time. ++ */ ++ if (list_empty(&shost->eh_abort_list) && ++ list_empty(&shost->eh_cmd_q)) ++ if (shost->eh_deadline != -1) ++ shost->last_reset = 0; ++ spin_unlock_irqrestore(shost->host_lock, flags); ++} ++ + /** + * scmd_eh_abort_handler - Handle command aborts + * @work: command to be aborted. +@@ -152,6 +169,7 @@ scmd_eh_abort_handler(struct work_struct + container_of(work, struct scsi_cmnd, abort_work.work); + struct scsi_device *sdev = scmd->device; + enum scsi_disposition rtn; ++ unsigned long flags; + + if (scsi_host_eh_past_deadline(sdev->host)) { + SCSI_LOG_ERROR_RECOVERY(3, +@@ -175,12 +193,14 @@ scmd_eh_abort_handler(struct work_struct + SCSI_LOG_ERROR_RECOVERY(3, + scmd_printk(KERN_WARNING, scmd, + "retry aborted command\n")); ++ scsi_eh_complete_abort(scmd, sdev->host); + scsi_queue_insert(scmd, SCSI_MLQUEUE_EH_RETRY); + return; + } else { + SCSI_LOG_ERROR_RECOVERY(3, + scmd_printk(KERN_WARNING, scmd, + "finish aborted command\n")); ++ scsi_eh_complete_abort(scmd, sdev->host); + scsi_finish_command(scmd); + return; + } +@@ -193,6 +213,9 @@ scmd_eh_abort_handler(struct work_struct + } + } + ++ spin_lock_irqsave(sdev->host->host_lock, flags); ++ list_del_init(&scmd->eh_entry); ++ spin_unlock_irqrestore(sdev->host->host_lock, flags); + scsi_eh_scmd_add(scmd); + } + +@@ -223,6 +246,8 @@ scsi_abort_command(struct scsi_cmnd *scm + spin_lock_irqsave(shost->host_lock, flags); + if (shost->eh_deadline != -1 && !shost->last_reset) + shost->last_reset = jiffies; ++ BUG_ON(!list_empty(&scmd->eh_entry)); ++ list_add_tail(&scmd->eh_entry, &shost->eh_abort_list); + spin_unlock_irqrestore(shost->host_lock, flags); + + scmd->eh_eflags |= SCSI_EH_ABORT_SCHEDULED; +--- a/drivers/scsi/scsi_lib.c ++++ b/drivers/scsi/scsi_lib.c +@@ -1143,6 +1143,7 @@ void scsi_init_command(struct scsi_devic + cmd->sense_buffer = buf; + cmd->prot_sdb = prot; + cmd->flags = flags; ++ INIT_LIST_HEAD(&cmd->eh_entry); + INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler); + cmd->jiffies_at_alloc = jiffies_at_alloc; + cmd->retries = retries; +--- a/include/scsi/scsi_cmnd.h ++++ b/include/scsi/scsi_cmnd.h +@@ -68,7 +68,7 @@ struct scsi_pointer { + struct scsi_cmnd { + struct scsi_request req; + struct scsi_device *device; +- struct list_head eh_entry; /* entry for the host eh_cmd_q */ ++ struct list_head eh_entry; /* entry for the host eh_abort_list/eh_cmd_q */ + struct delayed_work abort_work; + + struct rcu_head rcu; +--- a/include/scsi/scsi_host.h ++++ b/include/scsi/scsi_host.h +@@ -556,6 +556,7 @@ struct Scsi_Host { + + struct mutex scan_mutex;/* serialize scanning activity */ + ++ struct list_head eh_abort_list; + struct list_head eh_cmd_q; + struct task_struct * ehandler; /* Error recovery thread. */ + struct completion * eh_action; /* Wait for specific actions on the diff --git a/queue-5.15/scsi-core-remove-command-size-deduction-from-scsi_setup_scsi_cmnd.patch b/queue-5.15/scsi-core-remove-command-size-deduction-from-scsi_setup_scsi_cmnd.patch new file mode 100644 index 00000000000..5a0f6accf02 --- /dev/null +++ b/queue-5.15/scsi-core-remove-command-size-deduction-from-scsi_setup_scsi_cmnd.patch @@ -0,0 +1,70 @@ +From 703535e6ae1e94c89a9c1396b4c7b6b41160ef0c Mon Sep 17 00:00:00 2001 +From: Tadeusz Struk +Date: Wed, 3 Nov 2021 10:06:59 -0700 +Subject: scsi: core: Remove command size deduction from scsi_setup_scsi_cmnd() + +From: Tadeusz Struk + +commit 703535e6ae1e94c89a9c1396b4c7b6b41160ef0c upstream. + +No need to deduce command size in scsi_setup_scsi_cmnd() anymore as +appropriate checks have been added to scsi_fill_sghdr_rq() function and the +cmd_len should never be zero here. The code to do that wasn't correct +anyway, as it used uninitialized cmd->cmnd, which caused a null-ptr-deref +if the command size was zero as in the trace below. Fix this by removing +the unneeded code. + +KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] +CPU: 0 PID: 1822 Comm: repro Not tainted 5.15.0 #1 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-4.fc34 04/01/2014 +Call Trace: + blk_mq_dispatch_rq_list+0x7c7/0x12d0 + __blk_mq_sched_dispatch_requests+0x244/0x380 + blk_mq_sched_dispatch_requests+0xf0/0x160 + __blk_mq_run_hw_queue+0xe8/0x160 + __blk_mq_delay_run_hw_queue+0x252/0x5d0 + blk_mq_run_hw_queue+0x1dd/0x3b0 + blk_mq_sched_insert_request+0x1ff/0x3e0 + blk_execute_rq_nowait+0x173/0x1e0 + blk_execute_rq+0x15c/0x540 + sg_io+0x97c/0x1370 + scsi_ioctl+0xe16/0x28e0 + sd_ioctl+0x134/0x170 + blkdev_ioctl+0x362/0x6e0 + block_ioctl+0xb0/0xf0 + vfs_ioctl+0xa7/0xf0 + do_syscall_64+0x3d/0xb0 + entry_SYSCALL_64_after_hwframe+0x44/0xae +---[ end trace 8b086e334adef6d2 ]--- +Kernel panic - not syncing: Fatal exception + +Link: https://lore.kernel.org/r/20211103170659.22151-2-tadeusz.struk@linaro.org +Fixes: 2ceda20f0a99 ("scsi: core: Move command size detection out of the fast path") +Cc: Bart Van Assche +Cc: Christoph Hellwig +Cc: James E.J. Bottomley +Cc: Martin K. Petersen +Cc: +Cc: +Cc: # 5.15, 5.14, 5.10 +Reported-by: syzbot+5516b30f5401d4dcbcae@syzkaller.appspotmail.com +Reviewed-by: Bart Van Assche +Reviewed-by: Christoph Hellwig +Signed-off-by: Tadeusz Struk +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/scsi_lib.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/scsi/scsi_lib.c ++++ b/drivers/scsi/scsi_lib.c +@@ -1175,8 +1175,6 @@ static blk_status_t scsi_setup_scsi_cmnd + } + + cmd->cmd_len = scsi_req(req)->cmd_len; +- if (cmd->cmd_len == 0) +- cmd->cmd_len = scsi_command_size(cmd->cmnd); + cmd->cmnd = scsi_req(req)->cmd; + cmd->transfersize = blk_rq_bytes(req); + cmd->allowed = scsi_req(req)->retries; diff --git a/queue-5.15/scsi-lpfc-don-t-release-final-kref-on-fport-node-while-abts-outstanding.patch b/queue-5.15/scsi-lpfc-don-t-release-final-kref-on-fport-node-while-abts-outstanding.patch new file mode 100644 index 00000000000..64279e4e697 --- /dev/null +++ b/queue-5.15/scsi-lpfc-don-t-release-final-kref-on-fport-node-while-abts-outstanding.patch @@ -0,0 +1,120 @@ +From 982fc3965d1350d3332e04046b0e101006184ba9 Mon Sep 17 00:00:00 2001 +From: James Smart +Date: Fri, 10 Sep 2021 16:31:47 -0700 +Subject: scsi: lpfc: Don't release final kref on Fport node while ABTS outstanding + +From: James Smart + +commit 982fc3965d1350d3332e04046b0e101006184ba9 upstream. + +In a rarely executed path, FLOGI failure, there is a refcounting error. If +FLOGI completed with an error, typically a timeout, the initial completion +handler would remove the job reference. However, the job completion isn't +the actual end of the job/exchange as the timeout usually initiates an +ABTS, and upon that ABTS completion, a final completion is sent. The driver +removes the reference again in the final completion. Thus the imbalance. + +In the buggy cases, if there was a link bounce while the delayed response +is outstanding, the fport node may be referenced again but there was no +additional reference as it is already present. The delayed completion then +occurs and removes the last reference freeing the node and causing issues +in the link up processed that is using the node. + +Fix this scenario by removing the snippet that removed the reference in the +initial FLOGI completion. The bad snippet was poorly trying to identify the +FLOGI as OK to do so by realizing the node was not registered with either +SCSI or NVMe transport. + +Link: https://lore.kernel.org/r/20210910233159.115896-3-jsmart2021@gmail.com +Fixes: 618e2ee146d4 ("scsi: lpfc: Fix FLOGI failure due to accessing a freed node") +Cc: # v5.13+ +Co-developed-by: Justin Tee +Signed-off-by: Justin Tee +Signed-off-by: James Smart +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/lpfc/lpfc_els.c | 11 +++++------ + drivers/scsi/lpfc/lpfc_hbadisc.c | 10 ++++++---- + drivers/scsi/lpfc/lpfc_nvme.c | 5 +++-- + 3 files changed, 14 insertions(+), 12 deletions(-) + +--- a/drivers/scsi/lpfc/lpfc_els.c ++++ b/drivers/scsi/lpfc/lpfc_els.c +@@ -1059,9 +1059,10 @@ stop_rr_fcf_flogi: + + lpfc_printf_vlog(vport, KERN_WARNING, LOG_TRACE_EVENT, + "0150 FLOGI failure Status:x%x/x%x " +- "xri x%x TMO:x%x\n", ++ "xri x%x TMO:x%x refcnt %d\n", + irsp->ulpStatus, irsp->un.ulpWord[4], +- cmdiocb->sli4_xritag, irsp->ulpTimeout); ++ cmdiocb->sli4_xritag, irsp->ulpTimeout, ++ kref_read(&ndlp->kref)); + + /* If this is not a loop open failure, bail out */ + if (!(irsp->ulpStatus == IOSTAT_LOCAL_REJECT && +@@ -1122,12 +1123,12 @@ stop_rr_fcf_flogi: + /* FLOGI completes successfully */ + lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, + "0101 FLOGI completes successfully, I/O tag:x%x, " +- "xri x%x Data: x%x x%x x%x x%x x%x x%x x%x\n", ++ "xri x%x Data: x%x x%x x%x x%x x%x x%x x%x %d\n", + cmdiocb->iotag, cmdiocb->sli4_xritag, + irsp->un.ulpWord[4], sp->cmn.e_d_tov, + sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution, + vport->port_state, vport->fc_flag, +- sp->cmn.priority_tagging); ++ sp->cmn.priority_tagging, kref_read(&ndlp->kref)); + + if (sp->cmn.priority_tagging) + vport->vmid_flag |= LPFC_VMID_ISSUE_QFPA; +@@ -1205,8 +1206,6 @@ flogifail: + phba->fcf.fcf_flag &= ~FCF_DISCOVERY; + spin_unlock_irq(&phba->hbalock); + +- if (!(ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | NVME_XPT_REGD))) +- lpfc_nlp_put(ndlp); + if (!lpfc_error_lost_link(irsp)) { + /* FLOGI failed, so just use loop map to make discovery list */ + lpfc_disc_list_loopmap(vport); +--- a/drivers/scsi/lpfc/lpfc_hbadisc.c ++++ b/drivers/scsi/lpfc/lpfc_hbadisc.c +@@ -4449,8 +4449,9 @@ lpfc_register_remote_port(struct lpfc_vp + fc_remote_port_rolechg(rport, rport_ids.roles); + + lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, +- "3183 %s rport x%px DID x%x, role x%x\n", +- __func__, rport, rport->port_id, rport->roles); ++ "3183 %s rport x%px DID x%x, role x%x refcnt %d\n", ++ __func__, rport, rport->port_id, rport->roles, ++ kref_read(&ndlp->kref)); + + if ((rport->scsi_target_id != -1) && + (rport->scsi_target_id < LPFC_MAX_TARGET)) { +@@ -4475,8 +4476,9 @@ lpfc_unregister_remote_port(struct lpfc_ + + lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, + "3184 rport unregister x%06x, rport x%px " +- "xptflg x%x\n", +- ndlp->nlp_DID, rport, ndlp->fc4_xpt_flags); ++ "xptflg x%x refcnt %d\n", ++ ndlp->nlp_DID, rport, ndlp->fc4_xpt_flags, ++ kref_read(&ndlp->kref)); + + fc_remote_port_delete(rport); + lpfc_nlp_put(ndlp); +--- a/drivers/scsi/lpfc/lpfc_nvme.c ++++ b/drivers/scsi/lpfc/lpfc_nvme.c +@@ -209,8 +209,9 @@ lpfc_nvme_remoteport_delete(struct nvme_ + * calling state machine to remove the node. + */ + lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, +- "6146 remoteport delete of remoteport x%px\n", +- remoteport); ++ "6146 remoteport delete of remoteport x%px, ndlp x%px " ++ "DID x%x xflags x%x\n", ++ remoteport, ndlp, ndlp->nlp_DID, ndlp->fc4_xpt_flags); + spin_lock_irq(&ndlp->lock); + + /* The register rebind might have occurred before the delete diff --git a/queue-5.15/scsi-lpfc-fix-fcp-i-o-flush-functionality-for-tmf-routines.patch b/queue-5.15/scsi-lpfc-fix-fcp-i-o-flush-functionality-for-tmf-routines.patch new file mode 100644 index 00000000000..393dcc8a436 --- /dev/null +++ b/queue-5.15/scsi-lpfc-fix-fcp-i-o-flush-functionality-for-tmf-routines.patch @@ -0,0 +1,215 @@ +From cd8a36a90babf958082b87bc6b4df5dd70901eba Mon Sep 17 00:00:00 2001 +From: James Smart +Date: Fri, 10 Sep 2021 16:31:53 -0700 +Subject: scsi: lpfc: Fix FCP I/O flush functionality for TMF routines + +From: James Smart + +commit cd8a36a90babf958082b87bc6b4df5dd70901eba upstream. + +A prior patch inadvertently caused lpfc_sli_sum_iocb() to exclude counting +of outstanding aborted I/Os and ABORT IOCBs. Thus, +lpfc_reset_flush_io_context() called from any TMF routine does not properly +wait to flush all outstanding FCP IOCBs leading to a block layer crash on +an invalid scsi_cmnd->request pointer. + + kernel BUG at ../block/blk-core.c:1489! + RIP: 0010:blk_requeue_request+0xaf/0xc0 + ... + Call Trace: + + __scsi_queue_insert+0x90/0xe0 [scsi_mod] + blk_done_softirq+0x7e/0x90 + __do_softirq+0xd2/0x280 + irq_exit+0xd5/0xe0 + do_IRQ+0x4c/0xd0 + common_interrupt+0x87/0x87 + + +Fix by separating out the LPFC_IO_FCP, LPFC_IO_ON_TXCMPLQ, +LPFC_DRIVER_ABORTED, and CMD_ABORT_XRI_CN || CMD_CLOSE_XRI_CN checks into a +new lpfc_sli_validate_fcp_iocb_for_abort() routine when determining to +build an ABORT iocb. + +Restore lpfc_reset_flush_io_context() functionality by including counting +of outstanding aborted IOCBs and ABORT IOCBs in lpfc_sli_sum_iocb(). + +Link: https://lore.kernel.org/r/20210910233159.115896-9-jsmart2021@gmail.com +Fixes: e1364711359f ("scsi: lpfc: Fix illegal memory access on Abort IOCBs") +Cc: # v5.12+ +Co-developed-by: Justin Tee +Signed-off-by: Justin Tee +Signed-off-by: James Smart +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/lpfc/lpfc_sli.c | 101 +++++++++++++++++++++++++++++++++---------- + 1 file changed, 78 insertions(+), 23 deletions(-) + +--- a/drivers/scsi/lpfc/lpfc_sli.c ++++ b/drivers/scsi/lpfc/lpfc_sli.c +@@ -12488,15 +12488,54 @@ lpfc_sli_hba_iocb_abort(struct lpfc_hba + } + + /** +- * lpfc_sli_validate_fcp_iocb - find commands associated with a vport or LUN ++ * lpfc_sli_validate_fcp_iocb_for_abort - filter iocbs appropriate for FCP aborts ++ * @iocbq: Pointer to iocb object. ++ * @vport: Pointer to driver virtual port object. ++ * ++ * This function acts as an iocb filter for functions which abort FCP iocbs. ++ * ++ * Return values ++ * -ENODEV, if a null iocb or vport ptr is encountered ++ * -EINVAL, if the iocb is not an FCP I/O, not on the TX cmpl queue, premarked as ++ * driver already started the abort process, or is an abort iocb itself ++ * 0, passes criteria for aborting the FCP I/O iocb ++ **/ ++static int ++lpfc_sli_validate_fcp_iocb_for_abort(struct lpfc_iocbq *iocbq, ++ struct lpfc_vport *vport) ++{ ++ IOCB_t *icmd = NULL; ++ ++ /* No null ptr vports */ ++ if (!iocbq || iocbq->vport != vport) ++ return -ENODEV; ++ ++ /* iocb must be for FCP IO, already exists on the TX cmpl queue, ++ * can't be premarked as driver aborted, nor be an ABORT iocb itself ++ */ ++ icmd = &iocbq->iocb; ++ if (!(iocbq->iocb_flag & LPFC_IO_FCP) || ++ !(iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ) || ++ (iocbq->iocb_flag & LPFC_DRIVER_ABORTED) || ++ (icmd->ulpCommand == CMD_ABORT_XRI_CN || ++ icmd->ulpCommand == CMD_CLOSE_XRI_CN)) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++/** ++ * lpfc_sli_validate_fcp_iocb - validate commands associated with a SCSI target + * @iocbq: Pointer to driver iocb object. + * @vport: Pointer to driver virtual port object. + * @tgt_id: SCSI ID of the target. + * @lun_id: LUN ID of the scsi device. + * @ctx_cmd: LPFC_CTX_LUN/LPFC_CTX_TGT/LPFC_CTX_HOST + * +- * This function acts as an iocb filter for functions which abort or count +- * all FCP iocbs pending on a lun/SCSI target/SCSI host. It will return ++ * This function acts as an iocb filter for validating a lun/SCSI target/SCSI ++ * host. ++ * ++ * It will return + * 0 if the filtering criteria is met for the given iocb and will return + * 1 if the filtering criteria is not met. + * If ctx_cmd == LPFC_CTX_LUN, the function returns 0 only if the +@@ -12515,22 +12554,8 @@ lpfc_sli_validate_fcp_iocb(struct lpfc_i + lpfc_ctx_cmd ctx_cmd) + { + struct lpfc_io_buf *lpfc_cmd; +- IOCB_t *icmd = NULL; + int rc = 1; + +- if (!iocbq || iocbq->vport != vport) +- return rc; +- +- if (!(iocbq->iocb_flag & LPFC_IO_FCP) || +- !(iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ) || +- iocbq->iocb_flag & LPFC_DRIVER_ABORTED) +- return rc; +- +- icmd = &iocbq->iocb; +- if (icmd->ulpCommand == CMD_ABORT_XRI_CN || +- icmd->ulpCommand == CMD_CLOSE_XRI_CN) +- return rc; +- + lpfc_cmd = container_of(iocbq, struct lpfc_io_buf, cur_iocbq); + + if (lpfc_cmd->pCmd == NULL) +@@ -12585,17 +12610,33 @@ lpfc_sli_sum_iocb(struct lpfc_vport *vpo + { + struct lpfc_hba *phba = vport->phba; + struct lpfc_iocbq *iocbq; ++ IOCB_t *icmd = NULL; + int sum, i; ++ unsigned long iflags; + +- spin_lock_irq(&phba->hbalock); ++ spin_lock_irqsave(&phba->hbalock, iflags); + for (i = 1, sum = 0; i <= phba->sli.last_iotag; i++) { + iocbq = phba->sli.iocbq_lookup[i]; + +- if (lpfc_sli_validate_fcp_iocb (iocbq, vport, tgt_id, lun_id, +- ctx_cmd) == 0) ++ if (!iocbq || iocbq->vport != vport) ++ continue; ++ if (!(iocbq->iocb_flag & LPFC_IO_FCP) || ++ !(iocbq->iocb_flag & LPFC_IO_ON_TXCMPLQ)) ++ continue; ++ ++ /* Include counting outstanding aborts */ ++ icmd = &iocbq->iocb; ++ if (icmd->ulpCommand == CMD_ABORT_XRI_CN || ++ icmd->ulpCommand == CMD_CLOSE_XRI_CN) { ++ sum++; ++ continue; ++ } ++ ++ if (lpfc_sli_validate_fcp_iocb(iocbq, vport, tgt_id, lun_id, ++ ctx_cmd) == 0) + sum++; + } +- spin_unlock_irq(&phba->hbalock); ++ spin_unlock_irqrestore(&phba->hbalock, iflags); + + return sum; + } +@@ -12662,7 +12703,11 @@ lpfc_sli_abort_fcp_cmpl(struct lpfc_hba + * + * This function sends an abort command for every SCSI command + * associated with the given virtual port pending on the ring +- * filtered by lpfc_sli_validate_fcp_iocb function. ++ * filtered by lpfc_sli_validate_fcp_iocb_for_abort and then ++ * lpfc_sli_validate_fcp_iocb function. The ordering for validation before ++ * submitting abort iocbs must be lpfc_sli_validate_fcp_iocb_for_abort ++ * followed by lpfc_sli_validate_fcp_iocb. ++ * + * When abort_cmd == LPFC_CTX_LUN, the function sends abort only to the + * FCP iocbs associated with lun specified by tgt_id and lun_id + * parameters +@@ -12694,6 +12739,9 @@ lpfc_sli_abort_iocb(struct lpfc_vport *v + for (i = 1; i <= phba->sli.last_iotag; i++) { + iocbq = phba->sli.iocbq_lookup[i]; + ++ if (lpfc_sli_validate_fcp_iocb_for_abort(iocbq, vport)) ++ continue; ++ + if (lpfc_sli_validate_fcp_iocb(iocbq, vport, tgt_id, lun_id, + abort_cmd) != 0) + continue; +@@ -12726,7 +12774,11 @@ lpfc_sli_abort_iocb(struct lpfc_vport *v + * + * This function sends an abort command for every SCSI command + * associated with the given virtual port pending on the ring +- * filtered by lpfc_sli_validate_fcp_iocb function. ++ * filtered by lpfc_sli_validate_fcp_iocb_for_abort and then ++ * lpfc_sli_validate_fcp_iocb function. The ordering for validation before ++ * submitting abort iocbs must be lpfc_sli_validate_fcp_iocb_for_abort ++ * followed by lpfc_sli_validate_fcp_iocb. ++ * + * When taskmgmt_cmd == LPFC_CTX_LUN, the function sends abort only to the + * FCP iocbs associated with lun specified by tgt_id and lun_id + * parameters +@@ -12764,6 +12816,9 @@ lpfc_sli_abort_taskmgmt(struct lpfc_vpor + for (i = 1; i <= phba->sli.last_iotag; i++) { + iocbq = phba->sli.iocbq_lookup[i]; + ++ if (lpfc_sli_validate_fcp_iocb_for_abort(iocbq, vport)) ++ continue; ++ + if (lpfc_sli_validate_fcp_iocb(iocbq, vport, tgt_id, lun_id, + cmd) != 0) + continue; diff --git a/queue-5.15/scsi-qla2xxx-fix-crash-in-nvme-abort-path.patch b/queue-5.15/scsi-qla2xxx-fix-crash-in-nvme-abort-path.patch new file mode 100644 index 00000000000..c4a48b5901f --- /dev/null +++ b/queue-5.15/scsi-qla2xxx-fix-crash-in-nvme-abort-path.patch @@ -0,0 +1,87 @@ +From e6e22e6cc2962d3f3d71914b47f7fbc454670e8a Mon Sep 17 00:00:00 2001 +From: Arun Easi +Date: Wed, 8 Sep 2021 09:46:16 -0700 +Subject: scsi: qla2xxx: Fix crash in NVMe abort path + +From: Arun Easi + +commit e6e22e6cc2962d3f3d71914b47f7fbc454670e8a upstream. + +System crash was seen when I/O was run against an NVMe target and aborts +were occurring. + +Crash stack is: + + -- relevant crash stack -- + BUG: kernel NULL pointer dereference, address: 0000000000000010 + : + #6 [ffffae1f8666bdd0] page_fault at ffffffffa740122e + [exception RIP: qla_nvme_abort_work+339] + RIP: ffffffffc0f592e3 RSP: ffffae1f8666be80 RFLAGS: 00010297 + RAX: 0000000000000000 RBX: ffff9b581fc8af80 RCX: ffffffffc0f83bd0 + RDX: 0000000000000001 RSI: ffff9b5839c6c7c8 RDI: 0000000008000000 + RBP: ffff9b6832f85000 R8: ffffffffc0f68160 R9: ffffffffc0f70652 + R10: ffffae1f862ffdc8 R11: 0000000000000300 R12: 000000000000010d + R13: 0000000000000000 R14: ffff9b5839cea000 R15: 0ffff9b583fab170 + ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 + #7 [ffffae1f8666be98] process_one_work at ffffffffa6aba184 + #8 [ffffae1f8666bed8] worker_thread at ffffffffa6aba39d + #9 [ffffae1f8666bf10] kthread at ffffffffa6ac06ed + +The crash was due to a stale SRB structure access after it was aborted. +Fix the issue by removing stale access. + +Link: https://lore.kernel.org/r/20210908164622.19240-5-njavali@marvell.com +Fixes: 2cabf10dbbe3 ("scsi: qla2xxx: Fix hang on NVMe command timeouts") +Cc: stable@vger.kernel.org +Reviewed-by: Himanshu Madhani +Signed-off-by: Arun Easi +Signed-off-by: Nilesh Javali +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_nvme.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_nvme.c ++++ b/drivers/scsi/qla2xxx/qla_nvme.c +@@ -228,6 +228,8 @@ static void qla_nvme_abort_work(struct w + fc_port_t *fcport = sp->fcport; + struct qla_hw_data *ha = fcport->vha->hw; + int rval, abts_done_called = 1; ++ bool io_wait_for_abort_done; ++ uint32_t handle; + + ql_dbg(ql_dbg_io, fcport->vha, 0xffff, + "%s called for sp=%p, hndl=%x on fcport=%p desc=%p deleted=%d\n", +@@ -244,12 +246,20 @@ static void qla_nvme_abort_work(struct w + goto out; + } + ++ /* ++ * sp may not be valid after abort_command if return code is either ++ * SUCCESS or ERR_FROM_FW codes, so cache the value here. ++ */ ++ io_wait_for_abort_done = ql2xabts_wait_nvme && ++ QLA_ABTS_WAIT_ENABLED(sp); ++ handle = sp->handle; ++ + rval = ha->isp_ops->abort_command(sp); + + ql_dbg(ql_dbg_io, fcport->vha, 0x212b, + "%s: %s command for sp=%p, handle=%x on fcport=%p rval=%x\n", + __func__, (rval != QLA_SUCCESS) ? "Failed to abort" : "Aborted", +- sp, sp->handle, fcport, rval); ++ sp, handle, fcport, rval); + + /* + * If async tmf is enabled, the abort callback is called only on +@@ -264,7 +274,7 @@ static void qla_nvme_abort_work(struct w + * are waited until ABTS complete. This kref is decreased + * at qla24xx_abort_sp_done function. + */ +- if (abts_done_called && ql2xabts_wait_nvme && QLA_ABTS_WAIT_ENABLED(sp)) ++ if (abts_done_called && io_wait_for_abort_done) + return; + out: + /* kref_get was done before work was schedule. */ diff --git a/queue-5.15/scsi-qla2xxx-fix-kernel-crash-when-accessing-port_speed-sysfs-file.patch b/queue-5.15/scsi-qla2xxx-fix-kernel-crash-when-accessing-port_speed-sysfs-file.patch new file mode 100644 index 00000000000..53b91c64b17 --- /dev/null +++ b/queue-5.15/scsi-qla2xxx-fix-kernel-crash-when-accessing-port_speed-sysfs-file.patch @@ -0,0 +1,105 @@ +From 3ef68d4f0c9e7cb589ae8b70f07d77f528105331 Mon Sep 17 00:00:00 2001 +From: Arun Easi +Date: Wed, 8 Sep 2021 09:46:18 -0700 +Subject: scsi: qla2xxx: Fix kernel crash when accessing port_speed sysfs file + +From: Arun Easi + +commit 3ef68d4f0c9e7cb589ae8b70f07d77f528105331 upstream. + +Kernel crashes when accessing port_speed sysfs file. The issue happens on +a CNA when the local array was accessed beyond bounds. Fix this by changing +the lookup. + +BUG: unable to handle kernel paging request at 0000000000004000 +PGD 0 P4D 0 +Oops: 0000 [#1] SMP PTI +CPU: 15 PID: 455213 Comm: sosreport Kdump: loaded Not tainted +4.18.0-305.7.1.el8_4.x86_64 #1 +RIP: 0010:string_nocheck+0x12/0x70 +Code: 00 00 4c 89 e2 be 20 00 00 00 48 89 ef e8 86 9a 00 00 4c 01 +e3 eb 81 90 49 89 f2 48 89 ce 48 89 f8 48 c1 fe 30 66 85 f6 74 4f <44> 0f b6 0a +45 84 c9 74 46 83 ee 01 41 b8 01 00 00 00 48 8d 7c 37 +RSP: 0018:ffffb5141c1afcf0 EFLAGS: 00010286 +RAX: ffff8bf4009f8000 RBX: ffff8bf4009f9000 RCX: ffff0a00ffffff04 +RDX: 0000000000004000 RSI: ffffffffffffffff RDI: ffff8bf4009f8000 +RBP: 0000000000004000 R08: 0000000000000001 R09: ffffb5141c1afb84 +R10: ffff8bf4009f9000 R11: ffffb5141c1afce6 R12: ffff0a00ffffff04 +R13: ffffffffc08e21aa R14: 0000000000001000 R15: ffffffffc08e21aa +FS: 00007fc4ebfff700(0000) GS:ffff8c717f7c0000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 0000000000004000 CR3: 000000edfdee6006 CR4: 00000000001706e0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +Call Trace: + string+0x40/0x50 + vsnprintf+0x33c/0x520 + scnprintf+0x4d/0x90 + qla2x00_port_speed_show+0xb5/0x100 [qla2xxx] + dev_attr_show+0x1c/0x40 + sysfs_kf_seq_show+0x9b/0x100 + seq_read+0x153/0x410 + vfs_read+0x91/0x140 + ksys_read+0x4f/0xb0 + do_syscall_64+0x5b/0x1a0 + entry_SYSCALL_64_after_hwframe+0x65/0xca + +Link: https://lore.kernel.org/r/20210908164622.19240-7-njavali@marvell.com +Fixes: 4910b524ac9e ("scsi: qla2xxx: Add support for setting port speed") +Cc: stable@vger.kernel.org +Reviewed-by: Himanshu Madhani +Signed-off-by: Arun Easi +Signed-off-by: Nilesh Javali +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_attr.c | 24 ++++++++++++++++++++++-- + 1 file changed, 22 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_attr.c ++++ b/drivers/scsi/qla2xxx/qla_attr.c +@@ -1868,6 +1868,18 @@ qla2x00_port_speed_store(struct device * + return strlen(buf); + } + ++static const struct { ++ u16 rate; ++ char *str; ++} port_speed_str[] = { ++ { PORT_SPEED_4GB, "4" }, ++ { PORT_SPEED_8GB, "8" }, ++ { PORT_SPEED_16GB, "16" }, ++ { PORT_SPEED_32GB, "32" }, ++ { PORT_SPEED_64GB, "64" }, ++ { PORT_SPEED_10GB, "10" }, ++}; ++ + static ssize_t + qla2x00_port_speed_show(struct device *dev, struct device_attribute *attr, + char *buf) +@@ -1875,7 +1887,8 @@ qla2x00_port_speed_show(struct device *d + struct scsi_qla_host *vha = shost_priv(dev_to_shost(dev)); + struct qla_hw_data *ha = vha->hw; + ssize_t rval; +- char *spd[7] = {"0", "0", "0", "4", "8", "16", "32"}; ++ u16 i; ++ char *speed = "Unknown"; + + rval = qla2x00_get_data_rate(vha); + if (rval != QLA_SUCCESS) { +@@ -1884,7 +1897,14 @@ qla2x00_port_speed_show(struct device *d + return -EINVAL; + } + +- return scnprintf(buf, PAGE_SIZE, "%s\n", spd[ha->link_data_rate]); ++ for (i = 0; i < ARRAY_SIZE(port_speed_str); i++) { ++ if (port_speed_str[i].rate != ha->link_data_rate) ++ continue; ++ speed = port_speed_str[i].str; ++ break; ++ } ++ ++ return scnprintf(buf, PAGE_SIZE, "%s\n", speed); + } + + static ssize_t diff --git a/queue-5.15/scsi-qla2xxx-fix-use-after-free-in-eh_abort-path.patch b/queue-5.15/scsi-qla2xxx-fix-use-after-free-in-eh_abort-path.patch new file mode 100644 index 00000000000..cc8c6a12c28 --- /dev/null +++ b/queue-5.15/scsi-qla2xxx-fix-use-after-free-in-eh_abort-path.patch @@ -0,0 +1,84 @@ +From 3d33b303d4f3b74a71bede5639ebba3cfd2a2b4d Mon Sep 17 00:00:00 2001 +From: Quinn Tran +Date: Wed, 8 Sep 2021 09:46:21 -0700 +Subject: scsi: qla2xxx: Fix use after free in eh_abort path + +From: Quinn Tran + +commit 3d33b303d4f3b74a71bede5639ebba3cfd2a2b4d upstream. + +In eh_abort path driver prematurely exits the call to upper layer. Check +whether command is aborted / completed by firmware before exiting the call. + +9 [ffff8b1ebf803c00] page_fault at ffffffffb0389778 + [exception RIP: qla2x00_status_entry+0x48d] + RIP: ffffffffc04fa62d RSP: ffff8b1ebf803cb0 RFLAGS: 00010082 + RAX: 00000000ffffffff RBX: 00000000000e0000 RCX: 0000000000000000 + RDX: 0000000000000000 RSI: 00000000000013d8 RDI: fffff3253db78440 + RBP: ffff8b1ebf803dd0 R8: ffff8b1ebcd9b0c0 R9: 0000000000000000 + R10: ffff8b1e38a30808 R11: 0000000000001000 R12: 00000000000003e9 + R13: 0000000000000000 R14: ffff8b1ebcd9d740 R15: 0000000000000028 + ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 +10 [ffff8b1ebf803cb0] enqueue_entity at ffffffffafce708f +11 [ffff8b1ebf803d00] enqueue_task_fair at ffffffffafce7b88 +12 [ffff8b1ebf803dd8] qla24xx_process_response_queue at ffffffffc04fc9a6 +[qla2xxx] +13 [ffff8b1ebf803e78] qla24xx_msix_rsp_q at ffffffffc04ff01b [qla2xxx] +14 [ffff8b1ebf803eb0] __handle_irq_event_percpu at ffffffffafd50714 + +Link: https://lore.kernel.org/r/20210908164622.19240-10-njavali@marvell.com +Fixes: f45bca8c5052 ("scsi: qla2xxx: Fix double scsi_done for abort path") +Cc: stable@vger.kernel.org +Reviewed-by: Himanshu Madhani +Co-developed-by: David Jeffery +Signed-off-by: David Jeffery +Co-developed-by: Laurence Oberman +Signed-off-by: Laurence Oberman +Signed-off-by: Quinn Tran +Signed-off-by: Nilesh Javali +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qla2xxx/qla_os.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -1258,6 +1258,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) + uint32_t ratov_j; + struct qla_qpair *qpair; + unsigned long flags; ++ int fast_fail_status = SUCCESS; + + if (qla2x00_isp_reg_stat(ha)) { + ql_log(ql_log_info, vha, 0x8042, +@@ -1266,9 +1267,10 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) + return FAILED; + } + ++ /* Save any FAST_IO_FAIL value to return later if abort succeeds */ + ret = fc_block_scsi_eh(cmd); + if (ret != 0) +- return ret; ++ fast_fail_status = ret; + + sp = scsi_cmd_priv(cmd); + qpair = sp->qpair; +@@ -1276,7 +1278,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) + vha->cmd_timeout_cnt++; + + if ((sp->fcport && sp->fcport->deleted) || !qpair) +- return SUCCESS; ++ return fast_fail_status != SUCCESS ? fast_fail_status : FAILED; + + spin_lock_irqsave(qpair->qp_lock_ptr, flags); + sp->comp = ∁ +@@ -1311,7 +1313,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) + __func__, ha->r_a_tov/10); + ret = FAILED; + } else { +- ret = SUCCESS; ++ ret = fast_fail_status; + } + break; + default: diff --git a/queue-5.15/scsi-scsi_ioctl-validate-command-size.patch b/queue-5.15/scsi-scsi_ioctl-validate-command-size.patch new file mode 100644 index 00000000000..047eae396af --- /dev/null +++ b/queue-5.15/scsi-scsi_ioctl-validate-command-size.patch @@ -0,0 +1,38 @@ +From 20aaef52eb08f1d987d46ad26edb8f142f74d83a Mon Sep 17 00:00:00 2001 +From: Tadeusz Struk +Date: Wed, 3 Nov 2021 10:06:58 -0700 +Subject: scsi: scsi_ioctl: Validate command size + +From: Tadeusz Struk + +commit 20aaef52eb08f1d987d46ad26edb8f142f74d83a upstream. + +Need to make sure the command size is valid before copying the command from +user space. + +Link: https://lore.kernel.org/r/20211103170659.22151-1-tadeusz.struk@linaro.org +Cc: Bart Van Assche +Cc: Christoph Hellwig +Cc: James E.J. Bottomley +Cc: Martin K. Petersen +Cc: +Cc: +Cc: # 5.15, 5.14, 5.10 +Signed-off-by: Tadeusz Struk +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/scsi_ioctl.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/scsi/scsi_ioctl.c ++++ b/drivers/scsi/scsi_ioctl.c +@@ -347,6 +347,8 @@ static int scsi_fill_sghdr_rq(struct scs + { + struct scsi_request *req = scsi_req(rq); + ++ if (hdr->cmd_len < 6) ++ return -EMSGSIZE; + if (copy_from_user(req->cmd, hdr->cmdp, hdr->cmd_len)) + return -EFAULT; + if (!scsi_cmd_allowed(req->cmd, mode)) diff --git a/queue-5.15/series b/queue-5.15/series index ab7138b0e5c..645d5a94550 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -1,2 +1,17 @@ xhci-fix-usb-3.1-enumeration-issues-by-increasing-roothub-power-on-good-delay.patch usb-xhci-enable-runtime-pm-by-default-on-amd-yellow-carp-platform.patch +input-iforce-fix-control-message-timeout.patch +input-elantench-fix-misreporting-trackpoint-coordinates.patch +input-i8042-add-quirk-for-fujitsu-lifebook-t725.patch +libata-fix-read-log-timeout-value.patch +ocfs2-fix-data-corruption-on-truncate.patch +scsi-scsi_ioctl-validate-command-size.patch +scsi-core-avoid-leaving-shost-last_reset-with-stale-value-if-eh-does-not-run.patch +scsi-core-remove-command-size-deduction-from-scsi_setup_scsi_cmnd.patch +scsi-lpfc-don-t-release-final-kref-on-fport-node-while-abts-outstanding.patch +scsi-lpfc-fix-fcp-i-o-flush-functionality-for-tmf-routines.patch +scsi-qla2xxx-fix-crash-in-nvme-abort-path.patch +scsi-qla2xxx-fix-kernel-crash-when-accessing-port_speed-sysfs-file.patch +scsi-qla2xxx-fix-use-after-free-in-eh_abort-path.patch +ce-gf100-fix-incorrect-ce0-address-calculation-on-some-gpus.patch +char-xillybus-fix-msg_ep-uaf-in-xillyusb_probe.patch