mirror of
https://git.openwrt.org/openwrt/openwrt.git
synced 2026-03-03 14:53:47 +01:00
mt7620: workaround jal imm26 and redundant PAGE_ALIGN
Some checks are pending
Build Kernel / Build all affected Kernels (push) Waiting to run
Some checks are pending
Build Kernel / Build all affected Kernels (push) Waiting to run
On MT7620-class platforms (CONFIG_NET_RALINK_MT7620) we observe sporadic
wrong-jump-targets, kernel oopses, hanging, corrupted backtraces or even
"half-written" instructions when the compiler emits a direct 'jal imm26'
call.
This is triggered in:
- the small random helpers inside get_random_u32_below(), and
- the blkcg_maybe_throttle_current() call in resume_user_mode_work().
This patch forces those two call sites to use an indirect call via
a volatile function pointer (load into register + jalr) when building
for MT7620, avoiding embedding a 26-bit immediate jump target.
Additionally, on MT7620 builds the exec path in fs/exec.c is modified:
- skip arch_align_stack() + PAGE_ALIGN() in setup_arg_pages()
because the micro-randomization (< PAGE_SIZE) implemented by many
ports (including MT7620) is negated immediately by PAGE_ALIGN().
Skipping the redundant PAGE_ALIGN() reduces exposure to the
problematic code pattern.
These changes are targeted workarounds for MT7620; behavioral logic is unchanged.
Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com>
Link: https://github.com/openwrt/openwrt/pull/20553
Signed-off-by: Robert Marko <robimarko@gmail.com>
(cherry picked from commit 22ccb445e6)
This commit is contained in:
parent
0f46eefc66
commit
7d5d366404
3 changed files with 137 additions and 0 deletions
|
|
@ -0,0 +1,72 @@
|
|||
From: Mieczyslaw Nalewaj <namiltd@yahoo.com>
|
||||
Date: Sun, 26 Oct 2025 10:36:02 +0100
|
||||
Subject: [PATCH] mt7620: avoid direct jal imm26 in random helper
|
||||
|
||||
This patch forces an indirect call (via a function pointer) on the mt7620
|
||||
platform when calling the small random helpers used by the constant-folding
|
||||
fast path of get_random_u32_below(). That avoids embedding a 26-bit immediate
|
||||
jump target in a direct `jal` instruction, which on affected platforms can
|
||||
lead to sporadic incorrect jump targets, intermittent oopses/crashes/hangs,
|
||||
corrupted backtraces, or "half-written" instructions under some circumstances.
|
||||
|
||||
The change is targetted and conservative: it only alters code generation on
|
||||
CONFIG_NET_RALINK_MT7620 builds and does not change the algorithmic behaviour
|
||||
of get_random_u32_below().
|
||||
|
||||
Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com>
|
||||
---
|
||||
a/include/linux/random.h | 36 ++++++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 32 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/include/linux/random.h
|
||||
+++ b/include/linux/random.h
|
||||
@@ -73,17 +73,45 @@ static inline u32 get_random_u32_below(u
|
||||
BUILD_BUG_ON_MSG(!ceil, "get_random_u32_below() must take ceil > 0");
|
||||
if (ceil <= 1)
|
||||
return 0;
|
||||
- for (;;) {
|
||||
- if (ceil <= 1U << 8) {
|
||||
+ if (ceil <= 1U << 8) {
|
||||
+#ifdef CONFIG_NET_RALINK_MT7620
|
||||
+ typedef u8 (*getrnd_t)(void);
|
||||
+ volatile getrnd_t rnd_fn = (getrnd_t)get_random_u8;
|
||||
+#endif
|
||||
+ for (;;) {
|
||||
+#ifdef CONFIG_NET_RALINK_MT7620
|
||||
+ u32 mult = ceil * rnd_fn();
|
||||
+#else
|
||||
u32 mult = ceil * get_random_u8();
|
||||
+#endif
|
||||
if (likely(is_power_of_2(ceil) || (u8)mult >= (1U << 8) % ceil))
|
||||
return mult >> 8;
|
||||
- } else if (ceil <= 1U << 16) {
|
||||
+ }
|
||||
+ } else if (ceil <= 1U << 16) {
|
||||
+#ifdef CONFIG_NET_RALINK_MT7620
|
||||
+ typedef u16 (*getrnd_t)(void);
|
||||
+ volatile getrnd_t rnd_fn = (getrnd_t)get_random_u16;
|
||||
+#endif
|
||||
+ for (;;) {
|
||||
+#ifdef CONFIG_NET_RALINK_MT7620
|
||||
+ u32 mult = ceil * rnd_fn();
|
||||
+#else
|
||||
u32 mult = ceil * get_random_u16();
|
||||
+#endif
|
||||
if (likely(is_power_of_2(ceil) || (u16)mult >= (1U << 16) % ceil))
|
||||
return mult >> 16;
|
||||
- } else {
|
||||
+ }
|
||||
+ } else {
|
||||
+#ifdef CONFIG_NET_RALINK_MT7620
|
||||
+ typedef u32 (*getrnd_t)(void);
|
||||
+ volatile getrnd_t rnd_fn = (getrnd_t)get_random_u32;
|
||||
+#endif
|
||||
+ for (;;) {
|
||||
+#ifdef CONFIG_NET_RALINK_MT7620
|
||||
+ u64 mult = (u64)ceil * rnd_fn();
|
||||
+#else
|
||||
u64 mult = (u64)ceil * get_random_u32();
|
||||
+#endif
|
||||
if (likely(is_power_of_2(ceil) || (u32)mult >= -ceil % ceil))
|
||||
return mult >> 32;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
From: Mieczyslaw Nalewaj <namiltd@yahoo.com>
|
||||
Date: Tue, 28 Oct 2025 22:50:41 +0100
|
||||
Subject: [PATCH] mt7620: avoid direct jal imm26 in resume_user_mode_work
|
||||
|
||||
This patch forces an indirect call (via a function pointer) on the mt7620
|
||||
platform when invoking blkcg_maybe_throttle_current() from
|
||||
resume_user_mode_work(). Avoiding a direct `jal` with a 26-bit immediate
|
||||
jump target prevents sporadic incorrect jump targets / intermittent oopses,
|
||||
crashes or hanging behavior that can appear on affected platforms.
|
||||
|
||||
The change is targeted: it only alters the call site when CONFIG_NET_RALINK_MT7620
|
||||
is enabled and does not change the functional behaviour of resume_user_mode_work().
|
||||
|
||||
Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com>
|
||||
|
||||
---
|
||||
a/include/linux/resume_user_mode.h | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/include/linux/resume_user_mode.h
|
||||
+++ b/include/linux/resume_user_mode.h
|
||||
@@ -57,7 +57,13 @@ static inline void resume_user_mode_work
|
||||
#endif
|
||||
|
||||
mem_cgroup_handle_over_high(GFP_KERNEL);
|
||||
+#ifdef CONFIG_NET_RALINK_MT7620
|
||||
+ typedef void (*bmtc_t)(void);
|
||||
+ volatile bmtc_t bmtc_fn = (bmtc_t)blkcg_maybe_throttle_current;
|
||||
+ bmtc_fn();
|
||||
+#else
|
||||
blkcg_maybe_throttle_current();
|
||||
+#endif
|
||||
|
||||
rseq_handle_notify_resume(NULL, regs);
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
From: Mieczyslaw Nalewaj <namiltd@yahoo.com>
|
||||
Date: Sun, 26 Oct 2025 10:36:02 +0100
|
||||
Subject: [PATCH] mt7620: conditional stack align
|
||||
|
||||
This patch avoids applying arch_align_stack() and PAGE_ALIGN() in the exec
|
||||
path on CONFIG_NET_RALINK_MT7620 builds. Many ports (including mt7620)
|
||||
implement only micro-randomization inside arch_align_stack() (random offset
|
||||
< PAGE_SIZE and then align-down to small alignment). Callers that immediately
|
||||
apply PAGE_ALIGN() will round that micro-offset back to the original page
|
||||
boundary, so invoking arch_align_stack() then PAGE_ALIGN() is pointless and
|
||||
can be avoided on the affected platform.
|
||||
|
||||
Signed-off-by: Mieczyslaw Nalewaj <namiltd@yahoo.com>
|
||||
---
|
||||
a/fs/exec.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/fs/exec.c
|
||||
+++ b/fs/exec.c
|
||||
@@ -750,8 +750,10 @@ int setup_arg_pages(struct linux_binprm
|
||||
mm->arg_start = bprm->p - stack_shift;
|
||||
bprm->p = vma->vm_end - stack_shift;
|
||||
#else
|
||||
+#ifndef CONFIG_NET_RALINK_MT7620
|
||||
stack_top = arch_align_stack(stack_top);
|
||||
stack_top = PAGE_ALIGN(stack_top);
|
||||
+#endif
|
||||
|
||||
if (unlikely(stack_top < mmap_min_addr) ||
|
||||
unlikely(vma->vm_end - vma->vm_start >= stack_top - mmap_min_addr))
|
||||
Loading…
Add table
Reference in a new issue