From: Sasha Levin Date: Wed, 9 Aug 2023 01:44:05 +0000 (-0400) Subject: Fixes for 5.10 X-Git-Tag: v4.14.322~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0045e4660a7f9e3198ae45b7ffe4370e7bd2a0ff;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.10 Signed-off-by: Sasha Levin --- diff --git a/queue-5.10/arm-dts-imx-add-usb-alias.patch b/queue-5.10/arm-dts-imx-add-usb-alias.patch new file mode 100644 index 00000000000..69b40ab961b --- /dev/null +++ b/queue-5.10/arm-dts-imx-add-usb-alias.patch @@ -0,0 +1,127 @@ +From 9323bb3d03760f9c66c052430966b23aec4442dc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 1 Nov 2020 19:29:53 +0800 +Subject: ARM: dts: imx: add usb alias + +From: Peng Fan + +[ Upstream commit 5c8b3b8a182cbc1ccdfcdeea9b25dd2c12a8148f ] + +Add usb alias for bootloader searching the controller in correct order. + +Signed-off-by: Peng Fan +Signed-off-by: Shawn Guo +Stable-dep-of: ee70b908f77a ("ARM: dts: nxp/imx6sll: fix wrong property name in usbphy node") +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/imx6qdl.dtsi | 4 ++++ + arch/arm/boot/dts/imx6sl.dtsi | 3 +++ + arch/arm/boot/dts/imx6sll.dtsi | 2 ++ + arch/arm/boot/dts/imx6sx.dtsi | 3 +++ + arch/arm/boot/dts/imx6ul.dtsi | 2 ++ + arch/arm/boot/dts/imx7d.dtsi | 6 ++++++ + arch/arm/boot/dts/imx7s.dtsi | 2 ++ + 7 files changed, 22 insertions(+) + +diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi +index 7858ae5d39df7..7d81992dfafc6 100644 +--- a/arch/arm/boot/dts/imx6qdl.dtsi ++++ b/arch/arm/boot/dts/imx6qdl.dtsi +@@ -45,6 +45,10 @@ aliases { + spi1 = &ecspi2; + spi2 = &ecspi3; + spi3 = &ecspi4; ++ usb0 = &usbotg; ++ usb1 = &usbh1; ++ usb2 = &usbh2; ++ usb3 = &usbh3; + usbphy0 = &usbphy1; + usbphy1 = &usbphy2; + }; +diff --git a/arch/arm/boot/dts/imx6sl.dtsi b/arch/arm/boot/dts/imx6sl.dtsi +index c184a6d5bc420..5b4dfc62030e8 100644 +--- a/arch/arm/boot/dts/imx6sl.dtsi ++++ b/arch/arm/boot/dts/imx6sl.dtsi +@@ -39,6 +39,9 @@ aliases { + spi1 = &ecspi2; + spi2 = &ecspi3; + spi3 = &ecspi4; ++ usb0 = &usbotg1; ++ usb1 = &usbotg2; ++ usb2 = &usbh; + usbphy0 = &usbphy1; + usbphy1 = &usbphy2; + }; +diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi +index bf5b262b91f91..eecb2f68a1c32 100644 +--- a/arch/arm/boot/dts/imx6sll.dtsi ++++ b/arch/arm/boot/dts/imx6sll.dtsi +@@ -36,6 +36,8 @@ aliases { + spi1 = &ecspi2; + spi3 = &ecspi3; + spi4 = &ecspi4; ++ usb0 = &usbotg1; ++ usb1 = &usbotg2; + usbphy0 = &usbphy1; + usbphy1 = &usbphy2; + }; +diff --git a/arch/arm/boot/dts/imx6sx.dtsi b/arch/arm/boot/dts/imx6sx.dtsi +index c399919943c34..629c6a7432d9b 100644 +--- a/arch/arm/boot/dts/imx6sx.dtsi ++++ b/arch/arm/boot/dts/imx6sx.dtsi +@@ -49,6 +49,9 @@ aliases { + spi2 = &ecspi3; + spi3 = &ecspi4; + spi4 = &ecspi5; ++ usb0 = &usbotg1; ++ usb1 = &usbotg2; ++ usb2 = &usbh; + usbphy0 = &usbphy1; + usbphy1 = &usbphy2; + }; +diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi +index c40684ad11b8e..b40dd0c198028 100644 +--- a/arch/arm/boot/dts/imx6ul.dtsi ++++ b/arch/arm/boot/dts/imx6ul.dtsi +@@ -47,6 +47,8 @@ aliases { + spi1 = &ecspi2; + spi2 = &ecspi3; + spi3 = &ecspi4; ++ usb0 = &usbotg1; ++ usb1 = &usbotg2; + usbphy0 = &usbphy1; + usbphy1 = &usbphy2; + }; +diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi +index cff875b80b60e..b0bcfa9094a30 100644 +--- a/arch/arm/boot/dts/imx7d.dtsi ++++ b/arch/arm/boot/dts/imx7d.dtsi +@@ -7,6 +7,12 @@ + #include + + / { ++ aliases { ++ usb0 = &usbotg1; ++ usb1 = &usbotg2; ++ usb2 = &usbh; ++ }; ++ + cpus { + cpu0: cpu@0 { + clock-frequency = <996000000>; +diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi +index 43b39ad9ddcee..334e781663cc2 100644 +--- a/arch/arm/boot/dts/imx7s.dtsi ++++ b/arch/arm/boot/dts/imx7s.dtsi +@@ -47,6 +47,8 @@ aliases { + spi1 = &ecspi2; + spi2 = &ecspi3; + spi3 = &ecspi4; ++ usb0 = &usbotg1; ++ usb1 = &usbh; + }; + + cpus { +-- +2.40.1 + diff --git a/queue-5.10/arm-dts-imx6sll-fixup-of-operating-points.patch b/queue-5.10/arm-dts-imx6sll-fixup-of-operating-points.patch new file mode 100644 index 00000000000..223141aa2b3 --- /dev/null +++ b/queue-5.10/arm-dts-imx6sll-fixup-of-operating-points.patch @@ -0,0 +1,59 @@ +From a7f2ed0b27730bad07085a112189e37e56a3cd8d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Sep 2021 11:14:37 +0200 +Subject: ARM: dts: imx6sll: fixup of operating points + +From: Andreas Kemnade + +[ Upstream commit 1875903019ea6e32e6e544c1631b119e4fd60b20 ] + +Make operating point definitions comply with binding +specifications. + +Signed-off-by: Andreas Kemnade +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Shawn Guo +Stable-dep-of: ee70b908f77a ("ARM: dts: nxp/imx6sll: fix wrong property name in usbphy node") +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/imx6sll.dtsi | 22 ++++++++++------------ + 1 file changed, 10 insertions(+), 12 deletions(-) + +diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi +index eecb2f68a1c32..2873369a57c02 100644 +--- a/arch/arm/boot/dts/imx6sll.dtsi ++++ b/arch/arm/boot/dts/imx6sll.dtsi +@@ -51,20 +51,18 @@ cpu0: cpu@0 { + device_type = "cpu"; + reg = <0>; + next-level-cache = <&L2>; +- operating-points = < ++ operating-points = + /* kHz uV */ +- 996000 1275000 +- 792000 1175000 +- 396000 1075000 +- 198000 975000 +- >; +- fsl,soc-operating-points = < ++ <996000 1275000>, ++ <792000 1175000>, ++ <396000 1075000>, ++ <198000 975000>; ++ fsl,soc-operating-points = + /* ARM kHz SOC-PU uV */ +- 996000 1175000 +- 792000 1175000 +- 396000 1175000 +- 198000 1175000 +- >; ++ <996000 1175000>, ++ <792000 1175000>, ++ <396000 1175000>, ++ <198000 1175000>; + clock-latency = <61036>; /* two CLK32 periods */ + #cooling-cells = <2>; + clocks = <&clks IMX6SLL_CLK_ARM>, +-- +2.40.1 + diff --git a/queue-5.10/arm-dts-nxp-imx6sll-fix-wrong-property-name-in-usbph.patch b/queue-5.10/arm-dts-nxp-imx6sll-fix-wrong-property-name-in-usbph.patch new file mode 100644 index 00000000000..5d0ca3a1182 --- /dev/null +++ b/queue-5.10/arm-dts-nxp-imx6sll-fix-wrong-property-name-in-usbph.patch @@ -0,0 +1,36 @@ +From 005a79aa9afc6ad9731333a74c217d7f4b27f379 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Jul 2023 10:28:33 +0800 +Subject: ARM: dts: nxp/imx6sll: fix wrong property name in usbphy node + +From: Xu Yang + +[ Upstream commit ee70b908f77a9d8f689dea986f09e6d7dc481934 ] + +Property name "phy-3p0-supply" is used instead of "phy-reg_3p0-supply". + +Fixes: 9f30b6b1a957 ("ARM: dts: imx: Add basic dtsi file for imx6sll") +cc: +Signed-off-by: Xu Yang +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/imx6sll.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/imx6sll.dtsi b/arch/arm/boot/dts/imx6sll.dtsi +index 2873369a57c02..3659fd5ecfa62 100644 +--- a/arch/arm/boot/dts/imx6sll.dtsi ++++ b/arch/arm/boot/dts/imx6sll.dtsi +@@ -552,7 +552,7 @@ usbphy2: usb-phy@20ca000 { + reg = <0x020ca000 0x1000>; + interrupts = ; + clocks = <&clks IMX6SLL_CLK_USBPHY2>; +- phy-reg_3p0-supply = <®_3p0>; ++ phy-3p0-supply = <®_3p0>; + fsl,anatop = <&anatop>; + }; + +-- +2.40.1 + diff --git a/queue-5.10/exfat-check-if-filename-entries-exceeds-max-filename.patch b/queue-5.10/exfat-check-if-filename-entries-exceeds-max-filename.patch new file mode 100644 index 00000000000..49359209c61 --- /dev/null +++ b/queue-5.10/exfat-check-if-filename-entries-exceeds-max-filename.patch @@ -0,0 +1,65 @@ +From fbfa24459c36e49bc4fd8d9db9c2efeea9f5abae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Jul 2023 21:59:37 +0900 +Subject: exfat: check if filename entries exceeds max filename length + +From: Namjae Jeon + +[ Upstream commit d42334578eba1390859012ebb91e1e556d51db49 ] + +exfat_extract_uni_name copies characters from a given file name entry into +the 'uniname' variable. This variable is actually defined on the stack of +the exfat_readdir() function. According to the definition of +the 'exfat_uni_name' type, the file name should be limited 255 characters +(+ null teminator space), but the exfat_get_uniname_from_ext_entry() +function can write more characters because there is no check if filename +entries exceeds max filename length. This patch add the check not to copy +filename characters when exceeding max filename length. + +Cc: stable@vger.kernel.org +Cc: Yuezhang Mo +Reported-by: Maxim Suhanov +Reviewed-by: Sungjong Seo +Signed-off-by: Namjae Jeon +Signed-off-by: Sasha Levin +--- + fs/exfat/dir.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c +index d2be36ddc18a5..4e9b85d35d938 100644 +--- a/fs/exfat/dir.c ++++ b/fs/exfat/dir.c +@@ -33,6 +33,7 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb, + { + int i; + struct exfat_entry_set_cache es; ++ unsigned int uni_len = 0, len; + + if (exfat_get_dentry_set(&es, sb, p_dir, entry, ES_ALL_ENTRIES)) + return; +@@ -50,7 +51,10 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb, + if (exfat_get_entry_type(ep) != TYPE_EXTEND) + break; + +- exfat_extract_uni_name(ep, uniname); ++ len = exfat_extract_uni_name(ep, uniname); ++ uni_len += len; ++ if (len != EXFAT_FILE_NAME_LEN || uni_len >= MAX_NAME_LENGTH) ++ break; + uniname += EXFAT_FILE_NAME_LEN; + } + +@@ -1037,7 +1041,8 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei, + if (entry_type == TYPE_EXTEND) { + unsigned short entry_uniname[16], unichar; + +- if (step != DIRENT_STEP_NAME) { ++ if (step != DIRENT_STEP_NAME || ++ name_len >= MAX_NAME_LENGTH) { + step = DIRENT_STEP_FILE; + continue; + } +-- +2.40.1 + diff --git a/queue-5.10/exfat-move-exfat_entry_set_cache-from-heap-to-stack.patch b/queue-5.10/exfat-move-exfat_entry_set_cache-from-heap-to-stack.patch new file mode 100644 index 00000000000..79bf5963569 --- /dev/null +++ b/queue-5.10/exfat-move-exfat_entry_set_cache-from-heap-to-stack.patch @@ -0,0 +1,239 @@ +From 6c290ca5ee81f3322bcc3c5a7879a0e100405040 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Nov 2022 11:37:13 +0800 +Subject: exfat: move exfat_entry_set_cache from heap to stack + +From: Yuezhang Mo + +[ Upstream commit 20914ff6dd56dd6b548bf5dd90bff09ef89999e4 ] + +The size of struct exfat_entry_set_cache is only 56 bytes on +64-bit system, and allocating from stack is more efficient than +allocating from heap. + +Signed-off-by: Yuezhang Mo +Reviewed-by: Andy Wu +Reviewed-by: Aoyama Wataru +Reviewed-by: Sungjong Seo +Signed-off-by: Namjae Jeon +Stable-dep-of: d42334578eba ("exfat: check if filename entries exceeds max filename length") +Signed-off-by: Sasha Levin +--- + fs/exfat/dir.c | 35 +++++++++++++++-------------------- + fs/exfat/exfat_fs.h | 5 +++-- + fs/exfat/inode.c | 13 ++++++------- + fs/exfat/namei.c | 11 +++++------ + 4 files changed, 29 insertions(+), 35 deletions(-) + +diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c +index 185aa13945d3d..d2be36ddc18a5 100644 +--- a/fs/exfat/dir.c ++++ b/fs/exfat/dir.c +@@ -32,10 +32,9 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb, + struct exfat_chain *p_dir, int entry, unsigned short *uniname) + { + int i; +- struct exfat_entry_set_cache *es; ++ struct exfat_entry_set_cache es; + +- es = exfat_get_dentry_set(sb, p_dir, entry, ES_ALL_ENTRIES); +- if (!es) ++ if (exfat_get_dentry_set(&es, sb, p_dir, entry, ES_ALL_ENTRIES)) + return; + + /* +@@ -44,8 +43,8 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb, + * Third entry : first file-name entry + * So, the index of first file-name dentry should start from 2. + */ +- for (i = 2; i < es->num_entries; i++) { +- struct exfat_dentry *ep = exfat_get_dentry_cached(es, i); ++ for (i = 2; i < es.num_entries; i++) { ++ struct exfat_dentry *ep = exfat_get_dentry_cached(&es, i); + + /* end of name entry */ + if (exfat_get_entry_type(ep) != TYPE_EXTEND) +@@ -55,7 +54,7 @@ static void exfat_get_uniname_from_ext_entry(struct super_block *sb, + uniname += EXFAT_FILE_NAME_LEN; + } + +- exfat_free_dentry_set(es, false); ++ exfat_free_dentry_set(&es, false); + } + + /* read a directory entry from the opened directory */ +@@ -613,7 +612,6 @@ int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync) + if (IS_DYNAMIC_ES(es)) + kfree(es->bh); + +- kfree(es); + return err; + } + +@@ -813,14 +811,14 @@ struct exfat_dentry *exfat_get_dentry_cached( + * pointer of entry set on success, + * NULL on failure. + */ +-struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, +- struct exfat_chain *p_dir, int entry, unsigned int type) ++int exfat_get_dentry_set(struct exfat_entry_set_cache *es, ++ struct super_block *sb, struct exfat_chain *p_dir, int entry, ++ unsigned int type) + { + int ret, i, num_bh; + unsigned int off, byte_offset, clu = 0; + sector_t sec; + struct exfat_sb_info *sbi = EXFAT_SB(sb); +- struct exfat_entry_set_cache *es; + struct exfat_dentry *ep; + int num_entries; + enum exfat_validate_dentry_mode mode = ES_MODE_STARTED; +@@ -828,17 +826,15 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, + + if (p_dir->dir == DIR_DELETED) { + exfat_err(sb, "access to deleted dentry"); +- return NULL; ++ return -EIO; + } + + byte_offset = EXFAT_DEN_TO_B(entry); + ret = exfat_walk_fat_chain(sb, p_dir, byte_offset, &clu); + if (ret) +- return NULL; ++ return ret; + +- es = kzalloc(sizeof(*es), GFP_KERNEL); +- if (!es) +- return NULL; ++ memset(es, 0, sizeof(*es)); + es->sb = sb; + es->modified = false; + +@@ -856,7 +852,7 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, + + bh = sb_bread(sb, sec); + if (!bh) +- goto free_es; ++ return -EIO; + es->bh[es->num_bh++] = bh; + + ep = exfat_get_dentry_cached(es, 0); +@@ -872,8 +868,7 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, + es->bh = kmalloc_array(num_bh, sizeof(*es->bh), GFP_KERNEL); + if (!es->bh) { + brelse(bh); +- kfree(es); +- return NULL; ++ return -ENOMEM; + } + es->bh[0] = bh; + } +@@ -902,11 +897,11 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, + if (!exfat_validate_entry(exfat_get_entry_type(ep), &mode)) + goto free_es; + } +- return es; ++ return 0; + + free_es: + exfat_free_dentry_set(es, false); +- return NULL; ++ return -EIO; + } + + enum { +diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h +index 11e579a2598d8..6ecc7a51b4d18 100644 +--- a/fs/exfat/exfat_fs.h ++++ b/fs/exfat/exfat_fs.h +@@ -470,8 +470,9 @@ struct exfat_dentry *exfat_get_dentry(struct super_block *sb, + sector_t *sector); + struct exfat_dentry *exfat_get_dentry_cached(struct exfat_entry_set_cache *es, + int num); +-struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, +- struct exfat_chain *p_dir, int entry, unsigned int type); ++int exfat_get_dentry_set(struct exfat_entry_set_cache *es, ++ struct super_block *sb, struct exfat_chain *p_dir, int entry, ++ unsigned int type); + int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync); + int exfat_count_dir_entries(struct super_block *sb, struct exfat_chain *p_dir); + +diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c +index 4bd73820a4ac0..7f70284da530f 100644 +--- a/fs/exfat/inode.c ++++ b/fs/exfat/inode.c +@@ -21,7 +21,7 @@ static int __exfat_write_inode(struct inode *inode, int sync) + { + unsigned long long on_disk_size; + struct exfat_dentry *ep, *ep2; +- struct exfat_entry_set_cache *es = NULL; ++ struct exfat_entry_set_cache es; + struct super_block *sb = inode->i_sb; + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_inode_info *ei = EXFAT_I(inode); +@@ -42,11 +42,10 @@ static int __exfat_write_inode(struct inode *inode, int sync) + exfat_set_volume_dirty(sb); + + /* get the directory entry of given file or directory */ +- es = exfat_get_dentry_set(sb, &(ei->dir), ei->entry, ES_ALL_ENTRIES); +- if (!es) ++ if (exfat_get_dentry_set(&es, sb, &(ei->dir), ei->entry, ES_ALL_ENTRIES)) + return -EIO; +- ep = exfat_get_dentry_cached(es, 0); +- ep2 = exfat_get_dentry_cached(es, 1); ++ ep = exfat_get_dentry_cached(&es, 0); ++ ep2 = exfat_get_dentry_cached(&es, 1); + + ep->dentry.file.attr = cpu_to_le16(exfat_make_attr(inode)); + +@@ -76,8 +75,8 @@ static int __exfat_write_inode(struct inode *inode, int sync) + ep2->dentry.stream.valid_size = cpu_to_le64(on_disk_size); + ep2->dentry.stream.size = ep2->dentry.stream.valid_size; + +- exfat_update_dir_chksum_with_entry_set(es); +- return exfat_free_dentry_set(es, sync); ++ exfat_update_dir_chksum_with_entry_set(&es); ++ return exfat_free_dentry_set(&es, sync); + } + + int exfat_write_inode(struct inode *inode, struct writeback_control *wbc) +diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c +index bd00afc5e4c16..10062b5282bd0 100644 +--- a/fs/exfat/namei.c ++++ b/fs/exfat/namei.c +@@ -595,7 +595,7 @@ static int exfat_find(struct inode *dir, struct qstr *qname, + struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct exfat_inode_info *ei = EXFAT_I(dir); + struct exfat_dentry *ep, *ep2; +- struct exfat_entry_set_cache *es; ++ struct exfat_entry_set_cache es; + /* for optimized dir & entry to prevent long traverse of cluster chain */ + struct exfat_hint hint_opt; + +@@ -635,11 +635,10 @@ static int exfat_find(struct inode *dir, struct qstr *qname, + if (cdir.flags & ALLOC_NO_FAT_CHAIN) + cdir.size -= dentry / sbi->dentries_per_clu; + dentry = hint_opt.eidx; +- es = exfat_get_dentry_set(sb, &cdir, dentry, ES_2_ENTRIES); +- if (!es) ++ if (exfat_get_dentry_set(&es, sb, &cdir, dentry, ES_2_ENTRIES)) + return -EIO; +- ep = exfat_get_dentry_cached(es, 0); +- ep2 = exfat_get_dentry_cached(es, 1); ++ ep = exfat_get_dentry_cached(&es, 0); ++ ep2 = exfat_get_dentry_cached(&es, 1); + + info->type = exfat_get_entry_type(ep); + info->attr = le16_to_cpu(ep->dentry.file.attr); +@@ -668,7 +667,7 @@ static int exfat_find(struct inode *dir, struct qstr *qname, + ep->dentry.file.access_time, + ep->dentry.file.access_date, + 0); +- exfat_free_dentry_set(es, false); ++ exfat_free_dentry_set(&es, false); + + if (ei->start_clu == EXFAT_FREE_CLUSTER) { + exfat_fs_error(sb, +-- +2.40.1 + diff --git a/queue-5.10/exfat-speed-up-iterate-lookup-by-fixing-start-point-.patch b/queue-5.10/exfat-speed-up-iterate-lookup-by-fixing-start-point-.patch new file mode 100644 index 00000000000..eb128256885 --- /dev/null +++ b/queue-5.10/exfat-speed-up-iterate-lookup-by-fixing-start-point-.patch @@ -0,0 +1,131 @@ +From 13ced2ee70174024313b574b2bbc769be56b2baf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Mar 2021 12:53:36 +0900 +Subject: exfat: speed up iterate/lookup by fixing start point of traversing + cluster chain + +From: Hyeongseok Kim + +[ Upstream commit c6e2f52e3051e8d898d38840104638ca8bbcdec2 ] + +When directory iterate and lookup is called, there's a buggy rewinding +of start point for traversing cluster chain to the parent directory +entry's first cluster. This caused repeated cluster chain traversing +from the first entry of the parent directory that would show worse +performance if huge amounts of files exist under the parent directory. +Fix not to rewind, make continue from currently referenced cluster and +dir entry. + +Tested with 50,000 files under single directory / 256GB sdcard, +with command "time ls -l > /dev/null", +Before : 0m08.69s real 0m00.27s user 0m05.91s system +After : 0m07.01s real 0m00.25s user 0m04.34s system + +Signed-off-by: Hyeongseok Kim +Reviewed-by: Sungjong Seo +Signed-off-by: Namjae Jeon +Stable-dep-of: d42334578eba ("exfat: check if filename entries exceeds max filename length") +Signed-off-by: Sasha Levin +--- + fs/exfat/dir.c | 19 +++++++++++++------ + fs/exfat/exfat_fs.h | 2 +- + fs/exfat/namei.c | 9 ++++++++- + 3 files changed, 22 insertions(+), 8 deletions(-) + +diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c +index 093f79ae3c671..0e1886f9a6241 100644 +--- a/fs/exfat/dir.c ++++ b/fs/exfat/dir.c +@@ -148,7 +148,7 @@ static int exfat_readdir(struct inode *inode, loff_t *cpos, struct exfat_dir_ent + 0); + + *uni_name.name = 0x0; +- exfat_get_uniname_from_ext_entry(sb, &dir, dentry, ++ exfat_get_uniname_from_ext_entry(sb, &clu, i, + uni_name.name); + exfat_utf16_to_nls(sb, &uni_name, + dir_entry->namebuf.lfn, +@@ -902,14 +902,19 @@ enum { + }; + + /* +- * return values: +- * >= 0 : return dir entiry position with the name in dir +- * -ENOENT : entry with the name does not exist +- * -EIO : I/O error ++ * @ei: inode info of parent directory ++ * @p_dir: directory structure of parent directory ++ * @num_entries:entry size of p_uniname ++ * @hint_opt: If p_uniname is found, filled with optimized dir/entry ++ * for traversing cluster chain. ++ * @return: ++ * >= 0: file directory entry position where the name exists ++ * -ENOENT: entry with the name does not exist ++ * -EIO: I/O error + */ + int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei, + struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname, +- int num_entries, unsigned int type) ++ int num_entries, unsigned int type, struct exfat_hint *hint_opt) + { + int i, rewind = 0, dentry = 0, end_eidx = 0, num_ext = 0, len; + int order, step, name_len = 0; +@@ -986,6 +991,8 @@ int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei, + + if (entry_type == TYPE_FILE || entry_type == TYPE_DIR) { + step = DIRENT_STEP_FILE; ++ hint_opt->clu = clu.dir; ++ hint_opt->eidx = i; + if (type == TYPE_ALL || type == entry_type) { + num_ext = ep->dentry.file.num_ext; + step = DIRENT_STEP_STRM; +diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h +index 07b09af57436f..436683da2515c 100644 +--- a/fs/exfat/exfat_fs.h ++++ b/fs/exfat/exfat_fs.h +@@ -458,7 +458,7 @@ void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es); + int exfat_calc_num_entries(struct exfat_uni_name *p_uniname); + int exfat_find_dir_entry(struct super_block *sb, struct exfat_inode_info *ei, + struct exfat_chain *p_dir, struct exfat_uni_name *p_uniname, +- int num_entries, unsigned int type); ++ int num_entries, unsigned int type, struct exfat_hint *hint_opt); + int exfat_alloc_new_dir(struct inode *inode, struct exfat_chain *clu); + int exfat_find_location(struct super_block *sb, struct exfat_chain *p_dir, + int entry, sector_t *sector, int *offset); +diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c +index 1382d816912c8..bd00afc5e4c16 100644 +--- a/fs/exfat/namei.c ++++ b/fs/exfat/namei.c +@@ -596,6 +596,8 @@ static int exfat_find(struct inode *dir, struct qstr *qname, + struct exfat_inode_info *ei = EXFAT_I(dir); + struct exfat_dentry *ep, *ep2; + struct exfat_entry_set_cache *es; ++ /* for optimized dir & entry to prevent long traverse of cluster chain */ ++ struct exfat_hint hint_opt; + + if (qname->len == 0) + return -ENOENT; +@@ -619,7 +621,7 @@ static int exfat_find(struct inode *dir, struct qstr *qname, + + /* search the file name for directories */ + dentry = exfat_find_dir_entry(sb, ei, &cdir, &uni_name, +- num_entries, TYPE_ALL); ++ num_entries, TYPE_ALL, &hint_opt); + + if (dentry < 0) + return dentry; /* -error value */ +@@ -628,6 +630,11 @@ static int exfat_find(struct inode *dir, struct qstr *qname, + info->entry = dentry; + info->num_subdirs = 0; + ++ /* adjust cdir to the optimized value */ ++ cdir.dir = hint_opt.clu; ++ if (cdir.flags & ALLOC_NO_FAT_CHAIN) ++ cdir.size -= dentry / sbi->dentries_per_clu; ++ dentry = hint_opt.eidx; + es = exfat_get_dentry_set(sb, &cdir, dentry, ES_2_ENTRIES); + if (!es) + return -EIO; +-- +2.40.1 + diff --git a/queue-5.10/exfat-support-dynamic-allocate-bh-for-exfat_entry_se.patch b/queue-5.10/exfat-support-dynamic-allocate-bh-for-exfat_entry_se.patch new file mode 100644 index 00000000000..745cb404aaf --- /dev/null +++ b/queue-5.10/exfat-support-dynamic-allocate-bh-for-exfat_entry_se.patch @@ -0,0 +1,91 @@ +From 1471114981b32b5b4deb18990e261e67e5ef6ddf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Nov 2022 13:50:22 +0800 +Subject: exfat: support dynamic allocate bh for exfat_entry_set_cache + +From: Yuezhang Mo + +[ Upstream commit a3ff29a95fde16906304455aa8c0bd84eb770258 ] + +In special cases, a file or a directory may occupied more than 19 +directory entries, pre-allocating 3 bh is not enough. Such as + - Support vendor secondary directory entry in the future. + - Since file directory entry is damaged, the SecondaryCount + field is bigger than 18. + +So this commit supports dynamic allocation of bh. + +Signed-off-by: Yuezhang Mo +Reviewed-by: Andy Wu +Reviewed-by: Aoyama Wataru +Reviewed-by: Sungjong Seo +Signed-off-by: Namjae Jeon +Stable-dep-of: d42334578eba ("exfat: check if filename entries exceeds max filename length") +Signed-off-by: Sasha Levin +--- + fs/exfat/dir.c | 15 +++++++++++++++ + fs/exfat/exfat_fs.h | 5 ++++- + 2 files changed, 19 insertions(+), 1 deletion(-) + +diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c +index 0e1886f9a6241..185aa13945d3d 100644 +--- a/fs/exfat/dir.c ++++ b/fs/exfat/dir.c +@@ -609,6 +609,10 @@ int exfat_free_dentry_set(struct exfat_entry_set_cache *es, int sync) + bforget(es->bh[i]); + else + brelse(es->bh[i]); ++ ++ if (IS_DYNAMIC_ES(es)) ++ kfree(es->bh); ++ + kfree(es); + return err; + } +@@ -844,6 +848,7 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, + /* byte offset in sector */ + off = EXFAT_BLK_OFFSET(byte_offset, sb); + es->start_off = off; ++ es->bh = es->__bh; + + /* sector offset in cluster */ + sec = EXFAT_B_TO_BLK(byte_offset, sb); +@@ -863,6 +868,16 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, + es->num_entries = num_entries; + + num_bh = EXFAT_B_TO_BLK_ROUND_UP(off + num_entries * DENTRY_SIZE, sb); ++ if (num_bh > ARRAY_SIZE(es->__bh)) { ++ es->bh = kmalloc_array(num_bh, sizeof(*es->bh), GFP_KERNEL); ++ if (!es->bh) { ++ brelse(bh); ++ kfree(es); ++ return NULL; ++ } ++ es->bh[0] = bh; ++ } ++ + for (i = 1; i < num_bh; i++) { + /* get the next sector */ + if (exfat_is_last_sector_in_cluster(sbi, sec)) { +diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h +index 436683da2515c..11e579a2598d8 100644 +--- a/fs/exfat/exfat_fs.h ++++ b/fs/exfat/exfat_fs.h +@@ -170,10 +170,13 @@ struct exfat_entry_set_cache { + bool modified; + unsigned int start_off; + int num_bh; +- struct buffer_head *bh[DIR_CACHE_SIZE]; ++ struct buffer_head *__bh[DIR_CACHE_SIZE]; ++ struct buffer_head **bh; + unsigned int num_entries; + }; + ++#define IS_DYNAMIC_ES(es) ((es)->__bh != (es)->bh) ++ + struct exfat_dir_entry { + struct exfat_chain dir; + int entry; +-- +2.40.1 + diff --git a/queue-5.10/mt76-move-band-capabilities-in-mt76_phy.patch b/queue-5.10/mt76-move-band-capabilities-in-mt76_phy.patch new file mode 100644 index 00000000000..d1404ee1659 --- /dev/null +++ b/queue-5.10/mt76-move-band-capabilities-in-mt76_phy.patch @@ -0,0 +1,295 @@ +From 961b846f4b586328bcb83c59be949312f4dbacca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Nov 2020 10:56:56 +0100 +Subject: mt76: move band capabilities in mt76_phy + +From: Lorenzo Bianconi + +[ Upstream commit 48dbce5cb1ba3ce5b2ed3e997bcb1e4697d41b71 ] + +This is a preliminary patch to move properly support mt7915 dbdc + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Felix Fietkau +Stable-dep-of: 421033deb915 ("wifi: mt76: mt7615: do not advertise 5 GHz on first phy of MT7615D (DBDC)") +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mac80211.c | 8 ++++---- + drivers/net/wireless/mediatek/mt76/mt76.h | 2 +- + .../net/wireless/mediatek/mt76/mt7603/eeprom.c | 2 +- + drivers/net/wireless/mediatek/mt76/mt7615/dma.c | 2 +- + .../net/wireless/mediatek/mt76/mt7615/eeprom.c | 16 ++++++++-------- + .../net/wireless/mediatek/mt76/mt76x0/eeprom.c | 6 +++--- + drivers/net/wireless/mediatek/mt76/mt76x0/init.c | 4 ++-- + drivers/net/wireless/mediatek/mt76/mt76x0/phy.c | 4 ++-- + .../net/wireless/mediatek/mt76/mt76x02_eeprom.c | 8 ++++---- + .../net/wireless/mediatek/mt76/mt7915/eeprom.c | 8 ++++---- + drivers/net/wireless/mediatek/mt76/mt7915/init.c | 5 ++--- + 11 files changed, 32 insertions(+), 33 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c +index 81ff3b4c6c1b3..dc1191aa0443e 100644 +--- a/drivers/net/wireless/mediatek/mt76/mac80211.c ++++ b/drivers/net/wireless/mediatek/mt76/mac80211.c +@@ -160,9 +160,9 @@ static void mt76_init_stream_cap(struct mt76_phy *phy, + + void mt76_set_stream_caps(struct mt76_phy *phy, bool vht) + { +- if (phy->dev->cap.has_2ghz) ++ if (phy->cap.has_2ghz) + mt76_init_stream_cap(phy, &phy->sband_2g.sband, false); +- if (phy->dev->cap.has_5ghz) ++ if (phy->cap.has_5ghz) + mt76_init_stream_cap(phy, &phy->sband_5g.sband, vht); + } + EXPORT_SYMBOL_GPL(mt76_set_stream_caps); +@@ -463,13 +463,13 @@ int mt76_register_device(struct mt76_dev *dev, bool vht, + dev_set_drvdata(dev->dev, dev); + mt76_phy_init(dev, hw); + +- if (dev->cap.has_2ghz) { ++ if (phy->cap.has_2ghz) { + ret = mt76_init_sband_2g(dev, rates, n_rates); + if (ret) + return ret; + } + +- if (dev->cap.has_5ghz) { ++ if (phy->cap.has_5ghz) { + ret = mt76_init_sband_5g(dev, rates + 4, n_rates - 4, vht); + if (ret) + return ret; +diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h +index 5a8060790a61f..16e65020a242d 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76.h ++++ b/drivers/net/wireless/mediatek/mt76/mt76.h +@@ -561,6 +561,7 @@ struct mt76_phy { + struct mt76_channel_state *chan_state; + ktime_t survey_time; + ++ struct mt76_hw_cap cap; + struct mt76_sband sband_2g; + struct mt76_sband sband_5g; + +@@ -630,7 +631,6 @@ struct mt76_dev { + + struct debugfs_blob_wrapper eeprom; + struct debugfs_blob_wrapper otp; +- struct mt76_hw_cap cap; + + struct mt76_rate_power rate_power; + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c +index 01f1e0da5ee1e..a6df733aca492 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7603/eeprom.c +@@ -170,7 +170,7 @@ int mt7603_eeprom_init(struct mt7603_dev *dev) + } + + eeprom = (u8 *)dev->mt76.eeprom.data; +- dev->mt76.cap.has_2ghz = true; ++ dev->mphy.cap.has_2ghz = true; + memcpy(dev->mt76.macaddr, eeprom + MT_EE_MAC_ADDR, ETH_ALEN); + + /* Check for 1SS devices */ +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/dma.c b/drivers/net/wireless/mediatek/mt76/mt7615/dma.c +index bf8ae14121dba..637ef0882436c 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/dma.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/dma.c +@@ -202,7 +202,7 @@ int mt7615_dma_init(struct mt7615_dev *dev) + int ret; + + /* Increase buffer size to receive large VHT MPDUs */ +- if (dev->mt76.cap.has_5ghz) ++ if (dev->mphy.cap.has_5ghz) + rx_buf_size *= 2; + + mt76_dma_attach(&dev->mt76); +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c +index e9cdcdc54d5c3..714d1ff69c560 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c +@@ -100,20 +100,20 @@ mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev) + + if (is_mt7663(&dev->mt76)) { + /* dual band */ +- dev->mt76.cap.has_2ghz = true; +- dev->mt76.cap.has_5ghz = true; ++ dev->mphy.cap.has_2ghz = true; ++ dev->mphy.cap.has_5ghz = true; + return; + } + + if (is_mt7622(&dev->mt76)) { + /* 2GHz only */ +- dev->mt76.cap.has_2ghz = true; ++ dev->mphy.cap.has_2ghz = true; + return; + } + + if (is_mt7611(&dev->mt76)) { + /* 5GHz only */ +- dev->mt76.cap.has_5ghz = true; ++ dev->mphy.cap.has_5ghz = true; + return; + } + +@@ -121,17 +121,17 @@ mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev) + eeprom[MT_EE_WIFI_CONF]); + switch (val) { + case MT_EE_5GHZ: +- dev->mt76.cap.has_5ghz = true; ++ dev->mphy.cap.has_5ghz = true; + break; + case MT_EE_2GHZ: +- dev->mt76.cap.has_2ghz = true; ++ dev->mphy.cap.has_2ghz = true; + break; + case MT_EE_DBDC: + dev->dbdc_support = true; + /* fall through */ + default: +- dev->mt76.cap.has_2ghz = true; +- dev->mt76.cap.has_5ghz = true; ++ dev->mphy.cap.has_2ghz = true; ++ dev->mphy.cap.has_5ghz = true; + break; + } + } +diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c +index 9087607b621e8..ebf4c96532d31 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c +@@ -52,15 +52,15 @@ static void mt76x0_set_chip_cap(struct mt76x02_dev *dev) + + mt76x02_eeprom_parse_hw_cap(dev); + dev_dbg(dev->mt76.dev, "2GHz %d 5GHz %d\n", +- dev->mt76.cap.has_2ghz, dev->mt76.cap.has_5ghz); ++ dev->mphy.cap.has_2ghz, dev->mphy.cap.has_5ghz); + + if (dev->no_2ghz) { +- dev->mt76.cap.has_2ghz = false; ++ dev->mphy.cap.has_2ghz = false; + dev_dbg(dev->mt76.dev, "mask out 2GHz support\n"); + } + + if (is_mt7630(dev)) { +- dev->mt76.cap.has_5ghz = false; ++ dev->mphy.cap.has_5ghz = false; + dev_dbg(dev->mt76.dev, "mask out 5GHz support\n"); + } + +diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +index d78866bf41ba3..0bac39bf3b66d 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76x0/init.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76x0/init.c +@@ -245,7 +245,7 @@ int mt76x0_register_device(struct mt76x02_dev *dev) + if (ret) + return ret; + +- if (dev->mt76.cap.has_5ghz) { ++ if (dev->mphy.cap.has_5ghz) { + struct ieee80211_supported_band *sband; + + sband = &dev->mphy.sband_5g.sband; +@@ -253,7 +253,7 @@ int mt76x0_register_device(struct mt76x02_dev *dev) + mt76x0_init_txpower(dev, sband); + } + +- if (dev->mt76.cap.has_2ghz) ++ if (dev->mphy.cap.has_2ghz) + mt76x0_init_txpower(dev, &dev->mphy.sband_2g.sband); + + mt76x02_init_debugfs(dev); +diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c +index 3de33aadf7941..e91c314cdfac5 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76x0/phy.c +@@ -447,11 +447,11 @@ static void mt76x0_phy_ant_select(struct mt76x02_dev *dev) + else + coex3 |= BIT(4); + coex3 |= BIT(3); +- if (dev->mt76.cap.has_2ghz) ++ if (dev->mphy.cap.has_2ghz) + wlan |= BIT(6); + } else { + /* sigle antenna mode */ +- if (dev->mt76.cap.has_5ghz) { ++ if (dev->mphy.cap.has_5ghz) { + coex3 |= BIT(3) | BIT(4); + } else { + wlan |= BIT(6); +diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c +index c54c50fd639a9..0acabba2d1a50 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c +@@ -75,14 +75,14 @@ void mt76x02_eeprom_parse_hw_cap(struct mt76x02_dev *dev) + + switch (FIELD_GET(MT_EE_NIC_CONF_0_BOARD_TYPE, val)) { + case BOARD_TYPE_5GHZ: +- dev->mt76.cap.has_5ghz = true; ++ dev->mphy.cap.has_5ghz = true; + break; + case BOARD_TYPE_2GHZ: +- dev->mt76.cap.has_2ghz = true; ++ dev->mphy.cap.has_2ghz = true; + break; + default: +- dev->mt76.cap.has_2ghz = true; +- dev->mt76.cap.has_5ghz = true; ++ dev->mphy.cap.has_2ghz = true; ++ dev->mphy.cap.has_5ghz = true; + break; + } + } +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c +index e4c5f968f706d..5f6c527611f20 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c +@@ -57,14 +57,14 @@ static void mt7915_eeprom_parse_hw_cap(struct mt7915_dev *dev) + val = FIELD_GET(MT_EE_WIFI_CONF_BAND_SEL, val); + switch (val) { + case MT_EE_5GHZ: +- dev->mt76.cap.has_5ghz = true; ++ dev->mphy.cap.has_5ghz = true; + break; + case MT_EE_2GHZ: +- dev->mt76.cap.has_2ghz = true; ++ dev->mphy.cap.has_2ghz = true; + break; + default: +- dev->mt76.cap.has_2ghz = true; +- dev->mt76.cap.has_5ghz = true; ++ dev->mphy.cap.has_2ghz = true; ++ dev->mphy.cap.has_5ghz = true; + break; + } + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c +index 8f01ca1694bca..99683688a8363 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c +@@ -528,10 +528,9 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy) + { + struct ieee80211_sband_iftype_data *data; + struct ieee80211_supported_band *band; +- struct mt76_dev *mdev = &phy->dev->mt76; + int n; + +- if (mdev->cap.has_2ghz) { ++ if (phy->mt76->cap.has_2ghz) { + data = phy->iftype[NL80211_BAND_2GHZ]; + n = mt7915_init_he_caps(phy, NL80211_BAND_2GHZ, data); + +@@ -540,7 +539,7 @@ void mt7915_set_stream_he_caps(struct mt7915_phy *phy) + band->n_iftype_data = n; + } + +- if (mdev->cap.has_5ghz) { ++ if (phy->mt76->cap.has_5ghz) { + data = phy->iftype[NL80211_BAND_5GHZ]; + n = mt7915_init_he_caps(phy, NL80211_BAND_5GHZ, data); + +-- +2.40.1 + diff --git a/queue-5.10/mt76-mt7615-fix-fall-through-warnings-for-clang.patch b/queue-5.10/mt76-mt7615-fix-fall-through-warnings-for-clang.patch new file mode 100644 index 00000000000..2ef912161d3 --- /dev/null +++ b/queue-5.10/mt76-mt7615-fix-fall-through-warnings-for-clang.patch @@ -0,0 +1,42 @@ +From dfd012be3e12f57e4560c60120630906b1a4e39c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Nov 2020 12:37:18 -0600 +Subject: mt76: mt7615: Fix fall-through warnings for Clang + +From: Gustavo A. R. Silva + +[ Upstream commit f12758f6f929dbcd37abdb1d91d245539eca48f8 ] + +In preparation to enable -Wimplicit-fallthrough for Clang, fix a +warning by replacing a /* fall through */ comment with the new +pseudo-keyword macro fallthrough; instead of letting the code fall +through to the next case. + +Notice that Clang doesn't recognize /* fall through */ comments as +implicit fall-through markings. + +Link: https://github.com/KSPP/linux/issues/115 +Signed-off-by: Gustavo A. R. Silva +Signed-off-by: Felix Fietkau +Stable-dep-of: 421033deb915 ("wifi: mt76: mt7615: do not advertise 5 GHz on first phy of MT7615D (DBDC)") +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c +index 714d1ff69c560..48ce24f0f77b7 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c +@@ -128,7 +128,7 @@ mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev) + break; + case MT_EE_DBDC: + dev->dbdc_support = true; +- /* fall through */ ++ fallthrough; + default: + dev->mphy.cap.has_2ghz = true; + dev->mphy.cap.has_5ghz = true; +-- +2.40.1 + diff --git a/queue-5.10/pm-sleep-wakeirq-fix-wake-irq-arming.patch b/queue-5.10/pm-sleep-wakeirq-fix-wake-irq-arming.patch new file mode 100644 index 00000000000..2435fc99b3c --- /dev/null +++ b/queue-5.10/pm-sleep-wakeirq-fix-wake-irq-arming.patch @@ -0,0 +1,95 @@ +From 19ecf8b860166f21bf563792f7dc0e775d3648f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Jul 2023 16:57:39 +0200 +Subject: PM: sleep: wakeirq: fix wake irq arming + +From: Johan Hovold + +[ Upstream commit 8527beb12087238d4387607597b4020bc393c4b4 ] + +The decision whether to enable a wake irq during suspend can not be done +based on the runtime PM state directly as a driver may use wake irqs +without implementing runtime PM. Such drivers specifically leave the +state set to the default 'suspended' and the wake irq is thus never +enabled at suspend. + +Add a new wake irq flag to track whether a dedicated wake irq has been +enabled at runtime suspend and therefore must not be enabled at system +suspend. + +Note that pm_runtime_enabled() can not be used as runtime PM is always +disabled during late suspend. + +Fixes: 69728051f5bf ("PM / wakeirq: Fix unbalanced IRQ enable for wakeirq") +Cc: 4.16+ # 4.16+ +Signed-off-by: Johan Hovold +Reviewed-by: Tony Lindgren +Tested-by: Tony Lindgren +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/base/power/power.h | 1 + + drivers/base/power/wakeirq.c | 12 ++++++++---- + 2 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h +index 0eb7f02b3ad59..922ed457db191 100644 +--- a/drivers/base/power/power.h ++++ b/drivers/base/power/power.h +@@ -29,6 +29,7 @@ extern u64 pm_runtime_active_time(struct device *dev); + #define WAKE_IRQ_DEDICATED_MASK (WAKE_IRQ_DEDICATED_ALLOCATED | \ + WAKE_IRQ_DEDICATED_MANAGED | \ + WAKE_IRQ_DEDICATED_REVERSE) ++#define WAKE_IRQ_DEDICATED_ENABLED BIT(3) + + struct wake_irq { + struct device *dev; +diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c +index a6d53f0173d35..aea690c64e394 100644 +--- a/drivers/base/power/wakeirq.c ++++ b/drivers/base/power/wakeirq.c +@@ -317,8 +317,10 @@ void dev_pm_enable_wake_irq_check(struct device *dev, + return; + + enable: +- if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) ++ if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) { + enable_irq(wirq->irq); ++ wirq->status |= WAKE_IRQ_DEDICATED_ENABLED; ++ } + } + + /** +@@ -339,8 +341,10 @@ void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable) + if (cond_disable && (wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) + return; + +- if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) ++ if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) { ++ wirq->status &= ~WAKE_IRQ_DEDICATED_ENABLED; + disable_irq_nosync(wirq->irq); ++ } + } + + /** +@@ -379,7 +383,7 @@ void dev_pm_arm_wake_irq(struct wake_irq *wirq) + + if (device_may_wakeup(wirq->dev)) { + if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED && +- !pm_runtime_status_suspended(wirq->dev)) ++ !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED)) + enable_irq(wirq->irq); + + enable_irq_wake(wirq->irq); +@@ -402,7 +406,7 @@ void dev_pm_disarm_wake_irq(struct wake_irq *wirq) + disable_irq_wake(wirq->irq); + + if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED && +- !pm_runtime_status_suspended(wirq->dev)) ++ !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED)) + disable_irq_nosync(wirq->irq); + } + } +-- +2.40.1 + diff --git a/queue-5.10/pm-wakeirq-support-enabling-wake-up-irq-after-runtim.patch b/queue-5.10/pm-wakeirq-support-enabling-wake-up-irq-after-runtim.patch new file mode 100644 index 00000000000..3abe7ab45ce --- /dev/null +++ b/queue-5.10/pm-wakeirq-support-enabling-wake-up-irq-after-runtim.patch @@ -0,0 +1,290 @@ +From 3f52d790fa0341c0dde5210361bba6b1153d215b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Oct 2021 15:01:53 +0800 +Subject: PM / wakeirq: support enabling wake-up irq after runtime_suspend + called + +From: Chunfeng Yun + +[ Upstream commit 259714100d98b50bf04d36a21bf50ca8b829fc11 ] + +When the dedicated wake IRQ is level trigger, and it uses the +device's low-power status as the wakeup source, that means if the +device is not in low-power state, the wake IRQ will be triggered +if enabled; For this case, need enable the wake IRQ after running +the device's ->runtime_suspend() which make it enter low-power state. + +e.g. +Assume the wake IRQ is a low level trigger type, and the wakeup +signal comes from the low-power status of the device. +The wakeup signal is low level at running time (0), and becomes +high level when the device enters low-power state (runtime_suspend +(1) is called), a wakeup event at (2) make the device exit low-power +state, then the wakeup signal also becomes low level. + + ------------------ + | ^ ^| +---------------- | | -------------- + |<---(0)--->|<--(1)--| (3) (2) (4) + +if enable the wake IRQ before running runtime_suspend during (0), +a wake IRQ will arise, it causes resume immediately; +it works if enable wake IRQ ( e.g. at (3) or (4)) after running +->runtime_suspend(). + +This patch introduces a new status WAKE_IRQ_DEDICATED_REVERSE to +optionally support enabling wake IRQ after running ->runtime_suspend(). + +Suggested-by: Rafael J. Wysocki +Signed-off-by: Chunfeng Yun +Signed-off-by: Rafael J. Wysocki +Stable-dep-of: 8527beb12087 ("PM: sleep: wakeirq: fix wake irq arming") +Signed-off-by: Sasha Levin +--- + drivers/base/power/power.h | 7 ++- + drivers/base/power/runtime.c | 6 ++- + drivers/base/power/wakeirq.c | 101 +++++++++++++++++++++++++++-------- + include/linux/pm_wakeirq.h | 9 +++- + 4 files changed, 96 insertions(+), 27 deletions(-) + +diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h +index 54292cdd7808b..0eb7f02b3ad59 100644 +--- a/drivers/base/power/power.h ++++ b/drivers/base/power/power.h +@@ -25,8 +25,10 @@ extern u64 pm_runtime_active_time(struct device *dev); + + #define WAKE_IRQ_DEDICATED_ALLOCATED BIT(0) + #define WAKE_IRQ_DEDICATED_MANAGED BIT(1) ++#define WAKE_IRQ_DEDICATED_REVERSE BIT(2) + #define WAKE_IRQ_DEDICATED_MASK (WAKE_IRQ_DEDICATED_ALLOCATED | \ +- WAKE_IRQ_DEDICATED_MANAGED) ++ WAKE_IRQ_DEDICATED_MANAGED | \ ++ WAKE_IRQ_DEDICATED_REVERSE) + + struct wake_irq { + struct device *dev; +@@ -39,7 +41,8 @@ extern void dev_pm_arm_wake_irq(struct wake_irq *wirq); + extern void dev_pm_disarm_wake_irq(struct wake_irq *wirq); + extern void dev_pm_enable_wake_irq_check(struct device *dev, + bool can_change_status); +-extern void dev_pm_disable_wake_irq_check(struct device *dev); ++extern void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable); ++extern void dev_pm_enable_wake_irq_complete(struct device *dev); + + #ifdef CONFIG_PM_SLEEP + +diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c +index 360094692d29e..fbbc3ed143f27 100644 +--- a/drivers/base/power/runtime.c ++++ b/drivers/base/power/runtime.c +@@ -675,6 +675,8 @@ static int rpm_suspend(struct device *dev, int rpmflags) + if (retval) + goto fail; + ++ dev_pm_enable_wake_irq_complete(dev); ++ + no_callback: + __update_runtime_status(dev, RPM_SUSPENDED); + pm_runtime_deactivate_timer(dev); +@@ -720,7 +722,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) + return retval; + + fail: +- dev_pm_disable_wake_irq_check(dev); ++ dev_pm_disable_wake_irq_check(dev, true); + __update_runtime_status(dev, RPM_ACTIVE); + dev->power.deferred_resume = false; + wake_up_all(&dev->power.wait_queue); +@@ -903,7 +905,7 @@ static int rpm_resume(struct device *dev, int rpmflags) + + callback = RPM_GET_CALLBACK(dev, runtime_resume); + +- dev_pm_disable_wake_irq_check(dev); ++ dev_pm_disable_wake_irq_check(dev, false); + retval = rpm_callback(callback, dev); + if (retval) { + __update_runtime_status(dev, RPM_SUSPENDED); +diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c +index 8e021082dba8c..a6d53f0173d35 100644 +--- a/drivers/base/power/wakeirq.c ++++ b/drivers/base/power/wakeirq.c +@@ -145,24 +145,7 @@ static irqreturn_t handle_threaded_wake_irq(int irq, void *_wirq) + return IRQ_HANDLED; + } + +-/** +- * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt +- * @dev: Device entry +- * @irq: Device wake-up interrupt +- * +- * Unless your hardware has separate wake-up interrupts in addition +- * to the device IO interrupts, you don't need this. +- * +- * Sets up a threaded interrupt handler for a device that has +- * a dedicated wake-up interrupt in addition to the device IO +- * interrupt. +- * +- * The interrupt starts disabled, and needs to be managed for +- * the device by the bus code or the device driver using +- * dev_pm_enable_wake_irq() and dev_pm_disable_wake_irq() +- * functions. +- */ +-int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) ++static int __dev_pm_set_dedicated_wake_irq(struct device *dev, int irq, unsigned int flag) + { + struct wake_irq *wirq; + int err; +@@ -200,7 +183,7 @@ int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) + if (err) + goto err_free_irq; + +- wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED; ++ wirq->status = WAKE_IRQ_DEDICATED_ALLOCATED | flag; + + return err; + +@@ -213,8 +196,57 @@ int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) + + return err; + } ++ ++ ++/** ++ * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt ++ * @dev: Device entry ++ * @irq: Device wake-up interrupt ++ * ++ * Unless your hardware has separate wake-up interrupts in addition ++ * to the device IO interrupts, you don't need this. ++ * ++ * Sets up a threaded interrupt handler for a device that has ++ * a dedicated wake-up interrupt in addition to the device IO ++ * interrupt. ++ * ++ * The interrupt starts disabled, and needs to be managed for ++ * the device by the bus code or the device driver using ++ * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*() ++ * functions. ++ */ ++int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) ++{ ++ return __dev_pm_set_dedicated_wake_irq(dev, irq, 0); ++} + EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq); + ++/** ++ * dev_pm_set_dedicated_wake_irq_reverse - Request a dedicated wake-up interrupt ++ * with reverse enable ordering ++ * @dev: Device entry ++ * @irq: Device wake-up interrupt ++ * ++ * Unless your hardware has separate wake-up interrupts in addition ++ * to the device IO interrupts, you don't need this. ++ * ++ * Sets up a threaded interrupt handler for a device that has a dedicated ++ * wake-up interrupt in addition to the device IO interrupt. It sets ++ * the status of WAKE_IRQ_DEDICATED_REVERSE to tell rpm_suspend() ++ * to enable dedicated wake-up interrupt after running the runtime suspend ++ * callback for @dev. ++ * ++ * The interrupt starts disabled, and needs to be managed for ++ * the device by the bus code or the device driver using ++ * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*() ++ * functions. ++ */ ++int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq) ++{ ++ return __dev_pm_set_dedicated_wake_irq(dev, irq, WAKE_IRQ_DEDICATED_REVERSE); ++} ++EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq_reverse); ++ + /** + * dev_pm_enable_wake_irq - Enable device wake-up interrupt + * @dev: Device +@@ -285,27 +317,54 @@ void dev_pm_enable_wake_irq_check(struct device *dev, + return; + + enable: +- enable_irq(wirq->irq); ++ if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) ++ enable_irq(wirq->irq); + } + + /** + * dev_pm_disable_wake_irq_check - Checks and disables wake-up interrupt + * @dev: Device ++ * @cond_disable: if set, also check WAKE_IRQ_DEDICATED_REVERSE + * + * Disables wake-up interrupt conditionally based on status. + * Should be only called from rpm_suspend() and rpm_resume() path. + */ +-void dev_pm_disable_wake_irq_check(struct device *dev) ++void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable) + { + struct wake_irq *wirq = dev->power.wakeirq; + + if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK)) + return; + ++ if (cond_disable && (wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) ++ return; ++ + if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) + disable_irq_nosync(wirq->irq); + } + ++/** ++ * dev_pm_enable_wake_irq_complete - enable wake IRQ not enabled before ++ * @dev: Device using the wake IRQ ++ * ++ * Enable wake IRQ conditionally based on status, mainly used if want to ++ * enable wake IRQ after running ->runtime_suspend() which depends on ++ * WAKE_IRQ_DEDICATED_REVERSE. ++ * ++ * Should be only called from rpm_suspend() path. ++ */ ++void dev_pm_enable_wake_irq_complete(struct device *dev) ++{ ++ struct wake_irq *wirq = dev->power.wakeirq; ++ ++ if (!wirq || !(wirq->status & WAKE_IRQ_DEDICATED_MASK)) ++ return; ++ ++ if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED && ++ wirq->status & WAKE_IRQ_DEDICATED_REVERSE) ++ enable_irq(wirq->irq); ++} ++ + /** + * dev_pm_arm_wake_irq - Arm device wake-up + * @wirq: Device wake-up interrupt +diff --git a/include/linux/pm_wakeirq.h b/include/linux/pm_wakeirq.h +index cd5b62db90845..e63a63aa47a37 100644 +--- a/include/linux/pm_wakeirq.h ++++ b/include/linux/pm_wakeirq.h +@@ -17,8 +17,8 @@ + #ifdef CONFIG_PM + + extern int dev_pm_set_wake_irq(struct device *dev, int irq); +-extern int dev_pm_set_dedicated_wake_irq(struct device *dev, +- int irq); ++extern int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq); ++extern int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq); + extern void dev_pm_clear_wake_irq(struct device *dev); + extern void dev_pm_enable_wake_irq(struct device *dev); + extern void dev_pm_disable_wake_irq(struct device *dev); +@@ -35,6 +35,11 @@ static inline int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) + return 0; + } + ++static inline int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq) ++{ ++ return 0; ++} ++ + static inline void dev_pm_clear_wake_irq(struct device *dev) + { + } +-- +2.40.1 + diff --git a/queue-5.10/selftests-rseq-check-if-libc-rseq-support-is-registe.patch b/queue-5.10/selftests-rseq-check-if-libc-rseq-support-is-registe.patch new file mode 100644 index 00000000000..cf90392072a --- /dev/null +++ b/queue-5.10/selftests-rseq-check-if-libc-rseq-support-is-registe.patch @@ -0,0 +1,44 @@ +From 945041e91c00299bf5298d73776ca3ce500fb85f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Jun 2022 11:48:30 -0400 +Subject: selftests/rseq: check if libc rseq support is registered + +From: Michael Jeanson + +[ Upstream commit d1a997ba4c1bf65497d956aea90de42a6398f73a ] + +When checking for libc rseq support in the library constructor, don't +only depend on the symbols presence, check that the registration was +completed. + +This targets a scenario where the libc has rseq support but it is not +wired for the current architecture in 'bits/rseq.h', we want to fallback +to our internal registration mechanism. + +Signed-off-by: Michael Jeanson +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Mathieu Desnoyers +Link: https://lore.kernel.org/r/20220614154830.1367382-4-mjeanson@efficios.com +Stable-dep-of: 3bcbc20942db ("selftests/rseq: Play nice with binaries statically linked against glibc 2.35+") +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/rseq/rseq.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/rseq/rseq.c b/tools/testing/selftests/rseq/rseq.c +index 986b9458efb26..4177f9507bbee 100644 +--- a/tools/testing/selftests/rseq/rseq.c ++++ b/tools/testing/selftests/rseq/rseq.c +@@ -111,7 +111,8 @@ void rseq_init(void) + libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset"); + libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size"); + libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags"); +- if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p) { ++ if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p && ++ *libc_rseq_size_p != 0) { + /* rseq registration owned by glibc */ + rseq_offset = *libc_rseq_offset_p; + rseq_size = *libc_rseq_size_p; +-- +2.40.1 + diff --git a/queue-5.10/selftests-rseq-play-nice-with-binaries-statically-li.patch b/queue-5.10/selftests-rseq-play-nice-with-binaries-statically-li.patch new file mode 100644 index 00000000000..115a8926b62 --- /dev/null +++ b/queue-5.10/selftests-rseq-play-nice-with-binaries-statically-li.patch @@ -0,0 +1,84 @@ +From be2e644ce622bb85699da2eab45fe0b43cf7b8d4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Jul 2023 15:33:52 -0700 +Subject: selftests/rseq: Play nice with binaries statically linked against + glibc 2.35+ + +From: Sean Christopherson + +[ Upstream commit 3bcbc20942db5d738221cca31a928efc09827069 ] + +To allow running rseq and KVM's rseq selftests as statically linked +binaries, initialize the various "trampoline" pointers to point directly +at the expect glibc symbols, and skip the dlysm() lookups if the rseq +size is non-zero, i.e. the binary is statically linked *and* the libc +registered its own rseq. + +Define weak versions of the symbols so as not to break linking against +libc versions that don't support rseq in any capacity. + +The KVM selftests in particular are often statically linked so that they +can be run on targets with very limited runtime environments, i.e. test +machines. + +Fixes: 233e667e1ae3 ("selftests/rseq: Uplift rseq selftests for compatibility with glibc-2.35") +Cc: Aaron Lewis +Cc: kvm@vger.kernel.org +Cc: stable@vger.kernel.org +Signed-off-by: Sean Christopherson +Message-Id: <20230721223352.2333911-1-seanjc@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/rseq/rseq.c | 28 ++++++++++++++++++++++------ + 1 file changed, 22 insertions(+), 6 deletions(-) + +diff --git a/tools/testing/selftests/rseq/rseq.c b/tools/testing/selftests/rseq/rseq.c +index 4177f9507bbee..b736a5169aad0 100644 +--- a/tools/testing/selftests/rseq/rseq.c ++++ b/tools/testing/selftests/rseq/rseq.c +@@ -32,9 +32,17 @@ + #include "../kselftest.h" + #include "rseq.h" + +-static const ptrdiff_t *libc_rseq_offset_p; +-static const unsigned int *libc_rseq_size_p; +-static const unsigned int *libc_rseq_flags_p; ++/* ++ * Define weak versions to play nice with binaries that are statically linked ++ * against a libc that doesn't support registering its own rseq. ++ */ ++__weak ptrdiff_t __rseq_offset; ++__weak unsigned int __rseq_size; ++__weak unsigned int __rseq_flags; ++ ++static const ptrdiff_t *libc_rseq_offset_p = &__rseq_offset; ++static const unsigned int *libc_rseq_size_p = &__rseq_size; ++static const unsigned int *libc_rseq_flags_p = &__rseq_flags; + + /* Offset from the thread pointer to the rseq area. */ + ptrdiff_t rseq_offset; +@@ -108,9 +116,17 @@ int rseq_unregister_current_thread(void) + static __attribute__((constructor)) + void rseq_init(void) + { +- libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset"); +- libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size"); +- libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags"); ++ /* ++ * If the libc's registered rseq size isn't already valid, it may be ++ * because the binary is dynamically linked and not necessarily due to ++ * libc not having registered a restartable sequence. Try to find the ++ * symbols if that's the case. ++ */ ++ if (!*libc_rseq_size_p) { ++ libc_rseq_offset_p = dlsym(RTLD_NEXT, "__rseq_offset"); ++ libc_rseq_size_p = dlsym(RTLD_NEXT, "__rseq_size"); ++ libc_rseq_flags_p = dlsym(RTLD_NEXT, "__rseq_flags"); ++ } + if (libc_rseq_size_p && libc_rseq_offset_p && libc_rseq_flags_p && + *libc_rseq_size_p != 0) { + /* rseq registration owned by glibc */ +-- +2.40.1 + diff --git a/queue-5.10/series b/queue-5.10/series index cb5b627da88..b1a968473f1 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -183,3 +183,20 @@ ext2-drop-fragment-support.patch mtd-rawnand-omap_elm-fix-incorrect-type-in-assignmen.patch mtd-rawnand-fsl_upm-fix-an-off-by-one-test-in-fun_ex.patch powerpc-mm-altmap-fix-altmap-boundary-check.patch +selftests-rseq-check-if-libc-rseq-support-is-registe.patch +selftests-rseq-play-nice-with-binaries-statically-li.patch +soundwire-bus-add-better-dev_dbg-to-track-complete-c.patch +soundwire-bus-pm_runtime_request_resume-on-periphera.patch +soundwire-fix-enumeration-completion.patch +pm-wakeirq-support-enabling-wake-up-irq-after-runtim.patch +pm-sleep-wakeirq-fix-wake-irq-arming.patch +exfat-speed-up-iterate-lookup-by-fixing-start-point-.patch +exfat-support-dynamic-allocate-bh-for-exfat_entry_se.patch +exfat-move-exfat_entry_set_cache-from-heap-to-stack.patch +exfat-check-if-filename-entries-exceeds-max-filename.patch +mt76-move-band-capabilities-in-mt76_phy.patch +mt76-mt7615-fix-fall-through-warnings-for-clang.patch +wifi-mt76-mt7615-do-not-advertise-5-ghz-on-first-phy.patch +arm-dts-imx-add-usb-alias.patch +arm-dts-imx6sll-fixup-of-operating-points.patch +arm-dts-nxp-imx6sll-fix-wrong-property-name-in-usbph.patch diff --git a/queue-5.10/soundwire-bus-add-better-dev_dbg-to-track-complete-c.patch b/queue-5.10/soundwire-bus-add-better-dev_dbg-to-track-complete-c.patch new file mode 100644 index 00000000000..75702331ef9 --- /dev/null +++ b/queue-5.10/soundwire-bus-add-better-dev_dbg-to-track-complete-c.patch @@ -0,0 +1,64 @@ +From 45c65ae606247cb635ae0300f98b651bce8da65b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Jan 2021 16:54:02 +0800 +Subject: soundwire: bus: add better dev_dbg to track complete() calls + +From: Pierre-Louis Bossart + +[ Upstream commit f1b690261247c9895f7a4b05d14a4026739134eb ] + +Add a dev_dbg() log for both enumeration and initialization completion +to better track suspend-resume issues. + +Signed-off-by: Pierre-Louis Bossart +Reviewed-by: Rander Wang +Reviewed-by: Chao Song +Signed-off-by: Bard Liao +Link: https://lore.kernel.org/r/20210126085402.4264-1-yung-chuan.liao@linux.intel.com +Signed-off-by: Vinod Koul +Stable-dep-of: c40d6b3249b1 ("soundwire: fix enumeration completion") +Signed-off-by: Sasha Levin +--- + drivers/soundwire/bus.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c +index 3317a02bcc170..9c7c8fa7f53e4 100644 +--- a/drivers/soundwire/bus.c ++++ b/drivers/soundwire/bus.c +@@ -797,7 +797,7 @@ static void sdw_modify_slave_status(struct sdw_slave *slave, + + if (status == SDW_SLAVE_UNATTACHED) { + dev_dbg(&slave->dev, +- "%s: initializing completion for Slave %d\n", ++ "%s: initializing enumeration and init completion for Slave %d\n", + __func__, slave->dev_num); + + init_completion(&slave->enumeration_complete); +@@ -806,7 +806,7 @@ static void sdw_modify_slave_status(struct sdw_slave *slave, + } else if ((status == SDW_SLAVE_ATTACHED) && + (slave->status == SDW_SLAVE_UNATTACHED)) { + dev_dbg(&slave->dev, +- "%s: signaling completion for Slave %d\n", ++ "%s: signaling enumeration completion for Slave %d\n", + __func__, slave->dev_num); + + complete(&slave->enumeration_complete); +@@ -1734,8 +1734,13 @@ int sdw_handle_slave_status(struct sdw_bus *bus, + if (ret) + dev_err(slave->bus->dev, + "Update Slave status failed:%d\n", ret); +- if (attached_initializing) ++ if (attached_initializing) { ++ dev_dbg(&slave->dev, ++ "%s: signaling initialization completion for Slave %d\n", ++ __func__, slave->dev_num); ++ + complete(&slave->initialization_complete); ++ } + } + + return ret; +-- +2.40.1 + diff --git a/queue-5.10/soundwire-bus-pm_runtime_request_resume-on-periphera.patch b/queue-5.10/soundwire-bus-pm_runtime_request_resume-on-periphera.patch new file mode 100644 index 00000000000..d7c35e8fb1d --- /dev/null +++ b/queue-5.10/soundwire-bus-pm_runtime_request_resume-on-periphera.patch @@ -0,0 +1,68 @@ +From 5ffae591a68f43d3eb9e9d356ca00f0d5913a430 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Apr 2022 10:32:41 +0800 +Subject: soundwire: bus: pm_runtime_request_resume on peripheral attachment + +From: Pierre-Louis Bossart + +[ Upstream commit e557bca49b812908f380c56b5b4b2f273848b676 ] + +In typical use cases, the peripheral becomes pm_runtime active as a +result of the ALSA/ASoC framework starting up a DAI. The parent/child +hierarchy guarantees that the manager device will be fully resumed +beforehand. + +There is however a corner case where the manager device may become +pm_runtime active, but without ALSA/ASoC requesting any functionality +from the peripherals. In this case, the hardware peripheral device +will report as ATTACHED and its initialization routine will be +executed. If this initialization routine initiates any sort of +deferred processing, there is a possibility that the manager could +suspend without the peripheral suspend sequence being invoked: from +the pm_runtime framework perspective, the peripheral is *already* +suspended. + +To avoid such disconnects between hardware state and pm_runtime state, +this patch adds an asynchronous pm_request_resume() upon successful +attach/initialization which will result in the proper resume/suspend +sequence to be followed on the peripheral side. + +BugLink: https://github.com/thesofproject/linux/issues/3459 +Signed-off-by: Pierre-Louis Bossart +Reviewed-by: Ranjani Sridharan +Reviewed-by: Rander Wang +Signed-off-by: Bard Liao +Link: https://lore.kernel.org/r/20220420023241.14335-4-yung-chuan.liao@linux.intel.com +Signed-off-by: Vinod Koul +Stable-dep-of: c40d6b3249b1 ("soundwire: fix enumeration completion") +Signed-off-by: Sasha Levin +--- + drivers/soundwire/bus.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c +index 9c7c8fa7f53e4..831d2d751d5de 100644 +--- a/drivers/soundwire/bus.c ++++ b/drivers/soundwire/bus.c +@@ -1740,6 +1740,18 @@ int sdw_handle_slave_status(struct sdw_bus *bus, + __func__, slave->dev_num); + + complete(&slave->initialization_complete); ++ ++ /* ++ * If the manager became pm_runtime active, the peripherals will be ++ * restarted and attach, but their pm_runtime status may remain ++ * suspended. If the 'update_slave_status' callback initiates ++ * any sort of deferred processing, this processing would not be ++ * cancelled on pm_runtime suspend. ++ * To avoid such zombie states, we queue a request to resume. ++ * This would be a no-op in case the peripheral was being resumed ++ * by e.g. the ALSA/ASoC framework. ++ */ ++ pm_request_resume(&slave->dev); + } + } + +-- +2.40.1 + diff --git a/queue-5.10/soundwire-fix-enumeration-completion.patch b/queue-5.10/soundwire-fix-enumeration-completion.patch new file mode 100644 index 00000000000..1bc3319c66a --- /dev/null +++ b/queue-5.10/soundwire-fix-enumeration-completion.patch @@ -0,0 +1,75 @@ +From ac0a9a3463f50897e4f926073b4aa0cc9e473401 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Jul 2023 14:30:11 +0200 +Subject: soundwire: fix enumeration completion + +From: Johan Hovold + +[ Upstream commit c40d6b3249b11d60e09d81530588f56233d9aa44 ] + +The soundwire subsystem uses two completion structures that allow +drivers to wait for soundwire device to become enumerated on the bus and +initialised by their drivers, respectively. + +The code implementing the signalling is currently broken as it does not +signal all current and future waiters and also uses the wrong +reinitialisation function, which can potentially lead to memory +corruption if there are still waiters on the queue. + +Not signalling future waiters specifically breaks sound card probe +deferrals as codec drivers can not tell that the soundwire device is +already attached when being reprobed. Some codec runtime PM +implementations suffer from similar problems as waiting for enumeration +during resume can also timeout despite the device already having been +enumerated. + +Fixes: fb9469e54fa7 ("soundwire: bus: fix race condition with enumeration_complete signaling") +Fixes: a90def068127 ("soundwire: bus: fix race condition with initialization_complete signaling") +Cc: stable@vger.kernel.org # 5.7 +Cc: Pierre-Louis Bossart +Cc: Rander Wang +Signed-off-by: Johan Hovold +Reviewed-by: Pierre-Louis Bossart +Link: https://lore.kernel.org/r/20230705123018.30903-2-johan+linaro@kernel.org +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/soundwire/bus.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c +index 831d2d751d5de..0e0a19030c35b 100644 +--- a/drivers/soundwire/bus.c ++++ b/drivers/soundwire/bus.c +@@ -800,8 +800,8 @@ static void sdw_modify_slave_status(struct sdw_slave *slave, + "%s: initializing enumeration and init completion for Slave %d\n", + __func__, slave->dev_num); + +- init_completion(&slave->enumeration_complete); +- init_completion(&slave->initialization_complete); ++ reinit_completion(&slave->enumeration_complete); ++ reinit_completion(&slave->initialization_complete); + + } else if ((status == SDW_SLAVE_ATTACHED) && + (slave->status == SDW_SLAVE_UNATTACHED)) { +@@ -809,7 +809,7 @@ static void sdw_modify_slave_status(struct sdw_slave *slave, + "%s: signaling enumeration completion for Slave %d\n", + __func__, slave->dev_num); + +- complete(&slave->enumeration_complete); ++ complete_all(&slave->enumeration_complete); + } + slave->status = status; + mutex_unlock(&slave->bus->bus_lock); +@@ -1739,7 +1739,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus, + "%s: signaling initialization completion for Slave %d\n", + __func__, slave->dev_num); + +- complete(&slave->initialization_complete); ++ complete_all(&slave->initialization_complete); + + /* + * If the manager became pm_runtime active, the peripherals will be +-- +2.40.1 + diff --git a/queue-5.10/wifi-mt76-mt7615-do-not-advertise-5-ghz-on-first-phy.patch b/queue-5.10/wifi-mt76-mt7615-do-not-advertise-5-ghz-on-first-phy.patch new file mode 100644 index 00000000000..6e48d1b010d --- /dev/null +++ b/queue-5.10/wifi-mt76-mt7615-do-not-advertise-5-ghz-on-first-phy.patch @@ -0,0 +1,51 @@ +From 89c58c4fe58d72c8530f29e1853d59b3c17750c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Jun 2023 10:34:07 +0300 +Subject: wifi: mt76: mt7615: do not advertise 5 GHz on first phy of MT7615D + (DBDC) + +From: Paul Fertser + +[ Upstream commit 421033deb91521aa6a9255e495cb106741a52275 ] + +On DBDC devices the first (internal) phy is only capable of using +2.4 GHz band, and the 5 GHz band is exposed via a separate phy object, +so avoid the false advertising. + +Reported-by: Rani Hod +Closes: https://github.com/openwrt/openwrt/pull/12361 +Fixes: 7660a1bd0c22 ("mt76: mt7615: register ext_phy if DBDC is detected") +Cc: stable@vger.kernel.org +Signed-off-by: Paul Fertser +Reviewed-by: Simon Horman +Acked-by: Felix Fietkau +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230605073408.8699-1-fercerpav@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c +index 48ce24f0f77b7..85f56487feff2 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c +@@ -123,12 +123,12 @@ mt7615_eeprom_parse_hw_band_cap(struct mt7615_dev *dev) + case MT_EE_5GHZ: + dev->mphy.cap.has_5ghz = true; + break; +- case MT_EE_2GHZ: +- dev->mphy.cap.has_2ghz = true; +- break; + case MT_EE_DBDC: + dev->dbdc_support = true; + fallthrough; ++ case MT_EE_2GHZ: ++ dev->mphy.cap.has_2ghz = true; ++ break; + default: + dev->mphy.cap.has_2ghz = true; + dev->mphy.cap.has_5ghz = true; +-- +2.40.1 +