summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King (Oracle) <rmk+kernel@armlinux.org.uk>2026-10-14 17:27:00 +0100
committerRussell King <rmk+kernel@armlinux.org.uk>2026-10-14 17:27:00 +0100
commit01330dac0fa7c16ef0f3da39757e9509653a2e3f (patch)
treeb6f4a4a7fcd7e3122139940381ee1c3c8a2a73fa
parent1eb87d8f77379d4e4b279487b8c859fb64bd1afb (diff)
parentc2bbeff6952a84282333ebcff59f9fde449f60dd (diff)
Merge branches 'fixes' and 'misc' into for-next
-rw-r--r--arch/arm/boot/compressed/Makefile8
-rw-r--r--arch/arm/boot/compressed/big-endian.S14
-rw-r--r--arch/arm/boot/compressed/head-xscale.S18
-rw-r--r--arch/arm/lib/backtrace-clang.S4
-rw-r--r--arch/arm/mm/context.c15
5 files changed, 33 insertions, 26 deletions
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index e3f550d62857..5993dd1d0ee9 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -41,14 +41,6 @@ ifeq ($(CONFIG_PXA_SHARPSL_DETECT_MACH_ID),y)
OBJS += head-sharpsl.o
endif
-ifeq ($(CONFIG_CPU_ENDIAN_BE32),y)
-ifeq ($(CONFIG_CPU_CP15),y)
-OBJS += big-endian.o
-else
-# The endian should be set by h/w design.
-endif
-endif
-
#
# We now have a PIC decompressor implementation. Decompressors running
# from RAM should not define ZTEXTADDR. Decompressors running directly
diff --git a/arch/arm/boot/compressed/big-endian.S b/arch/arm/boot/compressed/big-endian.S
deleted file mode 100644
index 0e092c36da2f..000000000000
--- a/arch/arm/boot/compressed/big-endian.S
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * linux/arch/arm/boot/compressed/big-endian.S
- *
- * Switch CPU into big endian mode.
- * Author: Nicolas Pitre
- */
-
- .section ".start", "ax"
-
- mrc p15, 0, r0, c1, c0, 0 @ read control reg
- orr r0, r0, #(1 << 7) @ enable big endian mode
- mcr p15, 0, r0, c1, c0, 0 @ write control reg
-
diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S
index 20fa44d59f82..d6c3d0a76550 100644
--- a/arch/arm/boot/compressed/head-xscale.S
+++ b/arch/arm/boot/compressed/head-xscale.S
@@ -7,6 +7,7 @@
*/
#include <linux/linkage.h>
+#include <asm/cp15.h>
.section ".start", "ax"
@@ -14,6 +15,23 @@ __XScale_start:
@ Preserve r8/r7 i.e. kernel entry values
+ @ set correct endianness for ixp4xx regardless of bootloader
+ mrc p15, 0, r0, c1, c0, 0
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ orr r0, r0, #CR_B @ enable big endian mode
+#else
+ bic r0, r0, #CR_B
+#endif
+ mcr p15, 0, r0, c1, c0, 0
+0: mrc p15, 0, r0, c1, c0, 0
+ tst r0, #0x80
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ beq 0b
+#else
+ bne 0b
+#endif
+ sub pc, pc, #4 @ flush instruction pipeline
+
@ Data cache might be active.
@ Be sure to flush kernel binary out of the cache,
@ whatever state it is, before it is turned off.
diff --git a/arch/arm/lib/backtrace-clang.S b/arch/arm/lib/backtrace-clang.S
index 290c52a60fc6..9a10828992af 100644
--- a/arch/arm/lib/backtrace-clang.S
+++ b/arch/arm/lib/backtrace-clang.S
@@ -107,8 +107,10 @@ ENDPROC(c_backtrace)
/*
* Switches the current frame to be the frame for dump_stack.
+ * (Only in case of current task using current registers)
*/
- add frame, sp, #24 @ switch to false frame
+ cmp frame, fp
+ addeq frame, sp, #24 @ switch to false frame
for_each_frame: tst frame, mask @ Check for address exceptions
bne no_frame
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 4204ffa2d104..7c4e1e4ba77b 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -238,7 +238,7 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
{
unsigned long flags;
unsigned int cpu = smp_processor_id();
- u64 asid;
+ u64 asid, old_active_asid;
check_vmalloc_seq(mm);
@@ -250,8 +250,17 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk)
cpu_set_reserved_ttbr0();
asid = atomic64_read(&mm->context.id);
- if (!((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS)
- && atomic64_xchg(&per_cpu(active_asids, cpu), asid))
+
+ /*
+ * If our active_asids is zero, we are racing with an ASID roll-over
+ * on a different CPU, so skip the update (using cmpxchg if non-zero)
+ * and take the slow path.
+ */
+ old_active_asid = atomic64_read(&per_cpu(active_asids, cpu));
+ if (old_active_asid &&
+ !((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS) &&
+ atomic64_cmpxchg(&per_cpu(active_asids, cpu),
+ old_active_asid, asid))
goto switch_mm_fastpath;
raw_spin_lock_irqsave(&cpu_asid_lock, flags);