From: Sasha Levin Date: Thu, 2 Apr 2020 21:35:21 +0000 (-0400) Subject: Fixes for 5.4 X-Git-Tag: v5.4.31~47^2~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7a6286b65694d057b7ce15e750ce193659e916e6;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.4 Signed-off-by: Sasha Levin --- diff --git a/queue-5.4/bpf-fix-tnum-constraints-for-32-bit-comparisons.patch b/queue-5.4/bpf-fix-tnum-constraints-for-32-bit-comparisons.patch new file mode 100644 index 00000000000..ad54cae0050 --- /dev/null +++ b/queue-5.4/bpf-fix-tnum-constraints-for-32-bit-comparisons.patch @@ -0,0 +1,194 @@ +From dcefd3cdbe92aa760b07a36c5f80ea3e66bce517 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Mar 2020 18:03:23 +0200 +Subject: bpf: Fix tnum constraints for 32-bit comparisons + +From: Jann Horn + +[ Upstream commit 604dca5e3af1db98bd123b7bfc02b017af99e3a0 ] + +The BPF verifier tried to track values based on 32-bit comparisons by +(ab)using the tnum state via 581738a681b6 ("bpf: Provide better register +bounds after jmp32 instructions"). The idea is that after a check like +this: + + if ((u32)r0 > 3) + exit + +We can't meaningfully constrain the arithmetic-range-based tracking, but +we can update the tnum state to (value=0,mask=0xffff'ffff'0000'0003). +However, the implementation from 581738a681b6 didn't compute the tnum +constraint based on the fixed operand, but instead derives it from the +arithmetic-range-based tracking. This means that after the following +sequence of operations: + + if (r0 >= 0x1'0000'0001) + exit + if ((u32)r0 > 7) + exit + +The verifier assumed that the lower half of r0 is in the range (0, 0) +and apply the tnum constraint (value=0,mask=0xffff'ffff'0000'0000) thus +causing the overall tnum to be (value=0,mask=0x1'0000'0000), which was +incorrect. Provide a fixed implementation. + +Fixes: 581738a681b6 ("bpf: Provide better register bounds after jmp32 instructions") +Signed-off-by: Jann Horn +Signed-off-by: Daniel Borkmann +Signed-off-by: Alexei Starovoitov +Link: https://lore.kernel.org/bpf/20200330160324.15259-3-daniel@iogearbox.net +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 108 ++++++++++++++++++++++++++++-------------- + 1 file changed, 72 insertions(+), 36 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index a0b76b360d6f7..013780ef0bd7d 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -5325,6 +5325,70 @@ static bool cmp_val_with_extended_s64(s64 sval, struct bpf_reg_state *reg) + reg->smax_value <= 0 && reg->smin_value >= S32_MIN); + } + ++/* Constrain the possible values of @reg with unsigned upper bound @bound. ++ * If @is_exclusive, @bound is an exclusive limit, otherwise it is inclusive. ++ * If @is_jmp32, @bound is a 32-bit value that only constrains the low 32 bits ++ * of @reg. ++ */ ++static void set_upper_bound(struct bpf_reg_state *reg, u64 bound, bool is_jmp32, ++ bool is_exclusive) ++{ ++ if (is_exclusive) { ++ /* There are no values for `reg` that make `reg<0` true. */ ++ if (bound == 0) ++ return; ++ bound--; ++ } ++ if (is_jmp32) { ++ /* Constrain the register's value in the tnum representation. ++ * For 64-bit comparisons this happens later in ++ * __reg_bound_offset(), but for 32-bit comparisons, we can be ++ * more precise than what can be derived from the updated ++ * numeric bounds. ++ */ ++ struct tnum t = tnum_range(0, bound); ++ ++ t.mask |= ~0xffffffffULL; /* upper half is unknown */ ++ reg->var_off = tnum_intersect(reg->var_off, t); ++ ++ /* Compute the 64-bit bound from the 32-bit bound. */ ++ bound += gen_hi_max(reg->var_off); ++ } ++ reg->umax_value = min(reg->umax_value, bound); ++} ++ ++/* Constrain the possible values of @reg with unsigned lower bound @bound. ++ * If @is_exclusive, @bound is an exclusive limit, otherwise it is inclusive. ++ * If @is_jmp32, @bound is a 32-bit value that only constrains the low 32 bits ++ * of @reg. ++ */ ++static void set_lower_bound(struct bpf_reg_state *reg, u64 bound, bool is_jmp32, ++ bool is_exclusive) ++{ ++ if (is_exclusive) { ++ /* There are no values for `reg` that make `reg>MAX` true. */ ++ if (bound == (is_jmp32 ? U32_MAX : U64_MAX)) ++ return; ++ bound++; ++ } ++ if (is_jmp32) { ++ /* Constrain the register's value in the tnum representation. ++ * For 64-bit comparisons this happens later in ++ * __reg_bound_offset(), but for 32-bit comparisons, we can be ++ * more precise than what can be derived from the updated ++ * numeric bounds. ++ */ ++ struct tnum t = tnum_range(bound, U32_MAX); ++ ++ t.mask |= ~0xffffffffULL; /* upper half is unknown */ ++ reg->var_off = tnum_intersect(reg->var_off, t); ++ ++ /* Compute the 64-bit bound from the 32-bit bound. */ ++ bound += gen_hi_min(reg->var_off); ++ } ++ reg->umin_value = max(reg->umin_value, bound); ++} ++ + /* Adjusts the register min/max values in the case that the dst_reg is the + * variable register that we are working on, and src_reg is a constant or we're + * simply doing a BPF_K check. +@@ -5380,15 +5444,8 @@ static void reg_set_min_max(struct bpf_reg_state *true_reg, + case BPF_JGE: + case BPF_JGT: + { +- u64 false_umax = opcode == BPF_JGT ? val : val - 1; +- u64 true_umin = opcode == BPF_JGT ? val + 1 : val; +- +- if (is_jmp32) { +- false_umax += gen_hi_max(false_reg->var_off); +- true_umin += gen_hi_min(true_reg->var_off); +- } +- false_reg->umax_value = min(false_reg->umax_value, false_umax); +- true_reg->umin_value = max(true_reg->umin_value, true_umin); ++ set_upper_bound(false_reg, val, is_jmp32, opcode == BPF_JGE); ++ set_lower_bound(true_reg, val, is_jmp32, opcode == BPF_JGT); + break; + } + case BPF_JSGE: +@@ -5409,15 +5466,8 @@ static void reg_set_min_max(struct bpf_reg_state *true_reg, + case BPF_JLE: + case BPF_JLT: + { +- u64 false_umin = opcode == BPF_JLT ? val : val + 1; +- u64 true_umax = opcode == BPF_JLT ? val - 1 : val; +- +- if (is_jmp32) { +- false_umin += gen_hi_min(false_reg->var_off); +- true_umax += gen_hi_max(true_reg->var_off); +- } +- false_reg->umin_value = max(false_reg->umin_value, false_umin); +- true_reg->umax_value = min(true_reg->umax_value, true_umax); ++ set_lower_bound(false_reg, val, is_jmp32, opcode == BPF_JLE); ++ set_upper_bound(true_reg, val, is_jmp32, opcode == BPF_JLT); + break; + } + case BPF_JSLE: +@@ -5492,15 +5542,8 @@ static void reg_set_min_max_inv(struct bpf_reg_state *true_reg, + case BPF_JGE: + case BPF_JGT: + { +- u64 false_umin = opcode == BPF_JGT ? val : val + 1; +- u64 true_umax = opcode == BPF_JGT ? val - 1 : val; +- +- if (is_jmp32) { +- false_umin += gen_hi_min(false_reg->var_off); +- true_umax += gen_hi_max(true_reg->var_off); +- } +- false_reg->umin_value = max(false_reg->umin_value, false_umin); +- true_reg->umax_value = min(true_reg->umax_value, true_umax); ++ set_lower_bound(false_reg, val, is_jmp32, opcode == BPF_JGE); ++ set_upper_bound(true_reg, val, is_jmp32, opcode == BPF_JGT); + break; + } + case BPF_JSGE: +@@ -5518,15 +5561,8 @@ static void reg_set_min_max_inv(struct bpf_reg_state *true_reg, + case BPF_JLE: + case BPF_JLT: + { +- u64 false_umax = opcode == BPF_JLT ? val : val - 1; +- u64 true_umin = opcode == BPF_JLT ? val + 1 : val; +- +- if (is_jmp32) { +- false_umax += gen_hi_max(false_reg->var_off); +- true_umin += gen_hi_min(true_reg->var_off); +- } +- false_reg->umax_value = min(false_reg->umax_value, false_umax); +- true_reg->umin_value = max(true_reg->umin_value, true_umin); ++ set_upper_bound(false_reg, val, is_jmp32, opcode == BPF_JLE); ++ set_lower_bound(true_reg, val, is_jmp32, opcode == BPF_JLT); + break; + } + case BPF_JSLE: +-- +2.20.1 + diff --git a/queue-5.4/brcmfmac-abort-and-release-host-after-error.patch b/queue-5.4/brcmfmac-abort-and-release-host-after-error.patch new file mode 100644 index 00000000000..4026acd053b --- /dev/null +++ b/queue-5.4/brcmfmac-abort-and-release-host-after-error.patch @@ -0,0 +1,57 @@ +From 08c700337d5f195ad24dee3984590af4ae9feb25 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Jan 2020 14:14:57 -0800 +Subject: brcmfmac: abort and release host after error + +From: Guenter Roeck + +[ Upstream commit 863844ee3bd38219c88e82966d1df36a77716f3e ] + +With commit 216b44000ada ("brcmfmac: Fix use after free in +brcmf_sdio_readframes()") applied, we see locking timeouts in +brcmf_sdio_watchdog_thread(). + +brcmfmac: brcmf_escan_timeout: timer expired +INFO: task brcmf_wdog/mmc1:621 blocked for more than 120 seconds. +Not tainted 4.19.94-07984-g24ff99a0f713 #1 +"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. +brcmf_wdog/mmc1 D 0 621 2 0x00000000 last_sleep: 2440793077. last_runnable: 2440766827 +[] (__schedule) from [] (schedule+0x98/0xc4) +[] (schedule) from [] (__mmc_claim_host+0x154/0x274) +[] (__mmc_claim_host) from [] (brcmf_sdio_watchdog_thread+0x1b0/0x1f8 [brcmfmac]) +[] (brcmf_sdio_watchdog_thread [brcmfmac]) from [] (kthread+0x178/0x180) + +In addition to restarting or exiting the loop, it is also necessary to +abort the command and to release the host. + +Fixes: 216b44000ada ("brcmfmac: Fix use after free in brcmf_sdio_readframes()") +Cc: Dan Carpenter +Cc: Matthias Kaehlcke +Cc: Brian Norris +Cc: Douglas Anderson +Signed-off-by: Guenter Roeck +Reviewed-by: Douglas Anderson +Acked-by: franky.lin@broadcom.com +Acked-by: Dan Carpenter +Signed-off-by: Kalle Valo +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +index a935993a3c514..d43247a95ce53 100644 +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -1934,6 +1934,8 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) + if (brcmf_sdio_hdparse(bus, bus->rxhdr, &rd_new, + BRCMF_SDIO_FT_NORMAL)) { + rd->len = 0; ++ brcmf_sdio_rxfail(bus, true, true); ++ sdio_release_host(bus->sdiodev->func1); + brcmu_pkt_buf_free_skb(pkt); + continue; + } +-- +2.20.1 + diff --git a/queue-5.4/drm-amd-display-add-link_rate-quirk-for-apple-15-mbp.patch b/queue-5.4/drm-amd-display-add-link_rate-quirk-for-apple-15-mbp.patch new file mode 100644 index 00000000000..4eb9a92c306 --- /dev/null +++ b/queue-5.4/drm-amd-display-add-link_rate-quirk-for-apple-15-mbp.patch @@ -0,0 +1,67 @@ +From 654f242977161e631a756308bb0964cf2b0e1a8c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Feb 2020 22:36:07 +0100 +Subject: drm/amd/display: Add link_rate quirk for Apple 15" MBP 2017 + +From: Mario Kleiner + +[ Upstream commit dec9de2ada523b344eb2428abfedf9d6cd0a0029 ] + +This fixes a problem found on the MacBookPro 2017 Retina panel: + +The panel reports 10 bpc color depth in its EDID, and the +firmware chooses link settings at boot which support enough +bandwidth for 10 bpc (324000 kbit/sec aka LINK_RATE_RBR2 +aka 0xc), but the DP_MAX_LINK_RATE dpcd register only reports +2.7 Gbps (multiplier value 0xa) as possible, in direct +contradiction of what the firmware successfully set up. + +This restricts the panel to 8 bpc, not providing the full +color depth of the panel on Linux <= 5.5. Additionally, commit +'4a8ca46bae8a ("drm/amd/display: Default max bpc to 16 for eDP")' +introduced into Linux 5.6-rc1 will unclamp panel depth to +its full 10 bpc, thereby requiring a eDP bandwidth for all +modes that exceeds the bandwidth available and causes all modes +to fail validation -> No modes for the laptop panel -> failure +to set any mode -> Panel goes dark. + +This patch adds a quirk specific to the MBP 2017 15" Retina +panel to override reported max link rate to the correct maximum +of 0xc = LINK_RATE_RBR2 to fix the darkness and reduced display +precision. + +Please apply for Linux 5.6+ to avoid regressing Apple MBP panel +support. + +Signed-off-by: Mario Kleiner +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +index 0ab890c927ec7..6dd2334dd5e60 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c +@@ -2879,6 +2879,17 @@ static bool retrieve_link_cap(struct dc_link *link) + sink_id.ieee_device_id, + sizeof(sink_id.ieee_device_id)); + ++ /* Quirk Apple MBP 2017 15" Retina panel: Wrong DP_MAX_LINK_RATE */ ++ { ++ uint8_t str_mbp_2017[] = { 101, 68, 21, 101, 98, 97 }; ++ ++ if ((link->dpcd_caps.sink_dev_id == 0x0010fa) && ++ !memcmp(link->dpcd_caps.sink_dev_id_str, str_mbp_2017, ++ sizeof(str_mbp_2017))) { ++ link->reported_link_cap.link_rate = 0x0c; ++ } ++ } ++ + core_link_read_dpcd( + link, + DP_SINK_HW_REVISION_START, +-- +2.20.1 + diff --git a/queue-5.4/drm-amdgpu-fix-typo-for-vcn1-idle-check.patch b/queue-5.4/drm-amdgpu-fix-typo-for-vcn1-idle-check.patch new file mode 100644 index 00000000000..fc9e90543c5 --- /dev/null +++ b/queue-5.4/drm-amdgpu-fix-typo-for-vcn1-idle-check.patch @@ -0,0 +1,35 @@ +From 18443156def23d00f13a3bcece1d8147adf219d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 18 Mar 2020 17:09:05 -0400 +Subject: drm/amdgpu: fix typo for vcn1 idle check + +From: James Zhu + +[ Upstream commit acfc62dc68770aa665cc606891f6df7d6d1e52c0 ] + +fix typo for vcn1 idle check + +Signed-off-by: James Zhu +Reviewed-by: Leo Liu +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +index 93b3500e522b8..4f0f0de832937 100644 +--- a/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c ++++ b/drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c +@@ -1375,7 +1375,7 @@ static int vcn_v1_0_set_clockgating_state(void *handle, + + if (enable) { + /* wait for STATUS to clear */ +- if (vcn_v1_0_is_idle(handle)) ++ if (!vcn_v1_0_is_idle(handle)) + return -EBUSY; + vcn_v1_0_enable_clock_gating(adev); + } else { +-- +2.20.1 + diff --git a/queue-5.4/drm-bochs-downgrade-pci_request_region-failure-from-.patch b/queue-5.4/drm-bochs-downgrade-pci_request_region-failure-from-.patch new file mode 100644 index 00000000000..3dc178dccd4 --- /dev/null +++ b/queue-5.4/drm-bochs-downgrade-pci_request_region-failure-from-.patch @@ -0,0 +1,48 @@ +From df6183c0051709a7778d90f44be75ce5fb1ceae3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Mar 2020 09:41:52 +0100 +Subject: drm/bochs: downgrade pci_request_region failure from error to warning +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Gerd Hoffmann + +[ Upstream commit 8c34cd1a7f089dc03933289c5d4a4d1489549828 ] + +Shutdown of firmware framebuffer has a bunch of problems. Because +of this the framebuffer region might still be reserved even after +drm_fb_helper_remove_conflicting_pci_framebuffers() returned. + +Don't consider pci_request_region() failure for the framebuffer +region as fatal error to workaround this issue. + +Reported-by: Marek Marczykowski-Górecki +Signed-off-by: Gerd Hoffmann +Acked-by: Sam Ravnborg +Link: http://patchwork.freedesktop.org/patch/msgid/20200313084152.2734-1-kraxel@redhat.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bochs/bochs_hw.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/bochs/bochs_hw.c b/drivers/gpu/drm/bochs/bochs_hw.c +index e567bdfa2ab8e..bb1391784caf0 100644 +--- a/drivers/gpu/drm/bochs/bochs_hw.c ++++ b/drivers/gpu/drm/bochs/bochs_hw.c +@@ -156,10 +156,8 @@ int bochs_hw_init(struct drm_device *dev) + size = min(size, mem); + } + +- if (pci_request_region(pdev, 0, "bochs-drm") != 0) { +- DRM_ERROR("Cannot request framebuffer\n"); +- return -EBUSY; +- } ++ if (pci_request_region(pdev, 0, "bochs-drm") != 0) ++ DRM_WARN("Cannot request framebuffer, boot fb still active?\n"); + + bochs->fb_map = ioremap(addr, size); + if (bochs->fb_map == NULL) { +-- +2.20.1 + diff --git a/queue-5.4/initramfs-restore-default-compression-behavior.patch b/queue-5.4/initramfs-restore-default-compression-behavior.patch new file mode 100644 index 00000000000..5ae4d00062d --- /dev/null +++ b/queue-5.4/initramfs-restore-default-compression-behavior.patch @@ -0,0 +1,79 @@ +From e5a1838fb09dc07ccb98e54c736c705540bbbcef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Mar 2020 14:25:19 +0300 +Subject: initramfs: restore default compression behavior + +From: Eugeniy Paltsev + +[ Upstream commit 785d74ec3bbf26ac7f6e92e6e96a259aec0f107a ] + +Even though INITRAMFS_SOURCE kconfig option isn't set in most of +defconfigs it is used (set) extensively by various build systems. +Commit f26661e12765 ("initramfs: make initramfs compression choice +non-optional") has changed default compression mode. Previously we +compress initramfs using available compression algorithm. Now +we don't use any compression at all by default. +It significantly increases the image size in case of build system +chooses embedded initramfs. Initially I faced with this issue while +using buildroot. + +As of today it's not possible to set preferred compression mode +in target defconfig as this option depends on INITRAMFS_SOURCE +being set. Modification of all build systems either doesn't look +like good option. + +Let's instead rewrite initramfs compression mode choices list +the way that "INITRAMFS_COMPRESSION_NONE" will be the last option +in the list. In that case it will be chosen only if all other +options (which implements any compression) are not available. + +Signed-off-by: Eugeniy Paltsev +Signed-off-by: Masahiro Yamada +Signed-off-by: Sasha Levin +--- + usr/Kconfig | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/usr/Kconfig b/usr/Kconfig +index a6b68503d1774..a80cc79722745 100644 +--- a/usr/Kconfig ++++ b/usr/Kconfig +@@ -131,17 +131,6 @@ choice + + If in doubt, select 'None' + +-config INITRAMFS_COMPRESSION_NONE +- bool "None" +- help +- Do not compress the built-in initramfs at all. This may sound wasteful +- in space, but, you should be aware that the built-in initramfs will be +- compressed at a later stage anyways along with the rest of the kernel, +- on those architectures that support this. However, not compressing the +- initramfs may lead to slightly higher memory consumption during a +- short time at boot, while both the cpio image and the unpacked +- filesystem image will be present in memory simultaneously +- + config INITRAMFS_COMPRESSION_GZIP + bool "Gzip" + depends on RD_GZIP +@@ -214,6 +203,17 @@ config INITRAMFS_COMPRESSION_LZ4 + If you choose this, keep in mind that most distros don't provide lz4 + by default which could cause a build failure. + ++config INITRAMFS_COMPRESSION_NONE ++ bool "None" ++ help ++ Do not compress the built-in initramfs at all. This may sound wasteful ++ in space, but, you should be aware that the built-in initramfs will be ++ compressed at a later stage anyways along with the rest of the kernel, ++ on those architectures that support this. However, not compressing the ++ initramfs may lead to slightly higher memory consumption during a ++ short time at boot, while both the cpio image and the unpacked ++ filesystem image will be present in memory simultaneously ++ + endchoice + + config INITRAMFS_COMPRESSION +-- +2.20.1 + diff --git a/queue-5.4/kconfig-introduce-m32-flag-and-m64-flag.patch b/queue-5.4/kconfig-introduce-m32-flag-and-m64-flag.patch new file mode 100644 index 00000000000..2b655264404 --- /dev/null +++ b/queue-5.4/kconfig-introduce-m32-flag-and-m64-flag.patch @@ -0,0 +1,84 @@ +From 66dfe4c25cd36ad0545ce4220a8102a9889fc2b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Mar 2020 19:12:49 +0900 +Subject: kconfig: introduce m32-flag and m64-flag + +From: Masahiro Yamada + +[ Upstream commit 8cc4fd73501d9f1370c3eebb70cfe8cc9e24062b ] + +When a compiler supports multiple architectures, some compiler features +can be dependent on the target architecture. + +This is typical for Clang, which supports multiple LLVM backends. +Even for GCC, we need to take care of biarch compiler cases. + +It is not a problem when we evaluate cc-option in Makefiles because +cc-option is tested against the flag in question + $(KBUILD_CFLAGS). + +The cc-option in Kconfig, on the other hand, does not accumulate +tested flags. Due to this simplification, it could potentially test +cc-option against a different target. + +At first, Kconfig always evaluated cc-option against the host +architecture. + +Since commit e8de12fb7cde ("kbuild: Check for unknown options with +cc-option usage in Kconfig and clang"), in case of cross-compiling +with Clang, the target triple is correctly passed to Kconfig. + +The case with biarch GCC (and native build with Clang) is still not +handled properly. We need to pass some flags to specify the target +machine bit. + +Due to the design, all the macros in Kconfig are expanded in the +parse stage, where we do not know the target bit size yet. + +For example, arch/x86/Kconfig allows a user to toggle CONFIG_64BIT. +If a compiler flag -foo depends on the machine bit, it must be tested +twice, one with -m32 and the other with -m64. + +However, -m32/-m64 are not always recognized. So, this commits adds +m64-flag and m32-flag macros. They expand to -m32, -m64, respectively +if supported. Or, they expand to an empty string if unsupported. + +The typical usage is like this: + + config FOO + bool + default $(cc-option,$(m64-flag) -foo) if 64BIT + default $(cc-option,$(m32-flag) -foo) + +This is clumsy, but there is no elegant way to handle this in the +current static macro expansion. + +There was discussion for static functions vs dynamic functions. +The consensus was to go as far as possible with the static functions. +(https://lkml.org/lkml/2018/3/2/22) + +Signed-off-by: Masahiro Yamada +Tested-by: George Spelvin +Reviewed-by: Nathan Chancellor +Signed-off-by: Sasha Levin +--- + scripts/Kconfig.include | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/scripts/Kconfig.include b/scripts/Kconfig.include +index bfb44b265a948..77a69ba9cd198 100644 +--- a/scripts/Kconfig.include ++++ b/scripts/Kconfig.include +@@ -40,3 +40,10 @@ $(error-if,$(success, $(LD) -v | grep -q gold), gold linker '$(LD)' not supporte + + # gcc version including patch level + gcc-version := $(shell,$(srctree)/scripts/gcc-version.sh $(CC)) ++ ++# machine bit flags ++# $(m32-flag): -m32 if the compiler supports it, or an empty string otherwise. ++# $(m64-flag): -m64 if the compiler supports it, or an empty string otherwise. ++cc-option-bit = $(if-success,$(CC) -Werror $(1) -E -x c /dev/null -o /dev/null,$(1)) ++m32-flag := $(cc-option-bit,-m32) ++m64-flag := $(cc-option-bit,-m64) +-- +2.20.1 + diff --git a/queue-5.4/net-mlx5e-ktls-fix-tcp-seq-off-by-1-issue-in-tx-resy.patch b/queue-5.4/net-mlx5e-ktls-fix-tcp-seq-off-by-1-issue-in-tx-resy.patch new file mode 100644 index 00000000000..f331090912a --- /dev/null +++ b/queue-5.4/net-mlx5e-ktls-fix-tcp-seq-off-by-1-issue-in-tx-resy.patch @@ -0,0 +1,42 @@ +From b1f63636a367848056a44276b3f14cfa913dd851 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Feb 2020 13:40:24 +0200 +Subject: net/mlx5e: kTLS, Fix TCP seq off-by-1 issue in TX resync flow + +From: Tariq Toukan + +[ Upstream commit 56917766def72f5afdf4235adb91b6897ff26d9d ] + +We have an off-by-1 issue in the TCP seq comparison. +The last sequence number that belongs to the TCP packet's payload +is not "start_seq + len", but one byte before it. +Fix it so the 'ends_before' is evaluated properly. + +This fixes a bug that results in error completions in the +kTLS HW offload flows. + +Fixes: ffbd9ca94e2e ("net/mlx5e: kTLS, Fix corner-case checks in TX resync flow") +Signed-off-by: Tariq Toukan +Reviewed-by: Boris Pismenny +Signed-off-by: Saeed Mahameed +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c +index f260dd96873bf..52a56622034a0 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c +@@ -218,7 +218,7 @@ tx_sync_info_get(struct mlx5e_ktls_offload_context_tx *priv_tx, + * this packet was already acknowledged and its record info + * was released. + */ +- ends_before = before(tcp_seq + datalen, tls_record_start_seq(record)); ++ ends_before = before(tcp_seq + datalen - 1, tls_record_start_seq(record)); + + if (unlikely(tls_record_is_start_marker(record))) { + ret = ends_before ? MLX5E_KTLS_SYNC_SKIP_NO_DATA : MLX5E_KTLS_SYNC_FAIL; +-- +2.20.1 + diff --git a/queue-5.4/nvme-rdma-avoid-double-freeing-of-async-event-data.patch b/queue-5.4/nvme-rdma-avoid-double-freeing-of-async-event-data.patch new file mode 100644 index 00000000000..166eb173484 --- /dev/null +++ b/queue-5.4/nvme-rdma-avoid-double-freeing-of-async-event-data.patch @@ -0,0 +1,56 @@ +From 10908cbedd4e95e3212b79f9c82da9c19a9abef5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Mar 2020 15:07:53 -0600 +Subject: nvme-rdma: Avoid double freeing of async event data + +From: Prabhath Sajeepa + +[ Upstream commit 9134ae2a2546cb96abddcd4469a79c77ee3a4480 ] + +The timeout of identify cmd, which is invoked as part of admin queue +creation, can result in freeing of async event data both in +nvme_rdma_timeout handler and error handling path of +nvme_rdma_configure_admin queue thus causing NULL pointer reference. +Call Trace: + ? nvme_rdma_setup_ctrl+0x223/0x800 [nvme_rdma] + nvme_rdma_create_ctrl+0x2ba/0x3f7 [nvme_rdma] + nvmf_dev_write+0xa54/0xcc6 [nvme_fabrics] + __vfs_write+0x1b/0x40 + vfs_write+0xb2/0x1b0 + ksys_write+0x61/0xd0 + __x64_sys_write+0x1a/0x20 + do_syscall_64+0x60/0x1e0 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Reviewed-by: Roland Dreier +Reviewed-by: Max Gurtovoy +Reviewed-by: Christoph Hellwig +Signed-off-by: Prabhath Sajeepa +Signed-off-by: Keith Busch +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/rdma.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c +index 4ff51da3b13fa..73e8475ddc8ab 100644 +--- a/drivers/nvme/host/rdma.c ++++ b/drivers/nvme/host/rdma.c +@@ -850,9 +850,11 @@ out_free_tagset: + if (new) + blk_mq_free_tag_set(ctrl->ctrl.admin_tagset); + out_free_async_qe: +- nvme_rdma_free_qe(ctrl->device->dev, &ctrl->async_event_sqe, +- sizeof(struct nvme_command), DMA_TO_DEVICE); +- ctrl->async_event_sqe.data = NULL; ++ if (ctrl->async_event_sqe.data) { ++ nvme_rdma_free_qe(ctrl->device->dev, &ctrl->async_event_sqe, ++ sizeof(struct nvme_command), DMA_TO_DEVICE); ++ ctrl->async_event_sqe.data = NULL; ++ } + out_free_queue: + nvme_rdma_free_queue(&ctrl->queues[0]); + return error; +-- +2.20.1 + diff --git a/queue-5.4/padata-fix-uninitialized-return-value-in-padata_repl.patch b/queue-5.4/padata-fix-uninitialized-return-value-in-padata_repl.patch new file mode 100644 index 00000000000..fd1fee502f7 --- /dev/null +++ b/queue-5.4/padata-fix-uninitialized-return-value-in-padata_repl.patch @@ -0,0 +1,51 @@ +From 29baea1b56e4993d294c652551943430f303432e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Feb 2020 13:11:00 -0500 +Subject: padata: fix uninitialized return value in padata_replace() + +From: Daniel Jordan + +[ Upstream commit 41ccdbfd5427bbbf3ed58b16750113b38fad1780 ] + +According to Geert's report[0], + + kernel/padata.c: warning: 'err' may be used uninitialized in this + function [-Wuninitialized]: => 539:2 + +Warning is seen only with older compilers on certain archs. The +runtime effect is potentially returning garbage down the stack when +padata's cpumasks are modified before any pcrypt requests have run. + +Simplest fix is to initialize err to the success value. + +[0] http://lkml.kernel.org/r/20200210135506.11536-1-geert@linux-m68k.org + +Reported-by: Geert Uytterhoeven +Fixes: bbefa1dd6a6d ("crypto: pcrypt - Avoid deadlock by using per-instance padata queues") +Signed-off-by: Daniel Jordan +Cc: Herbert Xu +Cc: Steffen Klassert +Cc: linux-crypto@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + kernel/padata.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/padata.c b/kernel/padata.c +index fda7a7039422d..7bd37dd9ec55b 100644 +--- a/kernel/padata.c ++++ b/kernel/padata.c +@@ -516,7 +516,7 @@ static int padata_replace(struct padata_instance *pinst) + { + int notification_mask = 0; + struct padata_shell *ps; +- int err; ++ int err = 0; + + pinst->flags |= PADATA_RESET; + +-- +2.20.1 + diff --git a/queue-5.4/series b/queue-5.4/series new file mode 100644 index 00000000000..8f3cf52c01b --- /dev/null +++ b/queue-5.4/series @@ -0,0 +1,14 @@ +nvme-rdma-avoid-double-freeing-of-async-event-data.patch +kconfig-introduce-m32-flag-and-m64-flag.patch +drm-amd-display-add-link_rate-quirk-for-apple-15-mbp.patch +drm-bochs-downgrade-pci_request_region-failure-from-.patch +initramfs-restore-default-compression-behavior.patch +drm-amdgpu-fix-typo-for-vcn1-idle-check.patch +tools-power-turbostat-fix-gcc-build-warnings.patch +tools-power-turbostat-fix-missing-sys_lpi-counter-on.patch +tools-power-turbostat-fix-32-bit-capabilities-warnin.patch +bpf-fix-tnum-constraints-for-32-bit-comparisons.patch +net-mlx5e-ktls-fix-tcp-seq-off-by-1-issue-in-tx-resy.patch +xarray-fix-xa_find_next-for-large-multi-index-entrie.patch +padata-fix-uninitialized-return-value-in-padata_repl.patch +brcmfmac-abort-and-release-host-after-error.patch diff --git a/queue-5.4/tools-power-turbostat-fix-32-bit-capabilities-warnin.patch b/queue-5.4/tools-power-turbostat-fix-32-bit-capabilities-warnin.patch new file mode 100644 index 00000000000..84dbf20a178 --- /dev/null +++ b/queue-5.4/tools-power-turbostat-fix-32-bit-capabilities-warnin.patch @@ -0,0 +1,105 @@ +From 9e90d25ee4afecfb6a429a4d3e027579e5d09f1a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Mar 2020 23:24:17 -0400 +Subject: tools/power turbostat: Fix 32-bit capabilities warning + +From: Len Brown + +[ Upstream commit fcaa681c03ea82193e60d7f2cdfd94fbbcd4cae9 ] + +warning: `turbostat' uses 32-bit capabilities (legacy support in use) + +Signed-off-by: Len Brown +Signed-off-by: Sasha Levin +--- + tools/power/x86/turbostat/Makefile | 2 +- + tools/power/x86/turbostat/turbostat.c | 46 +++++++++++++++++---------- + 2 files changed, 31 insertions(+), 17 deletions(-) + +diff --git a/tools/power/x86/turbostat/Makefile b/tools/power/x86/turbostat/Makefile +index 13f1e8b9ac525..2b6551269e431 100644 +--- a/tools/power/x86/turbostat/Makefile ++++ b/tools/power/x86/turbostat/Makefile +@@ -16,7 +16,7 @@ override CFLAGS += -D_FORTIFY_SOURCE=2 + + %: %.c + @mkdir -p $(BUILD_OUTPUT) +- $(CC) $(CFLAGS) $< -o $(BUILD_OUTPUT)/$@ $(LDFLAGS) ++ $(CC) $(CFLAGS) $< -o $(BUILD_OUTPUT)/$@ $(LDFLAGS) -lcap + + .PHONY : clean + clean : +diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c +index 17e82eaf5c4f4..988326b67a916 100644 +--- a/tools/power/x86/turbostat/turbostat.c ++++ b/tools/power/x86/turbostat/turbostat.c +@@ -30,7 +30,7 @@ + #include + #include + #include +-#include ++#include + #include + #include + +@@ -3150,28 +3150,42 @@ void check_dev_msr() + err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" "); + } + +-void check_permissions() ++/* ++ * check for CAP_SYS_RAWIO ++ * return 0 on success ++ * return 1 on fail ++ */ ++int check_for_cap_sys_rawio(void) + { +- struct __user_cap_header_struct cap_header_data; +- cap_user_header_t cap_header = &cap_header_data; +- struct __user_cap_data_struct cap_data_data; +- cap_user_data_t cap_data = &cap_data_data; +- extern int capget(cap_user_header_t hdrp, cap_user_data_t datap); +- int do_exit = 0; +- char pathname[32]; ++ cap_t caps; ++ cap_flag_value_t cap_flag_value; + +- /* check for CAP_SYS_RAWIO */ +- cap_header->pid = getpid(); +- cap_header->version = _LINUX_CAPABILITY_VERSION; +- if (capget(cap_header, cap_data) < 0) +- err(-6, "capget(2) failed"); ++ caps = cap_get_proc(); ++ if (caps == NULL) ++ err(-6, "cap_get_proc\n"); + +- if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) { +- do_exit++; ++ if (cap_get_flag(caps, CAP_SYS_RAWIO, CAP_EFFECTIVE, &cap_flag_value)) ++ err(-6, "cap_get\n"); ++ ++ if (cap_flag_value != CAP_SET) { + warnx("capget(CAP_SYS_RAWIO) failed," + " try \"# setcap cap_sys_rawio=ep %s\"", progname); ++ return 1; + } + ++ if (cap_free(caps) == -1) ++ err(-6, "cap_free\n"); ++ ++ return 0; ++} ++void check_permissions(void) ++{ ++ int do_exit = 0; ++ char pathname[32]; ++ ++ /* check for CAP_SYS_RAWIO */ ++ do_exit += check_for_cap_sys_rawio(); ++ + /* test file permissions */ + sprintf(pathname, "/dev/cpu/%d/msr", base_cpu); + if (euidaccess(pathname, R_OK)) { +-- +2.20.1 + diff --git a/queue-5.4/tools-power-turbostat-fix-gcc-build-warnings.patch b/queue-5.4/tools-power-turbostat-fix-gcc-build-warnings.patch new file mode 100644 index 00000000000..9c29833d88c --- /dev/null +++ b/queue-5.4/tools-power-turbostat-fix-gcc-build-warnings.patch @@ -0,0 +1,43 @@ +From a6c0df7eb94f5ff2e5fd4789310a4eaf40fe8ca2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Mar 2020 18:33:12 -0400 +Subject: tools/power turbostat: Fix gcc build warnings +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Len Brown + +[ Upstream commit d8d005ba6afa502ca37ced5782f672c4d2fc1515 ] + +Warning: ‘__builtin_strncpy’ specified bound 20 equals destination size + [-Wstringop-truncation] + +reduce param to strncpy, to guarantee that a null byte is always copied +into destination buffer. + +Signed-off-by: Len Brown +Signed-off-by: Sasha Levin +--- + tools/power/x86/turbostat/turbostat.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c +index 5d0fddda842c4..78507cd479bb4 100644 +--- a/tools/power/x86/turbostat/turbostat.c ++++ b/tools/power/x86/turbostat/turbostat.c +@@ -5323,9 +5323,9 @@ int add_counter(unsigned int msr_num, char *path, char *name, + } + + msrp->msr_num = msr_num; +- strncpy(msrp->name, name, NAME_BYTES); ++ strncpy(msrp->name, name, NAME_BYTES - 1); + if (path) +- strncpy(msrp->path, path, PATH_BYTES); ++ strncpy(msrp->path, path, PATH_BYTES - 1); + msrp->width = width; + msrp->type = type; + msrp->format = format; +-- +2.20.1 + diff --git a/queue-5.4/tools-power-turbostat-fix-missing-sys_lpi-counter-on.patch b/queue-5.4/tools-power-turbostat-fix-missing-sys_lpi-counter-on.patch new file mode 100644 index 00000000000..04934ff3477 --- /dev/null +++ b/queue-5.4/tools-power-turbostat-fix-missing-sys_lpi-counter-on.patch @@ -0,0 +1,89 @@ +From 721cbf296fa1e06519a0f662d5181994f130f8fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Mar 2020 18:26:05 -0400 +Subject: tools/power turbostat: Fix missing SYS_LPI counter on some + Chromebooks + +From: Len Brown + +[ Upstream commit 1f81c5efc020314b2db30d77efe228b7e117750d ] + +Some Chromebook BIOS' do not export an ACPI LPIT, which is how +Linux finds the residency counter for CPU and SYSTEM low power states, +that is exports in /sys/devices/system/cpu/cpuidle/*residency_us + +When these sysfs attributes are missing, check the debugfs attrubte +from the pmc_core driver, which accesses the same counter value. + +Signed-off-by: Len Brown +Signed-off-by: Sasha Levin +--- + tools/power/x86/turbostat/turbostat.c | 23 ++++++++++++++--------- + 1 file changed, 14 insertions(+), 9 deletions(-) + +diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c +index 78507cd479bb4..17e82eaf5c4f4 100644 +--- a/tools/power/x86/turbostat/turbostat.c ++++ b/tools/power/x86/turbostat/turbostat.c +@@ -304,6 +304,10 @@ int *irqs_per_cpu; /* indexed by cpu_num */ + + void setup_all_buffers(void); + ++char *sys_lpi_file; ++char *sys_lpi_file_sysfs = "/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us"; ++char *sys_lpi_file_debugfs = "/sys/kernel/debug/pmc_core/slp_s0_residency_usec"; ++ + int cpu_is_not_present(int cpu) + { + return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set); +@@ -2916,8 +2920,6 @@ int snapshot_gfx_mhz(void) + * + * record snapshot of + * /sys/devices/system/cpu/cpuidle/low_power_idle_cpu_residency_us +- * +- * return 1 if config change requires a restart, else return 0 + */ + int snapshot_cpu_lpi_us(void) + { +@@ -2941,17 +2943,14 @@ int snapshot_cpu_lpi_us(void) + /* + * snapshot_sys_lpi() + * +- * record snapshot of +- * /sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us +- * +- * return 1 if config change requires a restart, else return 0 ++ * record snapshot of sys_lpi_file + */ + int snapshot_sys_lpi_us(void) + { + FILE *fp; + int retval; + +- fp = fopen_or_die("/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us", "r"); ++ fp = fopen_or_die(sys_lpi_file, "r"); + + retval = fscanf(fp, "%lld", &cpuidle_cur_sys_lpi_us); + if (retval != 1) { +@@ -4907,10 +4906,16 @@ void process_cpuid() + else + BIC_NOT_PRESENT(BIC_CPU_LPI); + +- if (!access("/sys/devices/system/cpu/cpuidle/low_power_idle_system_residency_us", R_OK)) ++ if (!access(sys_lpi_file_sysfs, R_OK)) { ++ sys_lpi_file = sys_lpi_file_sysfs; + BIC_PRESENT(BIC_SYS_LPI); +- else ++ } else if (!access(sys_lpi_file_debugfs, R_OK)) { ++ sys_lpi_file = sys_lpi_file_debugfs; ++ BIC_PRESENT(BIC_SYS_LPI); ++ } else { ++ sys_lpi_file_sysfs = NULL; + BIC_NOT_PRESENT(BIC_SYS_LPI); ++ } + + if (!quiet) + decode_misc_feature_control(); +-- +2.20.1 + diff --git a/queue-5.4/xarray-fix-xa_find_next-for-large-multi-index-entrie.patch b/queue-5.4/xarray-fix-xa_find_next-for-large-multi-index-entrie.patch new file mode 100644 index 00000000000..63fde9baaab --- /dev/null +++ b/queue-5.4/xarray-fix-xa_find_next-for-large-multi-index-entrie.patch @@ -0,0 +1,86 @@ +From a595c5a7c11dc493aeb0b78dcaa9d519e2a767ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Jan 2020 05:07:55 -0500 +Subject: XArray: Fix xa_find_next for large multi-index entries + +From: Matthew Wilcox (Oracle) + +[ Upstream commit bd40b17ca49d7d110adf456e647701ce74de2241 ] + +Coverity pointed out that xas_sibling() was shifting xa_offset without +promoting it to an unsigned long first, so the shift could cause an +overflow and we'd get the wrong answer. The fix is obvious, and the +new test-case provokes UBSAN to report an error: +runtime error: shift exponent 60 is too large for 32-bit type 'int' + +Fixes: 19c30f4dd092 ("XArray: Fix xa_find_after with multi-index entries") +Reported-by: Bjorn Helgaas +Reported-by: Kees Cook +Signed-off-by: Matthew Wilcox (Oracle) +Cc: stable@vger.kernel.org +Signed-off-by: Sasha Levin +--- + lib/test_xarray.c | 18 ++++++++++++++++++ + lib/xarray.c | 3 ++- + 2 files changed, 20 insertions(+), 1 deletion(-) + +diff --git a/lib/test_xarray.c b/lib/test_xarray.c +index 55c14e8c88591..8c7d7a8468b88 100644 +--- a/lib/test_xarray.c ++++ b/lib/test_xarray.c +@@ -12,6 +12,9 @@ + static unsigned int tests_run; + static unsigned int tests_passed; + ++static const unsigned int order_limit = ++ IS_ENABLED(CONFIG_XARRAY_MULTI) ? BITS_PER_LONG : 1; ++ + #ifndef XA_DEBUG + # ifdef __KERNEL__ + void xa_dump(const struct xarray *xa) { } +@@ -959,6 +962,20 @@ static noinline void check_multi_find_2(struct xarray *xa) + } + } + ++static noinline void check_multi_find_3(struct xarray *xa) ++{ ++ unsigned int order; ++ ++ for (order = 5; order < order_limit; order++) { ++ unsigned long index = 1UL << (order - 5); ++ ++ XA_BUG_ON(xa, !xa_empty(xa)); ++ xa_store_order(xa, 0, order - 4, xa_mk_index(0), GFP_KERNEL); ++ XA_BUG_ON(xa, xa_find_after(xa, &index, ULONG_MAX, XA_PRESENT)); ++ xa_erase_index(xa, 0); ++ } ++} ++ + static noinline void check_find_1(struct xarray *xa) + { + unsigned long i, j, k; +@@ -1081,6 +1098,7 @@ static noinline void check_find(struct xarray *xa) + for (i = 2; i < 10; i++) + check_multi_find_1(xa, i); + check_multi_find_2(xa); ++ check_multi_find_3(xa); + } + + /* See find_swap_entry() in mm/shmem.c */ +diff --git a/lib/xarray.c b/lib/xarray.c +index 1d9fab7db8dad..acd1fad2e862a 100644 +--- a/lib/xarray.c ++++ b/lib/xarray.c +@@ -1839,7 +1839,8 @@ static bool xas_sibling(struct xa_state *xas) + if (!node) + return false; + mask = (XA_CHUNK_SIZE << node->shift) - 1; +- return (xas->xa_index & mask) > (xas->xa_offset << node->shift); ++ return (xas->xa_index & mask) > ++ ((unsigned long)xas->xa_offset << node->shift); + } + + /** +-- +2.20.1 +