From: Greg Kroah-Hartman Date: Sun, 13 Aug 2023 20:46:05 +0000 (+0200) Subject: 5.15-stable patches X-Git-Tag: v4.14.323~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b1bded960297e723e4cc9c007ad07fe8d54f818b;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: alpha-remove-__init-annotation-from-exported-page_is_ram.patch sch_netem-fix-issues-in-netem_change-vs-get_dist_table.patch scsi-53c700-check-that-command-slot-is-not-null.patch scsi-core-fix-legacy-proc-parsing-buffer-overflow.patch scsi-core-fix-possible-memory-leak-if-device_add-fails.patch scsi-fnic-replace-return-codes-in-fnic_clean_pending_aborts.patch scsi-qedf-fix-firmware-halt-over-suspend-and-resume.patch scsi-qedi-fix-firmware-halt-over-suspend-and-resume.patch scsi-snic-fix-possible-memory-leak-if-device_add-fails.patch scsi-storvsc-fix-handling-of-virtual-fibre-channel-timeouts.patch tick-detect-and-fix-jiffies-update-stall.patch timers-nohz-last-resort-update-jiffies-on-nohz_full-irq-entry.patch timers-nohz-switch-to-oneshot_stopped-in-the-low-res-handler-when-the-tick-is-stopped.patch --- diff --git a/queue-5.15/alpha-remove-__init-annotation-from-exported-page_is_ram.patch b/queue-5.15/alpha-remove-__init-annotation-from-exported-page_is_ram.patch new file mode 100644 index 00000000000..73f9cf50667 --- /dev/null +++ b/queue-5.15/alpha-remove-__init-annotation-from-exported-page_is_ram.patch @@ -0,0 +1,40 @@ +From 6ccbd7fd474674654019a20177c943359469103a Mon Sep 17 00:00:00 2001 +From: Masahiro Yamada +Date: Sat, 29 Jul 2023 16:42:23 +0900 +Subject: alpha: remove __init annotation from exported page_is_ram() + +From: Masahiro Yamada + +commit 6ccbd7fd474674654019a20177c943359469103a upstream. + +EXPORT_SYMBOL and __init is a bad combination because the .init.text +section is freed up after the initialization. + +Commit c5a130325f13 ("ACPI/APEI: Add parameter check before error +injection") exported page_is_ram(), hence the __init annotation should +be removed. + +This fixes the modpost warning in ARCH=alpha builds: + + WARNING: modpost: vmlinux: page_is_ram: EXPORT_SYMBOL used for init symbol. Remove __init or EXPORT_SYMBOL. + +Fixes: c5a130325f13 ("ACPI/APEI: Add parameter check before error injection") +Signed-off-by: Masahiro Yamada +Reviewed-by: Randy Dunlap +Signed-off-by: Greg Kroah-Hartman +--- + arch/alpha/kernel/setup.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/arch/alpha/kernel/setup.c ++++ b/arch/alpha/kernel/setup.c +@@ -385,8 +385,7 @@ setup_memory(void *kernel_end) + #endif /* CONFIG_BLK_DEV_INITRD */ + } + +-int __init +-page_is_ram(unsigned long pfn) ++int page_is_ram(unsigned long pfn) + { + struct memclust_struct * cluster; + struct memdesc_struct * memdesc; diff --git a/queue-5.15/sch_netem-fix-issues-in-netem_change-vs-get_dist_table.patch b/queue-5.15/sch_netem-fix-issues-in-netem_change-vs-get_dist_table.patch new file mode 100644 index 00000000000..e062fbafe3c --- /dev/null +++ b/queue-5.15/sch_netem-fix-issues-in-netem_change-vs-get_dist_table.patch @@ -0,0 +1,148 @@ +From 11b73313c12403f617b47752db0ab3deef201af7 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 22 Jun 2023 18:15:03 +0000 +Subject: sch_netem: fix issues in netem_change() vs get_dist_table() + +From: Eric Dumazet + +commit 11b73313c12403f617b47752db0ab3deef201af7 upstream. + +In blamed commit, I missed that get_dist_table() was allocating +memory using GFP_KERNEL, and acquiring qdisc lock to perform +the swap of newly allocated table with current one. + +In this patch, get_dist_table() is allocating memory and +copy user data before we acquire the qdisc lock. + +Then we perform swap operations while being protected by the lock. + +Note that after this patch netem_change() no longer can do partial changes. +If an error is returned, qdisc conf is left unchanged. + +Fixes: 2174a08db80d ("sch_netem: acquire qdisc lock in netem_change()") +Reported-by: syzbot +Signed-off-by: Eric Dumazet +Cc: Stephen Hemminger +Acked-by: Jamal Hadi Salim +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/20230622181503.2327695-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Fedor Pchelkin +Signed-off-by: Greg Kroah-Hartman +--- + net/sched/sch_netem.c | 59 +++++++++++++++++++++----------------------------- + 1 file changed, 25 insertions(+), 34 deletions(-) + +--- a/net/sched/sch_netem.c ++++ b/net/sched/sch_netem.c +@@ -773,12 +773,10 @@ static void dist_free(struct disttable * + * signed 16 bit values. + */ + +-static int get_dist_table(struct Qdisc *sch, struct disttable **tbl, +- const struct nlattr *attr) ++static int get_dist_table(struct disttable **tbl, const struct nlattr *attr) + { + size_t n = nla_len(attr)/sizeof(__s16); + const __s16 *data = nla_data(attr); +- spinlock_t *root_lock; + struct disttable *d; + int i; + +@@ -793,13 +791,7 @@ static int get_dist_table(struct Qdisc * + for (i = 0; i < n; i++) + d->table[i] = data[i]; + +- root_lock = qdisc_root_sleeping_lock(sch); +- +- spin_lock_bh(root_lock); +- swap(*tbl, d); +- spin_unlock_bh(root_lock); +- +- dist_free(d); ++ *tbl = d; + return 0; + } + +@@ -956,6 +948,8 @@ static int netem_change(struct Qdisc *sc + { + struct netem_sched_data *q = qdisc_priv(sch); + struct nlattr *tb[TCA_NETEM_MAX + 1]; ++ struct disttable *delay_dist = NULL; ++ struct disttable *slot_dist = NULL; + struct tc_netem_qopt *qopt; + struct clgstate old_clg; + int old_loss_model = CLG_RANDOM; +@@ -969,6 +963,18 @@ static int netem_change(struct Qdisc *sc + if (ret < 0) + return ret; + ++ if (tb[TCA_NETEM_DELAY_DIST]) { ++ ret = get_dist_table(&delay_dist, tb[TCA_NETEM_DELAY_DIST]); ++ if (ret) ++ goto table_free; ++ } ++ ++ if (tb[TCA_NETEM_SLOT_DIST]) { ++ ret = get_dist_table(&slot_dist, tb[TCA_NETEM_SLOT_DIST]); ++ if (ret) ++ goto table_free; ++ } ++ + sch_tree_lock(sch); + /* backup q->clg and q->loss_model */ + old_clg = q->clg; +@@ -978,26 +984,17 @@ static int netem_change(struct Qdisc *sc + ret = get_loss_clg(q, tb[TCA_NETEM_LOSS]); + if (ret) { + q->loss_model = old_loss_model; ++ q->clg = old_clg; + goto unlock; + } + } else { + q->loss_model = CLG_RANDOM; + } + +- if (tb[TCA_NETEM_DELAY_DIST]) { +- ret = get_dist_table(sch, &q->delay_dist, +- tb[TCA_NETEM_DELAY_DIST]); +- if (ret) +- goto get_table_failure; +- } +- +- if (tb[TCA_NETEM_SLOT_DIST]) { +- ret = get_dist_table(sch, &q->slot_dist, +- tb[TCA_NETEM_SLOT_DIST]); +- if (ret) +- goto get_table_failure; +- } +- ++ if (delay_dist) ++ swap(q->delay_dist, delay_dist); ++ if (slot_dist) ++ swap(q->slot_dist, slot_dist); + sch->limit = qopt->limit; + + q->latency = PSCHED_TICKS2NS(qopt->latency); +@@ -1047,17 +1044,11 @@ static int netem_change(struct Qdisc *sc + + unlock: + sch_tree_unlock(sch); +- return ret; + +-get_table_failure: +- /* recover clg and loss_model, in case of +- * q->clg and q->loss_model were modified +- * in get_loss_clg() +- */ +- q->clg = old_clg; +- q->loss_model = old_loss_model; +- +- goto unlock; ++table_free: ++ dist_free(delay_dist); ++ dist_free(slot_dist); ++ return ret; + } + + static int netem_init(struct Qdisc *sch, struct nlattr *opt, diff --git a/queue-5.15/scsi-53c700-check-that-command-slot-is-not-null.patch b/queue-5.15/scsi-53c700-check-that-command-slot-is-not-null.patch new file mode 100644 index 00000000000..439d76b2c04 --- /dev/null +++ b/queue-5.15/scsi-53c700-check-that-command-slot-is-not-null.patch @@ -0,0 +1,36 @@ +From 8366d1f1249a0d0bba41d0bd1298d63e5d34c7f7 Mon Sep 17 00:00:00 2001 +From: Alexandra Diupina +Date: Fri, 28 Jul 2023 15:35:21 +0300 +Subject: scsi: 53c700: Check that command slot is not NULL + +From: Alexandra Diupina + +commit 8366d1f1249a0d0bba41d0bd1298d63e5d34c7f7 upstream. + +Add a check for the command slot value to avoid dereferencing a NULL +pointer. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Co-developed-by: Vladimir Telezhnikov +Signed-off-by: Vladimir Telezhnikov +Signed-off-by: Alexandra Diupina +Link: https://lore.kernel.org/r/20230728123521.18293-1-adiupina@astralinux.ru +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/53c700.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/53c700.c ++++ b/drivers/scsi/53c700.c +@@ -1599,7 +1599,7 @@ NCR_700_intr(int irq, void *dev_id) + printk("scsi%d (%d:%d) PHASE MISMATCH IN SEND MESSAGE %d remain, return %p[%04x], phase %s\n", host->host_no, pun, lun, count, (void *)temp, temp - hostdata->pScript, sbcl_to_string(NCR_700_readb(host, SBCL_REG))); + #endif + resume_offset = hostdata->pScript + Ent_SendMessagePhaseMismatch; +- } else if(dsp >= to32bit(&slot->pSG[0].ins) && ++ } else if (slot && dsp >= to32bit(&slot->pSG[0].ins) && + dsp <= to32bit(&slot->pSG[NCR_700_SG_SEGMENTS].ins)) { + int data_transfer = NCR_700_readl(host, DBC_REG) & 0xffffff; + int SGcount = (dsp - to32bit(&slot->pSG[0].ins))/sizeof(struct NCR_700_SG_List); diff --git a/queue-5.15/scsi-core-fix-legacy-proc-parsing-buffer-overflow.patch b/queue-5.15/scsi-core-fix-legacy-proc-parsing-buffer-overflow.patch new file mode 100644 index 00000000000..e4ad8d3a3bd --- /dev/null +++ b/queue-5.15/scsi-core-fix-legacy-proc-parsing-buffer-overflow.patch @@ -0,0 +1,106 @@ +From 9426d3cef5000824e5f24f80ed5f42fb935f2488 Mon Sep 17 00:00:00 2001 +From: Tony Battersby +Date: Mon, 24 Jul 2023 14:25:40 -0400 +Subject: scsi: core: Fix legacy /proc parsing buffer overflow + +From: Tony Battersby + +commit 9426d3cef5000824e5f24f80ed5f42fb935f2488 upstream. + +(lightly modified commit message mostly by Linus Torvalds) + +The parsing code for /proc/scsi/scsi is disgusting and broken. We should +have just used 'sscanf()' or something simple like that, but the logic may +actually predate our kernel sscanf library routine for all I know. It +certainly predates both git and BK histories. + +And we can't change it to be something sane like that now, because the +string matching at the start is done case-insensitively, and the separator +parsing between numbers isn't done at all, so *any* separator will work, +including a possible terminating NUL character. + +This interface is root-only, and entirely for legacy use, so there is +absolutely no point in trying to tighten up the parsing. Because any +separator has traditionally worked, it's entirely possible that people have +used random characters rather than the suggested space. + +So don't bother to try to pretty it up, and let's just make a minimal patch +that can be back-ported and we can forget about this whole sorry thing for +another two decades. + +Just make it at least not read past the end of the supplied data. + +Link: https://lore.kernel.org/linux-scsi/b570f5fe-cb7c-863a-6ed9-f6774c219b88@cybernetics.com/ +Cc: Linus Torvalds +Cc: Martin K Petersen +Cc: James Bottomley +Cc: Willy Tarreau +Cc: stable@kernel.org +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Tony Battersby +Signed-off-by: Martin K Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/scsi_proc.c | 30 +++++++++++++++++------------- + 1 file changed, 17 insertions(+), 13 deletions(-) + +--- a/drivers/scsi/scsi_proc.c ++++ b/drivers/scsi/scsi_proc.c +@@ -311,7 +311,7 @@ static ssize_t proc_scsi_write(struct fi + size_t length, loff_t *ppos) + { + int host, channel, id, lun; +- char *buffer, *p; ++ char *buffer, *end, *p; + int err; + + if (!buf || length > PAGE_SIZE) +@@ -326,10 +326,14 @@ static ssize_t proc_scsi_write(struct fi + goto out; + + err = -EINVAL; +- if (length < PAGE_SIZE) +- buffer[length] = '\0'; +- else if (buffer[PAGE_SIZE-1]) +- goto out; ++ if (length < PAGE_SIZE) { ++ end = buffer + length; ++ *end = '\0'; ++ } else { ++ end = buffer + PAGE_SIZE - 1; ++ if (*end) ++ goto out; ++ } + + /* + * Usage: echo "scsi add-single-device 0 1 2 3" >/proc/scsi/scsi +@@ -338,10 +342,10 @@ static ssize_t proc_scsi_write(struct fi + if (!strncmp("scsi add-single-device", buffer, 22)) { + p = buffer + 23; + +- host = simple_strtoul(p, &p, 0); +- channel = simple_strtoul(p + 1, &p, 0); +- id = simple_strtoul(p + 1, &p, 0); +- lun = simple_strtoul(p + 1, &p, 0); ++ host = (p < end) ? simple_strtoul(p, &p, 0) : 0; ++ channel = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; ++ id = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; ++ lun = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; + + err = scsi_add_single_device(host, channel, id, lun); + +@@ -352,10 +356,10 @@ static ssize_t proc_scsi_write(struct fi + } else if (!strncmp("scsi remove-single-device", buffer, 25)) { + p = buffer + 26; + +- host = simple_strtoul(p, &p, 0); +- channel = simple_strtoul(p + 1, &p, 0); +- id = simple_strtoul(p + 1, &p, 0); +- lun = simple_strtoul(p + 1, &p, 0); ++ host = (p < end) ? simple_strtoul(p, &p, 0) : 0; ++ channel = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; ++ id = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; ++ lun = (p + 1 < end) ? simple_strtoul(p + 1, &p, 0) : 0; + + err = scsi_remove_single_device(host, channel, id, lun); + } diff --git a/queue-5.15/scsi-core-fix-possible-memory-leak-if-device_add-fails.patch b/queue-5.15/scsi-core-fix-possible-memory-leak-if-device_add-fails.patch new file mode 100644 index 00000000000..eadcc32886b --- /dev/null +++ b/queue-5.15/scsi-core-fix-possible-memory-leak-if-device_add-fails.patch @@ -0,0 +1,34 @@ +From 04b5b5cb0136ce970333a9c6cec7e46adba1ea3a Mon Sep 17 00:00:00 2001 +From: Zhu Wang +Date: Thu, 3 Aug 2023 10:02:30 +0800 +Subject: scsi: core: Fix possible memory leak if device_add() fails + +From: Zhu Wang + +commit 04b5b5cb0136ce970333a9c6cec7e46adba1ea3a upstream. + +If device_add() returns error, the name allocated by dev_set_name() needs +be freed. As the comment of device_add() says, put_device() should be used +to decrease the reference count in the error path. So fix this by calling +put_device(), then the name can be freed in kobject_cleanp(). + +Fixes: ee959b00c335 ("SCSI: convert struct class_device to struct device") +Signed-off-by: Zhu Wang +Link: https://lore.kernel.org/r/20230803020230.226903-1-wangzhu9@huawei.com +Reviewed-by: Bart Van Assche +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/raid_class.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/scsi/raid_class.c ++++ b/drivers/scsi/raid_class.c +@@ -248,6 +248,7 @@ int raid_component_add(struct raid_templ + return 0; + + err_out: ++ put_device(&rc->dev); + list_del(&rc->node); + rd->component_count--; + put_device(component_dev); diff --git a/queue-5.15/scsi-fnic-replace-return-codes-in-fnic_clean_pending_aborts.patch b/queue-5.15/scsi-fnic-replace-return-codes-in-fnic_clean_pending_aborts.patch new file mode 100644 index 00000000000..33a3d16479e --- /dev/null +++ b/queue-5.15/scsi-fnic-replace-return-codes-in-fnic_clean_pending_aborts.patch @@ -0,0 +1,48 @@ +From 5a43b07a87835660f91d88a4db11abfea8c523b7 Mon Sep 17 00:00:00 2001 +From: Karan Tilak Kumar +Date: Thu, 27 Jul 2023 12:39:19 -0700 +Subject: scsi: fnic: Replace return codes in fnic_clean_pending_aborts() + +From: Karan Tilak Kumar + +commit 5a43b07a87835660f91d88a4db11abfea8c523b7 upstream. + +fnic_clean_pending_aborts() was returning a non-zero value irrespective of +failure or success. This caused the caller of this function to assume that +the device reset had failed, even though it would succeed in most cases. As +a consequence, a successful device reset would escalate to host reset. + +Reviewed-by: Sesidhar Baddela +Tested-by: Karan Tilak Kumar +Signed-off-by: Karan Tilak Kumar +Link: https://lore.kernel.org/r/20230727193919.2519-1-kartilak@cisco.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/fnic/fnic_scsi.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/fnic/fnic_scsi.c ++++ b/drivers/scsi/fnic/fnic_scsi.c +@@ -2172,7 +2172,7 @@ static int fnic_clean_pending_aborts(str + bool new_sc) + + { +- int ret = SUCCESS; ++ int ret = 0; + struct fnic_pending_aborts_iter_data iter_data = { + .fnic = fnic, + .lun_dev = lr_sc->device, +@@ -2192,9 +2192,11 @@ static int fnic_clean_pending_aborts(str + + /* walk again to check, if IOs are still pending in fw */ + if (fnic_is_abts_pending(fnic, lr_sc)) +- ret = FAILED; ++ ret = 1; + + clean_pending_aborts_end: ++ FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, ++ "%s: exit status: %d\n", __func__, ret); + return ret; + } + diff --git a/queue-5.15/scsi-qedf-fix-firmware-halt-over-suspend-and-resume.patch b/queue-5.15/scsi-qedf-fix-firmware-halt-over-suspend-and-resume.patch new file mode 100644 index 00000000000..cf20c98074b --- /dev/null +++ b/queue-5.15/scsi-qedf-fix-firmware-halt-over-suspend-and-resume.patch @@ -0,0 +1,71 @@ +From ef222f551e7c4e2008fc442ffc9edcd1a7fd8f63 Mon Sep 17 00:00:00 2001 +From: Nilesh Javali +Date: Mon, 7 Aug 2023 15:07:24 +0530 +Subject: scsi: qedf: Fix firmware halt over suspend and resume + +From: Nilesh Javali + +commit ef222f551e7c4e2008fc442ffc9edcd1a7fd8f63 upstream. + +While performing certain power-off sequences, PCI drivers are called to +suspend and resume their underlying devices through PCI PM (power +management) interface. However the hardware does not support PCI PM +suspend/resume operations so system wide suspend/resume leads to bad MFW +(management firmware) state which causes various follow-up errors in driver +when communicating with the device/firmware. + +To fix this driver implements PCI PM suspend handler to indicate +unsupported operation to the PCI subsystem explicitly, thus avoiding system +to go into suspended/standby mode. + +Fixes: 61d8658b4a43 ("scsi: qedf: Add QLogic FastLinQ offload FCoE driver framework.") +Signed-off-by: Saurav Kashyap +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20230807093725.46829-1-njavali@marvell.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qedf/qedf_main.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/drivers/scsi/qedf/qedf_main.c ++++ b/drivers/scsi/qedf/qedf_main.c +@@ -31,6 +31,7 @@ static void qedf_remove(struct pci_dev * + static void qedf_shutdown(struct pci_dev *pdev); + static void qedf_schedule_recovery_handler(void *dev); + static void qedf_recovery_handler(struct work_struct *work); ++static int qedf_suspend(struct pci_dev *pdev, pm_message_t state); + + /* + * Driver module parameters. +@@ -3276,6 +3277,7 @@ static struct pci_driver qedf_pci_driver + .probe = qedf_probe, + .remove = qedf_remove, + .shutdown = qedf_shutdown, ++ .suspend = qedf_suspend, + }; + + static int __qedf_probe(struct pci_dev *pdev, int mode) +@@ -4005,6 +4007,22 @@ static void qedf_shutdown(struct pci_dev + __qedf_remove(pdev, QEDF_MODE_NORMAL); + } + ++static int qedf_suspend(struct pci_dev *pdev, pm_message_t state) ++{ ++ struct qedf_ctx *qedf; ++ ++ if (!pdev) { ++ QEDF_ERR(NULL, "pdev is NULL.\n"); ++ return -ENODEV; ++ } ++ ++ qedf = pci_get_drvdata(pdev); ++ ++ QEDF_ERR(&qedf->dbg_ctx, "%s: Device does not support suspend operation\n", __func__); ++ ++ return -EPERM; ++} ++ + /* + * Recovery handler code + */ diff --git a/queue-5.15/scsi-qedi-fix-firmware-halt-over-suspend-and-resume.patch b/queue-5.15/scsi-qedi-fix-firmware-halt-over-suspend-and-resume.patch new file mode 100644 index 00000000000..2cad62cb3ab --- /dev/null +++ b/queue-5.15/scsi-qedi-fix-firmware-halt-over-suspend-and-resume.patch @@ -0,0 +1,70 @@ +From 1516ee035df32115197cd93ae3619dba7b020986 Mon Sep 17 00:00:00 2001 +From: Nilesh Javali +Date: Mon, 7 Aug 2023 15:07:25 +0530 +Subject: scsi: qedi: Fix firmware halt over suspend and resume + +From: Nilesh Javali + +commit 1516ee035df32115197cd93ae3619dba7b020986 upstream. + +While performing certain power-off sequences, PCI drivers are called to +suspend and resume their underlying devices through PCI PM (power +management) interface. However the hardware does not support PCI PM +suspend/resume operations so system wide suspend/resume leads to bad MFW +(management firmware) state which causes various follow-up errors in driver +when communicating with the device/firmware. + +To fix this driver implements PCI PM suspend handler to indicate +unsupported operation to the PCI subsystem explicitly, thus avoiding system +to go into suspended/standby mode. + +Fixes: ace7f46ba5fd ("scsi: qedi: Add QLogic FastLinQ offload iSCSI driver framework.") +Signed-off-by: Nilesh Javali +Link: https://lore.kernel.org/r/20230807093725.46829-2-njavali@marvell.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/qedi/qedi_main.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/drivers/scsi/qedi/qedi_main.c ++++ b/drivers/scsi/qedi/qedi_main.c +@@ -69,6 +69,7 @@ static struct nvm_iscsi_block *qedi_get_ + static void qedi_recovery_handler(struct work_struct *work); + static void qedi_schedule_hw_err_handler(void *dev, + enum qed_hw_err_type err_type); ++static int qedi_suspend(struct pci_dev *pdev, pm_message_t state); + + static int qedi_iscsi_event_cb(void *context, u8 fw_event_code, void *fw_handle) + { +@@ -2515,6 +2516,22 @@ static void qedi_shutdown(struct pci_dev + __qedi_remove(pdev, QEDI_MODE_SHUTDOWN); + } + ++static int qedi_suspend(struct pci_dev *pdev, pm_message_t state) ++{ ++ struct qedi_ctx *qedi; ++ ++ if (!pdev) { ++ QEDI_ERR(NULL, "pdev is NULL.\n"); ++ return -ENODEV; ++ } ++ ++ qedi = pci_get_drvdata(pdev); ++ ++ QEDI_ERR(&qedi->dbg_ctx, "%s: Device does not support suspend operation\n", __func__); ++ ++ return -EPERM; ++} ++ + static int __qedi_probe(struct pci_dev *pdev, int mode) + { + struct qedi_ctx *qedi; +@@ -2873,6 +2890,7 @@ static struct pci_driver qedi_pci_driver + .remove = qedi_remove, + .shutdown = qedi_shutdown, + .err_handler = &qedi_err_handler, ++ .suspend = qedi_suspend, + }; + + static int __init qedi_init(void) diff --git a/queue-5.15/scsi-snic-fix-possible-memory-leak-if-device_add-fails.patch b/queue-5.15/scsi-snic-fix-possible-memory-leak-if-device_add-fails.patch new file mode 100644 index 00000000000..514c88e72a7 --- /dev/null +++ b/queue-5.15/scsi-snic-fix-possible-memory-leak-if-device_add-fails.patch @@ -0,0 +1,34 @@ +From 41320b18a0e0dfb236dba4edb9be12dba1878156 Mon Sep 17 00:00:00 2001 +From: Zhu Wang +Date: Tue, 1 Aug 2023 19:14:21 +0800 +Subject: scsi: snic: Fix possible memory leak if device_add() fails + +From: Zhu Wang + +commit 41320b18a0e0dfb236dba4edb9be12dba1878156 upstream. + +If device_add() returns error, the name allocated by dev_set_name() needs +be freed. As the comment of device_add() says, put_device() should be used +to give up the reference in the error path. So fix this by calling +put_device(), then the name can be freed in kobject_cleanp(). + +Fixes: c8806b6c9e82 ("snic: driver for Cisco SCSI HBA") +Signed-off-by: Zhu Wang +Acked-by: Narsimhulu Musini +Link: https://lore.kernel.org/r/20230801111421.63651-1-wangzhu9@huawei.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/snic/snic_disc.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/scsi/snic/snic_disc.c ++++ b/drivers/scsi/snic/snic_disc.c +@@ -317,6 +317,7 @@ snic_tgt_create(struct snic *snic, struc + "Snic Tgt: device_add, with err = %d\n", + ret); + ++ put_device(&tgt->dev); + put_device(&snic->shost->shost_gendev); + spin_lock_irqsave(snic->shost->host_lock, flags); + list_del(&tgt->list); diff --git a/queue-5.15/scsi-storvsc-fix-handling-of-virtual-fibre-channel-timeouts.patch b/queue-5.15/scsi-storvsc-fix-handling-of-virtual-fibre-channel-timeouts.patch new file mode 100644 index 00000000000..592b847aa61 --- /dev/null +++ b/queue-5.15/scsi-storvsc-fix-handling-of-virtual-fibre-channel-timeouts.patch @@ -0,0 +1,62 @@ +From 175544ad48cbf56affeef2a679c6a4d4fb1e2881 Mon Sep 17 00:00:00 2001 +From: Michael Kelley +Date: Fri, 28 Jul 2023 21:59:24 -0700 +Subject: scsi: storvsc: Fix handling of virtual Fibre Channel timeouts + +From: Michael Kelley + +commit 175544ad48cbf56affeef2a679c6a4d4fb1e2881 upstream. + +Hyper-V provides the ability to connect Fibre Channel LUNs to the host +system and present them in a guest VM as a SCSI device. I/O to the vFC +device is handled by the storvsc driver. The storvsc driver includes a +partial integration with the FC transport implemented in the generic +portion of the Linux SCSI subsystem so that FC attributes can be displayed +in /sys. However, the partial integration means that some aspects of vFC +don't work properly. Unfortunately, a full and correct integration isn't +practical because of limitations in what Hyper-V provides to the guest. + +In particular, in the context of Hyper-V storvsc, the FC transport timeout +function fc_eh_timed_out() causes a kernel panic because it can't find the +rport and dereferences a NULL pointer. The original patch that added the +call from storvsc_eh_timed_out() to fc_eh_timed_out() is faulty in this +regard. + +In many cases a timeout is due to a transient condition, so the situation +can be improved by just continuing to wait like with other I/O requests +issued by storvsc, and avoiding the guaranteed panic. For a permanent +failure, continuing to wait may result in a hung thread instead of a panic, +which again may be better. + +So fix the panic by removing the storvsc call to fc_eh_timed_out(). This +allows storvsc to keep waiting for a response. The change has been tested +by users who experienced a panic in fc_eh_timed_out() due to transient +timeouts, and it solves their problem. + +In the future we may want to deprecate the vFC functionality in storvsc +since it can't be fully fixed. But it has current users for whom it is +working well enough, so it should probably stay for a while longer. + +Fixes: 3930d7309807 ("scsi: storvsc: use default I/O timeout handler for FC devices") +Cc: stable@vger.kernel.org +Signed-off-by: Michael Kelley +Link: https://lore.kernel.org/r/1690606764-79669-1-git-send-email-mikelley@microsoft.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/scsi/storvsc_drv.c | 4 ---- + 1 file changed, 4 deletions(-) + +--- a/drivers/scsi/storvsc_drv.c ++++ b/drivers/scsi/storvsc_drv.c +@@ -1730,10 +1730,6 @@ static int storvsc_host_reset_handler(st + */ + static enum blk_eh_timer_return storvsc_eh_timed_out(struct scsi_cmnd *scmnd) + { +-#if IS_ENABLED(CONFIG_SCSI_FC_ATTRS) +- if (scmnd->device->host->transportt == fc_transport_template) +- return fc_eh_timed_out(scmnd); +-#endif + return BLK_EH_RESET_TIMER; + } + diff --git a/queue-5.15/series b/queue-5.15/series index f38a56a2333..ddd11765325 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -74,3 +74,16 @@ btrfs-set-cache_block_group_error-if-we-find-an-error.patch nvme-tcp-fix-potential-unbalanced-freeze-unfreeze.patch nvme-rdma-fix-potential-unbalanced-freeze-unfreeze.patch netfilter-nf_tables-report-use-refcount-overflow.patch +scsi-core-fix-legacy-proc-parsing-buffer-overflow.patch +scsi-storvsc-fix-handling-of-virtual-fibre-channel-timeouts.patch +scsi-53c700-check-that-command-slot-is-not-null.patch +scsi-snic-fix-possible-memory-leak-if-device_add-fails.patch +scsi-core-fix-possible-memory-leak-if-device_add-fails.patch +scsi-fnic-replace-return-codes-in-fnic_clean_pending_aborts.patch +scsi-qedi-fix-firmware-halt-over-suspend-and-resume.patch +scsi-qedf-fix-firmware-halt-over-suspend-and-resume.patch +alpha-remove-__init-annotation-from-exported-page_is_ram.patch +sch_netem-fix-issues-in-netem_change-vs-get_dist_table.patch +tick-detect-and-fix-jiffies-update-stall.patch +timers-nohz-switch-to-oneshot_stopped-in-the-low-res-handler-when-the-tick-is-stopped.patch +timers-nohz-last-resort-update-jiffies-on-nohz_full-irq-entry.patch diff --git a/queue-5.15/tick-detect-and-fix-jiffies-update-stall.patch b/queue-5.15/tick-detect-and-fix-jiffies-update-stall.patch new file mode 100644 index 00000000000..c4f91689149 --- /dev/null +++ b/queue-5.15/tick-detect-and-fix-jiffies-update-stall.patch @@ -0,0 +1,90 @@ +From stable-owner@vger.kernel.org Sun Aug 13 05:16:30 2023 +From: "Joel Fernandes (Google)" +Date: Sun, 13 Aug 2023 03:16:18 +0000 +Subject: tick: Detect and fix jiffies update stall +To: stable@vger.kernel.org +Cc: Guenter Roeck , Steven Rostedt , Frederic Weisbecker , "Paul E . McKenney" , Thomas Gleixner , Joel Fernandes +Message-ID: <20230813031620.2218302-1-joel@joelfernandes.org> + +From: Frederic Weisbecker + +[ Upstream commit a1ff03cd6fb9c501fff63a4a2bface9adcfa81cd ] + +tick: Detect and fix jiffies update stall + +On some rare cases, the timekeeper CPU may be delaying its jiffies +update duty for a while. Known causes include: + +* The timekeeper is waiting on stop_machine in a MULTI_STOP_DISABLE_IRQ + or MULTI_STOP_RUN state. Disabled interrupts prevent from timekeeping + updates while waiting for the target CPU to complete its + stop_machine() callback. + +* The timekeeper vcpu has VMEXIT'ed for a long while due to some overload + on the host. + +Detect and fix these situations with emergency timekeeping catchups. + +Original-patch-by: Paul E. McKenney +Signed-off-by: Frederic Weisbecker +Cc: Thomas Gleixner +Signed-off-by: Joel Fernandes (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/time/tick-sched.c | 17 +++++++++++++++++ + kernel/time/tick-sched.h | 4 ++++ + 2 files changed, 21 insertions(+) + +--- a/kernel/time/tick-sched.c ++++ b/kernel/time/tick-sched.c +@@ -180,6 +180,8 @@ static ktime_t tick_init_jiffy_update(vo + return period; + } + ++#define MAX_STALLED_JIFFIES 5 ++ + static void tick_sched_do_timer(struct tick_sched *ts, ktime_t now) + { + int cpu = smp_processor_id(); +@@ -207,6 +209,21 @@ static void tick_sched_do_timer(struct t + if (tick_do_timer_cpu == cpu) + tick_do_update_jiffies64(now); + ++ /* ++ * If jiffies update stalled for too long (timekeeper in stop_machine() ++ * or VMEXIT'ed for several msecs), force an update. ++ */ ++ if (ts->last_tick_jiffies != jiffies) { ++ ts->stalled_jiffies = 0; ++ ts->last_tick_jiffies = READ_ONCE(jiffies); ++ } else { ++ if (++ts->stalled_jiffies == MAX_STALLED_JIFFIES) { ++ tick_do_update_jiffies64(now); ++ ts->stalled_jiffies = 0; ++ ts->last_tick_jiffies = READ_ONCE(jiffies); ++ } ++ } ++ + if (ts->inidle) + ts->got_idle_tick = 1; + } +--- a/kernel/time/tick-sched.h ++++ b/kernel/time/tick-sched.h +@@ -49,6 +49,8 @@ enum tick_nohz_mode { + * @timer_expires_base: Base time clock monotonic for @timer_expires + * @next_timer: Expiry time of next expiring timer for debugging purpose only + * @tick_dep_mask: Tick dependency mask - is set, if someone needs the tick ++ * @last_tick_jiffies: Value of jiffies seen on last tick ++ * @stalled_jiffies: Number of stalled jiffies detected across ticks + */ + struct tick_sched { + struct hrtimer sched_timer; +@@ -77,6 +79,8 @@ struct tick_sched { + u64 next_timer; + ktime_t idle_expires; + atomic_t tick_dep_mask; ++ unsigned long last_tick_jiffies; ++ unsigned int stalled_jiffies; + }; + + extern struct tick_sched *tick_get_tick_sched(int cpu); diff --git a/queue-5.15/timers-nohz-last-resort-update-jiffies-on-nohz_full-irq-entry.patch b/queue-5.15/timers-nohz-last-resort-update-jiffies-on-nohz_full-irq-entry.patch new file mode 100644 index 00000000000..f5adaf35df0 --- /dev/null +++ b/queue-5.15/timers-nohz-last-resort-update-jiffies-on-nohz_full-irq-entry.patch @@ -0,0 +1,92 @@ +From stable-owner@vger.kernel.org Sun Aug 13 05:16:33 2023 +From: "Joel Fernandes (Google)" +Date: Sun, 13 Aug 2023 03:16:20 +0000 +Subject: timers/nohz: Last resort update jiffies on nohz_full IRQ entry +To: stable@vger.kernel.org +Cc: Guenter Roeck , Steven Rostedt , Frederic Weisbecker , "Paul E . McKenney" , Thomas Gleixner , Joel Fernandes +Message-ID: <20230813031620.2218302-3-joel@joelfernandes.org> + +From: Frederic Weisbecker + +[ Upstream commit 53e87e3cdc155f20c3417b689df8d2ac88d79576 ] + +When at least one CPU runs in nohz_full mode, a dedicated timekeeper CPU +is guaranteed to stay online and to never stop its tick. + +Meanwhile on some rare case, the dedicated timekeeper may be running +with interrupts disabled for a while, such as in stop_machine. + +If jiffies stop being updated, a nohz_full CPU may end up endlessly +programming the next tick in the past, taking the last jiffies update +monotonic timestamp as a stale base, resulting in an tick storm. + +Here is a scenario where it matters: + +0) CPU 0 is the timekeeper and CPU 1 a nohz_full CPU. + +1) A stop machine callback is queued to execute somewhere. + +2) CPU 0 reaches MULTI_STOP_DISABLE_IRQ while CPU 1 is still in + MULTI_STOP_PREPARE. Hence CPU 0 can't do its timekeeping duty. CPU 1 + can still take IRQs. + +3) CPU 1 receives an IRQ which queues a timer callback one jiffy forward. + +4) On IRQ exit, CPU 1 schedules the tick one jiffy forward, taking + last_jiffies_update as a base. But last_jiffies_update hasn't been + updated for 2 jiffies since the timekeeper has interrupts disabled. + +5) clockevents_program_event(), which relies on ktime_get(), observes + that the expiration is in the past and therefore programs the min + delta event on the clock. + +6) The tick fires immediately, goto 3) + +7) Tick storm, the nohz_full CPU is drown and takes ages to reach + MULTI_STOP_DISABLE_IRQ, which is the only way out of this situation. + +Solve this with unconditionally updating jiffies if the value is stale +on nohz_full IRQ entry. IRQs and other disturbances are expected to be +rare enough on nohz_full for the unconditional call to ktime_get() to +actually matter. + +Reported-by: Paul E. McKenney +Signed-off-by: Frederic Weisbecker +Signed-off-by: Thomas Gleixner +Tested-by: Paul E. McKenney +Link: https://lore.kernel.org/r/20211026141055.57358-2-frederic@kernel.org +Signed-off-by: Joel Fernandes (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/softirq.c | 3 ++- + kernel/time/tick-sched.c | 7 +++++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + +--- a/kernel/softirq.c ++++ b/kernel/softirq.c +@@ -595,7 +595,8 @@ void irq_enter_rcu(void) + { + __irq_enter_raw(); + +- if (is_idle_task(current) && (irq_count() == HARDIRQ_OFFSET)) ++ if (tick_nohz_full_cpu(smp_processor_id()) || ++ (is_idle_task(current) && (irq_count() == HARDIRQ_OFFSET))) + tick_irq_enter(); + + account_hardirq_enter(current); +--- a/kernel/time/tick-sched.c ++++ b/kernel/time/tick-sched.c +@@ -1420,6 +1420,13 @@ static inline void tick_nohz_irq_enter(v + now = ktime_get(); + if (ts->idle_active) + tick_nohz_stop_idle(ts, now); ++ /* ++ * If all CPUs are idle. We may need to update a stale jiffies value. ++ * Note nohz_full is a special case: a timekeeper is guaranteed to stay ++ * alive but it might be busy looping with interrupts disabled in some ++ * rare case (typically stop machine). So we must make sure we have a ++ * last resort. ++ */ + if (ts->tick_stopped) + tick_nohz_update_jiffies(now); + } diff --git a/queue-5.15/timers-nohz-switch-to-oneshot_stopped-in-the-low-res-handler-when-the-tick-is-stopped.patch b/queue-5.15/timers-nohz-switch-to-oneshot_stopped-in-the-low-res-handler-when-the-tick-is-stopped.patch new file mode 100644 index 00000000000..654ec417414 --- /dev/null +++ b/queue-5.15/timers-nohz-switch-to-oneshot_stopped-in-the-low-res-handler-when-the-tick-is-stopped.patch @@ -0,0 +1,61 @@ +From stable-owner@vger.kernel.org Sun Aug 13 05:16:31 2023 +From: "Joel Fernandes (Google)" +Date: Sun, 13 Aug 2023 03:16:19 +0000 +Subject: timers/nohz: Switch to ONESHOT_STOPPED in the low-res handler when the tick is stopped +To: stable@vger.kernel.org +Cc: Guenter Roeck , Steven Rostedt , Nicholas Piggin , Thomas Gleixner , Joel Fernandes +Message-ID: <20230813031620.2218302-2-joel@joelfernandes.org> + +From: Nicholas Piggin + +[ Upstream commit 62c1256d544747b38e77ca9b5bfe3a26f9592576 ] + +When tick_nohz_stop_tick() stops the tick and high resolution timers are +disabled, then the clock event device is not put into ONESHOT_STOPPED +mode. This can lead to spurious timer interrupts with some clock event +device drivers that don't shut down entirely after firing. + +Eliminate these by putting the device into ONESHOT_STOPPED mode at points +where it is not being reprogrammed. When there are no timers active, then +tick_program_event() with KTIME_MAX can be used to stop the device. When +there is a timer active, the device can be stopped at the next tick (any +new timer added by timers will reprogram the tick). + +Signed-off-by: Nicholas Piggin +Signed-off-by: Thomas Gleixner +Link: https://lore.kernel.org/r/20220422141446.915024-1-npiggin@gmail.com +Signed-off-by: Joel Fernandes (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/time/tick-sched.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/kernel/time/tick-sched.c ++++ b/kernel/time/tick-sched.c +@@ -950,6 +950,8 @@ static void tick_nohz_stop_tick(struct t + if (unlikely(expires == KTIME_MAX)) { + if (ts->nohz_mode == NOHZ_MODE_HIGHRES) + hrtimer_cancel(&ts->sched_timer); ++ else ++ tick_program_event(KTIME_MAX, 1); + return; + } + +@@ -1356,9 +1358,15 @@ static void tick_nohz_handler(struct clo + tick_sched_do_timer(ts, now); + tick_sched_handle(ts, regs); + +- /* No need to reprogram if we are running tickless */ +- if (unlikely(ts->tick_stopped)) ++ if (unlikely(ts->tick_stopped)) { ++ /* ++ * The clockevent device is not reprogrammed, so change the ++ * clock event device to ONESHOT_STOPPED to avoid spurious ++ * interrupts on devices which might not be truly one shot. ++ */ ++ tick_program_event(KTIME_MAX, 1); + return; ++ } + + hrtimer_forward(&ts->sched_timer, now, TICK_NSEC); + tick_program_event(hrtimer_get_expires(&ts->sched_timer), 1);