From: Greg Kroah-Hartman Date: Fri, 24 Mar 2017 15:02:43 +0000 (+0100) Subject: 4.4-stable patches X-Git-Tag: v4.4.57~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f8478a2953e20d62049db517c9b868061767a1c6;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: cpufreq-fix-and-clean-up-show_cpuinfo_cur_freq.patch gfs2-avoid-alignment-hole-in-struct-lm_lockname.patch isdn-gigaset-fix-null-deref-at-probe.patch md-raid1-10-fix-potential-deadlock.patch percpu-acquire-pcpu_lock-when-updating-pcpu_nr_empty_pop_pages.patch powerpc-boot-fix-zimage-toc-alignment.patch scsi-libiscsi-add-lock-around-task-lists-to-fix-list-corruption-regression.patch scsi-lpfc-add-shutdown-method-for-kexec.patch target-fix-verify_16-handling-in-sbc_parse_cdb.patch target-pscsi-fix-type_tape-type_medimum_changer-export.patch --- diff --git a/queue-4.4/cpufreq-fix-and-clean-up-show_cpuinfo_cur_freq.patch b/queue-4.4/cpufreq-fix-and-clean-up-show_cpuinfo_cur_freq.patch new file mode 100644 index 00000000000..6c9754a205c --- /dev/null +++ b/queue-4.4/cpufreq-fix-and-clean-up-show_cpuinfo_cur_freq.patch @@ -0,0 +1,37 @@ +From 9b4f603e7a9f4282aec451063ffbbb8bb410dcd9 Mon Sep 17 00:00:00 2001 +From: "Rafael J. Wysocki" +Date: Wed, 15 Mar 2017 00:12:16 +0100 +Subject: cpufreq: Fix and clean up show_cpuinfo_cur_freq() + +From: Rafael J. Wysocki + +commit 9b4f603e7a9f4282aec451063ffbbb8bb410dcd9 upstream. + +There is a missing newline in show_cpuinfo_cur_freq(), so add it, +but while at it clean that function up somewhat too. + +Signed-off-by: Rafael J. Wysocki +Acked-by: Viresh Kumar +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/cpufreq/cpufreq.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -626,9 +626,11 @@ static ssize_t show_cpuinfo_cur_freq(str + char *buf) + { + unsigned int cur_freq = __cpufreq_get(policy); +- if (!cur_freq) +- return sprintf(buf, ""); +- return sprintf(buf, "%u\n", cur_freq); ++ ++ if (cur_freq) ++ return sprintf(buf, "%u\n", cur_freq); ++ ++ return sprintf(buf, "\n"); + } + + /** diff --git a/queue-4.4/gfs2-avoid-alignment-hole-in-struct-lm_lockname.patch b/queue-4.4/gfs2-avoid-alignment-hole-in-struct-lm_lockname.patch new file mode 100644 index 00000000000..864a3f1c9ee --- /dev/null +++ b/queue-4.4/gfs2-avoid-alignment-hole-in-struct-lm_lockname.patch @@ -0,0 +1,34 @@ +From 28ea06c46fbcab63fd9a55531387b7928a18a590 Mon Sep 17 00:00:00 2001 +From: Andreas Gruenbacher +Date: Mon, 6 Mar 2017 12:58:42 -0500 +Subject: gfs2: Avoid alignment hole in struct lm_lockname + +From: Andreas Gruenbacher + +commit 28ea06c46fbcab63fd9a55531387b7928a18a590 upstream. + +Commit 88ffbf3e03 switches to using rhashtables for glocks, hashing over +the entire struct lm_lockname instead of its individual fields. On some +architectures, struct lm_lockname contains a hole of uninitialized +memory due to alignment rules, which now leads to incorrect hash values. +Get rid of that hole. + +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Bob Peterson +Signed-off-by: Greg Kroah-Hartman + +--- + fs/gfs2/incore.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/gfs2/incore.h ++++ b/fs/gfs2/incore.h +@@ -207,7 +207,7 @@ struct lm_lockname { + struct gfs2_sbd *ln_sbd; + u64 ln_number; + unsigned int ln_type; +-}; ++} __packed __aligned(sizeof(int)); + + #define lm_name_equal(name1, name2) \ + (((name1)->ln_number == (name2)->ln_number) && \ diff --git a/queue-4.4/isdn-gigaset-fix-null-deref-at-probe.patch b/queue-4.4/isdn-gigaset-fix-null-deref-at-probe.patch new file mode 100644 index 00000000000..36acf7f8aaa --- /dev/null +++ b/queue-4.4/isdn-gigaset-fix-null-deref-at-probe.patch @@ -0,0 +1,34 @@ +From 68c32f9c2a36d410aa242e661506e5b2c2764179 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Mon, 13 Mar 2017 13:39:01 +0100 +Subject: isdn/gigaset: fix NULL-deref at probe + +From: Johan Hovold + +commit 68c32f9c2a36d410aa242e661506e5b2c2764179 upstream. + +Make sure to check the number of endpoints to avoid dereferencing a +NULL-pointer should a malicious device lack endpoints. + +Fixes: cf7776dc05b8 ("[PATCH] isdn4linux: Siemens Gigaset drivers - direct USB connection") +Cc: Hansjoerg Lipp +Signed-off-by: Johan Hovold +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/isdn/gigaset/bas-gigaset.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/isdn/gigaset/bas-gigaset.c ++++ b/drivers/isdn/gigaset/bas-gigaset.c +@@ -2317,6 +2317,9 @@ static int gigaset_probe(struct usb_inte + return -ENODEV; + } + ++ if (hostif->desc.bNumEndpoints < 1) ++ return -ENODEV; ++ + dev_info(&udev->dev, + "%s: Device matched (Vendor: 0x%x, Product: 0x%x)\n", + __func__, le16_to_cpu(udev->descriptor.idVendor), diff --git a/queue-4.4/md-raid1-10-fix-potential-deadlock.patch b/queue-4.4/md-raid1-10-fix-potential-deadlock.patch new file mode 100644 index 00000000000..f80e6206212 --- /dev/null +++ b/queue-4.4/md-raid1-10-fix-potential-deadlock.patch @@ -0,0 +1,90 @@ +From 61eb2b43b99ebdc9bc6bc83d9792257b243e7cb3 Mon Sep 17 00:00:00 2001 +From: Shaohua Li +Date: Tue, 28 Feb 2017 13:00:20 -0800 +Subject: md/raid1/10: fix potential deadlock + +From: Shaohua Li + +commit 61eb2b43b99ebdc9bc6bc83d9792257b243e7cb3 upstream. + +Neil Brown pointed out a potential deadlock in raid 10 code with +bio_split/chain. The raid1 code could have the same issue, but recent +barrier rework makes it less likely to happen. The deadlock happens in +below sequence: + +1. generic_make_request(bio), this will set current->bio_list +2. raid10_make_request will split bio to bio1 and bio2 +3. __make_request(bio1), wait_barrer, add underlayer disk bio to +current->bio_list +4. __make_request(bio2), wait_barrer + +If raise_barrier happens between 3 & 4, since wait_barrier runs at 3, +raise_barrier waits for IO completion from 3. And since raise_barrier +sets barrier, 4 waits for raise_barrier. But IO from 3 can't be +dispatched because raid10_make_request() doesn't finished yet. + +The solution is to adjust the IO ordering. Quotes from Neil: +" +It is much safer to: + + if (need to split) { + split = bio_split(bio, ...) + bio_chain(...) + make_request_fn(split); + generic_make_request(bio); + } else + make_request_fn(mddev, bio); + +This way we first process the initial section of the bio (in 'split') +which will queue some requests to the underlying devices. These +requests will be queued in generic_make_request. +Then we queue the remainder of the bio, which will be added to the end +of the generic_make_request queue. +Then we return. +generic_make_request() will pop the lower-level device requests off the +queue and handle them first. Then it will process the remainder +of the original bio once the first section has been fully processed. +" + +Note, this only happens in read path. In write path, the bio is flushed to +underlaying disks either by blk flush (from schedule) or offladed to raid1/10d. +It's queued in current->bio_list. + +Cc: Coly Li +Suggested-by: NeilBrown +Reviewed-by: Jack Wang +Signed-off-by: Shaohua Li +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/raid10.c | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +--- a/drivers/md/raid10.c ++++ b/drivers/md/raid10.c +@@ -1477,7 +1477,25 @@ static void make_request(struct mddev *m + split = bio; + } + ++ /* ++ * If a bio is splitted, the first part of bio will pass ++ * barrier but the bio is queued in current->bio_list (see ++ * generic_make_request). If there is a raise_barrier() called ++ * here, the second part of bio can't pass barrier. But since ++ * the first part bio isn't dispatched to underlaying disks ++ * yet, the barrier is never released, hence raise_barrier will ++ * alays wait. We have a deadlock. ++ * Note, this only happens in read path. For write path, the ++ * first part of bio is dispatched in a schedule() call ++ * (because of blk plug) or offloaded to raid10d. ++ * Quitting from the function immediately can change the bio ++ * order queued in bio_list and avoid the deadlock. ++ */ + __make_request(mddev, split); ++ if (split != bio && bio_data_dir(bio) == READ) { ++ generic_make_request(bio); ++ break; ++ } + } while (split != bio); + + /* In case raid10d snuck in to freeze_array */ diff --git a/queue-4.4/percpu-acquire-pcpu_lock-when-updating-pcpu_nr_empty_pop_pages.patch b/queue-4.4/percpu-acquire-pcpu_lock-when-updating-pcpu_nr_empty_pop_pages.patch new file mode 100644 index 00000000000..2e6060e2ee1 --- /dev/null +++ b/queue-4.4/percpu-acquire-pcpu_lock-when-updating-pcpu_nr_empty_pop_pages.patch @@ -0,0 +1,37 @@ +From 320661b08dd6f1746d5c7ab4eb435ec64b97cd45 Mon Sep 17 00:00:00 2001 +From: Tahsin Erdogan +Date: Sat, 25 Feb 2017 13:00:19 -0800 +Subject: percpu: acquire pcpu_lock when updating pcpu_nr_empty_pop_pages + +From: Tahsin Erdogan + +commit 320661b08dd6f1746d5c7ab4eb435ec64b97cd45 upstream. + +Update to pcpu_nr_empty_pop_pages in pcpu_alloc() is currently done +without holding pcpu_lock. This can lead to bad updates to the variable. +Add missing lock calls. + +Fixes: b539b87fed37 ("percpu: implmeent pcpu_nr_empty_pop_pages and chunk->nr_populated") +Signed-off-by: Tahsin Erdogan +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman + +--- + mm/percpu.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/mm/percpu.c ++++ b/mm/percpu.c +@@ -1012,8 +1012,11 @@ area_found: + mutex_unlock(&pcpu_alloc_mutex); + } + +- if (chunk != pcpu_reserved_chunk) ++ if (chunk != pcpu_reserved_chunk) { ++ spin_lock_irqsave(&pcpu_lock, flags); + pcpu_nr_empty_pop_pages -= occ_pages; ++ spin_unlock_irqrestore(&pcpu_lock, flags); ++ } + + if (pcpu_nr_empty_pop_pages < PCPU_EMPTY_POP_PAGES_LOW) + pcpu_schedule_balance_work(); diff --git a/queue-4.4/powerpc-boot-fix-zimage-toc-alignment.patch b/queue-4.4/powerpc-boot-fix-zimage-toc-alignment.patch new file mode 100644 index 00000000000..1192cde9f63 --- /dev/null +++ b/queue-4.4/powerpc-boot-fix-zimage-toc-alignment.patch @@ -0,0 +1,33 @@ +From 97ee351b50a49717543533cfb85b4bf9d88c9680 Mon Sep 17 00:00:00 2001 +From: Michael Ellerman +Date: Tue, 7 Mar 2017 16:14:49 +1100 +Subject: powerpc/boot: Fix zImage TOC alignment + +From: Michael Ellerman + +commit 97ee351b50a49717543533cfb85b4bf9d88c9680 upstream. + +Recent toolchains force the TOC to be 256 byte aligned. We need to +enforce this alignment in the zImage linker script, otherwise pointers +to our TOC variables (__toc_start) could be incorrect. If the actual +start of the TOC and __toc_start don't have the same value we crash +early in the zImage wrapper. + +Suggested-by: Alan Modra +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/boot/zImage.lds.S | 1 + + 1 file changed, 1 insertion(+) + +--- a/arch/powerpc/boot/zImage.lds.S ++++ b/arch/powerpc/boot/zImage.lds.S +@@ -68,6 +68,7 @@ SECTIONS + } + + #ifdef CONFIG_PPC64_BOOT_WRAPPER ++ . = ALIGN(256); + .got : + { + __toc_start = .; diff --git a/queue-4.4/scsi-libiscsi-add-lock-around-task-lists-to-fix-list-corruption-regression.patch b/queue-4.4/scsi-libiscsi-add-lock-around-task-lists-to-fix-list-corruption-regression.patch new file mode 100644 index 00000000000..2ea1349b8e0 --- /dev/null +++ b/queue-4.4/scsi-libiscsi-add-lock-around-task-lists-to-fix-list-corruption-regression.patch @@ -0,0 +1,181 @@ +From 6f8830f5bbab16e54f261de187f3df4644a5b977 Mon Sep 17 00:00:00 2001 +From: Chris Leech +Date: Mon, 27 Feb 2017 16:58:36 -0800 +Subject: scsi: libiscsi: add lock around task lists to fix list corruption regression + +From: Chris Leech + +commit 6f8830f5bbab16e54f261de187f3df4644a5b977 upstream. + +There's a rather long standing regression from the commit "libiscsi: +Reduce locking contention in fast path" + +Depending on iSCSI target behavior, it's possible to hit the case in +iscsi_complete_task where the task is still on a pending list +(!list_empty(&task->running)). When that happens the task is removed +from the list while holding the session back_lock, but other task list +modification occur under the frwd_lock. That leads to linked list +corruption and eventually a panicked system. + +Rather than back out the session lock split entirely, in order to try +and keep some of the performance gains this patch adds another lock to +maintain the task lists integrity. + +Major enterprise supported kernels have been backing out the lock split +for while now, thanks to the efforts at IBM where a lab setup has the +most reliable reproducer I've seen on this issue. This patch has been +tested there successfully. + +Signed-off-by: Chris Leech +Fixes: 659743b02c41 ("[SCSI] libiscsi: Reduce locking contention in fast path") +Reported-by: Prashantha Subbarao +Reviewed-by: Guilherme G. Piccoli +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/libiscsi.c | 26 +++++++++++++++++++++++++- + include/scsi/libiscsi.h | 1 + + 2 files changed, 26 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/libiscsi.c ++++ b/drivers/scsi/libiscsi.c +@@ -560,8 +560,12 @@ static void iscsi_complete_task(struct i + WARN_ON_ONCE(task->state == ISCSI_TASK_FREE); + task->state = state; + +- if (!list_empty(&task->running)) ++ spin_lock_bh(&conn->taskqueuelock); ++ if (!list_empty(&task->running)) { ++ pr_debug_once("%s while task on list", __func__); + list_del_init(&task->running); ++ } ++ spin_unlock_bh(&conn->taskqueuelock); + + if (conn->task == task) + conn->task = NULL; +@@ -783,7 +787,9 @@ __iscsi_conn_send_pdu(struct iscsi_conn + if (session->tt->xmit_task(task)) + goto free_task; + } else { ++ spin_lock_bh(&conn->taskqueuelock); + list_add_tail(&task->running, &conn->mgmtqueue); ++ spin_unlock_bh(&conn->taskqueuelock); + iscsi_conn_queue_work(conn); + } + +@@ -1474,8 +1480,10 @@ void iscsi_requeue_task(struct iscsi_tas + * this may be on the requeue list already if the xmit_task callout + * is handling the r2ts while we are adding new ones + */ ++ spin_lock_bh(&conn->taskqueuelock); + if (list_empty(&task->running)) + list_add_tail(&task->running, &conn->requeue); ++ spin_unlock_bh(&conn->taskqueuelock); + iscsi_conn_queue_work(conn); + } + EXPORT_SYMBOL_GPL(iscsi_requeue_task); +@@ -1512,22 +1520,26 @@ static int iscsi_data_xmit(struct iscsi_ + * only have one nop-out as a ping from us and targets should not + * overflow us with nop-ins + */ ++ spin_lock_bh(&conn->taskqueuelock); + check_mgmt: + while (!list_empty(&conn->mgmtqueue)) { + conn->task = list_entry(conn->mgmtqueue.next, + struct iscsi_task, running); + list_del_init(&conn->task->running); ++ spin_unlock_bh(&conn->taskqueuelock); + if (iscsi_prep_mgmt_task(conn, conn->task)) { + /* regular RX path uses back_lock */ + spin_lock_bh(&conn->session->back_lock); + __iscsi_put_task(conn->task); + spin_unlock_bh(&conn->session->back_lock); + conn->task = NULL; ++ spin_lock_bh(&conn->taskqueuelock); + continue; + } + rc = iscsi_xmit_task(conn); + if (rc) + goto done; ++ spin_lock_bh(&conn->taskqueuelock); + } + + /* process pending command queue */ +@@ -1535,19 +1547,24 @@ check_mgmt: + conn->task = list_entry(conn->cmdqueue.next, struct iscsi_task, + running); + list_del_init(&conn->task->running); ++ spin_unlock_bh(&conn->taskqueuelock); + if (conn->session->state == ISCSI_STATE_LOGGING_OUT) { + fail_scsi_task(conn->task, DID_IMM_RETRY); ++ spin_lock_bh(&conn->taskqueuelock); + continue; + } + rc = iscsi_prep_scsi_cmd_pdu(conn->task); + if (rc) { + if (rc == -ENOMEM || rc == -EACCES) { ++ spin_lock_bh(&conn->taskqueuelock); + list_add_tail(&conn->task->running, + &conn->cmdqueue); + conn->task = NULL; ++ spin_unlock_bh(&conn->taskqueuelock); + goto done; + } else + fail_scsi_task(conn->task, DID_ABORT); ++ spin_lock_bh(&conn->taskqueuelock); + continue; + } + rc = iscsi_xmit_task(conn); +@@ -1558,6 +1575,7 @@ check_mgmt: + * we need to check the mgmt queue for nops that need to + * be sent to aviod starvation + */ ++ spin_lock_bh(&conn->taskqueuelock); + if (!list_empty(&conn->mgmtqueue)) + goto check_mgmt; + } +@@ -1577,12 +1595,15 @@ check_mgmt: + conn->task = task; + list_del_init(&conn->task->running); + conn->task->state = ISCSI_TASK_RUNNING; ++ spin_unlock_bh(&conn->taskqueuelock); + rc = iscsi_xmit_task(conn); + if (rc) + goto done; ++ spin_lock_bh(&conn->taskqueuelock); + if (!list_empty(&conn->mgmtqueue)) + goto check_mgmt; + } ++ spin_unlock_bh(&conn->taskqueuelock); + spin_unlock_bh(&conn->session->frwd_lock); + return -ENODATA; + +@@ -1738,7 +1759,9 @@ int iscsi_queuecommand(struct Scsi_Host + goto prepd_reject; + } + } else { ++ spin_lock_bh(&conn->taskqueuelock); + list_add_tail(&task->running, &conn->cmdqueue); ++ spin_unlock_bh(&conn->taskqueuelock); + iscsi_conn_queue_work(conn); + } + +@@ -2900,6 +2923,7 @@ iscsi_conn_setup(struct iscsi_cls_sessio + INIT_LIST_HEAD(&conn->mgmtqueue); + INIT_LIST_HEAD(&conn->cmdqueue); + INIT_LIST_HEAD(&conn->requeue); ++ spin_lock_init(&conn->taskqueuelock); + INIT_WORK(&conn->xmitwork, iscsi_xmitworker); + + /* allocate login_task used for the login/text sequences */ +--- a/include/scsi/libiscsi.h ++++ b/include/scsi/libiscsi.h +@@ -196,6 +196,7 @@ struct iscsi_conn { + struct iscsi_task *task; /* xmit task in progress */ + + /* xmit */ ++ spinlock_t taskqueuelock; /* protects the next three lists */ + struct list_head mgmtqueue; /* mgmt (control) xmit queue */ + struct list_head cmdqueue; /* data-path cmd queue */ + struct list_head requeue; /* tasks needing another run */ diff --git a/queue-4.4/scsi-lpfc-add-shutdown-method-for-kexec.patch b/queue-4.4/scsi-lpfc-add-shutdown-method-for-kexec.patch new file mode 100644 index 00000000000..65cb53a94d7 --- /dev/null +++ b/queue-4.4/scsi-lpfc-add-shutdown-method-for-kexec.patch @@ -0,0 +1,32 @@ +From 85e8a23936ab3442de0c42da97d53b29f004ece1 Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Mon, 13 Feb 2017 08:49:20 +1100 +Subject: scsi: lpfc: Add shutdown method for kexec + +From: Anton Blanchard + +commit 85e8a23936ab3442de0c42da97d53b29f004ece1 upstream. + +We see lpfc devices regularly fail during kexec. Fix this by adding a +shutdown method which mirrors the remove method. + +Signed-off-by: Anton Blanchard +Reviewed-by: Mauricio Faria de Oliveira +Tested-by: Mauricio Faria de Oliveira +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/lpfc/lpfc_init.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/scsi/lpfc/lpfc_init.c ++++ b/drivers/scsi/lpfc/lpfc_init.c +@@ -11387,6 +11387,7 @@ static struct pci_driver lpfc_driver = { + .id_table = lpfc_id_table, + .probe = lpfc_pci_probe_one, + .remove = lpfc_pci_remove_one, ++ .shutdown = lpfc_pci_remove_one, + .suspend = lpfc_pci_suspend_one, + .resume = lpfc_pci_resume_one, + .err_handler = &lpfc_err_handler, diff --git a/queue-4.4/series b/queue-4.4/series index ac57cd242a9..dd7503dc73b 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -17,3 +17,13 @@ hv_netvsc-use-skb_get_hash-instead-of-a-homegrown-implementation.patch kernek-fork.c-allocate-idle-task-for-a-cpu-always-on-its-local-node.patch give-up-on-gcc-ilog2-constant-optimizations.patch perf-core-fix-event-inheritance-on-fork.patch +cpufreq-fix-and-clean-up-show_cpuinfo_cur_freq.patch +powerpc-boot-fix-zimage-toc-alignment.patch +md-raid1-10-fix-potential-deadlock.patch +target-pscsi-fix-type_tape-type_medimum_changer-export.patch +scsi-lpfc-add-shutdown-method-for-kexec.patch +scsi-libiscsi-add-lock-around-task-lists-to-fix-list-corruption-regression.patch +target-fix-verify_16-handling-in-sbc_parse_cdb.patch +isdn-gigaset-fix-null-deref-at-probe.patch +gfs2-avoid-alignment-hole-in-struct-lm_lockname.patch +percpu-acquire-pcpu_lock-when-updating-pcpu_nr_empty_pop_pages.patch diff --git a/queue-4.4/target-fix-verify_16-handling-in-sbc_parse_cdb.patch b/queue-4.4/target-fix-verify_16-handling-in-sbc_parse_cdb.patch new file mode 100644 index 00000000000..7db05fe3ab8 --- /dev/null +++ b/queue-4.4/target-fix-verify_16-handling-in-sbc_parse_cdb.patch @@ -0,0 +1,46 @@ +From 13603685c1f12c67a7a2427f00b63f39a2b6f7c9 Mon Sep 17 00:00:00 2001 +From: Max Lohrmann +Date: Tue, 7 Mar 2017 22:09:56 -0800 +Subject: target: Fix VERIFY_16 handling in sbc_parse_cdb + +From: Max Lohrmann + +commit 13603685c1f12c67a7a2427f00b63f39a2b6f7c9 upstream. + +As reported by Max, the Windows 2008 R2 chkdsk utility expects +VERIFY_16 to be supported, and does not handle the returned +CHECK_CONDITION properly, resulting in an infinite loop. + +The kernel will log huge amounts of this error: + +kernel: TARGET_CORE[iSCSI]: Unsupported SCSI Opcode 0x8f, sending +CHECK_CONDITION. + +Signed-off-by: Max Lohrmann +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_sbc.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/target/target_core_sbc.c ++++ b/drivers/target/target_core_sbc.c +@@ -1096,9 +1096,15 @@ sbc_parse_cdb(struct se_cmd *cmd, struct + return ret; + break; + case VERIFY: ++ case VERIFY_16: + size = 0; +- sectors = transport_get_sectors_10(cdb); +- cmd->t_task_lba = transport_lba_32(cdb); ++ if (cdb[0] == VERIFY) { ++ sectors = transport_get_sectors_10(cdb); ++ cmd->t_task_lba = transport_lba_32(cdb); ++ } else { ++ sectors = transport_get_sectors_16(cdb); ++ cmd->t_task_lba = transport_lba_64(cdb); ++ } + cmd->execute_cmd = sbc_emulate_noop; + goto check_lba; + case REZERO_UNIT: diff --git a/queue-4.4/target-pscsi-fix-type_tape-type_medimum_changer-export.patch b/queue-4.4/target-pscsi-fix-type_tape-type_medimum_changer-export.patch new file mode 100644 index 00000000000..40c02eabd30 --- /dev/null +++ b/queue-4.4/target-pscsi-fix-type_tape-type_medimum_changer-export.patch @@ -0,0 +1,148 @@ +From a04e54f2c35823ca32d56afcd5cea5b783e2f51a Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Thu, 3 Nov 2016 23:06:53 -0700 +Subject: target/pscsi: Fix TYPE_TAPE + TYPE_MEDIMUM_CHANGER export + +From: Nicholas Bellinger + +commit a04e54f2c35823ca32d56afcd5cea5b783e2f51a upstream. + +The following fixes a divide by zero OOPs with TYPE_TAPE +due to pscsi_tape_read_blocksize() failing causing a zero +sd->sector_size being propigated up via dev_attrib.hw_block_size. + +It also fixes another long-standing bug where TYPE_TAPE and +TYPE_MEDIMUM_CHANGER where using pscsi_create_type_other(), +which does not call scsi_device_get() to take the device +reference. Instead, rename pscsi_create_type_rom() to +pscsi_create_type_nondisk() and use it for all cases. + +Finally, also drop a dump_stack() in pscsi_get_blocks() for +non TYPE_DISK, which in modern target-core can get invoked +via target_sense_desc_format() during CHECK_CONDITION. + +Reported-by: Malcolm Haak +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_pscsi.c | 47 +++++++++---------------------------- + 1 file changed, 12 insertions(+), 35 deletions(-) + +--- a/drivers/target/target_core_pscsi.c ++++ b/drivers/target/target_core_pscsi.c +@@ -154,7 +154,7 @@ static void pscsi_tape_read_blocksize(st + + buf = kzalloc(12, GFP_KERNEL); + if (!buf) +- return; ++ goto out_free; + + memset(cdb, 0, MAX_COMMAND_SIZE); + cdb[0] = MODE_SENSE; +@@ -169,9 +169,10 @@ static void pscsi_tape_read_blocksize(st + * If MODE_SENSE still returns zero, set the default value to 1024. + */ + sdev->sector_size = (buf[9] << 16) | (buf[10] << 8) | (buf[11]); ++out_free: + if (!sdev->sector_size) + sdev->sector_size = 1024; +-out_free: ++ + kfree(buf); + } + +@@ -314,9 +315,10 @@ static int pscsi_add_device_to_list(stru + sd->lun, sd->queue_depth); + } + +- dev->dev_attrib.hw_block_size = sd->sector_size; ++ dev->dev_attrib.hw_block_size = ++ min_not_zero((int)sd->sector_size, 512); + dev->dev_attrib.hw_max_sectors = +- min_t(int, sd->host->max_sectors, queue_max_hw_sectors(q)); ++ min_not_zero(sd->host->max_sectors, queue_max_hw_sectors(q)); + dev->dev_attrib.hw_queue_depth = sd->queue_depth; + + /* +@@ -339,8 +341,10 @@ static int pscsi_add_device_to_list(stru + /* + * For TYPE_TAPE, attempt to determine blocksize with MODE_SENSE. + */ +- if (sd->type == TYPE_TAPE) ++ if (sd->type == TYPE_TAPE) { + pscsi_tape_read_blocksize(dev, sd); ++ dev->dev_attrib.hw_block_size = sd->sector_size; ++ } + return 0; + } + +@@ -406,7 +410,7 @@ static int pscsi_create_type_disk(struct + /* + * Called with struct Scsi_Host->host_lock called. + */ +-static int pscsi_create_type_rom(struct se_device *dev, struct scsi_device *sd) ++static int pscsi_create_type_nondisk(struct se_device *dev, struct scsi_device *sd) + __releases(sh->host_lock) + { + struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; +@@ -433,28 +437,6 @@ static int pscsi_create_type_rom(struct + return 0; + } + +-/* +- * Called with struct Scsi_Host->host_lock called. +- */ +-static int pscsi_create_type_other(struct se_device *dev, +- struct scsi_device *sd) +- __releases(sh->host_lock) +-{ +- struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; +- struct Scsi_Host *sh = sd->host; +- int ret; +- +- spin_unlock_irq(sh->host_lock); +- ret = pscsi_add_device_to_list(dev, sd); +- if (ret) +- return ret; +- +- pr_debug("CORE_PSCSI[%d] - Added Type: %s for %d:%d:%d:%llu\n", +- phv->phv_host_id, scsi_device_type(sd->type), sh->host_no, +- sd->channel, sd->id, sd->lun); +- return 0; +-} +- + static int pscsi_configure_device(struct se_device *dev) + { + struct se_hba *hba = dev->se_hba; +@@ -542,11 +524,8 @@ static int pscsi_configure_device(struct + case TYPE_DISK: + ret = pscsi_create_type_disk(dev, sd); + break; +- case TYPE_ROM: +- ret = pscsi_create_type_rom(dev, sd); +- break; + default: +- ret = pscsi_create_type_other(dev, sd); ++ ret = pscsi_create_type_nondisk(dev, sd); + break; + } + +@@ -611,8 +590,7 @@ static void pscsi_free_device(struct se_ + else if (pdv->pdv_lld_host) + scsi_host_put(pdv->pdv_lld_host); + +- if ((sd->type == TYPE_DISK) || (sd->type == TYPE_ROM)) +- scsi_device_put(sd); ++ scsi_device_put(sd); + + pdv->pdv_sd = NULL; + } +@@ -1088,7 +1066,6 @@ static sector_t pscsi_get_blocks(struct + if (pdv->pdv_bd && pdv->pdv_bd->bd_part) + return pdv->pdv_bd->bd_part->nr_sects; + +- dump_stack(); + return 0; + } +