From: Greg Kroah-Hartman Date: Fri, 10 Feb 2017 21:09:41 +0000 (+0100) Subject: 4.4-stable patches X-Git-Tag: v4.9.10~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ae9737eeba77d5a0890ee04711d400e45d87bb41;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: arm-8642-1-lpae-catch-pending-imprecise-abort-on-unmask.patch arm-8643-3-arm-ptrace-preserve-previous-registers-for-short-regset-write.patch cpumask-use-nr_cpumask_bits-for-parsing-functions.patch hns-avoid-stack-overflow-with-config_kasan.patch mac80211-fix-adding-of-mesh-vendor-ies.patch target-don-t-bug_on-during-nodeacl-dynamic-explicit-conversion.patch target-fix-compare_and_write-ref-leak-for-non-good-status.patch target-fix-early-transport_generic_handle_tmr-abort-scenario.patch target-use-correct-scsi-status-during-extended_copy-exception.patch --- diff --git a/queue-4.4/arm-8642-1-lpae-catch-pending-imprecise-abort-on-unmask.patch b/queue-4.4/arm-8642-1-lpae-catch-pending-imprecise-abort-on-unmask.patch new file mode 100644 index 00000000000..052acfe6f75 --- /dev/null +++ b/queue-4.4/arm-8642-1-lpae-catch-pending-imprecise-abort-on-unmask.patch @@ -0,0 +1,56 @@ +From 97a98ae5b8acf08d07d972c087b2def060bc9b73 Mon Sep 17 00:00:00 2001 +From: Alexander Sverdlin +Date: Tue, 17 Jan 2017 21:10:11 +0100 +Subject: ARM: 8642/1: LPAE: catch pending imprecise abort on unmask + +From: Alexander Sverdlin + +commit 97a98ae5b8acf08d07d972c087b2def060bc9b73 upstream. + +Asynchronous external abort is coded differently in DFSR with LPAE enabled. + +Fixes: 9254970c "ARM: 8447/1: catch pending imprecise abort on unmask". +Signed-off-by: Alexander Sverdlin +Cc: Russell King +Cc: Andrew Morton +Cc: linux-arm-kernel@lists.infradead.org +Signed-off-by: Russell King +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/mm/fault.c | 4 ++-- + arch/arm/mm/fault.h | 4 ++++ + 2 files changed, 6 insertions(+), 2 deletions(-) + +--- a/arch/arm/mm/fault.c ++++ b/arch/arm/mm/fault.c +@@ -610,9 +610,9 @@ static int __init early_abort_handler(un + + void __init early_abt_enable(void) + { +- fsr_info[22].fn = early_abort_handler; ++ fsr_info[FSR_FS_AEA].fn = early_abort_handler; + local_abt_enable(); +- fsr_info[22].fn = do_bad; ++ fsr_info[FSR_FS_AEA].fn = do_bad; + } + + #ifndef CONFIG_ARM_LPAE +--- a/arch/arm/mm/fault.h ++++ b/arch/arm/mm/fault.h +@@ -11,11 +11,15 @@ + #define FSR_FS5_0 (0x3f) + + #ifdef CONFIG_ARM_LPAE ++#define FSR_FS_AEA 17 ++ + static inline int fsr_fs(unsigned int fsr) + { + return fsr & FSR_FS5_0; + } + #else ++#define FSR_FS_AEA 22 ++ + static inline int fsr_fs(unsigned int fsr) + { + return (fsr & FSR_FS3_0) | (fsr & FSR_FS4) >> 6; diff --git a/queue-4.4/arm-8643-3-arm-ptrace-preserve-previous-registers-for-short-regset-write.patch b/queue-4.4/arm-8643-3-arm-ptrace-preserve-previous-registers-for-short-regset-write.patch new file mode 100644 index 00000000000..70d0cc2d596 --- /dev/null +++ b/queue-4.4/arm-8643-3-arm-ptrace-preserve-previous-registers-for-short-regset-write.patch @@ -0,0 +1,34 @@ +From 228dbbfb5d77f8e047b2a1d78da14b7158433027 Mon Sep 17 00:00:00 2001 +From: Dave Martin +Date: Wed, 18 Jan 2017 17:11:56 +0100 +Subject: ARM: 8643/3: arm/ptrace: Preserve previous registers for short regset write + +From: Dave Martin + +commit 228dbbfb5d77f8e047b2a1d78da14b7158433027 upstream. + +Ensure that if userspace supplies insufficient data to +PTRACE_SETREGSET to fill all the registers, the thread's old +registers are preserved. + +Fixes: 5be6f62b0059 ("ARM: 6883/1: ptrace: Migrate to regsets framework") +Signed-off-by: Dave Martin +Acked-by: Russell King +Signed-off-by: Russell King +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/kernel/ptrace.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/kernel/ptrace.c ++++ b/arch/arm/kernel/ptrace.c +@@ -600,7 +600,7 @@ static int gpr_set(struct task_struct *t + const void *kbuf, const void __user *ubuf) + { + int ret; +- struct pt_regs newregs; ++ struct pt_regs newregs = *task_pt_regs(target); + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, + &newregs, diff --git a/queue-4.4/cpumask-use-nr_cpumask_bits-for-parsing-functions.patch b/queue-4.4/cpumask-use-nr_cpumask_bits-for-parsing-functions.patch new file mode 100644 index 00000000000..46f6efb7559 --- /dev/null +++ b/queue-4.4/cpumask-use-nr_cpumask_bits-for-parsing-functions.patch @@ -0,0 +1,84 @@ +From 4d59b6ccf000862beed6fc0765d3209f98a8d8a2 Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Wed, 8 Feb 2017 14:30:56 -0800 +Subject: cpumask: use nr_cpumask_bits for parsing functions + +From: Tejun Heo + +commit 4d59b6ccf000862beed6fc0765d3209f98a8d8a2 upstream. + +Commit 513e3d2d11c9 ("cpumask: always use nr_cpu_ids in formatting and +parsing functions") converted both cpumask printing and parsing +functions to use nr_cpu_ids instead of nr_cpumask_bits. While this was +okay for the printing functions as it just picked one of the two output +formats that we were alternating between depending on a kernel config, +doing the same for parsing wasn't okay. + +nr_cpumask_bits can be either nr_cpu_ids or NR_CPUS. We can always use +nr_cpu_ids but that is a variable while NR_CPUS is a constant, so it can +be more efficient to use NR_CPUS when we can get away with it. +Converting the printing functions to nr_cpu_ids makes sense because it +affects how the masks get presented to userspace and doesn't break +anything; however, using nr_cpu_ids for parsing functions can +incorrectly leave the higher bits uninitialized while reading in these +masks from userland. As all testing and comparison functions use +nr_cpumask_bits which can be larger than nr_cpu_ids, the parsed cpumasks +can erroneously yield false negative results. + +This made the taskstats interface incorrectly return -EINVAL even when +the inputs were correct. + +Fix it by restoring the parse functions to use nr_cpumask_bits instead +of nr_cpu_ids. + +Link: http://lkml.kernel.org/r/20170206182442.GB31078@htj.duckdns.org +Fixes: 513e3d2d11c9 ("cpumask: always use nr_cpu_ids in formatting and parsing functions") +Signed-off-by: Tejun Heo +Reported-by: Martin Steigerwald +Debugged-by: Ben Hutchings +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/cpumask.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/include/linux/cpumask.h ++++ b/include/linux/cpumask.h +@@ -556,7 +556,7 @@ static inline void cpumask_copy(struct c + static inline int cpumask_parse_user(const char __user *buf, int len, + struct cpumask *dstp) + { +- return bitmap_parse_user(buf, len, cpumask_bits(dstp), nr_cpu_ids); ++ return bitmap_parse_user(buf, len, cpumask_bits(dstp), nr_cpumask_bits); + } + + /** +@@ -571,7 +571,7 @@ static inline int cpumask_parselist_user + struct cpumask *dstp) + { + return bitmap_parselist_user(buf, len, cpumask_bits(dstp), +- nr_cpu_ids); ++ nr_cpumask_bits); + } + + /** +@@ -586,7 +586,7 @@ static inline int cpumask_parse(const ch + char *nl = strchr(buf, '\n'); + unsigned int len = nl ? (unsigned int)(nl - buf) : strlen(buf); + +- return bitmap_parse(buf, len, cpumask_bits(dstp), nr_cpu_ids); ++ return bitmap_parse(buf, len, cpumask_bits(dstp), nr_cpumask_bits); + } + + /** +@@ -598,7 +598,7 @@ static inline int cpumask_parse(const ch + */ + static inline int cpulist_parse(const char *buf, struct cpumask *dstp) + { +- return bitmap_parselist(buf, cpumask_bits(dstp), nr_cpu_ids); ++ return bitmap_parselist(buf, cpumask_bits(dstp), nr_cpumask_bits); + } + + /** diff --git a/queue-4.4/hns-avoid-stack-overflow-with-config_kasan.patch b/queue-4.4/hns-avoid-stack-overflow-with-config_kasan.patch new file mode 100644 index 00000000000..68c594288e6 --- /dev/null +++ b/queue-4.4/hns-avoid-stack-overflow-with-config_kasan.patch @@ -0,0 +1,82 @@ +From b3f2d07f4649adcf6905953a10d217b5683e4077 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Fri, 3 Feb 2017 17:35:46 +0100 +Subject: hns: avoid stack overflow with CONFIG_KASAN + +From: Arnd Bergmann + +commit b3f2d07f4649adcf6905953a10d217b5683e4077 upstream. + +The use of ACCESS_ONCE() looks like a micro-optimization to force gcc to use +an indexed load for the register address, but it has an absolutely detrimental +effect on builds with gcc-5 and CONFIG_KASAN=y, leading to a very likely +kernel stack overflow aside from very complex object code: + +hisilicon/hns/hns_dsaf_gmac.c: In function 'hns_gmac_update_stats': +hisilicon/hns/hns_dsaf_gmac.c:419:1: error: the frame size of 2912 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] +hisilicon/hns/hns_dsaf_ppe.c: In function 'hns_ppe_reset_common': +hisilicon/hns/hns_dsaf_ppe.c:390:1: error: the frame size of 1184 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] +hisilicon/hns/hns_dsaf_ppe.c: In function 'hns_ppe_get_regs': +hisilicon/hns/hns_dsaf_ppe.c:621:1: error: the frame size of 3632 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] +hisilicon/hns/hns_dsaf_rcb.c: In function 'hns_rcb_get_common_regs': +hisilicon/hns/hns_dsaf_rcb.c:970:1: error: the frame size of 2784 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] +hisilicon/hns/hns_dsaf_gmac.c: In function 'hns_gmac_get_regs': +hisilicon/hns/hns_dsaf_gmac.c:641:1: error: the frame size of 5728 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] +hisilicon/hns/hns_dsaf_rcb.c: In function 'hns_rcb_get_ring_regs': +hisilicon/hns/hns_dsaf_rcb.c:1021:1: error: the frame size of 2208 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] +hisilicon/hns/hns_dsaf_main.c: In function 'hns_dsaf_comm_init': +hisilicon/hns/hns_dsaf_main.c:1209:1: error: the frame size of 1904 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] +hisilicon/hns/hns_dsaf_xgmac.c: In function 'hns_xgmac_get_regs': +hisilicon/hns/hns_dsaf_xgmac.c:748:1: error: the frame size of 4704 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] +hisilicon/hns/hns_dsaf_main.c: In function 'hns_dsaf_update_stats': +hisilicon/hns/hns_dsaf_main.c:2420:1: error: the frame size of 1088 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] +hisilicon/hns/hns_dsaf_main.c: In function 'hns_dsaf_get_regs': +hisilicon/hns/hns_dsaf_main.c:2753:1: error: the frame size of 10768 bytes is larger than 1024 bytes [-Werror=frame-larger-than=] + +This does not seem to happen any more with gcc-7, but removing the ACCESS_ONCE +seems safe anyway and it avoids a serious issue for some people. I have verified +that with gcc-5.3.1, the object code we get is better in the new version +both with and without CONFIG_KASAN, as we no longer allocate a 1344 byte +stack frame for hns_dsaf_get_regs() but otherwise have practically identical +object code. + +With gcc-7.0.0, removing ACCESS_ONCE has no effect, the object code is already +good either way. + +This patch is probably not urgent to get into 4.11 as only KASAN=y builds +with certain compilers are affected, but I still think it makes sense to +backport into older kernels. + +Fixes: 511e6bc ("net: add Hisilicon Network Subsystem DSAF support") +Signed-off-by: Arnd Bergmann +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h ++++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h +@@ -900,9 +900,7 @@ + + static inline void dsaf_write_reg(void __iomem *base, u32 reg, u32 value) + { +- u8 __iomem *reg_addr = ACCESS_ONCE(base); +- +- writel(value, reg_addr + reg); ++ writel(value, base + reg); + } + + #define dsaf_write_dev(a, reg, value) \ +@@ -910,9 +908,7 @@ static inline void dsaf_write_reg(void _ + + static inline u32 dsaf_read_reg(u8 __iomem *base, u32 reg) + { +- u8 __iomem *reg_addr = ACCESS_ONCE(base); +- +- return readl(reg_addr + reg); ++ return readl(base + reg); + } + + #define dsaf_read_dev(a, reg) \ diff --git a/queue-4.4/mac80211-fix-adding-of-mesh-vendor-ies.patch b/queue-4.4/mac80211-fix-adding-of-mesh-vendor-ies.patch new file mode 100644 index 00000000000..15af3e7dcf2 --- /dev/null +++ b/queue-4.4/mac80211-fix-adding-of-mesh-vendor-ies.patch @@ -0,0 +1,39 @@ +From da7061c82e4a1bc6a5e134ef362c86261906c860 Mon Sep 17 00:00:00 2001 +From: Thorsten Horstmann +Date: Fri, 3 Feb 2017 14:38:29 +0100 +Subject: mac80211: Fix adding of mesh vendor IEs + +From: Thorsten Horstmann + +commit da7061c82e4a1bc6a5e134ef362c86261906c860 upstream. + +The function ieee80211_ie_split_vendor doesn't return 0 on errors. Instead +it returns any offset < ielen when WLAN_EID_VENDOR_SPECIFIC is found. The +return value in mesh_add_vendor_ies must therefore be checked against +ifmsh->ie_len and not 0. Otherwise all ifmsh->ie starting with +WLAN_EID_VENDOR_SPECIFIC will be rejected. + +Fixes: 082ebb0c258d ("mac80211: fix mesh beacon format") +Signed-off-by: Thorsten Horstmann +Signed-off-by: Mathias Kretschmer +Signed-off-by: Simon Wunderlich +[sven@narfation.org: Add commit message] +Signed-off-by: Sven Eckelmann +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/mesh.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -355,7 +355,7 @@ int mesh_add_vendor_ies(struct ieee80211 + /* fast-forward to vendor IEs */ + offset = ieee80211_ie_split_vendor(ifmsh->ie, ifmsh->ie_len, 0); + +- if (offset) { ++ if (offset < ifmsh->ie_len) { + len = ifmsh->ie_len - offset; + data = ifmsh->ie + offset; + if (skb_tailroom(skb) < len) diff --git a/queue-4.4/series b/queue-4.4/series index b2a57f45f49..885de152d30 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -1,3 +1,12 @@ arc-brown-paper-bag-bug-in-unaligned-access-delay-slot-fixup.patch selinux-fix-off-by-one-in-setprocattr.patch revert-x86-ioapic-restore-io-apic-irq_chip-retrigger-callback.patch +cpumask-use-nr_cpumask_bits-for-parsing-functions.patch +hns-avoid-stack-overflow-with-config_kasan.patch +arm-8643-3-arm-ptrace-preserve-previous-registers-for-short-regset-write.patch +target-don-t-bug_on-during-nodeacl-dynamic-explicit-conversion.patch +target-use-correct-scsi-status-during-extended_copy-exception.patch +target-fix-early-transport_generic_handle_tmr-abort-scenario.patch +target-fix-compare_and_write-ref-leak-for-non-good-status.patch +arm-8642-1-lpae-catch-pending-imprecise-abort-on-unmask.patch +mac80211-fix-adding-of-mesh-vendor-ies.patch diff --git a/queue-4.4/target-don-t-bug_on-during-nodeacl-dynamic-explicit-conversion.patch b/queue-4.4/target-don-t-bug_on-during-nodeacl-dynamic-explicit-conversion.patch new file mode 100644 index 00000000000..eec3a987f25 --- /dev/null +++ b/queue-4.4/target-don-t-bug_on-during-nodeacl-dynamic-explicit-conversion.patch @@ -0,0 +1,51 @@ +From 391e2a6de9781e4906dd7e0b1cc097050bf43e11 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Sun, 23 Oct 2016 14:28:15 -0700 +Subject: target: Don't BUG_ON during NodeACL dynamic -> explicit conversion + +From: Nicholas Bellinger + +commit 391e2a6de9781e4906dd7e0b1cc097050bf43e11 upstream. + +After the v4.2+ RCU conversion to se_node_acl->lun_entry_hlist, +a BUG_ON() was added in core_enable_device_list_for_node() to +detect when the located orig->se_lun_acl contains an existing +se_lun_acl pointer reference. + +However, this scenario can happen when a dynamically generated +NodeACL is being converted to an explicit NodeACL, when the +explicit NodeACL contains a different LUN mapping than the +default provided by the WWN endpoint. + +So instead of triggering BUG_ON(), go ahead and fail instead +following the original pre RCU conversion logic. + +Reported-by: Benjamin ESTRABAUD +Cc: Benjamin ESTRABAUD +Reviewed-by: Christoph Hellwig +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_device.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/target/target_core_device.c ++++ b/drivers/target/target_core_device.c +@@ -362,7 +362,15 @@ int core_enable_device_list_for_node( + kfree(new); + return -EINVAL; + } +- BUG_ON(orig->se_lun_acl != NULL); ++ if (orig->se_lun_acl != NULL) { ++ pr_warn_ratelimited("Detected existing explicit" ++ " se_lun_acl->se_lun_group reference for %s" ++ " mapped_lun: %llu, failing\n", ++ nacl->initiatorname, mapped_lun); ++ mutex_unlock(&nacl->lun_entry_mutex); ++ kfree(new); ++ return -EINVAL; ++ } + + rcu_assign_pointer(new->se_lun, lun); + rcu_assign_pointer(new->se_lun_acl, lun_acl); diff --git a/queue-4.4/target-fix-compare_and_write-ref-leak-for-non-good-status.patch b/queue-4.4/target-fix-compare_and_write-ref-leak-for-non-good-status.patch new file mode 100644 index 00000000000..675101d65d1 --- /dev/null +++ b/queue-4.4/target-fix-compare_and_write-ref-leak-for-non-good-status.patch @@ -0,0 +1,73 @@ +From 9b2792c3da1e80f2d460167d319302a24c9ca2b7 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Mon, 6 Feb 2017 14:28:09 -0800 +Subject: target: Fix COMPARE_AND_WRITE ref leak for non GOOD status + +From: Nicholas Bellinger + +commit 9b2792c3da1e80f2d460167d319302a24c9ca2b7 upstream. + +This patch addresses a long standing bug where the commit phase +of COMPARE_AND_WRITE would result in a se_cmd->cmd_kref reference +leak if se_cmd->scsi_status returned non SAM_STAT_GOOD. + +This would manifest first as a lost SCSI response, and eventual +hung task during fabric driver logout or re-login, as existing +shutdown logic waited for the COMPARE_AND_WRITE se_cmd->cmd_kref +to reach zero. + +To address this bug, compare_and_write_post() has been changed +to drop the incorrect !cmd->scsi_status conditional that was +preventing *post_ret = 1 for being set during non SAM_STAT_GOOD +status. + +This patch has been tested with SAM_STAT_CHECK_CONDITION status +from normal target_complete_cmd() callback path, as well as the +incoming __target_execute_cmd() submission failure path when +se_cmd->execute_cmd() returns non zero status. + +Reported-by: Donald White +Cc: Donald White +Tested-by: Gary Guo +Cc: Gary Guo +Reviewed-by: Christoph Hellwig +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_sbc.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/drivers/target/target_core_sbc.c ++++ b/drivers/target/target_core_sbc.c +@@ -442,6 +442,7 @@ static sense_reason_t compare_and_write_ + int *post_ret) + { + struct se_device *dev = cmd->se_dev; ++ sense_reason_t ret = TCM_NO_SENSE; + + /* + * Only set SCF_COMPARE_AND_WRITE_POST to force a response fall-through +@@ -449,9 +450,12 @@ static sense_reason_t compare_and_write_ + * sent to the backend driver. + */ + spin_lock_irq(&cmd->t_state_lock); +- if ((cmd->transport_state & CMD_T_SENT) && !cmd->scsi_status) { ++ if (cmd->transport_state & CMD_T_SENT) { + cmd->se_cmd_flags |= SCF_COMPARE_AND_WRITE_POST; + *post_ret = 1; ++ ++ if (cmd->scsi_status == SAM_STAT_CHECK_CONDITION) ++ ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; + } + spin_unlock_irq(&cmd->t_state_lock); + +@@ -461,7 +465,7 @@ static sense_reason_t compare_and_write_ + */ + up(&dev->caw_sem); + +- return TCM_NO_SENSE; ++ return ret; + } + + static sense_reason_t compare_and_write_callback(struct se_cmd *cmd, bool success, diff --git a/queue-4.4/target-fix-early-transport_generic_handle_tmr-abort-scenario.patch b/queue-4.4/target-fix-early-transport_generic_handle_tmr-abort-scenario.patch new file mode 100644 index 00000000000..3e9979e5749 --- /dev/null +++ b/queue-4.4/target-fix-early-transport_generic_handle_tmr-abort-scenario.patch @@ -0,0 +1,77 @@ +From c54eeffbe9338fa982dc853d816fda9202a13b5a Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Tue, 6 Dec 2016 22:45:46 -0800 +Subject: target: Fix early transport_generic_handle_tmr abort scenario + +From: Nicholas Bellinger + +commit c54eeffbe9338fa982dc853d816fda9202a13b5a upstream. + +This patch fixes a bug where incoming task management requests +can be explicitly aborted during an active LUN_RESET, but who's +struct work_struct are canceled in-flight before execution. + +This occurs when core_tmr_drain_tmr_list() invokes cancel_work_sync() +for the incoming se_tmr_req->task_cmd->work, resulting in cmd->work +for target_tmr_work() never getting invoked and the aborted TMR +waiting indefinately within transport_wait_for_tasks(). + +To address this case, perform a CMD_T_ABORTED check early in +transport_generic_handle_tmr(), and invoke the normal path via +transport_cmd_check_stop_to_fabric() to complete any TMR kthreads +blocked waiting for CMD_T_STOP in transport_wait_for_tasks(). + +Also, move the TRANSPORT_ISTATE_PROCESSING assignment earlier +into transport_generic_handle_tmr() so the existing check in +core_tmr_drain_tmr_list() avoids attempting abort the incoming +se_tmr_req->task_cmd->work if it has already been queued into +se_device->tmr_wq. + +Reported-by: Rob Millner +Tested-by: Rob Millner +Cc: Rob Millner +Reviewed-by: Christoph Hellwig +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_transport.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +--- a/drivers/target/target_core_transport.c ++++ b/drivers/target/target_core_transport.c +@@ -3058,7 +3058,6 @@ static void target_tmr_work(struct work_ + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + goto check_stop; + } +- cmd->t_state = TRANSPORT_ISTATE_PROCESSING; + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + + cmd->se_tfo->queue_tm_rsp(cmd); +@@ -3071,11 +3070,25 @@ int transport_generic_handle_tmr( + struct se_cmd *cmd) + { + unsigned long flags; ++ bool aborted = false; + + spin_lock_irqsave(&cmd->t_state_lock, flags); +- cmd->transport_state |= CMD_T_ACTIVE; ++ if (cmd->transport_state & CMD_T_ABORTED) { ++ aborted = true; ++ } else { ++ cmd->t_state = TRANSPORT_ISTATE_PROCESSING; ++ cmd->transport_state |= CMD_T_ACTIVE; ++ } + spin_unlock_irqrestore(&cmd->t_state_lock, flags); + ++ if (aborted) { ++ pr_warn_ratelimited("handle_tmr caught CMD_T_ABORTED TMR %d" ++ "ref_tag: %llu tag: %llu\n", cmd->se_tmr_req->function, ++ cmd->se_tmr_req->ref_task_tag, cmd->tag); ++ transport_cmd_check_stop_to_fabric(cmd); ++ return 0; ++ } ++ + INIT_WORK(&cmd->work, target_tmr_work); + queue_work(cmd->se_dev->tmr_wq, &cmd->work); + return 0; diff --git a/queue-4.4/target-use-correct-scsi-status-during-extended_copy-exception.patch b/queue-4.4/target-use-correct-scsi-status-during-extended_copy-exception.patch new file mode 100644 index 00000000000..252ab9851e5 --- /dev/null +++ b/queue-4.4/target-use-correct-scsi-status-during-extended_copy-exception.patch @@ -0,0 +1,44 @@ +From 0583c261e6325f392c1f7a1b9112e31298e1a4bd Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Mon, 31 Oct 2016 00:54:40 -0700 +Subject: target: Use correct SCSI status during EXTENDED_COPY exception + +From: Nicholas Bellinger + +commit 0583c261e6325f392c1f7a1b9112e31298e1a4bd upstream. + +This patch adds the missing target_complete_cmd() SCSI status +parameter change in target_xcopy_do_work(), that was originally +missing in commit 926317de33. + +It correctly propigates up the correct SCSI status during +EXTENDED_COPY exception cases, instead of always using the +hardcoded SAM_STAT_CHECK_CONDITION from original code. + +This is required for ESX host environments that expect to +hit SAM_STAT_RESERVATION_CONFLICT for certain scenarios, +and SAM_STAT_CHECK_CONDITION results in non-retriable +status for these cases. + +Reported-by: Nixon Vincent +Tested-by: Nixon Vincent +Cc: Nixon Vincent +Reviewed-by: Christoph Hellwig +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_xcopy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/target/target_core_xcopy.c ++++ b/drivers/target/target_core_xcopy.c +@@ -836,7 +836,7 @@ out: + " CHECK_CONDITION -> sending response\n", rc); + ec_cmd->scsi_status = SAM_STAT_CHECK_CONDITION; + } +- target_complete_cmd(ec_cmd, SAM_STAT_CHECK_CONDITION); ++ target_complete_cmd(ec_cmd, ec_cmd->scsi_status); + } + + sense_reason_t target_do_xcopy(struct se_cmd *se_cmd)