From: Greg Kroah-Hartman Date: Tue, 24 Mar 2015 15:40:16 +0000 (+0100) Subject: 3.14-stable patches X-Git-Tag: v3.19.3~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=840d66d991b09aaabb9c43eb20b2ebe50b4b5e02;p=thirdparty%2Fkernel%2Fstable-queue.git 3.14-stable patches added patches: arm-at91-pm-fix-at91rm9200-standby.patch arm-dts-dra7x-fix-the-bypass-clock-source-for-dpll_iva-and-others.patch arm-imx6qdl-sabresd-set-swbst_reg-as-vbus-s-parent-reg.patch iscsi-target-avoid-early-conn_logout_comp-for-iser-connections.patch target-allow-allregistrants-to-re-reserve-existing-reservation.patch target-allow-write-exclusive-non-reservation-holders-to-read.patch target-avoid-dropping-allregistrants-reservation-during-unregister.patch target-fix-r_holder-bit-usage-for-allregistrants.patch target-fix-reference-leak-in-target_get_sess_cmd-error-path.patch target-fix-virtual-lun-0-target_configure_device-failure-oops.patch target-pscsi-fix-null-pointer-dereference-in-get_device_type.patch --- diff --git a/queue-3.14/arm-at91-pm-fix-at91rm9200-standby.patch b/queue-3.14/arm-at91-pm-fix-at91rm9200-standby.patch new file mode 100644 index 00000000000..4d4ae059327 --- /dev/null +++ b/queue-3.14/arm-at91-pm-fix-at91rm9200-standby.patch @@ -0,0 +1,36 @@ +From 84e871660bebfddb9a62ebd6f19d02536e782f0a Mon Sep 17 00:00:00 2001 +From: Alexandre Belloni +Date: Tue, 3 Mar 2015 19:58:22 +0100 +Subject: ARM: at91: pm: fix at91rm9200 standby + +From: Alexandre Belloni + +commit 84e871660bebfddb9a62ebd6f19d02536e782f0a upstream. + +at91rm9200 standby and suspend to ram has been broken since +00482a4078f4. It is wrongly using AT91_BASE_SYS which is a physical address +and actually doesn't correspond to any register on at91rm9200. + +Use the correct at91_ramc_base[0] instead. + +Fixes: 00482a4078f4 (ARM: at91: implement the standby function for pm/cpuidle) + +Signed-off-by: Alexandre Belloni +Signed-off-by: Nicolas Ferre +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/mach-at91/pm.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm/mach-at91/pm.h ++++ b/arch/arm/mach-at91/pm.h +@@ -45,7 +45,7 @@ static inline void at91rm9200_standby(vo + " mcr p15, 0, %0, c7, c0, 4\n\t" + " str %5, [%1, %2]" + : +- : "r" (0), "r" (AT91_BASE_SYS), "r" (AT91RM9200_SDRAMC_LPR), ++ : "r" (0), "r" (at91_ramc_base[0]), "r" (AT91RM9200_SDRAMC_LPR), + "r" (1), "r" (AT91RM9200_SDRAMC_SRR), + "r" (lpr)); + } diff --git a/queue-3.14/arm-dts-dra7x-fix-the-bypass-clock-source-for-dpll_iva-and-others.patch b/queue-3.14/arm-dts-dra7x-fix-the-bypass-clock-source-for-dpll_iva-and-others.patch new file mode 100644 index 00000000000..e877691e089 --- /dev/null +++ b/queue-3.14/arm-dts-dra7x-fix-the-bypass-clock-source-for-dpll_iva-and-others.patch @@ -0,0 +1,221 @@ +From d2192ea09858a8535b056fcede1a41d824e0b3d8 Mon Sep 17 00:00:00 2001 +From: Ravikumar Kattekola +Date: Sat, 31 Jan 2015 22:36:44 +0530 +Subject: ARM: dts: DRA7x: Fix the bypass clock source for dpll_iva and others + +From: Ravikumar Kattekola + +commit d2192ea09858a8535b056fcede1a41d824e0b3d8 upstream. + +Fixes: ee6c750761 (ARM: dts: dra7 clock data) + +On DRA7x, For DPLL_IVA, the ref clock(CLKINP) is connected to sys_clk1 and +the bypass input(CLKINPULOW) is connected to iva_dpll_hs_clk_div clock. +But the bypass input is not directly routed to bypass clkout instead +both CLKINP and CLKINPULOW are connected to bypass clkout via a mux. + +This mux is controlled by the bit - CM_CLKSEL_DPLL_IVA[23]:DPLL_BYP_CLKSEL +and it's POR value is zero which selects the CLKINP as bypass clkout. +which means iva_dpll_hs_clk_div is not the bypass clock for dpll_iva_ck + +Fix this by adding another mux clock as parent in bypass mode. + +This design is common to most of the PLLs and the rest have only one bypass +clock. Below is a list of the DPLLs that need this fix: + +DPLL_IVA, DPLL_DDR, +DPLL_DSP, DPLL_EVE, +DPLL_GMAC, DPLL_PER, +DPLL_USB and DPLL_CORE + +Signed-off-by: Ravikumar Kattekola +Acked-by: Tero Kristo +Signed-off-by: Tony Lindgren +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/boot/dts/dra7xx-clocks.dtsi | 90 +++++++++++++++++++++++++++++++---- + 1 file changed, 81 insertions(+), 9 deletions(-) + +--- a/arch/arm/boot/dts/dra7xx-clocks.dtsi ++++ b/arch/arm/boot/dts/dra7xx-clocks.dtsi +@@ -243,10 +243,18 @@ + ti,invert-autoidle-bit; + }; + ++ dpll_core_byp_mux: dpll_core_byp_mux { ++ #clock-cells = <0>; ++ compatible = "ti,mux-clock"; ++ clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; ++ ti,bit-shift = <23>; ++ reg = <0x012c>; ++ }; ++ + dpll_core_ck: dpll_core_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-core-clock"; +- clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; ++ clocks = <&sys_clkin1>, <&dpll_core_byp_mux>; + reg = <0x0120>, <0x0124>, <0x012c>, <0x0128>; + }; + +@@ -309,10 +317,18 @@ + clock-div = <1>; + }; + ++ dpll_dsp_byp_mux: dpll_dsp_byp_mux { ++ #clock-cells = <0>; ++ compatible = "ti,mux-clock"; ++ clocks = <&sys_clkin1>, <&dsp_dpll_hs_clk_div>; ++ ti,bit-shift = <23>; ++ reg = <0x0240>; ++ }; ++ + dpll_dsp_ck: dpll_dsp_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-clock"; +- clocks = <&sys_clkin1>, <&dsp_dpll_hs_clk_div>; ++ clocks = <&sys_clkin1>, <&dpll_dsp_byp_mux>; + reg = <0x0234>, <0x0238>, <0x0240>, <0x023c>; + }; + +@@ -335,10 +351,18 @@ + clock-div = <1>; + }; + ++ dpll_iva_byp_mux: dpll_iva_byp_mux { ++ #clock-cells = <0>; ++ compatible = "ti,mux-clock"; ++ clocks = <&sys_clkin1>, <&iva_dpll_hs_clk_div>; ++ ti,bit-shift = <23>; ++ reg = <0x01ac>; ++ }; ++ + dpll_iva_ck: dpll_iva_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-clock"; +- clocks = <&sys_clkin1>, <&iva_dpll_hs_clk_div>; ++ clocks = <&sys_clkin1>, <&dpll_iva_byp_mux>; + reg = <0x01a0>, <0x01a4>, <0x01ac>, <0x01a8>; + }; + +@@ -361,10 +385,18 @@ + clock-div = <1>; + }; + ++ dpll_gpu_byp_mux: dpll_gpu_byp_mux { ++ #clock-cells = <0>; ++ compatible = "ti,mux-clock"; ++ clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; ++ ti,bit-shift = <23>; ++ reg = <0x02e4>; ++ }; ++ + dpll_gpu_ck: dpll_gpu_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-clock"; +- clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; ++ clocks = <&sys_clkin1>, <&dpll_gpu_byp_mux>; + reg = <0x02d8>, <0x02dc>, <0x02e4>, <0x02e0>; + }; + +@@ -398,10 +430,18 @@ + clock-div = <1>; + }; + ++ dpll_ddr_byp_mux: dpll_ddr_byp_mux { ++ #clock-cells = <0>; ++ compatible = "ti,mux-clock"; ++ clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; ++ ti,bit-shift = <23>; ++ reg = <0x021c>; ++ }; ++ + dpll_ddr_ck: dpll_ddr_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-clock"; +- clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; ++ clocks = <&sys_clkin1>, <&dpll_ddr_byp_mux>; + reg = <0x0210>, <0x0214>, <0x021c>, <0x0218>; + }; + +@@ -416,10 +456,18 @@ + ti,invert-autoidle-bit; + }; + ++ dpll_gmac_byp_mux: dpll_gmac_byp_mux { ++ #clock-cells = <0>; ++ compatible = "ti,mux-clock"; ++ clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; ++ ti,bit-shift = <23>; ++ reg = <0x02b4>; ++ }; ++ + dpll_gmac_ck: dpll_gmac_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-clock"; +- clocks = <&sys_clkin1>, <&dpll_abe_m3x2_ck>; ++ clocks = <&sys_clkin1>, <&dpll_gmac_byp_mux>; + reg = <0x02a8>, <0x02ac>, <0x02b4>, <0x02b0>; + }; + +@@ -482,10 +530,18 @@ + clock-div = <1>; + }; + ++ dpll_eve_byp_mux: dpll_eve_byp_mux { ++ #clock-cells = <0>; ++ compatible = "ti,mux-clock"; ++ clocks = <&sys_clkin1>, <&eve_dpll_hs_clk_div>; ++ ti,bit-shift = <23>; ++ reg = <0x0290>; ++ }; ++ + dpll_eve_ck: dpll_eve_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-clock"; +- clocks = <&sys_clkin1>, <&eve_dpll_hs_clk_div>; ++ clocks = <&sys_clkin1>, <&dpll_eve_byp_mux>; + reg = <0x0284>, <0x0288>, <0x0290>, <0x028c>; + }; + +@@ -1214,10 +1270,18 @@ + clock-div = <1>; + }; + ++ dpll_per_byp_mux: dpll_per_byp_mux { ++ #clock-cells = <0>; ++ compatible = "ti,mux-clock"; ++ clocks = <&sys_clkin1>, <&per_dpll_hs_clk_div>; ++ ti,bit-shift = <23>; ++ reg = <0x014c>; ++ }; ++ + dpll_per_ck: dpll_per_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-clock"; +- clocks = <&sys_clkin1>, <&per_dpll_hs_clk_div>; ++ clocks = <&sys_clkin1>, <&dpll_per_byp_mux>; + reg = <0x0140>, <0x0144>, <0x014c>, <0x0148>; + }; + +@@ -1240,10 +1304,18 @@ + clock-div = <1>; + }; + ++ dpll_usb_byp_mux: dpll_usb_byp_mux { ++ #clock-cells = <0>; ++ compatible = "ti,mux-clock"; ++ clocks = <&sys_clkin1>, <&usb_dpll_hs_clk_div>; ++ ti,bit-shift = <23>; ++ reg = <0x018c>; ++ }; ++ + dpll_usb_ck: dpll_usb_ck { + #clock-cells = <0>; + compatible = "ti,omap4-dpll-j-type-clock"; +- clocks = <&sys_clkin1>, <&usb_dpll_hs_clk_div>; ++ clocks = <&sys_clkin1>, <&dpll_usb_byp_mux>; + reg = <0x0180>, <0x0184>, <0x018c>, <0x0188>; + }; + diff --git a/queue-3.14/arm-imx6qdl-sabresd-set-swbst_reg-as-vbus-s-parent-reg.patch b/queue-3.14/arm-imx6qdl-sabresd-set-swbst_reg-as-vbus-s-parent-reg.patch new file mode 100644 index 00000000000..cb202f46939 --- /dev/null +++ b/queue-3.14/arm-imx6qdl-sabresd-set-swbst_reg-as-vbus-s-parent-reg.patch @@ -0,0 +1,39 @@ +From 40f737791d4dab26bf23a6331609c604142228bd Mon Sep 17 00:00:00 2001 +From: Peter Chen +Date: Fri, 6 Mar 2015 16:04:20 +0800 +Subject: ARM: imx6qdl-sabresd: set swbst_reg as vbus's parent reg + +From: Peter Chen + +commit 40f737791d4dab26bf23a6331609c604142228bd upstream. + +USB vbus 5V is from PMIC SWBST, so set swbst_reg as vbus's +parent reg, it fixed a bug that the voltage of vbus is incorrect +due to swbst_reg is disabled after boots up. + +Signed-off-by: Peter Chen +Signed-off-by: Shawn Guo +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/boot/dts/imx6qdl-sabresd.dtsi | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi ++++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi +@@ -25,6 +25,7 @@ + regulator-max-microvolt = <5000000>; + gpio = <&gpio3 22 0>; + enable-active-high; ++ vin-supply = <&swbst_reg>; + }; + + reg_usb_h1_vbus: usb_h1_vbus { +@@ -34,6 +35,7 @@ + regulator-max-microvolt = <5000000>; + gpio = <&gpio1 29 0>; + enable-active-high; ++ vin-supply = <&swbst_reg>; + }; + + reg_audio: wm8962_supply { diff --git a/queue-3.14/iscsi-target-avoid-early-conn_logout_comp-for-iser-connections.patch b/queue-3.14/iscsi-target-avoid-early-conn_logout_comp-for-iser-connections.patch new file mode 100644 index 00000000000..86b58695746 --- /dev/null +++ b/queue-3.14/iscsi-target-avoid-early-conn_logout_comp-for-iser-connections.patch @@ -0,0 +1,53 @@ +From f068fbc82e7696d67b1bb8189306865bedf368b6 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Mon, 23 Feb 2015 00:57:51 -0800 +Subject: iscsi-target: Avoid early conn_logout_comp for iser connections + +From: Nicholas Bellinger + +commit f068fbc82e7696d67b1bb8189306865bedf368b6 upstream. + +This patch fixes a iser specific logout bug where early complete() +of conn->conn_logout_comp in iscsit_close_connection() was causing +isert_wait4logout() to complete too soon, triggering a use after +free NULL pointer dereference of iscsi_conn memory. + +The complete() was originally added for traditional iscsi-target +when a ISCSI_LOGOUT_OP failed in iscsi_target_rx_opcode(), but given +iser-target does not wait in logout failure, this special case needs +to be avoided. + +Reported-by: Sagi Grimberg +Cc: Sagi Grimberg +Cc: Slava Shwartsman +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/iscsi/iscsi_target.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/drivers/target/iscsi/iscsi_target.c ++++ b/drivers/target/iscsi/iscsi_target.c +@@ -4196,11 +4196,17 @@ int iscsit_close_connection( + pr_debug("Closing iSCSI connection CID %hu on SID:" + " %u\n", conn->cid, sess->sid); + /* +- * Always up conn_logout_comp just in case the RX Thread is sleeping +- * and the logout response never got sent because the connection +- * failed. ++ * Always up conn_logout_comp for the traditional TCP case just in case ++ * the RX Thread in iscsi_target_rx_opcode() is sleeping and the logout ++ * response never got sent because the connection failed. ++ * ++ * However for iser-target, isert_wait4logout() is using conn_logout_comp ++ * to signal logout response TX interrupt completion. Go ahead and skip ++ * this for iser since isert_rx_opcode() does not wait on logout failure, ++ * and to avoid iscsi_conn pointer dereference in iser-target code. + */ +- complete(&conn->conn_logout_comp); ++ if (conn->conn_transport->transport_type == ISCSI_TCP) ++ complete(&conn->conn_logout_comp); + + iscsi_release_thread_set(conn); + diff --git a/queue-3.14/series b/queue-3.14/series index f3c2be1ab4e..271de7e0549 100644 --- a/queue-3.14/series +++ b/queue-3.14/series @@ -66,3 +66,14 @@ netfilter-nft_compat-fix-module-refcount-underflow.patch netfilter-xt_socket-fix-a-stack-corruption-bug.patch arm-imx6sl-evk-set-swbst_reg-as-vbus-s-parent-reg.patch arm64-honor-__gfp_zero-in-dma-allocations.patch +arm-imx6qdl-sabresd-set-swbst_reg-as-vbus-s-parent-reg.patch +arm-at91-pm-fix-at91rm9200-standby.patch +arm-dts-dra7x-fix-the-bypass-clock-source-for-dpll_iva-and-others.patch +target-fix-reference-leak-in-target_get_sess_cmd-error-path.patch +target-fix-virtual-lun-0-target_configure_device-failure-oops.patch +iscsi-target-avoid-early-conn_logout_comp-for-iser-connections.patch +target-pscsi-fix-null-pointer-dereference-in-get_device_type.patch +target-fix-r_holder-bit-usage-for-allregistrants.patch +target-avoid-dropping-allregistrants-reservation-during-unregister.patch +target-allow-allregistrants-to-re-reserve-existing-reservation.patch +target-allow-write-exclusive-non-reservation-holders-to-read.patch diff --git a/queue-3.14/target-allow-allregistrants-to-re-reserve-existing-reservation.patch b/queue-3.14/target-allow-allregistrants-to-re-reserve-existing-reservation.patch new file mode 100644 index 00000000000..50b9b498111 --- /dev/null +++ b/queue-3.14/target-allow-allregistrants-to-re-reserve-existing-reservation.patch @@ -0,0 +1,57 @@ +From ae450e246e8540300699480a3780a420a028b73f Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Fri, 19 Dec 2014 00:49:23 +0000 +Subject: target: Allow AllRegistrants to re-RESERVE existing reservation + +From: Nicholas Bellinger + +commit ae450e246e8540300699480a3780a420a028b73f upstream. + +This patch changes core_scsi3_pro_release() logic to allow an +existing AllRegistrants type reservation to be re-reserved by +any registered I_T nexus. + +This addresses a issue where AllRegistrants type RESERVE was +receiving RESERVATION_CONFLICT status if dev_pr_res_holder did +not match the same I_T nexus, instead of just returning GOOD +status following spc4r34 Section 5.9.9: + +"If the device server receives a PERSISTENT RESERVE OUT command + with RESERVE service action where the TYPE field and the SCOPE + field contain the same values as the existing type and scope + from a persistent reservation holder, it shall not make any + change to the existing persistent reservation and shall complete + the command with GOOD status." + +Reported-by: Ilias Tsitsimpis +Cc: Ilias Tsitsimpis +Cc: Lee Duncan +Cc: James Bottomley +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_pr.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/target/target_core_pr.c ++++ b/drivers/target/target_core_pr.c +@@ -2297,6 +2297,7 @@ core_scsi3_pro_reserve(struct se_cmd *cm + spin_lock(&dev->dev_reservation_lock); + pr_res_holder = dev->dev_pr_res_holder; + if (pr_res_holder) { ++ int pr_res_type = pr_res_holder->pr_res_type; + /* + * From spc4r17 Section 5.7.9: Reserving: + * +@@ -2307,7 +2308,9 @@ core_scsi3_pro_reserve(struct se_cmd *cm + * the logical unit, then the command shall be completed with + * RESERVATION CONFLICT status. + */ +- if (pr_res_holder != pr_reg) { ++ if ((pr_res_holder != pr_reg) && ++ (pr_res_type != PR_TYPE_WRITE_EXCLUSIVE_ALLREG) && ++ (pr_res_type != PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) { + struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl; + pr_err("SPC-3 PR: Attempted RESERVE from" + " [%s]: %s while reservation already held by" diff --git a/queue-3.14/target-allow-write-exclusive-non-reservation-holders-to-read.patch b/queue-3.14/target-allow-write-exclusive-non-reservation-holders-to-read.patch new file mode 100644 index 00000000000..209b240bab3 --- /dev/null +++ b/queue-3.14/target-allow-write-exclusive-non-reservation-holders-to-read.patch @@ -0,0 +1,45 @@ +From 1ecc7586922662e3ca2f3f0c3f17fec8749fc621 Mon Sep 17 00:00:00 2001 +From: Lee Duncan +Date: Mon, 5 Jan 2015 10:49:44 -0800 +Subject: target: Allow Write Exclusive non-reservation holders to READ + +From: Lee Duncan + +commit 1ecc7586922662e3ca2f3f0c3f17fec8749fc621 upstream. + +For PGR reservation of type Write Exclusive Access, allow all non +reservation holding I_T nexuses with active registrations to READ +from the device. + +This addresses a bug where active registrations that attempted +to READ would result in an reservation conflict. + +Signed-off-by: Lee Duncan +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_pr.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/drivers/target/target_core_pr.c ++++ b/drivers/target/target_core_pr.c +@@ -528,6 +528,18 @@ static int core_scsi3_pr_seq_non_holder( + + return 0; + } ++ } else if (we && registered_nexus) { ++ /* ++ * Reads are allowed for Write Exclusive locks ++ * from all registrants. ++ */ ++ if (cmd->data_direction == DMA_FROM_DEVICE) { ++ pr_debug("Allowing READ CDB: 0x%02x for %s" ++ " reservation\n", cdb[0], ++ core_scsi3_pr_dump_type(pr_reg_type)); ++ ++ return 0; ++ } + } + pr_debug("%s Conflict for %sregistered nexus %s CDB: 0x%2x" + " for %s reservation\n", transport_dump_cmd_direction(cmd), diff --git a/queue-3.14/target-avoid-dropping-allregistrants-reservation-during-unregister.patch b/queue-3.14/target-avoid-dropping-allregistrants-reservation-during-unregister.patch new file mode 100644 index 00000000000..103453a7bc0 --- /dev/null +++ b/queue-3.14/target-avoid-dropping-allregistrants-reservation-during-unregister.patch @@ -0,0 +1,232 @@ +From 6c3c9baa0debeb4bcc52a78c4463a0a97518de10 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Mon, 15 Dec 2014 11:50:26 -0800 +Subject: target: Avoid dropping AllRegistrants reservation during unregister + +From: Nicholas Bellinger + +commit 6c3c9baa0debeb4bcc52a78c4463a0a97518de10 upstream. + +This patch fixes an issue with AllRegistrants reservations where +an unregister operation by the I_T nexus reservation holder would +incorrectly drop the reservation, instead of waiting until the +last active I_T nexus is unregistered as per SPC-4. + +This includes updating __core_scsi3_complete_pro_release() to reset +dev->dev_pr_res_holder with another pr_reg for this special case, +as well as a new 'unreg' parameter to determine when the release +is occuring from an implicit unregister, vs. explicit RELEASE. + +It also adds special handling in core_scsi3_free_pr_reg_from_nacl() +to release the left-over pr_res_holder, now that pr_reg is deleted +from pr_reg_list within __core_scsi3_complete_pro_release(). + +Reported-by: Ilias Tsitsimpis +Cc: James Bottomley +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_pr.c | 89 +++++++++++++++++++++++++++++----------- + 1 file changed, 66 insertions(+), 23 deletions(-) + +--- a/drivers/target/target_core_pr.c ++++ b/drivers/target/target_core_pr.c +@@ -76,7 +76,7 @@ enum preempt_type { + }; + + static void __core_scsi3_complete_pro_release(struct se_device *, struct se_node_acl *, +- struct t10_pr_registration *, int); ++ struct t10_pr_registration *, int, int); + + static sense_reason_t + target_scsi2_reservation_check(struct se_cmd *cmd) +@@ -1186,7 +1186,7 @@ static int core_scsi3_check_implicit_rel + * service action with the SERVICE ACTION RESERVATION KEY + * field set to zero (see 5.7.11.3). + */ +- __core_scsi3_complete_pro_release(dev, nacl, pr_reg, 0); ++ __core_scsi3_complete_pro_release(dev, nacl, pr_reg, 0, 1); + ret = 1; + /* + * For 'All Registrants' reservation types, all existing +@@ -1228,7 +1228,8 @@ static void __core_scsi3_free_registrati + + pr_reg->pr_reg_deve->def_pr_registered = 0; + pr_reg->pr_reg_deve->pr_res_key = 0; +- list_del(&pr_reg->pr_reg_list); ++ if (!list_empty(&pr_reg->pr_reg_list)) ++ list_del(&pr_reg->pr_reg_list); + /* + * Caller accessing *pr_reg using core_scsi3_locate_pr_reg(), + * so call core_scsi3_put_pr_reg() to decrement our reference. +@@ -1280,6 +1281,7 @@ void core_scsi3_free_pr_reg_from_nacl( + { + struct t10_reservation *pr_tmpl = &dev->t10_pr; + struct t10_pr_registration *pr_reg, *pr_reg_tmp, *pr_res_holder; ++ bool free_reg = false; + /* + * If the passed se_node_acl matches the reservation holder, + * release the reservation. +@@ -1287,13 +1289,18 @@ void core_scsi3_free_pr_reg_from_nacl( + spin_lock(&dev->dev_reservation_lock); + pr_res_holder = dev->dev_pr_res_holder; + if ((pr_res_holder != NULL) && +- (pr_res_holder->pr_reg_nacl == nacl)) +- __core_scsi3_complete_pro_release(dev, nacl, pr_res_holder, 0); ++ (pr_res_holder->pr_reg_nacl == nacl)) { ++ __core_scsi3_complete_pro_release(dev, nacl, pr_res_holder, 0, 1); ++ free_reg = true; ++ } + spin_unlock(&dev->dev_reservation_lock); + /* + * Release any registration associated with the struct se_node_acl. + */ + spin_lock(&pr_tmpl->registration_lock); ++ if (pr_res_holder && free_reg) ++ __core_scsi3_free_registration(dev, pr_res_holder, NULL, 0); ++ + list_for_each_entry_safe(pr_reg, pr_reg_tmp, + &pr_tmpl->registration_list, pr_reg_list) { + +@@ -1316,7 +1323,7 @@ void core_scsi3_free_all_registrations( + if (pr_res_holder != NULL) { + struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl; + __core_scsi3_complete_pro_release(dev, pr_res_nacl, +- pr_res_holder, 0); ++ pr_res_holder, 0, 0); + } + spin_unlock(&dev->dev_reservation_lock); + +@@ -2126,13 +2133,13 @@ core_scsi3_emulate_pro_register(struct s + /* + * sa_res_key=0 Unregister Reservation Key for registered I_T Nexus. + */ +- pr_holder = core_scsi3_check_implicit_release( +- cmd->se_dev, pr_reg); ++ type = pr_reg->pr_res_type; ++ pr_holder = core_scsi3_check_implicit_release(cmd->se_dev, ++ pr_reg); + if (pr_holder < 0) { + ret = TCM_RESERVATION_CONFLICT; + goto out; + } +- type = pr_reg->pr_res_type; + + spin_lock(&pr_tmpl->registration_lock); + /* +@@ -2406,23 +2413,59 @@ static void __core_scsi3_complete_pro_re + struct se_device *dev, + struct se_node_acl *se_nacl, + struct t10_pr_registration *pr_reg, +- int explicit) ++ int explicit, ++ int unreg) + { + struct target_core_fabric_ops *tfo = se_nacl->se_tpg->se_tpg_tfo; + char i_buf[PR_REG_ISID_ID_LEN]; ++ int pr_res_type = 0, pr_res_scope = 0; + + memset(i_buf, 0, PR_REG_ISID_ID_LEN); + core_pr_dump_initiator_port(pr_reg, i_buf, PR_REG_ISID_ID_LEN); + /* + * Go ahead and release the current PR reservation holder. +- */ +- dev->dev_pr_res_holder = NULL; ++ * If an All Registrants reservation is currently active and ++ * a unregister operation is requested, replace the current ++ * dev_pr_res_holder with another active registration. ++ */ ++ if (dev->dev_pr_res_holder) { ++ pr_res_type = dev->dev_pr_res_holder->pr_res_type; ++ pr_res_scope = dev->dev_pr_res_holder->pr_res_scope; ++ dev->dev_pr_res_holder->pr_res_type = 0; ++ dev->dev_pr_res_holder->pr_res_scope = 0; ++ dev->dev_pr_res_holder->pr_res_holder = 0; ++ dev->dev_pr_res_holder = NULL; ++ } ++ if (!unreg) ++ goto out; + +- pr_debug("SPC-3 PR [%s] Service Action: %s RELEASE cleared" +- " reservation holder TYPE: %s ALL_TG_PT: %d\n", +- tfo->get_fabric_name(), (explicit) ? "explicit" : "implicit", +- core_scsi3_pr_dump_type(pr_reg->pr_res_type), +- (pr_reg->pr_reg_all_tg_pt) ? 1 : 0); ++ spin_lock(&dev->t10_pr.registration_lock); ++ list_del_init(&pr_reg->pr_reg_list); ++ /* ++ * If the I_T nexus is a reservation holder, the persistent reservation ++ * is of an all registrants type, and the I_T nexus is the last remaining ++ * registered I_T nexus, then the device server shall also release the ++ * persistent reservation. ++ */ ++ if (!list_empty(&dev->t10_pr.registration_list) && ++ ((pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || ++ (pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG))) { ++ dev->dev_pr_res_holder = ++ list_entry(dev->t10_pr.registration_list.next, ++ struct t10_pr_registration, pr_reg_list); ++ dev->dev_pr_res_holder->pr_res_type = pr_res_type; ++ dev->dev_pr_res_holder->pr_res_scope = pr_res_scope; ++ dev->dev_pr_res_holder->pr_res_holder = 1; ++ } ++ spin_unlock(&dev->t10_pr.registration_lock); ++out: ++ if (!dev->dev_pr_res_holder) { ++ pr_debug("SPC-3 PR [%s] Service Action: %s RELEASE cleared" ++ " reservation holder TYPE: %s ALL_TG_PT: %d\n", ++ tfo->get_fabric_name(), (explicit) ? "explicit" : ++ "implicit", core_scsi3_pr_dump_type(pr_res_type), ++ (pr_reg->pr_reg_all_tg_pt) ? 1 : 0); ++ } + pr_debug("SPC-3 PR [%s] RELEASE Node: %s%s\n", + tfo->get_fabric_name(), se_nacl->initiatorname, + i_buf); +@@ -2553,7 +2596,7 @@ core_scsi3_emulate_pro_release(struct se + * server shall not establish a unit attention condition. + */ + __core_scsi3_complete_pro_release(dev, se_sess->se_node_acl, +- pr_reg, 1); ++ pr_reg, 1, 0); + + spin_unlock(&dev->dev_reservation_lock); + +@@ -2641,7 +2684,7 @@ core_scsi3_emulate_pro_clear(struct se_c + if (pr_res_holder) { + struct se_node_acl *pr_res_nacl = pr_res_holder->pr_reg_nacl; + __core_scsi3_complete_pro_release(dev, pr_res_nacl, +- pr_res_holder, 0); ++ pr_res_holder, 0, 0); + } + spin_unlock(&dev->dev_reservation_lock); + /* +@@ -2700,7 +2743,7 @@ static void __core_scsi3_complete_pro_pr + */ + if (dev->dev_pr_res_holder) + __core_scsi3_complete_pro_release(dev, nacl, +- dev->dev_pr_res_holder, 0); ++ dev->dev_pr_res_holder, 0, 0); + + dev->dev_pr_res_holder = pr_reg; + pr_reg->pr_res_holder = 1; +@@ -2944,8 +2987,8 @@ core_scsi3_pro_preempt(struct se_cmd *cm + */ + if (pr_reg_n != pr_res_holder) + __core_scsi3_complete_pro_release(dev, +- pr_res_holder->pr_reg_nacl, +- dev->dev_pr_res_holder, 0); ++ pr_res_holder->pr_reg_nacl, ++ dev->dev_pr_res_holder, 0, 0); + /* + * b) Remove the registrations for all I_T nexuses identified + * by the SERVICE ACTION RESERVATION KEY field, except the +@@ -3415,7 +3458,7 @@ after_iport_check: + * holder (i.e., the I_T nexus on which the + */ + __core_scsi3_complete_pro_release(dev, pr_res_nacl, +- dev->dev_pr_res_holder, 0); ++ dev->dev_pr_res_holder, 0, 0); + /* + * g) Move the persistent reservation to the specified I_T nexus using + * the same scope and type as the persistent reservation released in diff --git a/queue-3.14/target-fix-r_holder-bit-usage-for-allregistrants.patch b/queue-3.14/target-fix-r_holder-bit-usage-for-allregistrants.patch new file mode 100644 index 00000000000..83c7b6ec3a1 --- /dev/null +++ b/queue-3.14/target-fix-r_holder-bit-usage-for-allregistrants.patch @@ -0,0 +1,82 @@ +From d16ca7c5198fd668db10d2c7b048ed3359c12c54 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Sun, 14 Dec 2014 01:47:19 -0800 +Subject: target: Fix R_HOLDER bit usage for AllRegistrants + +From: Nicholas Bellinger + +commit d16ca7c5198fd668db10d2c7b048ed3359c12c54 upstream. + +This patch fixes the usage of R_HOLDER bit for an All Registrants +reservation in READ_FULL_STATUS, where only the registration who +issued RESERVE was being reported as having an active reservation. + +It changes core_scsi3_pri_read_full_status() to check ahead of the +list walk of active registrations to see if All Registrants is active, +and if so set R_HOLDER bit and scope/type fields for all active +registrations. + +Reported-by: Ilias Tsitsimpis +Cc: James Bottomley +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_pr.c | 26 +++++++++++++++++++++++--- + 1 file changed, 23 insertions(+), 3 deletions(-) + +--- a/drivers/target/target_core_pr.c ++++ b/drivers/target/target_core_pr.c +@@ -3855,7 +3855,8 @@ core_scsi3_pri_read_full_status(struct s + unsigned char *buf; + u32 add_desc_len = 0, add_len = 0, desc_len, exp_desc_len; + u32 off = 8; /* off into first Full Status descriptor */ +- int format_code = 0; ++ int format_code = 0, pr_res_type = 0, pr_res_scope = 0; ++ bool all_reg = false; + + if (cmd->data_length < 8) { + pr_err("PRIN SA READ_FULL_STATUS SCSI Data Length: %u" +@@ -3872,6 +3873,19 @@ core_scsi3_pri_read_full_status(struct s + buf[2] = ((dev->t10_pr.pr_generation >> 8) & 0xff); + buf[3] = (dev->t10_pr.pr_generation & 0xff); + ++ spin_lock(&dev->dev_reservation_lock); ++ if (dev->dev_pr_res_holder) { ++ struct t10_pr_registration *pr_holder = dev->dev_pr_res_holder; ++ ++ if (pr_holder->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG || ++ pr_holder->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG) { ++ all_reg = true; ++ pr_res_type = pr_holder->pr_res_type; ++ pr_res_scope = pr_holder->pr_res_scope; ++ } ++ } ++ spin_unlock(&dev->dev_reservation_lock); ++ + spin_lock(&pr_tmpl->registration_lock); + list_for_each_entry_safe(pr_reg, pr_reg_tmp, + &pr_tmpl->registration_list, pr_reg_list) { +@@ -3921,14 +3935,20 @@ core_scsi3_pri_read_full_status(struct s + * reservation holder for PR_HOLDER bit. + * + * Also, if this registration is the reservation +- * holder, fill in SCOPE and TYPE in the next byte. ++ * holder or there is an All Registrants reservation ++ * active, fill in SCOPE and TYPE in the next byte. + */ + if (pr_reg->pr_res_holder) { + buf[off++] |= 0x01; + buf[off++] = (pr_reg->pr_res_scope & 0xf0) | + (pr_reg->pr_res_type & 0x0f); +- } else ++ } else if (all_reg) { ++ buf[off++] |= 0x01; ++ buf[off++] = (pr_res_scope & 0xf0) | ++ (pr_res_type & 0x0f); ++ } else { + off += 2; ++ } + + off += 4; /* Skip over reserved area */ + /* diff --git a/queue-3.14/target-fix-reference-leak-in-target_get_sess_cmd-error-path.patch b/queue-3.14/target-fix-reference-leak-in-target_get_sess_cmd-error-path.patch new file mode 100644 index 00000000000..90f21eb21a9 --- /dev/null +++ b/queue-3.14/target-fix-reference-leak-in-target_get_sess_cmd-error-path.patch @@ -0,0 +1,36 @@ +From 7544e597343e2166daba3f32e4708533aa53c233 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Wed, 18 Feb 2015 15:33:58 +0100 +Subject: target: Fix reference leak in target_get_sess_cmd() error path + +From: Bart Van Assche + +commit 7544e597343e2166daba3f32e4708533aa53c233 upstream. + +This patch fixes a se_cmd->cmd_kref leak buf when se_sess->sess_tearing_down +is true within target_get_sess_cmd() submission path code. + +This se_cmd reference leak can occur during active session shutdown when +ack_kref=1 is passed by target_submit_cmd_[map_sgls,tmr]() callers. + +Signed-off-by: Bart Van Assche +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_transport.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/target/target_core_transport.c ++++ b/drivers/target/target_core_transport.c +@@ -2327,6 +2327,10 @@ int target_get_sess_cmd(struct se_sessio + list_add_tail(&se_cmd->se_cmd_list, &se_sess->sess_cmd_list); + out: + spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags); ++ ++ if (ret && ack_kref) ++ target_put_sess_cmd(se_sess, se_cmd); ++ + return ret; + } + EXPORT_SYMBOL(target_get_sess_cmd); diff --git a/queue-3.14/target-fix-virtual-lun-0-target_configure_device-failure-oops.patch b/queue-3.14/target-fix-virtual-lun-0-target_configure_device-failure-oops.patch new file mode 100644 index 00000000000..407ddfead5f --- /dev/null +++ b/queue-3.14/target-fix-virtual-lun-0-target_configure_device-failure-oops.patch @@ -0,0 +1,52 @@ +From 5f7da044f8bc1cfb21c962edf34bd5699a76e7ae Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Thu, 5 Mar 2015 03:28:24 +0000 +Subject: target: Fix virtual LUN=0 target_configure_device failure OOPs + +From: Nicholas Bellinger + +commit 5f7da044f8bc1cfb21c962edf34bd5699a76e7ae upstream. + +This patch fixes a NULL pointer dereference triggered by a late +target_configure_device() -> alloc_workqueue() failure that results +in target_free_device() being called with DF_CONFIGURED already set, +which subsequently OOPses in destroy_workqueue() code. + +Currently this only happens at modprobe target_core_mod time when +core_dev_setup_virtual_lun0() -> target_configure_device() fails, +and the explicit target_free_device() gets called. + +To address this bug originally introduced by commit 0fd97ccf45, go +ahead and move DF_CONFIGURED to end of target_configure_device() +code to handle this special failure case. + +Reported-by: Claudio Fleiner +Cc: Claudio Fleiner +Cc: Christoph Hellwig +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_device.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/target/target_core_device.c ++++ b/drivers/target/target_core_device.c +@@ -1591,8 +1591,6 @@ int target_configure_device(struct se_de + ret = dev->transport->configure_device(dev); + if (ret) + goto out; +- dev->dev_flags |= DF_CONFIGURED; +- + /* + * XXX: there is not much point to have two different values here.. + */ +@@ -1654,6 +1652,8 @@ int target_configure_device(struct se_de + list_add_tail(&dev->g_dev_node, &g_device_list); + mutex_unlock(&g_device_mutex); + ++ dev->dev_flags |= DF_CONFIGURED; ++ + return 0; + + out_free_alua: diff --git a/queue-3.14/target-pscsi-fix-null-pointer-dereference-in-get_device_type.patch b/queue-3.14/target-pscsi-fix-null-pointer-dereference-in-get_device_type.patch new file mode 100644 index 00000000000..b742d47606f --- /dev/null +++ b/queue-3.14/target-pscsi-fix-null-pointer-dereference-in-get_device_type.patch @@ -0,0 +1,32 @@ +From 215a8fe4198f607f34ecdbc9969dae783d8b5a61 Mon Sep 17 00:00:00 2001 +From: Nicholas Bellinger +Date: Fri, 27 Feb 2015 03:54:13 -0800 +Subject: target/pscsi: Fix NULL pointer dereference in get_device_type + +From: Nicholas Bellinger + +commit 215a8fe4198f607f34ecdbc9969dae783d8b5a61 upstream. + +This patch fixes a NULL pointer dereference OOPs with pSCSI backends +within target_core_stat.c code. The bug is caused by a configfs attr +read if no pscsi_dev_virt->pdv_sd has been configured. + +Reported-by: Olaf Hering +Signed-off-by: Nicholas Bellinger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/target/target_core_pscsi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/target/target_core_pscsi.c ++++ b/drivers/target/target_core_pscsi.c +@@ -1111,7 +1111,7 @@ static u32 pscsi_get_device_type(struct + struct pscsi_dev_virt *pdv = PSCSI_DEV(dev); + struct scsi_device *sd = pdv->pdv_sd; + +- return sd->type; ++ return (sd) ? sd->type : TYPE_NO_LUN; + } + + static sector_t pscsi_get_blocks(struct se_device *dev)