From: Greg Kroah-Hartman Date: Mon, 1 Jun 2020 11:35:27 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v4.4.226~36 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4cf901f8459ca77d3ff96d9b159c9f80f5812350;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: cfg80211-fix-debugfs-rename-crash.patch copy_xstate_to_kernel-don-t-leave-parts-of-destination-uninitialized.patch mac80211-mesh-fix-discovery-timer-re-arming-issue-crash.patch x86-dma-fix-max-pfn-arithmetic-overflow-on-32-bit-systems.patch x86-syscalls-revert-x86-syscalls-make-__x32_syscall_bit-be-unsigned-long.patch --- diff --git a/queue-5.4/cfg80211-fix-debugfs-rename-crash.patch b/queue-5.4/cfg80211-fix-debugfs-rename-crash.patch new file mode 100644 index 00000000000..254f819d6e7 --- /dev/null +++ b/queue-5.4/cfg80211-fix-debugfs-rename-crash.patch @@ -0,0 +1,40 @@ +From 0bbab5f0301587cad4e923ccc49bb910db86162c Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Mon, 25 May 2020 11:38:17 +0200 +Subject: cfg80211: fix debugfs rename crash + +From: Johannes Berg + +commit 0bbab5f0301587cad4e923ccc49bb910db86162c upstream. + +Removing the "if (IS_ERR(dir)) dir = NULL;" check only works +if we adjust the remaining code to not rely on it being NULL. +Check IS_ERR_OR_NULL() before attempting to dereference it. + +I'm not actually entirely sure this fixes the syzbot crash as +the kernel config indicates that they do have DEBUG_FS in the +kernel, but this is what I found when looking there. + +Cc: stable@vger.kernel.org +Fixes: d82574a8e5a4 ("cfg80211: no need to check return value of debugfs_create functions") +Reported-by: syzbot+fd5332e429401bf42d18@syzkaller.appspotmail.com +Reviewed-by: Greg Kroah-Hartman +Link: https://lore.kernel.org/r/20200525113816.fc4da3ec3d4b.Ica63a110679819eaa9fb3bc1b7437d96b1fd187d@changeid +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/wireless/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -142,7 +142,7 @@ int cfg80211_dev_rename(struct cfg80211_ + if (result) + return result; + +- if (rdev->wiphy.debugfsdir) ++ if (!IS_ERR_OR_NULL(rdev->wiphy.debugfsdir)) + debugfs_rename(rdev->wiphy.debugfsdir->d_parent, + rdev->wiphy.debugfsdir, + rdev->wiphy.debugfsdir->d_parent, newname); diff --git a/queue-5.4/copy_xstate_to_kernel-don-t-leave-parts-of-destination-uninitialized.patch b/queue-5.4/copy_xstate_to_kernel-don-t-leave-parts-of-destination-uninitialized.patch new file mode 100644 index 00000000000..d011e9b2d81 --- /dev/null +++ b/queue-5.4/copy_xstate_to_kernel-don-t-leave-parts-of-destination-uninitialized.patch @@ -0,0 +1,146 @@ +From 9e4636545933131de15e1ecd06733538ae939b2f Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Tue, 26 May 2020 18:39:49 -0400 +Subject: copy_xstate_to_kernel(): don't leave parts of destination uninitialized + +From: Al Viro + +commit 9e4636545933131de15e1ecd06733538ae939b2f upstream. + +copy the corresponding pieces of init_fpstate into the gaps instead. + +Cc: stable@kernel.org +Tested-by: Alexander Potapenko +Acked-by: Borislav Petkov +Signed-off-by: Al Viro +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/fpu/xstate.c | 86 ++++++++++++++++++++++++------------------- + 1 file changed, 48 insertions(+), 38 deletions(-) + +--- a/arch/x86/kernel/fpu/xstate.c ++++ b/arch/x86/kernel/fpu/xstate.c +@@ -952,18 +952,31 @@ static inline bool xfeatures_mxcsr_quirk + return true; + } + +-/* +- * This is similar to user_regset_copyout(), but will not add offset to +- * the source data pointer or increment pos, count, kbuf, and ubuf. +- */ +-static inline void +-__copy_xstate_to_kernel(void *kbuf, const void *data, +- unsigned int offset, unsigned int size, unsigned int size_total) ++static void fill_gap(unsigned to, void **kbuf, unsigned *pos, unsigned *count) + { +- if (offset < size_total) { +- unsigned int copy = min(size, size_total - offset); ++ if (*pos < to) { ++ unsigned size = to - *pos; ++ ++ if (size > *count) ++ size = *count; ++ memcpy(*kbuf, (void *)&init_fpstate.xsave + *pos, size); ++ *kbuf += size; ++ *pos += size; ++ *count -= size; ++ } ++} + +- memcpy(kbuf + offset, data, copy); ++static void copy_part(unsigned offset, unsigned size, void *from, ++ void **kbuf, unsigned *pos, unsigned *count) ++{ ++ fill_gap(offset, kbuf, pos, count); ++ if (size > *count) ++ size = *count; ++ if (size) { ++ memcpy(*kbuf, from, size); ++ *kbuf += size; ++ *pos += size; ++ *count -= size; + } + } + +@@ -976,8 +989,9 @@ __copy_xstate_to_kernel(void *kbuf, cons + */ + int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int offset_start, unsigned int size_total) + { +- unsigned int offset, size; + struct xstate_header header; ++ const unsigned off_mxcsr = offsetof(struct fxregs_state, mxcsr); ++ unsigned count = size_total; + int i; + + /* +@@ -993,46 +1007,42 @@ int copy_xstate_to_kernel(void *kbuf, st + header.xfeatures = xsave->header.xfeatures; + header.xfeatures &= ~XFEATURE_MASK_SUPERVISOR; + ++ if (header.xfeatures & XFEATURE_MASK_FP) ++ copy_part(0, off_mxcsr, ++ &xsave->i387, &kbuf, &offset_start, &count); ++ if (header.xfeatures & (XFEATURE_MASK_SSE | XFEATURE_MASK_YMM)) ++ copy_part(off_mxcsr, MXCSR_AND_FLAGS_SIZE, ++ &xsave->i387.mxcsr, &kbuf, &offset_start, &count); ++ if (header.xfeatures & XFEATURE_MASK_FP) ++ copy_part(offsetof(struct fxregs_state, st_space), 128, ++ &xsave->i387.st_space, &kbuf, &offset_start, &count); ++ if (header.xfeatures & XFEATURE_MASK_SSE) ++ copy_part(xstate_offsets[XFEATURE_MASK_SSE], 256, ++ &xsave->i387.xmm_space, &kbuf, &offset_start, &count); ++ /* ++ * Fill xsave->i387.sw_reserved value for ptrace frame: ++ */ ++ copy_part(offsetof(struct fxregs_state, sw_reserved), 48, ++ xstate_fx_sw_bytes, &kbuf, &offset_start, &count); + /* + * Copy xregs_state->header: + */ +- offset = offsetof(struct xregs_state, header); +- size = sizeof(header); +- +- __copy_xstate_to_kernel(kbuf, &header, offset, size, size_total); ++ copy_part(offsetof(struct xregs_state, header), sizeof(header), ++ &header, &kbuf, &offset_start, &count); + +- for (i = 0; i < XFEATURE_MAX; i++) { ++ for (i = FIRST_EXTENDED_XFEATURE; i < XFEATURE_MAX; i++) { + /* + * Copy only in-use xstates: + */ + if ((header.xfeatures >> i) & 1) { + void *src = __raw_xsave_addr(xsave, i); + +- offset = xstate_offsets[i]; +- size = xstate_sizes[i]; +- +- /* The next component has to fit fully into the output buffer: */ +- if (offset + size > size_total) +- break; +- +- __copy_xstate_to_kernel(kbuf, src, offset, size, size_total); ++ copy_part(xstate_offsets[i], xstate_sizes[i], ++ src, &kbuf, &offset_start, &count); + } + + } +- +- if (xfeatures_mxcsr_quirk(header.xfeatures)) { +- offset = offsetof(struct fxregs_state, mxcsr); +- size = MXCSR_AND_FLAGS_SIZE; +- __copy_xstate_to_kernel(kbuf, &xsave->i387.mxcsr, offset, size, size_total); +- } +- +- /* +- * Fill xsave->i387.sw_reserved value for ptrace frame: +- */ +- offset = offsetof(struct fxregs_state, sw_reserved); +- size = sizeof(xstate_fx_sw_bytes); +- +- __copy_xstate_to_kernel(kbuf, xstate_fx_sw_bytes, offset, size, size_total); ++ fill_gap(size_total, &kbuf, &offset_start, &count); + + return 0; + } diff --git a/queue-5.4/mac80211-mesh-fix-discovery-timer-re-arming-issue-crash.patch b/queue-5.4/mac80211-mesh-fix-discovery-timer-re-arming-issue-crash.patch new file mode 100644 index 00000000000..123dc5904d8 --- /dev/null +++ b/queue-5.4/mac80211-mesh-fix-discovery-timer-re-arming-issue-crash.patch @@ -0,0 +1,165 @@ +From e2d4a80f93fcfaf72e2e20daf6a28e39c3b90677 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Linus=20L=C3=BCssing?= +Date: Fri, 22 May 2020 19:04:13 +0200 +Subject: mac80211: mesh: fix discovery timer re-arming issue / crash +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Linus Lüssing + +commit e2d4a80f93fcfaf72e2e20daf6a28e39c3b90677 upstream. + +On a non-forwarding 802.11s link between two fairly busy +neighboring nodes (iperf with -P 16 at ~850MBit/s TCP; +1733.3 MBit/s VHT-MCS 9 80MHz short GI VHT-NSS 4), so with +frequent PREQ retries, usually after around 30-40 seconds the +following crash would occur: + +[ 1110.822428] Unable to handle kernel read from unreadable memory at virtual address 00000000 +[ 1110.830786] Mem abort info: +[ 1110.833573] Exception class = IABT (current EL), IL = 32 bits +[ 1110.839494] SET = 0, FnV = 0 +[ 1110.842546] EA = 0, S1PTW = 0 +[ 1110.845678] user pgtable: 4k pages, 48-bit VAs, pgd = ffff800076386000 +[ 1110.852204] [0000000000000000] *pgd=00000000f6322003, *pud=00000000f62de003, *pmd=0000000000000000 +[ 1110.861167] Internal error: Oops: 86000004 [#1] PREEMPT SMP +[ 1110.866730] Modules linked in: pppoe ppp_async batman_adv ath10k_pci ath10k_core ath pppox ppp_generic nf_conntrack_ipv6 mac80211 iptable_nat ipt_REJECT ipt_MASQUERADE cfg80211 xt_time xt_tcpudp xt_state xt_nat xt_multiport xt_mark xt_mac xt_limit xt_conntrack xt_comment xt_TCPMSS xt_REDIRECT xt_LOG xt_FLOWOFFLOAD slhc nf_reject_ipv4 nf_nat_redirect nf_nat_masquerade_ipv4 nf_conntrack_ipv4 nf_nat_ipv4 nf_nat nf_log_ipv4 nf_flow_table_hw nf_flow_table nf_defrag_ipv6 nf_defrag_ipv4 nf_conntrack_rtcache nf_conntrack iptable_mangle iptable_filter ip_tables crc_ccitt compat nf_log_ipv6 nf_log_common ip6table_mangle ip6table_filter ip6_tables ip6t_REJECT x_tables nf_reject_ipv6 usb_storage xhci_plat_hcd xhci_pci xhci_hcd dwc3 usbcore usb_common +[ 1110.932190] Process swapper/3 (pid: 0, stack limit = 0xffff0000090c8000) +[ 1110.938884] CPU: 3 PID: 0 Comm: swapper/3 Not tainted 4.14.162 #0 +[ 1110.944965] Hardware name: LS1043A RGW Board (DT) +[ 1110.949658] task: ffff8000787a81c0 task.stack: ffff0000090c8000 +[ 1110.955568] PC is at 0x0 +[ 1110.958097] LR is at call_timer_fn.isra.27+0x24/0x78 +[ 1110.963055] pc : [<0000000000000000>] lr : [] pstate: 00400145 +[ 1110.970440] sp : ffff00000801be10 +[ 1110.973744] x29: ffff00000801be10 x28: ffff000008bf7018 +[ 1110.979047] x27: ffff000008bf87c8 x26: ffff000008c160c0 +[ 1110.984352] x25: 0000000000000000 x24: 0000000000000000 +[ 1110.989657] x23: dead000000000200 x22: 0000000000000000 +[ 1110.994959] x21: 0000000000000000 x20: 0000000000000101 +[ 1111.000262] x19: ffff8000787a81c0 x18: 0000000000000000 +[ 1111.005565] x17: ffff0000089167b0 x16: 0000000000000058 +[ 1111.010868] x15: ffff0000089167b0 x14: 0000000000000000 +[ 1111.016172] x13: ffff000008916788 x12: 0000000000000040 +[ 1111.021475] x11: ffff80007fda9af0 x10: 0000000000000001 +[ 1111.026777] x9 : ffff00000801bea0 x8 : 0000000000000004 +[ 1111.032080] x7 : 0000000000000000 x6 : ffff80007fda9aa8 +[ 1111.037383] x5 : ffff00000801bea0 x4 : 0000000000000010 +[ 1111.042685] x3 : ffff00000801be98 x2 : 0000000000000614 +[ 1111.047988] x1 : 0000000000000000 x0 : 0000000000000000 +[ 1111.053290] Call trace: +[ 1111.055728] Exception stack(0xffff00000801bcd0 to 0xffff00000801be10) +[ 1111.062158] bcc0: 0000000000000000 0000000000000000 +[ 1111.069978] bce0: 0000000000000614 ffff00000801be98 0000000000000010 ffff00000801bea0 +[ 1111.077798] bd00: ffff80007fda9aa8 0000000000000000 0000000000000004 ffff00000801bea0 +[ 1111.085618] bd20: 0000000000000001 ffff80007fda9af0 0000000000000040 ffff000008916788 +[ 1111.093437] bd40: 0000000000000000 ffff0000089167b0 0000000000000058 ffff0000089167b0 +[ 1111.101256] bd60: 0000000000000000 ffff8000787a81c0 0000000000000101 0000000000000000 +[ 1111.109075] bd80: 0000000000000000 dead000000000200 0000000000000000 0000000000000000 +[ 1111.116895] bda0: ffff000008c160c0 ffff000008bf87c8 ffff000008bf7018 ffff00000801be10 +[ 1111.124715] bdc0: ffff0000080ff29c ffff00000801be10 0000000000000000 0000000000400145 +[ 1111.132534] bde0: ffff8000787a81c0 ffff00000801bde8 0000ffffffffffff 000001029eb19be8 +[ 1111.140353] be00: ffff00000801be10 0000000000000000 +[ 1111.145220] [< (null)>] (null) +[ 1111.149917] [] run_timer_softirq+0x184/0x398 +[ 1111.155741] [] __do_softirq+0x100/0x1fc +[ 1111.161130] [] irq_exit+0x80/0xd8 +[ 1111.166002] [] __handle_domain_irq+0x88/0xb0 +[ 1111.171825] [] gic_handle_irq+0x68/0xb0 +[ 1111.177213] Exception stack(0xffff0000090cbe30 to 0xffff0000090cbf70) +[ 1111.183642] be20: 0000000000000020 0000000000000000 +[ 1111.191461] be40: 0000000000000001 0000000000000000 00008000771af000 0000000000000000 +[ 1111.199281] be60: ffff000008c95180 0000000000000000 ffff000008c19360 ffff0000090cbef0 +[ 1111.207101] be80: 0000000000000810 0000000000000400 0000000000000098 ffff000000000000 +[ 1111.214920] bea0: 0000000000000001 ffff0000089167b0 0000000000000000 ffff0000089167b0 +[ 1111.222740] bec0: 0000000000000000 ffff000008c198e8 ffff000008bf7018 ffff000008c19000 +[ 1111.230559] bee0: 0000000000000000 0000000000000000 ffff8000787a81c0 ffff000008018000 +[ 1111.238380] bf00: ffff00000801c000 ffff00000913ba34 ffff8000787a81c0 ffff0000090cbf70 +[ 1111.246199] bf20: ffff0000080857cc ffff0000090cbf70 ffff0000080857d0 0000000000400145 +[ 1111.254020] bf40: ffff000008018000 ffff00000801c000 ffffffffffffffff ffff0000080fa574 +[ 1111.261838] bf60: ffff0000090cbf70 ffff0000080857d0 +[ 1111.266706] [] el1_irq+0xe8/0x18c +[ 1111.271576] [] arch_cpu_idle+0x10/0x18 +[ 1111.276880] [] do_idle+0xec/0x1b8 +[ 1111.281748] [] cpu_startup_entry+0x20/0x28 +[ 1111.287399] [] secondary_start_kernel+0x104/0x110 +[ 1111.293662] Code: bad PC value +[ 1111.296710] ---[ end trace 555b6ca4363c3edd ]--- +[ 1111.301318] Kernel panic - not syncing: Fatal exception in interrupt +[ 1111.307661] SMP: stopping secondary CPUs +[ 1111.311574] Kernel Offset: disabled +[ 1111.315053] CPU features: 0x0002000 +[ 1111.318530] Memory Limit: none +[ 1111.321575] Rebooting in 3 seconds.. + +With some added debug output / delays we were able to push the crash from +the timer callback runner into the callback function and by that shedding +some light on which object holding the timer gets corrupted: + +[ 401.720899] Unable to handle kernel read from unreadable memory at virtual address 00000868 +[...] +[ 402.335836] [] _raw_spin_lock_bh+0x14/0x48 +[ 402.341548] [] mesh_path_timer+0x10c/0x248 [mac80211] +[ 402.348154] [] call_timer_fn.isra.27+0x24/0x78 +[ 402.354150] [] run_timer_softirq+0x184/0x398 +[ 402.359974] [] __do_softirq+0x100/0x1fc +[ 402.365362] [] irq_exit+0x80/0xd8 +[ 402.370231] [] __handle_domain_irq+0x88/0xb0 +[ 402.376053] [] gic_handle_irq+0x68/0xb0 + +The issue happens due to the following sequence of events: + +1) mesh_path_start_discovery(): +-> spin_unlock_bh(&mpath->state_lock) before mesh_path_sel_frame_tx() + +2) mesh_path_free_rcu() +-> del_timer_sync(&mpath->timer) + [...] +-> kfree_rcu(mpath) + +3) mesh_path_start_discovery(): +-> mod_timer(&mpath->timer, ...) + [...] +-> rcu_read_unlock() + +4) mesh_path_free_rcu()'s kfree_rcu(): +-> kfree(mpath) + +5) mesh_path_timer() starts after timeout, using freed mpath object + +So a use-after-free issue due to a timer re-arming bug caused by an +early spin-unlocking. + +This patch fixes this issue by re-checking if mpath is about to be +free'd and if so bails out of re-arming the timer. + +Cc: stable@vger.kernel.org +Fixes: 050ac52cbe1f ("mac80211: code for on-demand Hybrid Wireless Mesh Protocol") +Cc: Simon Wunderlich +Signed-off-by: Linus Lüssing +Link: https://lore.kernel.org/r/20200522170413.14973-1-linus.luessing@c0d3.blue +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman + +--- + net/mac80211/mesh_hwmp.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/net/mac80211/mesh_hwmp.c ++++ b/net/mac80211/mesh_hwmp.c +@@ -1103,7 +1103,14 @@ void mesh_path_start_discovery(struct ie + mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->vif.addr, ifmsh->sn, + target_flags, mpath->dst, mpath->sn, da, 0, + ttl, lifetime, 0, ifmsh->preq_id++, sdata); ++ ++ spin_lock_bh(&mpath->state_lock); ++ if (mpath->flags & MESH_PATH_DELETED) { ++ spin_unlock_bh(&mpath->state_lock); ++ goto enddiscovery; ++ } + mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout); ++ spin_unlock_bh(&mpath->state_lock); + + enddiscovery: + rcu_read_unlock(); diff --git a/queue-5.4/series b/queue-5.4/series index 377652e3004..17b8edc9fa4 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -104,3 +104,8 @@ revert-block-end-bio-with-blk_sts_again-in-case-of-n.patch gpio-fix-locking-open-drain-irq-lines.patch iommu-fix-reference-count-leak-in-iommu_group_alloc.patch parisc-fix-kernel-panic-in-mem_init.patch +cfg80211-fix-debugfs-rename-crash.patch +x86-syscalls-revert-x86-syscalls-make-__x32_syscall_bit-be-unsigned-long.patch +mac80211-mesh-fix-discovery-timer-re-arming-issue-crash.patch +x86-dma-fix-max-pfn-arithmetic-overflow-on-32-bit-systems.patch +copy_xstate_to_kernel-don-t-leave-parts-of-destination-uninitialized.patch diff --git a/queue-5.4/x86-dma-fix-max-pfn-arithmetic-overflow-on-32-bit-systems.patch b/queue-5.4/x86-dma-fix-max-pfn-arithmetic-overflow-on-32-bit-systems.patch new file mode 100644 index 00000000000..f743a7a479b --- /dev/null +++ b/queue-5.4/x86-dma-fix-max-pfn-arithmetic-overflow-on-32-bit-systems.patch @@ -0,0 +1,108 @@ +From 88743470668ef5eb6b7ba9e0f99888e5999bf172 Mon Sep 17 00:00:00 2001 +From: Alexander Dahl +Date: Tue, 26 May 2020 19:57:49 +0200 +Subject: x86/dma: Fix max PFN arithmetic overflow on 32 bit systems +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Alexander Dahl + +commit 88743470668ef5eb6b7ba9e0f99888e5999bf172 upstream. + +The intermediate result of the old term (4UL * 1024 * 1024 * 1024) is +4 294 967 296 or 0x100000000 which is no problem on 64 bit systems. +The patch does not change the later overall result of 0x100000 for +MAX_DMA32_PFN (after it has been shifted by PAGE_SHIFT). The new +calculation yields the same result, but does not require 64 bit +arithmetic. + +On 32 bit systems the old calculation suffers from an arithmetic +overflow in that intermediate term in braces: 4UL aka unsigned long int +is 4 byte wide and an arithmetic overflow happens (the 0x100000000 does +not fit in 4 bytes), the in braces result is truncated to zero, the +following right shift does not alter that, so MAX_DMA32_PFN evaluates to +0 on 32 bit systems. + +That wrong value is a problem in a comparision against MAX_DMA32_PFN in +the init code for swiotlb in pci_swiotlb_detect_4gb() to decide if +swiotlb should be active. That comparison yields the opposite result, +when compiling on 32 bit systems. + +This was not possible before + + 1b7e03ef7570 ("x86, NUMA: Enable emulation on 32bit too") + +when that MAX_DMA32_PFN was first made visible to x86_32 (and which +landed in v3.0). + +In practice this wasn't a problem, unless CONFIG_SWIOTLB is active on +x86-32. + +However if one has set CONFIG_IOMMU_INTEL, since + + c5a5dc4cbbf4 ("iommu/vt-d: Don't switch off swiotlb if bounce page is used") + +there's a dependency on CONFIG_SWIOTLB, which was not necessarily +active before. That landed in v5.4, where we noticed it in the fli4l +Linux distribution. We have CONFIG_IOMMU_INTEL active on both 32 and 64 +bit kernel configs there (I could not find out why, so let's just say +historical reasons). + +The effect is at boot time 64 MiB (default size) were allocated for +bounce buffers now, which is a noticeable amount of memory on small +systems like pcengines ALIX 2D3 with 256 MiB memory, which are still +frequently used as home routers. + +We noticed this effect when migrating from kernel v4.19 (LTS) to v5.4 +(LTS) in fli4l and got that kernel messages for example: + + Linux version 5.4.22 (buildroot@buildroot) (gcc version 7.3.0 (Buildroot 2018.02.8)) #1 SMP Mon Nov 26 23:40:00 CET 2018 + … + Memory: 183484K/261756K available (4594K kernel code, 393K rwdata, 1660K rodata, 536K init, 456K bss , 78272K reserved, 0K cma-reserved, 0K highmem) + … + PCI-DMA: Using software bounce buffering for IO (SWIOTLB) + software IO TLB: mapped [mem 0x0bb78000-0x0fb78000] (64MB) + +The initial analysis and the suggested fix was done by user 'sourcejedi' +at stackoverflow and explicitly marked as GPLv2 for inclusion in the +Linux kernel: + + https://unix.stackexchange.com/a/520525/50007 + +The new calculation, which does not suffer from that overflow, is the +same as for arch/mips now as suggested by Robin Murphy. + +The fix was tested by fli4l users on round about two dozen different +systems, including both 32 and 64 bit archs, bare metal and virtualized +machines. + + [ bp: Massage commit message. ] + +Fixes: 1b7e03ef7570 ("x86, NUMA: Enable emulation on 32bit too") +Reported-by: Alan Jenkins +Suggested-by: Robin Murphy +Signed-off-by: Alexander Dahl +Signed-off-by: Borislav Petkov +Reviewed-by: Greg Kroah-Hartman +Cc: stable@vger.kernel.org +Link: https://unix.stackexchange.com/q/520065/50007 +Link: https://web.nettworks.org/bugs/browse/FFL-2560 +Link: https://lkml.kernel.org/r/20200526175749.20742-1-post@lespocky.de +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/asm/dma.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/include/asm/dma.h ++++ b/arch/x86/include/asm/dma.h +@@ -74,7 +74,7 @@ + #define MAX_DMA_PFN ((16UL * 1024 * 1024) >> PAGE_SHIFT) + + /* 4GB broken PCI/AGP hardware bus master zone */ +-#define MAX_DMA32_PFN ((4UL * 1024 * 1024 * 1024) >> PAGE_SHIFT) ++#define MAX_DMA32_PFN (1UL << (32 - PAGE_SHIFT)) + + #ifdef CONFIG_X86_32 + /* The maximum address that we can perform a DMA transfer to on this platform */ diff --git a/queue-5.4/x86-syscalls-revert-x86-syscalls-make-__x32_syscall_bit-be-unsigned-long.patch b/queue-5.4/x86-syscalls-revert-x86-syscalls-make-__x32_syscall_bit-be-unsigned-long.patch new file mode 100644 index 00000000000..6c335380d67 --- /dev/null +++ b/queue-5.4/x86-syscalls-revert-x86-syscalls-make-__x32_syscall_bit-be-unsigned-long.patch @@ -0,0 +1,66 @@ +From 700d3a5a664df267f01ec8887fd2d8ff98f67e7f Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +Date: Fri, 8 May 2020 17:25:32 -0700 +Subject: x86/syscalls: Revert "x86/syscalls: Make __X32_SYSCALL_BIT be unsigned long" + +From: Andy Lutomirski + +commit 700d3a5a664df267f01ec8887fd2d8ff98f67e7f upstream. + +Revert + + 45e29d119e99 ("x86/syscalls: Make __X32_SYSCALL_BIT be unsigned long") + +and add a comment to discourage someone else from making the same +mistake again. + +It turns out that some user code fails to compile if __X32_SYSCALL_BIT +is unsigned long. See, for example [1] below. + + [ bp: Massage and do the same thing in the respective tools/ header. ] + +Fixes: 45e29d119e99 ("x86/syscalls: Make __X32_SYSCALL_BIT be unsigned long") +Reported-by: Thorsten Glaser +Signed-off-by: Andy Lutomirski +Signed-off-by: Borislav Petkov +Cc: stable@kernel.org +Link: [1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=954294 +Link: https://lkml.kernel.org/r/92e55442b744a5951fdc9cfee10badd0a5f7f828.1588983892.git.luto@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/include/uapi/asm/unistd.h | 11 +++++++++-- + tools/arch/x86/include/uapi/asm/unistd.h | 2 +- + 2 files changed, 10 insertions(+), 3 deletions(-) + +--- a/arch/x86/include/uapi/asm/unistd.h ++++ b/arch/x86/include/uapi/asm/unistd.h +@@ -2,8 +2,15 @@ + #ifndef _UAPI_ASM_X86_UNISTD_H + #define _UAPI_ASM_X86_UNISTD_H + +-/* x32 syscall flag bit */ +-#define __X32_SYSCALL_BIT 0x40000000UL ++/* ++ * x32 syscall flag bit. Some user programs expect syscall NR macros ++ * and __X32_SYSCALL_BIT to have type int, even though syscall numbers ++ * are, for practical purposes, unsigned long. ++ * ++ * Fortunately, expressions like (nr & ~__X32_SYSCALL_BIT) do the right ++ * thing regardless. ++ */ ++#define __X32_SYSCALL_BIT 0x40000000 + + #ifndef __KERNEL__ + # ifdef __i386__ +--- a/tools/arch/x86/include/uapi/asm/unistd.h ++++ b/tools/arch/x86/include/uapi/asm/unistd.h +@@ -3,7 +3,7 @@ + #define _UAPI_ASM_X86_UNISTD_H + + /* x32 syscall flag bit */ +-#define __X32_SYSCALL_BIT 0x40000000UL ++#define __X32_SYSCALL_BIT 0x40000000 + + #ifndef __KERNEL__ + # ifdef __i386__