From: Greg Kroah-Hartman Date: Thu, 4 Mar 2021 13:53:17 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v4.4.260~55 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=43a82676ecb890ad3f657d4c558a844ce0154067;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: arm64-module-set-plt-section-addresses-to-0x0.patch input-elantech-fix-protocol-errors-for-some-trackpoints-in-smbus-mode.patch mips-vdso-use-clang_flags-instead-of-filtering-out-target.patch net-usb-qmi_wwan-support-zte-p685m-modem.patch nvme-pci-fix-error-unwind-in-nvme_map_data.patch nvme-pci-refactor-nvme_unmap_data.patch --- diff --git a/queue-5.4/arm64-module-set-plt-section-addresses-to-0x0.patch b/queue-5.4/arm64-module-set-plt-section-addresses-to-0x0.patch new file mode 100644 index 00000000000..386d2ddd1bf --- /dev/null +++ b/queue-5.4/arm64-module-set-plt-section-addresses-to-0x0.patch @@ -0,0 +1,39 @@ +From f5c6d0fcf90ce07ee0d686d465b19b247ebd5ed7 Mon Sep 17 00:00:00 2001 +From: Shaoying Xu +Date: Tue, 16 Feb 2021 18:32:34 +0000 +Subject: arm64 module: set plt* section addresses to 0x0 + +From: Shaoying Xu + +commit f5c6d0fcf90ce07ee0d686d465b19b247ebd5ed7 upstream. + +These plt* and .text.ftrace_trampoline sections specified for arm64 have +non-zero addressses. Non-zero section addresses in a relocatable ELF would +confuse GDB when it tries to compute the section offsets and it ends up +printing wrong symbol addresses. Therefore, set them to zero, which mirrors +the change in commit 5d8591bc0fba ("module: set ksymtab/kcrctab* section +addresses to 0x0"). + +Reported-by: Frank van der Linden +Signed-off-by: Shaoying Xu +Cc: +Link: https://lore.kernel.org/r/20210216183234.GA23876@amazon.com +Signed-off-by: Will Deacon +[shaoyi@amazon.com: made same changes in arch/arm64/kernel/module.lds for 5.4] +Signed-off-by: Shaoying Xu +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/kernel/module.lds | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/arm64/kernel/module.lds ++++ b/arch/arm64/kernel/module.lds +@@ -1,5 +1,5 @@ + SECTIONS { +- .plt (NOLOAD) : { BYTE(0) } +- .init.plt (NOLOAD) : { BYTE(0) } +- .text.ftrace_trampoline (NOLOAD) : { BYTE(0) } ++ .plt 0 (NOLOAD) : { BYTE(0) } ++ .init.plt 0 (NOLOAD) : { BYTE(0) } ++ .text.ftrace_trampoline 0 (NOLOAD) : { BYTE(0) } + } diff --git a/queue-5.4/input-elantech-fix-protocol-errors-for-some-trackpoints-in-smbus-mode.patch b/queue-5.4/input-elantech-fix-protocol-errors-for-some-trackpoints-in-smbus-mode.patch new file mode 100644 index 00000000000..72aced0c9bf --- /dev/null +++ b/queue-5.4/input-elantech-fix-protocol-errors-for-some-trackpoints-in-smbus-mode.patch @@ -0,0 +1,199 @@ +From e4c9062717feda88900b566463228d1c4910af6d Mon Sep 17 00:00:00 2001 +From: "jingle.wu" +Date: Thu, 10 Dec 2020 23:49:16 -0800 +Subject: Input: elantech - fix protocol errors for some trackpoints in SMBus mode + +From: jingle.wu + +commit e4c9062717feda88900b566463228d1c4910af6d upstream. + +There are some version of Elan trackpads that send incorrect data when +in SMbus mode, unless they are switched to use 0x5f reports instead of +standard 0x5e. This patch implements querying device to retrieve chips +identifying data, and switching it, when needed to the alternative +report. + +Signed-off-by: Jingle Wu +Link: https://lore.kernel.org/r/20201211071531.32413-1-jingle.wu@emc.com.tw +Signed-off-by: Dmitry Torokhov +Cc: Uwe Kleine-König +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/mouse/elantech.c | 99 ++++++++++++++++++++++++++++++++++++++++- + drivers/input/mouse/elantech.h | 4 + + 2 files changed, 101 insertions(+), 2 deletions(-) + +--- a/drivers/input/mouse/elantech.c ++++ b/drivers/input/mouse/elantech.c +@@ -90,6 +90,47 @@ static int elantech_ps2_command(struct p + } + + /* ++ * Send an Elantech style special command to read 3 bytes from a register ++ */ ++static int elantech_read_reg_params(struct psmouse *psmouse, u8 reg, u8 *param) ++{ ++ if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || ++ elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) || ++ elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || ++ elantech_ps2_command(psmouse, NULL, reg) || ++ elantech_ps2_command(psmouse, param, PSMOUSE_CMD_GETINFO)) { ++ psmouse_err(psmouse, ++ "failed to read register %#02x\n", reg); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++/* ++ * Send an Elantech style special command to write a register with a parameter ++ */ ++static int elantech_write_reg_params(struct psmouse *psmouse, u8 reg, u8 *param) ++{ ++ if (elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || ++ elantech_ps2_command(psmouse, NULL, ETP_REGISTER_READWRITE) || ++ elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || ++ elantech_ps2_command(psmouse, NULL, reg) || ++ elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || ++ elantech_ps2_command(psmouse, NULL, param[0]) || ++ elantech_ps2_command(psmouse, NULL, ETP_PS2_CUSTOM_COMMAND) || ++ elantech_ps2_command(psmouse, NULL, param[1]) || ++ elantech_ps2_command(psmouse, NULL, PSMOUSE_CMD_SETSCALE11)) { ++ psmouse_err(psmouse, ++ "failed to write register %#02x with value %#02x%#02x\n", ++ reg, param[0], param[1]); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++/* + * Send an Elantech style special command to read a value from a register + */ + static int elantech_read_reg(struct psmouse *psmouse, unsigned char reg, +@@ -1530,18 +1571,34 @@ static const struct dmi_system_id no_hw_ + }; + + /* ++ * Change Report id 0x5E to 0x5F. ++ */ ++static int elantech_change_report_id(struct psmouse *psmouse) ++{ ++ unsigned char param[2] = { 0x10, 0x03 }; ++ ++ if (elantech_write_reg_params(psmouse, 0x7, param) || ++ elantech_read_reg_params(psmouse, 0x7, param) || ++ param[0] != 0x10 || param[1] != 0x03) { ++ psmouse_err(psmouse, "Unable to change report ID to 0x5f.\n"); ++ return -EIO; ++ } ++ ++ return 0; ++} ++/* + * determine hardware version and set some properties according to it. + */ + static int elantech_set_properties(struct elantech_device_info *info) + { + /* This represents the version of IC body. */ +- int ver = (info->fw_version & 0x0f0000) >> 16; ++ info->ic_version = (info->fw_version & 0x0f0000) >> 16; + + /* Early version of Elan touchpads doesn't obey the rule. */ + if (info->fw_version < 0x020030 || info->fw_version == 0x020600) + info->hw_version = 1; + else { +- switch (ver) { ++ switch (info->ic_version) { + case 2: + case 4: + info->hw_version = 2; +@@ -1557,6 +1614,11 @@ static int elantech_set_properties(struc + } + } + ++ /* Get information pattern for hw_version 4 */ ++ info->pattern = 0x00; ++ if (info->ic_version == 0x0f && (info->fw_version & 0xff) <= 0x02) ++ info->pattern = info->fw_version & 0xff; ++ + /* decide which send_cmd we're gonna use early */ + info->send_cmd = info->hw_version >= 3 ? elantech_send_cmd : + synaptics_send_cmd; +@@ -1598,6 +1660,7 @@ static int elantech_query_info(struct ps + { + unsigned char param[3]; + unsigned char traces; ++ unsigned char ic_body[3]; + + memset(info, 0, sizeof(*info)); + +@@ -1640,6 +1703,21 @@ static int elantech_query_info(struct ps + info->samples[2]); + } + ++ if (info->pattern > 0x00 && info->ic_version == 0xf) { ++ if (info->send_cmd(psmouse, ETP_ICBODY_QUERY, ic_body)) { ++ psmouse_err(psmouse, "failed to query ic body\n"); ++ return -EINVAL; ++ } ++ info->ic_version = be16_to_cpup((__be16 *)ic_body); ++ psmouse_info(psmouse, ++ "Elan ic body: %#04x, current fw version: %#02x\n", ++ info->ic_version, ic_body[2]); ++ } ++ ++ info->product_id = be16_to_cpup((__be16 *)info->samples); ++ if (info->pattern == 0x00) ++ info->product_id &= 0xff; ++ + if (info->samples[1] == 0x74 && info->hw_version == 0x03) { + /* + * This module has a bug which makes absolute mode +@@ -1654,6 +1732,23 @@ static int elantech_query_info(struct ps + /* The MSB indicates the presence of the trackpoint */ + info->has_trackpoint = (info->capabilities[0] & 0x80) == 0x80; + ++ if (info->has_trackpoint && info->ic_version == 0x0011 && ++ (info->product_id == 0x08 || info->product_id == 0x09 || ++ info->product_id == 0x0d || info->product_id == 0x0e)) { ++ /* ++ * This module has a bug which makes trackpoint in SMBus ++ * mode return invalid data unless trackpoint is switched ++ * from using 0x5e reports to 0x5f. If we are not able to ++ * make the switch, let's abort initialization so we'll be ++ * using standard PS/2 protocol. ++ */ ++ if (elantech_change_report_id(psmouse)) { ++ psmouse_info(psmouse, ++ "Trackpoint report is broken, forcing standard PS/2 protocol\n"); ++ return -ENODEV; ++ } ++ } ++ + info->x_res = 31; + info->y_res = 31; + if (info->hw_version == 4) { +--- a/drivers/input/mouse/elantech.h ++++ b/drivers/input/mouse/elantech.h +@@ -18,6 +18,7 @@ + #define ETP_CAPABILITIES_QUERY 0x02 + #define ETP_SAMPLE_QUERY 0x03 + #define ETP_RESOLUTION_QUERY 0x04 ++#define ETP_ICBODY_QUERY 0x05 + + /* + * Command values for register reading or writing +@@ -140,7 +141,10 @@ struct elantech_device_info { + unsigned char samples[3]; + unsigned char debug; + unsigned char hw_version; ++ unsigned char pattern; + unsigned int fw_version; ++ unsigned int ic_version; ++ unsigned int product_id; + unsigned int x_min; + unsigned int y_min; + unsigned int x_max; diff --git a/queue-5.4/mips-vdso-use-clang_flags-instead-of-filtering-out-target.patch b/queue-5.4/mips-vdso-use-clang_flags-instead-of-filtering-out-target.patch new file mode 100644 index 00000000000..aee2a06ce5d --- /dev/null +++ b/queue-5.4/mips-vdso-use-clang_flags-instead-of-filtering-out-target.patch @@ -0,0 +1,61 @@ +From foo@baz Thu Mar 4 02:51:17 PM CET 2021 +From: Nathan Chancellor +Date: Fri, 15 Jan 2021 12:26:22 -0700 +Subject: MIPS: VDSO: Use CLANG_FLAGS instead of filtering out '--target=' + +From: Nathan Chancellor + +commit 76d7fff22be3e4185ee5f9da2eecbd8188e76b2c upstream. + +Commit ee67855ecd9d ("MIPS: vdso: Allow clang's --target flag in VDSO +cflags") allowed the '--target=' flag from the main Makefile to filter +through to the vDSO. However, it did not bring any of the other clang +specific flags for controlling the integrated assembler and the GNU +tools locations (--prefix=, --gcc-toolchain=, and -no-integrated-as). +Without these, we will get a warning (visible with tinyconfig): + +arch/mips/vdso/elf.S:14:1: warning: DWARF2 only supports one section per +compilation unit +.pushsection .note.Linux, "a",@note ; .balign 4 ; .long 2f - 1f ; .long +4484f - 3f ; .long 0 ; 1:.asciz "Linux" ; 2:.balign 4 ; 3: +^ +arch/mips/vdso/elf.S:34:2: warning: DWARF2 only supports one section per +compilation unit + .section .mips_abiflags, "a" + ^ + +All of these flags are bundled up under CLANG_FLAGS in the main Makefile +and exported so that they can be added to Makefiles that set their own +CFLAGS. Use this value instead of filtering out '--target=' so there is +no warning and all of the tools are properly used. + +Cc: stable@vger.kernel.org +Fixes: ee67855ecd9d ("MIPS: vdso: Allow clang's --target flag in VDSO cflags") +Link: https://github.com/ClangBuiltLinux/linux/issues/1256 +Reported-by: Anders Roxell +Signed-off-by: Nathan Chancellor +Tested-by: Anders Roxell +Signed-off-by: Thomas Bogendoerfer +[nc: Fix conflict due to lack of 99570c3da96a in 5.4] +Signed-off-by: Nathan Chancellor +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/vdso/Makefile | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/arch/mips/vdso/Makefile ++++ b/arch/mips/vdso/Makefile +@@ -16,12 +16,9 @@ ccflags-vdso := \ + $(filter -march=%,$(KBUILD_CFLAGS)) \ + $(filter -m%-float,$(KBUILD_CFLAGS)) \ + $(filter -mno-loongson-%,$(KBUILD_CFLAGS)) \ ++ $(CLANG_FLAGS) \ + -D__VDSO__ + +-ifdef CONFIG_CC_IS_CLANG +-ccflags-vdso += $(filter --target=%,$(KBUILD_CFLAGS)) +-endif +- + # + # The -fno-jump-tables flag only prevents the compiler from generating + # jump tables but does not prevent the compiler from emitting absolute diff --git a/queue-5.4/net-usb-qmi_wwan-support-zte-p685m-modem.patch b/queue-5.4/net-usb-qmi_wwan-support-zte-p685m-modem.patch new file mode 100644 index 00000000000..3acdb857af8 --- /dev/null +++ b/queue-5.4/net-usb-qmi_wwan-support-zte-p685m-modem.patch @@ -0,0 +1,65 @@ +From 88eee9b7b42e69fb622ddb3ff6f37e8e4347f5b2 Mon Sep 17 00:00:00 2001 +From: Lech Perczak +Date: Tue, 23 Feb 2021 19:34:56 +0100 +Subject: net: usb: qmi_wwan: support ZTE P685M modem +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lech Perczak + +commit 88eee9b7b42e69fb622ddb3ff6f37e8e4347f5b2 upstream. + +Now that interface 3 in "option" driver is no longer mapped, add device +ID matching it to qmi_wwan. + +The modem is used inside ZTE MF283+ router and carriers identify it as +such. +Interface mapping is: +0: QCDM, 1: AT (PCUI), 2: AT (Modem), 3: QMI, 4: ADB + +T: Bus=02 Lev=02 Prnt=02 Port=05 Cnt=01 Dev#= 3 Spd=480 MxCh= 0 +D: Ver= 2.01 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=19d2 ProdID=1275 Rev=f0.00 +S: Manufacturer=ZTE,Incorporated +S: Product=ZTE Technologies MSM +S: SerialNumber=P685M510ZTED0000CP&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&0 +C:* #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms +E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan +E: Ad=87(I) Atr=03(Int.) MxPS= 8 Ivl=32ms +E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms +I:* If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=42 Prot=01 Driver=(none) +E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms +E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms + +Acked-by: Bjørn Mork +Signed-off-by: Lech Perczak +Link: https://lore.kernel.org/r/20210223183456.6377-1-lech.perczak@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/qmi_wwan.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/usb/qmi_wwan.c ++++ b/drivers/net/usb/qmi_wwan.c +@@ -1280,6 +1280,7 @@ static const struct usb_device_id produc + {QMI_FIXED_INTF(0x19d2, 0x1255, 4)}, + {QMI_FIXED_INTF(0x19d2, 0x1256, 4)}, + {QMI_FIXED_INTF(0x19d2, 0x1270, 5)}, /* ZTE MF667 */ ++ {QMI_FIXED_INTF(0x19d2, 0x1275, 3)}, /* ZTE P685M */ + {QMI_FIXED_INTF(0x19d2, 0x1401, 2)}, + {QMI_FIXED_INTF(0x19d2, 0x1402, 2)}, /* ZTE MF60 */ + {QMI_FIXED_INTF(0x19d2, 0x1424, 2)}, diff --git a/queue-5.4/nvme-pci-fix-error-unwind-in-nvme_map_data.patch b/queue-5.4/nvme-pci-fix-error-unwind-in-nvme_map_data.patch new file mode 100644 index 00000000000..a73e8756c4f --- /dev/null +++ b/queue-5.4/nvme-pci-fix-error-unwind-in-nvme_map_data.patch @@ -0,0 +1,109 @@ +From foo@baz Thu Mar 4 02:41:47 PM CET 2021 +From: Marc Orr +Date: Tue, 2 Mar 2021 17:39:11 +0000 +Subject: nvme-pci: fix error unwind in nvme_map_data +To: stable@vger.kernel.org +Cc: Christoph Hellwig , Marc Orr , Keith Busch +Message-ID: <20210302173911.12044-2-marcorr@google.com> + +From: Christoph Hellwig + +commit fa0732168fa1369dd089e5b06d6158a68229f7b7 upstream. + +Properly unwind step by step using refactored helpers from nvme_unmap_data +to avoid a potential double dma_unmap on a mapping failure. + +Fixes: 7fe07d14f71f ("nvme-pci: merge nvme_free_iod into nvme_unmap_data") +Reported-by: Marc Orr +Signed-off-by: Christoph Hellwig +Reviewed-by: Keith Busch +Reviewed-by: Marc Orr +Signed-off-by: Marc Orr +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvme/host/pci.c | 28 ++++++++++++++++++---------- + 1 file changed, 18 insertions(+), 10 deletions(-) + +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -669,7 +669,7 @@ static blk_status_t nvme_pci_setup_prps( + __le64 *old_prp_list = prp_list; + prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma); + if (!prp_list) +- return BLK_STS_RESOURCE; ++ goto free_prps; + list[iod->npages++] = prp_list; + prp_list[0] = old_prp_list[i - 1]; + old_prp_list[i - 1] = cpu_to_le64(prp_dma); +@@ -689,14 +689,14 @@ static blk_status_t nvme_pci_setup_prps( + dma_addr = sg_dma_address(sg); + dma_len = sg_dma_len(sg); + } +- + done: + cmnd->dptr.prp1 = cpu_to_le64(sg_dma_address(iod->sg)); + cmnd->dptr.prp2 = cpu_to_le64(iod->first_dma); +- + return BLK_STS_OK; +- +- bad_sgl: ++free_prps: ++ nvme_free_prps(dev, req); ++ return BLK_STS_RESOURCE; ++bad_sgl: + WARN(DO_ONCE(nvme_print_sgl, iod->sg, iod->nents), + "Invalid SGL for payload:%d nents:%d\n", + blk_rq_payload_bytes(req), iod->nents); +@@ -768,7 +768,7 @@ static blk_status_t nvme_pci_setup_sgls( + + sg_list = dma_pool_alloc(pool, GFP_ATOMIC, &sgl_dma); + if (!sg_list) +- return BLK_STS_RESOURCE; ++ goto free_sgls; + + i = 0; + nvme_pci_iod_list(req)[iod->npages++] = sg_list; +@@ -781,6 +781,9 @@ static blk_status_t nvme_pci_setup_sgls( + } while (--entries > 0); + + return BLK_STS_OK; ++free_sgls: ++ nvme_free_sgls(dev, req); ++ return BLK_STS_RESOURCE; + } + + static blk_status_t nvme_setup_prp_simple(struct nvme_dev *dev, +@@ -849,7 +852,7 @@ static blk_status_t nvme_map_data(struct + sg_init_table(iod->sg, blk_rq_nr_phys_segments(req)); + iod->nents = blk_rq_map_sg(req->q, req, iod->sg); + if (!iod->nents) +- goto out; ++ goto out_free_sg; + + if (is_pci_p2pdma_page(sg_page(iod->sg))) + nr_mapped = pci_p2pdma_map_sg_attrs(dev->dev, iod->sg, +@@ -858,16 +861,21 @@ static blk_status_t nvme_map_data(struct + nr_mapped = dma_map_sg_attrs(dev->dev, iod->sg, iod->nents, + rq_dma_dir(req), DMA_ATTR_NO_WARN); + if (!nr_mapped) +- goto out; ++ goto out_free_sg; + + iod->use_sgl = nvme_pci_use_sgls(dev, req); + if (iod->use_sgl) + ret = nvme_pci_setup_sgls(dev, req, &cmnd->rw, nr_mapped); + else + ret = nvme_pci_setup_prps(dev, req, &cmnd->rw); +-out: + if (ret != BLK_STS_OK) +- nvme_unmap_data(dev, req); ++ goto out_unmap_sg; ++ return BLK_STS_OK; ++ ++out_unmap_sg: ++ nvme_unmap_sg(dev, req); ++out_free_sg: ++ mempool_free(iod->sg, dev->iod_mempool); + return ret; + } + diff --git a/queue-5.4/nvme-pci-refactor-nvme_unmap_data.patch b/queue-5.4/nvme-pci-refactor-nvme_unmap_data.patch new file mode 100644 index 00000000000..a09654488a2 --- /dev/null +++ b/queue-5.4/nvme-pci-refactor-nvme_unmap_data.patch @@ -0,0 +1,126 @@ +From foo@baz Thu Mar 4 02:41:47 PM CET 2021 +From: Marc Orr +Date: Tue, 2 Mar 2021 17:39:10 +0000 +Subject: nvme-pci: refactor nvme_unmap_data +To: stable@vger.kernel.org +Cc: Christoph Hellwig , Keith Busch , Marc Orr +Message-ID: <20210302173911.12044-1-marcorr@google.com> + +From: Christoph Hellwig + +commit 9275c206f88e5c49cb3e71932c81c8561083db9e upstream. + +Split out three helpers from nvme_unmap_data that will allow finer grained +unwinding from nvme_map_data. + +Signed-off-by: Christoph Hellwig +Reviewed-by: Keith Busch +Reviewed-by: Marc Orr +Signed-off-by: Marc Orr +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvme/host/pci.c | 77 ++++++++++++++++++++++++++++++------------------ + 1 file changed, 49 insertions(+), 28 deletions(-) + +--- a/drivers/nvme/host/pci.c ++++ b/drivers/nvme/host/pci.c +@@ -528,50 +528,71 @@ static inline bool nvme_pci_use_sgls(str + return true; + } + +-static void nvme_unmap_data(struct nvme_dev *dev, struct request *req) ++static void nvme_free_prps(struct nvme_dev *dev, struct request *req) + { +- struct nvme_iod *iod = blk_mq_rq_to_pdu(req); + const int last_prp = dev->ctrl.page_size / sizeof(__le64) - 1; +- dma_addr_t dma_addr = iod->first_dma, next_dma_addr; ++ struct nvme_iod *iod = blk_mq_rq_to_pdu(req); ++ dma_addr_t dma_addr = iod->first_dma; + int i; + +- if (iod->dma_len) { +- dma_unmap_page(dev->dev, dma_addr, iod->dma_len, +- rq_dma_dir(req)); +- return; ++ for (i = 0; i < iod->npages; i++) { ++ __le64 *prp_list = nvme_pci_iod_list(req)[i]; ++ dma_addr_t next_dma_addr = le64_to_cpu(prp_list[last_prp]); ++ ++ dma_pool_free(dev->prp_page_pool, prp_list, dma_addr); ++ dma_addr = next_dma_addr; + } + +- WARN_ON_ONCE(!iod->nents); ++} + +- if (is_pci_p2pdma_page(sg_page(iod->sg))) +- pci_p2pdma_unmap_sg(dev->dev, iod->sg, iod->nents, +- rq_dma_dir(req)); +- else +- dma_unmap_sg(dev->dev, iod->sg, iod->nents, rq_dma_dir(req)); ++static void nvme_free_sgls(struct nvme_dev *dev, struct request *req) ++{ ++ const int last_sg = SGES_PER_PAGE - 1; ++ struct nvme_iod *iod = blk_mq_rq_to_pdu(req); ++ dma_addr_t dma_addr = iod->first_dma; ++ int i; + ++ for (i = 0; i < iod->npages; i++) { ++ struct nvme_sgl_desc *sg_list = nvme_pci_iod_list(req)[i]; ++ dma_addr_t next_dma_addr = le64_to_cpu((sg_list[last_sg]).addr); + +- if (iod->npages == 0) +- dma_pool_free(dev->prp_small_pool, nvme_pci_iod_list(req)[0], +- dma_addr); ++ dma_pool_free(dev->prp_page_pool, sg_list, dma_addr); ++ dma_addr = next_dma_addr; ++ } + +- for (i = 0; i < iod->npages; i++) { +- void *addr = nvme_pci_iod_list(req)[i]; ++} + +- if (iod->use_sgl) { +- struct nvme_sgl_desc *sg_list = addr; ++static void nvme_unmap_sg(struct nvme_dev *dev, struct request *req) ++{ ++ struct nvme_iod *iod = blk_mq_rq_to_pdu(req); + +- next_dma_addr = +- le64_to_cpu((sg_list[SGES_PER_PAGE - 1]).addr); +- } else { +- __le64 *prp_list = addr; ++ if (is_pci_p2pdma_page(sg_page(iod->sg))) ++ pci_p2pdma_unmap_sg(dev->dev, iod->sg, iod->nents, ++ rq_dma_dir(req)); ++ else ++ dma_unmap_sg(dev->dev, iod->sg, iod->nents, rq_dma_dir(req)); ++} + +- next_dma_addr = le64_to_cpu(prp_list[last_prp]); +- } ++static void nvme_unmap_data(struct nvme_dev *dev, struct request *req) ++{ ++ struct nvme_iod *iod = blk_mq_rq_to_pdu(req); + +- dma_pool_free(dev->prp_page_pool, addr, dma_addr); +- dma_addr = next_dma_addr; ++ if (iod->dma_len) { ++ dma_unmap_page(dev->dev, iod->first_dma, iod->dma_len, ++ rq_dma_dir(req)); ++ return; + } + ++ WARN_ON_ONCE(!iod->nents); ++ ++ nvme_unmap_sg(dev, req); ++ if (iod->npages == 0) ++ dma_pool_free(dev->prp_small_pool, nvme_pci_iod_list(req)[0], ++ iod->first_dma); ++ else if (iod->use_sgl) ++ nvme_free_sgls(dev, req); ++ else ++ nvme_free_prps(dev, req); + mempool_free(iod->sg, dev->iod_mempool); + } +