public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support
@ 2025-11-18 11:27 Huacai Chen
  2025-11-18 11:27 ` [PATCH V2 01/14] LoongArch: Add atomic operations for 32BIT/64BIT Huacai Chen
                   ` (14 more replies)
  0 siblings, 15 replies; 37+ messages in thread
From: Huacai Chen @ 2025-11-18 11:27 UTC (permalink / raw)
  To: Arnd Bergmann, Huacai Chen
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Xuerui Wang,
	Jiaxun Yang, linux-kernel, Huacai Chen, Yawei Li

LoongArch includes a reduced 32-bit version (LA32R), a standard 32-bit
version (LA32S) and a 64-bit version (LA64). LoongArch32 use FDT as its
boot protocol which is already supported in LoongArch64. LoongArch32's
ILP32 ABI use the same calling convention as LoongArch64.

This patchset is adding basic LoongArch32 support in mainline kernel, it
is the successor of Jiaxun Yang's previous work (V1):
https://lore.kernel.org/loongarch/20250102-la32-uapi-v1-0-db32aa769b88@flygoat.com/

We can see a complete snapshot here:
https://github.com/chenhuacai/linux/tree/loongarch-next

Cross-compile tool chain to build kernel:
https://github.com/sunhaiyong1978/Yongbao-Embedded/releases/download/0.13-2025.9.3/loongarch32-unknown-linux-gnu-gcc-0.13-20251105.x86_64.tar.xz

A CLFS-based Linux distro (Yongbao):
https://github.com/sunhaiyong1978/Yongbao-Embedded/releases/download/0.13-2025.9.3/loongarch32-Yongbao-Embedded-0.13-20251018-sysroot.tar.xz

Open-source tool chain which is under review (Also in maillist for upstream):
https://github.com/cloudspurs/binutils-gdb/tree/la32/
https://github.com/cloudspurs/gcc/tree/la32/
https://github.com/cloudspurs/glibc/tree/la32/

LA32 QEMU emulator (hardware is not as widely used as LA64):
https://github.com/loongson-community/qemu/tree/la32-user-exp/

Usage:
1. Extract Yongbao to a virtual disk (la32.img);
2. qemu-system-loongarch -kernel vmlinux -append "rw root=/dev/vda console=ttyS0,115200" \
   -m 256M -cpu max32 -machine virt,accel=tcg -drive file=la32.img,format=raw,if=virtio -display none -serial stdio

V1 -> V2:
1, Rebased on 6.18-rc6;
2, Port a full runnable kernel (except irqchip drivers);
3, Remove controversial flush_icache syscall for now.

Jiaxun Yang, Yawei Li and Huacai Chen(14):
 LoongArch: Add atomic operations for 32BIT/64BIT;
 LoongArch: Add adaptive CSR accessors for 32BIT/64BIT;
 LoongArch: Adjust common macro definitions for 32BIT/64BIT;
 LoongArch: Adjust boot & setup for 32BIT/64BIT;
 LoongArch: Adjust memory management for 32BIT/64BIT;
 LoongArch: Adjust process management for 32BIT/64BIT;
 LoongArch: Adjust time routines for 32BIT/64BIT;
 LoongArch: Adjust module loader for 32BIT/64BIT;
 LoongArch: Adjust system call for 32BIT/64BIT;
 LoongArch: Adjust user accessors for 32BIT/64BIT;
 LoongArch: Adjust misc routines for 32BIT/64BIT;
 LoongArch: Adjust VDSO/VSYSCALL for 32BIT/64BIT;
 LoongArch: Adjust default config files for 32BIT/64BIT;
 LoongArch: Adjust build infrastructure for 32BIT/64BIT.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Yawei Li <liyawei@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
 arch/loongarch/Kconfig                             |  115 +-
 arch/loongarch/Makefile                            |   29 +-
 arch/loongarch/boot/Makefile                       |    6 +
 arch/loongarch/configs/loongson32_defconfig        | 1110 ++++++++++++++++++++
 .../{loongson3_defconfig => loongson64_defconfig}  |    0
 arch/loongarch/include/asm/Kbuild                  |    1 +
 arch/loongarch/include/asm/addrspace.h             |   15 +-
 arch/loongarch/include/asm/asm.h                   |   77 +-
 arch/loongarch/include/asm/asmmacro.h              |  117 ++-
 arch/loongarch/include/asm/atomic-amo.h            |  206 ++++
 arch/loongarch/include/asm/atomic-llsc.h           |  100 ++
 arch/loongarch/include/asm/atomic.h                |  197 +---
 arch/loongarch/include/asm/checksum.h              |    4 +
 arch/loongarch/include/asm/cmpxchg.h               |   48 +-
 arch/loongarch/include/asm/cpu-features.h          |    3 -
 arch/loongarch/include/asm/elf.h                   |    1 +
 arch/loongarch/include/asm/inst.h                  |   12 +-
 arch/loongarch/include/asm/irq.h                   |    5 +
 arch/loongarch/include/asm/jump_label.h            |   12 +-
 arch/loongarch/include/asm/local.h                 |   37 +
 arch/loongarch/include/asm/loongarch.h             |  100 +-
 arch/loongarch/include/asm/module.h                |   11 +
 arch/loongarch/include/asm/page.h                  |    2 +-
 arch/loongarch/include/asm/percpu.h                |   44 +-
 arch/loongarch/include/asm/pgtable-bits.h          |   36 +-
 arch/loongarch/include/asm/pgtable.h               |   74 +-
 arch/loongarch/include/asm/stackframe.h            |   34 +-
 arch/loongarch/include/asm/string.h                |    2 +
 arch/loongarch/include/asm/timex.h                 |   29 +-
 arch/loongarch/include/asm/uaccess.h               |   63 +-
 arch/loongarch/include/asm/vdso/gettimeofday.h     |    4 +
 arch/loongarch/include/uapi/asm/Kbuild             |    1 +
 arch/loongarch/include/uapi/asm/unistd.h           |    6 +
 arch/loongarch/kernel/Makefile.syscalls            |    1 +
 arch/loongarch/kernel/cpu-probe.c                  |   23 +-
 arch/loongarch/kernel/efi-header.S                 |    4 +
 arch/loongarch/kernel/efi.c                        |    4 +-
 arch/loongarch/kernel/entry.S                      |   22 +-
 arch/loongarch/kernel/env.c                        |    9 +-
 arch/loongarch/kernel/fpu.S                        |  111 ++
 arch/loongarch/kernel/head.S                       |   39 +-
 arch/loongarch/kernel/module.c                     |   80 +-
 arch/loongarch/kernel/proc.c                       |   13 +-
 arch/loongarch/kernel/process.c                    |    6 +-
 arch/loongarch/kernel/ptrace.c                     |    5 +
 arch/loongarch/kernel/relocate.c                   |    9 +-
 arch/loongarch/kernel/switch.S                     |   25 +-
 arch/loongarch/kernel/syscall.c                    |   15 +-
 arch/loongarch/kernel/time.c                       |   31 +-
 arch/loongarch/kernel/traps.c                      |   15 +-
 arch/loongarch/kernel/unaligned.c                  |   30 +-
 arch/loongarch/kernel/vmlinux.lds.S                |    7 +-
 arch/loongarch/kvm/Kconfig                         |    2 +-
 arch/loongarch/kvm/vcpu.c                          |    5 +-
 arch/loongarch/lib/Makefile                        |    5 +-
 arch/loongarch/lib/clear_user.S                    |   22 +-
 arch/loongarch/lib/copy_user.S                     |   28 +-
 arch/loongarch/lib/dump_tlb.c                      |   14 +-
 arch/loongarch/lib/unaligned.S                     |   72 +-
 arch/loongarch/mm/init.c                           |    4 +-
 arch/loongarch/mm/page.S                           |  118 +--
 arch/loongarch/mm/tlb.c                            |   12 +-
 arch/loongarch/mm/tlbex.S                          |  322 ++++--
 arch/loongarch/pci/pci.c                           |    8 +-
 arch/loongarch/power/hibernate.c                   |    6 +-
 arch/loongarch/power/suspend.c                     |   24 +-
 arch/loongarch/power/suspend_asm.S                 |   72 +-
 arch/loongarch/vdso/Makefile                       |    7 +-
 arch/loongarch/vdso/vdso.lds.S                     |    4 +-
 arch/loongarch/vdso/vgetcpu.c                      |    8 +
 drivers/firmware/efi/libstub/Makefile              |    1 +
 drivers/firmware/efi/libstub/loongarch.c           |    8 +-
 drivers/pci/controller/Kconfig                     |    2 +-
 lib/crc/Kconfig                                    |    2 +-
 74 files changed, 2915 insertions(+), 781 deletions(-)
 create mode 100644 arch/loongarch/configs/loongson32_defconfig
 rename arch/loongarch/configs/{loongson3_defconfig => loongson64_defconfig} (100%)
 create mode 100644 arch/loongarch/include/asm/atomic-amo.h
 create mode 100644 arch/loongarch/include/asm/atomic-llsc.h
--
2.27.0


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH V2 01/14] LoongArch: Add atomic operations for 32BIT/64BIT
  2025-11-18 11:27 [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Huacai Chen
@ 2025-11-18 11:27 ` Huacai Chen
  2025-11-18 11:27 ` [PATCH V2 02/14] LoongArch: Add adaptive CSR accessors " Huacai Chen
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 37+ messages in thread
From: Huacai Chen @ 2025-11-18 11:27 UTC (permalink / raw)
  To: Arnd Bergmann, Huacai Chen
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Xuerui Wang,
	Jiaxun Yang, linux-kernel, Huacai Chen

LoongArch64 has both AMO and LL/SC instructions, while LoongArch32 only
has LL/SC intstructions. So we add a Kconfig option CPU_HAS_AMO here and
implement atomic operations (also including local operations and percpu
operations) for both 32BIT and 64BIT platforms.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
 arch/loongarch/Kconfig                   |   4 +
 arch/loongarch/include/asm/atomic-amo.h  | 206 +++++++++++++++++++++++
 arch/loongarch/include/asm/atomic-llsc.h | 100 +++++++++++
 arch/loongarch/include/asm/atomic.h      | 197 ++--------------------
 arch/loongarch/include/asm/cmpxchg.h     |  48 ++++--
 arch/loongarch/include/asm/local.h       |  37 ++++
 arch/loongarch/include/asm/percpu.h      |  40 +++--
 7 files changed, 413 insertions(+), 219 deletions(-)
 create mode 100644 arch/loongarch/include/asm/atomic-amo.h
 create mode 100644 arch/loongarch/include/asm/atomic-llsc.h

diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index a672f689cb03..730f34214519 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -568,6 +568,10 @@ config ARCH_STRICT_ALIGN
 	  to run kernel only on systems with h/w unaligned access support in
 	  order to optimise for performance.
 
+config CPU_HAS_AMO
+	bool
+	default 64BIT
+
 config CPU_HAS_FPU
 	bool
 	default y
diff --git a/arch/loongarch/include/asm/atomic-amo.h b/arch/loongarch/include/asm/atomic-amo.h
new file mode 100644
index 000000000000..d5efa5252d56
--- /dev/null
+++ b/arch/loongarch/include/asm/atomic-amo.h
@@ -0,0 +1,206 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Atomic operations (AMO).
+ *
+ * Copyright (C) 2020-2025 Loongson Technology Corporation Limited
+ */
+
+#ifndef _ASM_ATOMIC_AMO_H
+#define _ASM_ATOMIC_AMO_H
+
+#include <linux/types.h>
+#include <asm/barrier.h>
+#include <asm/cmpxchg.h>
+
+#define ATOMIC_OP(op, I, asm_op)					\
+static inline void arch_atomic_##op(int i, atomic_t *v)			\
+{									\
+	__asm__ __volatile__(						\
+	"am"#asm_op".w" " $zero, %1, %0	\n"				\
+	: "+ZB" (v->counter)						\
+	: "r" (I)							\
+	: "memory");							\
+}
+
+#define ATOMIC_OP_RETURN(op, I, asm_op, c_op, mb, suffix)		\
+static inline int arch_atomic_##op##_return##suffix(int i, atomic_t *v)	\
+{									\
+	int result;							\
+									\
+	__asm__ __volatile__(						\
+	"am"#asm_op#mb".w" " %1, %2, %0		\n"			\
+	: "+ZB" (v->counter), "=&r" (result)				\
+	: "r" (I)							\
+	: "memory");							\
+									\
+	return result c_op I;						\
+}
+
+#define ATOMIC_FETCH_OP(op, I, asm_op, mb, suffix)			\
+static inline int arch_atomic_fetch_##op##suffix(int i, atomic_t *v)	\
+{									\
+	int result;							\
+									\
+	__asm__ __volatile__(						\
+	"am"#asm_op#mb".w" " %1, %2, %0		\n"			\
+	: "+ZB" (v->counter), "=&r" (result)				\
+	: "r" (I)							\
+	: "memory");							\
+									\
+	return result;							\
+}
+
+#define ATOMIC_OPS(op, I, asm_op, c_op)					\
+	ATOMIC_OP(op, I, asm_op)					\
+	ATOMIC_OP_RETURN(op, I, asm_op, c_op, _db,         )		\
+	ATOMIC_OP_RETURN(op, I, asm_op, c_op,    , _relaxed)		\
+	ATOMIC_FETCH_OP(op, I, asm_op, _db,         )			\
+	ATOMIC_FETCH_OP(op, I, asm_op,    , _relaxed)
+
+ATOMIC_OPS(add, i, add, +)
+ATOMIC_OPS(sub, -i, add, +)
+
+#define arch_atomic_add_return		arch_atomic_add_return
+#define arch_atomic_add_return_acquire	arch_atomic_add_return
+#define arch_atomic_add_return_release	arch_atomic_add_return
+#define arch_atomic_add_return_relaxed	arch_atomic_add_return_relaxed
+#define arch_atomic_sub_return		arch_atomic_sub_return
+#define arch_atomic_sub_return_acquire	arch_atomic_sub_return
+#define arch_atomic_sub_return_release	arch_atomic_sub_return
+#define arch_atomic_sub_return_relaxed	arch_atomic_sub_return_relaxed
+#define arch_atomic_fetch_add		arch_atomic_fetch_add
+#define arch_atomic_fetch_add_acquire	arch_atomic_fetch_add
+#define arch_atomic_fetch_add_release	arch_atomic_fetch_add
+#define arch_atomic_fetch_add_relaxed	arch_atomic_fetch_add_relaxed
+#define arch_atomic_fetch_sub		arch_atomic_fetch_sub
+#define arch_atomic_fetch_sub_acquire	arch_atomic_fetch_sub
+#define arch_atomic_fetch_sub_release	arch_atomic_fetch_sub
+#define arch_atomic_fetch_sub_relaxed	arch_atomic_fetch_sub_relaxed
+
+#undef ATOMIC_OPS
+
+#define ATOMIC_OPS(op, I, asm_op)					\
+	ATOMIC_OP(op, I, asm_op)					\
+	ATOMIC_FETCH_OP(op, I, asm_op, _db,         )			\
+	ATOMIC_FETCH_OP(op, I, asm_op,    , _relaxed)
+
+ATOMIC_OPS(and, i, and)
+ATOMIC_OPS(or, i, or)
+ATOMIC_OPS(xor, i, xor)
+
+#define arch_atomic_fetch_and		arch_atomic_fetch_and
+#define arch_atomic_fetch_and_acquire	arch_atomic_fetch_and
+#define arch_atomic_fetch_and_release	arch_atomic_fetch_and
+#define arch_atomic_fetch_and_relaxed	arch_atomic_fetch_and_relaxed
+#define arch_atomic_fetch_or		arch_atomic_fetch_or
+#define arch_atomic_fetch_or_acquire	arch_atomic_fetch_or
+#define arch_atomic_fetch_or_release	arch_atomic_fetch_or
+#define arch_atomic_fetch_or_relaxed	arch_atomic_fetch_or_relaxed
+#define arch_atomic_fetch_xor		arch_atomic_fetch_xor
+#define arch_atomic_fetch_xor_acquire	arch_atomic_fetch_xor
+#define arch_atomic_fetch_xor_release	arch_atomic_fetch_xor
+#define arch_atomic_fetch_xor_relaxed	arch_atomic_fetch_xor_relaxed
+
+#undef ATOMIC_OPS
+#undef ATOMIC_FETCH_OP
+#undef ATOMIC_OP_RETURN
+#undef ATOMIC_OP
+
+#ifdef CONFIG_64BIT
+
+#define ATOMIC64_OP(op, I, asm_op)					\
+static inline void arch_atomic64_##op(long i, atomic64_t *v)		\
+{									\
+	__asm__ __volatile__(						\
+	"am"#asm_op".d " " $zero, %1, %0	\n"			\
+	: "+ZB" (v->counter)						\
+	: "r" (I)							\
+	: "memory");							\
+}
+
+#define ATOMIC64_OP_RETURN(op, I, asm_op, c_op, mb, suffix)			\
+static inline long arch_atomic64_##op##_return##suffix(long i, atomic64_t *v)	\
+{										\
+	long result;								\
+	__asm__ __volatile__(							\
+	"am"#asm_op#mb".d " " %1, %2, %0		\n"			\
+	: "+ZB" (v->counter), "=&r" (result)					\
+	: "r" (I)								\
+	: "memory");								\
+										\
+	return result c_op I;							\
+}
+
+#define ATOMIC64_FETCH_OP(op, I, asm_op, mb, suffix)				\
+static inline long arch_atomic64_fetch_##op##suffix(long i, atomic64_t *v)	\
+{										\
+	long result;								\
+										\
+	__asm__ __volatile__(							\
+	"am"#asm_op#mb".d " " %1, %2, %0		\n"			\
+	: "+ZB" (v->counter), "=&r" (result)					\
+	: "r" (I)								\
+	: "memory");								\
+										\
+	return result;								\
+}
+
+#define ATOMIC64_OPS(op, I, asm_op, c_op)				      \
+	ATOMIC64_OP(op, I, asm_op)					      \
+	ATOMIC64_OP_RETURN(op, I, asm_op, c_op, _db,         )		      \
+	ATOMIC64_OP_RETURN(op, I, asm_op, c_op,    , _relaxed)		      \
+	ATOMIC64_FETCH_OP(op, I, asm_op, _db,         )			      \
+	ATOMIC64_FETCH_OP(op, I, asm_op,    , _relaxed)
+
+ATOMIC64_OPS(add, i, add, +)
+ATOMIC64_OPS(sub, -i, add, +)
+
+#define arch_atomic64_add_return		arch_atomic64_add_return
+#define arch_atomic64_add_return_acquire	arch_atomic64_add_return
+#define arch_atomic64_add_return_release	arch_atomic64_add_return
+#define arch_atomic64_add_return_relaxed	arch_atomic64_add_return_relaxed
+#define arch_atomic64_sub_return		arch_atomic64_sub_return
+#define arch_atomic64_sub_return_acquire	arch_atomic64_sub_return
+#define arch_atomic64_sub_return_release	arch_atomic64_sub_return
+#define arch_atomic64_sub_return_relaxed	arch_atomic64_sub_return_relaxed
+#define arch_atomic64_fetch_add			arch_atomic64_fetch_add
+#define arch_atomic64_fetch_add_acquire		arch_atomic64_fetch_add
+#define arch_atomic64_fetch_add_release		arch_atomic64_fetch_add
+#define arch_atomic64_fetch_add_relaxed		arch_atomic64_fetch_add_relaxed
+#define arch_atomic64_fetch_sub			arch_atomic64_fetch_sub
+#define arch_atomic64_fetch_sub_acquire		arch_atomic64_fetch_sub
+#define arch_atomic64_fetch_sub_release		arch_atomic64_fetch_sub
+#define arch_atomic64_fetch_sub_relaxed		arch_atomic64_fetch_sub_relaxed
+
+#undef ATOMIC64_OPS
+
+#define ATOMIC64_OPS(op, I, asm_op)					      \
+	ATOMIC64_OP(op, I, asm_op)					      \
+	ATOMIC64_FETCH_OP(op, I, asm_op, _db,         )			      \
+	ATOMIC64_FETCH_OP(op, I, asm_op,    , _relaxed)
+
+ATOMIC64_OPS(and, i, and)
+ATOMIC64_OPS(or, i, or)
+ATOMIC64_OPS(xor, i, xor)
+
+#define arch_atomic64_fetch_and		arch_atomic64_fetch_and
+#define arch_atomic64_fetch_and_acquire	arch_atomic64_fetch_and
+#define arch_atomic64_fetch_and_release	arch_atomic64_fetch_and
+#define arch_atomic64_fetch_and_relaxed	arch_atomic64_fetch_and_relaxed
+#define arch_atomic64_fetch_or		arch_atomic64_fetch_or
+#define arch_atomic64_fetch_or_acquire	arch_atomic64_fetch_or
+#define arch_atomic64_fetch_or_release	arch_atomic64_fetch_or
+#define arch_atomic64_fetch_or_relaxed	arch_atomic64_fetch_or_relaxed
+#define arch_atomic64_fetch_xor		arch_atomic64_fetch_xor
+#define arch_atomic64_fetch_xor_acquire	arch_atomic64_fetch_xor
+#define arch_atomic64_fetch_xor_release	arch_atomic64_fetch_xor
+#define arch_atomic64_fetch_xor_relaxed	arch_atomic64_fetch_xor_relaxed
+
+#undef ATOMIC64_OPS
+#undef ATOMIC64_FETCH_OP
+#undef ATOMIC64_OP_RETURN
+#undef ATOMIC64_OP
+
+#endif
+
+#endif /* _ASM_ATOMIC_AMO_H */
diff --git a/arch/loongarch/include/asm/atomic-llsc.h b/arch/loongarch/include/asm/atomic-llsc.h
new file mode 100644
index 000000000000..b4f5670b85cf
--- /dev/null
+++ b/arch/loongarch/include/asm/atomic-llsc.h
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Atomic operations (LLSC).
+ *
+ * Copyright (C) 2024-2025 Loongson Technology Corporation Limited
+ */
+
+#ifndef _ASM_ATOMIC_LLSC_H
+#define _ASM_ATOMIC_LLSC_H
+
+#include <linux/types.h>
+#include <asm/barrier.h>
+#include <asm/cmpxchg.h>
+
+#define ATOMIC_OP(op, I, asm_op)					\
+static inline void arch_atomic_##op(int i, atomic_t *v)			\
+{									\
+	int temp;							\
+									\
+	__asm__ __volatile__(						\
+	"1:	ll.w		%0, %1      #atomic_" #op "	\n"	\
+	"       " #asm_op "	%0, %0, %2			\n"	\
+	"	sc.w		%0, %1				\n"	\
+	"       beq		%0, $r0, 1b			\n"	\
+	:"=&r" (temp) , "+ZB"(v->counter)				\
+	:"r" (I)							\
+	);								\
+}
+
+#define ATOMIC_OP_RETURN(op, I, asm_op)					\
+static inline int arch_atomic_##op##_return_relaxed(int i, atomic_t *v)	\
+{									\
+	int result, temp;						\
+									\
+	__asm__ __volatile__(						\
+	"1:     ll.w		%1, %2      # atomic_" #op "_return \n"	\
+	"       " #asm_op "	%0, %1, %3                          \n"	\
+	"       sc.w		%0, %2                              \n"	\
+	"       beq		%0, $r0 ,1b                         \n"	\
+	"       " #asm_op "	%0, %1, %3                          \n"	\
+	: "=&r" (result), "=&r" (temp),	"+ZB"(v->counter)		\
+	: "r" (I));							\
+									\
+	return result;							\
+}
+
+#define ATOMIC_FETCH_OP(op, I, asm_op)					\
+static inline int arch_atomic_fetch_##op##_relaxed(int i, atomic_t *v)	\
+{									\
+	int result, temp;						\
+									\
+	__asm__ __volatile__(						\
+	"1:     ll.w		%1, %2      # atomic_fetch_" #op "  \n"	\
+	"       " #asm_op "	%0, %1, %3                          \n" \
+	"       sc.w		%0, %2                              \n"	\
+	"       beq		%0, $r0 ,1b                         \n"	\
+	"       add.w		%0, %1  ,$r0                        \n"	\
+	: "=&r" (result), "=&r" (temp), "+ZB" (v->counter)		\
+	: "r" (I));							\
+									\
+	return result;							\
+}
+
+#define ATOMIC_OPS(op,I ,asm_op, c_op)					\
+	ATOMIC_OP(op, I, asm_op)					\
+	ATOMIC_OP_RETURN(op, I , asm_op)				\
+	ATOMIC_FETCH_OP(op, I, asm_op)
+
+ATOMIC_OPS(add, i , add.w ,+=)
+ATOMIC_OPS(sub, -i , add.w ,+=)
+
+#define arch_atomic_add_return_relaxed	arch_atomic_add_return_relaxed
+#define arch_atomic_sub_return_relaxed	arch_atomic_sub_return_relaxed
+#define arch_atomic_fetch_add_relaxed	arch_atomic_fetch_add_relaxed
+#define arch_atomic_fetch_sub_relaxed	arch_atomic_fetch_sub_relaxed
+
+#undef ATOMIC_OPS
+
+#define ATOMIC_OPS(op, I, asm_op)					\
+	ATOMIC_OP(op, I, asm_op)					\
+	ATOMIC_FETCH_OP(op, I, asm_op)
+
+ATOMIC_OPS(and, i, and)
+ATOMIC_OPS(or, i, or)
+ATOMIC_OPS(xor, i, xor)
+
+#define arch_atomic_fetch_and_relaxed	arch_atomic_fetch_and_relaxed
+#define arch_atomic_fetch_or_relaxed	arch_atomic_fetch_or_relaxed
+#define arch_atomic_fetch_xor_relaxed	arch_atomic_fetch_xor_relaxed
+
+#undef ATOMIC_OPS
+#undef ATOMIC_FETCH_OP
+#undef ATOMIC_OP_RETURN
+#undef ATOMIC_OP
+
+#ifdef CONFIG_64BIT
+#error "64-bit LLSC atomic operations are not supported"
+#endif
+
+#endif /* _ASM_ATOMIC_LLSC_H */
diff --git a/arch/loongarch/include/asm/atomic.h b/arch/loongarch/include/asm/atomic.h
index c86f0ab922ec..444b9ddcd004 100644
--- a/arch/loongarch/include/asm/atomic.h
+++ b/arch/loongarch/include/asm/atomic.h
@@ -11,6 +11,16 @@
 #include <asm/barrier.h>
 #include <asm/cmpxchg.h>
 
+#ifdef CONFIG_CPU_HAS_AMO
+#include <asm/atomic-amo.h>
+#else
+#include <asm/atomic-llsc.h>
+#endif
+
+#ifdef CONFIG_GENERIC_ATOMIC64
+#include <asm-generic/atomic64.h>
+#endif
+
 #if __SIZEOF_LONG__ == 4
 #define __LL		"ll.w	"
 #define __SC		"sc.w	"
@@ -34,100 +44,6 @@
 #define arch_atomic_read(v)	READ_ONCE((v)->counter)
 #define arch_atomic_set(v, i)	WRITE_ONCE((v)->counter, (i))
 
-#define ATOMIC_OP(op, I, asm_op)					\
-static inline void arch_atomic_##op(int i, atomic_t *v)			\
-{									\
-	__asm__ __volatile__(						\
-	"am"#asm_op".w" " $zero, %1, %0	\n"				\
-	: "+ZB" (v->counter)						\
-	: "r" (I)							\
-	: "memory");							\
-}
-
-#define ATOMIC_OP_RETURN(op, I, asm_op, c_op, mb, suffix)		\
-static inline int arch_atomic_##op##_return##suffix(int i, atomic_t *v)	\
-{									\
-	int result;							\
-									\
-	__asm__ __volatile__(						\
-	"am"#asm_op#mb".w" " %1, %2, %0		\n"			\
-	: "+ZB" (v->counter), "=&r" (result)				\
-	: "r" (I)							\
-	: "memory");							\
-									\
-	return result c_op I;						\
-}
-
-#define ATOMIC_FETCH_OP(op, I, asm_op, mb, suffix)			\
-static inline int arch_atomic_fetch_##op##suffix(int i, atomic_t *v)	\
-{									\
-	int result;							\
-									\
-	__asm__ __volatile__(						\
-	"am"#asm_op#mb".w" " %1, %2, %0		\n"			\
-	: "+ZB" (v->counter), "=&r" (result)				\
-	: "r" (I)							\
-	: "memory");							\
-									\
-	return result;							\
-}
-
-#define ATOMIC_OPS(op, I, asm_op, c_op)					\
-	ATOMIC_OP(op, I, asm_op)					\
-	ATOMIC_OP_RETURN(op, I, asm_op, c_op, _db,         )		\
-	ATOMIC_OP_RETURN(op, I, asm_op, c_op,    , _relaxed)		\
-	ATOMIC_FETCH_OP(op, I, asm_op, _db,         )			\
-	ATOMIC_FETCH_OP(op, I, asm_op,    , _relaxed)
-
-ATOMIC_OPS(add, i, add, +)
-ATOMIC_OPS(sub, -i, add, +)
-
-#define arch_atomic_add_return		arch_atomic_add_return
-#define arch_atomic_add_return_acquire	arch_atomic_add_return
-#define arch_atomic_add_return_release	arch_atomic_add_return
-#define arch_atomic_add_return_relaxed	arch_atomic_add_return_relaxed
-#define arch_atomic_sub_return		arch_atomic_sub_return
-#define arch_atomic_sub_return_acquire	arch_atomic_sub_return
-#define arch_atomic_sub_return_release	arch_atomic_sub_return
-#define arch_atomic_sub_return_relaxed	arch_atomic_sub_return_relaxed
-#define arch_atomic_fetch_add		arch_atomic_fetch_add
-#define arch_atomic_fetch_add_acquire	arch_atomic_fetch_add
-#define arch_atomic_fetch_add_release	arch_atomic_fetch_add
-#define arch_atomic_fetch_add_relaxed	arch_atomic_fetch_add_relaxed
-#define arch_atomic_fetch_sub		arch_atomic_fetch_sub
-#define arch_atomic_fetch_sub_acquire	arch_atomic_fetch_sub
-#define arch_atomic_fetch_sub_release	arch_atomic_fetch_sub
-#define arch_atomic_fetch_sub_relaxed	arch_atomic_fetch_sub_relaxed
-
-#undef ATOMIC_OPS
-
-#define ATOMIC_OPS(op, I, asm_op)					\
-	ATOMIC_OP(op, I, asm_op)					\
-	ATOMIC_FETCH_OP(op, I, asm_op, _db,         )			\
-	ATOMIC_FETCH_OP(op, I, asm_op,    , _relaxed)
-
-ATOMIC_OPS(and, i, and)
-ATOMIC_OPS(or, i, or)
-ATOMIC_OPS(xor, i, xor)
-
-#define arch_atomic_fetch_and		arch_atomic_fetch_and
-#define arch_atomic_fetch_and_acquire	arch_atomic_fetch_and
-#define arch_atomic_fetch_and_release	arch_atomic_fetch_and
-#define arch_atomic_fetch_and_relaxed	arch_atomic_fetch_and_relaxed
-#define arch_atomic_fetch_or		arch_atomic_fetch_or
-#define arch_atomic_fetch_or_acquire	arch_atomic_fetch_or
-#define arch_atomic_fetch_or_release	arch_atomic_fetch_or
-#define arch_atomic_fetch_or_relaxed	arch_atomic_fetch_or_relaxed
-#define arch_atomic_fetch_xor		arch_atomic_fetch_xor
-#define arch_atomic_fetch_xor_acquire	arch_atomic_fetch_xor
-#define arch_atomic_fetch_xor_release	arch_atomic_fetch_xor
-#define arch_atomic_fetch_xor_relaxed	arch_atomic_fetch_xor_relaxed
-
-#undef ATOMIC_OPS
-#undef ATOMIC_FETCH_OP
-#undef ATOMIC_OP_RETURN
-#undef ATOMIC_OP
-
 static inline int arch_atomic_fetch_add_unless(atomic_t *v, int a, int u)
 {
        int prev, rc;
@@ -194,99 +110,6 @@ static inline int arch_atomic_sub_if_positive(int i, atomic_t *v)
 #define arch_atomic64_read(v)	READ_ONCE((v)->counter)
 #define arch_atomic64_set(v, i)	WRITE_ONCE((v)->counter, (i))
 
-#define ATOMIC64_OP(op, I, asm_op)					\
-static inline void arch_atomic64_##op(long i, atomic64_t *v)		\
-{									\
-	__asm__ __volatile__(						\
-	"am"#asm_op".d " " $zero, %1, %0	\n"			\
-	: "+ZB" (v->counter)						\
-	: "r" (I)							\
-	: "memory");							\
-}
-
-#define ATOMIC64_OP_RETURN(op, I, asm_op, c_op, mb, suffix)			\
-static inline long arch_atomic64_##op##_return##suffix(long i, atomic64_t *v)	\
-{										\
-	long result;								\
-	__asm__ __volatile__(							\
-	"am"#asm_op#mb".d " " %1, %2, %0		\n"			\
-	: "+ZB" (v->counter), "=&r" (result)					\
-	: "r" (I)								\
-	: "memory");								\
-										\
-	return result c_op I;							\
-}
-
-#define ATOMIC64_FETCH_OP(op, I, asm_op, mb, suffix)				\
-static inline long arch_atomic64_fetch_##op##suffix(long i, atomic64_t *v)	\
-{										\
-	long result;								\
-										\
-	__asm__ __volatile__(							\
-	"am"#asm_op#mb".d " " %1, %2, %0		\n"			\
-	: "+ZB" (v->counter), "=&r" (result)					\
-	: "r" (I)								\
-	: "memory");								\
-										\
-	return result;								\
-}
-
-#define ATOMIC64_OPS(op, I, asm_op, c_op)				      \
-	ATOMIC64_OP(op, I, asm_op)					      \
-	ATOMIC64_OP_RETURN(op, I, asm_op, c_op, _db,         )		      \
-	ATOMIC64_OP_RETURN(op, I, asm_op, c_op,    , _relaxed)		      \
-	ATOMIC64_FETCH_OP(op, I, asm_op, _db,         )			      \
-	ATOMIC64_FETCH_OP(op, I, asm_op,    , _relaxed)
-
-ATOMIC64_OPS(add, i, add, +)
-ATOMIC64_OPS(sub, -i, add, +)
-
-#define arch_atomic64_add_return		arch_atomic64_add_return
-#define arch_atomic64_add_return_acquire	arch_atomic64_add_return
-#define arch_atomic64_add_return_release	arch_atomic64_add_return
-#define arch_atomic64_add_return_relaxed	arch_atomic64_add_return_relaxed
-#define arch_atomic64_sub_return		arch_atomic64_sub_return
-#define arch_atomic64_sub_return_acquire	arch_atomic64_sub_return
-#define arch_atomic64_sub_return_release	arch_atomic64_sub_return
-#define arch_atomic64_sub_return_relaxed	arch_atomic64_sub_return_relaxed
-#define arch_atomic64_fetch_add			arch_atomic64_fetch_add
-#define arch_atomic64_fetch_add_acquire		arch_atomic64_fetch_add
-#define arch_atomic64_fetch_add_release		arch_atomic64_fetch_add
-#define arch_atomic64_fetch_add_relaxed		arch_atomic64_fetch_add_relaxed
-#define arch_atomic64_fetch_sub			arch_atomic64_fetch_sub
-#define arch_atomic64_fetch_sub_acquire		arch_atomic64_fetch_sub
-#define arch_atomic64_fetch_sub_release		arch_atomic64_fetch_sub
-#define arch_atomic64_fetch_sub_relaxed		arch_atomic64_fetch_sub_relaxed
-
-#undef ATOMIC64_OPS
-
-#define ATOMIC64_OPS(op, I, asm_op)					      \
-	ATOMIC64_OP(op, I, asm_op)					      \
-	ATOMIC64_FETCH_OP(op, I, asm_op, _db,         )			      \
-	ATOMIC64_FETCH_OP(op, I, asm_op,    , _relaxed)
-
-ATOMIC64_OPS(and, i, and)
-ATOMIC64_OPS(or, i, or)
-ATOMIC64_OPS(xor, i, xor)
-
-#define arch_atomic64_fetch_and		arch_atomic64_fetch_and
-#define arch_atomic64_fetch_and_acquire	arch_atomic64_fetch_and
-#define arch_atomic64_fetch_and_release	arch_atomic64_fetch_and
-#define arch_atomic64_fetch_and_relaxed	arch_atomic64_fetch_and_relaxed
-#define arch_atomic64_fetch_or		arch_atomic64_fetch_or
-#define arch_atomic64_fetch_or_acquire	arch_atomic64_fetch_or
-#define arch_atomic64_fetch_or_release	arch_atomic64_fetch_or
-#define arch_atomic64_fetch_or_relaxed	arch_atomic64_fetch_or_relaxed
-#define arch_atomic64_fetch_xor		arch_atomic64_fetch_xor
-#define arch_atomic64_fetch_xor_acquire	arch_atomic64_fetch_xor
-#define arch_atomic64_fetch_xor_release	arch_atomic64_fetch_xor
-#define arch_atomic64_fetch_xor_relaxed	arch_atomic64_fetch_xor_relaxed
-
-#undef ATOMIC64_OPS
-#undef ATOMIC64_FETCH_OP
-#undef ATOMIC64_OP_RETURN
-#undef ATOMIC64_OP
-
 static inline long arch_atomic64_fetch_add_unless(atomic64_t *v, long a, long u)
 {
        long prev, rc;
diff --git a/arch/loongarch/include/asm/cmpxchg.h b/arch/loongarch/include/asm/cmpxchg.h
index 979fde61bba8..0494c2ab553e 100644
--- a/arch/loongarch/include/asm/cmpxchg.h
+++ b/arch/loongarch/include/asm/cmpxchg.h
@@ -9,17 +9,33 @@
 #include <linux/build_bug.h>
 #include <asm/barrier.h>
 
-#define __xchg_asm(amswap_db, m, val)		\
+#define __xchg_amo_asm(amswap_db, m, val)	\
 ({						\
-		__typeof(val) __ret;		\
+	__typeof(val) __ret;			\
 						\
-		__asm__ __volatile__ (		\
-		" "amswap_db" %1, %z2, %0 \n"	\
-		: "+ZB" (*m), "=&r" (__ret)	\
-		: "Jr" (val)			\
-		: "memory");			\
+	__asm__ __volatile__ (			\
+	" "amswap_db" %1, %z2, %0 \n"		\
+	: "+ZB" (*m), "=&r" (__ret)		\
+	: "Jr" (val)				\
+	: "memory");				\
 						\
-		__ret;				\
+	__ret;					\
+})
+
+#define __xchg_llsc_asm(ld, st, m, val)			\
+({							\
+	__typeof(val) __ret, __tmp;			\
+							\
+	asm volatile (					\
+	"1:	ll.w	%0, %3		\n"		\
+	"	move	%1, %z4		\n"		\
+	"	sc.w	%1, %2		\n"		\
+	"	beqz	%1, 1b		\n"		\
+	: "=&r" (__ret), "=&r" (__tmp), "=ZC" (*m)	\
+	: "ZC" (*m), "Jr" (val)				\
+	: "memory");					\
+							\
+	__ret;						\
 })
 
 static inline unsigned int __xchg_small(volatile void *ptr, unsigned int val,
@@ -67,13 +83,23 @@ __arch_xchg(volatile void *ptr, unsigned long x, int size)
 	switch (size) {
 	case 1:
 	case 2:
-		return __xchg_small(ptr, x, size);
+		return __xchg_small((volatile void *)ptr, x, size);
 
 	case 4:
-		return __xchg_asm("amswap_db.w", (volatile u32 *)ptr, (u32)x);
+#ifdef CONFIG_CPU_HAS_AMO
+		return __xchg_amo_asm("amswap_db.w", (volatile u32 *)ptr, (u32)x);
+#else
+		return __xchg_llsc_asm("ll.w", "sc.w", (volatile u32 *)ptr, (u32)x);
+#endif /* CONFIG_CPU_HAS_AMO */
 
+#ifdef CONFIG_64BIT
 	case 8:
-		return __xchg_asm("amswap_db.d", (volatile u64 *)ptr, (u64)x);
+#ifdef CONFIG_CPU_HAS_AMO
+		return __xchg_amo_asm("amswap_db.d", (volatile u64 *)ptr, (u64)x);
+#else
+		return __xchg_llsc_asm("ll.d", "sc.d", (volatile u64 *)ptr, (u64)x);
+#endif /* CONFIG_CPU_HAS_AMO */
+#endif /* CONFIG_64BIT */
 
 	default:
 		BUILD_BUG();
diff --git a/arch/loongarch/include/asm/local.h b/arch/loongarch/include/asm/local.h
index f53ea653af76..65ace8e4350a 100644
--- a/arch/loongarch/include/asm/local.h
+++ b/arch/loongarch/include/asm/local.h
@@ -8,6 +8,7 @@
 #include <linux/percpu.h>
 #include <linux/bitops.h>
 #include <linux/atomic.h>
+#include <asm/asm.h>
 #include <asm/cmpxchg.h>
 
 typedef struct {
@@ -27,6 +28,7 @@ typedef struct {
 /*
  * Same as above, but return the result value
  */
+#ifdef CONFIG_CPU_HAS_AMO
 static inline long local_add_return(long i, local_t *l)
 {
 	unsigned long result;
@@ -55,6 +57,41 @@ static inline long local_sub_return(long i, local_t *l)
 
 	return result;
 }
+#else
+static inline long local_add_return(long i, local_t * l)
+{
+        unsigned long result, temp;
+
+        __asm__ __volatile__(
+        "1:"    __LL    "%1, %2         # local_add_return      \n"
+        __stringify(LONG_ADD) "   %0, %1, %3                    \n"
+                __SC    "%0, %2                                 \n"
+        "       beq     %0, $r0, 1b                             \n"
+        __stringify(LONG_ADD) "   %0, %1, %3                    \n"
+        : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
+        : "r" (i), "m" (l->a.counter)
+        : "memory");
+
+        return result;
+}
+
+static inline long local_sub_return(long i, local_t * l)
+{
+        unsigned long result, temp;
+
+        __asm__ __volatile__(
+        "1:"    __LL    "%1, %2         # local_sub_return      \n"
+        __stringify(LONG_SUB) "   %0, %1, %3                    \n"
+                __SC    "%0, %2                                 \n"
+        "       beq     %0, $r0, 1b                             \n"
+	__stringify(LONG_SUB) "   %0, %1, %3                    \n"
+        : "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
+        : "r" (i), "m" (l->a.counter)
+        : "memory");
+
+        return result;
+}
+#endif
 
 static inline long local_cmpxchg(local_t *l, long old, long new)
 {
diff --git a/arch/loongarch/include/asm/percpu.h b/arch/loongarch/include/asm/percpu.h
index 87be9b14e9da..1619c1d15e6b 100644
--- a/arch/loongarch/include/asm/percpu.h
+++ b/arch/loongarch/include/asm/percpu.h
@@ -36,6 +36,8 @@ static inline void set_my_cpu_offset(unsigned long off)
 	__my_cpu_offset;				\
 })
 
+#ifdef CONFIG_CPU_HAS_AMO
+
 #define PERCPU_OP(op, asm_op, c_op)					\
 static __always_inline unsigned long __percpu_##op(void *ptr,		\
 			unsigned long val, int size)			\
@@ -68,25 +70,9 @@ PERCPU_OP(and, and, &)
 PERCPU_OP(or, or, |)
 #undef PERCPU_OP
 
-static __always_inline unsigned long __percpu_xchg(void *ptr, unsigned long val, int size)
-{
-	switch (size) {
-	case 1:
-	case 2:
-		return __xchg_small((volatile void *)ptr, val, size);
-
-	case 4:
-		return __xchg_asm("amswap.w", (volatile u32 *)ptr, (u32)val);
-
-	case 8:
-		return __xchg_asm("amswap.d", (volatile u64 *)ptr, (u64)val);
+#endif
 
-	default:
-		BUILD_BUG();
-	}
-
-	return 0;
-}
+#ifdef CONFIG_64BIT
 
 #define __pcpu_op_1(op)		op ".b "
 #define __pcpu_op_2(op)		op ".h "
@@ -115,6 +101,10 @@ do {									\
 		: "memory");						\
 } while (0)
 
+#endif
+
+#define __percpu_xchg __arch_xchg
+
 /* this_cpu_cmpxchg */
 #define _protect_cmpxchg_local(pcp, o, n)			\
 ({								\
@@ -135,6 +125,8 @@ do {									\
 	__retval;						\
 })
 
+#ifdef CONFIG_CPU_HAS_AMO
+
 #define _percpu_add(pcp, val) \
 	_pcp_protect(__percpu_add, pcp, val)
 
@@ -146,9 +138,6 @@ do {									\
 #define _percpu_or(pcp, val) \
 	_pcp_protect(__percpu_or, pcp, val)
 
-#define _percpu_xchg(pcp, val) ((typeof(pcp)) \
-	_pcp_protect(__percpu_xchg, pcp, (unsigned long)(val)))
-
 #define this_cpu_add_4(pcp, val) _percpu_add(pcp, val)
 #define this_cpu_add_8(pcp, val) _percpu_add(pcp, val)
 
@@ -161,6 +150,10 @@ do {									\
 #define this_cpu_or_4(pcp, val) _percpu_or(pcp, val)
 #define this_cpu_or_8(pcp, val) _percpu_or(pcp, val)
 
+#endif
+
+#ifdef CONFIG_64BIT
+
 #define this_cpu_read_1(pcp) _percpu_read(1, pcp)
 #define this_cpu_read_2(pcp) _percpu_read(2, pcp)
 #define this_cpu_read_4(pcp) _percpu_read(4, pcp)
@@ -171,6 +164,11 @@ do {									\
 #define this_cpu_write_4(pcp, val) _percpu_write(4, pcp, val)
 #define this_cpu_write_8(pcp, val) _percpu_write(8, pcp, val)
 
+#endif
+
+#define _percpu_xchg(pcp, val) ((typeof(pcp)) \
+	_pcp_protect(__percpu_xchg, pcp, (unsigned long)(val)))
+
 #define this_cpu_xchg_1(pcp, val) _percpu_xchg(pcp, val)
 #define this_cpu_xchg_2(pcp, val) _percpu_xchg(pcp, val)
 #define this_cpu_xchg_4(pcp, val) _percpu_xchg(pcp, val)
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH V2 02/14] LoongArch: Add adaptive CSR accessors for 32BIT/64BIT
  2025-11-18 11:27 [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Huacai Chen
  2025-11-18 11:27 ` [PATCH V2 01/14] LoongArch: Add atomic operations for 32BIT/64BIT Huacai Chen
@ 2025-11-18 11:27 ` Huacai Chen
  2025-11-18 11:27 ` [PATCH V2 03/14] LoongArch: Adjust common macro definitions " Huacai Chen
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 37+ messages in thread
From: Huacai Chen @ 2025-11-18 11:27 UTC (permalink / raw)
  To: Arnd Bergmann, Huacai Chen
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Xuerui Wang,
	Jiaxun Yang, linux-kernel, Huacai Chen

32BIT platforms only have 32bit CSR/IOCSR registers, 64BIT platforms
have both 32bit/64bit CSR/IOCSR registers. Now there are both 32bit and
64bit CSR accessors:

csr_read32()/csr_write32()/csr_xchg32();
csr_read64()/csr_write64()/csr_xchg64();

Some CSR registers (address and timer registers) are 32bit length on
32BIT platform and 64bit length on 64BIT platform. To avoid #ifdefs here
and there, they need adaptive accessors, so we define and use:

csr_read()/csr_write()/csr_xchg();

IOCSR doesn't have a "natural length", which means a 64bit register can
be treated as two 32bit registers, so we just use two 32bit accessors to
emulate a 64bit accessors.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
 arch/loongarch/include/asm/loongarch.h   | 46 +++++++++++++++---------
 arch/loongarch/include/asm/percpu.h      |  2 +-
 arch/loongarch/kernel/cpu-probe.c        | 17 +++++++--
 arch/loongarch/kernel/time.c             | 16 ++++-----
 arch/loongarch/kernel/traps.c            | 15 ++++----
 arch/loongarch/lib/dump_tlb.c            |  6 ++--
 arch/loongarch/mm/tlb.c                  | 10 +++---
 arch/loongarch/power/hibernate.c         |  6 ++--
 arch/loongarch/power/suspend.c           | 24 ++++++-------
 drivers/firmware/efi/libstub/loongarch.c |  8 ++---
 10 files changed, 88 insertions(+), 62 deletions(-)

diff --git a/arch/loongarch/include/asm/loongarch.h b/arch/loongarch/include/asm/loongarch.h
index 3de03cb864b2..9f71a79271da 100644
--- a/arch/loongarch/include/asm/loongarch.h
+++ b/arch/loongarch/include/asm/loongarch.h
@@ -182,6 +182,16 @@
 #define csr_xchg32(val, mask, reg) __csrxchg_w(val, mask, reg)
 #define csr_xchg64(val, mask, reg) __csrxchg_d(val, mask, reg)
 
+#ifdef CONFIG_32BIT
+#define csr_read(reg) csr_read32(reg)
+#define csr_write(val, reg) csr_write32(val, reg)
+#define csr_xchg(val, mask, reg) csr_xchg32(val, mask, reg)
+#else
+#define csr_read(reg) csr_read64(reg)
+#define csr_write(val, reg) csr_write64(val, reg)
+#define csr_xchg(val, mask, reg) csr_xchg64(val, mask, reg)
+#endif
+
 /* IOCSR */
 #define iocsr_read32(reg) __iocsrrd_w(reg)
 #define iocsr_read64(reg) __iocsrrd_d(reg)
@@ -1223,6 +1233,7 @@ static inline unsigned int get_csr_cpuid(void)
 	return csr_read32(LOONGARCH_CSR_CPUID);
 }
 
+#ifdef CONFIG_64BIT
 static inline void csr_any_send(unsigned int addr, unsigned int data,
 				unsigned int data_mask, unsigned int cpu)
 {
@@ -1234,6 +1245,7 @@ static inline void csr_any_send(unsigned int addr, unsigned int data,
 	val |= ((uint64_t)data << IOCSR_ANY_SEND_BUF_SHIFT);
 	iocsr_write64(val, LOONGARCH_IOCSR_ANY_SEND);
 }
+#endif
 
 static inline unsigned int read_csr_excode(void)
 {
@@ -1257,22 +1269,22 @@ static inline void write_csr_pagesize(unsigned int size)
 
 static inline unsigned int read_csr_tlbrefill_pagesize(void)
 {
-	return (csr_read64(LOONGARCH_CSR_TLBREHI) & CSR_TLBREHI_PS) >> CSR_TLBREHI_PS_SHIFT;
+	return (csr_read(LOONGARCH_CSR_TLBREHI) & CSR_TLBREHI_PS) >> CSR_TLBREHI_PS_SHIFT;
 }
 
 static inline void write_csr_tlbrefill_pagesize(unsigned int size)
 {
-	csr_xchg64(size << CSR_TLBREHI_PS_SHIFT, CSR_TLBREHI_PS, LOONGARCH_CSR_TLBREHI);
+	csr_xchg(size << CSR_TLBREHI_PS_SHIFT, CSR_TLBREHI_PS, LOONGARCH_CSR_TLBREHI);
 }
 
 #define read_csr_asid()			csr_read32(LOONGARCH_CSR_ASID)
 #define write_csr_asid(val)		csr_write32(val, LOONGARCH_CSR_ASID)
-#define read_csr_entryhi()		csr_read64(LOONGARCH_CSR_TLBEHI)
-#define write_csr_entryhi(val)		csr_write64(val, LOONGARCH_CSR_TLBEHI)
-#define read_csr_entrylo0()		csr_read64(LOONGARCH_CSR_TLBELO0)
-#define write_csr_entrylo0(val)		csr_write64(val, LOONGARCH_CSR_TLBELO0)
-#define read_csr_entrylo1()		csr_read64(LOONGARCH_CSR_TLBELO1)
-#define write_csr_entrylo1(val)		csr_write64(val, LOONGARCH_CSR_TLBELO1)
+#define read_csr_entryhi()		csr_read(LOONGARCH_CSR_TLBEHI)
+#define write_csr_entryhi(val)		csr_write(val, LOONGARCH_CSR_TLBEHI)
+#define read_csr_entrylo0()		csr_read(LOONGARCH_CSR_TLBELO0)
+#define write_csr_entrylo0(val)		csr_write(val, LOONGARCH_CSR_TLBELO0)
+#define read_csr_entrylo1()		csr_read(LOONGARCH_CSR_TLBELO1)
+#define write_csr_entrylo1(val)		csr_write(val, LOONGARCH_CSR_TLBELO1)
 #define read_csr_ecfg()			csr_read32(LOONGARCH_CSR_ECFG)
 #define write_csr_ecfg(val)		csr_write32(val, LOONGARCH_CSR_ECFG)
 #define read_csr_estat()		csr_read32(LOONGARCH_CSR_ESTAT)
@@ -1282,20 +1294,20 @@ static inline void write_csr_tlbrefill_pagesize(unsigned int size)
 #define read_csr_euen()			csr_read32(LOONGARCH_CSR_EUEN)
 #define write_csr_euen(val)		csr_write32(val, LOONGARCH_CSR_EUEN)
 #define read_csr_cpuid()		csr_read32(LOONGARCH_CSR_CPUID)
-#define read_csr_prcfg1()		csr_read64(LOONGARCH_CSR_PRCFG1)
-#define write_csr_prcfg1(val)		csr_write64(val, LOONGARCH_CSR_PRCFG1)
-#define read_csr_prcfg2()		csr_read64(LOONGARCH_CSR_PRCFG2)
-#define write_csr_prcfg2(val)		csr_write64(val, LOONGARCH_CSR_PRCFG2)
-#define read_csr_prcfg3()		csr_read64(LOONGARCH_CSR_PRCFG3)
-#define write_csr_prcfg3(val)		csr_write64(val, LOONGARCH_CSR_PRCFG3)
+#define read_csr_prcfg1()		csr_read(LOONGARCH_CSR_PRCFG1)
+#define write_csr_prcfg1(val)		csr_write(val, LOONGARCH_CSR_PRCFG1)
+#define read_csr_prcfg2()		csr_read(LOONGARCH_CSR_PRCFG2)
+#define write_csr_prcfg2(val)		csr_write(val, LOONGARCH_CSR_PRCFG2)
+#define read_csr_prcfg3()		csr_read(LOONGARCH_CSR_PRCFG3)
+#define write_csr_prcfg3(val)		csr_write(val, LOONGARCH_CSR_PRCFG3)
 #define read_csr_stlbpgsize()		csr_read32(LOONGARCH_CSR_STLBPGSIZE)
 #define write_csr_stlbpgsize(val)	csr_write32(val, LOONGARCH_CSR_STLBPGSIZE)
 #define read_csr_rvacfg()		csr_read32(LOONGARCH_CSR_RVACFG)
 #define write_csr_rvacfg(val)		csr_write32(val, LOONGARCH_CSR_RVACFG)
 #define write_csr_tintclear(val)	csr_write32(val, LOONGARCH_CSR_TINTCLR)
-#define read_csr_impctl1()		csr_read64(LOONGARCH_CSR_IMPCTL1)
-#define write_csr_impctl1(val)		csr_write64(val, LOONGARCH_CSR_IMPCTL1)
-#define write_csr_impctl2(val)		csr_write64(val, LOONGARCH_CSR_IMPCTL2)
+#define read_csr_impctl1()		csr_read(LOONGARCH_CSR_IMPCTL1)
+#define write_csr_impctl1(val)		csr_write(val, LOONGARCH_CSR_IMPCTL1)
+#define write_csr_impctl2(val)		csr_write(val, LOONGARCH_CSR_IMPCTL2)
 
 #define read_csr_perfctrl0()		csr_read64(LOONGARCH_CSR_PERFCTRL0)
 #define read_csr_perfcntr0()		csr_read64(LOONGARCH_CSR_PERFCNTR0)
diff --git a/arch/loongarch/include/asm/percpu.h b/arch/loongarch/include/asm/percpu.h
index 1619c1d15e6b..44a8aea2b0e5 100644
--- a/arch/loongarch/include/asm/percpu.h
+++ b/arch/loongarch/include/asm/percpu.h
@@ -27,7 +27,7 @@ register unsigned long __my_cpu_offset __asm__("$r21");
 static inline void set_my_cpu_offset(unsigned long off)
 {
 	__my_cpu_offset = off;
-	csr_write64(off, PERCPU_BASE_KS);
+	csr_write(off, PERCPU_BASE_KS);
 }
 
 #define __my_cpu_offset					\
diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c
index 6f943d1391ff..97933e9e2aa3 100644
--- a/arch/loongarch/kernel/cpu-probe.c
+++ b/arch/loongarch/kernel/cpu-probe.c
@@ -314,11 +314,22 @@ static inline void cpu_probe_loongson(struct cpuinfo_loongarch *c, unsigned int
 	if (!cpu_has_iocsr)
 		return;
 
-	if (!__cpu_full_name[cpu])
-		__cpu_full_name[cpu] = cpu_full_name;
-
+#ifdef CONFIG_64BIT
 	*vendor = iocsr_read64(LOONGARCH_IOCSR_VENDOR);
 	*cpuname = iocsr_read64(LOONGARCH_IOCSR_CPUNAME);
+#else
+	*vendor = iocsr_read32(LOONGARCH_IOCSR_VENDOR) |
+		(u64)iocsr_read32(LOONGARCH_IOCSR_VENDOR + 4) << 32;
+	*cpuname = iocsr_read32(LOONGARCH_IOCSR_CPUNAME) |
+		(u64)iocsr_read32(LOONGARCH_IOCSR_CPUNAME + 4) << 32;
+#endif
+
+	if (!__cpu_full_name[cpu]) {
+		if (((char *)vendor)[0] == 0)
+			__cpu_full_name[cpu] = "Unknown";
+		else
+			__cpu_full_name[cpu] = cpu_full_name;
+	}
 
 	config = iocsr_read32(LOONGARCH_IOCSR_FEATURES);
 	if (config & IOCSRF_CSRIPI)
diff --git a/arch/loongarch/kernel/time.c b/arch/loongarch/kernel/time.c
index 6fb92cc1a4c9..1c31bf3a16ed 100644
--- a/arch/loongarch/kernel/time.c
+++ b/arch/loongarch/kernel/time.c
@@ -50,10 +50,10 @@ static int constant_set_state_oneshot(struct clock_event_device *evt)
 
 	raw_spin_lock(&state_lock);
 
-	timer_config = csr_read64(LOONGARCH_CSR_TCFG);
+	timer_config = csr_read(LOONGARCH_CSR_TCFG);
 	timer_config |= CSR_TCFG_EN;
 	timer_config &= ~CSR_TCFG_PERIOD;
-	csr_write64(timer_config, LOONGARCH_CSR_TCFG);
+	csr_write(timer_config, LOONGARCH_CSR_TCFG);
 
 	raw_spin_unlock(&state_lock);
 
@@ -70,7 +70,7 @@ static int constant_set_state_periodic(struct clock_event_device *evt)
 	period = const_clock_freq / HZ;
 	timer_config = period & CSR_TCFG_VAL;
 	timer_config |= (CSR_TCFG_PERIOD | CSR_TCFG_EN);
-	csr_write64(timer_config, LOONGARCH_CSR_TCFG);
+	csr_write(timer_config, LOONGARCH_CSR_TCFG);
 
 	raw_spin_unlock(&state_lock);
 
@@ -83,9 +83,9 @@ static int constant_set_state_shutdown(struct clock_event_device *evt)
 
 	raw_spin_lock(&state_lock);
 
-	timer_config = csr_read64(LOONGARCH_CSR_TCFG);
+	timer_config = csr_read(LOONGARCH_CSR_TCFG);
 	timer_config &= ~CSR_TCFG_EN;
-	csr_write64(timer_config, LOONGARCH_CSR_TCFG);
+	csr_write(timer_config, LOONGARCH_CSR_TCFG);
 
 	raw_spin_unlock(&state_lock);
 
@@ -98,7 +98,7 @@ static int constant_timer_next_event(unsigned long delta, struct clock_event_dev
 
 	delta &= CSR_TCFG_VAL;
 	timer_config = delta | CSR_TCFG_EN;
-	csr_write64(timer_config, LOONGARCH_CSR_TCFG);
+	csr_write(timer_config, LOONGARCH_CSR_TCFG);
 
 	return 0;
 }
@@ -137,7 +137,7 @@ void save_counter(void)
 void sync_counter(void)
 {
 	/* Ensure counter begin at 0 */
-	csr_write64(init_offset, LOONGARCH_CSR_CNTC);
+	csr_write(init_offset, LOONGARCH_CSR_CNTC);
 }
 
 int constant_clockevent_init(void)
@@ -235,7 +235,7 @@ void __init time_init(void)
 	else
 		const_clock_freq = calc_const_freq();
 
-	init_offset = -(drdtime() - csr_read64(LOONGARCH_CSR_CNTC));
+	init_offset = -(drdtime() - csr_read(LOONGARCH_CSR_CNTC));
 
 	constant_clockevent_init();
 	constant_clocksource_init();
diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c
index da5926fead4a..004b8ebf0051 100644
--- a/arch/loongarch/kernel/traps.c
+++ b/arch/loongarch/kernel/traps.c
@@ -625,7 +625,7 @@ asmlinkage void noinstr do_bce(struct pt_regs *regs)
 	bool user = user_mode(regs);
 	bool pie = regs_irqs_disabled(regs);
 	unsigned long era = exception_era(regs);
-	u64 badv = 0, lower = 0, upper = ULONG_MAX;
+	unsigned long badv = 0, lower = 0, upper = ULONG_MAX;
 	union loongarch_instruction insn;
 	irqentry_state_t state = irqentry_enter(regs);
 
@@ -1070,10 +1070,13 @@ asmlinkage void noinstr do_reserved(struct pt_regs *regs)
 
 asmlinkage void cache_parity_error(void)
 {
+	u32 merrctl = csr_read32(LOONGARCH_CSR_MERRCTL);
+	unsigned long merrera = csr_read(LOONGARCH_CSR_MERRERA);
+
 	/* For the moment, report the problem and hang. */
 	pr_err("Cache error exception:\n");
-	pr_err("csr_merrctl == %08x\n", csr_read32(LOONGARCH_CSR_MERRCTL));
-	pr_err("csr_merrera == %016lx\n", csr_read64(LOONGARCH_CSR_MERRERA));
+	pr_err("csr_merrctl == %08x\n", merrctl);
+	pr_err("csr_merrera == %016lx\n", merrera);
 	panic("Can't handle the cache error!");
 }
 
@@ -1130,9 +1133,9 @@ static void configure_exception_vector(void)
 	eentry    = (unsigned long)exception_handlers;
 	tlbrentry = (unsigned long)exception_handlers + 80*VECSIZE;
 
-	csr_write64(eentry, LOONGARCH_CSR_EENTRY);
-	csr_write64(__pa(eentry), LOONGARCH_CSR_MERRENTRY);
-	csr_write64(__pa(tlbrentry), LOONGARCH_CSR_TLBRENTRY);
+	csr_write(eentry, LOONGARCH_CSR_EENTRY);
+	csr_write(__pa(eentry), LOONGARCH_CSR_MERRENTRY);
+	csr_write(__pa(tlbrentry), LOONGARCH_CSR_TLBRENTRY);
 }
 
 void per_cpu_trap_init(int cpu)
diff --git a/arch/loongarch/lib/dump_tlb.c b/arch/loongarch/lib/dump_tlb.c
index 0b886a6e260f..116f21ea4e2c 100644
--- a/arch/loongarch/lib/dump_tlb.c
+++ b/arch/loongarch/lib/dump_tlb.c
@@ -20,9 +20,9 @@ void dump_tlb_regs(void)
 
 	pr_info("Index    : 0x%0x\n", read_csr_tlbidx());
 	pr_info("PageSize : 0x%0x\n", read_csr_pagesize());
-	pr_info("EntryHi  : 0x%0*lx\n", field, read_csr_entryhi());
-	pr_info("EntryLo0 : 0x%0*lx\n", field, read_csr_entrylo0());
-	pr_info("EntryLo1 : 0x%0*lx\n", field, read_csr_entrylo1());
+	pr_info("EntryHi  : 0x%0*lx\n", field, (unsigned long)read_csr_entryhi());
+	pr_info("EntryLo0 : 0x%0*lx\n", field, (unsigned long)read_csr_entrylo0());
+	pr_info("EntryLo1 : 0x%0*lx\n", field, (unsigned long)read_csr_entrylo1());
 }
 
 static void dump_tlb(int first, int last)
diff --git a/arch/loongarch/mm/tlb.c b/arch/loongarch/mm/tlb.c
index 3b427b319db2..6e474469e210 100644
--- a/arch/loongarch/mm/tlb.c
+++ b/arch/loongarch/mm/tlb.c
@@ -229,11 +229,11 @@ static void setup_ptwalker(void)
 	if (cpu_has_ptw)
 		pwctl1 |= CSR_PWCTL1_PTW;
 
-	csr_write64(pwctl0, LOONGARCH_CSR_PWCTL0);
-	csr_write64(pwctl1, LOONGARCH_CSR_PWCTL1);
-	csr_write64((long)swapper_pg_dir, LOONGARCH_CSR_PGDH);
-	csr_write64((long)invalid_pg_dir, LOONGARCH_CSR_PGDL);
-	csr_write64((long)smp_processor_id(), LOONGARCH_CSR_TMID);
+	csr_write(pwctl0, LOONGARCH_CSR_PWCTL0);
+	csr_write(pwctl1, LOONGARCH_CSR_PWCTL1);
+	csr_write((long)swapper_pg_dir, LOONGARCH_CSR_PGDH);
+	csr_write((long)invalid_pg_dir, LOONGARCH_CSR_PGDL);
+	csr_write((long)smp_processor_id(), LOONGARCH_CSR_TMID);
 }
 
 static void output_pgtable_bits_defines(void)
diff --git a/arch/loongarch/power/hibernate.c b/arch/loongarch/power/hibernate.c
index e7b7346592cb..817270410ef9 100644
--- a/arch/loongarch/power/hibernate.c
+++ b/arch/loongarch/power/hibernate.c
@@ -10,7 +10,7 @@ static u32 saved_crmd;
 static u32 saved_prmd;
 static u32 saved_euen;
 static u32 saved_ecfg;
-static u64 saved_pcpu_base;
+static unsigned long saved_pcpu_base;
 struct pt_regs saved_regs;
 
 void save_processor_state(void)
@@ -20,7 +20,7 @@ void save_processor_state(void)
 	saved_prmd = csr_read32(LOONGARCH_CSR_PRMD);
 	saved_euen = csr_read32(LOONGARCH_CSR_EUEN);
 	saved_ecfg = csr_read32(LOONGARCH_CSR_ECFG);
-	saved_pcpu_base = csr_read64(PERCPU_BASE_KS);
+	saved_pcpu_base = csr_read(PERCPU_BASE_KS);
 
 	if (is_fpu_owner())
 		save_fp(current);
@@ -33,7 +33,7 @@ void restore_processor_state(void)
 	csr_write32(saved_prmd, LOONGARCH_CSR_PRMD);
 	csr_write32(saved_euen, LOONGARCH_CSR_EUEN);
 	csr_write32(saved_ecfg, LOONGARCH_CSR_ECFG);
-	csr_write64(saved_pcpu_base, PERCPU_BASE_KS);
+	csr_write(saved_pcpu_base, PERCPU_BASE_KS);
 
 	if (is_fpu_owner())
 		restore_fp(current);
diff --git a/arch/loongarch/power/suspend.c b/arch/loongarch/power/suspend.c
index c9e594925c47..7e3d79f8bbd4 100644
--- a/arch/loongarch/power/suspend.c
+++ b/arch/loongarch/power/suspend.c
@@ -20,24 +20,24 @@ u64 loongarch_suspend_addr;
 struct saved_registers {
 	u32 ecfg;
 	u32 euen;
-	u64 pgd;
-	u64 kpgd;
 	u32 pwctl0;
 	u32 pwctl1;
-	u64 pcpu_base;
+	unsigned long pgd;
+	unsigned long kpgd;
+	unsigned long pcpu_base;
 };
 static struct saved_registers saved_regs;
 
 void loongarch_common_suspend(void)
 {
 	save_counter();
-	saved_regs.pgd = csr_read64(LOONGARCH_CSR_PGDL);
-	saved_regs.kpgd = csr_read64(LOONGARCH_CSR_PGDH);
+	saved_regs.pgd = csr_read(LOONGARCH_CSR_PGDL);
+	saved_regs.kpgd = csr_read(LOONGARCH_CSR_PGDH);
 	saved_regs.pwctl0 = csr_read32(LOONGARCH_CSR_PWCTL0);
 	saved_regs.pwctl1 = csr_read32(LOONGARCH_CSR_PWCTL1);
 	saved_regs.ecfg = csr_read32(LOONGARCH_CSR_ECFG);
 	saved_regs.euen = csr_read32(LOONGARCH_CSR_EUEN);
-	saved_regs.pcpu_base = csr_read64(PERCPU_BASE_KS);
+	saved_regs.pcpu_base = csr_read(PERCPU_BASE_KS);
 
 	loongarch_suspend_addr = loongson_sysconf.suspend_addr;
 }
@@ -46,17 +46,17 @@ void loongarch_common_resume(void)
 {
 	sync_counter();
 	local_flush_tlb_all();
-	csr_write64(eentry, LOONGARCH_CSR_EENTRY);
-	csr_write64(eentry, LOONGARCH_CSR_MERRENTRY);
-	csr_write64(tlbrentry, LOONGARCH_CSR_TLBRENTRY);
+	csr_write(eentry, LOONGARCH_CSR_EENTRY);
+	csr_write(eentry, LOONGARCH_CSR_MERRENTRY);
+	csr_write(tlbrentry, LOONGARCH_CSR_TLBRENTRY);
 
-	csr_write64(saved_regs.pgd, LOONGARCH_CSR_PGDL);
-	csr_write64(saved_regs.kpgd, LOONGARCH_CSR_PGDH);
+	csr_write(saved_regs.pgd, LOONGARCH_CSR_PGDL);
+	csr_write(saved_regs.kpgd, LOONGARCH_CSR_PGDH);
 	csr_write32(saved_regs.pwctl0, LOONGARCH_CSR_PWCTL0);
 	csr_write32(saved_regs.pwctl1, LOONGARCH_CSR_PWCTL1);
 	csr_write32(saved_regs.ecfg, LOONGARCH_CSR_ECFG);
 	csr_write32(saved_regs.euen, LOONGARCH_CSR_EUEN);
-	csr_write64(saved_regs.pcpu_base, PERCPU_BASE_KS);
+	csr_write(saved_regs.pcpu_base, PERCPU_BASE_KS);
 }
 
 int loongarch_acpi_suspend(void)
diff --git a/drivers/firmware/efi/libstub/loongarch.c b/drivers/firmware/efi/libstub/loongarch.c
index 3782d0a187d1..9825f5218137 100644
--- a/drivers/firmware/efi/libstub/loongarch.c
+++ b/drivers/firmware/efi/libstub/loongarch.c
@@ -72,10 +72,10 @@ efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image,
 		    desc_ver, priv.runtime_map);
 
 	/* Config Direct Mapping */
-	csr_write64(CSR_DMW0_INIT, LOONGARCH_CSR_DMWIN0);
-	csr_write64(CSR_DMW1_INIT, LOONGARCH_CSR_DMWIN1);
-	csr_write64(CSR_DMW2_INIT, LOONGARCH_CSR_DMWIN2);
-	csr_write64(CSR_DMW3_INIT, LOONGARCH_CSR_DMWIN3);
+	csr_write(CSR_DMW0_INIT, LOONGARCH_CSR_DMWIN0);
+	csr_write(CSR_DMW1_INIT, LOONGARCH_CSR_DMWIN1);
+	csr_write(CSR_DMW2_INIT, LOONGARCH_CSR_DMWIN2);
+	csr_write(CSR_DMW3_INIT, LOONGARCH_CSR_DMWIN3);
 
 	real_kernel_entry = (void *)kernel_entry_address(kernel_addr, image);
 
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH V2 03/14] LoongArch: Adjust common macro definitions for 32BIT/64BIT
  2025-11-18 11:27 [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Huacai Chen
  2025-11-18 11:27 ` [PATCH V2 01/14] LoongArch: Add atomic operations for 32BIT/64BIT Huacai Chen
  2025-11-18 11:27 ` [PATCH V2 02/14] LoongArch: Add adaptive CSR accessors " Huacai Chen
@ 2025-11-18 11:27 ` Huacai Chen
  2025-11-18 11:27 ` [PATCH V2 04/14] LoongArch: Adjust boot & setup " Huacai Chen
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 37+ messages in thread
From: Huacai Chen @ 2025-11-18 11:27 UTC (permalink / raw)
  To: Arnd Bergmann, Huacai Chen
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Xuerui Wang,
	Jiaxun Yang, linux-kernel, Huacai Chen

Most common macros are defined in asm.h, asmmacro.h and stackframe.h.
Adjust these macros for both 32BIT and 64BIT.

Add SETUP_TWINS (Setup Trampoline Windows) and SETUP_MODES (Setup CRMD/
PRMD/EUEN) which will be used later.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
 arch/loongarch/include/asm/asm.h        |  77 ++++++++++++----
 arch/loongarch/include/asm/asmmacro.h   | 117 ++++++++++++++++++------
 arch/loongarch/include/asm/stackframe.h |  34 +++++--
 3 files changed, 173 insertions(+), 55 deletions(-)

diff --git a/arch/loongarch/include/asm/asm.h b/arch/loongarch/include/asm/asm.h
index f018d26fc995..719cab1a0ad8 100644
--- a/arch/loongarch/include/asm/asm.h
+++ b/arch/loongarch/include/asm/asm.h
@@ -72,11 +72,11 @@
 #define INT_SUB		sub.w
 #define INT_L		ld.w
 #define INT_S		st.w
-#define INT_SLL		slli.w
+#define INT_SLLI	slli.w
 #define INT_SLLV	sll.w
-#define INT_SRL		srli.w
+#define INT_SRLI	srli.w
 #define INT_SRLV	srl.w
-#define INT_SRA		srai.w
+#define INT_SRAI	srai.w
 #define INT_SRAV	sra.w
 #endif
 
@@ -86,11 +86,11 @@
 #define INT_SUB		sub.d
 #define INT_L		ld.d
 #define INT_S		st.d
-#define INT_SLL		slli.d
+#define INT_SLLI	slli.d
 #define INT_SLLV	sll.d
-#define INT_SRL		srli.d
+#define INT_SRLI	srli.d
 #define INT_SRLV	srl.d
-#define INT_SRA		srai.d
+#define INT_SRAI	srai.d
 #define INT_SRAV	sra.d
 #endif
 
@@ -100,15 +100,23 @@
 #if (__SIZEOF_LONG__ == 4)
 #define LONG_ADD	add.w
 #define LONG_ADDI	addi.w
+#define LONG_ALSL	alsl.w
+#define LONG_BSTRINS	bstrins.w
+#define LONG_BSTRPICK	bstrpick.w
 #define LONG_SUB	sub.w
 #define LONG_L		ld.w
+#define LONG_LI		li.w
+#define LONG_LPTR	ld.w
 #define LONG_S		st.w
-#define LONG_SLL	slli.w
+#define LONG_SPTR	st.w
+#define LONG_SLLI	slli.w
 #define LONG_SLLV	sll.w
-#define LONG_SRL	srli.w
+#define LONG_SRLI	srli.w
 #define LONG_SRLV	srl.w
-#define LONG_SRA	srai.w
+#define LONG_SRAI	srai.w
 #define LONG_SRAV	sra.w
+#define LONG_ROTR	rotr.w
+#define LONG_ROTRI	rotri.w
 
 #ifdef __ASSEMBLER__
 #define LONG		.word
@@ -121,15 +129,23 @@
 #if (__SIZEOF_LONG__ == 8)
 #define LONG_ADD	add.d
 #define LONG_ADDI	addi.d
+#define LONG_ALSL	alsl.d
+#define LONG_BSTRINS	bstrins.d
+#define LONG_BSTRPICK	bstrpick.d
 #define LONG_SUB	sub.d
 #define LONG_L		ld.d
+#define LONG_LI		li.d
+#define LONG_LPTR	ldptr.d
 #define LONG_S		st.d
-#define LONG_SLL	slli.d
+#define LONG_SPTR	stptr.d
+#define LONG_SLLI	slli.d
 #define LONG_SLLV	sll.d
-#define LONG_SRL	srli.d
+#define LONG_SRLI	srli.d
 #define LONG_SRLV	srl.d
-#define LONG_SRA	srai.d
+#define LONG_SRAI	srai.d
 #define LONG_SRAV	sra.d
+#define LONG_ROTR	rotr.d
+#define LONG_ROTRI	rotri.d
 
 #ifdef __ASSEMBLER__
 #define LONG		.dword
@@ -145,16 +161,23 @@
 #if (__SIZEOF_POINTER__ == 4)
 #define PTR_ADD		add.w
 #define PTR_ADDI	addi.w
+#define PTR_ALSL	alsl.w
+#define PTR_BSTRINS	bstrins.w
+#define PTR_BSTRPICK	bstrpick.w
 #define PTR_SUB		sub.w
 #define PTR_L		ld.w
-#define PTR_S		st.w
 #define PTR_LI		li.w
-#define PTR_SLL		slli.w
+#define PTR_LPTR	ld.w
+#define PTR_S		st.w
+#define PTR_SPTR	st.w
+#define PTR_SLLI	slli.w
 #define PTR_SLLV	sll.w
-#define PTR_SRL		srli.w
+#define PTR_SRLI	srli.w
 #define PTR_SRLV	srl.w
-#define PTR_SRA		srai.w
+#define PTR_SRAI	srai.w
 #define PTR_SRAV	sra.w
+#define PTR_ROTR	rotr.w
+#define PTR_ROTRI	rotri.w
 
 #define PTR_SCALESHIFT	2
 
@@ -168,16 +191,23 @@
 #if (__SIZEOF_POINTER__ == 8)
 #define PTR_ADD		add.d
 #define PTR_ADDI	addi.d
+#define PTR_ALSL	alsl.d
+#define PTR_BSTRINS	bstrins.d
+#define PTR_BSTRPICK	bstrpick.d
 #define PTR_SUB		sub.d
 #define PTR_L		ld.d
-#define PTR_S		st.d
 #define PTR_LI		li.d
-#define PTR_SLL		slli.d
+#define PTR_LPTR	ldptr.d
+#define PTR_S		st.d
+#define PTR_SPTR	stptr.d
+#define PTR_SLLI	slli.d
 #define PTR_SLLV	sll.d
-#define PTR_SRL		srli.d
+#define PTR_SRLI	srli.d
 #define PTR_SRLV	srl.d
-#define PTR_SRA		srai.d
+#define PTR_SRAI	srai.d
 #define PTR_SRAV	sra.d
+#define PTR_ROTR	rotr.d
+#define PTR_ROTRI	rotri.d
 
 #define PTR_SCALESHIFT	3
 
@@ -190,10 +220,17 @@
 
 /* Annotate a function as being unsuitable for kprobes. */
 #ifdef CONFIG_KPROBES
+#ifdef CONFIG_32BIT
+#define _ASM_NOKPROBE(name)				\
+	.pushsection "_kprobe_blacklist", "aw";		\
+	.long	name;					\
+	.popsection
+#else
 #define _ASM_NOKPROBE(name)				\
 	.pushsection "_kprobe_blacklist", "aw";		\
 	.quad	name;					\
 	.popsection
+#endif
 #else
 #define _ASM_NOKPROBE(name)
 #endif
diff --git a/arch/loongarch/include/asm/asmmacro.h b/arch/loongarch/include/asm/asmmacro.h
index 8d7f501b0a12..33becf3f987d 100644
--- a/arch/loongarch/include/asm/asmmacro.h
+++ b/arch/loongarch/include/asm/asmmacro.h
@@ -5,43 +5,54 @@
 #ifndef _ASM_ASMMACRO_H
 #define _ASM_ASMMACRO_H
 
+#include <linux/sizes.h>
 #include <asm/asm-offsets.h>
 #include <asm/regdef.h>
 #include <asm/fpregdef.h>
 #include <asm/loongarch.h>
 
+#ifdef CONFIG_64BIT
+#define TASK_STRUCT_OFFSET 0
+#else
+#define TASK_STRUCT_OFFSET SZ_1K
+#endif
+
 	.macro	cpu_save_nonscratch thread
-	stptr.d	s0, \thread, THREAD_REG23
-	stptr.d	s1, \thread, THREAD_REG24
-	stptr.d	s2, \thread, THREAD_REG25
-	stptr.d	s3, \thread, THREAD_REG26
-	stptr.d	s4, \thread, THREAD_REG27
-	stptr.d	s5, \thread, THREAD_REG28
-	stptr.d	s6, \thread, THREAD_REG29
-	stptr.d	s7, \thread, THREAD_REG30
-	stptr.d	s8, \thread, THREAD_REG31
-	stptr.d	sp, \thread, THREAD_REG03
-	stptr.d	fp, \thread, THREAD_REG22
+	LONG_SPTR	s0, \thread, (THREAD_REG23 - TASK_STRUCT_OFFSET)
+	LONG_SPTR	s1, \thread, (THREAD_REG24 - TASK_STRUCT_OFFSET)
+	LONG_SPTR	s2, \thread, (THREAD_REG25 - TASK_STRUCT_OFFSET)
+	LONG_SPTR	s3, \thread, (THREAD_REG26 - TASK_STRUCT_OFFSET)
+	LONG_SPTR	s4, \thread, (THREAD_REG27 - TASK_STRUCT_OFFSET)
+	LONG_SPTR	s5, \thread, (THREAD_REG28 - TASK_STRUCT_OFFSET)
+	LONG_SPTR	s6, \thread, (THREAD_REG29 - TASK_STRUCT_OFFSET)
+	LONG_SPTR	s7, \thread, (THREAD_REG30 - TASK_STRUCT_OFFSET)
+	LONG_SPTR	s8, \thread, (THREAD_REG31 - TASK_STRUCT_OFFSET)
+	LONG_SPTR	sp, \thread, (THREAD_REG03 - TASK_STRUCT_OFFSET)
+	LONG_SPTR	fp, \thread, (THREAD_REG22 - TASK_STRUCT_OFFSET)
 	.endm
 
 	.macro	cpu_restore_nonscratch thread
-	ldptr.d	s0, \thread, THREAD_REG23
-	ldptr.d	s1, \thread, THREAD_REG24
-	ldptr.d	s2, \thread, THREAD_REG25
-	ldptr.d	s3, \thread, THREAD_REG26
-	ldptr.d	s4, \thread, THREAD_REG27
-	ldptr.d	s5, \thread, THREAD_REG28
-	ldptr.d	s6, \thread, THREAD_REG29
-	ldptr.d	s7, \thread, THREAD_REG30
-	ldptr.d	s8, \thread, THREAD_REG31
-	ldptr.d	ra, \thread, THREAD_REG01
-	ldptr.d	sp, \thread, THREAD_REG03
-	ldptr.d	fp, \thread, THREAD_REG22
+	LONG_LPTR	s0, \thread, (THREAD_REG23 - TASK_STRUCT_OFFSET)
+	LONG_LPTR	s1, \thread, (THREAD_REG24 - TASK_STRUCT_OFFSET)
+	LONG_LPTR	s2, \thread, (THREAD_REG25 - TASK_STRUCT_OFFSET)
+	LONG_LPTR	s3, \thread, (THREAD_REG26 - TASK_STRUCT_OFFSET)
+	LONG_LPTR	s4, \thread, (THREAD_REG27 - TASK_STRUCT_OFFSET)
+	LONG_LPTR	s5, \thread, (THREAD_REG28 - TASK_STRUCT_OFFSET)
+	LONG_LPTR	s6, \thread, (THREAD_REG29 - TASK_STRUCT_OFFSET)
+	LONG_LPTR	s7, \thread, (THREAD_REG30 - TASK_STRUCT_OFFSET)
+	LONG_LPTR	s8, \thread, (THREAD_REG31 - TASK_STRUCT_OFFSET)
+	LONG_LPTR	ra, \thread, (THREAD_REG01 - TASK_STRUCT_OFFSET)
+	LONG_LPTR	sp, \thread, (THREAD_REG03 - TASK_STRUCT_OFFSET)
+	LONG_LPTR	fp, \thread, (THREAD_REG22 - TASK_STRUCT_OFFSET)
 	.endm
 
 	.macro fpu_save_csr thread tmp
 	movfcsr2gr	\tmp, fcsr0
+#ifdef CONFIG_32BIT
+	st.w		\tmp, \thread, THREAD_FCSR
+#else
 	stptr.w		\tmp, \thread, THREAD_FCSR
+#endif
 #ifdef CONFIG_CPU_HAS_LBT
 	/* TM bit is always 0 if LBT not supported */
 	andi		\tmp, \tmp, FPU_CSR_TM
@@ -56,7 +67,11 @@
 	.endm
 
 	.macro fpu_restore_csr thread tmp0 tmp1
+#ifdef CONFIG_32BIT
+	ld.w		\tmp0, \thread, THREAD_FCSR
+#else
 	ldptr.w		\tmp0, \thread, THREAD_FCSR
+#endif
 	movgr2fcsr	fcsr0, \tmp0
 #ifdef CONFIG_CPU_HAS_LBT
 	/* TM bit is always 0 if LBT not supported */
@@ -88,9 +103,52 @@
 #endif
 	.endm
 
+#ifdef CONFIG_32BIT
 	.macro fpu_save_cc thread tmp0 tmp1
 	movcf2gr	\tmp0, $fcc0
-	move	\tmp1, \tmp0
+	move		\tmp1, \tmp0
+	movcf2gr	\tmp0, $fcc1
+	bstrins.w	\tmp1, \tmp0, 15, 8
+	movcf2gr	\tmp0, $fcc2
+	bstrins.w	\tmp1, \tmp0, 23, 16
+	movcf2gr	\tmp0, $fcc3
+	bstrins.w	\tmp1, \tmp0, 31, 24
+	st.w		\tmp1, \thread, THREAD_FCC
+	movcf2gr	\tmp0, $fcc4
+	move		\tmp1, \tmp0
+	movcf2gr	\tmp0, $fcc5
+	bstrins.w	\tmp1, \tmp0, 15, 8
+	movcf2gr	\tmp0, $fcc6
+	bstrins.w	\tmp1, \tmp0, 23, 16
+	movcf2gr	\tmp0, $fcc7
+	bstrins.w	\tmp1, \tmp0, 31, 24
+	st.w		\tmp1, \thread, (THREAD_FCC + 4)
+	.endm
+
+	.macro fpu_restore_cc thread tmp0 tmp1
+	ld.w		\tmp0, \thread, THREAD_FCC
+	bstrpick.w	\tmp1, \tmp0, 7, 0
+	movgr2cf	$fcc0, \tmp1
+	bstrpick.w	\tmp1, \tmp0, 15, 8
+	movgr2cf	$fcc1, \tmp1
+	bstrpick.w	\tmp1, \tmp0, 23, 16
+	movgr2cf	$fcc2, \tmp1
+	bstrpick.w	\tmp1, \tmp0, 31, 24
+	movgr2cf	$fcc3, \tmp1
+	ld.w		\tmp0, \thread, (THREAD_FCC + 4)
+	bstrpick.w	\tmp1, \tmp0, 7, 0
+	movgr2cf	$fcc4, \tmp1
+	bstrpick.w	\tmp1, \tmp0, 15, 8
+	movgr2cf	$fcc5, \tmp1
+	bstrpick.w	\tmp1, \tmp0, 23, 16
+	movgr2cf	$fcc6, \tmp1
+	bstrpick.w	\tmp1, \tmp0, 31, 24
+	movgr2cf	$fcc7, \tmp1
+	.endm
+#else
+	.macro fpu_save_cc thread tmp0 tmp1
+	movcf2gr	\tmp0, $fcc0
+	move		\tmp1, \tmp0
 	movcf2gr	\tmp0, $fcc1
 	bstrins.d	\tmp1, \tmp0, 15, 8
 	movcf2gr	\tmp0, $fcc2
@@ -109,7 +167,7 @@
 	.endm
 
 	.macro fpu_restore_cc thread tmp0 tmp1
-	ldptr.d	\tmp0, \thread, THREAD_FCC
+	ldptr.d		\tmp0, \thread, THREAD_FCC
 	bstrpick.d	\tmp1, \tmp0, 7, 0
 	movgr2cf	$fcc0, \tmp1
 	bstrpick.d	\tmp1, \tmp0, 15, 8
@@ -127,6 +185,7 @@
 	bstrpick.d	\tmp1, \tmp0, 63, 56
 	movgr2cf	$fcc7, \tmp1
 	.endm
+#endif
 
 	.macro	fpu_save_double thread tmp
 	li.w	\tmp, THREAD_FPR0
@@ -606,12 +665,14 @@
 	766:
 	lu12i.w	\reg, 0
 	ori	\reg, \reg, 0
+#ifdef CONFIG_64BIT
 	lu32i.d	\reg, 0
 	lu52i.d	\reg, \reg, 0
+#endif
 	.pushsection ".la_abs", "aw", %progbits
-	.p2align 3
-	.dword	766b
-	.dword	\sym
+	.p2align PTRLOG
+	PTR	766b
+	PTR	\sym
 	.popsection
 #endif
 .endm
diff --git a/arch/loongarch/include/asm/stackframe.h b/arch/loongarch/include/asm/stackframe.h
index 5cb568a60cf8..b44930fbb675 100644
--- a/arch/loongarch/include/asm/stackframe.h
+++ b/arch/loongarch/include/asm/stackframe.h
@@ -38,22 +38,42 @@
 	cfi_restore \reg \offset \docfi
 	.endm
 
+	.macro SETUP_TWINS temp
+	pcaddi	t0, 0
+	PTR_LI	t1, ~TO_PHYS_MASK
+	and	t0, t0, t1
+	ori	t0, t0, (1 << 4 | 1)
+	csrwr	t0, LOONGARCH_CSR_DMWIN0
+	PTR_LI	t0, CSR_DMW1_INIT
+	csrwr	t0, LOONGARCH_CSR_DMWIN1
+	.endm
+
+	.macro SETUP_MODES temp
+	/* Enable PG */
+	li.w	\temp, 0xb0		# PLV=0, IE=0, PG=1
+	csrwr	\temp, LOONGARCH_CSR_CRMD
+	li.w	\temp, 0x04		# PLV=0, PIE=1, PWE=0
+	csrwr	\temp, LOONGARCH_CSR_PRMD
+	li.w	\temp, 0x00		# FPE=0, SXE=0, ASXE=0, BTE=0
+	csrwr	\temp, LOONGARCH_CSR_EUEN
+	.endm
+
 	.macro SETUP_DMWINS temp
-	li.d	\temp, CSR_DMW0_INIT	# WUC, PLV0, 0x8000 xxxx xxxx xxxx
+	PTR_LI	\temp, CSR_DMW0_INIT	# WUC, PLV0, 0x8000 xxxx xxxx xxxx
 	csrwr	\temp, LOONGARCH_CSR_DMWIN0
-	li.d	\temp, CSR_DMW1_INIT	# CAC, PLV0, 0x9000 xxxx xxxx xxxx
+	PTR_LI	\temp, CSR_DMW1_INIT	# CAC, PLV0, 0x9000 xxxx xxxx xxxx
 	csrwr	\temp, LOONGARCH_CSR_DMWIN1
-	li.d	\temp, CSR_DMW2_INIT	# WUC, PLV0, 0xa000 xxxx xxxx xxxx
+	PTR_LI	\temp, CSR_DMW2_INIT	# WUC, PLV0, 0xa000 xxxx xxxx xxxx
 	csrwr	\temp, LOONGARCH_CSR_DMWIN2
-	li.d	\temp, CSR_DMW3_INIT	# 0x0, unused
+	PTR_LI	\temp, CSR_DMW3_INIT	# 0x0, unused
 	csrwr	\temp, LOONGARCH_CSR_DMWIN3
 	.endm
 
 /* Jump to the runtime virtual address. */
 	.macro JUMP_VIRT_ADDR temp1 temp2
-	li.d	\temp1, CACHE_BASE
+	PTR_LI	\temp1, CACHE_BASE
 	pcaddi	\temp2, 0
-	bstrins.d  \temp1, \temp2, (DMW_PABITS - 1), 0
+	PTR_BSTRINS  \temp1, \temp2, (DMW_PABITS - 1), 0
 	jirl	zero, \temp1, 0xc
 	.endm
 
@@ -171,7 +191,7 @@
 	andi	t0, t0, 0x3	/* extract pplv bit */
 	beqz	t0, 9f
 
-	li.d	tp, ~_THREAD_MASK
+	LONG_LI	tp, ~_THREAD_MASK
 	and	tp, tp, sp
 	cfi_st  u0, PT_R21, \docfi
 	csrrd	u0, PERCPU_BASE_KS
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH V2 04/14] LoongArch: Adjust boot & setup for 32BIT/64BIT
  2025-11-18 11:27 [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Huacai Chen
                   ` (2 preceding siblings ...)
  2025-11-18 11:27 ` [PATCH V2 03/14] LoongArch: Adjust common macro definitions " Huacai Chen
@ 2025-11-18 11:27 ` Huacai Chen
  2025-11-18 17:09   ` Yao Zi
  2025-11-18 11:27 ` [PATCH V2 05/14] LoongArch: Adjust memory management " Huacai Chen
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Huacai Chen @ 2025-11-18 11:27 UTC (permalink / raw)
  To: Arnd Bergmann, Huacai Chen
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Xuerui Wang,
	Jiaxun Yang, linux-kernel, Huacai Chen

Adjust boot & setup for both 32BIT and 64BIT, including: efi header
definition, MAX_IO_PICS definition, kernel entry and environment setup
routines, etc.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
 arch/loongarch/include/asm/addrspace.h |  2 +-
 arch/loongarch/include/asm/irq.h       |  5 ++++
 arch/loongarch/kernel/efi-header.S     |  4 +++
 arch/loongarch/kernel/efi.c            |  4 ++-
 arch/loongarch/kernel/env.c            |  9 ++++--
 arch/loongarch/kernel/head.S           | 39 +++++++++++---------------
 arch/loongarch/kernel/relocate.c       |  9 +++++-
 7 files changed, 45 insertions(+), 27 deletions(-)

diff --git a/arch/loongarch/include/asm/addrspace.h b/arch/loongarch/include/asm/addrspace.h
index e739dbc6329d..9766a100504a 100644
--- a/arch/loongarch/include/asm/addrspace.h
+++ b/arch/loongarch/include/asm/addrspace.h
@@ -42,7 +42,7 @@ extern unsigned long vm_map_base;
 #endif
 
 #define DMW_PABITS	48
-#define TO_PHYS_MASK	((1ULL << DMW_PABITS) - 1)
+#define TO_PHYS_MASK	((_ULL(1) << _ULL(DMW_PABITS)) - 1)
 
 /*
  * Memory above this physical address will be considered highmem.
diff --git a/arch/loongarch/include/asm/irq.h b/arch/loongarch/include/asm/irq.h
index 12bd15578c33..cf6c82a9117b 100644
--- a/arch/loongarch/include/asm/irq.h
+++ b/arch/loongarch/include/asm/irq.h
@@ -53,7 +53,12 @@ void spurious_interrupt(void);
 #define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
 void arch_trigger_cpumask_backtrace(const struct cpumask *mask, int exclude_cpu);
 
+#ifdef CONFIG_32BIT
+#define MAX_IO_PICS 1
+#else
 #define MAX_IO_PICS 8
+#endif
+
 #define NR_IRQS	(64 + NR_VECTORS * (NR_CPUS + MAX_IO_PICS))
 
 struct acpi_vector_group {
diff --git a/arch/loongarch/kernel/efi-header.S b/arch/loongarch/kernel/efi-header.S
index ba0bdbf86aa8..6df56241cb95 100644
--- a/arch/loongarch/kernel/efi-header.S
+++ b/arch/loongarch/kernel/efi-header.S
@@ -9,7 +9,11 @@
 	.macro	__EFI_PE_HEADER
 	.long	IMAGE_NT_SIGNATURE
 .Lcoff_header:
+#ifdef CONFIG_32BIT
+	.short	IMAGE_FILE_MACHINE_LOONGARCH32		/* Machine */
+#else
 	.short	IMAGE_FILE_MACHINE_LOONGARCH64		/* Machine */
+#endif
 	.short	.Lsection_count				/* NumberOfSections */
 	.long	0 					/* TimeDateStamp */
 	.long	0					/* PointerToSymbolTable */
diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c
index 860a3bc030e0..52c21c895318 100644
--- a/arch/loongarch/kernel/efi.c
+++ b/arch/loongarch/kernel/efi.c
@@ -115,7 +115,9 @@ void __init efi_init(void)
 
 	efi_systab_report_header(&efi_systab->hdr, efi_systab->fw_vendor);
 
-	set_bit(EFI_64BIT, &efi.flags);
+	if (IS_ENABLED(CONFIG_64BIT))
+		set_bit(EFI_64BIT, &efi.flags);
+
 	efi_nr_tables	 = efi_systab->nr_tables;
 	efi_config_table = (unsigned long)efi_systab->tables;
 
diff --git a/arch/loongarch/kernel/env.c b/arch/loongarch/kernel/env.c
index 23bd5ae2212c..3e8a25eb901b 100644
--- a/arch/loongarch/kernel/env.c
+++ b/arch/loongarch/kernel/env.c
@@ -68,18 +68,23 @@ static int __init fdt_cpu_clk_init(void)
 
 	np = of_get_cpu_node(0, NULL);
 	if (!np)
-		return -ENODEV;
+		goto fallback;
 
 	clk = of_clk_get(np, 0);
 	of_node_put(np);
 
 	if (IS_ERR(clk))
-		return -ENODEV;
+		goto fallback;
 
 	cpu_clock_freq = clk_get_rate(clk);
 	clk_put(clk);
 
 	return 0;
+
+fallback:
+	cpu_clock_freq = 200 * 1000 * 1000;
+
+	return -ENODEV;
 }
 late_initcall(fdt_cpu_clk_init);
 
diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S
index e3865e92a917..aba548db2446 100644
--- a/arch/loongarch/kernel/head.S
+++ b/arch/loongarch/kernel/head.S
@@ -43,36 +43,29 @@ SYM_DATA(kernel_fsize, .long _kernel_fsize);
 
 SYM_CODE_START(kernel_entry)			# kernel entry point
 
-	/* Config direct window and set PG */
-	SETUP_DMWINS	t0
+	SETUP_TWINS
+	SETUP_MODES	t0
 	JUMP_VIRT_ADDR	t0, t1
-
-	/* Enable PG */
-	li.w		t0, 0xb0		# PLV=0, IE=0, PG=1
-	csrwr		t0, LOONGARCH_CSR_CRMD
-	li.w		t0, 0x04		# PLV=0, PIE=1, PWE=0
-	csrwr		t0, LOONGARCH_CSR_PRMD
-	li.w		t0, 0x00		# FPE=0, SXE=0, ASXE=0, BTE=0
-	csrwr		t0, LOONGARCH_CSR_EUEN
+	SETUP_DMWINS	t0
 
 	la.pcrel	t0, __bss_start		# clear .bss
-	st.d		zero, t0, 0
+	LONG_S		zero, t0, 0
 	la.pcrel	t1, __bss_stop - LONGSIZE
 1:
-	addi.d		t0, t0, LONGSIZE
-	st.d		zero, t0, 0
+	PTR_ADDI	t0, t0, LONGSIZE
+	LONG_S		zero, t0, 0
 	bne		t0, t1, 1b
 
 	la.pcrel	t0, fw_arg0
-	st.d		a0, t0, 0		# firmware arguments
+	PTR_S		a0, t0, 0		# firmware arguments
 	la.pcrel	t0, fw_arg1
-	st.d		a1, t0, 0
+	PTR_S		a1, t0, 0
 	la.pcrel	t0, fw_arg2
-	st.d		a2, t0, 0
+	PTR_S		a2, t0, 0
 
 #ifdef CONFIG_PAGE_SIZE_4KB
-	li.d		t0, 0
-	li.d		t1, CSR_STFILL
+	LONG_LI		t0, 0
+	LONG_LI		t1, CSR_STFILL
 	csrxchg		t0, t1, LOONGARCH_CSR_IMPCTL1
 #endif
 	/* KSave3 used for percpu base, initialized as 0 */
@@ -98,7 +91,7 @@ SYM_CODE_START(kernel_entry)			# kernel entry point
 
 	/* Jump to the new kernel: new_pc = current_pc + random_offset */
 	pcaddi		t0, 0
-	add.d		t0, t0, a0
+	PTR_ADD		t0, t0, a0
 	jirl		zero, t0, 0xc
 #endif /* CONFIG_RANDOMIZE_BASE */
 
@@ -121,12 +114,14 @@ SYM_CODE_END(kernel_entry)
  */
 SYM_CODE_START(smpboot_entry)
 
-	SETUP_DMWINS	t0
+	SETUP_TWINS
+	SETUP_MODES	t0
 	JUMP_VIRT_ADDR	t0, t1
+	SETUP_DMWINS	t0
 
 #ifdef CONFIG_PAGE_SIZE_4KB
-	li.d		t0, 0
-	li.d		t1, CSR_STFILL
+	LONG_LI		t0, 0
+	LONG_LI		t1, CSR_STFILL
 	csrxchg		t0, t1, LOONGARCH_CSR_IMPCTL1
 #endif
 	/* Enable PG */
diff --git a/arch/loongarch/kernel/relocate.c b/arch/loongarch/kernel/relocate.c
index b5e2312a2fca..c28ba45d80d6 100644
--- a/arch/loongarch/kernel/relocate.c
+++ b/arch/loongarch/kernel/relocate.c
@@ -68,18 +68,25 @@ static inline void __init relocate_absolute(long random_offset)
 
 	for (p = begin; (void *)p < end; p++) {
 		long v = p->symvalue;
-		uint32_t lu12iw, ori, lu32id, lu52id;
+		uint32_t lu12iw, ori;
+#ifdef CONFIG_64BIT
+		uint32_t lu32id, lu52id;
+#endif
 		union loongarch_instruction *insn = (void *)p->pc;
 
 		lu12iw = (v >> 12) & 0xfffff;
 		ori    = v & 0xfff;
+#ifdef CONFIG_64BIT
 		lu32id = (v >> 32) & 0xfffff;
 		lu52id = v >> 52;
+#endif
 
 		insn[0].reg1i20_format.immediate = lu12iw;
 		insn[1].reg2i12_format.immediate = ori;
+#ifdef CONFIG_64BIT
 		insn[2].reg1i20_format.immediate = lu32id;
 		insn[3].reg2i12_format.immediate = lu52id;
+#endif
 	}
 }
 
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH V2 05/14] LoongArch: Adjust memory management for 32BIT/64BIT
  2025-11-18 11:27 [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Huacai Chen
                   ` (3 preceding siblings ...)
  2025-11-18 11:27 ` [PATCH V2 04/14] LoongArch: Adjust boot & setup " Huacai Chen
@ 2025-11-18 11:27 ` Huacai Chen
  2025-11-18 11:27 ` [PATCH V2 06/14] LoongArch: Adjust process " Huacai Chen
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 37+ messages in thread
From: Huacai Chen @ 2025-11-18 11:27 UTC (permalink / raw)
  To: Arnd Bergmann, Huacai Chen
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Xuerui Wang,
	Jiaxun Yang, linux-kernel, Huacai Chen, Yawei Li

Adjust memory management for both 32BIT and 64BIT, including: address
space definition, DMW CSR definition, page table bits definition, boot
time detection of VA/PA bits, page table init, tlb exception handling,
copy_page/clear_page/dump_tlb libraries, etc.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Yawei Li <liyawei@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
 arch/loongarch/include/asm/addrspace.h    |  13 +
 arch/loongarch/include/asm/cpu-features.h |   3 -
 arch/loongarch/include/asm/loongarch.h    |  24 ++
 arch/loongarch/include/asm/page.h         |   2 +-
 arch/loongarch/include/asm/pgtable-bits.h |  36 ++-
 arch/loongarch/include/asm/pgtable.h      |  74 +++--
 arch/loongarch/kernel/cpu-probe.c         |   6 +-
 arch/loongarch/lib/dump_tlb.c             |   8 +
 arch/loongarch/mm/init.c                  |   4 +-
 arch/loongarch/mm/page.S                  | 118 ++++----
 arch/loongarch/mm/tlb.c                   |   2 +
 arch/loongarch/mm/tlbex.S                 | 322 +++++++++++++++-------
 12 files changed, 418 insertions(+), 194 deletions(-)

diff --git a/arch/loongarch/include/asm/addrspace.h b/arch/loongarch/include/asm/addrspace.h
index 9766a100504a..d6472cafb32c 100644
--- a/arch/loongarch/include/asm/addrspace.h
+++ b/arch/loongarch/include/asm/addrspace.h
@@ -38,11 +38,20 @@ extern unsigned long vm_map_base;
 #endif
 
 #ifndef WRITECOMBINE_BASE
+#ifdef CONFIG_32BIT
+#define WRITECOMBINE_BASE	CSR_DMW0_BASE
+#else
 #define WRITECOMBINE_BASE	CSR_DMW2_BASE
 #endif
+#endif
 
+#ifdef CONFIG_32BIT
+#define DMW_PABITS	29
+#define TO_PHYS_MASK	((_UL(1) << _UL(DMW_PABITS)) - 1)
+#else
 #define DMW_PABITS	48
 #define TO_PHYS_MASK	((_ULL(1) << _ULL(DMW_PABITS)) - 1)
+#endif
 
 /*
  * Memory above this physical address will be considered highmem.
@@ -112,7 +121,11 @@ extern unsigned long vm_map_base;
 /*
  * Returns the physical address of a KPRANGEx / XKPRANGE address
  */
+#ifdef CONFIG_32BIT
+#define PHYSADDR(a)		((_ACAST32_(a)) & TO_PHYS_MASK)
+#else
 #define PHYSADDR(a)		((_ACAST64_(a)) & TO_PHYS_MASK)
+#endif
 
 /*
  * On LoongArch, I/O ports mappring is following:
diff --git a/arch/loongarch/include/asm/cpu-features.h b/arch/loongarch/include/asm/cpu-features.h
index bd5f0457ad21..3745d991a99a 100644
--- a/arch/loongarch/include/asm/cpu-features.h
+++ b/arch/loongarch/include/asm/cpu-features.h
@@ -20,16 +20,13 @@
 #define cpu_has_loongarch64		(cpu_data[0].isa_level & LOONGARCH_CPU_ISA_64BIT)
 
 #ifdef CONFIG_32BIT
-# define cpu_has_64bits			(cpu_data[0].isa_level & LOONGARCH_CPU_ISA_64BIT)
 # define cpu_vabits			31
 # define cpu_pabits			31
 #endif
 
 #ifdef CONFIG_64BIT
-# define cpu_has_64bits			1
 # define cpu_vabits			cpu_data[0].vabits
 # define cpu_pabits			cpu_data[0].pabits
-# define __NEED_ADDRBITS_PROBE
 #endif
 
 /*
diff --git a/arch/loongarch/include/asm/loongarch.h b/arch/loongarch/include/asm/loongarch.h
index 9f71a79271da..804341bd8d2e 100644
--- a/arch/loongarch/include/asm/loongarch.h
+++ b/arch/loongarch/include/asm/loongarch.h
@@ -912,6 +912,26 @@
 #define LOONGARCH_CSR_DMWIN3		0x183	/* 64 direct map win3: MEM */
 
 /* Direct Map window 0/1/2/3 */
+
+#ifdef CONFIG_32BIT
+
+#define CSR_DMW0_PLV0		(1 << 0)
+#define CSR_DMW0_VSEG		(0x4)
+#define CSR_DMW0_BASE		(CSR_DMW0_VSEG << DMW_PABITS)
+#define CSR_DMW0_INIT		(CSR_DMW0_BASE | CSR_DMW0_PLV0)
+
+#define CSR_DMW1_PLV0		(1 << 0)
+#define CSR_DMW1_MAT		(1 << 4)
+#define CSR_DMW1_VSEG		(0x5)
+#define CSR_DMW1_BASE		(CSR_DMW1_VSEG << DMW_PABITS)
+#define CSR_DMW1_INIT		(CSR_DMW1_BASE | CSR_DMW1_MAT | CSR_DMW1_PLV0)
+
+#define CSR_DMW2_INIT		0x0
+
+#define CSR_DMW3_INIT		0x0
+
+#else
+
 #define CSR_DMW0_PLV0		_CONST64_(1 << 0)
 #define CSR_DMW0_VSEG		_CONST64_(0x8000)
 #define CSR_DMW0_BASE		(CSR_DMW0_VSEG << DMW_PABITS)
@@ -931,6 +951,8 @@
 
 #define CSR_DMW3_INIT		0x0
 
+#endif
+
 /* Performance Counter registers */
 #define LOONGARCH_CSR_PERFCTRL0		0x200	/* 32 perf event 0 config */
 #define LOONGARCH_CSR_PERFCNTR0		0x201	/* 64 perf event 0 count value */
@@ -1388,8 +1410,10 @@ __BUILD_CSR_OP(tlbidx)
 #define ENTRYLO_C_SHIFT		4
 #define ENTRYLO_C		(_ULCAST_(3) << ENTRYLO_C_SHIFT)
 #define ENTRYLO_G		(_ULCAST_(1) << 6)
+#ifdef CONFIG_64BIT
 #define ENTRYLO_NR		(_ULCAST_(1) << 61)
 #define ENTRYLO_NX		(_ULCAST_(1) << 62)
+#endif
 
 /* Values for PageSize register */
 #define PS_4K		0x0000000c
diff --git a/arch/loongarch/include/asm/page.h b/arch/loongarch/include/asm/page.h
index a3aaf34fba16..256d1ff7a1e3 100644
--- a/arch/loongarch/include/asm/page.h
+++ b/arch/loongarch/include/asm/page.h
@@ -10,7 +10,7 @@
 
 #include <vdso/page.h>
 
-#define HPAGE_SHIFT	(PAGE_SHIFT + PAGE_SHIFT - 3)
+#define HPAGE_SHIFT	(PAGE_SHIFT + PAGE_SHIFT - PTRLOG)
 #define HPAGE_SIZE	(_AC(1, UL) << HPAGE_SHIFT)
 #define HPAGE_MASK	(~(HPAGE_SIZE - 1))
 #define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
diff --git a/arch/loongarch/include/asm/pgtable-bits.h b/arch/loongarch/include/asm/pgtable-bits.h
index 2fc3789220ac..b565573cd82e 100644
--- a/arch/loongarch/include/asm/pgtable-bits.h
+++ b/arch/loongarch/include/asm/pgtable-bits.h
@@ -6,6 +6,26 @@
 #define _ASM_PGTABLE_BITS_H
 
 /* Page table bits */
+
+#ifdef CONFIG_32BIT
+#define	_PAGE_VALID_SHIFT	0
+#define	_PAGE_ACCESSED_SHIFT	0  /* Reuse Valid for Accessed */
+#define	_PAGE_DIRTY_SHIFT	1
+#define	_PAGE_PLV_SHIFT		2  /* 2~3, two bits */
+#define	_CACHE_SHIFT		4  /* 4~5, two bits */
+#define	_PAGE_GLOBAL_SHIFT	6
+#define	_PAGE_HUGE_SHIFT	6  /* HUGE is a PMD bit */
+#define	_PAGE_PRESENT_SHIFT	7
+#define	_PAGE_PFN_SHIFT		8
+#define	_PAGE_HGLOBAL_SHIFT	12 /* HGlobal is a PMD bit */
+#define	_PAGE_SWP_EXCLUSIVE_SHIFT 13
+#define	_PAGE_PFN_END_SHIFT	28
+#define	_PAGE_WRITE_SHIFT	29
+#define	_PAGE_MODIFIED_SHIFT	30
+#define	_PAGE_PRESENT_INVALID_SHIFT 31
+#endif
+
+#ifdef CONFIG_64BIT
 #define	_PAGE_VALID_SHIFT	0
 #define	_PAGE_ACCESSED_SHIFT	0  /* Reuse Valid for Accessed */
 #define	_PAGE_DIRTY_SHIFT	1
@@ -18,14 +38,15 @@
 #define	_PAGE_MODIFIED_SHIFT	9
 #define	_PAGE_PROTNONE_SHIFT	10
 #define	_PAGE_SPECIAL_SHIFT	11
-#define	_PAGE_HGLOBAL_SHIFT	12 /* HGlobal is a PMD bit */
 #define	_PAGE_PFN_SHIFT		12
+#define	_PAGE_HGLOBAL_SHIFT	12 /* HGlobal is a PMD bit */
 #define	_PAGE_SWP_EXCLUSIVE_SHIFT 23
 #define	_PAGE_PFN_END_SHIFT	48
 #define	_PAGE_PRESENT_INVALID_SHIFT 60
 #define	_PAGE_NO_READ_SHIFT	61
 #define	_PAGE_NO_EXEC_SHIFT	62
 #define	_PAGE_RPLV_SHIFT	63
+#endif
 
 /* Used by software */
 #define _PAGE_PRESENT		(_ULCAST_(1) << _PAGE_PRESENT_SHIFT)
@@ -33,10 +54,15 @@
 #define _PAGE_WRITE		(_ULCAST_(1) << _PAGE_WRITE_SHIFT)
 #define _PAGE_ACCESSED		(_ULCAST_(1) << _PAGE_ACCESSED_SHIFT)
 #define _PAGE_MODIFIED		(_ULCAST_(1) << _PAGE_MODIFIED_SHIFT)
+#ifdef CONFIG_32BIT
+#define _PAGE_PROTNONE		0
+#define _PAGE_SPECIAL		0
+#else
 #define _PAGE_PROTNONE		(_ULCAST_(1) << _PAGE_PROTNONE_SHIFT)
 #define _PAGE_SPECIAL		(_ULCAST_(1) << _PAGE_SPECIAL_SHIFT)
+#endif
 
-/* We borrow bit 23 to store the exclusive marker in swap PTEs. */
+/* We borrow bit 13/23 to store the exclusive marker in swap PTEs. */
 #define _PAGE_SWP_EXCLUSIVE	(_ULCAST_(1) << _PAGE_SWP_EXCLUSIVE_SHIFT)
 
 /* Used by TLB hardware (placed in EntryLo*) */
@@ -46,9 +72,15 @@
 #define _PAGE_GLOBAL		(_ULCAST_(1) << _PAGE_GLOBAL_SHIFT)
 #define _PAGE_HUGE		(_ULCAST_(1) << _PAGE_HUGE_SHIFT)
 #define _PAGE_HGLOBAL		(_ULCAST_(1) << _PAGE_HGLOBAL_SHIFT)
+#ifdef CONFIG_32BIT
+#define _PAGE_NO_READ		0
+#define _PAGE_NO_EXEC		0
+#define _PAGE_RPLV		0
+#else
 #define _PAGE_NO_READ		(_ULCAST_(1) << _PAGE_NO_READ_SHIFT)
 #define _PAGE_NO_EXEC		(_ULCAST_(1) << _PAGE_NO_EXEC_SHIFT)
 #define _PAGE_RPLV		(_ULCAST_(1) << _PAGE_RPLV_SHIFT)
+#endif
 #define _CACHE_MASK		(_ULCAST_(3) << _CACHE_SHIFT)
 #define PFN_PTE_SHIFT		(PAGE_SHIFT - 12 + _PAGE_PFN_SHIFT)
 
diff --git a/arch/loongarch/include/asm/pgtable.h b/arch/loongarch/include/asm/pgtable.h
index 03fb60432fde..9ed2ea23c580 100644
--- a/arch/loongarch/include/asm/pgtable.h
+++ b/arch/loongarch/include/asm/pgtable.h
@@ -11,6 +11,7 @@
 
 #include <linux/compiler.h>
 #include <asm/addrspace.h>
+#include <asm/asm.h>
 #include <asm/page.h>
 #include <asm/pgtable-bits.h>
 
@@ -23,37 +24,45 @@
 #endif
 
 #if CONFIG_PGTABLE_LEVELS == 2
-#define PGDIR_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT - 3))
+#define PGDIR_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT - PTRLOG))
 #elif CONFIG_PGTABLE_LEVELS == 3
-#define PMD_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT - 3))
+#define PMD_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT - PTRLOG))
 #define PMD_SIZE	(1UL << PMD_SHIFT)
 #define PMD_MASK	(~(PMD_SIZE-1))
-#define PGDIR_SHIFT	(PMD_SHIFT + (PAGE_SHIFT - 3))
+#define PGDIR_SHIFT	(PMD_SHIFT + (PAGE_SHIFT - PTRLOG))
 #elif CONFIG_PGTABLE_LEVELS == 4
-#define PMD_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT - 3))
+#define PMD_SHIFT	(PAGE_SHIFT + (PAGE_SHIFT - PTRLOG))
 #define PMD_SIZE	(1UL << PMD_SHIFT)
 #define PMD_MASK	(~(PMD_SIZE-1))
-#define PUD_SHIFT	(PMD_SHIFT + (PAGE_SHIFT - 3))
+#define PUD_SHIFT	(PMD_SHIFT + (PAGE_SHIFT - PTRLOG))
 #define PUD_SIZE	(1UL << PUD_SHIFT)
 #define PUD_MASK	(~(PUD_SIZE-1))
-#define PGDIR_SHIFT	(PUD_SHIFT + (PAGE_SHIFT - 3))
+#define PGDIR_SHIFT	(PUD_SHIFT + (PAGE_SHIFT - PTRLOG))
 #endif
 
 #define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
 #define PGDIR_MASK	(~(PGDIR_SIZE-1))
 
-#define VA_BITS		(PGDIR_SHIFT + (PAGE_SHIFT - 3))
+#ifdef CONFIG_32BIT
+#define VA_BITS		32
+#else
+#define VA_BITS		(PGDIR_SHIFT + (PAGE_SHIFT - PTRLOG))
+#endif
 
-#define PTRS_PER_PGD	(PAGE_SIZE >> 3)
+#define PTRS_PER_PGD	(PAGE_SIZE >> PTRLOG)
 #if CONFIG_PGTABLE_LEVELS > 3
-#define PTRS_PER_PUD	(PAGE_SIZE >> 3)
+#define PTRS_PER_PUD	(PAGE_SIZE >> PTRLOG)
 #endif
 #if CONFIG_PGTABLE_LEVELS > 2
-#define PTRS_PER_PMD	(PAGE_SIZE >> 3)
+#define PTRS_PER_PMD	(PAGE_SIZE >> PTRLOG)
 #endif
-#define PTRS_PER_PTE	(PAGE_SIZE >> 3)
+#define PTRS_PER_PTE	(PAGE_SIZE >> PTRLOG)
 
+#ifdef CONFIG_32BIT
+#define USER_PTRS_PER_PGD       (TASK_SIZE / PGDIR_SIZE)
+#else
 #define USER_PTRS_PER_PGD       ((TASK_SIZE64 / PGDIR_SIZE)?(TASK_SIZE64 / PGDIR_SIZE):1)
+#endif
 
 #ifndef __ASSEMBLER__
 
@@ -74,11 +83,15 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
 
 #define ZERO_PAGE(vaddr)	virt_to_page(empty_zero_page)
 
-/*
- * TLB refill handlers may also map the vmalloc area into xkvrange.
- * Avoid the first couple of pages so NULL pointer dereferences will
- * still reliably trap.
- */
+#ifdef CONFIG_32BIT
+
+#define VMALLOC_START	(vm_map_base + PCI_IOSIZE + (2 * PAGE_SIZE))
+#define VMALLOC_END	(FIXADDR_START - (2 * PAGE_SIZE))
+
+#endif
+
+#ifdef CONFIG_64BIT
+
 #define MODULES_VADDR	(vm_map_base + PCI_IOSIZE + (2 * PAGE_SIZE))
 #define MODULES_END	(MODULES_VADDR + SZ_256M)
 
@@ -106,6 +119,8 @@ extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
 #define KFENCE_AREA_START	(VMEMMAP_END + 1)
 #define KFENCE_AREA_END		(KFENCE_AREA_START + KFENCE_AREA_SIZE - 1)
 
+#endif
+
 #define ptep_get(ptep) READ_ONCE(*(ptep))
 #define pmdp_get(pmdp) READ_ONCE(*(pmdp))
 
@@ -277,7 +292,16 @@ extern void kernel_pte_init(void *addr);
  * Encode/decode swap entries and swap PTEs. Swap PTEs are all PTEs that
  * are !pte_none() && !pte_present().
  *
- * Format of swap PTEs:
+ * Format of 32bit swap PTEs:
+ *
+ *   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
+ *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+ *   <------------ offset -------------> E <- type -> <-- zeroes -->
+ *
+ *   E is the exclusive marker that is not stored in swap entries.
+ *   The zero'ed bits include _PAGE_PRESENT.
+ *
+ * Format of 64bit swap PTEs:
  *
  *   6 6 6 6 5 5 5 5 5 5 5 5 5 5 4 4 4 4 4 4 4 4 4 4 3 3 3 3 3 3 3 3
  *   3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2
@@ -290,11 +314,21 @@ extern void kernel_pte_init(void *addr);
  *   E is the exclusive marker that is not stored in swap entries.
  *   The zero'ed bits include _PAGE_PRESENT and _PAGE_PROTNONE.
  */
+
+#define __SWP_TYPE_BITS		(IS_ENABLED(CONFIG_32BIT) ? 5 : 7)
+#define __SWP_TYPE_MASK		((1UL << __SWP_TYPE_BITS) - 1)
+#define __SWP_TYPE_SHIFT	(IS_ENABLED(CONFIG_32BIT) ? 8 : 16)
+#define __SWP_OFFSET_SHIFT	(__SWP_TYPE_BITS + __SWP_TYPE_SHIFT + 1)
+
 static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset)
-{ pte_t pte; pte_val(pte) = ((type & 0x7f) << 16) | (offset << 24); return pte; }
+{
+	pte_t pte;
+	pte_val(pte) = ((type & __SWP_TYPE_MASK) << __SWP_TYPE_SHIFT) | (offset << __SWP_OFFSET_SHIFT);
+	return pte;
+}
 
-#define __swp_type(x)		(((x).val >> 16) & 0x7f)
-#define __swp_offset(x)		((x).val >> 24)
+#define __swp_type(x)		(((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK)
+#define __swp_offset(x)		((x).val >> __SWP_OFFSET_SHIFT)
 #define __swp_entry(type, offset) ((swp_entry_t) { pte_val(mk_swap_pte((type), (offset))) })
 #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
 #define __swp_entry_to_pte(x)	((pte_t) { (x).val })
diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c
index 97933e9e2aa3..a10e902a9888 100644
--- a/arch/loongarch/kernel/cpu-probe.c
+++ b/arch/loongarch/kernel/cpu-probe.c
@@ -106,7 +106,11 @@ EXPORT_SYMBOL(vm_map_base);
 
 static void cpu_probe_addrbits(struct cpuinfo_loongarch *c)
 {
-#ifdef __NEED_ADDRBITS_PROBE
+#ifdef CONFIG_32BIT
+	c->pabits = cpu_pabits;
+	c->vabits = cpu_vabits;
+	vm_map_base = KVRANGE;
+#else
 	c->pabits = (read_cpucfg(LOONGARCH_CPUCFG1) & CPUCFG1_PABITS) >> 4;
 	c->vabits = (read_cpucfg(LOONGARCH_CPUCFG1) & CPUCFG1_VABITS) >> 12;
 	vm_map_base = 0UL - (1UL << c->vabits);
diff --git a/arch/loongarch/lib/dump_tlb.c b/arch/loongarch/lib/dump_tlb.c
index 116f21ea4e2c..e1cdad7a676e 100644
--- a/arch/loongarch/lib/dump_tlb.c
+++ b/arch/loongarch/lib/dump_tlb.c
@@ -73,12 +73,16 @@ static void dump_tlb(int first, int last)
 			vwidth, (entryhi & ~0x1fffUL), asidwidth, asid & asidmask);
 
 		/* NR/NX are in awkward places, so mask them off separately */
+#ifdef CONFIG_64BIT
 		pa = entrylo0 & ~(ENTRYLO_NR | ENTRYLO_NX);
+#endif
 		pa = pa & PAGE_MASK;
 		pr_cont("\n\t[");
+#ifdef CONFIG_64BIT
 		pr_cont("nr=%d nx=%d ",
 			(entrylo0 & ENTRYLO_NR) ? 1 : 0,
 			(entrylo0 & ENTRYLO_NX) ? 1 : 0);
+#endif
 		pr_cont("pa=0x%0*llx c=%d d=%d v=%d g=%d plv=%lld] [",
 			pwidth, pa, c0,
 			(entrylo0 & ENTRYLO_D) ? 1 : 0,
@@ -86,11 +90,15 @@ static void dump_tlb(int first, int last)
 			(entrylo0 & ENTRYLO_G) ? 1 : 0,
 			(entrylo0 & ENTRYLO_PLV) >> ENTRYLO_PLV_SHIFT);
 		/* NR/NX are in awkward places, so mask them off separately */
+#ifdef CONFIG_64BIT
 		pa = entrylo1 & ~(ENTRYLO_NR | ENTRYLO_NX);
+#endif
 		pa = pa & PAGE_MASK;
+#ifdef CONFIG_64BIT
 		pr_cont("nr=%d nx=%d ",
 			(entrylo1 & ENTRYLO_NR) ? 1 : 0,
 			(entrylo1 & ENTRYLO_NX) ? 1 : 0);
+#endif
 		pr_cont("pa=0x%0*llx c=%d d=%d v=%d g=%d plv=%lld]\n",
 			pwidth, pa, c1,
 			(entrylo1 & ENTRYLO_D) ? 1 : 0,
diff --git a/arch/loongarch/mm/init.c b/arch/loongarch/mm/init.c
index 6bfd4b8dad1b..0946662afdd6 100644
--- a/arch/loongarch/mm/init.c
+++ b/arch/loongarch/mm/init.c
@@ -224,7 +224,7 @@ EXPORT_SYMBOL(invalid_pmd_table);
 pte_t invalid_pte_table[PTRS_PER_PTE] __page_aligned_bss;
 EXPORT_SYMBOL(invalid_pte_table);
 
-#ifdef CONFIG_EXECMEM
+#if defined(CONFIG_EXECMEM) && defined(MODULES_VADDR)
 static struct execmem_info execmem_info __ro_after_init;
 
 struct execmem_info __init *execmem_arch_setup(void)
@@ -242,4 +242,4 @@ struct execmem_info __init *execmem_arch_setup(void)
 
 	return &execmem_info;
 }
-#endif /* CONFIG_EXECMEM */
+#endif /* CONFIG_EXECMEM && MODULES_VADDR */
diff --git a/arch/loongarch/mm/page.S b/arch/loongarch/mm/page.S
index 7ad76551d313..7286b804756d 100644
--- a/arch/loongarch/mm/page.S
+++ b/arch/loongarch/mm/page.S
@@ -10,75 +10,75 @@
 
 	.align 5
 SYM_FUNC_START(clear_page)
-	lu12i.w	t0, 1 << (PAGE_SHIFT - 12)
-	add.d	t0, t0, a0
+	lu12i.w		t0, 1 << (PAGE_SHIFT - 12)
+	PTR_ADD		t0, t0, a0
 1:
-	st.d	zero, a0, 0
-	st.d	zero, a0, 8
-	st.d	zero, a0, 16
-	st.d	zero, a0, 24
-	st.d	zero, a0, 32
-	st.d	zero, a0, 40
-	st.d	zero, a0, 48
-	st.d	zero, a0, 56
-	addi.d	a0,   a0, 128
-	st.d	zero, a0, -64
-	st.d	zero, a0, -56
-	st.d	zero, a0, -48
-	st.d	zero, a0, -40
-	st.d	zero, a0, -32
-	st.d	zero, a0, -24
-	st.d	zero, a0, -16
-	st.d	zero, a0, -8
-	bne	t0,   a0, 1b
+	LONG_S		zero, a0, (LONGSIZE * 0)
+	LONG_S		zero, a0, (LONGSIZE * 1)
+	LONG_S		zero, a0, (LONGSIZE * 2)
+	LONG_S		zero, a0, (LONGSIZE * 3)
+	LONG_S		zero, a0, (LONGSIZE * 4)
+	LONG_S		zero, a0, (LONGSIZE * 5)
+	LONG_S		zero, a0, (LONGSIZE * 6)
+	LONG_S		zero, a0, (LONGSIZE * 7)
+	PTR_ADDI	a0,   a0, (LONGSIZE * 16)
+	LONG_S		zero, a0, -(LONGSIZE * 8)
+	LONG_S		zero, a0, -(LONGSIZE * 7)
+	LONG_S		zero, a0, -(LONGSIZE * 6)
+	LONG_S		zero, a0, -(LONGSIZE * 5)
+	LONG_S		zero, a0, -(LONGSIZE * 4)
+	LONG_S		zero, a0, -(LONGSIZE * 3)
+	LONG_S		zero, a0, -(LONGSIZE * 2)
+	LONG_S		zero, a0, -(LONGSIZE * 1)
+	bne		t0,   a0, 1b
 
-	jr	ra
+	jr		ra
 SYM_FUNC_END(clear_page)
 EXPORT_SYMBOL(clear_page)
 
 .align 5
 SYM_FUNC_START(copy_page)
-	lu12i.w	t8, 1 << (PAGE_SHIFT - 12)
-	add.d	t8, t8, a0
+	lu12i.w		t8, 1 << (PAGE_SHIFT - 12)
+	PTR_ADD		t8, t8, a0
 1:
-	ld.d	t0, a1, 0
-	ld.d	t1, a1, 8
-	ld.d	t2, a1, 16
-	ld.d	t3, a1, 24
-	ld.d	t4, a1, 32
-	ld.d	t5, a1, 40
-	ld.d	t6, a1, 48
-	ld.d	t7, a1, 56
+	LONG_L		t0, a1, (LONGSIZE * 0)
+	LONG_L		t1, a1, (LONGSIZE * 1)
+	LONG_L		t2, a1, (LONGSIZE * 2)
+	LONG_L		t3, a1, (LONGSIZE * 3)
+	LONG_L		t4, a1, (LONGSIZE * 4)
+	LONG_L		t5, a1, (LONGSIZE * 5)
+	LONG_L		t6, a1, (LONGSIZE * 6)
+	LONG_L		t7, a1, (LONGSIZE * 7)
 
-	st.d	t0, a0, 0
-	st.d	t1, a0, 8
-	ld.d	t0, a1, 64
-	ld.d	t1, a1, 72
-	st.d	t2, a0, 16
-	st.d	t3, a0, 24
-	ld.d	t2, a1, 80
-	ld.d	t3, a1, 88
-	st.d	t4, a0, 32
-	st.d	t5, a0, 40
-	ld.d	t4, a1, 96
-	ld.d	t5, a1, 104
-	st.d	t6, a0, 48
-	st.d	t7, a0, 56
-	ld.d	t6, a1, 112
-	ld.d	t7, a1, 120
-	addi.d	a0, a0, 128
-	addi.d	a1, a1, 128
+	LONG_S		t0, a0, (LONGSIZE * 0)
+	LONG_S		t1, a0, (LONGSIZE * 1)
+	LONG_L		t0, a1, (LONGSIZE * 8)
+	LONG_L		t1, a1, (LONGSIZE * 9)
+	LONG_S		t2, a0, (LONGSIZE * 2)
+	LONG_S		t3, a0, (LONGSIZE * 3)
+	LONG_L		t2, a1, (LONGSIZE * 10)
+	LONG_L		t3, a1, (LONGSIZE * 11)
+	LONG_S		t4, a0, (LONGSIZE * 4)
+	LONG_S		t5, a0, (LONGSIZE * 5)
+	LONG_L		t4, a1, (LONGSIZE * 12)
+	LONG_L		t5, a1, (LONGSIZE * 13)
+	LONG_S		t6, a0, (LONGSIZE * 6)
+	LONG_S		t7, a0, (LONGSIZE * 7)
+	LONG_L		t6, a1, (LONGSIZE * 14)
+	LONG_L		t7, a1, (LONGSIZE * 15)
+	PTR_ADDI	a0, a0, (LONGSIZE * 16)
+	PTR_ADDI	a1, a1, (LONGSIZE * 16)
 
-	st.d	t0, a0, -64
-	st.d	t1, a0, -56
-	st.d	t2, a0, -48
-	st.d	t3, a0, -40
-	st.d	t4, a0, -32
-	st.d	t5, a0, -24
-	st.d	t6, a0, -16
-	st.d	t7, a0, -8
+	LONG_S		t0, a0, -(LONGSIZE * 8)
+	LONG_S		t1, a0, -(LONGSIZE * 7)
+	LONG_S		t2, a0, -(LONGSIZE * 6)
+	LONG_S		t3, a0, -(LONGSIZE * 5)
+	LONG_S		t4, a0, -(LONGSIZE * 4)
+	LONG_S		t5, a0, -(LONGSIZE * 3)
+	LONG_S		t6, a0, -(LONGSIZE * 2)
+	LONG_S		t7, a0, -(LONGSIZE * 1)
 
-	bne	t8, a0, 1b
-	jr	ra
+	bne		t8, a0, 1b
+	jr		ra
 SYM_FUNC_END(copy_page)
 EXPORT_SYMBOL(copy_page)
diff --git a/arch/loongarch/mm/tlb.c b/arch/loongarch/mm/tlb.c
index 6e474469e210..6a3c91b9cacd 100644
--- a/arch/loongarch/mm/tlb.c
+++ b/arch/loongarch/mm/tlb.c
@@ -251,8 +251,10 @@ static void output_pgtable_bits_defines(void)
 	pr_define("_PAGE_GLOBAL_SHIFT %d\n", _PAGE_GLOBAL_SHIFT);
 	pr_define("_PAGE_PRESENT_SHIFT %d\n", _PAGE_PRESENT_SHIFT);
 	pr_define("_PAGE_WRITE_SHIFT %d\n", _PAGE_WRITE_SHIFT);
+#ifdef CONFIG_64BIT
 	pr_define("_PAGE_NO_READ_SHIFT %d\n", _PAGE_NO_READ_SHIFT);
 	pr_define("_PAGE_NO_EXEC_SHIFT %d\n", _PAGE_NO_EXEC_SHIFT);
+#endif
 	pr_define("PFN_PTE_SHIFT %d\n", PFN_PTE_SHIFT);
 	pr_debug("\n");
 }
diff --git a/arch/loongarch/mm/tlbex.S b/arch/loongarch/mm/tlbex.S
index c08682a89c58..84a881a339a7 100644
--- a/arch/loongarch/mm/tlbex.S
+++ b/arch/loongarch/mm/tlbex.S
@@ -11,10 +11,18 @@
 
 #define INVTLB_ADDR_GFALSE_AND_ASID	5
 
-#define PTRS_PER_PGD_BITS	(PAGE_SHIFT - 3)
-#define PTRS_PER_PUD_BITS	(PAGE_SHIFT - 3)
-#define PTRS_PER_PMD_BITS	(PAGE_SHIFT - 3)
-#define PTRS_PER_PTE_BITS	(PAGE_SHIFT - 3)
+#define PTRS_PER_PGD_BITS	(PAGE_SHIFT - PTRLOG)
+#define PTRS_PER_PUD_BITS	(PAGE_SHIFT - PTRLOG)
+#define PTRS_PER_PMD_BITS	(PAGE_SHIFT - PTRLOG)
+#define PTRS_PER_PTE_BITS	(PAGE_SHIFT - PTRLOG)
+
+#ifdef CONFIG_32BIT
+#define PTE_LL	ll.w
+#define PTE_SC	sc.w
+#else
+#define PTE_LL	ll.d
+#define PTE_SC	sc.d
+#endif
 
 	.macro tlb_do_page_fault, write
 	SYM_CODE_START(tlb_do_page_fault_\write)
@@ -60,52 +68,61 @@ SYM_CODE_START(handle_tlb_load)
 
 vmalloc_done_load:
 	/* Get PGD offset in bytes */
-	bstrpick.d	ra, t0, PTRS_PER_PGD_BITS + PGDIR_SHIFT - 1, PGDIR_SHIFT
-	alsl.d		t1, ra, t1, 3
+#ifdef CONFIG_32BIT
+	PTR_BSTRPICK	ra, t0, 31, PGDIR_SHIFT
+#else
+	PTR_BSTRPICK	ra, t0, PTRS_PER_PGD_BITS + PGDIR_SHIFT - 1, PGDIR_SHIFT
+#endif
+	PTR_ALSL	t1, ra, t1, _PGD_T_LOG2
+
 #if CONFIG_PGTABLE_LEVELS > 3
-	ld.d		t1, t1, 0
-	bstrpick.d	ra, t0, PTRS_PER_PUD_BITS + PUD_SHIFT - 1, PUD_SHIFT
-	alsl.d		t1, ra, t1, 3
+	PTR_L		t1, t1, 0
+	PTR_BSTRPICK	ra, t0, PTRS_PER_PUD_BITS + PUD_SHIFT - 1, PUD_SHIFT
+	PTR_ALSL	t1, ra, t1, _PMD_T_LOG2
+
 #endif
 #if CONFIG_PGTABLE_LEVELS > 2
-	ld.d		t1, t1, 0
-	bstrpick.d	ra, t0, PTRS_PER_PMD_BITS + PMD_SHIFT - 1, PMD_SHIFT
-	alsl.d		t1, ra, t1, 3
+	PTR_L		t1, t1, 0
+	PTR_BSTRPICK	ra, t0, PTRS_PER_PMD_BITS + PMD_SHIFT - 1, PMD_SHIFT
+	PTR_ALSL	t1, ra, t1, _PMD_T_LOG2
+
 #endif
-	ld.d		ra, t1, 0
+	PTR_L		ra, t1, 0
 
 	/*
 	 * For huge tlb entries, pmde doesn't contain an address but
 	 * instead contains the tlb pte. Check the PAGE_HUGE bit and
 	 * see if we need to jump to huge tlb processing.
 	 */
-	rotri.d		ra, ra, _PAGE_HUGE_SHIFT + 1
+	PTR_ROTRI	ra, ra, _PAGE_HUGE_SHIFT + 1
 	bltz		ra, tlb_huge_update_load
 
-	rotri.d		ra, ra, 64 - (_PAGE_HUGE_SHIFT + 1)
-	bstrpick.d	t0, t0, PTRS_PER_PTE_BITS + PAGE_SHIFT - 1, PAGE_SHIFT
-	alsl.d		t1, t0, ra, _PTE_T_LOG2
+	PTR_ROTRI	ra, ra, BITS_PER_LONG - (_PAGE_HUGE_SHIFT + 1)
+	PTR_BSTRPICK	t0, t0, PTRS_PER_PTE_BITS + PAGE_SHIFT - 1, PAGE_SHIFT
+	PTR_ALSL	t1, t0, ra, _PTE_T_LOG2
 
 #ifdef CONFIG_SMP
 smp_pgtable_change_load:
-	ll.d		t0, t1, 0
+	PTE_LL		t0, t1, 0
 #else
-	ld.d		t0, t1, 0
+	PTR_L		t0, t1, 0
 #endif
 	andi		ra, t0, _PAGE_PRESENT
 	beqz		ra, nopage_tlb_load
 
 	ori		t0, t0, _PAGE_VALID
+
 #ifdef CONFIG_SMP
-	sc.d		t0, t1, 0
+	PTE_SC		t0, t1, 0
 	beqz		t0, smp_pgtable_change_load
 #else
-	st.d		t0, t1, 0
+	PTR_S		t0, t1, 0
 #endif
+
 	tlbsrch
-	bstrins.d	t1, zero, 3, 3
-	ld.d		t0, t1, 0
-	ld.d		t1, t1, 8
+	PTR_BSTRINS	t1, zero, _PTE_T_LOG2, _PTE_T_LOG2
+	PTR_L		t0, t1, 0
+	PTR_L		t1, t1, _PTE_T_SIZE
 	csrwr		t0, LOONGARCH_CSR_TLBELO0
 	csrwr		t1, LOONGARCH_CSR_TLBELO1
 	tlbwr
@@ -115,30 +132,28 @@ smp_pgtable_change_load:
 	csrrd		ra, EXCEPTION_KS2
 	ertn
 
-#ifdef CONFIG_64BIT
 vmalloc_load:
 	la_abs		t1, swapper_pg_dir
 	b		vmalloc_done_load
-#endif
 
 	/* This is the entry point of a huge page. */
 tlb_huge_update_load:
 #ifdef CONFIG_SMP
-	ll.d		ra, t1, 0
+	PTE_LL		ra, t1, 0
 #else
-	rotri.d		ra, ra, 64 - (_PAGE_HUGE_SHIFT + 1)
+	PTR_ROTRI	ra, ra, BITS_PER_LONG - (_PAGE_HUGE_SHIFT + 1)
 #endif
 	andi		t0, ra, _PAGE_PRESENT
 	beqz		t0, nopage_tlb_load
 
 #ifdef CONFIG_SMP
 	ori		t0, ra, _PAGE_VALID
-	sc.d		t0, t1, 0
+	PTE_SC		t0, t1, 0
 	beqz		t0, tlb_huge_update_load
 	ori		t0, ra, _PAGE_VALID
 #else
 	ori		t0, ra, _PAGE_VALID
-	st.d		t0, t1, 0
+	PTR_S		t0, t1, 0
 #endif
 	csrrd		ra, LOONGARCH_CSR_ASID
 	csrrd		t1, LOONGARCH_CSR_BADV
@@ -158,27 +173,27 @@ tlb_huge_update_load:
 	xori		t0, t0, _PAGE_HUGE
 	lu12i.w		t1, _PAGE_HGLOBAL >> 12
 	and		t1, t0, t1
-	srli.d		t1, t1, (_PAGE_HGLOBAL_SHIFT - _PAGE_GLOBAL_SHIFT)
+	PTR_SRLI	t1, t1, (_PAGE_HGLOBAL_SHIFT - _PAGE_GLOBAL_SHIFT)
 	or		t0, t0, t1
 
 	move		ra, t0
 	csrwr		ra, LOONGARCH_CSR_TLBELO0
 
 	/* Convert to entrylo1 */
-	addi.d		t1, zero, 1
-	slli.d		t1, t1, (HPAGE_SHIFT - 1)
-	add.d		t0, t0, t1
+	PTR_ADDI	t1, zero, 1
+	PTR_SLLI	t1, t1, (HPAGE_SHIFT - 1)
+	PTR_ADD		t0, t0, t1
 	csrwr		t0, LOONGARCH_CSR_TLBELO1
 
 	/* Set huge page tlb entry size */
-	addu16i.d	t0, zero, (CSR_TLBIDX_PS >> 16)
-	addu16i.d	t1, zero, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
+	PTR_LI		t0, (CSR_TLBIDX_PS >> 16) << 16
+	PTR_LI		t1, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT))
 	csrxchg		t1, t0, LOONGARCH_CSR_TLBIDX
 
 	tlbfill
 
-	addu16i.d	t0, zero, (CSR_TLBIDX_PS >> 16)
-	addu16i.d	t1, zero, (PS_DEFAULT_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
+	PTR_LI		t0, (CSR_TLBIDX_PS >> 16) << 16
+	PTR_LI		t1, (PS_DEFAULT_SIZE << (CSR_TLBIDX_PS_SHIFT))
 	csrxchg		t1, t0, LOONGARCH_CSR_TLBIDX
 
 	csrrd		t0, EXCEPTION_KS0
@@ -216,53 +231,71 @@ SYM_CODE_START(handle_tlb_store)
 
 vmalloc_done_store:
 	/* Get PGD offset in bytes */
-	bstrpick.d	ra, t0, PTRS_PER_PGD_BITS + PGDIR_SHIFT - 1, PGDIR_SHIFT
-	alsl.d		t1, ra, t1, 3
+#ifdef CONFIG_32BIT
+	PTR_BSTRPICK	ra, t0, 31, PGDIR_SHIFT
+#else
+	PTR_BSTRPICK	ra, t0, PTRS_PER_PGD_BITS + PGDIR_SHIFT - 1, PGDIR_SHIFT
+#endif
+	PTR_ALSL	t1, ra, t1, _PGD_T_LOG2
+
 #if CONFIG_PGTABLE_LEVELS > 3
-	ld.d		t1, t1, 0
-	bstrpick.d	ra, t0, PTRS_PER_PUD_BITS + PUD_SHIFT - 1, PUD_SHIFT
-	alsl.d		t1, ra, t1, 3
+	PTR_L		t1, t1, 0
+	PTR_BSTRPICK	ra, t0, PTRS_PER_PUD_BITS + PUD_SHIFT - 1, PUD_SHIFT
+	PTR_ALSL	t1, ra, t1, _PMD_T_LOG2
 #endif
 #if CONFIG_PGTABLE_LEVELS > 2
-	ld.d		t1, t1, 0
-	bstrpick.d	ra, t0, PTRS_PER_PMD_BITS + PMD_SHIFT - 1, PMD_SHIFT
-	alsl.d		t1, ra, t1, 3
+	PTR_L		t1, t1, 0
+	PTR_BSTRPICK	ra, t0, PTRS_PER_PMD_BITS + PMD_SHIFT - 1, PMD_SHIFT
+	PTR_ALSL	t1, ra, t1, _PMD_T_LOG2
 #endif
-	ld.d		ra, t1, 0
+	PTR_L		ra, t1, 0
 
 	/*
 	 * For huge tlb entries, pmde doesn't contain an address but
 	 * instead contains the tlb pte. Check the PAGE_HUGE bit and
 	 * see if we need to jump to huge tlb processing.
 	 */
-	rotri.d		ra, ra, _PAGE_HUGE_SHIFT + 1
+	PTR_ROTRI	ra, ra, _PAGE_HUGE_SHIFT + 1
 	bltz		ra, tlb_huge_update_store
 
-	rotri.d		ra, ra, 64 - (_PAGE_HUGE_SHIFT + 1)
-	bstrpick.d	t0, t0, PTRS_PER_PTE_BITS + PAGE_SHIFT - 1, PAGE_SHIFT
-	alsl.d		t1, t0, ra, _PTE_T_LOG2
+	PTR_ROTRI	ra, ra, BITS_PER_LONG - (_PAGE_HUGE_SHIFT + 1)
+	PTR_BSTRPICK	t0, t0, PTRS_PER_PTE_BITS + PAGE_SHIFT - 1, PAGE_SHIFT
+	PTR_ALSL	t1, t0, ra, _PTE_T_LOG2
 
 #ifdef CONFIG_SMP
 smp_pgtable_change_store:
-	ll.d		t0, t1, 0
+	PTE_LL		t0, t1, 0
 #else
-	ld.d		t0, t1, 0
+	PTR_L		t0, t1, 0
 #endif
+
+#ifdef CONFIG_64BIT
 	andi		ra, t0, _PAGE_PRESENT | _PAGE_WRITE
 	xori		ra, ra, _PAGE_PRESENT | _PAGE_WRITE
+#else
+	PTR_LI		ra, _PAGE_PRESENT | _PAGE_WRITE
+	and		ra, ra, t0
+	nor		ra, ra, zero
+#endif
 	bnez		ra, nopage_tlb_store
 
+#ifdef CONFIG_64BIT
 	ori		t0, t0, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
+#else
+	PTR_LI		ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
+	or		t0, ra, t0
+#endif
+
 #ifdef CONFIG_SMP
-	sc.d		t0, t1, 0
+	PTE_SC		t0, t1, 0
 	beqz		t0, smp_pgtable_change_store
 #else
-	st.d		t0, t1, 0
+	PTR_S		t0, t1, 0
 #endif
 	tlbsrch
-	bstrins.d	t1, zero, 3, 3
-	ld.d		t0, t1, 0
-	ld.d		t1, t1, 8
+	PTR_BSTRINS	t1, zero, _PTE_T_LOG2, _PTE_T_LOG2
+	PTR_L		t0, t1, 0
+	PTR_L		t1, t1, _PTE_T_SIZE
 	csrwr		t0, LOONGARCH_CSR_TLBELO0
 	csrwr		t1, LOONGARCH_CSR_TLBELO1
 	tlbwr
@@ -272,31 +305,42 @@ smp_pgtable_change_store:
 	csrrd		ra, EXCEPTION_KS2
 	ertn
 
-#ifdef CONFIG_64BIT
 vmalloc_store:
 	la_abs		t1, swapper_pg_dir
 	b		vmalloc_done_store
-#endif
 
 	/* This is the entry point of a huge page. */
 tlb_huge_update_store:
 #ifdef CONFIG_SMP
-	ll.d		ra, t1, 0
+	PTE_LL		ra, t1, 0
 #else
-	rotri.d		ra, ra, 64 - (_PAGE_HUGE_SHIFT + 1)
+	PTR_ROTRI	ra, ra, BITS_PER_LONG - (_PAGE_HUGE_SHIFT + 1)
 #endif
+
+#ifdef CONFIG_64BIT
 	andi		t0, ra, _PAGE_PRESENT | _PAGE_WRITE
 	xori		t0, t0, _PAGE_PRESENT | _PAGE_WRITE
+#else
+	PTR_LI		t0, _PAGE_PRESENT | _PAGE_WRITE
+	and		t0, t0, ra
+	nor		t0, t0, zero
+#endif
+
 	bnez		t0, nopage_tlb_store
 
 #ifdef CONFIG_SMP
 	ori		t0, ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
-	sc.d		t0, t1, 0
+	PTE_SC		t0, t1, 0
 	beqz		t0, tlb_huge_update_store
 	ori		t0, ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
 #else
+#ifdef CONFIG_64BIT
 	ori		t0, ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
-	st.d		t0, t1, 0
+#else
+	PTR_LI		t0, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
+	or		t0, ra, t0
+#endif
+	PTR_S		t0, t1, 0
 #endif
 	csrrd		ra, LOONGARCH_CSR_ASID
 	csrrd		t1, LOONGARCH_CSR_BADV
@@ -316,28 +360,28 @@ tlb_huge_update_store:
 	xori		t0, t0, _PAGE_HUGE
 	lu12i.w		t1, _PAGE_HGLOBAL >> 12
 	and		t1, t0, t1
-	srli.d		t1, t1, (_PAGE_HGLOBAL_SHIFT - _PAGE_GLOBAL_SHIFT)
+	PTR_SRLI	t1, t1, (_PAGE_HGLOBAL_SHIFT - _PAGE_GLOBAL_SHIFT)
 	or		t0, t0, t1
 
 	move		ra, t0
 	csrwr		ra, LOONGARCH_CSR_TLBELO0
 
 	/* Convert to entrylo1 */
-	addi.d		t1, zero, 1
-	slli.d		t1, t1, (HPAGE_SHIFT - 1)
-	add.d		t0, t0, t1
+	PTR_ADDI	t1, zero, 1
+	PTR_SLLI	t1, t1, (HPAGE_SHIFT - 1)
+	PTR_ADD		t0, t0, t1
 	csrwr		t0, LOONGARCH_CSR_TLBELO1
 
 	/* Set huge page tlb entry size */
-	addu16i.d	t0, zero, (CSR_TLBIDX_PS >> 16)
-	addu16i.d	t1, zero, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
+	PTR_LI		t0, (CSR_TLBIDX_PS >> 16) << 16
+	PTR_LI		t1, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT))
 	csrxchg		t1, t0, LOONGARCH_CSR_TLBIDX
 
 	tlbfill
 
 	/* Reset default page size */
-	addu16i.d	t0, zero, (CSR_TLBIDX_PS >> 16)
-	addu16i.d	t1, zero, (PS_DEFAULT_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
+	PTR_LI		t0, (CSR_TLBIDX_PS >> 16) << 16
+	PTR_LI		t1, (PS_DEFAULT_SIZE << (CSR_TLBIDX_PS_SHIFT))
 	csrxchg		t1, t0, LOONGARCH_CSR_TLBIDX
 
 	csrrd		t0, EXCEPTION_KS0
@@ -375,52 +419,69 @@ SYM_CODE_START(handle_tlb_modify)
 
 vmalloc_done_modify:
 	/* Get PGD offset in bytes */
-	bstrpick.d	ra, t0, PTRS_PER_PGD_BITS + PGDIR_SHIFT - 1, PGDIR_SHIFT
-	alsl.d		t1, ra, t1, 3
+#ifdef CONFIG_32BIT
+	PTR_BSTRPICK	ra, t0, 31, PGDIR_SHIFT
+#else
+	PTR_BSTRPICK	ra, t0, PTRS_PER_PGD_BITS + PGDIR_SHIFT - 1, PGDIR_SHIFT
+#endif
+	PTR_ALSL	t1, ra, t1, _PGD_T_LOG2
+
 #if CONFIG_PGTABLE_LEVELS > 3
-	ld.d		t1, t1, 0
-	bstrpick.d	ra, t0, PTRS_PER_PUD_BITS + PUD_SHIFT - 1, PUD_SHIFT
-	alsl.d		t1, ra, t1, 3
+	PTR_L		t1, t1, 0
+	PTR_BSTRPICK	ra, t0, PTRS_PER_PUD_BITS + PUD_SHIFT - 1, PUD_SHIFT
+	PTR_ALSL	t1, ra, t1, _PMD_T_LOG2
 #endif
 #if CONFIG_PGTABLE_LEVELS > 2
-	ld.d		t1, t1, 0
-	bstrpick.d	ra, t0, PTRS_PER_PMD_BITS + PMD_SHIFT - 1, PMD_SHIFT
-	alsl.d		t1, ra, t1, 3
+	PTR_L		t1, t1, 0
+	PTR_BSTRPICK	ra, t0, PTRS_PER_PMD_BITS + PMD_SHIFT - 1, PMD_SHIFT
+	PTR_ALSL	t1, ra, t1, _PMD_T_LOG2
 #endif
-	ld.d		ra, t1, 0
+	PTR_L		ra, t1, 0
 
 	/*
 	 * For huge tlb entries, pmde doesn't contain an address but
 	 * instead contains the tlb pte. Check the PAGE_HUGE bit and
 	 * see if we need to jump to huge tlb processing.
 	 */
-	rotri.d		ra, ra, _PAGE_HUGE_SHIFT + 1
+	PTR_ROTRI	ra, ra, _PAGE_HUGE_SHIFT + 1
 	bltz		ra, tlb_huge_update_modify
 
-	rotri.d		ra, ra, 64 - (_PAGE_HUGE_SHIFT + 1)
-	bstrpick.d	t0, t0, PTRS_PER_PTE_BITS + PAGE_SHIFT - 1, PAGE_SHIFT
-	alsl.d		t1, t0, ra, _PTE_T_LOG2
+	PTR_ROTRI	ra, ra, BITS_PER_LONG - (_PAGE_HUGE_SHIFT + 1)
+	PTR_BSTRPICK	t0, t0, PTRS_PER_PTE_BITS + PAGE_SHIFT - 1, PAGE_SHIFT
+	PTR_ALSL	t1, t0, ra, _PTE_T_LOG2
 
 #ifdef CONFIG_SMP
 smp_pgtable_change_modify:
-	ll.d		t0, t1, 0
+	PTE_LL		t0, t1, 0
 #else
-	ld.d		t0, t1, 0
+	PTR_L		t0, t1, 0
 #endif
+#ifdef CONFIG_64BIT
 	andi		ra, t0, _PAGE_WRITE
+#else
+	PTR_LI		ra, _PAGE_WRITE
+	and 		ra, t0, ra
+#endif
+
 	beqz		ra, nopage_tlb_modify
 
+#ifdef CONFIG_64BIT
 	ori		t0, t0, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
+#else
+	PTR_LI		ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
+	or		t0, ra, t0
+#endif
+
 #ifdef CONFIG_SMP
-	sc.d		t0, t1, 0
+	PTE_SC		t0, t1, 0
 	beqz		t0, smp_pgtable_change_modify
 #else
-	st.d		t0, t1, 0
+	PTR_S		t0, t1, 0
 #endif
 	tlbsrch
-	bstrins.d	t1, zero, 3, 3
-	ld.d		t0, t1, 0
-	ld.d		t1, t1, 8
+	PTR_BSTRINS	t1, zero, _PTE_T_LOG2, _PTE_T_LOG2
+	PTR_L		t0, t1, 0
+	PTR_L		t1, t1, _PTE_T_SIZE
 	csrwr		t0, LOONGARCH_CSR_TLBELO0
 	csrwr		t1, LOONGARCH_CSR_TLBELO1
 	tlbwr
@@ -430,30 +491,40 @@ smp_pgtable_change_modify:
 	csrrd		ra, EXCEPTION_KS2
 	ertn
 
-#ifdef CONFIG_64BIT
 vmalloc_modify:
 	la_abs		t1, swapper_pg_dir
 	b		vmalloc_done_modify
-#endif
 
 	/* This is the entry point of a huge page. */
 tlb_huge_update_modify:
 #ifdef CONFIG_SMP
-	ll.d		ra, t1, 0
+	PTE_LL		ra, t1, 0
 #else
-	rotri.d		ra, ra, 64 - (_PAGE_HUGE_SHIFT + 1)
+	PTR_ROTRI	ra, ra, BITS_PER_LONG - (_PAGE_HUGE_SHIFT + 1)
 #endif
+
+#ifdef CONFIG_64BIT
 	andi		t0, ra, _PAGE_WRITE
+#else
+	PTR_LI		t0, _PAGE_WRITE
+	and 		t0, ra, t0
+#endif
+
 	beqz		t0, nopage_tlb_modify
 
 #ifdef CONFIG_SMP
 	ori		t0, ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
-	sc.d		t0, t1, 0
+	PTE_SC		t0, t1, 0
 	beqz		t0, tlb_huge_update_modify
 	ori		t0, ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
 #else
+#ifdef CONFIG_64BIT
 	ori		t0, ra, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
-	st.d		t0, t1, 0
+#else
+	PTR_LI		t0, (_PAGE_VALID | _PAGE_DIRTY | _PAGE_MODIFIED)
+	or		t0, ra, t0
+#endif
+	PTR_S		t0, t1, 0
 #endif
 	csrrd		ra, LOONGARCH_CSR_ASID
 	csrrd		t1, LOONGARCH_CSR_BADV
@@ -473,28 +544,28 @@ tlb_huge_update_modify:
 	xori		t0, t0, _PAGE_HUGE
 	lu12i.w		t1, _PAGE_HGLOBAL >> 12
 	and		t1, t0, t1
-	srli.d		t1, t1, (_PAGE_HGLOBAL_SHIFT - _PAGE_GLOBAL_SHIFT)
+	PTR_SRLI	t1, t1, (_PAGE_HGLOBAL_SHIFT - _PAGE_GLOBAL_SHIFT)
 	or		t0, t0, t1
 
 	move		ra, t0
 	csrwr		ra, LOONGARCH_CSR_TLBELO0
 
 	/* Convert to entrylo1 */
-	addi.d		t1, zero, 1
-	slli.d		t1, t1, (HPAGE_SHIFT - 1)
-	add.d		t0, t0, t1
+	PTR_ADDI	t1, zero, 1
+	PTR_SLLI	t1, t1, (HPAGE_SHIFT - 1)
+	PTR_ADD		t0, t0, t1
 	csrwr		t0, LOONGARCH_CSR_TLBELO1
 
 	/* Set huge page tlb entry size */
-	addu16i.d	t0, zero, (CSR_TLBIDX_PS >> 16)
-	addu16i.d	t1, zero, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
+	PTR_LI		t0, (CSR_TLBIDX_PS >> 16) << 16
+	PTR_LI		t1, (PS_HUGE_SIZE << (CSR_TLBIDX_PS_SHIFT))
 	csrxchg		t1, t0, LOONGARCH_CSR_TLBIDX
 
 	tlbfill
 
 	/* Reset default page size */
-	addu16i.d	t0, zero, (CSR_TLBIDX_PS >> 16)
-	addu16i.d	t1, zero, (PS_DEFAULT_SIZE << (CSR_TLBIDX_PS_SHIFT - 16))
+	PTR_LI		t0, (CSR_TLBIDX_PS >> 16) << 16
+	PTR_LI		t1, (PS_DEFAULT_SIZE << (CSR_TLBIDX_PS_SHIFT))
 	csrxchg		t1, t0, LOONGARCH_CSR_TLBIDX
 
 	csrrd		t0, EXCEPTION_KS0
@@ -517,6 +588,44 @@ SYM_CODE_START(handle_tlb_modify_ptw)
 	jr		t0
 SYM_CODE_END(handle_tlb_modify_ptw)
 
+#ifdef CONFIG_32BIT
+SYM_CODE_START(handle_tlb_refill)
+	UNWIND_HINT_UNDEFINED
+	csrwr		t0, EXCEPTION_KS0
+	csrwr		t1, EXCEPTION_KS1
+	csrwr		ra, EXCEPTION_KS2
+	li.w		ra, 0x1fffffff
+
+	csrrd		t0, LOONGARCH_CSR_PGD
+	csrrd		t1, LOONGARCH_CSR_TLBRBADV
+	srli.w		t1, t1, PGDIR_SHIFT
+	slli.w		t1, t1, 0x2
+	add.w		t0, t0, t1
+	and		t0, t0, ra
+
+	ld.w		t0, t0, 0
+	csrrd		t1, LOONGARCH_CSR_TLBRBADV
+	slli.w		t1, t1, (32 - PGDIR_SHIFT)
+	srli.w		t1, t1, (32 - PGDIR_SHIFT + PAGE_SHIFT + 1)
+	slli.w		t1, t1, (0x2 + 1)
+	add.w		t0, t0, t1
+	and		t0, t0, ra
+
+	ld.w		t1, t0, 0x0
+	csrwr		t1, LOONGARCH_CSR_TLBRELO0
+
+	ld.w		t1, t0, 0x4
+	csrwr		t1, LOONGARCH_CSR_TLBRELO1
+
+	tlbfill
+	csrrd		t0, EXCEPTION_KS0
+	csrrd		t1, EXCEPTION_KS1
+	csrrd		ra, EXCEPTION_KS2
+	ertn
+SYM_CODE_END(handle_tlb_refill)
+#endif
+
+#ifdef CONFIG_64BIT
 SYM_CODE_START(handle_tlb_refill)
 	UNWIND_HINT_UNDEFINED
 	csrwr		t0, LOONGARCH_CSR_TLBRSAVE
@@ -534,3 +643,4 @@ SYM_CODE_START(handle_tlb_refill)
 	csrrd		t0, LOONGARCH_CSR_TLBRSAVE
 	ertn
 SYM_CODE_END(handle_tlb_refill)
+#endif
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH V2 06/14] LoongArch: Adjust process management for 32BIT/64BIT
  2025-11-18 11:27 [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Huacai Chen
                   ` (4 preceding siblings ...)
  2025-11-18 11:27 ` [PATCH V2 05/14] LoongArch: Adjust memory management " Huacai Chen
@ 2025-11-18 11:27 ` Huacai Chen
  2025-11-18 11:27 ` [PATCH V2 07/14] LoongArch: Adjust time routines " Huacai Chen
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 37+ messages in thread
From: Huacai Chen @ 2025-11-18 11:27 UTC (permalink / raw)
  To: Arnd Bergmann, Huacai Chen
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Xuerui Wang,
	Jiaxun Yang, linux-kernel, Huacai Chen

Adjust memory management for both 32BIT and 64BIT, including: CPU
context switching, FPU loading/restoring, process dumping and process
tracing routines.

Q: Why modify switch.S?
A: LoongArch32 has no ldptr.d/stptr.d instructions, and asm offsets of
   thead_struct members are too large to be filled in the 12b immediate
   field of ld.w/st.w.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
 arch/loongarch/include/asm/elf.h         |   1 +
 arch/loongarch/include/asm/inst.h        |  12 ++-
 arch/loongarch/include/uapi/asm/ptrace.h |  10 ++
 arch/loongarch/kernel/fpu.S              | 111 +++++++++++++++++++++++
 arch/loongarch/kernel/process.c          |   6 +-
 arch/loongarch/kernel/ptrace.c           |   5 +
 arch/loongarch/kernel/switch.S           |  25 +++--
 7 files changed, 157 insertions(+), 13 deletions(-)

diff --git a/arch/loongarch/include/asm/elf.h b/arch/loongarch/include/asm/elf.h
index f16bd42456e4..1b6489427e30 100644
--- a/arch/loongarch/include/asm/elf.h
+++ b/arch/loongarch/include/asm/elf.h
@@ -156,6 +156,7 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 typedef double elf_fpreg_t;
 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
 
+void loongarch_dump_regs32(u32 *uregs, const struct pt_regs *regs);
 void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs);
 
 #ifdef CONFIG_32BIT
diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm/inst.h
index 55e64a12a124..f9f207082d0e 100644
--- a/arch/loongarch/include/asm/inst.h
+++ b/arch/loongarch/include/asm/inst.h
@@ -438,8 +438,10 @@ static inline bool is_branch_ins(union loongarch_instruction *ip)
 
 static inline bool is_ra_save_ins(union loongarch_instruction *ip)
 {
-	/* st.d $ra, $sp, offset */
-	return ip->reg2i12_format.opcode == std_op &&
+	const u32 opcode = IS_ENABLED(CONFIG_32BIT) ? stw_op : std_op;
+
+	/* st.w / st.d $ra, $sp, offset */
+	return ip->reg2i12_format.opcode == opcode &&
 		ip->reg2i12_format.rj == LOONGARCH_GPR_SP &&
 		ip->reg2i12_format.rd == LOONGARCH_GPR_RA &&
 		!is_imm12_negative(ip->reg2i12_format.immediate);
@@ -447,8 +449,10 @@ static inline bool is_ra_save_ins(union loongarch_instruction *ip)
 
 static inline bool is_stack_alloc_ins(union loongarch_instruction *ip)
 {
-	/* addi.d $sp, $sp, -imm */
-	return ip->reg2i12_format.opcode == addid_op &&
+	const u32 opcode = IS_ENABLED(CONFIG_32BIT) ? addiw_op : addid_op;
+
+	/* addi.w / addi.d $sp, $sp, -imm */
+	return ip->reg2i12_format.opcode == opcode &&
 		ip->reg2i12_format.rj == LOONGARCH_GPR_SP &&
 		ip->reg2i12_format.rd == LOONGARCH_GPR_SP &&
 		is_imm12_negative(ip->reg2i12_format.immediate);
diff --git a/arch/loongarch/include/uapi/asm/ptrace.h b/arch/loongarch/include/uapi/asm/ptrace.h
index 215e0f9e8aa3..b35c794323bc 100644
--- a/arch/loongarch/include/uapi/asm/ptrace.h
+++ b/arch/loongarch/include/uapi/asm/ptrace.h
@@ -61,8 +61,13 @@ struct user_lbt_state {
 struct user_watch_state {
 	__u64 dbg_info;
 	struct {
+#if __BITS_PER_LONG == 32
+		__u32    addr;
+		__u32    mask;
+#else
 		__u64    addr;
 		__u64    mask;
+#endif
 		__u32    ctrl;
 		__u32    pad;
 	} dbg_regs[8];
@@ -71,8 +76,13 @@ struct user_watch_state {
 struct user_watch_state_v2 {
 	__u64 dbg_info;
 	struct {
+#if __BITS_PER_LONG == 32
+		__u32    addr;
+		__u32    mask;
+#else
 		__u64    addr;
 		__u64    mask;
+#endif
 		__u32    ctrl;
 		__u32    pad;
 	} dbg_regs[14];
diff --git a/arch/loongarch/kernel/fpu.S b/arch/loongarch/kernel/fpu.S
index 28caf416ae36..f225dcc5b530 100644
--- a/arch/loongarch/kernel/fpu.S
+++ b/arch/loongarch/kernel/fpu.S
@@ -96,6 +96,49 @@
 	EX	fld.d	$f31, \base, (31 * FPU_REG_WIDTH)
 	.endm
 
+#ifdef CONFIG_32BIT
+	.macro sc_save_fcc thread tmp0 tmp1
+	movcf2gr	\tmp0, $fcc0
+	move		\tmp1, \tmp0
+	movcf2gr	\tmp0, $fcc1
+	bstrins.w	\tmp1, \tmp0, 15, 8
+	movcf2gr	\tmp0, $fcc2
+	bstrins.w	\tmp1, \tmp0, 23, 16
+	movcf2gr	\tmp0, $fcc3
+	bstrins.w	\tmp1, \tmp0, 31, 24
+	EX	st.w	\tmp1, \thread, THREAD_FCC
+	movcf2gr	\tmp0, $fcc4
+	move		\tmp1, \tmp0
+	movcf2gr	\tmp0, $fcc5
+	bstrins.w	\tmp1, \tmp0, 15, 8
+	movcf2gr	\tmp0, $fcc6
+	bstrins.w	\tmp1, \tmp0, 23, 16
+	movcf2gr	\tmp0, $fcc7
+	bstrins.w	\tmp1, \tmp0, 31, 24
+	EX	st.w	\tmp1, \thread, (THREAD_FCC + 4)
+	.endm
+
+	.macro sc_restore_fcc thread tmp0 tmp1
+	EX	ld.w	\tmp0, \thread, THREAD_FCC
+	bstrpick.w	\tmp1, \tmp0, 7, 0
+	movgr2cf	$fcc0, \tmp1
+	bstrpick.w	\tmp1, \tmp0, 15, 8
+	movgr2cf	$fcc1, \tmp1
+	bstrpick.w	\tmp1, \tmp0, 23, 16
+	movgr2cf	$fcc2, \tmp1
+	bstrpick.w	\tmp1, \tmp0, 31, 24
+	movgr2cf	$fcc3, \tmp1
+	EX	ld.w	\tmp0, \thread, (THREAD_FCC + 4)
+	bstrpick.w	\tmp1, \tmp0, 7, 0
+	movgr2cf	$fcc4, \tmp1
+	bstrpick.w	\tmp1, \tmp0, 15, 8
+	movgr2cf	$fcc5, \tmp1
+	bstrpick.w	\tmp1, \tmp0, 23, 16
+	movgr2cf	$fcc6, \tmp1
+	bstrpick.w	\tmp1, \tmp0, 31, 24
+	movgr2cf	$fcc7, \tmp1
+	.endm
+#else
 	.macro sc_save_fcc base, tmp0, tmp1
 	movcf2gr	\tmp0, $fcc0
 	move		\tmp1, \tmp0
@@ -135,6 +178,7 @@
 	bstrpick.d	\tmp1, \tmp0, 63, 56
 	movgr2cf	$fcc7, \tmp1
 	.endm
+#endif
 
 	.macro sc_save_fcsr base, tmp0
 	movfcsr2gr	\tmp0, fcsr0
@@ -410,6 +454,72 @@ SYM_FUNC_START(_init_fpu)
 
 	li.w	t1, -1				# SNaN
 
+#ifdef CONFIG_32BIT
+	movgr2fr.w	$f0, t1
+	movgr2frh.w	$f0, t1
+	movgr2fr.w	$f1, t1
+	movgr2frh.w	$f1, t1
+	movgr2fr.w	$f2, t1
+	movgr2frh.w	$f2, t1
+	movgr2fr.w	$f3, t1
+	movgr2frh.w	$f3, t1
+	movgr2fr.w	$f4, t1
+	movgr2frh.w	$f4, t1
+	movgr2fr.w	$f5, t1
+	movgr2frh.w	$f5, t1
+	movgr2fr.w	$f6, t1
+	movgr2frh.w	$f6, t1
+	movgr2fr.w	$f7, t1
+	movgr2frh.w	$f7, t1
+	movgr2fr.w	$f8, t1
+	movgr2frh.w	$f8, t1
+	movgr2fr.w	$f9, t1
+	movgr2frh.w	$f9, t1
+	movgr2fr.w	$f10, t1
+	movgr2frh.w	$f10, t1
+	movgr2fr.w	$f11, t1
+	movgr2frh.w	$f11, t1
+	movgr2fr.w	$f12, t1
+	movgr2frh.w	$f12, t1
+	movgr2fr.w	$f13, t1
+	movgr2frh.w	$f13, t1
+	movgr2fr.w	$f14, t1
+	movgr2frh.w	$f14, t1
+	movgr2fr.w	$f15, t1
+	movgr2frh.w	$f15, t1
+	movgr2fr.w	$f16, t1
+	movgr2frh.w	$f16, t1
+	movgr2fr.w	$f17, t1
+	movgr2frh.w	$f17, t1
+	movgr2fr.w	$f18, t1
+	movgr2frh.w	$f18, t1
+	movgr2fr.w	$f19, t1
+	movgr2frh.w	$f19, t1
+	movgr2fr.w	$f20, t1
+	movgr2frh.w	$f20, t1
+	movgr2fr.w	$f21, t1
+	movgr2frh.w	$f21, t1
+	movgr2fr.w	$f22, t1
+	movgr2frh.w	$f22, t1
+	movgr2fr.w	$f23, t1
+	movgr2frh.w	$f23, t1
+	movgr2fr.w	$f24, t1
+	movgr2frh.w	$f24, t1
+	movgr2fr.w	$f25, t1
+	movgr2frh.w	$f25, t1
+	movgr2fr.w	$f26, t1
+	movgr2frh.w	$f26, t1
+	movgr2fr.w	$f27, t1
+	movgr2frh.w	$f27, t1
+	movgr2fr.w	$f28, t1
+	movgr2frh.w	$f28, t1
+	movgr2fr.w	$f29, t1
+	movgr2frh.w	$f29, t1
+	movgr2fr.w	$f30, t1
+	movgr2frh.w	$f30, t1
+	movgr2fr.w	$f31, t1
+	movgr2frh.w	$f31, t1
+#else
 	movgr2fr.d	$f0, t1
 	movgr2fr.d	$f1, t1
 	movgr2fr.d	$f2, t1
@@ -442,6 +552,7 @@ SYM_FUNC_START(_init_fpu)
 	movgr2fr.d	$f29, t1
 	movgr2fr.d	$f30, t1
 	movgr2fr.d	$f31, t1
+#endif
 
 	jr	ra
 SYM_FUNC_END(_init_fpu)
diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c
index efd9edf65603..d01af0e9ec7c 100644
--- a/arch/loongarch/kernel/process.c
+++ b/arch/loongarch/kernel/process.c
@@ -377,8 +377,11 @@ void arch_trigger_cpumask_backtrace(const cpumask_t *mask, int exclude_cpu)
 	nmi_trigger_cpumask_backtrace(mask, exclude_cpu, raise_backtrace);
 }
 
-#ifdef CONFIG_64BIT
+#ifdef CONFIG_32BIT
+void loongarch_dump_regs32(u32 *uregs, const struct pt_regs *regs)
+#else
 void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs)
+#endif
 {
 	unsigned int i;
 
@@ -395,4 +398,3 @@ void loongarch_dump_regs64(u64 *uregs, const struct pt_regs *regs)
 	uregs[LOONGARCH_EF_CSR_ECFG] = regs->csr_ecfg;
 	uregs[LOONGARCH_EF_CSR_ESTAT] = regs->csr_estat;
 }
-#endif /* CONFIG_64BIT */
diff --git a/arch/loongarch/kernel/ptrace.c b/arch/loongarch/kernel/ptrace.c
index 8edd0954e55a..bea376e87d4e 100644
--- a/arch/loongarch/kernel/ptrace.c
+++ b/arch/loongarch/kernel/ptrace.c
@@ -650,8 +650,13 @@ static int ptrace_hbp_set_addr(unsigned int note_type,
 	struct perf_event_attr attr;
 
 	/* Kernel-space address cannot be monitored by user-space */
+#ifdef CONFIG_32BIT
+	if ((unsigned long)addr >= KPRANGE1)
+		return -EINVAL;
+#else
 	if ((unsigned long)addr >= XKPRANGE)
 		return -EINVAL;
+#endif
 
 	bp = ptrace_hbp_get_initialised_bp(note_type, tsk, idx);
 	if (IS_ERR(bp))
diff --git a/arch/loongarch/kernel/switch.S b/arch/loongarch/kernel/switch.S
index 9c23cb7e432f..46ba46bcd467 100644
--- a/arch/loongarch/kernel/switch.S
+++ b/arch/loongarch/kernel/switch.S
@@ -16,18 +16,26 @@
  */
 	.align	5
 SYM_FUNC_START(__switch_to)
-	csrrd	t1, LOONGARCH_CSR_PRMD
-	stptr.d	t1, a0, THREAD_CSRPRMD
+#ifdef CONFIG_32BIT
+	PTR_ADDI	a0, a0, TASK_STRUCT_OFFSET
+#endif
+	csrrd		t1, LOONGARCH_CSR_PRMD
+	LONG_SPTR	t1, a0, (THREAD_CSRPRMD - TASK_STRUCT_OFFSET)
 
 	cpu_save_nonscratch a0
-	stptr.d	ra, a0, THREAD_REG01
-	stptr.d a3, a0, THREAD_SCHED_RA
-	stptr.d a4, a0, THREAD_SCHED_CFA
+	LONG_SPTR	ra, a0, (THREAD_REG01 - TASK_STRUCT_OFFSET)
+	LONG_SPTR	a3, a0, (THREAD_SCHED_RA - TASK_STRUCT_OFFSET)
+	LONG_SPTR	a4, a0, (THREAD_SCHED_CFA - TASK_STRUCT_OFFSET)
+
 #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP)
 	la	t7, __stack_chk_guard
 	LONG_L	t8, a1, TASK_STACK_CANARY
 	LONG_S	t8, t7, 0
 #endif
+
+#ifdef CONFIG_32BIT
+	PTR_ADDI	a1, a1, TASK_STRUCT_OFFSET
+#endif
 	move	tp, a2
 	cpu_restore_nonscratch a1
 
@@ -35,8 +43,11 @@ SYM_FUNC_START(__switch_to)
 	PTR_ADD		t0, t0, tp
 	set_saved_sp	t0, t1, t2
 
-	ldptr.d	t1, a1, THREAD_CSRPRMD
-	csrwr	t1, LOONGARCH_CSR_PRMD
+	LONG_LPTR	t1, a1, (THREAD_CSRPRMD - TASK_STRUCT_OFFSET)
+	csrwr		t1, LOONGARCH_CSR_PRMD
 
+#ifdef CONFIG_32BIT
+	PTR_ADDI	a0, a0, -TASK_STRUCT_OFFSET
+#endif
 	jr	ra
 SYM_FUNC_END(__switch_to)
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH V2 07/14] LoongArch: Adjust time routines for 32BIT/64BIT
  2025-11-18 11:27 [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Huacai Chen
                   ` (5 preceding siblings ...)
  2025-11-18 11:27 ` [PATCH V2 06/14] LoongArch: Adjust process " Huacai Chen
@ 2025-11-18 11:27 ` Huacai Chen
  2025-11-18 11:27 ` [PATCH V2 08/14] LoongArch: Adjust module loader " Huacai Chen
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 37+ messages in thread
From: Huacai Chen @ 2025-11-18 11:27 UTC (permalink / raw)
  To: Arnd Bergmann, Huacai Chen
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Xuerui Wang,
	Jiaxun Yang, linux-kernel, Huacai Chen

Adjust time routines for both 32BIT and 64BIT, including: rdtime_h() /
rdtime_l() definitions for 32BIT and rdtime_d() definition for 64BIT,
get_cycles() and get_cycles64() definitions for 32BIT/64BIT, show time
frequency info ("CPU MHz" and "BogoMIPS") in /proc/cpuinfo, etc.

Use do_div() for division which works on both 32BIT and 64BIT platforms.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
 arch/loongarch/include/asm/loongarch.h | 32 +++++++++++++++++++++++++-
 arch/loongarch/include/asm/timex.h     | 29 ++++++++++++++++++++++-
 arch/loongarch/kernel/proc.c           | 13 ++++++-----
 arch/loongarch/kernel/syscall.c        |  2 +-
 arch/loongarch/kernel/time.c           | 15 ++++++------
 arch/loongarch/kvm/vcpu.c              |  5 ++--
 6 files changed, 78 insertions(+), 18 deletions(-)

diff --git a/arch/loongarch/include/asm/loongarch.h b/arch/loongarch/include/asm/loongarch.h
index 804341bd8d2e..19e3f2c183fe 100644
--- a/arch/loongarch/include/asm/loongarch.h
+++ b/arch/loongarch/include/asm/loongarch.h
@@ -1238,7 +1238,35 @@
 
 #ifndef __ASSEMBLER__
 
-static __always_inline u64 drdtime(void)
+#ifdef CONFIG_32BIT
+
+static __always_inline u32 rdtime_h(void)
+{
+	u32 val = 0;
+
+	__asm__ __volatile__(
+		"rdtimeh.w %0, $zero\n\t"
+		: "=r"(val)
+		:
+		);
+	return val;
+}
+
+static __always_inline u32 rdtime_l(void)
+{
+	u32 val = 0;
+
+	__asm__ __volatile__(
+		"rdtimel.w %0, $zero\n\t"
+		: "=r"(val)
+		:
+		);
+	return val;
+}
+
+#else
+
+static __always_inline u64 rdtime_d(void)
 {
 	u64 val = 0;
 
@@ -1250,6 +1278,8 @@ static __always_inline u64 drdtime(void)
 	return val;
 }
 
+#endif
+
 static inline unsigned int get_csr_cpuid(void)
 {
 	return csr_read32(LOONGARCH_CSR_CPUID);
diff --git a/arch/loongarch/include/asm/timex.h b/arch/loongarch/include/asm/timex.h
index fb41e9e7a222..1640c66ab430 100644
--- a/arch/loongarch/include/asm/timex.h
+++ b/arch/loongarch/include/asm/timex.h
@@ -18,7 +18,34 @@ typedef unsigned long cycles_t;
 
 static inline cycles_t get_cycles(void)
 {
-	return drdtime();
+#ifdef CONFIG_32BIT
+	return rdtime_l();
+#else
+	return rdtime_d();
+#endif
+}
+
+#define get_cycles_hi get_cycles_hi
+
+static inline cycles_t get_cycles_hi(void)
+{
+	return rdtime_h();
+}
+
+static inline u64 get_cycles64(void)
+{
+#ifdef CONFIG_32BIT
+	u32 hi, lo;
+
+	do {
+		hi = rdtime_h();
+		lo = rdtime_l();
+	} while (hi != rdtime_h());
+
+	return ((u64)hi << 32) | lo;
+#else
+	return rdtime_d();
+#endif
 }
 
 #endif /* __KERNEL__ */
diff --git a/arch/loongarch/kernel/proc.c b/arch/loongarch/kernel/proc.c
index cea30768ae92..464efdafa586 100644
--- a/arch/loongarch/kernel/proc.c
+++ b/arch/loongarch/kernel/proc.c
@@ -19,6 +19,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 	unsigned int isa = cpu_data[n].isa_level;
 	unsigned int version = cpu_data[n].processor_id & 0xff;
 	unsigned int fp_version = cpu_data[n].fpu_vers;
+	u64 freq = cpu_clock_freq, bogomips = lpj_fine * cpu_clock_freq;
 
 #ifdef CONFIG_SMP
 	if (!cpu_online(n))
@@ -28,8 +29,11 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 	/*
 	 * For the first processor also print the system type
 	 */
-	if (n == 0)
+	if (n == 0) {
+		do_div(freq, 10000);
+		do_div(bogomips, const_clock_freq * (5000/HZ));
 		seq_printf(m, "system type\t\t: %s\n\n", get_system_type());
+	}
 
 	seq_printf(m, "processor\t\t: %ld\n", n);
 	seq_printf(m, "package\t\t\t: %d\n", cpu_data[n].package);
@@ -39,11 +43,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 	seq_printf(m, "Model Name\t\t: %s\n", __cpu_full_name[n]);
 	seq_printf(m, "CPU Revision\t\t: 0x%02x\n", version);
 	seq_printf(m, "FPU Revision\t\t: 0x%02x\n", fp_version);
-	seq_printf(m, "CPU MHz\t\t\t: %llu.%02llu\n",
-		      cpu_clock_freq / 1000000, (cpu_clock_freq / 10000) % 100);
-	seq_printf(m, "BogoMIPS\t\t: %llu.%02llu\n",
-		      (lpj_fine * cpu_clock_freq / const_clock_freq) / (500000/HZ),
-		      ((lpj_fine * cpu_clock_freq / const_clock_freq) / (5000/HZ)) % 100);
+	seq_printf(m, "CPU MHz\t\t\t: %u.%02u\n", (u32)freq / 100, (u32)freq % 100);
+	seq_printf(m, "BogoMIPS\t\t: %u.%02u\n", (u32)bogomips / 100, (u32)bogomips % 100);
 	seq_printf(m, "TLB Entries\t\t: %d\n", cpu_data[n].tlbsize);
 	seq_printf(m, "Address Sizes\t\t: %d bits physical, %d bits virtual\n",
 		      cpu_pabits + 1, cpu_vabits + 1);
diff --git a/arch/loongarch/kernel/syscall.c b/arch/loongarch/kernel/syscall.c
index 168bd97540f8..ab94eb5ce039 100644
--- a/arch/loongarch/kernel/syscall.c
+++ b/arch/loongarch/kernel/syscall.c
@@ -75,7 +75,7 @@ void noinstr __no_stack_protector do_syscall(struct pt_regs *regs)
 	 *
 	 * The resulting 6 bits of entropy is seen in SP[9:4].
 	 */
-	choose_random_kstack_offset(drdtime());
+	choose_random_kstack_offset(get_cycles());
 
 	syscall_exit_to_user_mode(regs);
 }
diff --git a/arch/loongarch/kernel/time.c b/arch/loongarch/kernel/time.c
index 1c31bf3a16ed..5892f6da07a5 100644
--- a/arch/loongarch/kernel/time.c
+++ b/arch/loongarch/kernel/time.c
@@ -18,6 +18,7 @@
 #include <asm/loongarch.h>
 #include <asm/paravirt.h>
 #include <asm/time.h>
+#include <asm/timex.h>
 
 u64 cpu_clock_freq;
 EXPORT_SYMBOL(cpu_clock_freq);
@@ -62,12 +63,12 @@ static int constant_set_state_oneshot(struct clock_event_device *evt)
 
 static int constant_set_state_periodic(struct clock_event_device *evt)
 {
-	unsigned long period;
 	unsigned long timer_config;
+	u64 period = const_clock_freq;
 
 	raw_spin_lock(&state_lock);
 
-	period = const_clock_freq / HZ;
+	do_div(period, HZ);
 	timer_config = period & CSR_TCFG_VAL;
 	timer_config |= (CSR_TCFG_PERIOD | CSR_TCFG_EN);
 	csr_write(timer_config, LOONGARCH_CSR_TCFG);
@@ -120,7 +121,7 @@ static int arch_timer_dying(unsigned int cpu)
 
 static unsigned long get_loops_per_jiffy(void)
 {
-	unsigned long lpj = (unsigned long)const_clock_freq;
+	u64 lpj = const_clock_freq;
 
 	do_div(lpj, HZ);
 
@@ -131,7 +132,7 @@ static long init_offset;
 
 void save_counter(void)
 {
-	init_offset = drdtime();
+	init_offset = get_cycles();
 }
 
 void sync_counter(void)
@@ -197,12 +198,12 @@ int constant_clockevent_init(void)
 
 static u64 read_const_counter(struct clocksource *clk)
 {
-	return drdtime();
+	return get_cycles64();
 }
 
 static noinstr u64 sched_clock_read(void)
 {
-	return drdtime();
+	return get_cycles64();
 }
 
 static struct clocksource clocksource_const = {
@@ -235,7 +236,7 @@ void __init time_init(void)
 	else
 		const_clock_freq = calc_const_freq();
 
-	init_offset = -(drdtime() - csr_read(LOONGARCH_CSR_CNTC));
+	init_offset = -(get_cycles() - csr_read(LOONGARCH_CSR_CNTC));
 
 	constant_clockevent_init();
 	constant_clocksource_init();
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 1245a6b35896..803224d297eb 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -9,6 +9,7 @@
 #include <asm/loongarch.h>
 #include <asm/setup.h>
 #include <asm/time.h>
+#include <asm/timex.h>
 
 #define CREATE_TRACE_POINTS
 #include "trace.h"
@@ -811,7 +812,7 @@ static int kvm_get_one_reg(struct kvm_vcpu *vcpu,
 	case KVM_REG_LOONGARCH_KVM:
 		switch (reg->id) {
 		case KVM_REG_LOONGARCH_COUNTER:
-			*v = drdtime() + vcpu->kvm->arch.time_offset;
+			*v = get_cycles() + vcpu->kvm->arch.time_offset;
 			break;
 		case KVM_REG_LOONGARCH_DEBUG_INST:
 			*v = INSN_HVCL | KVM_HCALL_SWDBG;
@@ -906,7 +907,7 @@ static int kvm_set_one_reg(struct kvm_vcpu *vcpu,
 			 * only set for the first time for smp system
 			 */
 			if (vcpu->vcpu_id == 0)
-				vcpu->kvm->arch.time_offset = (signed long)(v - drdtime());
+				vcpu->kvm->arch.time_offset = (signed long)(v - get_cycles());
 			break;
 		case KVM_REG_LOONGARCH_VCPU_RESET:
 			vcpu->arch.st.guest_addr = 0;
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH V2 08/14] LoongArch: Adjust module loader for 32BIT/64BIT
  2025-11-18 11:27 [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Huacai Chen
                   ` (6 preceding siblings ...)
  2025-11-18 11:27 ` [PATCH V2 07/14] LoongArch: Adjust time routines " Huacai Chen
@ 2025-11-18 11:27 ` Huacai Chen
  2025-11-18 11:27 ` [PATCH V2 09/14] LoongArch: Adjust system call " Huacai Chen
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 37+ messages in thread
From: Huacai Chen @ 2025-11-18 11:27 UTC (permalink / raw)
  To: Arnd Bergmann, Huacai Chen
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Xuerui Wang,
	Jiaxun Yang, linux-kernel, Huacai Chen

Adjust module loader for both 32BIT and 64BIT, including: change the s64
type to long, change the u64 type to unsigned long, change the plt entry
definition and handling, etc.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
 arch/loongarch/include/asm/module.h | 11 ++++
 arch/loongarch/include/asm/percpu.h |  2 +-
 arch/loongarch/kernel/module.c      | 80 +++++++++++++++++------------
 3 files changed, 59 insertions(+), 34 deletions(-)

diff --git a/arch/loongarch/include/asm/module.h b/arch/loongarch/include/asm/module.h
index f33f3fd32ecc..d56a968273de 100644
--- a/arch/loongarch/include/asm/module.h
+++ b/arch/loongarch/include/asm/module.h
@@ -38,8 +38,10 @@ struct got_entry {
 
 struct plt_entry {
 	u32 inst_lu12iw;
+#ifdef CONFIG_64BIT
 	u32 inst_lu32id;
 	u32 inst_lu52id;
+#endif
 	u32 inst_jirl;
 };
 
@@ -57,6 +59,14 @@ static inline struct got_entry emit_got_entry(Elf_Addr val)
 
 static inline struct plt_entry emit_plt_entry(unsigned long val)
 {
+#ifdef CONFIG_32BIT
+	u32 lu12iw, jirl;
+
+	lu12iw = larch_insn_gen_lu12iw(LOONGARCH_GPR_T1, ADDR_IMM(val, LU12IW));
+	jirl = larch_insn_gen_jirl(0, LOONGARCH_GPR_T1, ADDR_IMM(val, ORI));
+
+	return (struct plt_entry) { lu12iw, jirl };
+#else
 	u32 lu12iw, lu32id, lu52id, jirl;
 
 	lu12iw = larch_insn_gen_lu12iw(LOONGARCH_GPR_T1, ADDR_IMM(val, LU12IW));
@@ -65,6 +75,7 @@ static inline struct plt_entry emit_plt_entry(unsigned long val)
 	jirl = larch_insn_gen_jirl(0, LOONGARCH_GPR_T1, ADDR_IMM(val, ORI));
 
 	return (struct plt_entry) { lu12iw, lu32id, lu52id, jirl };
+#endif
 }
 
 static inline struct plt_idx_entry emit_plt_idx_entry(unsigned long val)
diff --git a/arch/loongarch/include/asm/percpu.h b/arch/loongarch/include/asm/percpu.h
index 44a8aea2b0e5..583f2466262f 100644
--- a/arch/loongarch/include/asm/percpu.h
+++ b/arch/loongarch/include/asm/percpu.h
@@ -13,7 +13,7 @@
  * the loading address of main kernel image, but far from where the modules are
  * loaded. Tell the compiler this fact when using explicit relocs.
  */
-#if defined(MODULE) && defined(CONFIG_AS_HAS_EXPLICIT_RELOCS)
+#if defined(MODULE) && defined(CONFIG_AS_HAS_EXPLICIT_RELOCS) && defined(CONFIG_64BIT)
 # if __has_attribute(model)
 #  define PER_CPU_ATTRIBUTES __attribute__((model("extreme")))
 # else
diff --git a/arch/loongarch/kernel/module.c b/arch/loongarch/kernel/module.c
index 36d6d9eeb7c7..27f6d6b2e3ff 100644
--- a/arch/loongarch/kernel/module.c
+++ b/arch/loongarch/kernel/module.c
@@ -22,72 +22,76 @@
 #include <asm/inst.h>
 #include <asm/unwind.h>
 
-static int rela_stack_push(s64 stack_value, s64 *rela_stack, size_t *rela_stack_top)
+static int rela_stack_push(long stack_value, long *rela_stack, size_t *rela_stack_top)
 {
 	if (*rela_stack_top >= RELA_STACK_DEPTH)
 		return -ENOEXEC;
 
 	rela_stack[(*rela_stack_top)++] = stack_value;
-	pr_debug("%s stack_value = 0x%llx\n", __func__, stack_value);
+	pr_debug("%s stack_value = 0x%lx\n", __func__, stack_value);
 
 	return 0;
 }
 
-static int rela_stack_pop(s64 *stack_value, s64 *rela_stack, size_t *rela_stack_top)
+static int rela_stack_pop(long *stack_value, long *rela_stack, size_t *rela_stack_top)
 {
 	if (*rela_stack_top == 0)
 		return -ENOEXEC;
 
 	*stack_value = rela_stack[--(*rela_stack_top)];
-	pr_debug("%s stack_value = 0x%llx\n", __func__, *stack_value);
+	pr_debug("%s stack_value = 0x%lx\n", __func__, *stack_value);
 
 	return 0;
 }
 
 static int apply_r_larch_none(struct module *mod, u32 *location, Elf_Addr v,
-			s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
+			long *rela_stack, size_t *rela_stack_top, unsigned int type)
 {
 	return 0;
 }
 
 static int apply_r_larch_error(struct module *me, u32 *location, Elf_Addr v,
-			s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
+			long *rela_stack, size_t *rela_stack_top, unsigned int type)
 {
 	pr_err("%s: Unsupport relocation type %u, please add its support.\n", me->name, type);
 	return -EINVAL;
 }
 
 static int apply_r_larch_32(struct module *mod, u32 *location, Elf_Addr v,
-			s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
+			long *rela_stack, size_t *rela_stack_top, unsigned int type)
 {
 	*location = v;
 	return 0;
 }
 
+#ifdef CONFIG_32BIT
+#define apply_r_larch_64 apply_r_larch_error
+#else
 static int apply_r_larch_64(struct module *mod, u32 *location, Elf_Addr v,
-			s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
+			long *rela_stack, size_t *rela_stack_top, unsigned int type)
 {
 	*(Elf_Addr *)location = v;
 	return 0;
 }
+#endif
 
 static int apply_r_larch_sop_push_pcrel(struct module *mod, u32 *location, Elf_Addr v,
-			s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
+			long *rela_stack, size_t *rela_stack_top, unsigned int type)
 {
-	return rela_stack_push(v - (u64)location, rela_stack, rela_stack_top);
+	return rela_stack_push(v - (unsigned long)location, rela_stack, rela_stack_top);
 }
 
 static int apply_r_larch_sop_push_absolute(struct module *mod, u32 *location, Elf_Addr v,
-			s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
+			long *rela_stack, size_t *rela_stack_top, unsigned int type)
 {
 	return rela_stack_push(v, rela_stack, rela_stack_top);
 }
 
 static int apply_r_larch_sop_push_dup(struct module *mod, u32 *location, Elf_Addr v,
-			s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
+			long *rela_stack, size_t *rela_stack_top, unsigned int type)
 {
 	int err = 0;
-	s64 opr1;
+	long opr1;
 
 	err = rela_stack_pop(&opr1, rela_stack, rela_stack_top);
 	if (err)
@@ -104,7 +108,7 @@ static int apply_r_larch_sop_push_dup(struct module *mod, u32 *location, Elf_Add
 
 static int apply_r_larch_sop_push_plt_pcrel(struct module *mod,
 			Elf_Shdr *sechdrs, u32 *location, Elf_Addr v,
-			s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
+			long *rela_stack, size_t *rela_stack_top, unsigned int type)
 {
 	ptrdiff_t offset = (void *)v - (void *)location;
 
@@ -118,10 +122,10 @@ static int apply_r_larch_sop_push_plt_pcrel(struct module *mod,
 }
 
 static int apply_r_larch_sop(struct module *mod, u32 *location, Elf_Addr v,
-			s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
+			long *rela_stack, size_t *rela_stack_top, unsigned int type)
 {
 	int err = 0;
-	s64 opr1, opr2, opr3;
+	long opr1, opr2, opr3;
 
 	if (type == R_LARCH_SOP_IF_ELSE) {
 		err = rela_stack_pop(&opr3, rela_stack, rela_stack_top);
@@ -164,10 +168,10 @@ static int apply_r_larch_sop(struct module *mod, u32 *location, Elf_Addr v,
 }
 
 static int apply_r_larch_sop_imm_field(struct module *mod, u32 *location, Elf_Addr v,
-			s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
+			long *rela_stack, size_t *rela_stack_top, unsigned int type)
 {
 	int err = 0;
-	s64 opr1;
+	long opr1;
 	union loongarch_instruction *insn = (union loongarch_instruction *)location;
 
 	err = rela_stack_pop(&opr1, rela_stack, rela_stack_top);
@@ -244,31 +248,33 @@ static int apply_r_larch_sop_imm_field(struct module *mod, u32 *location, Elf_Ad
 	}
 
 overflow:
-	pr_err("module %s: opr1 = 0x%llx overflow! dangerous %s (%u) relocation\n",
+	pr_err("module %s: opr1 = 0x%lx overflow! dangerous %s (%u) relocation\n",
 		mod->name, opr1, __func__, type);
 	return -ENOEXEC;
 
 unaligned:
-	pr_err("module %s: opr1 = 0x%llx unaligned! dangerous %s (%u) relocation\n",
+	pr_err("module %s: opr1 = 0x%lx unaligned! dangerous %s (%u) relocation\n",
 		mod->name, opr1, __func__, type);
 	return -ENOEXEC;
 }
 
 static int apply_r_larch_add_sub(struct module *mod, u32 *location, Elf_Addr v,
-			s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
+			long *rela_stack, size_t *rela_stack_top, unsigned int type)
 {
 	switch (type) {
 	case R_LARCH_ADD32:
 		*(s32 *)location += v;
 		return 0;
-	case R_LARCH_ADD64:
-		*(s64 *)location += v;
-		return 0;
 	case R_LARCH_SUB32:
 		*(s32 *)location -= v;
 		return 0;
+#ifdef CONFIG_64BIT
+	case R_LARCH_ADD64:
+		*(s64 *)location += v;
+		return 0;
 	case R_LARCH_SUB64:
 		*(s64 *)location -= v;
+#endif
 		return 0;
 	default:
 		pr_err("%s: Unsupport relocation type %u\n", mod->name, type);
@@ -278,7 +284,7 @@ static int apply_r_larch_add_sub(struct module *mod, u32 *location, Elf_Addr v,
 
 static int apply_r_larch_b26(struct module *mod,
 			Elf_Shdr *sechdrs, u32 *location, Elf_Addr v,
-			s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
+			long *rela_stack, size_t *rela_stack_top, unsigned int type)
 {
 	ptrdiff_t offset = (void *)v - (void *)location;
 	union loongarch_instruction *insn = (union loongarch_instruction *)location;
@@ -311,14 +317,16 @@ static int apply_r_larch_b26(struct module *mod,
 }
 
 static int apply_r_larch_pcala(struct module *mod, u32 *location, Elf_Addr v,
-			s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
+			long *rela_stack, size_t *rela_stack_top, unsigned int type)
 {
 	union loongarch_instruction *insn = (union loongarch_instruction *)location;
 	/* Use s32 for a sign-extension deliberately. */
 	s32 offset_hi20 = (void *)((v + 0x800) & ~0xfff) -
 			  (void *)((Elf_Addr)location & ~0xfff);
+#ifdef CONFIG_64BIT
 	Elf_Addr anchor = (((Elf_Addr)location) & ~0xfff) + offset_hi20;
 	ptrdiff_t offset_rem = (void *)v - (void *)anchor;
+#endif
 
 	switch (type) {
 	case R_LARCH_PCALA_LO12:
@@ -328,6 +336,7 @@ static int apply_r_larch_pcala(struct module *mod, u32 *location, Elf_Addr v,
 		v = offset_hi20 >> 12;
 		insn->reg1i20_format.immediate = v & 0xfffff;
 		break;
+#ifdef CONFIG_64BIT
 	case R_LARCH_PCALA64_LO20:
 		v = offset_rem >> 32;
 		insn->reg1i20_format.immediate = v & 0xfffff;
@@ -336,6 +345,7 @@ static int apply_r_larch_pcala(struct module *mod, u32 *location, Elf_Addr v,
 		v = offset_rem >> 52;
 		insn->reg2i12_format.immediate = v & 0xfff;
 		break;
+#endif
 	default:
 		pr_err("%s: Unsupport relocation type %u\n", mod->name, type);
 		return -EINVAL;
@@ -346,7 +356,7 @@ static int apply_r_larch_pcala(struct module *mod, u32 *location, Elf_Addr v,
 
 static int apply_r_larch_got_pc(struct module *mod,
 			Elf_Shdr *sechdrs, u32 *location, Elf_Addr v,
-			s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
+			long *rela_stack, size_t *rela_stack_top, unsigned int type)
 {
 	Elf_Addr got = module_emit_got_entry(mod, sechdrs, v);
 
@@ -369,7 +379,7 @@ static int apply_r_larch_got_pc(struct module *mod,
 }
 
 static int apply_r_larch_32_pcrel(struct module *mod, u32 *location, Elf_Addr v,
-				  s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
+				  long *rela_stack, size_t *rela_stack_top, unsigned int type)
 {
 	ptrdiff_t offset = (void *)v - (void *)location;
 
@@ -377,14 +387,18 @@ static int apply_r_larch_32_pcrel(struct module *mod, u32 *location, Elf_Addr v,
 	return 0;
 }
 
+#ifdef CONFIG_32BIT
+#define apply_r_larch_64_pcrel apply_r_larch_error
+#else
 static int apply_r_larch_64_pcrel(struct module *mod, u32 *location, Elf_Addr v,
-				  s64 *rela_stack, size_t *rela_stack_top, unsigned int type)
+				  long *rela_stack, size_t *rela_stack_top, unsigned int type)
 {
 	ptrdiff_t offset = (void *)v - (void *)location;
 
 	*(u64 *)location = offset;
 	return 0;
 }
+#endif
 
 /*
  * reloc_handlers_rela() - Apply a particular relocation to a module
@@ -397,7 +411,7 @@ static int apply_r_larch_64_pcrel(struct module *mod, u32 *location, Elf_Addr v,
  * Return: 0 upon success, else -ERRNO
  */
 typedef int (*reloc_rela_handler)(struct module *mod, u32 *location, Elf_Addr v,
-			s64 *rela_stack, size_t *rela_stack_top, unsigned int type);
+			long *rela_stack, size_t *rela_stack_top, unsigned int type);
 
 /* The handlers for known reloc types */
 static reloc_rela_handler reloc_rela_handlers[] = {
@@ -425,7 +439,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
 {
 	int i, err;
 	unsigned int type;
-	s64 rela_stack[RELA_STACK_DEPTH];
+	long rela_stack[RELA_STACK_DEPTH];
 	size_t rela_stack_top = 0;
 	reloc_rela_handler handler;
 	void *location;
@@ -462,9 +476,9 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
 			return -EINVAL;
 		}
 
-		pr_debug("type %d st_value %llx r_addend %llx loc %llx\n",
+		pr_debug("type %d st_value %lx r_addend %lx loc %lx\n",
 		       (int)ELF_R_TYPE(rel[i].r_info),
-		       sym->st_value, rel[i].r_addend, (u64)location);
+		       (unsigned long)sym->st_value, (unsigned long)rel[i].r_addend, (unsigned long)location);
 
 		v = sym->st_value + rel[i].r_addend;
 		switch (type) {
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH V2 09/14] LoongArch: Adjust system call for 32BIT/64BIT
  2025-11-18 11:27 [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Huacai Chen
                   ` (7 preceding siblings ...)
  2025-11-18 11:27 ` [PATCH V2 08/14] LoongArch: Adjust module loader " Huacai Chen
@ 2025-11-18 11:27 ` Huacai Chen
  2025-11-20 10:40   ` WANG Xuerui
  2025-11-18 11:27 ` [PATCH V2 10/14] LoongArch: Adjust user accessors " Huacai Chen
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Huacai Chen @ 2025-11-18 11:27 UTC (permalink / raw)
  To: Arnd Bergmann, Huacai Chen
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Xuerui Wang,
	Jiaxun Yang, linux-kernel, Huacai Chen

Adjust system call for both 32BIT and 64BIT, including: add the uapi
unistd_{32,64}.h and syscall_table_{32,64}.h inclusion, add sys_mmap2()
definition, change the system call entry routines, etc.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
 arch/loongarch/include/asm/Kbuild        |  1 +
 arch/loongarch/include/uapi/asm/Kbuild   |  1 +
 arch/loongarch/include/uapi/asm/unistd.h |  6 ++++++
 arch/loongarch/kernel/Makefile.syscalls  |  1 +
 arch/loongarch/kernel/entry.S            | 22 +++++++++++-----------
 arch/loongarch/kernel/syscall.c          | 13 +++++++++++++
 6 files changed, 33 insertions(+), 11 deletions(-)

diff --git a/arch/loongarch/include/asm/Kbuild b/arch/loongarch/include/asm/Kbuild
index b04d2cef935f..9034b583a88a 100644
--- a/arch/loongarch/include/asm/Kbuild
+++ b/arch/loongarch/include/asm/Kbuild
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
+syscall-y += syscall_table_32.h
 syscall-y += syscall_table_64.h
 generated-y += orc_hash.h
 
diff --git a/arch/loongarch/include/uapi/asm/Kbuild b/arch/loongarch/include/uapi/asm/Kbuild
index 517761419999..89ac01faa5ae 100644
--- a/arch/loongarch/include/uapi/asm/Kbuild
+++ b/arch/loongarch/include/uapi/asm/Kbuild
@@ -1,2 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
+syscall-y += unistd_32.h
 syscall-y += unistd_64.h
diff --git a/arch/loongarch/include/uapi/asm/unistd.h b/arch/loongarch/include/uapi/asm/unistd.h
index 1f01980f9c94..e19c7f2f9f87 100644
--- a/arch/loongarch/include/uapi/asm/unistd.h
+++ b/arch/loongarch/include/uapi/asm/unistd.h
@@ -1,3 +1,9 @@
 /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
 
+#include <asm/bitsperlong.h>
+
+#if __BITS_PER_LONG == 32
+#include <asm/unistd_32.h>
+#else
 #include <asm/unistd_64.h>
+#endif
diff --git a/arch/loongarch/kernel/Makefile.syscalls b/arch/loongarch/kernel/Makefile.syscalls
index ab7d9baa2915..cd46c2b69c7f 100644
--- a/arch/loongarch/kernel/Makefile.syscalls
+++ b/arch/loongarch/kernel/Makefile.syscalls
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 
 # No special ABIs on loongarch so far
+syscall_abis_32 +=
 syscall_abis_64 +=
diff --git a/arch/loongarch/kernel/entry.S b/arch/loongarch/kernel/entry.S
index 47e1db9a1ce4..b53d333a7c42 100644
--- a/arch/loongarch/kernel/entry.S
+++ b/arch/loongarch/kernel/entry.S
@@ -23,24 +23,24 @@ SYM_CODE_START(handle_syscall)
 	UNWIND_HINT_UNDEFINED
 	csrrd		t0, PERCPU_BASE_KS
 	la.pcrel	t1, kernelsp
-	add.d		t1, t1, t0
+	PTR_ADD		t1, t1, t0
 	move		t2, sp
-	ld.d		sp, t1, 0
+	PTR_L		sp, t1, 0
 
-	addi.d		sp, sp, -PT_SIZE
+	PTR_ADDI	sp, sp, -PT_SIZE
 	cfi_st		t2, PT_R3
 	cfi_rel_offset	sp, PT_R3
-	st.d		zero, sp, PT_R0
+	LONG_S		zero, sp, PT_R0
 	csrrd		t2, LOONGARCH_CSR_PRMD
-	st.d		t2, sp, PT_PRMD
+	LONG_S		t2, sp, PT_PRMD
 	csrrd		t2, LOONGARCH_CSR_CRMD
-	st.d		t2, sp, PT_CRMD
+	LONG_S		t2, sp, PT_CRMD
 	csrrd		t2, LOONGARCH_CSR_EUEN
-	st.d		t2, sp, PT_EUEN
+	LONG_S		t2, sp, PT_EUEN
 	csrrd		t2, LOONGARCH_CSR_ECFG
-	st.d		t2, sp, PT_ECFG
+	LONG_S		t2, sp, PT_ECFG
 	csrrd		t2, LOONGARCH_CSR_ESTAT
-	st.d		t2, sp, PT_ESTAT
+	LONG_S		t2, sp, PT_ESTAT
 	cfi_st		ra, PT_R1
 	cfi_st		a0, PT_R4
 	cfi_st		a1, PT_R5
@@ -51,7 +51,7 @@ SYM_CODE_START(handle_syscall)
 	cfi_st		a6, PT_R10
 	cfi_st		a7, PT_R11
 	csrrd		ra, LOONGARCH_CSR_ERA
-	st.d		ra, sp, PT_ERA
+	LONG_S		ra, sp, PT_ERA
 	cfi_rel_offset	ra, PT_ERA
 
 	cfi_st		tp, PT_R2
@@ -67,7 +67,7 @@ SYM_CODE_START(handle_syscall)
 #endif
 
 	move		u0, t0
-	li.d		tp, ~_THREAD_MASK
+	LONG_LI		tp, ~_THREAD_MASK
 	and		tp, tp, sp
 
 	move		a0, sp
diff --git a/arch/loongarch/kernel/syscall.c b/arch/loongarch/kernel/syscall.c
index ab94eb5ce039..1249d82c1cd0 100644
--- a/arch/loongarch/kernel/syscall.c
+++ b/arch/loongarch/kernel/syscall.c
@@ -34,9 +34,22 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, unsigned long,
 	return ksys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
 }
 
+SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, unsigned long,
+		 prot, unsigned long, flags, unsigned long, fd, unsigned long, offset)
+{
+	if (offset & (~PAGE_MASK >> 12))
+		return -EINVAL;
+
+	return ksys_mmap_pgoff(addr, len, prot, flags, fd, offset >> (PAGE_SHIFT - 12));
+}
+
 void *sys_call_table[__NR_syscalls] = {
 	[0 ... __NR_syscalls - 1] = sys_ni_syscall,
+#ifdef CONFIG_32BIT
+#include <asm/syscall_table_32.h>
+#else
 #include <asm/syscall_table_64.h>
+#endif
 };
 
 typedef long (*sys_call_fn)(unsigned long, unsigned long,
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH V2 10/14] LoongArch: Adjust user accessors for 32BIT/64BIT
  2025-11-18 11:27 [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Huacai Chen
                   ` (8 preceding siblings ...)
  2025-11-18 11:27 ` [PATCH V2 09/14] LoongArch: Adjust system call " Huacai Chen
@ 2025-11-18 11:27 ` Huacai Chen
  2025-11-18 11:27 ` [PATCH V2 11/14] LoongArch: Adjust misc routines " Huacai Chen
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 37+ messages in thread
From: Huacai Chen @ 2025-11-18 11:27 UTC (permalink / raw)
  To: Arnd Bergmann, Huacai Chen
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Xuerui Wang,
	Jiaxun Yang, linux-kernel, Huacai Chen

Adjust user accessors for both 32BIT and 64BIT, including: get_user(),
put_user(), copy_user(), clear_user(), etc.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
 arch/loongarch/include/asm/uaccess.h | 63 ++++++++++++++++++++++++++--
 arch/loongarch/lib/clear_user.S      | 22 ++++++----
 arch/loongarch/lib/copy_user.S       | 28 ++++++++-----
 3 files changed, 91 insertions(+), 22 deletions(-)

diff --git a/arch/loongarch/include/asm/uaccess.h b/arch/loongarch/include/asm/uaccess.h
index 0d22991ae430..4e259d490e45 100644
--- a/arch/loongarch/include/asm/uaccess.h
+++ b/arch/loongarch/include/asm/uaccess.h
@@ -19,10 +19,16 @@
 #include <asm/asm-extable.h>
 #include <asm-generic/access_ok.h>
 
+#define __LSW	0
+#define __MSW	1
+
 extern u64 __ua_limit;
 
-#define __UA_ADDR	".dword"
+#ifdef CONFIG_64BIT
 #define __UA_LIMIT	__ua_limit
+#else
+#define __UA_LIMIT	0x80000000UL
+#endif
 
 /*
  * get_user: - Get a simple variable from user space.
@@ -126,6 +132,7 @@ extern u64 __ua_limit;
  *
  * Returns zero on success, or -EFAULT on error.
  */
+
 #define __put_user(x, ptr) \
 ({									\
 	int __pu_err = 0;						\
@@ -146,7 +153,7 @@ do {									\
 	case 1: __get_data_asm(val, "ld.b", ptr); break;		\
 	case 2: __get_data_asm(val, "ld.h", ptr); break;		\
 	case 4: __get_data_asm(val, "ld.w", ptr); break;		\
-	case 8: __get_data_asm(val, "ld.d", ptr); break;		\
+	case 8: __get_data_asm_8(val, ptr); break;			\
 	default: BUILD_BUG(); break;					\
 	}								\
 } while (0)
@@ -167,13 +174,39 @@ do {									\
 	(val) = (__typeof__(*(ptr))) __gu_tmp;				\
 }
 
+#ifdef CONFIG_64BIT
+#define __get_data_asm_8(val, ptr) \
+	__get_data_asm(val, "ld.d", ptr)
+#else /* !CONFIG_64BIT */
+#define __get_data_asm_8(val, ptr)					\
+{									\
+	u32 __lo, __hi;							\
+	u32 __user *__ptr = (u32 __user *)(ptr);			\
+									\
+	__asm__ __volatile__ (						\
+		"1:\n"							\
+		"	ld.w %1, %3				\n"	\
+		"2:\n"							\
+		"	ld.w %2, %4				\n"	\
+		"3:\n"							\
+		_ASM_EXTABLE_UACCESS_ERR_ZERO(1b, 3b, %0, %1)		\
+		_ASM_EXTABLE_UACCESS_ERR_ZERO(2b, 3b, %0, %1)		\
+		: "+r" (__gu_err), "=&r" (__lo), "=r" (__hi)		\
+		: "m" (__ptr[__LSW]), "m" (__ptr[__MSW]));		\
+	if (__gu_err)							\
+		__hi = 0;						\
+	(val) = (__typeof__(val))((__typeof__((val)-(val)))		\
+		((((u64)__hi << 32) | __lo)));				\
+}
+#endif /* CONFIG_64BIT */
+
 #define __put_user_common(ptr, size)					\
 do {									\
 	switch (size) {							\
 	case 1: __put_data_asm("st.b", ptr); break;			\
 	case 2: __put_data_asm("st.h", ptr); break;			\
 	case 4: __put_data_asm("st.w", ptr); break;			\
-	case 8: __put_data_asm("st.d", ptr); break;			\
+	case 8: __put_data_asm_8(ptr); break;				\
 	default: BUILD_BUG(); break;					\
 	}								\
 } while (0)
@@ -190,6 +223,30 @@ do {									\
 	: "Jr" (__pu_val));						\
 }
 
+#ifdef CONFIG_64BIT
+#define __put_data_asm_8(ptr) \
+	__put_data_asm("st.d", ptr)
+#else /* !CONFIG_64BIT */
+#define __put_data_asm_8(ptr)						\
+{									\
+	u32 __user *__ptr = (u32 __user *)(ptr);			\
+	u64 __x = (__typeof__((__pu_val)-(__pu_val)))(__pu_val);	\
+									\
+	__asm__ __volatile__ (						\
+		"1:\n"							\
+		"	st.w %z3, %1				\n"	\
+		"2:\n"							\
+		"	st.w %z4, %2				\n"	\
+		"3:\n"							\
+		_ASM_EXTABLE_UACCESS_ERR(1b, 3b, %0)			\
+		_ASM_EXTABLE_UACCESS_ERR(2b, 3b, %0)			\
+		: "+r" (__pu_err),					\
+			"=m" (__ptr[__LSW]),				\
+			"=m" (__ptr[__MSW])				\
+		: "rJ" (__x), "rJ" (__x >> 32));			\
+}
+#endif /* CONFIG_64BIT */
+
 #define __get_kernel_nofault(dst, src, type, err_label)			\
 do {									\
 	int __gu_err = 0;						\
diff --git a/arch/loongarch/lib/clear_user.S b/arch/loongarch/lib/clear_user.S
index 7a0db643b286..58c667dde882 100644
--- a/arch/loongarch/lib/clear_user.S
+++ b/arch/loongarch/lib/clear_user.S
@@ -13,11 +13,15 @@
 #include <asm/unwind_hints.h>
 
 SYM_FUNC_START(__clear_user)
+#ifdef CONFIG_32BIT
+	b		__clear_user_generic
+#else
 	/*
 	 * Some CPUs support hardware unaligned access
 	 */
 	ALTERNATIVE	"b __clear_user_generic",	\
 			"b __clear_user_fast", CPU_FEATURE_UAL
+#endif
 SYM_FUNC_END(__clear_user)
 
 EXPORT_SYMBOL(__clear_user)
@@ -29,19 +33,20 @@ EXPORT_SYMBOL(__clear_user)
  * a1: size
  */
 SYM_FUNC_START(__clear_user_generic)
-	beqz	a1, 2f
+	beqz		a1, 2f
 
-1:	st.b	zero, a0, 0
-	addi.d	a0, a0, 1
-	addi.d	a1, a1, -1
-	bgtz	a1, 1b
+1:	st.b		zero, a0, 0
+	PTR_ADDI	a0, a0, 1
+	PTR_ADDI	a1, a1, -1
+	bgtz		a1, 1b
 
-2:	move	a0, a1
-	jr	ra
+2:	move		a0, a1
+	jr		ra
 
-	_asm_extable 1b, 2b
+	_asm_extable 	1b, 2b
 SYM_FUNC_END(__clear_user_generic)
 
+#ifdef CONFIG_64BIT
 /*
  * unsigned long __clear_user_fast(void *addr, unsigned long size)
  *
@@ -207,3 +212,4 @@ SYM_FUNC_START(__clear_user_fast)
 SYM_FUNC_END(__clear_user_fast)
 
 STACK_FRAME_NON_STANDARD __clear_user_fast
+#endif
diff --git a/arch/loongarch/lib/copy_user.S b/arch/loongarch/lib/copy_user.S
index 095ce9181c6c..c7264b779f6e 100644
--- a/arch/loongarch/lib/copy_user.S
+++ b/arch/loongarch/lib/copy_user.S
@@ -13,11 +13,15 @@
 #include <asm/unwind_hints.h>
 
 SYM_FUNC_START(__copy_user)
+#ifdef CONFIG_32BIT
+	b		__copy_user_generic
+#else
 	/*
 	 * Some CPUs support hardware unaligned access
 	 */
 	ALTERNATIVE	"b __copy_user_generic",	\
 			"b __copy_user_fast", CPU_FEATURE_UAL
+#endif
 SYM_FUNC_END(__copy_user)
 
 EXPORT_SYMBOL(__copy_user)
@@ -30,22 +34,23 @@ EXPORT_SYMBOL(__copy_user)
  * a2: n
  */
 SYM_FUNC_START(__copy_user_generic)
-	beqz	a2, 3f
+	beqz		a2, 3f
 
-1:	ld.b	t0, a1, 0
-2:	st.b	t0, a0, 0
-	addi.d	a0, a0, 1
-	addi.d	a1, a1, 1
-	addi.d	a2, a2, -1
-	bgtz	a2, 1b
+1:	ld.b		t0, a1, 0
+2:	st.b		t0, a0, 0
+	PTR_ADDI	a0, a0, 1
+	PTR_ADDI	a1, a1, 1
+	PTR_ADDI	a2, a2, -1
+	bgtz		a2, 1b
 
-3:	move	a0, a2
-	jr	ra
+3:	move		a0, a2
+	jr		ra
 
-	_asm_extable 1b, 3b
-	_asm_extable 2b, 3b
+	_asm_extable	1b, 3b
+	_asm_extable	2b, 3b
 SYM_FUNC_END(__copy_user_generic)
 
+#ifdef CONFIG_64BIT
 /*
  * unsigned long __copy_user_fast(void *to, const void *from, unsigned long n)
  *
@@ -281,3 +286,4 @@ SYM_FUNC_START(__copy_user_fast)
 SYM_FUNC_END(__copy_user_fast)
 
 STACK_FRAME_NON_STANDARD __copy_user_fast
+#endif
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH V2 11/14] LoongArch: Adjust misc routines for 32BIT/64BIT
  2025-11-18 11:27 [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Huacai Chen
                   ` (9 preceding siblings ...)
  2025-11-18 11:27 ` [PATCH V2 10/14] LoongArch: Adjust user accessors " Huacai Chen
@ 2025-11-18 11:27 ` Huacai Chen
  2025-11-20 10:45   ` WANG Xuerui
  2025-11-18 11:27 ` [PATCH V2 12/14] LoongArch: Adjust VDSO/VSYSCALL " Huacai Chen
                   ` (3 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Huacai Chen @ 2025-11-18 11:27 UTC (permalink / raw)
  To: Arnd Bergmann, Huacai Chen
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Xuerui Wang,
	Jiaxun Yang, linux-kernel, Huacai Chen

Adjust misc routines for both 32BIT and 64BIT, including: checksum,
jump label, unaligned access emulator, PCI init routines, sleep/wakeup
routines, etc.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
 arch/loongarch/include/asm/checksum.h   |  4 ++
 arch/loongarch/include/asm/jump_label.h | 12 ++++-
 arch/loongarch/include/asm/string.h     |  2 +
 arch/loongarch/kernel/unaligned.c       | 30 ++++++++---
 arch/loongarch/lib/unaligned.S          | 72 ++++++++++++-------------
 arch/loongarch/pci/pci.c                |  8 +--
 arch/loongarch/power/suspend_asm.S      | 72 ++++++++++++-------------
 7 files changed, 116 insertions(+), 84 deletions(-)

diff --git a/arch/loongarch/include/asm/checksum.h b/arch/loongarch/include/asm/checksum.h
index cabbf6af44c4..cc2754e0aa25 100644
--- a/arch/loongarch/include/asm/checksum.h
+++ b/arch/loongarch/include/asm/checksum.h
@@ -9,6 +9,8 @@
 #include <linux/bitops.h>
 #include <linux/in6.h>
 
+#ifdef CONFIG_64BIT
+
 #define _HAVE_ARCH_IPV6_CSUM
 __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
 			const struct in6_addr *daddr,
@@ -61,6 +63,8 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
 extern unsigned int do_csum(const unsigned char *buff, int len);
 #define do_csum do_csum
 
+#endif
+
 #include <asm-generic/checksum.h>
 
 #endif	/* __ASM_CHECKSUM_H */
diff --git a/arch/loongarch/include/asm/jump_label.h b/arch/loongarch/include/asm/jump_label.h
index 4000c7603d8e..dcaecf69ea5a 100644
--- a/arch/loongarch/include/asm/jump_label.h
+++ b/arch/loongarch/include/asm/jump_label.h
@@ -10,15 +10,23 @@
 #ifndef __ASSEMBLER__
 
 #include <linux/types.h>
+#include <linux/stringify.h>
+#include <asm/asm.h>
 
 #define JUMP_LABEL_NOP_SIZE	4
 
+#ifdef CONFIG_32BIT
+#define JUMP_LABEL_TYPE		".long "
+#else
+#define JUMP_LABEL_TYPE		".quad "
+#endif
+
 /* This macro is also expanded on the Rust side. */
 #define JUMP_TABLE_ENTRY(key, label)			\
 	 ".pushsection	__jump_table, \"aw\"	\n\t"	\
-	 ".align	3			\n\t"	\
+	 ".align	" __stringify(PTRLOG) "	\n\t"	\
 	 ".long		1b - ., " label " - .	\n\t"	\
-	 ".quad		" key " - .		\n\t"	\
+	 JUMP_LABEL_TYPE  key " - .		\n\t"	\
 	 ".popsection				\n\t"
 
 #define ARCH_STATIC_BRANCH_ASM(key, label)		\
diff --git a/arch/loongarch/include/asm/string.h b/arch/loongarch/include/asm/string.h
index 5bb5a90d2681..bfa3fd879c7f 100644
--- a/arch/loongarch/include/asm/string.h
+++ b/arch/loongarch/include/asm/string.h
@@ -5,6 +5,7 @@
 #ifndef _ASM_STRING_H
 #define _ASM_STRING_H
 
+#ifdef CONFIG_64BIT
 #define __HAVE_ARCH_MEMSET
 extern void *memset(void *__s, int __c, size_t __count);
 extern void *__memset(void *__s, int __c, size_t __count);
@@ -16,6 +17,7 @@ extern void *__memcpy(void *__to, __const__ void *__from, size_t __n);
 #define __HAVE_ARCH_MEMMOVE
 extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
 extern void *__memmove(void *__dest, __const__ void *__src, size_t __n);
+#endif
 
 #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
 
diff --git a/arch/loongarch/kernel/unaligned.c b/arch/loongarch/kernel/unaligned.c
index 487be604b96a..cc929c9fe7e9 100644
--- a/arch/loongarch/kernel/unaligned.c
+++ b/arch/loongarch/kernel/unaligned.c
@@ -27,12 +27,21 @@ static u32 unaligned_instructions_user;
 static u32 unaligned_instructions_kernel;
 #endif
 
-static inline unsigned long read_fpr(unsigned int idx)
+static inline u64 read_fpr(unsigned int idx)
 {
+#ifdef CONFIG_64BIT
 #define READ_FPR(idx, __value)		\
 	__asm__ __volatile__("movfr2gr.d %0, $f"#idx"\n\t" : "=r"(__value));
-
-	unsigned long __value;
+#else
+#define READ_FPR(idx, __value)								\
+{											\
+	u32 __value_lo, __value_hi;							\
+	__asm__ __volatile__("movfr2gr.s  %0, $f"#idx"\n\t" : "=r"(__value_lo));	\
+	__asm__ __volatile__("movfrh2gr.s %0, $f"#idx"\n\t" : "=r"(__value_hi));	\
+	__value = (__value_lo | ((u64)__value_hi << 32));				\
+}
+#endif
+	u64 __value;
 
 	switch (idx) {
 	case 0:
@@ -138,11 +147,20 @@ static inline unsigned long read_fpr(unsigned int idx)
 	return __value;
 }
 
-static inline void write_fpr(unsigned int idx, unsigned long value)
+static inline void write_fpr(unsigned int idx, u64 value)
 {
+#ifdef CONFIG_64BIT
 #define WRITE_FPR(idx, value)		\
 	__asm__ __volatile__("movgr2fr.d $f"#idx", %0\n\t" :: "r"(value));
-
+#else
+#define WRITE_FPR(idx, value)							\
+{										\
+	u32 value_lo = value;							\
+	u32 value_hi = value >> 32;						\
+	__asm__ __volatile__("movgr2fr.w  $f"#idx", %0\n\t" :: "r"(value_lo));	\
+	__asm__ __volatile__("movgr2frh.w $f"#idx", %0\n\t" :: "r"(value_hi));	\
+}
+#endif
 	switch (idx) {
 	case 0:
 		WRITE_FPR(0, value);
@@ -252,7 +270,7 @@ void emulate_load_store_insn(struct pt_regs *regs, void __user *addr, unsigned i
 	bool sign, write;
 	bool user = user_mode(regs);
 	unsigned int res, size = 0;
-	unsigned long value = 0;
+	u64 value = 0;
 	union loongarch_instruction insn;
 
 	perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0);
diff --git a/arch/loongarch/lib/unaligned.S b/arch/loongarch/lib/unaligned.S
index 185f82d85810..470c0bfa3463 100644
--- a/arch/loongarch/lib/unaligned.S
+++ b/arch/loongarch/lib/unaligned.S
@@ -24,35 +24,35 @@
  * a3: sign
  */
 SYM_FUNC_START(unaligned_read)
-	beqz	a2, 5f
+	beqz		a2, 5f
 
-	li.w	t2, 0
-	addi.d	t0, a2, -1
-	slli.d	t1, t0, 3
-	add.d 	a0, a0, t0
+	li.w		t2, 0
+	LONG_ADDI	t0, a2, -1
+	PTR_SLLI	t1, t0, LONGLOG
+	PTR_ADD		a0, a0, t0
 
-	beqz	a3, 2f
-1:	ld.b	t3, a0, 0
-	b	3f
+	beqz		a3, 2f
+1:	ld.b		t3, a0, 0
+	b		3f
 
-2:	ld.bu	t3, a0, 0
-3:	sll.d	t3, t3, t1
-	or	t2, t2, t3
-	addi.d	t1, t1, -8
-	addi.d	a0, a0, -1
-	addi.d	a2, a2, -1
-	bgtz	a2, 2b
-4:	st.d	t2, a1, 0
+2:	ld.bu		t3, a0, 0
+3:	LONG_SLLV	t3, t3, t1
+	or		t2, t2, t3
+	LONG_ADDI	t1, t1, -8
+	PTR_ADDI	a0, a0, -1
+	PTR_ADDI	a2, a2, -1
+	bgtz		a2, 2b
+4:	LONG_S		t2, a1, 0
 
-	move	a0, a2
-	jr	ra
+	move		a0, a2
+	jr		ra
 
-5:	li.w    a0, -EFAULT
-	jr	ra
+5:	li.w		a0, -EFAULT
+	jr		ra
 
-	_asm_extable 1b, .L_fixup_handle_unaligned
-	_asm_extable 2b, .L_fixup_handle_unaligned
-	_asm_extable 4b, .L_fixup_handle_unaligned
+	_asm_extable	1b, .L_fixup_handle_unaligned
+	_asm_extable	2b, .L_fixup_handle_unaligned
+	_asm_extable	4b, .L_fixup_handle_unaligned
 SYM_FUNC_END(unaligned_read)
 
 /*
@@ -63,21 +63,21 @@ SYM_FUNC_END(unaligned_read)
  * a2: n
  */
 SYM_FUNC_START(unaligned_write)
-	beqz	a2, 3f
+	beqz		a2, 3f
 
-	li.w	t0, 0
-1:	srl.d	t1, a1, t0
-2:	st.b	t1, a0, 0
-	addi.d	t0, t0, 8
-	addi.d	a2, a2, -1
-	addi.d	a0, a0, 1
-	bgtz	a2, 1b
+	li.w		t0, 0
+1:	LONG_SRLV	t1, a1, t0
+2:	st.b		t1, a0, 0
+	LONG_ADDI	t0, t0, 8
+	PTR_ADDI	a2, a2, -1
+	PTR_ADDI	a0, a0, 1
+	bgtz		a2, 1b
 
-	move	a0, a2
-	jr	ra
+	move		a0, a2
+	jr		ra
 
-3:	li.w    a0, -EFAULT
-	jr	ra
+3:	li.w		a0, -EFAULT
+	jr		ra
 
-	_asm_extable 2b, .L_fixup_handle_unaligned
+	_asm_extable	2b, .L_fixup_handle_unaligned
 SYM_FUNC_END(unaligned_write)
diff --git a/arch/loongarch/pci/pci.c b/arch/loongarch/pci/pci.c
index 5bc9627a6cf9..d9fc5d520b37 100644
--- a/arch/loongarch/pci/pci.c
+++ b/arch/loongarch/pci/pci.c
@@ -50,11 +50,11 @@ static int __init pcibios_init(void)
 	 */
 	lsize = cpu_last_level_cache_line_size();
 
-	BUG_ON(!lsize);
+	if (lsize) {
+		pci_dfl_cache_line_size = lsize >> 2;
 
-	pci_dfl_cache_line_size = lsize >> 2;
-
-	pr_debug("PCI: pci_cache_line_size set to %d bytes\n", lsize);
+		pr_debug("PCI: pci_cache_line_size set to %d bytes\n", lsize);
+	}
 
 	return 0;
 }
diff --git a/arch/loongarch/power/suspend_asm.S b/arch/loongarch/power/suspend_asm.S
index df0865df26fa..c8119ad5fb2c 100644
--- a/arch/loongarch/power/suspend_asm.S
+++ b/arch/loongarch/power/suspend_asm.S
@@ -14,41 +14,41 @@
 
 /* preparatory stuff */
 .macro	SETUP_SLEEP
-	addi.d		sp, sp, -PT_SIZE
-	st.d		$r1, sp, PT_R1
-	st.d		$r2, sp, PT_R2
-	st.d		$r3, sp, PT_R3
-	st.d		$r4, sp, PT_R4
-	st.d		$r21, sp, PT_R21
-	st.d		$r22, sp, PT_R22
-	st.d		$r23, sp, PT_R23
-	st.d		$r24, sp, PT_R24
-	st.d		$r25, sp, PT_R25
-	st.d		$r26, sp, PT_R26
-	st.d		$r27, sp, PT_R27
-	st.d		$r28, sp, PT_R28
-	st.d		$r29, sp, PT_R29
-	st.d		$r30, sp, PT_R30
-	st.d		$r31, sp, PT_R31
+	PTR_ADDI	sp, sp, -PT_SIZE
+	REG_S		$r1, sp, PT_R1
+	REG_S		$r2, sp, PT_R2
+	REG_S		$r3, sp, PT_R3
+	REG_S		$r4, sp, PT_R4
+	REG_S		$r21, sp, PT_R21
+	REG_S		$r22, sp, PT_R22
+	REG_S		$r23, sp, PT_R23
+	REG_S		$r24, sp, PT_R24
+	REG_S		$r25, sp, PT_R25
+	REG_S		$r26, sp, PT_R26
+	REG_S		$r27, sp, PT_R27
+	REG_S		$r28, sp, PT_R28
+	REG_S		$r29, sp, PT_R29
+	REG_S		$r30, sp, PT_R30
+	REG_S		$r31, sp, PT_R31
 .endm
 
 .macro SETUP_WAKEUP
-	ld.d		$r1, sp, PT_R1
-	ld.d		$r2, sp, PT_R2
-	ld.d		$r3, sp, PT_R3
-	ld.d		$r4, sp, PT_R4
-	ld.d		$r21, sp, PT_R21
-	ld.d		$r22, sp, PT_R22
-	ld.d		$r23, sp, PT_R23
-	ld.d		$r24, sp, PT_R24
-	ld.d		$r25, sp, PT_R25
-	ld.d		$r26, sp, PT_R26
-	ld.d		$r27, sp, PT_R27
-	ld.d		$r28, sp, PT_R28
-	ld.d		$r29, sp, PT_R29
-	ld.d		$r30, sp, PT_R30
-	ld.d		$r31, sp, PT_R31
-	addi.d		sp, sp, PT_SIZE
+	REG_L		$r1, sp, PT_R1
+	REG_L		$r2, sp, PT_R2
+	REG_L		$r3, sp, PT_R3
+	REG_L		$r4, sp, PT_R4
+	REG_L		$r21, sp, PT_R21
+	REG_L		$r22, sp, PT_R22
+	REG_L		$r23, sp, PT_R23
+	REG_L		$r24, sp, PT_R24
+	REG_L		$r25, sp, PT_R25
+	REG_L		$r26, sp, PT_R26
+	REG_L		$r27, sp, PT_R27
+	REG_L		$r28, sp, PT_R28
+	REG_L		$r29, sp, PT_R29
+	REG_L		$r30, sp, PT_R30
+	REG_L		$r31, sp, PT_R31
+	PTR_ADDI	sp, sp, PT_SIZE
 .endm
 
 	.text
@@ -59,15 +59,15 @@ SYM_FUNC_START(loongarch_suspend_enter)
 	SETUP_SLEEP
 
 	la.pcrel	t0, acpi_saved_sp
-	st.d		sp, t0, 0
+	REG_S		sp, t0, 0
 
 	bl		__flush_cache_all
 
 	/* Pass RA and SP to BIOS */
-	addi.d		a1, sp, 0
+	PTR_ADDI	a1, sp, 0
 	la.pcrel	a0, loongarch_wakeup_start
 	la.pcrel	t0, loongarch_suspend_addr
-	ld.d		t0, t0, 0
+	REG_L		t0, t0, 0
 	jirl		ra, t0, 0 /* Call BIOS's STR sleep routine */
 
 	/*
@@ -83,7 +83,7 @@ SYM_INNER_LABEL(loongarch_wakeup_start, SYM_L_GLOBAL)
 	csrwr		t0, LOONGARCH_CSR_CRMD
 
 	la.pcrel	t0, acpi_saved_sp
-	ld.d		sp, t0, 0
+	REG_L		sp, t0, 0
 
 	SETUP_WAKEUP
 	jr		ra
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH V2 12/14] LoongArch: Adjust VDSO/VSYSCALL for 32BIT/64BIT
  2025-11-18 11:27 [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Huacai Chen
                   ` (10 preceding siblings ...)
  2025-11-18 11:27 ` [PATCH V2 11/14] LoongArch: Adjust misc routines " Huacai Chen
@ 2025-11-18 11:27 ` Huacai Chen
  2025-11-18 13:41   ` Arnd Bergmann
  2025-11-18 11:27 ` [PATCH V2 13/14] LoongArch: Adjust default config files " Huacai Chen
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 37+ messages in thread
From: Huacai Chen @ 2025-11-18 11:27 UTC (permalink / raw)
  To: Arnd Bergmann, Huacai Chen
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Xuerui Wang,
	Jiaxun Yang, linux-kernel, Huacai Chen

Adjust VDSO/VSYSCALL because read_cpu_id() for 32BIT/64BIT are
different, and LoongArch32 doesn't support GENERIC_GETTIMEOFDAY now.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
 arch/loongarch/include/asm/vdso/gettimeofday.h | 4 ++++
 arch/loongarch/kernel/time.c                   | 2 ++
 arch/loongarch/vdso/Makefile                   | 7 ++++++-
 arch/loongarch/vdso/vdso.lds.S                 | 4 ++--
 arch/loongarch/vdso/vgetcpu.c                  | 8 ++++++++
 5 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/loongarch/include/asm/vdso/gettimeofday.h b/arch/loongarch/include/asm/vdso/gettimeofday.h
index dcafabca9bb6..bae76767c693 100644
--- a/arch/loongarch/include/asm/vdso/gettimeofday.h
+++ b/arch/loongarch/include/asm/vdso/gettimeofday.h
@@ -12,6 +12,8 @@
 #include <asm/unistd.h>
 #include <asm/vdso/vdso.h>
 
+#ifdef CONFIG_GENERIC_GETTIMEOFDAY
+
 #define VDSO_HAS_CLOCK_GETRES		1
 
 static __always_inline long gettimeofday_fallback(
@@ -89,6 +91,8 @@ static inline bool loongarch_vdso_hres_capable(void)
 }
 #define __arch_vdso_hres_capable loongarch_vdso_hres_capable
 
+#endif /* CONFIG_GENERIC_GETTIMEOFDAY */
+
 #endif /* !__ASSEMBLER__ */
 
 #endif /* __ASM_VDSO_GETTIMEOFDAY_H */
diff --git a/arch/loongarch/kernel/time.c b/arch/loongarch/kernel/time.c
index 5892f6da07a5..dbaaabcaf6f0 100644
--- a/arch/loongarch/kernel/time.c
+++ b/arch/loongarch/kernel/time.c
@@ -212,7 +212,9 @@ static struct clocksource clocksource_const = {
 	.read = read_const_counter,
 	.mask = CLOCKSOURCE_MASK(64),
 	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
+#ifdef CONFIG_GENERIC_GETTIMEOFDAY
 	.vdso_clock_mode = VDSO_CLOCKMODE_CPU,
+#endif
 };
 
 int __init constant_clocksource_init(void)
diff --git a/arch/loongarch/vdso/Makefile b/arch/loongarch/vdso/Makefile
index d8316f993482..a8ac0e811e39 100644
--- a/arch/loongarch/vdso/Makefile
+++ b/arch/loongarch/vdso/Makefile
@@ -4,8 +4,9 @@
 # Include the generic Makefile to check the built vdso.
 include $(srctree)/lib/vdso/Makefile.include
 
-obj-vdso-y := elf.o vgetcpu.o vgettimeofday.o vgetrandom.o \
+obj-vdso-y := elf.o vgetcpu.o vgetrandom.o \
               vgetrandom-chacha.o sigreturn.o
+obj-vdso-$(CONFIG_GENERIC_GETTIMEOFDAY) += vgettimeofday.o
 
 # Common compiler flags between ABIs.
 ccflags-vdso := \
@@ -16,6 +17,10 @@ ccflags-vdso := \
 	$(CLANG_FLAGS) \
 	-D__VDSO__
 
+ifdef CONFIG_32BIT
+ccflags-vdso += -DBUILD_VDSO32
+endif
+
 cflags-vdso := $(ccflags-vdso) \
 	-isystem $(shell $(CC) -print-file-name=include) \
 	$(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \
diff --git a/arch/loongarch/vdso/vdso.lds.S b/arch/loongarch/vdso/vdso.lds.S
index 8ff986499947..ac537e02beb1 100644
--- a/arch/loongarch/vdso/vdso.lds.S
+++ b/arch/loongarch/vdso/vdso.lds.S
@@ -7,8 +7,6 @@
 #include <generated/asm-offsets.h>
 #include <vdso/datapage.h>
 
-OUTPUT_FORMAT("elf64-loongarch", "elf64-loongarch", "elf64-loongarch")
-
 OUTPUT_ARCH(loongarch)
 
 SECTIONS
@@ -63,9 +61,11 @@ VERSION
 	LINUX_5.10 {
 	global:
 		__vdso_getcpu;
+#ifdef CONFIG_GENERIC_GETTIMEOFDAY
 		__vdso_clock_getres;
 		__vdso_clock_gettime;
 		__vdso_gettimeofday;
+#endif
 		__vdso_getrandom;
 		__vdso_rt_sigreturn;
 	local: *;
diff --git a/arch/loongarch/vdso/vgetcpu.c b/arch/loongarch/vdso/vgetcpu.c
index 5301cd9d0f83..73af49242ecd 100644
--- a/arch/loongarch/vdso/vgetcpu.c
+++ b/arch/loongarch/vdso/vgetcpu.c
@@ -10,11 +10,19 @@ static __always_inline int read_cpu_id(void)
 {
 	int cpu_id;
 
+#ifdef CONFIG_64BIT
 	__asm__ __volatile__(
 	"	rdtime.d $zero, %0\n"
 	: "=r" (cpu_id)
 	:
 	: "memory");
+#else
+	__asm__ __volatile__(
+	"	rdtimel.w $zero, %0\n"
+	: "=r" (cpu_id)
+	:
+	: "memory");
+#endif
 
 	return cpu_id;
 }
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH V2 13/14] LoongArch: Adjust default config files for 32BIT/64BIT
  2025-11-18 11:27 [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Huacai Chen
                   ` (11 preceding siblings ...)
  2025-11-18 11:27 ` [PATCH V2 12/14] LoongArch: Adjust VDSO/VSYSCALL " Huacai Chen
@ 2025-11-18 11:27 ` Huacai Chen
  2025-11-18 13:45   ` Arnd Bergmann
  2025-11-20  8:11   ` Thomas Weißschuh
  2025-11-18 11:27 ` [PATCH V2 14/14] LoongArch: Adjust build infrastructure " Huacai Chen
  2025-11-18 14:07 ` [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Arnd Bergmann
  14 siblings, 2 replies; 37+ messages in thread
From: Huacai Chen @ 2025-11-18 11:27 UTC (permalink / raw)
  To: Arnd Bergmann, Huacai Chen
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Xuerui Wang,
	Jiaxun Yang, linux-kernel, Huacai Chen

Add loongson32_defconfig (for 32BIT) and rename loongson3_defconfig to
loongson64_defconfig (for 64BIT).

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
 arch/loongarch/configs/loongson32_defconfig   | 1110 +++++++++++++++++
 ...ongson3_defconfig => loongson64_defconfig} |    0
 2 files changed, 1110 insertions(+)
 create mode 100644 arch/loongarch/configs/loongson32_defconfig
 rename arch/loongarch/configs/{loongson3_defconfig => loongson64_defconfig} (100%)

diff --git a/arch/loongarch/configs/loongson32_defconfig b/arch/loongarch/configs/loongson32_defconfig
new file mode 100644
index 000000000000..e45e70c38866
--- /dev/null
+++ b/arch/loongarch/configs/loongson32_defconfig
@@ -0,0 +1,1110 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_KERNEL_ZSTD=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_BPF_SYSCALL=y
+CONFIG_PREEMPT=y
+CONFIG_PREEMPT_DYNAMIC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_PSI=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_IKHEADERS=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_MEMCG=y
+CONFIG_BLK_CGROUP=y
+CONFIG_CFS_BANDWIDTH=y
+CONFIG_CGROUP_PIDS=y
+CONFIG_CGROUP_RDMA=y
+CONFIG_CGROUP_DMEM=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_PERF=y
+CONFIG_CGROUP_BPF=y
+CONFIG_CGROUP_MISC=y
+CONFIG_NAMESPACES=y
+CONFIG_USER_NS=y
+CONFIG_CHECKPOINT_RESTORE=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_PERF_EVENTS=y
+CONFIG_KEXEC=y
+CONFIG_LOONGARCH=y
+CONFIG_32BIT=y
+CONFIG_32BIT_STANDARD=y
+CONFIG_MACH_LOONGSON32=y
+CONFIG_PAGE_SIZE_16KB=y
+CONFIG_HZ_250=y
+CONFIG_DMI=y
+CONFIG_EFI=y
+CONFIG_SUSPEND=y
+CONFIG_HIBERNATION=y
+CONFIG_ACPI=y
+CONFIG_ACPI_SPCR_TABLE=y
+CONFIG_ACPI_TAD=y
+CONFIG_ACPI_DOCK=y
+CONFIG_ACPI_IPMI=m
+CONFIG_ACPI_HOTPLUG_CPU=y
+CONFIG_ACPI_PCI_SLOT=y
+CONFIG_ACPI_HOTPLUG_MEMORY=y
+CONFIG_ACPI_BGRT=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
+CONFIG_VIRTUALIZATION=y
+CONFIG_JUMP_LABEL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_COMPRESS=y
+CONFIG_MODULE_COMPRESS_ZSTD=y
+CONFIG_MODULE_DECOMPRESS=y
+CONFIG_BLK_DEV_ZONED=y
+CONFIG_BLK_DEV_THROTTLING=y
+CONFIG_BLK_WBT=y
+CONFIG_BLK_CGROUP_IOLATENCY=y
+CONFIG_BLK_CGROUP_FC_APPID=y
+CONFIG_BLK_CGROUP_IOCOST=y
+CONFIG_BLK_CGROUP_IOPRIO=y
+CONFIG_BLK_INLINE_ENCRYPTION=y
+CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_CMDLINE_PARTITION=y
+CONFIG_IOSCHED_BFQ=y
+CONFIG_BFQ_GROUP_IOSCHED=y
+CONFIG_BINFMT_MISC=m
+CONFIG_ZSWAP=y
+CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD=y
+CONFIG_ZSMALLOC=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MEMORY_HOTPLUG=y
+# CONFIG_MHP_DEFAULT_ONLINE_TYPE_OFFLINE is not set
+CONFIG_MHP_DEFAULT_ONLINE_TYPE_ONLINE_AUTO=y
+# CONFIG_MHP_DEFAULT_ONLINE_TYPE_ONLINE_KERNEL is not set
+# CONFIG_MHP_DEFAULT_ONLINE_TYPE_ONLINE_MOVABLE is not set
+CONFIG_MEMORY_HOTREMOVE=y
+CONFIG_KSM=y
+CONFIG_CMA=y
+CONFIG_CMA_SYSFS=y
+CONFIG_USERFAULTFD=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_TLS=m
+CONFIG_TLS_DEVICE=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_XDP_SOCKETS=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=m
+CONFIG_NET_IPGRE_DEMUX=m
+CONFIG_NET_IPGRE=m
+CONFIG_NET_IPGRE_BROADCAST=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_ESP_OFFLOAD=m
+CONFIG_INET_ESPINTCP=y
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_UDP_DIAG=y
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_BIC=y
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_NV=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_DCTCP=m
+CONFIG_TCP_CONG_CDG=m
+CONFIG_TCP_CONG_BBR=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_ESP_OFFLOAD=m
+CONFIG_INET6_ESPINTCP=y
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_MROUTE=y
+CONFIG_MPTCP=y
+CONFIG_NETWORK_PHY_TIMESTAMPING=y
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE_NETFILTER=m
+CONFIG_NETFILTER_NETLINK_LOG=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_SNMP=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NF_TABLES=m
+CONFIG_NF_TABLES_INET=y
+CONFIG_NFT_CT=m
+CONFIG_NFT_CONNLIMIT=m
+CONFIG_NFT_LOG=m
+CONFIG_NFT_LIMIT=m
+CONFIG_NFT_MASQ=m
+CONFIG_NFT_REDIR=m
+CONFIG_NFT_NAT=m
+CONFIG_NFT_TUNNEL=m
+CONFIG_NFT_QUEUE=m
+CONFIG_NFT_QUOTA=m
+CONFIG_NFT_REJECT=m
+CONFIG_NFT_COMPAT=m
+CONFIG_NFT_HASH=m
+CONFIG_NFT_FIB_INET=m
+CONFIG_NFT_SOCKET=m
+CONFIG_NFT_OSF=m
+CONFIG_NFT_TPROXY=m
+CONFIG_NETFILTER_XT_SET=m
+CONFIG_NETFILTER_XT_TARGET_AUDIT=m
+CONFIG_NETFILTER_XT_TARGET_CHECKSUM=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_CT=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HMARK=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_LED=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_BPF=m
+CONFIG_NETFILTER_XT_MATCH_CGROUP=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLABEL=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_CPU=m
+CONFIG_NETFILTER_XT_MATCH_DEVGROUP=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_IPCOMP=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_IPVS=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_NFACCT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_SET=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_IPV6=y
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_PROTO_SCTP=y
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_NFCT=y
+CONFIG_NF_TABLES_IPV4=y
+CONFIG_NFT_DUP_IPV4=m
+CONFIG_NFT_FIB_IPV4=m
+CONFIG_NF_TABLES_ARP=y
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_SYNPROXY=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_SECURITY=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_TABLES_IPV6=y
+CONFIG_NFT_FIB_IPV6=m
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_MATCH_SRH=m
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_TARGET_SYNPROXY=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_IP6_NF_SECURITY=m
+CONFIG_IP6_NF_NAT=m
+CONFIG_IP6_NF_TARGET_MASQUERADE=m
+CONFIG_IP6_NF_TARGET_NPT=m
+CONFIG_NF_TABLES_BRIDGE=m
+CONFIG_NF_CONNTRACK_BRIDGE=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_IP6=m
+CONFIG_IP_SCTP=m
+CONFIG_RDS=y
+CONFIG_L2TP=m
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=m
+CONFIG_L2TP_ETH=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_VLAN_8021Q_MVRP=y
+CONFIG_LLC2=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_MULTIQ=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFB=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_CBS=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_MQPRIO=m
+CONFIG_NET_SCH_SKBPRIO=m
+CONFIG_NET_SCH_QFQ=m
+CONFIG_NET_SCH_CODEL=m
+CONFIG_NET_SCH_FQ_CODEL=m
+CONFIG_NET_SCH_CAKE=m
+CONFIG_NET_SCH_FQ=m
+CONFIG_NET_SCH_PIE=m
+CONFIG_NET_SCH_FQ_PIE=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_SCH_DEFAULT=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_CGROUP=m
+CONFIG_NET_CLS_BPF=m
+CONFIG_NET_CLS_FLOWER=m
+CONFIG_NET_CLS_MATCHALL=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_BPF=m
+CONFIG_OPENVSWITCH=m
+CONFIG_VSOCKETS=m
+CONFIG_VIRTIO_VSOCKETS=m
+CONFIG_NETLINK_DIAG=y
+CONFIG_CGROUP_NET_PRIO=y
+CONFIG_BPF_STREAM_PARSER=y
+CONFIG_BT=m
+CONFIG_BT_RFCOMM=m
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=m
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=m
+CONFIG_BT_HS=y
+CONFIG_BT_HCIBTUSB=m
+CONFIG_BT_HCIBTUSB_AUTOSUSPEND=y
+CONFIG_BT_HCIBTUSB_MTK=y
+CONFIG_BT_HCIUART=m
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_ATH3K=y
+CONFIG_BT_HCIUART_INTEL=y
+CONFIG_BT_HCIUART_AG6XX=y
+CONFIG_BT_HCIBCM203X=m
+CONFIG_BT_HCIBPA10X=m
+CONFIG_BT_HCIBFUSB=m
+CONFIG_BT_HCIDTL1=m
+CONFIG_BT_HCIBT3C=m
+CONFIG_BT_HCIBLUECARD=m
+CONFIG_BT_HCIVHCI=m
+CONFIG_BT_MRVL=m
+CONFIG_BT_ATH3K=m
+CONFIG_BT_VIRTIO=m
+CONFIG_CFG80211=m
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=m
+CONFIG_RFKILL=m
+CONFIG_RFKILL_INPUT=y
+CONFIG_NET_9P=y
+CONFIG_NET_9P_VIRTIO=y
+CONFIG_CEPH_LIB=m
+CONFIG_PCIEPORTBUS=y
+CONFIG_HOTPLUG_PCI_PCIE=y
+CONFIG_PCIEAER=y
+# CONFIG_PCIEASPM is not set
+CONFIG_PCI_IOV=y
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HOTPLUG_PCI_SHPC=y
+CONFIG_PCI_HOST_GENERIC=y
+CONFIG_PCCARD=m
+CONFIG_YENTA=m
+CONFIG_RAPIDIO=y
+CONFIG_RAPIDIO_TSI721=y
+CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS=y
+CONFIG_RAPIDIO_ENUM_BASIC=m
+CONFIG_RAPIDIO_CHMAN=m
+CONFIG_RAPIDIO_MPORT_CDEV=m
+CONFIG_UEVENT_HELPER=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_FW_LOADER_COMPRESS=y
+CONFIG_FW_LOADER_COMPRESS_ZSTD=y
+CONFIG_SYSFB_SIMPLEFB=y
+CONFIG_EFI_ZBOOT=y
+CONFIG_EFI_BOOTLOADER_CONTROL=m
+CONFIG_EFI_CAPSULE_LOADER=m
+CONFIG_EFI_TEST=m
+CONFIG_MTD=m
+CONFIG_MTD_BLOCK=m
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_RAM=m
+CONFIG_MTD_ROM=m
+CONFIG_MTD_RAW_NAND=m
+CONFIG_MTD_NAND_PLATFORM=m
+CONFIG_MTD_NAND_LOONGSON=m
+CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC=y
+CONFIG_MTD_NAND_ECC_SW_BCH=y
+CONFIG_MTD_UBI=m
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_PARPORT=y
+CONFIG_PARPORT_PC=y
+CONFIG_PARPORT_SERIAL=y
+CONFIG_PARPORT_PC_FIFO=y
+CONFIG_ZRAM=m
+CONFIG_ZRAM_BACKEND_LZ4=y
+CONFIG_ZRAM_BACKEND_LZ4HC=y
+CONFIG_ZRAM_BACKEND_ZSTD=y
+CONFIG_ZRAM_BACKEND_DEFLATE=y
+CONFIG_ZRAM_BACKEND_842=y
+CONFIG_ZRAM_BACKEND_LZO=y
+CONFIG_ZRAM_DEF_COMP_ZSTD=y
+CONFIG_ZRAM_WRITEBACK=y
+CONFIG_ZRAM_MEMORY_TRACKING=y
+CONFIG_ZRAM_MULTI_COMP=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_DRBD=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_VIRTIO_BLK=y
+CONFIG_BLK_DEV_RBD=m
+CONFIG_BLK_DEV_NVME=y
+CONFIG_NVME_MULTIPATH=y
+CONFIG_NVME_RDMA=m
+CONFIG_NVME_FC=m
+CONFIG_NVME_TCP=m
+CONFIG_NVME_TARGET=m
+CONFIG_NVME_TARGET_PASSTHRU=y
+CONFIG_NVME_TARGET_LOOP=m
+CONFIG_NVME_TARGET_RDMA=m
+CONFIG_NVME_TARGET_FC=m
+CONFIG_NVME_TARGET_TCP=m
+CONFIG_EEPROM_AT24=m
+CONFIG_PVPANIC=y
+CONFIG_PVPANIC_MMIO=m
+CONFIG_PVPANIC_PCI=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_ATTRS=m
+CONFIG_SCSI_SAS_ATA=y
+CONFIG_ISCSI_TCP=m
+CONFIG_SCSI_MVSAS=y
+# CONFIG_SCSI_MVSAS_DEBUG is not set
+CONFIG_SCSI_MVSAS_TASKLET=y
+CONFIG_SCSI_MVUMI=y
+CONFIG_MEGARAID_NEWGEN=y
+CONFIG_MEGARAID_MM=y
+CONFIG_MEGARAID_MAILBOX=y
+CONFIG_MEGARAID_LEGACY=y
+CONFIG_MEGARAID_SAS=y
+CONFIG_SCSI_MPT2SAS=y
+CONFIG_LIBFC=m
+CONFIG_LIBFCOE=m
+CONFIG_FCOE=m
+CONFIG_SCSI_QLOGIC_1280=m
+CONFIG_SCSI_QLA_FC=m
+CONFIG_TCM_QLA2XXX=m
+CONFIG_SCSI_QLA_ISCSI=m
+CONFIG_SCSI_LPFC=m
+CONFIG_SCSI_VIRTIO=m
+CONFIG_ATA=y
+CONFIG_SATA_AHCI=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_AHCI_DWC=y
+CONFIG_PATA_ATIIXP=y
+CONFIG_PATA_PCMCIA=m
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=m
+CONFIG_MD_LLBITMAP=y
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_BCACHE=m
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_THIN_PROVISIONING=m
+CONFIG_DM_CACHE=m
+CONFIG_DM_WRITECACHE=m
+CONFIG_DM_MIRROR=m
+CONFIG_DM_RAID=m
+CONFIG_DM_ZERO=m
+CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
+CONFIG_DM_MULTIPATH_HST=m
+CONFIG_DM_MULTIPATH_IOA=m
+CONFIG_DM_INIT=y
+CONFIG_DM_UEVENT=y
+CONFIG_DM_VERITY=m
+CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y
+CONFIG_DM_VERITY_FEC=y
+CONFIG_DM_INTEGRITY=m
+CONFIG_DM_ZONED=m
+CONFIG_DM_VDO=m
+CONFIG_TARGET_CORE=m
+CONFIG_TCM_IBLOCK=m
+CONFIG_TCM_FILEIO=m
+CONFIG_TCM_PSCSI=m
+CONFIG_TCM_USER2=m
+CONFIG_LOOPBACK_TARGET=m
+CONFIG_ISCSI_TARGET=m
+CONFIG_NETDEVICES=y
+CONFIG_BONDING=m
+CONFIG_DUMMY=y
+CONFIG_WIREGUARD=m
+CONFIG_IFB=m
+CONFIG_NET_TEAM=m
+CONFIG_NET_TEAM_MODE_BROADCAST=m
+CONFIG_NET_TEAM_MODE_ROUNDROBIN=m
+CONFIG_NET_TEAM_MODE_RANDOM=m
+CONFIG_NET_TEAM_MODE_ACTIVEBACKUP=m
+CONFIG_NET_TEAM_MODE_LOADBALANCE=m
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+CONFIG_IPVLAN=m
+CONFIG_VXLAN=y
+CONFIG_RIONET=m
+CONFIG_TUN=m
+CONFIG_VETH=m
+CONFIG_VIRTIO_NET=m
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_ADAPTEC is not set
+# CONFIG_NET_VENDOR_AGERE is not set
+# CONFIG_NET_VENDOR_ALACRITECH is not set
+# CONFIG_NET_VENDOR_ALTEON is not set
+# CONFIG_NET_VENDOR_AMAZON is not set
+# CONFIG_NET_VENDOR_AMD is not set
+# CONFIG_NET_VENDOR_AQUANTIA is not set
+# CONFIG_NET_VENDOR_ARC is not set
+# CONFIG_NET_VENDOR_ATHEROS is not set
+CONFIG_BNX2=y
+# CONFIG_NET_VENDOR_CAVIUM is not set
+CONFIG_CHELSIO_T1=m
+CONFIG_CHELSIO_T1_1G=y
+CONFIG_CHELSIO_T3=m
+CONFIG_CHELSIO_T4=m
+# CONFIG_NET_VENDOR_CISCO is not set
+# CONFIG_NET_VENDOR_DEC is not set
+# CONFIG_NET_VENDOR_DLINK is not set
+# CONFIG_NET_VENDOR_EMULEX is not set
+# CONFIG_NET_VENDOR_EZCHIP is not set
+# CONFIG_NET_VENDOR_I825XX is not set
+CONFIG_E1000=y
+CONFIG_E1000E=y
+CONFIG_IGB=y
+CONFIG_IXGBE=y
+CONFIG_I40E=y
+CONFIG_ICE=y
+CONFIG_FM10K=y
+CONFIG_IGC=y
+CONFIG_IDPF=y
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MELLANOX is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MYRI is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_NETRONOME is not set
+# CONFIG_NET_VENDOR_NVIDIA is not set
+# CONFIG_NET_VENDOR_OKI is not set
+# CONFIG_NET_VENDOR_QLOGIC is not set
+# CONFIG_NET_VENDOR_BROCADE is not set
+# CONFIG_NET_VENDOR_QUALCOMM is not set
+# CONFIG_NET_VENDOR_RDC is not set
+CONFIG_8139CP=m
+CONFIG_8139TOO=m
+CONFIG_R8169=y
+# CONFIG_NET_VENDOR_RENESAS is not set
+# CONFIG_NET_VENDOR_ROCKER is not set
+# CONFIG_NET_VENDOR_SAMSUNG is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SILAN is not set
+# CONFIG_NET_VENDOR_SIS is not set
+# CONFIG_NET_VENDOR_SOLARFLARE is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+CONFIG_STMMAC_ETH=y
+# CONFIG_NET_VENDOR_SUN is not set
+# CONFIG_NET_VENDOR_TEHUTI is not set
+# CONFIG_NET_VENDOR_TI is not set
+# CONFIG_NET_VENDOR_VIA is not set
+CONFIG_NGBE=y
+CONFIG_TXGBE=y
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_NET_VENDOR_XILINX is not set
+CONFIG_MOTORCOMM_PHY=y
+CONFIG_PPP=m
+CONFIG_PPP_BSDCOMP=m
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=m
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=m
+CONFIG_PPTP=m
+CONFIG_PPPOL2TP=m
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_RTL8152=m
+CONFIG_USB_USBNET=m
+# CONFIG_USB_NET_AX8817X is not set
+# CONFIG_USB_NET_AX88179_178A is not set
+CONFIG_USB_NET_CDC_EEM=m
+CONFIG_USB_NET_HUAWEI_CDC_NCM=m
+CONFIG_USB_NET_CDC_MBIM=m
+# CONFIG_USB_NET_NET1080 is not set
+CONFIG_USB_NET_RNDIS_HOST=m
+# CONFIG_USB_BELKIN is not set
+# CONFIG_USB_ARMLINUX is not set
+# CONFIG_USB_NET_ZAURUS is not set
+CONFIG_ATH9K=m
+CONFIG_ATH9K_HTC=m
+CONFIG_IWLWIFI=m
+CONFIG_IWLDVM=m
+CONFIG_IWLMVM=m
+CONFIG_MT7601U=m
+CONFIG_RT2X00=m
+CONFIG_RT2800USB=m
+CONFIG_RTL8180=m
+CONFIG_RTL8187=m
+CONFIG_RTL8192CE=m
+CONFIG_RTL8192SE=m
+CONFIG_RTL8192DE=m
+CONFIG_RTL8723AE=m
+CONFIG_RTL8723BE=m
+CONFIG_RTL8188EE=m
+CONFIG_RTL8192EE=m
+CONFIG_RTL8821AE=m
+CONFIG_RTL8192CU=m
+CONFIG_RTL8192DU=m
+# CONFIG_RTLWIFI_DEBUG is not set
+CONFIG_RTL8XXXU=m
+CONFIG_RTW88=m
+CONFIG_RTW88_8822BE=m
+CONFIG_RTW88_8822BU=m
+CONFIG_RTW88_8822CE=m
+CONFIG_RTW88_8822CU=m
+CONFIG_RTW88_8723DE=m
+CONFIG_RTW88_8723DU=m
+CONFIG_RTW88_8821CE=m
+CONFIG_RTW88_8821CU=m
+CONFIG_RTW88_8821AU=m
+CONFIG_RTW88_8812AU=m
+CONFIG_RTW88_8814AE=m
+CONFIG_RTW88_8814AU=m
+CONFIG_RTW89=m
+CONFIG_RTW89_8851BE=m
+CONFIG_RTW89_8852AE=m
+CONFIG_RTW89_8852BE=m
+CONFIG_RTW89_8852BTE=m
+CONFIG_RTW89_8852CE=m
+CONFIG_RTW89_8922AE=m
+CONFIG_ZD1211RW=m
+CONFIG_USB4_NET=m
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_KEYBOARD_GPIO=m
+CONFIG_KEYBOARD_GPIO_POLLED=m
+CONFIG_KEYBOARD_MATRIX=m
+CONFIG_KEYBOARD_XTKBD=m
+CONFIG_MOUSE_PS2_ELANTECH=y
+CONFIG_MOUSE_PS2_SENTELIC=y
+CONFIG_MOUSE_SERIAL=m
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=m
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_RAW=m
+CONFIG_LEGACY_PTY_COUNT=16
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=16
+CONFIG_SERIAL_8250_RUNTIME_UARTS=16
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+CONFIG_SERIAL_OF_PLATFORM=y
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_PRINTER=m
+CONFIG_VIRTIO_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_VIRTIO=m
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_PIIX4=y
+CONFIG_I2C_DESIGNWARE_CORE=y
+CONFIG_I2C_DESIGNWARE_SLAVE=y
+CONFIG_I2C_DESIGNWARE_PCI=y
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_LOONGSON_PCI=m
+CONFIG_SPI_LOONGSON_PLATFORM=m
+CONFIG_PINCTRL=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_LOONGSON1=y
+CONFIG_GPIO_PCA953X=m
+CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_GPIO_PCA9570=m
+CONFIG_GPIO_PCF857X=m
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_RESTART=y
+CONFIG_POWER_RESET_SYSCON=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+CONFIG_SYSCON_REBOOT_MODE=y
+CONFIG_SENSORS_LM75=m
+CONFIG_SENSORS_LM93=m
+CONFIG_SENSORS_W83795=m
+CONFIG_SENSORS_W83627HF=m
+CONFIG_WATCHDOG=y
+CONFIG_LOONGSON1_WDT=m
+CONFIG_RC_CORE=m
+CONFIG_LIRC=y
+CONFIG_RC_DECODERS=y
+CONFIG_IR_IMON_DECODER=m
+CONFIG_IR_JVC_DECODER=m
+CONFIG_IR_MCE_KBD_DECODER=m
+CONFIG_IR_NEC_DECODER=m
+CONFIG_IR_RC5_DECODER=m
+CONFIG_IR_RC6_DECODER=m
+CONFIG_IR_SANYO_DECODER=m
+CONFIG_IR_SHARP_DECODER=m
+CONFIG_IR_SONY_DECODER=m
+CONFIG_IR_XMP_DECODER=m
+CONFIG_MEDIA_SUPPORT=m
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_MEDIA_PCI_SUPPORT=y
+CONFIG_VIDEO_BT848=m
+CONFIG_DVB_BT8XX=m
+CONFIG_DRM=y
+CONFIG_DRM_LOAD_EDID_FIRMWARE=y
+CONFIG_DRM_RADEON=m
+CONFIG_DRM_RADEON_USERPTR=y
+CONFIG_DRM_AMDGPU=m
+CONFIG_DRM_AMDGPU_SI=y
+CONFIG_DRM_AMDGPU_CIK=y
+CONFIG_DRM_AMDGPU_USERPTR=y
+CONFIG_DRM_AST=y
+CONFIG_DRM_QXL=m
+CONFIG_DRM_VIRTIO_GPU=m
+CONFIG_DRM_LOONGSON=y
+CONFIG_DRM_SIMPLEDRM=y
+CONFIG_FB=y
+CONFIG_FB_EFI=y
+CONFIG_FB_RADEON=y
+CONFIG_FIRMWARE_EDID=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_PLATFORM=m
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_BT87X=m
+CONFIG_SND_BT87X_OVERCLOCK=y
+CONFIG_SND_HDA_INTEL=y
+CONFIG_SND_HDA_HWDEP=y
+CONFIG_SND_HDA_INPUT_BEEP=y
+CONFIG_SND_HDA_PATCH_LOADER=y
+CONFIG_SND_HDA_CODEC_REALTEK=y
+CONFIG_SND_HDA_CODEC_REALTEK_LIB=y
+CONFIG_SND_HDA_CODEC_ALC260=y
+CONFIG_SND_HDA_CODEC_ALC262=y
+CONFIG_SND_HDA_CODEC_ALC268=y
+CONFIG_SND_HDA_CODEC_ALC269=y
+CONFIG_SND_HDA_CODEC_ALC662=y
+CONFIG_SND_HDA_CODEC_ALC680=y
+CONFIG_SND_HDA_CODEC_ALC861=y
+CONFIG_SND_HDA_CODEC_ALC861VD=y
+CONFIG_SND_HDA_CODEC_ALC880=y
+CONFIG_SND_HDA_CODEC_ALC882=y
+CONFIG_SND_HDA_CODEC_SIGMATEL=y
+CONFIG_SND_HDA_CODEC_HDMI=y
+CONFIG_SND_HDA_CODEC_HDMI_GENERIC=y
+CONFIG_SND_HDA_CODEC_HDMI_INTEL=y
+CONFIG_SND_HDA_CODEC_HDMI_ATI=y
+CONFIG_SND_HDA_CODEC_HDMI_NVIDIA=y
+CONFIG_SND_HDA_CODEC_CONEXANT=y
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_USB_AUDIO_MIDI_V2=y
+CONFIG_SND_SOC=m
+CONFIG_SND_SOC_LOONGSON_CARD=m
+CONFIG_SND_LOONGSON1_AC97=m
+CONFIG_SND_SOC_ES7134=m
+CONFIG_SND_SOC_ES7241=m
+CONFIG_SND_SOC_ES8311=m
+CONFIG_SND_SOC_ES8316=m
+CONFIG_SND_SOC_ES8323=m
+CONFIG_SND_SOC_ES8326=m
+CONFIG_SND_SOC_ES8328_I2C=m
+CONFIG_SND_SOC_ES8328_SPI=m
+CONFIG_SND_SOC_UDA1334=m
+CONFIG_SND_SOC_UDA1342=m
+CONFIG_SND_VIRTIO=m
+CONFIG_HIDRAW=y
+CONFIG_UHID=m
+CONFIG_HID_A4TECH=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_ELAN=m
+CONFIG_HID_LOGITECH=m
+CONFIG_HID_LOGITECH_DJ=m
+CONFIG_LOGITECH_FF=y
+CONFIG_LOGIRUMBLEPAD2_FF=y
+CONFIG_LOGIG940_FF=y
+CONFIG_HID_MICROSOFT=m
+CONFIG_HID_MULTITOUCH=m
+CONFIG_HID_SUNPLUS=m
+CONFIG_HID_WACOM=m
+CONFIG_USB_HIDDEV=y
+CONFIG_I2C_HID_ACPI=m
+CONFIG_I2C_HID_OF=m
+CONFIG_I2C_HID_OF_ELAN=m
+CONFIG_USB=y
+CONFIG_USB_OTG=y
+CONFIG_USB_MON=y
+CONFIG_USB_XHCI_HCD=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_HCD_PLATFORM=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_HCD_PLATFORM=y
+CONFIG_USB_UHCI_HCD=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_STORAGE_REALTEK=m
+CONFIG_USB_UAS=m
+CONFIG_USB_DWC2=y
+CONFIG_USB_DWC2_HOST=y
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_CH341=m
+CONFIG_USB_SERIAL_CP210X=m
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_GADGET=y
+CONFIG_TYPEC=m
+CONFIG_TYPEC_TCPM=m
+CONFIG_TYPEC_TCPCI=m
+CONFIG_TYPEC_UCSI=m
+CONFIG_UCSI_ACPI=m
+CONFIG_MMC=y
+CONFIG_INFINIBAND=m
+CONFIG_EDAC=y
+# CONFIG_EDAC_LEGACY_SYSFS is not set
+CONFIG_EDAC_LOONGSON=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_EFI=y
+CONFIG_RTC_DRV_LOONGSON=y
+CONFIG_DMADEVICES=y
+CONFIG_LOONGSON1_APB_DMA=y
+CONFIG_UDMABUF=y
+CONFIG_DMABUF_HEAPS=y
+CONFIG_DMABUF_HEAPS_SYSTEM=y
+CONFIG_DMABUF_HEAPS_CMA=y
+CONFIG_UIO=m
+CONFIG_UIO_PDRV_GENIRQ=m
+CONFIG_UIO_DMEM_GENIRQ=m
+CONFIG_UIO_PCI_GENERIC=m
+CONFIG_VFIO=m
+CONFIG_VFIO_PCI=m
+CONFIG_VIRTIO_PCI=y
+CONFIG_VIRTIO_BALLOON=m
+CONFIG_VIRTIO_INPUT=m
+CONFIG_VIRTIO_MMIO=m
+CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y
+CONFIG_VHOST_NET=m
+CONFIG_VHOST_SCSI=m
+CONFIG_VHOST_VSOCK=m
+CONFIG_COMEDI=m
+CONFIG_COMEDI_PCI_DRIVERS=m
+CONFIG_COMEDI_8255_PCI=m
+CONFIG_COMEDI_ADL_PCI6208=m
+CONFIG_COMEDI_ADL_PCI7X3X=m
+CONFIG_COMEDI_ADL_PCI8164=m
+CONFIG_COMEDI_ADL_PCI9111=m
+CONFIG_COMEDI_ADL_PCI9118=m
+CONFIG_COMEDI_ADV_PCI1710=m
+CONFIG_COMEDI_ADV_PCI1720=m
+CONFIG_COMEDI_ADV_PCI1723=m
+CONFIG_COMEDI_ADV_PCI1724=m
+CONFIG_COMEDI_ADV_PCI1760=m
+CONFIG_COMEDI_ADV_PCI_DIO=m
+CONFIG_COMEDI_NI_LABPC_PCI=m
+CONFIG_COMEDI_NI_PCIDIO=m
+CONFIG_COMEDI_NI_PCIMIO=m
+CONFIG_STAGING=y
+CONFIG_CLKSRC_LOONGSON1_PWM=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_PM_DEVFREQ=y
+CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
+CONFIG_DEVFREQ_GOV_PERFORMANCE=y
+CONFIG_DEVFREQ_GOV_POWERSAVE=y
+CONFIG_DEVFREQ_GOV_USERSPACE=y
+CONFIG_NTB=m
+CONFIG_NTB_MSI=y
+CONFIG_NTB_IDT=m
+CONFIG_NTB_EPF=m
+CONFIG_NTB_SWITCHTEC=m
+CONFIG_NTB_PERF=m
+CONFIG_NTB_TRANSPORT=m
+CONFIG_PWM=y
+CONFIG_GENERIC_PHY=y
+CONFIG_USB4=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_JFS_FS=m
+CONFIG_JFS_POSIX_ACL=y
+CONFIG_JFS_SECURITY=y
+CONFIG_XFS_FS=y
+CONFIG_XFS_SUPPORT_V4=y
+CONFIG_XFS_SUPPORT_ASCII_CI=y
+CONFIG_XFS_QUOTA=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_GFS2_FS=m
+CONFIG_GFS2_FS_LOCKING_DLM=y
+CONFIG_OCFS2_FS=m
+CONFIG_BTRFS_FS=y
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_F2FS_FS=m
+CONFIG_F2FS_FS_SECURITY=y
+CONFIG_F2FS_CHECK_FS=y
+CONFIG_F2FS_FS_COMPRESSION=y
+CONFIG_FS_ENCRYPTION=y
+CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y
+CONFIG_FS_VERITY=y
+CONFIG_FANOTIFY=y
+CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y
+CONFIG_QUOTA=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QFMT_V1=m
+CONFIG_QFMT_V2=m
+CONFIG_AUTOFS_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_CUSE=m
+CONFIG_VIRTIO_FS=m
+CONFIG_OVERLAY_FS=y
+CONFIG_OVERLAY_FS_INDEX=y
+CONFIG_OVERLAY_FS_XINO_AUTO=y
+CONFIG_OVERLAY_FS_METACOPY=y
+CONFIG_FSCACHE=y
+CONFIG_CACHEFILES=m
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=936
+CONFIG_FAT_DEFAULT_IOCHARSET="gb2312"
+CONFIG_EXFAT_FS=m
+CONFIG_NTFS3_FS=m
+CONFIG_NTFS3_LZX_XPRESS=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_ORANGEFS_FS=m
+CONFIG_ECRYPT_FS=m
+CONFIG_ECRYPT_FS_MESSAGING=y
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_UBIFS_FS=m
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_FILE_DIRECT=y
+CONFIG_SQUASHFS_CHOICE_DECOMP_BY_MOUNT=y
+CONFIG_SQUASHFS_XATTR=y
+CONFIG_SQUASHFS_LZ4=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_SQUASHFS_ZSTD=y
+CONFIG_MINIX_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_PSTORE=m
+CONFIG_PSTORE_COMPRESS=y
+CONFIG_UFS_FS=m
+CONFIG_EROFS_FS=m
+CONFIG_EROFS_FS_ZIP_LZMA=y
+CONFIG_EROFS_FS_ZIP_DEFLATE=y
+CONFIG_EROFS_FS_ZIP_ZSTD=y
+CONFIG_EROFS_FS_ONDEMAND=y
+CONFIG_EROFS_FS_PCPU_KTHREAD=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_V4_2=y
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_NFSD_BLOCKLAYOUT=y
+CONFIG_CEPH_FS=m
+CONFIG_CEPH_FSCACHE=y
+CONFIG_CEPH_FS_POSIX_ACL=y
+CONFIG_CEPH_FS_SECURITY_LABEL=y
+CONFIG_CIFS=m
+# CONFIG_CIFS_DEBUG is not set
+CONFIG_9P_FS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_UTF8=y
+CONFIG_DLM=m
+CONFIG_KEY_DH_OPERATIONS=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_APPARMOR=y
+CONFIG_SECURITY_YAMA=y
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_CRYPTO_USER=m
+CONFIG_CRYPTO_SELFTESTS=y
+CONFIG_CRYPTO_PCRYPT=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_SM4_GENERIC=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_CHACHA20POLY1305=m
+CONFIG_CRYPTO_SM3_GENERIC=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_DEFLATE=m
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRYPTO_842=m
+CONFIG_CRYPTO_LZ4=m
+CONFIG_CRYPTO_LZ4HC=m
+CONFIG_CRYPTO_USER_API_HASH=m
+CONFIG_CRYPTO_USER_API_SKCIPHER=m
+CONFIG_CRYPTO_USER_API_RNG=m
+CONFIG_CRYPTO_USER_API_AEAD=m
+CONFIG_CRYPTO_DEV_VIRTIO=m
+CONFIG_CRYPTO_DEV_LOONGSON_RNG=m
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=0
+CONFIG_PRINTK_TIME=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_SCHEDSTATS=y
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_FTRACE is not set
diff --git a/arch/loongarch/configs/loongson3_defconfig b/arch/loongarch/configs/loongson64_defconfig
similarity index 100%
rename from arch/loongarch/configs/loongson3_defconfig
rename to arch/loongarch/configs/loongson64_defconfig
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH V2 14/14] LoongArch: Adjust build infrastructure for 32BIT/64BIT
  2025-11-18 11:27 [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Huacai Chen
                   ` (12 preceding siblings ...)
  2025-11-18 11:27 ` [PATCH V2 13/14] LoongArch: Adjust default config files " Huacai Chen
@ 2025-11-18 11:27 ` Huacai Chen
  2025-11-18 14:07 ` [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Arnd Bergmann
  14 siblings, 0 replies; 37+ messages in thread
From: Huacai Chen @ 2025-11-18 11:27 UTC (permalink / raw)
  To: Arnd Bergmann, Huacai Chen
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Xuerui Wang,
	Jiaxun Yang, linux-kernel, Huacai Chen

Adjust build infrastructure (Kconfig, Makefile and ld scripts) to let
us enable both 32BIT/64BIT kernel build.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
 arch/loongarch/Kconfig                | 113 ++++++++++++++++++--------
 arch/loongarch/Makefile               |  29 ++++++-
 arch/loongarch/boot/Makefile          |   6 ++
 arch/loongarch/kernel/vmlinux.lds.S   |   7 +-
 arch/loongarch/kvm/Kconfig            |   2 +-
 arch/loongarch/lib/Makefile           |   5 +-
 drivers/firmware/efi/libstub/Makefile |   1 +
 drivers/pci/controller/Kconfig        |   2 +-
 lib/crc/Kconfig                       |   2 +-
 9 files changed, 125 insertions(+), 42 deletions(-)

diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig
index 730f34214519..4bacde9f46d1 100644
--- a/arch/loongarch/Kconfig
+++ b/arch/loongarch/Kconfig
@@ -21,11 +21,11 @@ config LOONGARCH
 	select ARCH_HAS_FAST_MULTIPLIER
 	select ARCH_HAS_FORTIFY_SOURCE
 	select ARCH_HAS_KCOV
-	select ARCH_HAS_KERNEL_FPU_SUPPORT if CPU_HAS_FPU
+	select ARCH_HAS_KERNEL_FPU_SUPPORT if 64BIT && CPU_HAS_FPU
 	select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS
 	select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
 	select ARCH_HAS_PREEMPT_LAZY
-	select ARCH_HAS_PTE_SPECIAL
+	select ARCH_HAS_PTE_SPECIAL if 64BIT
 	select ARCH_HAS_SET_MEMORY
 	select ARCH_HAS_SET_DIRECT_MAP
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
@@ -60,16 +60,15 @@ config LOONGARCH
 	select ARCH_KEEP_MEMBLOCK
 	select ARCH_MIGHT_HAVE_PC_PARPORT
 	select ARCH_MIGHT_HAVE_PC_SERIO
-	select ARCH_SPARSEMEM_ENABLE
 	select ARCH_STACKWALK
 	select ARCH_SUPPORTS_ACPI
 	select ARCH_SUPPORTS_ATOMIC_RMW
-	select ARCH_SUPPORTS_HUGETLBFS
+	select ARCH_SUPPORTS_HUGETLBFS if 64BIT
 	select ARCH_SUPPORTS_INT128 if CC_HAS_INT128
 	select ARCH_SUPPORTS_LTO_CLANG
 	select ARCH_SUPPORTS_LTO_CLANG_THIN
 	select ARCH_SUPPORTS_MSEAL_SYSTEM_MAPPINGS
-	select ARCH_SUPPORTS_NUMA_BALANCING
+	select ARCH_SUPPORTS_NUMA_BALANCING if NUMA
 	select ARCH_SUPPORTS_PER_VMA_LOCK
 	select ARCH_SUPPORTS_RT
 	select ARCH_SUPPORTS_SCHED_SMT if SMP
@@ -79,10 +78,10 @@ config LOONGARCH
 	select ARCH_USE_MEMTEST
 	select ARCH_USE_QUEUED_RWLOCKS
 	select ARCH_USE_QUEUED_SPINLOCKS
-	select ARCH_WANT_DEFAULT_BPF_JIT
+	select ARCH_WANT_DEFAULT_BPF_JIT if HAVE_EBPF_JIT
 	select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT
 	select ARCH_WANT_LD_ORPHAN_WARN
-	select ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP
+	select ARCH_WANT_OPTIMIZE_HUGETLB_VMEMMAP if 64BIT
 	select ARCH_WANTS_NO_INSTR
 	select ARCH_WANTS_THP_SWAP if HAVE_ARCH_TRANSPARENT_HUGEPAGE
 	select BUILDTIME_TABLE_SORT
@@ -90,13 +89,14 @@ config LOONGARCH
 	select CPU_PM
 	select EDAC_SUPPORT
 	select EFI
+	select GENERIC_ATOMIC64 if 32BIT
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_CMOS_UPDATE
 	select GENERIC_CPU_AUTOPROBE
 	select GENERIC_CPU_DEVICES
 	select GENERIC_CPU_VULNERABILITIES
 	select GENERIC_ENTRY
-	select GENERIC_GETTIMEOFDAY
+	select GENERIC_GETTIMEOFDAY if 64BIT
 	select GENERIC_IOREMAP if !ARCH_IOREMAP
 	select GENERIC_IRQ_MATRIX_ALLOCATOR
 	select GENERIC_IRQ_MULTI_HANDLER
@@ -111,15 +111,15 @@ config LOONGARCH
 	select GENERIC_PCI_IOMAP
 	select GENERIC_SCHED_CLOCK
 	select GENERIC_SMP_IDLE_THREAD
-	select GENERIC_TIME_VSYSCALL
+	select GENERIC_TIME_VSYSCALL if GENERIC_GETTIMEOFDAY
 	select GPIOLIB
 	select HAS_IOPORT
 	select HAVE_ARCH_AUDITSYSCALL
-	select HAVE_ARCH_BITREVERSE
+	select HAVE_ARCH_BITREVERSE if 64BIT
 	select HAVE_ARCH_JUMP_LABEL
 	select HAVE_ARCH_JUMP_LABEL_RELATIVE
-	select HAVE_ARCH_KASAN
-	select HAVE_ARCH_KFENCE
+	select HAVE_ARCH_KASAN if 64BIT
+	select HAVE_ARCH_KFENCE if 64BIT
 	select HAVE_ARCH_KGDB if PERF_EVENTS
 	select HAVE_ARCH_KSTACK_ERASE
 	select HAVE_ARCH_MMAP_RND_BITS if MMU
@@ -127,8 +127,8 @@ config LOONGARCH
 	select HAVE_ARCH_SECCOMP
 	select HAVE_ARCH_SECCOMP_FILTER
 	select HAVE_ARCH_TRACEHOOK
-	select HAVE_ARCH_TRANSPARENT_HUGEPAGE
-	select HAVE_ARCH_USERFAULTFD_MINOR if USERFAULTFD
+	select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64BIT
+	select HAVE_ARCH_USERFAULTFD_MINOR if 64BIT && USERFAULTFD
 	select HAVE_ASM_MODVERSIONS
 	select HAVE_CONTEXT_TRACKING_USER
 	select HAVE_C_RECORDMCOUNT
@@ -140,7 +140,7 @@ config LOONGARCH
 	select HAVE_FTRACE_REGS_HAVING_PT_REGS
 	select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
 	select HAVE_DYNAMIC_FTRACE_WITH_REGS
-	select HAVE_EBPF_JIT
+	select HAVE_EBPF_JIT if 64BIT
 	select HAVE_EFFICIENT_UNALIGNED_ACCESS if !ARCH_STRICT_ALIGN
 	select HAVE_EXIT_THREAD
 	select HAVE_GENERIC_TIF_BITS
@@ -163,9 +163,9 @@ config LOONGARCH
 	select HAVE_LIVEPATCH
 	select HAVE_MOD_ARCH_SPECIFIC
 	select HAVE_NMI
-	select HAVE_OBJTOOL if AS_HAS_EXPLICIT_RELOCS && AS_HAS_THIN_ADD_SUB
+	select HAVE_OBJTOOL if AS_HAS_EXPLICIT_RELOCS && AS_HAS_THIN_ADD_SUB && 64BIT
 	select HAVE_PCI
-	select HAVE_PERF_EVENTS
+	select HAVE_PERF_EVENTS if 64BIT
 	select HAVE_PERF_REGS
 	select HAVE_PERF_USER_STACK_DUMP
 	select HAVE_POSIX_CPU_TIMERS_TASK_WORK
@@ -205,18 +205,50 @@ config LOONGARCH
 	select SYSCTL_ARCH_UNALIGN_ALLOW
 	select SYSCTL_ARCH_UNALIGN_NO_WARN
 	select SYSCTL_EXCEPTION_TRACE
-	select SWIOTLB
+	select SWIOTLB if 64BIT
 	select TRACE_IRQFLAGS_SUPPORT
 	select USE_PERCPU_NUMA_NODE_ID
 	select USER_STACKTRACE_SUPPORT
 	select VDSO_GETRANDOM
-	select ZONE_DMA32
+	select ZONE_DMA32 if 64BIT
+
+menu "Kernel type and options"
+
+choice
+	prompt "Kernel type"
 
 config 32BIT
-	bool
+	bool "32-bit kernel"
+	help
+	  Select this option if you want to build a 32-bit kernel.
 
 config 64BIT
-	def_bool y
+	bool "64-bit kernel"
+	help
+	  Select this option if you want to build a 64-bit kernel.
+
+endchoice
+
+if 32BIT
+
+choice
+	prompt "32-bit kernel sub-type"
+
+config 32BIT_REDUCED
+	bool "32-bit kernel for LA32R"
+	help
+	  Select this option if you want to build a 32-bit kernel for
+	  LoongArch32 Reduced (LA32R).
+
+config 32BIT_STANDARD
+	bool "32-bit kernel for LA32S"
+	help
+	  Select this option if you want to build a 32-bit kernel for
+	  LoongArch32 Standard (LA32S).
+
+endchoice
+
+endif
 
 config GENERIC_BUG
 	def_bool y
@@ -306,8 +338,6 @@ config RUSTC_HAS_ANNOTATE_TABLEJUMP
 	depends on RUST
 	def_bool $(rustc-option,-Cllvm-args=--loongarch-annotate-tablejump)
 
-menu "Kernel type and options"
-
 source "kernel/Kconfig.hz"
 
 choice
@@ -319,8 +349,17 @@ choice
 	  of page size and page table levels. The size of virtual memory
 	  address space are determined by the page table layout.
 
+config 4KB_2LEVEL
+	bool "4KB with 2 levels"
+	select HAVE_PAGE_SIZE_4KB
+	select PGTABLE_2LEVEL
+	help
+	  This option selects 16KB page size with 2 level page tables, which
+	  support a maximum of 32 bits of application virtual memory.
+
 config 4KB_3LEVEL
 	bool "4KB with 3 levels"
+	depends on 64BIT
 	select HAVE_PAGE_SIZE_4KB
 	select PGTABLE_3LEVEL
 	help
@@ -329,6 +368,7 @@ config 4KB_3LEVEL
 
 config 4KB_4LEVEL
 	bool "4KB with 4 levels"
+	depends on 64BIT
 	select HAVE_PAGE_SIZE_4KB
 	select PGTABLE_4LEVEL
 	help
@@ -345,6 +385,7 @@ config 16KB_2LEVEL
 
 config 16KB_3LEVEL
 	bool "16KB with 3 levels"
+	depends on 64BIT
 	select HAVE_PAGE_SIZE_16KB
 	select PGTABLE_3LEVEL
 	help
@@ -361,6 +402,7 @@ config 64KB_2LEVEL
 
 config 64KB_3LEVEL
 	bool "64KB with 3 levels"
+	depends on 64BIT
 	select HAVE_PAGE_SIZE_64KB
 	select PGTABLE_3LEVEL
 	help
@@ -458,6 +500,7 @@ config EFI_STUB
 
 config SMP
 	bool "Multi-Processing support"
+	depends on 64BIT
 	help
 	  This enables support for systems with more than one CPU. If you have
 	  a system with only one CPU, say N. If you have a system with more
@@ -496,6 +539,7 @@ config NR_CPUS
 config NUMA
 	bool "NUMA Support"
 	select SMP
+	depends on 64BIT
 	help
 	  Say Y to compile the kernel with NUMA (Non-Uniform Memory Access)
 	  support.  This option improves performance on systems with more
@@ -578,7 +622,7 @@ config CPU_HAS_FPU
 
 config CPU_HAS_LSX
 	bool "Support for the Loongson SIMD Extension"
-	depends on AS_HAS_LSX_EXTENSION
+	depends on AS_HAS_LSX_EXTENSION && 64BIT
 	help
 	  Loongson SIMD Extension (LSX) introduces 128 bit wide vector registers
 	  and a set of SIMD instructions to operate on them. When this option
@@ -593,7 +637,7 @@ config CPU_HAS_LSX
 config CPU_HAS_LASX
 	bool "Support for the Loongson Advanced SIMD Extension"
 	depends on CPU_HAS_LSX
-	depends on AS_HAS_LASX_EXTENSION
+	depends on AS_HAS_LASX_EXTENSION && 64BIT
 	help
 	  Loongson Advanced SIMD Extension (LASX) introduces 256 bit wide vector
 	  registers and a set of SIMD instructions to operate on them. When this
@@ -607,7 +651,7 @@ config CPU_HAS_LASX
 
 config CPU_HAS_LBT
 	bool "Support for the Loongson Binary Translation Extension"
-	depends on AS_HAS_LBT_EXTENSION
+	depends on AS_HAS_LBT_EXTENSION && 64BIT
 	help
 	  Loongson Binary Translation (LBT) introduces 4 scratch registers (SCR0
 	  to SCR3), x86/ARM eflags (eflags) and x87 fpu stack pointer (ftop).
@@ -635,13 +679,13 @@ config ARCH_SELECTS_KEXEC_FILE
 	select HAVE_IMA_KEXEC if IMA
 
 config ARCH_SUPPORTS_CRASH_DUMP
-	def_bool y
+	def_bool 64BIT
 
 config ARCH_DEFAULT_CRASH_DUMP
-	def_bool y
+	def_bool 64BIT
 
 config ARCH_SELECTS_CRASH_DUMP
-	def_bool y
+	def_bool 64BIT
 	depends on CRASH_DUMP
 	select RELOCATABLE
 
@@ -650,6 +694,7 @@ config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
 
 config RELOCATABLE
 	bool "Relocatable kernel"
+	depends on 64BIT
 	select ARCH_HAS_RELR
 	help
 	  This builds the kernel as a Position Independent Executable (PIE),
@@ -686,7 +731,7 @@ source "kernel/livepatch/Kconfig"
 
 config PARAVIRT
 	bool "Enable paravirtualization code"
-	depends on AS_HAS_LVZ_EXTENSION
+	depends on AS_HAS_LVZ_EXTENSION && 64BIT
 	help
 	  This changes the kernel so it can modify itself when it is run
 	  under a hypervisor, potentially improving performance significantly
@@ -714,7 +759,7 @@ config ARCH_FLATMEM_ENABLE
 	depends on !NUMA
 
 config ARCH_SPARSEMEM_ENABLE
-	def_bool y
+	def_bool 64BIT
 	select SPARSEMEM_VMEMMAP_ENABLE
 	help
 	  Say Y to support efficient handling of sparse physical memory,
@@ -731,10 +776,12 @@ config MMU
 	default y
 
 config ARCH_MMAP_RND_BITS_MIN
-	default 12
+	default 10 if 32BIT
+	default 12 if 64BIT
 
 config ARCH_MMAP_RND_BITS_MAX
-	default 18
+	default 15 if 32BIT
+	default 18 if 64BIT
 
 config ARCH_SUPPORTS_UPROBES
 	def_bool y
diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile
index 96ca1a688984..9d54dccc1625 100644
--- a/arch/loongarch/Makefile
+++ b/arch/loongarch/Makefile
@@ -5,7 +5,12 @@
 
 boot	:= arch/loongarch/boot
 
-KBUILD_DEFCONFIG := loongson3_defconfig
+ifdef CONFIG_32BIT
+KBUILD_DEFCONFIG := loongson32_defconfig
+else
+KBUILD_DEFCONFIG := loongson64_defconfig
+endif
+
 KBUILD_DTBS      := dtbs
 
 image-name-y			:= vmlinux
@@ -46,7 +51,10 @@ KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY
 CC_FLAGS_FTRACE := -fpatchable-function-entry=2
 endif
 
-ifdef CONFIG_64BIT
+ifdef CONFIG_32BIT
+tool-archpref		= $(32bit-tool-archpref)
+UTS_MACHINE		:= loongarch32
+else
 tool-archpref		= $(64bit-tool-archpref)
 UTS_MACHINE		:= loongarch64
 endif
@@ -57,9 +65,19 @@ ifneq ($(SUBARCH),$(ARCH))
   endif
 endif
 
+ifdef CONFIG_32BIT
+ifdef CONFIG_32BIT_STANDARD
+ld-emul			= $(32bit-emul)
+cflags-y		+= -march=la32v1.0 -mabi=ilp32s -mcmodel=normal
+else  # CONFIG_32BIT_REDUCED
+ld-emul			= $(32bit-emul)
+cflags-y		+= -march=la32rv1.0 -mabi=ilp32s -mcmodel=normal
+endif
+endif
+
 ifdef CONFIG_64BIT
 ld-emul			= $(64bit-emul)
-cflags-y		+= -mabi=lp64s -mcmodel=normal
+cflags-y		+= -march=loongarch64 -mabi=lp64s -mcmodel=normal
 endif
 
 cflags-y			+= -pipe $(CC_FLAGS_NO_FPU)
@@ -135,7 +153,12 @@ ifndef CONFIG_KASAN
 cflags-y += -fno-builtin-memcpy -fno-builtin-memmove -fno-builtin-memset
 endif
 
+ifdef CONFIG_32BIT
+load-y		= 0xa0200000
+else
 load-y		= 0x9000000000200000
+endif
+
 bootvars-y	= VMLINUX_LOAD_ADDRESS=$(load-y)
 
 drivers-$(CONFIG_PCI)		+= arch/loongarch/pci/
diff --git a/arch/loongarch/boot/Makefile b/arch/loongarch/boot/Makefile
index 4e1c374c5782..8b6d9b42b5f0 100644
--- a/arch/loongarch/boot/Makefile
+++ b/arch/loongarch/boot/Makefile
@@ -20,7 +20,13 @@ $(obj)/vmlinux.efi: vmlinux FORCE
 	$(call if_changed,objcopy)
 
 EFI_ZBOOT_PAYLOAD      := vmlinux.efi
+
+ifdef CONFIG_32BIT
+EFI_ZBOOT_BFD_TARGET   := elf32-loongarch
+EFI_ZBOOT_MACH_TYPE    := LOONGARCH32
+else
 EFI_ZBOOT_BFD_TARGET   := elf64-loongarch
 EFI_ZBOOT_MACH_TYPE    := LOONGARCH64
+endif
 
 include $(srctree)/drivers/firmware/efi/libstub/Makefile.zboot
diff --git a/arch/loongarch/kernel/vmlinux.lds.S b/arch/loongarch/kernel/vmlinux.lds.S
index 08ea921cdec1..b95c0acdab90 100644
--- a/arch/loongarch/kernel/vmlinux.lds.S
+++ b/arch/loongarch/kernel/vmlinux.lds.S
@@ -6,7 +6,12 @@
 
 #define PAGE_SIZE _PAGE_SIZE
 #define RO_EXCEPTION_TABLE_ALIGN	4
-#define PHYSADDR_MASK			0xffffffffffff /* 48-bit */
+
+#ifdef CONFIG_32BIT
+#define PHYSADDR_MASK			0x1fffffff	/* 29-bit */
+#else
+#define PHYSADDR_MASK			0xffffffffffff	/* 48-bit */
+#endif
 
 /*
  * Put .bss..swapper_pg_dir as the first thing in .bss. This will
diff --git a/arch/loongarch/kvm/Kconfig b/arch/loongarch/kvm/Kconfig
index ae64bbdf83a7..3dc5ebc546d5 100644
--- a/arch/loongarch/kvm/Kconfig
+++ b/arch/loongarch/kvm/Kconfig
@@ -19,7 +19,7 @@ if VIRTUALIZATION
 
 config KVM
 	tristate "Kernel-based Virtual Machine (KVM) support"
-	depends on AS_HAS_LVZ_EXTENSION
+	depends on AS_HAS_LVZ_EXTENSION && 64BIT
 	select HAVE_KVM_DIRTY_RING_ACQ_REL
 	select HAVE_KVM_IRQ_ROUTING
 	select HAVE_KVM_IRQCHIP
diff --git a/arch/loongarch/lib/Makefile b/arch/loongarch/lib/Makefile
index ccea3bbd4353..d8f1e8559487 100644
--- a/arch/loongarch/lib/Makefile
+++ b/arch/loongarch/lib/Makefile
@@ -3,8 +3,9 @@
 # Makefile for LoongArch-specific library files.
 #
 
-lib-y	+= delay.o memset.o memcpy.o memmove.o \
-	   clear_user.o copy_user.o csum.o dump_tlb.o unaligned.o
+lib-y	+= delay.o clear_user.o copy_user.o dump_tlb.o unaligned.o
+
+lib-$(CONFIG_64BIT) += memset.o memcpy.o memmove.o csum.o
 
 obj-$(CONFIG_ARCH_SUPPORTS_INT128) += tishift.o
 
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index 94b05e4451dd..2ba0f7c400a7 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -97,6 +97,7 @@ zboot-obj-$(CONFIG_KERNEL_ZSTD)	:= zboot-decompress-zstd.o lib-xxhash.o
 CFLAGS_zboot-decompress-zstd.o	+= -I$(srctree)/lib/zstd
 
 zboot-obj-$(CONFIG_RISCV)	+= lib-clz_ctz.o lib-ashldi3.o
+zboot-obj-$(CONFIG_LOONGARCH)	+= lib-clz_ctz.o lib-ashldi3.o
 lib-$(CONFIG_EFI_ZBOOT)		+= zboot.o $(zboot-obj-y)
 
 lib-$(CONFIG_UNACCEPTED_MEMORY) += unaccepted_memory.o bitmap.o find.o
diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 41748d083b93..35ef71b0695d 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -171,7 +171,7 @@ config VMD
 
 config PCI_LOONGSON
 	bool "LOONGSON PCIe controller"
-	depends on MACH_LOONGSON64 || COMPILE_TEST
+	depends on MACH_LOONGSON32 || MACH_LOONGSON64 || COMPILE_TEST
 	depends on OF || ACPI
 	depends on PCI_QUIRKS
 	default MACH_LOONGSON64
diff --git a/lib/crc/Kconfig b/lib/crc/Kconfig
index 70e7a6016de3..5bf613405fdd 100644
--- a/lib/crc/Kconfig
+++ b/lib/crc/Kconfig
@@ -65,7 +65,7 @@ config CRC32_ARCH
 	depends on CRC32 && CRC_OPTIMIZATIONS
 	default y if ARM && KERNEL_MODE_NEON
 	default y if ARM64
-	default y if LOONGARCH
+	default y if LOONGARCH && 64BIT
 	default y if MIPS && CPU_MIPSR6
 	default y if PPC64 && ALTIVEC
 	default y if RISCV && RISCV_ISA_ZBC
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 12/14] LoongArch: Adjust VDSO/VSYSCALL for 32BIT/64BIT
  2025-11-18 11:27 ` [PATCH V2 12/14] LoongArch: Adjust VDSO/VSYSCALL " Huacai Chen
@ 2025-11-18 13:41   ` Arnd Bergmann
  2025-11-18 14:34     ` Huacai Chen
  0 siblings, 1 reply; 37+ messages in thread
From: Arnd Bergmann @ 2025-11-18 13:41 UTC (permalink / raw)
  To: Huacai Chen, Huacai Chen
  Cc: loongarch, Linux-Arch, Xuefeng Li, guoren, WANG Xuerui,
	Jiaxun Yang, linux-kernel

On Tue, Nov 18, 2025, at 12:27, Huacai Chen wrote:
> Adjust VDSO/VSYSCALL because read_cpu_id() for 32BIT/64BIT are
> different, and LoongArch32 doesn't support GENERIC_GETTIMEOFDAY now.
>
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>

Are you planning to add vdso_clock_gettime() later, or is the
architecture missing hardware access to the timer register
on loongarch32?

It would be good to add some comments here to ensure this is
done correctly if someone adds the vdso32 support later:
There should be clock_gettime32 support, but not the old
clock_gettime(), clock_getres() or time().

       Arnd

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 13/14] LoongArch: Adjust default config files for 32BIT/64BIT
  2025-11-18 11:27 ` [PATCH V2 13/14] LoongArch: Adjust default config files " Huacai Chen
@ 2025-11-18 13:45   ` Arnd Bergmann
  2025-11-19  8:01     ` Huacai Chen
  2025-11-20  8:11   ` Thomas Weißschuh
  1 sibling, 1 reply; 37+ messages in thread
From: Arnd Bergmann @ 2025-11-18 13:45 UTC (permalink / raw)
  To: Huacai Chen, Huacai Chen
  Cc: loongarch, Linux-Arch, Xuefeng Li, guoren, WANG Xuerui,
	Jiaxun Yang, linux-kernel

On Tue, Nov 18, 2025, at 12:27, Huacai Chen wrote:
> Add loongson32_defconfig (for 32BIT) and rename loongson3_defconfig to
> loongson64_defconfig (for 64BIT).
>
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
> ---
>  arch/loongarch/configs/loongson32_defconfig   | 1110 +++++++++++++++++
>  ...ongson3_defconfig => loongson64_defconfig} |    0

I would suggest using .config fragment here and only listing
the differences in the defconfig files in there, rather than
duplicating everything.

> +CONFIG_DMI=y
> +CONFIG_EFI=y
> +CONFIG_SUSPEND=y
> +CONFIG_HIBERNATION=y
> +CONFIG_ACPI=y
> +CONFIG_ACPI_SPCR_TABLE=y
> +CONFIG_ACPI_TAD=y
> +CONFIG_ACPI_DOCK=y
> +CONFIG_ACPI_IPMI=m
> +CONFIG_ACPI_HOTPLUG_CPU=y
> +CONFIG_ACPI_PCI_SLOT=y
> +CONFIG_ACPI_HOTPLUG_MEMORY=y
> +CONFIG_ACPI_BGRT=y

You mention that loongarch32 uses ftb based boot,
so ACPI should probably be disabled here.

> +CONFIG_DRM=y
> +CONFIG_DRM_LOAD_EDID_FIRMWARE=y
> +CONFIG_DRM_RADEON=m
> +CONFIG_DRM_RADEON_USERPTR=y
> +CONFIG_DRM_AMDGPU=m
> +CONFIG_DRM_AMDGPU_SI=y
> +CONFIG_DRM_AMDGPU_CIK=y
> +CONFIG_DRM_AMDGPU_USERPTR=y
> +CONFIG_DRM_AST=y
> +CONFIG_DRM_QXL=m
> +CONFIG_DRM_VIRTIO_GPU=m
> +CONFIG_DRM_LOONGSON=y
> +CONFIG_DRM_SIMPLEDRM=y
> +CONFIG_FB=y
> +CONFIG_FB_EFI=y
> +CONFIG_FB_RADEON=y
> +CONFIG_FIRMWARE_EDID=y

Is AMDGPU actually working? This driver is rather tricky to get
reliable on new architectures.

I would suggest turning off CONFIG_FB here (also on loongarch64).
There is a replacement driver for FB_EFI in DRM now.

       Arnd

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support
  2025-11-18 11:27 [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Huacai Chen
                   ` (13 preceding siblings ...)
  2025-11-18 11:27 ` [PATCH V2 14/14] LoongArch: Adjust build infrastructure " Huacai Chen
@ 2025-11-18 14:07 ` Arnd Bergmann
  2025-11-18 14:30   ` Huacai Chen
  14 siblings, 1 reply; 37+ messages in thread
From: Arnd Bergmann @ 2025-11-18 14:07 UTC (permalink / raw)
  To: Huacai Chen, Huacai Chen
  Cc: loongarch, Linux-Arch, Xuefeng Li, guoren, WANG Xuerui,
	Jiaxun Yang, linux-kernel, Yawei Li

On Tue, Nov 18, 2025, at 12:27, Huacai Chen wrote:
> LoongArch includes a reduced 32-bit version (LA32R), a standard 32-bit
> version (LA32S) and a 64-bit version (LA64). LoongArch32 use FDT as its
> boot protocol which is already supported in LoongArch64. LoongArch32's
> ILP32 ABI use the same calling convention as LoongArch64.
>
> This patchset is adding basic LoongArch32 support in mainline kernel, it
> is the successor of Jiaxun Yang's previous work (V1):
> https://lore.kernel.org/loongarch/20250102-la32-uapi-v1-0-db32aa769b88@flygoat.com/
>
> We can see a complete snapshot here:
> https://github.com/chenhuacai/linux/tree/loongarch-next

I looked through all the patches, and this seems completely fine
implementation-wise. I replied with a few minor comments, but
found no show-stoppers.

Reviewed-by: Arnd Bergmann <arnd@arndb.de>

I'm still skeptical about the usefulness overall and would warn you
that you may regret merging this in a few years: 32-bit Linux is
clearly in decline, and the amount of work in bringing up and
maintaining another ABI (or two if you count LA32R/S separately)
is substantial.

In your cover letter, I'm missing information about running LA32
code on LA64 hardware. Specifically, do you plan to add CONFIG_COMPAT
support later, and do you plan to support LA32 kernels running
on LA64-capable hardware?
I would suggest supporting COMPAT 32-bit userspace here, but not
32-bit kernels: based on the experience with x86, arm, powerpc
and mips platforms that allow both, the compat mode usually
results in a much better experience overall. Compat support should
probably be a follow-up and not part of the initial submission
though, so what you have here is fine.

       Arnd

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support
  2025-11-18 14:07 ` [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Arnd Bergmann
@ 2025-11-18 14:30   ` Huacai Chen
  0 siblings, 0 replies; 37+ messages in thread
From: Huacai Chen @ 2025-11-18 14:30 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Huacai Chen, loongarch, Linux-Arch, Xuefeng Li, guoren,
	WANG Xuerui, Jiaxun Yang, linux-kernel, Yawei Li

Hi, Arnd,

On Tue, Nov 18, 2025 at 10:08 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Tue, Nov 18, 2025, at 12:27, Huacai Chen wrote:
> > LoongArch includes a reduced 32-bit version (LA32R), a standard 32-bit
> > version (LA32S) and a 64-bit version (LA64). LoongArch32 use FDT as its
> > boot protocol which is already supported in LoongArch64. LoongArch32's
> > ILP32 ABI use the same calling convention as LoongArch64.
> >
> > This patchset is adding basic LoongArch32 support in mainline kernel, it
> > is the successor of Jiaxun Yang's previous work (V1):
> > https://lore.kernel.org/loongarch/20250102-la32-uapi-v1-0-db32aa769b88@flygoat.com/
> >
> > We can see a complete snapshot here:
> > https://github.com/chenhuacai/linux/tree/loongarch-next
>
> I looked through all the patches, and this seems completely fine
> implementation-wise. I replied with a few minor comments, but
> found no show-stoppers.
Thank you very much, I will try to solve those problems if possible.

>
> Reviewed-by: Arnd Bergmann <arnd@arndb.de>
>
> I'm still skeptical about the usefulness overall and would warn you
> that you may regret merging this in a few years: 32-bit Linux is
> clearly in decline, and the amount of work in bringing up and
The motivation is explained by Jiaxun Yang, and maybe I should keep it
in the cover letter.

> maintaining another ABI (or two if you count LA32R/S separately)
> is substantial.
The ABI of LA32R/S is the same (I mean they are both ILP32), but
something is not compatible so we can not use a single kernel binary.

>
> In your cover letter, I'm missing information about running LA32
> code on LA64 hardware. Specifically, do you plan to add CONFIG_COMPAT
> support later, and do you plan to support LA32 kernels running
> on LA64-capable hardware?
Yes, Jiaxun is working on CONFIG_COMPAT.


Huacai

> I would suggest supporting COMPAT 32-bit userspace here, but not
> 32-bit kernels: based on the experience with x86, arm, powerpc
> and mips platforms that allow both, the compat mode usually
> results in a much better experience overall. Compat support should
> probably be a follow-up and not part of the initial submission
> though, so what you have here is fine.
>
>        Arnd

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 12/14] LoongArch: Adjust VDSO/VSYSCALL for 32BIT/64BIT
  2025-11-18 13:41   ` Arnd Bergmann
@ 2025-11-18 14:34     ` Huacai Chen
  0 siblings, 0 replies; 37+ messages in thread
From: Huacai Chen @ 2025-11-18 14:34 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Huacai Chen, loongarch, Linux-Arch, Xuefeng Li, guoren,
	WANG Xuerui, Jiaxun Yang, linux-kernel

Hi, Arnd,

On Tue, Nov 18, 2025 at 9:42 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Tue, Nov 18, 2025, at 12:27, Huacai Chen wrote:
> > Adjust VDSO/VSYSCALL because read_cpu_id() for 32BIT/64BIT are
> > different, and LoongArch32 doesn't support GENERIC_GETTIMEOFDAY now.
> >
> > Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> > Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
>
> Are you planning to add vdso_clock_gettime() later, or is the
> architecture missing hardware access to the timer register
> on loongarch32?
Hardware has no problem, vdso_clock_gettime() will be added later.

Huacai

>
> It would be good to add some comments here to ensure this is
> done correctly if someone adds the vdso32 support later:
> There should be clock_gettime32 support, but not the old
> clock_gettime(), clock_getres() or time().
>
>        Arnd
>

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 04/14] LoongArch: Adjust boot & setup for 32BIT/64BIT
  2025-11-18 11:27 ` [PATCH V2 04/14] LoongArch: Adjust boot & setup " Huacai Chen
@ 2025-11-18 17:09   ` Yao Zi
  2025-11-19  4:28     ` Huacai Chen
  0 siblings, 1 reply; 37+ messages in thread
From: Yao Zi @ 2025-11-18 17:09 UTC (permalink / raw)
  To: Huacai Chen, Arnd Bergmann, Huacai Chen, Huacai Chen, f
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Xuerui Wang,
	Jiaxun Yang, linux-kernel

On Tue, Nov 18, 2025 at 07:27:18PM +0800, Huacai Chen wrote:
> Adjust boot & setup for both 32BIT and 64BIT, including: efi header
> definition, MAX_IO_PICS definition, kernel entry and environment setup
> routines, etc.
> 
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
> ---
>  arch/loongarch/include/asm/addrspace.h |  2 +-
>  arch/loongarch/include/asm/irq.h       |  5 ++++
>  arch/loongarch/kernel/efi-header.S     |  4 +++
>  arch/loongarch/kernel/efi.c            |  4 ++-
>  arch/loongarch/kernel/env.c            |  9 ++++--
>  arch/loongarch/kernel/head.S           | 39 +++++++++++---------------
>  arch/loongarch/kernel/relocate.c       |  9 +++++-
>  7 files changed, 45 insertions(+), 27 deletions(-)
> 

...

> diff --git a/arch/loongarch/kernel/env.c b/arch/loongarch/kernel/env.c
> index 23bd5ae2212c..3e8a25eb901b 100644
> --- a/arch/loongarch/kernel/env.c
> +++ b/arch/loongarch/kernel/env.c
> @@ -68,18 +68,23 @@ static int __init fdt_cpu_clk_init(void)
>  
>  	np = of_get_cpu_node(0, NULL);
>  	if (!np)
> -		return -ENODEV;
> +		goto fallback;
>  
>  	clk = of_clk_get(np, 0);
>  	of_node_put(np);
>  
>  	if (IS_ERR(clk))
> -		return -ENODEV;
> +		goto fallback;
>  
>  	cpu_clock_freq = clk_get_rate(clk);
>  	clk_put(clk);
>  
>  	return 0;
> +
> +fallback:
> +	cpu_clock_freq = 200 * 1000 * 1000;

Why pick 200MHz here? And shouldn't the clock being always provided in
devicetree if it's necessary for kernel to function?

Per the schema for LoongArch CPUs (loongarch/cpus.yaml), "clocks"
property is also described as mandantory, thus I don't think such
fallback makes sense.

> +
> +	return -ENODEV;
>  }
>  late_initcall(fdt_cpu_clk_init);

Best regards,
Yao Zi

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 04/14] LoongArch: Adjust boot & setup for 32BIT/64BIT
  2025-11-18 17:09   ` Yao Zi
@ 2025-11-19  4:28     ` Huacai Chen
  2025-11-19  6:03       ` Jiaxun Yang
  0 siblings, 1 reply; 37+ messages in thread
From: Huacai Chen @ 2025-11-19  4:28 UTC (permalink / raw)
  To: Yao Zi
  Cc: Huacai Chen, Arnd Bergmann, f, loongarch, linux-arch, Xuefeng Li,
	Guo Ren, Xuerui Wang, Jiaxun Yang, linux-kernel

On Wed, Nov 19, 2025 at 1:09 AM Yao Zi <ziyao@disroot.org> wrote:
>
> On Tue, Nov 18, 2025 at 07:27:18PM +0800, Huacai Chen wrote:
> > Adjust boot & setup for both 32BIT and 64BIT, including: efi header
> > definition, MAX_IO_PICS definition, kernel entry and environment setup
> > routines, etc.
> >
> > Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> > Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
> > ---
> >  arch/loongarch/include/asm/addrspace.h |  2 +-
> >  arch/loongarch/include/asm/irq.h       |  5 ++++
> >  arch/loongarch/kernel/efi-header.S     |  4 +++
> >  arch/loongarch/kernel/efi.c            |  4 ++-
> >  arch/loongarch/kernel/env.c            |  9 ++++--
> >  arch/loongarch/kernel/head.S           | 39 +++++++++++---------------
> >  arch/loongarch/kernel/relocate.c       |  9 +++++-
> >  7 files changed, 45 insertions(+), 27 deletions(-)
> >
>
> ...
>
> > diff --git a/arch/loongarch/kernel/env.c b/arch/loongarch/kernel/env.c
> > index 23bd5ae2212c..3e8a25eb901b 100644
> > --- a/arch/loongarch/kernel/env.c
> > +++ b/arch/loongarch/kernel/env.c
> > @@ -68,18 +68,23 @@ static int __init fdt_cpu_clk_init(void)
> >
> >       np = of_get_cpu_node(0, NULL);
> >       if (!np)
> > -             return -ENODEV;
> > +             goto fallback;
> >
> >       clk = of_clk_get(np, 0);
> >       of_node_put(np);
> >
> >       if (IS_ERR(clk))
> > -             return -ENODEV;
> > +             goto fallback;
> >
> >       cpu_clock_freq = clk_get_rate(clk);
> >       clk_put(clk);
> >
> >       return 0;
> > +
> > +fallback:
> > +     cpu_clock_freq = 200 * 1000 * 1000;
>
> Why pick 200MHz here? And shouldn't the clock being always provided in
> devicetree if it's necessary for kernel to function?
>
> Per the schema for LoongArch CPUs (loongarch/cpus.yaml), "clocks"
> property is also described as mandantory, thus I don't think such
> fallback makes sense.
Yes, "clocks" is mandatory in theory, but sometimes is missing in
practice, at least in QEMU. On the other hand, if "clocks" really
always exist, then the error checking in fdt_cpu_clk_init() can also
be removed. So the fallback makes sense.

Why pick 200MHz? That is because we assume the constant timer is
100MHz (which is true for all real machines), 200MHz is the minimal
multiple of 100MHz, it is more reasonable than 0MHz.

Huacai
>
> > +
> > +     return -ENODEV;
> >  }
> >  late_initcall(fdt_cpu_clk_init);
>
> Best regards,
> Yao Zi
>

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 04/14] LoongArch: Adjust boot & setup for 32BIT/64BIT
  2025-11-19  4:28     ` Huacai Chen
@ 2025-11-19  6:03       ` Jiaxun Yang
  2025-11-19  7:51         ` Huacai Chen
  0 siblings, 1 reply; 37+ messages in thread
From: Jiaxun Yang @ 2025-11-19  6:03 UTC (permalink / raw)
  To: Huacai Chen, Yao Zi
  Cc: Huacai Chen, Arnd Bergmann, f, loongarch, linux-arch, Xuefeng Li,
	Guo Ren, Xuerui Wang, linux-kernel



On Wed, 19 Nov 2025, at 12:28 PM, Huacai Chen wrote:
[...]
>> Per the schema for LoongArch CPUs (loongarch/cpus.yaml), "clocks"
>> property is also described as mandantory, thus I don't think such
>> fallback makes sense.
> Yes, "clocks" is mandatory in theory, but sometimes is missing in
> practice, at least in QEMU. On the other hand, if "clocks" really
> always exist, then the error checking in fdt_cpu_clk_init() can also
> be removed. So the fallback makes sense.

IMHO this should be fixed on QEMU side, but I recall QEMU do have clock
supplied in generic fdt?

>
> Why pick 200MHz? That is because we assume the constant timer is
> 100MHz (which is true for all real machines), 200MHz is the minimal
> multiple of 100MHz, it is more reasonable than 0MHz.

Maybe better panic here :-)

Thanks
-- 
- Jiaxun

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 04/14] LoongArch: Adjust boot & setup for 32BIT/64BIT
  2025-11-19  6:03       ` Jiaxun Yang
@ 2025-11-19  7:51         ` Huacai Chen
  2025-11-19 14:28           ` Yao Zi
  0 siblings, 1 reply; 37+ messages in thread
From: Huacai Chen @ 2025-11-19  7:51 UTC (permalink / raw)
  To: Jiaxun Yang
  Cc: Yao Zi, Huacai Chen, Arnd Bergmann, f, loongarch, linux-arch,
	Xuefeng Li, Guo Ren, Xuerui Wang, linux-kernel

On Wed, Nov 19, 2025 at 2:03 PM Jiaxun Yang <jiaxun.yang@flygoat.com> wrote:
>
>
>
> On Wed, 19 Nov 2025, at 12:28 PM, Huacai Chen wrote:
> [...]
> >> Per the schema for LoongArch CPUs (loongarch/cpus.yaml), "clocks"
> >> property is also described as mandantory, thus I don't think such
> >> fallback makes sense.
> > Yes, "clocks" is mandatory in theory, but sometimes is missing in
> > practice, at least in QEMU. On the other hand, if "clocks" really
> > always exist, then the error checking in fdt_cpu_clk_init() can also
> > be removed. So the fallback makes sense.
>
> IMHO this should be fixed on QEMU side, but I recall QEMU do have clock
> supplied in generic fdt?
It is difficult to fix, you can have a try. :)
If without fallback, cpuinfo shows 0MHz now.

>
> >
> > Why pick 200MHz? That is because we assume the constant timer is
> > 100MHz (which is true for all real machines), 200MHz is the minimal
> > multiple of 100MHz, it is more reasonable than 0MHz.
>
> Maybe better panic here :-)
No, this is not a fatal error, we don't need to treat everything as
fatal. As you know, many "BUG_ON" have been replaced with "WARN_ON" in
kernel.

Huacai

>
> Thanks
> --
> - Jiaxun
>

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 13/14] LoongArch: Adjust default config files for 32BIT/64BIT
  2025-11-18 13:45   ` Arnd Bergmann
@ 2025-11-19  8:01     ` Huacai Chen
  2025-11-19  8:13       ` Arnd Bergmann
  0 siblings, 1 reply; 37+ messages in thread
From: Huacai Chen @ 2025-11-19  8:01 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Huacai Chen, loongarch, Linux-Arch, Xuefeng Li, guoren,
	WANG Xuerui, Jiaxun Yang, linux-kernel

Hi, Arnd,

On Tue, Nov 18, 2025 at 9:46 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Tue, Nov 18, 2025, at 12:27, Huacai Chen wrote:
> > Add loongson32_defconfig (for 32BIT) and rename loongson3_defconfig to
> > loongson64_defconfig (for 64BIT).
> >
> > Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> > Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
> > ---
> >  arch/loongarch/configs/loongson32_defconfig   | 1110 +++++++++++++++++
> >  ...ongson3_defconfig => loongson64_defconfig} |    0
>
> I would suggest using .config fragment here and only listing
> the differences in the defconfig files in there, rather than
> duplicating everything.
>
> > +CONFIG_DMI=y
> > +CONFIG_EFI=y
> > +CONFIG_SUSPEND=y
> > +CONFIG_HIBERNATION=y
> > +CONFIG_ACPI=y
> > +CONFIG_ACPI_SPCR_TABLE=y
> > +CONFIG_ACPI_TAD=y
> > +CONFIG_ACPI_DOCK=y
> > +CONFIG_ACPI_IPMI=m
> > +CONFIG_ACPI_HOTPLUG_CPU=y
> > +CONFIG_ACPI_PCI_SLOT=y
> > +CONFIG_ACPI_HOTPLUG_MEMORY=y
> > +CONFIG_ACPI_BGRT=y
>
> You mention that loongarch32 uses ftb based boot,
> so ACPI should probably be disabled here.
I have tried my best, adding #ifdef CONFIG_ACPI all over the world but
still failed. :)

LoongArch is deeply coupled with ACPI and can hardly disabled. On the
other hand, it is not forbidden to use ACPI for LoongArch32. So let's
keep it, and I will modify the description for LoongArch32 booting.

>
> > +CONFIG_DRM=y
> > +CONFIG_DRM_LOAD_EDID_FIRMWARE=y
> > +CONFIG_DRM_RADEON=m
> > +CONFIG_DRM_RADEON_USERPTR=y
> > +CONFIG_DRM_AMDGPU=m
> > +CONFIG_DRM_AMDGPU_SI=y
> > +CONFIG_DRM_AMDGPU_CIK=y
> > +CONFIG_DRM_AMDGPU_USERPTR=y
> > +CONFIG_DRM_AST=y
> > +CONFIG_DRM_QXL=m
> > +CONFIG_DRM_VIRTIO_GPU=m
> > +CONFIG_DRM_LOONGSON=y
> > +CONFIG_DRM_SIMPLEDRM=y
> > +CONFIG_FB=y
> > +CONFIG_FB_EFI=y
> > +CONFIG_FB_RADEON=y
> > +CONFIG_FIRMWARE_EDID=y
>
> Is AMDGPU actually working? This driver is rather tricky to get
> reliable on new architectures.
Never tried and probably not work. I will remove it.

>
> I would suggest turning off CONFIG_FB here (also on loongarch64).
> There is a replacement driver for FB_EFI in DRM now.
Do you mean simpledrm? It probably works but not always works. From
sysfb_init() we know it only mark EFIFB as a simpledrm device when
"compatible", so we still need FB_EFI as a fallback.

Huacai

>
>        Arnd
>

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 13/14] LoongArch: Adjust default config files for 32BIT/64BIT
  2025-11-19  8:01     ` Huacai Chen
@ 2025-11-19  8:13       ` Arnd Bergmann
  2025-11-19 14:13         ` Huacai Chen
  0 siblings, 1 reply; 37+ messages in thread
From: Arnd Bergmann @ 2025-11-19  8:13 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Huacai Chen, loongarch, Linux-Arch, Xuefeng Li, guoren,
	WANG Xuerui, Jiaxun Yang, linux-kernel

On Wed, Nov 19, 2025, at 09:01, Huacai Chen wrote:
> On Tue, Nov 18, 2025 at 9:46 PM Arnd Bergmann <arnd@arndb.de> wrote:
>>
>> On Tue, Nov 18, 2025, at 12:27, Huacai Chen wrote:
>> > Add loongson32_defconfig (for 32BIT) and rename loongson3_defconfig to
>> > loongson64_defconfig (for 64BIT).
>> >
>> > Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>> > Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
>> > ---
>> >  arch/loongarch/configs/loongson32_defconfig   | 1110 +++++++++++++++++
>> >  ...ongson3_defconfig => loongson64_defconfig} |    0
>>
>> I would suggest using .config fragment here and only listing
>> the differences in the defconfig files in there, rather than
>> duplicating everything.
>>
>> > +CONFIG_DMI=y
>> > +CONFIG_EFI=y
>> > +CONFIG_SUSPEND=y
>> > +CONFIG_HIBERNATION=y
>> > +CONFIG_ACPI=y
>> > +CONFIG_ACPI_SPCR_TABLE=y
>> > +CONFIG_ACPI_TAD=y
>> > +CONFIG_ACPI_DOCK=y
>> > +CONFIG_ACPI_IPMI=m
>> > +CONFIG_ACPI_HOTPLUG_CPU=y
>> > +CONFIG_ACPI_PCI_SLOT=y
>> > +CONFIG_ACPI_HOTPLUG_MEMORY=y
>> > +CONFIG_ACPI_BGRT=y
>>
>> You mention that loongarch32 uses ftb based boot,
>> so ACPI should probably be disabled here.
> I have tried my best, adding #ifdef CONFIG_ACPI all over the world but
> still failed. :)
>
> LoongArch is deeply coupled with ACPI and can hardly disabled. On the
> other hand, it is not forbidden to use ACPI for LoongArch32. So let's
> keep it, and I will modify the description for LoongArch32 booting.

Ok. You will probably want get back to it eventually, since the
32-bit port is likely intended for small-memory devices, and the
ACPI code is fairly large.

>> I would suggest turning off CONFIG_FB here (also on loongarch64).
>> There is a replacement driver for FB_EFI in DRM now.
> Do you mean simpledrm? It probably works but not always works. From
> sysfb_init() we know it only mark EFIFB as a simpledrm device when
> "compatible", so we still need FB_EFI as a fallback.

I meant CONFIG_DRM_EFIDRM, which was added earlier this year.
EFIDRM should work more reliably than SIMPLEDRM.

     Arnd

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 13/14] LoongArch: Adjust default config files for 32BIT/64BIT
  2025-11-19  8:13       ` Arnd Bergmann
@ 2025-11-19 14:13         ` Huacai Chen
  0 siblings, 0 replies; 37+ messages in thread
From: Huacai Chen @ 2025-11-19 14:13 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Huacai Chen, loongarch, Linux-Arch, Xuefeng Li, guoren,
	WANG Xuerui, Jiaxun Yang, linux-kernel

On Wed, Nov 19, 2025 at 4:13 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> On Wed, Nov 19, 2025, at 09:01, Huacai Chen wrote:
> > On Tue, Nov 18, 2025 at 9:46 PM Arnd Bergmann <arnd@arndb.de> wrote:
> >>
> >> On Tue, Nov 18, 2025, at 12:27, Huacai Chen wrote:
> >> > Add loongson32_defconfig (for 32BIT) and rename loongson3_defconfig to
> >> > loongson64_defconfig (for 64BIT).
> >> >
> >> > Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> >> > Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
> >> > ---
> >> >  arch/loongarch/configs/loongson32_defconfig   | 1110 +++++++++++++++++
> >> >  ...ongson3_defconfig => loongson64_defconfig} |    0
> >>
> >> I would suggest using .config fragment here and only listing
> >> the differences in the defconfig files in there, rather than
> >> duplicating everything.
> >>
> >> > +CONFIG_DMI=y
> >> > +CONFIG_EFI=y
> >> > +CONFIG_SUSPEND=y
> >> > +CONFIG_HIBERNATION=y
> >> > +CONFIG_ACPI=y
> >> > +CONFIG_ACPI_SPCR_TABLE=y
> >> > +CONFIG_ACPI_TAD=y
> >> > +CONFIG_ACPI_DOCK=y
> >> > +CONFIG_ACPI_IPMI=m
> >> > +CONFIG_ACPI_HOTPLUG_CPU=y
> >> > +CONFIG_ACPI_PCI_SLOT=y
> >> > +CONFIG_ACPI_HOTPLUG_MEMORY=y
> >> > +CONFIG_ACPI_BGRT=y
> >>
> >> You mention that loongarch32 uses ftb based boot,
> >> so ACPI should probably be disabled here.
> > I have tried my best, adding #ifdef CONFIG_ACPI all over the world but
> > still failed. :)
> >
> > LoongArch is deeply coupled with ACPI and can hardly disabled. On the
> > other hand, it is not forbidden to use ACPI for LoongArch32. So let's
> > keep it, and I will modify the description for LoongArch32 booting.
>
> Ok. You will probably want get back to it eventually, since the
> 32-bit port is likely intended for small-memory devices, and the
> ACPI code is fairly large.
>
> >> I would suggest turning off CONFIG_FB here (also on loongarch64).
> >> There is a replacement driver for FB_EFI in DRM now.
> > Do you mean simpledrm? It probably works but not always works. From
> > sysfb_init() we know it only mark EFIFB as a simpledrm device when
> > "compatible", so we still need FB_EFI as a fallback.
>
> I meant CONFIG_DRM_EFIDRM, which was added earlier this year.
> EFIDRM should work more reliably than SIMPLEDRM.
OK, I will disable FB_EFI and enable EFIDRM instead.

Huacai

>
>      Arnd
>

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 04/14] LoongArch: Adjust boot & setup for 32BIT/64BIT
  2025-11-19  7:51         ` Huacai Chen
@ 2025-11-19 14:28           ` Yao Zi
  2025-11-19 14:43             ` Huacai Chen
  0 siblings, 1 reply; 37+ messages in thread
From: Yao Zi @ 2025-11-19 14:28 UTC (permalink / raw)
  To: Huacai Chen, Jiaxun Yang
  Cc: Huacai Chen, Arnd Bergmann, f, loongarch, linux-arch, Xuefeng Li,
	Guo Ren, Xuerui Wang, linux-kernel

On Wed, Nov 19, 2025 at 03:51:01PM +0800, Huacai Chen wrote:
> On Wed, Nov 19, 2025 at 2:03 PM Jiaxun Yang <jiaxun.yang@flygoat.com> wrote:
> >
> >
> >
> > On Wed, 19 Nov 2025, at 12:28 PM, Huacai Chen wrote:
> > [...]
> > >> Per the schema for LoongArch CPUs (loongarch/cpus.yaml), "clocks"
> > >> property is also described as mandantory, thus I don't think such
> > >> fallback makes sense.
> > > Yes, "clocks" is mandatory in theory, but sometimes is missing in
> > > practice, at least in QEMU. On the other hand, if "clocks" really
> > > always exist, then the error checking in fdt_cpu_clk_init() can also
> > > be removed. So the fallback makes sense.
> >
> > IMHO this should be fixed on QEMU side, but I recall QEMU do have clock
> > supplied in generic fdt?
> It is difficult to fix, you can have a try. :)
> If without fallback, cpuinfo shows 0MHz now.

A fake "200MHz" output sounds much worse than obviously wrong "0MHz":
the latter informs the user something bad happened here, while a
mysterious "200MHz" output only makes it more confusing since no one has
specified so in the failing case.

> >
> > >
> > > Why pick 200MHz? That is because we assume the constant timer is
> > > 100MHz (which is true for all real machines), 200MHz is the minimal
> > > multiple of 100MHz, it is more reasonable than 0MHz.
> >
> > Maybe better panic here :-)
> No, this is not a fatal error, we don't need to treat everything as
> fatal. As you know, many "BUG_ON" have been replaced with "WARN_ON" in
> kernel.

But it is an error and shouldn't be ignored. I agree that panic is too
serious for this, but at least a warning should be issued.

> Huacai

Regards,
Yao Zi


> >
> > Thanks
> > --
> > - Jiaxun
> >

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 04/14] LoongArch: Adjust boot & setup for 32BIT/64BIT
  2025-11-19 14:28           ` Yao Zi
@ 2025-11-19 14:43             ` Huacai Chen
  0 siblings, 0 replies; 37+ messages in thread
From: Huacai Chen @ 2025-11-19 14:43 UTC (permalink / raw)
  To: Yao Zi
  Cc: Jiaxun Yang, Huacai Chen, Arnd Bergmann, f, loongarch, linux-arch,
	Xuefeng Li, Guo Ren, Xuerui Wang, linux-kernel

On Wed, Nov 19, 2025 at 10:29 PM Yao Zi <ziyao@disroot.org> wrote:
>
> On Wed, Nov 19, 2025 at 03:51:01PM +0800, Huacai Chen wrote:
> > On Wed, Nov 19, 2025 at 2:03 PM Jiaxun Yang <jiaxun.yang@flygoat.com> wrote:
> > >
> > >
> > >
> > > On Wed, 19 Nov 2025, at 12:28 PM, Huacai Chen wrote:
> > > [...]
> > > >> Per the schema for LoongArch CPUs (loongarch/cpus.yaml), "clocks"
> > > >> property is also described as mandantory, thus I don't think such
> > > >> fallback makes sense.
> > > > Yes, "clocks" is mandatory in theory, but sometimes is missing in
> > > > practice, at least in QEMU. On the other hand, if "clocks" really
> > > > always exist, then the error checking in fdt_cpu_clk_init() can also
> > > > be removed. So the fallback makes sense.
> > >
> > > IMHO this should be fixed on QEMU side, but I recall QEMU do have clock
> > > supplied in generic fdt?
> > It is difficult to fix, you can have a try. :)
> > If without fallback, cpuinfo shows 0MHz now.
>
> A fake "200MHz" output sounds much worse than obviously wrong "0MHz":
> the latter informs the user something bad happened here, while a
> mysterious "200MHz" output only makes it more confusing since no one has
> specified so in the failing case.
All CPU freq in QEMU TCG is fake, even if it is provided by DTS. But
if someone fixes QEMU, I'm happy to remove this part.

>
> > >
> > > >
> > > > Why pick 200MHz? That is because we assume the constant timer is
> > > > 100MHz (which is true for all real machines), 200MHz is the minimal
> > > > multiple of 100MHz, it is more reasonable than 0MHz.
> > >
> > > Maybe better panic here :-)
> > No, this is not a fatal error, we don't need to treat everything as
> > fatal. As you know, many "BUG_ON" have been replaced with "WARN_ON" in
> > kernel.
>
> But it is an error and shouldn't be ignored. I agree that panic is too
> serious for this, but at least a warning should be issued.
Yes, it is better to add a warning.


Huacai
>
> > Huacai
>
> Regards,
> Yao Zi
>
>
> > >
> > > Thanks
> > > --
> > > - Jiaxun
> > >
>

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 13/14] LoongArch: Adjust default config files for 32BIT/64BIT
  2025-11-18 11:27 ` [PATCH V2 13/14] LoongArch: Adjust default config files " Huacai Chen
  2025-11-18 13:45   ` Arnd Bergmann
@ 2025-11-20  8:11   ` Thomas Weißschuh
  2025-11-20  8:16     ` Huacai Chen
  1 sibling, 1 reply; 37+ messages in thread
From: Thomas Weißschuh @ 2025-11-20  8:11 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Arnd Bergmann, Huacai Chen, loongarch, linux-arch, Xuefeng Li,
	Guo Ren, Xuerui Wang, Jiaxun Yang, linux-kernel

On Tue, Nov 18, 2025 at 07:27:27PM +0800, Huacai Chen wrote:
> Add loongson32_defconfig (for 32BIT) and rename loongson3_defconfig to
> loongson64_defconfig (for 64BIT).
> 
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
> ---
>  arch/loongarch/configs/loongson32_defconfig   | 1110 +++++++++++++++++
>  ...ongson3_defconfig => loongson64_defconfig} |    0
>  2 files changed, 1110 insertions(+)
>  create mode 100644 arch/loongarch/configs/loongson32_defconfig
>  rename arch/loongarch/configs/{loongson3_defconfig => loongson64_defconfig} (100%)

KBUILD_DEFCONFIG also needs to be adapted to this rename.

FYI the cover letter says the series is based on v6.16-rc6, but the series
doesn't apply to it.

(...)

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 13/14] LoongArch: Adjust default config files for 32BIT/64BIT
  2025-11-20  8:11   ` Thomas Weißschuh
@ 2025-11-20  8:16     ` Huacai Chen
  2025-11-20  8:26       ` Thomas Weißschuh
  0 siblings, 1 reply; 37+ messages in thread
From: Huacai Chen @ 2025-11-20  8:16 UTC (permalink / raw)
  To: Thomas Weißschuh
  Cc: Huacai Chen, Arnd Bergmann, loongarch, linux-arch, Xuefeng Li,
	Guo Ren, Xuerui Wang, Jiaxun Yang, linux-kernel

Hi, Thomas,

On Thu, Nov 20, 2025 at 4:11 PM Thomas Weißschuh
<thomas.weissschuh@linutronix.de> wrote:
>
> On Tue, Nov 18, 2025 at 07:27:27PM +0800, Huacai Chen wrote:
> > Add loongson32_defconfig (for 32BIT) and rename loongson3_defconfig to
> > loongson64_defconfig (for 64BIT).
> >
> > Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> > Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
> > ---
> >  arch/loongarch/configs/loongson32_defconfig   | 1110 +++++++++++++++++
> >  ...ongson3_defconfig => loongson64_defconfig} |    0
> >  2 files changed, 1110 insertions(+)
> >  create mode 100644 arch/loongarch/configs/loongson32_defconfig
> >  rename arch/loongarch/configs/{loongson3_defconfig => loongson64_defconfig} (100%)
>
> KBUILD_DEFCONFIG also needs to be adapted to this rename.
That is done in the last patch.

>
> FYI the cover letter says the series is based on v6.16-rc6, but the series
> doesn't apply to it.
Not 6.16-rc6, but 6.18-rc6, and the next version will be on top of 6.18-rc7.

Huacai

>
> (...)

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 13/14] LoongArch: Adjust default config files for 32BIT/64BIT
  2025-11-20  8:16     ` Huacai Chen
@ 2025-11-20  8:26       ` Thomas Weißschuh
  2025-11-20  8:54         ` Huacai Chen
  0 siblings, 1 reply; 37+ messages in thread
From: Thomas Weißschuh @ 2025-11-20  8:26 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Huacai Chen, Arnd Bergmann, loongarch, linux-arch, Xuefeng Li,
	Guo Ren, Xuerui Wang, Jiaxun Yang, linux-kernel

On Thu, Nov 20, 2025 at 04:16:25PM +0800, Huacai Chen wrote:
> Hi, Thomas,
> 
> On Thu, Nov 20, 2025 at 4:11 PM Thomas Weißschuh
> <thomas.weissschuh@linutronix.de> wrote:
> >
> > On Tue, Nov 18, 2025 at 07:27:27PM +0800, Huacai Chen wrote:
> > > Add loongson32_defconfig (for 32BIT) and rename loongson3_defconfig to
> > > loongson64_defconfig (for 64BIT).
> > >
> > > Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> > > Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
> > > ---
> > >  arch/loongarch/configs/loongson32_defconfig   | 1110 +++++++++++++++++
> > >  ...ongson3_defconfig => loongson64_defconfig} |    0
> > >  2 files changed, 1110 insertions(+)
> > >  create mode 100644 arch/loongarch/configs/loongson32_defconfig
> > >  rename arch/loongarch/configs/{loongson3_defconfig => loongson64_defconfig} (100%)
> >
> > KBUILD_DEFCONFIG also needs to be adapted to this rename.
> That is done in the last patch.

That means the 64bit 'make defconfig' is broken within this series, potentially
breaking bisects.

> > FYI the cover letter says the series is based on v6.16-rc6, but the series
> > doesn't apply to it.
> Not 6.16-rc6, but 6.18-rc6, and the next version will be on top of 6.18-rc7.

That was a mistype. It doesn't apply to v6.18-rc6.

Looking at the GitHub repo mentioned in the cover letter, there are additional
patches on top of rc6. Which I guess is fine in general, but the changelog
could be a bit clearer.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 13/14] LoongArch: Adjust default config files for 32BIT/64BIT
  2025-11-20  8:26       ` Thomas Weißschuh
@ 2025-11-20  8:54         ` Huacai Chen
  0 siblings, 0 replies; 37+ messages in thread
From: Huacai Chen @ 2025-11-20  8:54 UTC (permalink / raw)
  To: Thomas Weißschuh
  Cc: Huacai Chen, Arnd Bergmann, loongarch, linux-arch, Xuefeng Li,
	Guo Ren, Xuerui Wang, Jiaxun Yang, linux-kernel

On Thu, Nov 20, 2025 at 4:27 PM Thomas Weißschuh
<thomas.weissschuh@linutronix.de> wrote:
>
> On Thu, Nov 20, 2025 at 04:16:25PM +0800, Huacai Chen wrote:
> > Hi, Thomas,
> >
> > On Thu, Nov 20, 2025 at 4:11 PM Thomas Weißschuh
> > <thomas.weissschuh@linutronix.de> wrote:
> > >
> > > On Tue, Nov 18, 2025 at 07:27:27PM +0800, Huacai Chen wrote:
> > > > Add loongson32_defconfig (for 32BIT) and rename loongson3_defconfig to
> > > > loongson64_defconfig (for 64BIT).
> > > >
> > > > Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> > > > Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
> > > > ---
> > > >  arch/loongarch/configs/loongson32_defconfig   | 1110 +++++++++++++++++
> > > >  ...ongson3_defconfig => loongson64_defconfig} |    0
> > > >  2 files changed, 1110 insertions(+)
> > > >  create mode 100644 arch/loongarch/configs/loongson32_defconfig
> > > >  rename arch/loongarch/configs/{loongson3_defconfig => loongson64_defconfig} (100%)
> > >
> > > KBUILD_DEFCONFIG also needs to be adapted to this rename.
> > That is done in the last patch.
>
> That means the 64bit 'make defconfig' is broken within this series, potentially
> breaking bisects.
You are right, that should be done in this patch.

>
> > > FYI the cover letter says the series is based on v6.16-rc6, but the series
> > > doesn't apply to it.
> > Not 6.16-rc6, but 6.18-rc6, and the next version will be on top of 6.18-rc7.
>
> That was a mistype. It doesn't apply to v6.18-rc6.
>
> Looking at the GitHub repo mentioned in the cover letter, there are additional
> patches on top of rc6. Which I guess is fine in general, but the changelog
> could be a bit clearer.
OK, I know, thank you.

Huacai
>

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 09/14] LoongArch: Adjust system call for 32BIT/64BIT
  2025-11-18 11:27 ` [PATCH V2 09/14] LoongArch: Adjust system call " Huacai Chen
@ 2025-11-20 10:40   ` WANG Xuerui
  2025-11-20 12:05     ` Huacai Chen
  0 siblings, 1 reply; 37+ messages in thread
From: WANG Xuerui @ 2025-11-20 10:40 UTC (permalink / raw)
  To: Huacai Chen, Arnd Bergmann, Huacai Chen
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Jiaxun Yang,
	linux-kernel

On 11/18/25 19:27, Huacai Chen wrote:
> Adjust system call for both 32BIT and 64BIT, including: add the uapi
> unistd_{32,64}.h and syscall_table_{32,64}.h inclusion, add sys_mmap2()
> definition, change the system call entry routines, etc.
> 
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
> ---
>   arch/loongarch/include/asm/Kbuild        |  1 +
>   arch/loongarch/include/uapi/asm/Kbuild   |  1 +
>   arch/loongarch/include/uapi/asm/unistd.h |  6 ++++++
>   arch/loongarch/kernel/Makefile.syscalls  |  1 +
>   arch/loongarch/kernel/entry.S            | 22 +++++++++++-----------
>   arch/loongarch/kernel/syscall.c          | 13 +++++++++++++
>   6 files changed, 33 insertions(+), 11 deletions(-)
> 
> [snip]
> diff --git a/arch/loongarch/kernel/syscall.c b/arch/loongarch/kernel/syscall.c
> index ab94eb5ce039..1249d82c1cd0 100644
> --- a/arch/loongarch/kernel/syscall.c
> +++ b/arch/loongarch/kernel/syscall.c
> @@ -34,9 +34,22 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, unsigned long,
>   	return ksys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
>   }
>   
> +SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, unsigned long,
> +		 prot, unsigned long, flags, unsigned long, fd, unsigned long, offset)
> +{
> +	if (offset & (~PAGE_MASK >> 12))
> +		return -EINVAL;
> +
> +	return ksys_mmap_pgoff(addr, len, prot, flags, fd, offset >> (PAGE_SHIFT - 12));
> +}
> +

Why not guard this with #ifdef CONFIG_32BIT?

>   void *sys_call_table[__NR_syscalls] = {
>   	[0 ... __NR_syscalls - 1] = sys_ni_syscall,
> +#ifdef CONFIG_32BIT
> +#include <asm/syscall_table_32.h>
> +#else
>   #include <asm/syscall_table_64.h>
> +#endif
>   };
>   
>   typedef long (*sys_call_fn)(unsigned long, unsigned long,

-- 
WANG "xen0n" Xuerui

Linux/LoongArch mailing list: https://lore.kernel.org/loongarch/

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 11/14] LoongArch: Adjust misc routines for 32BIT/64BIT
  2025-11-18 11:27 ` [PATCH V2 11/14] LoongArch: Adjust misc routines " Huacai Chen
@ 2025-11-20 10:45   ` WANG Xuerui
  2025-11-20 12:04     ` Huacai Chen
  0 siblings, 1 reply; 37+ messages in thread
From: WANG Xuerui @ 2025-11-20 10:45 UTC (permalink / raw)
  To: Huacai Chen, Arnd Bergmann, Huacai Chen
  Cc: loongarch, linux-arch, Xuefeng Li, Guo Ren, Jiaxun Yang,
	linux-kernel

On 11/18/25 19:27, Huacai Chen wrote:
> Adjust misc routines for both 32BIT and 64BIT, including: checksum,
> jump label, unaligned access emulator, PCI init routines, sleep/wakeup
> routines, etc.
> 
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
> ---
>   arch/loongarch/include/asm/checksum.h   |  4 ++
>   arch/loongarch/include/asm/jump_label.h | 12 ++++-
>   arch/loongarch/include/asm/string.h     |  2 +
>   arch/loongarch/kernel/unaligned.c       | 30 ++++++++---
>   arch/loongarch/lib/unaligned.S          | 72 ++++++++++++-------------
>   arch/loongarch/pci/pci.c                |  8 +--
>   arch/loongarch/power/suspend_asm.S      | 72 ++++++++++++-------------
>   7 files changed, 116 insertions(+), 84 deletions(-)
> 
> [snip]
> diff --git a/arch/loongarch/pci/pci.c b/arch/loongarch/pci/pci.c
> index 5bc9627a6cf9..d9fc5d520b37 100644
> --- a/arch/loongarch/pci/pci.c
> +++ b/arch/loongarch/pci/pci.c
> @@ -50,11 +50,11 @@ static int __init pcibios_init(void)
>   	 */
>   	lsize = cpu_last_level_cache_line_size();
>   
> -	BUG_ON(!lsize);
> +	if (lsize) {
> +		pci_dfl_cache_line_size = lsize >> 2;
>   
> -	pci_dfl_cache_line_size = lsize >> 2;
> -
> -	pr_debug("PCI: pci_cache_line_size set to %d bytes\n", lsize);
> +		pr_debug("PCI: pci_cache_line_size set to %d bytes\n", lsize);
> +	}
>   
>   	return 0;
>   }
Mind adding a few words about why this is no longer considered a BUG and 
why functionality isn't adversely affected by the change?

-- 
WANG "xen0n" Xuerui

Linux/LoongArch mailing list: https://lore.kernel.org/loongarch/

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 11/14] LoongArch: Adjust misc routines for 32BIT/64BIT
  2025-11-20 10:45   ` WANG Xuerui
@ 2025-11-20 12:04     ` Huacai Chen
  0 siblings, 0 replies; 37+ messages in thread
From: Huacai Chen @ 2025-11-20 12:04 UTC (permalink / raw)
  To: WANG Xuerui
  Cc: Huacai Chen, Arnd Bergmann, loongarch, linux-arch, Xuefeng Li,
	Guo Ren, Jiaxun Yang, linux-kernel

On Thu, Nov 20, 2025 at 6:45 PM WANG Xuerui <kernel@xen0n.name> wrote:
>
> On 11/18/25 19:27, Huacai Chen wrote:
> > Adjust misc routines for both 32BIT and 64BIT, including: checksum,
> > jump label, unaligned access emulator, PCI init routines, sleep/wakeup
> > routines, etc.
> >
> > Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> > Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
> > ---
> >   arch/loongarch/include/asm/checksum.h   |  4 ++
> >   arch/loongarch/include/asm/jump_label.h | 12 ++++-
> >   arch/loongarch/include/asm/string.h     |  2 +
> >   arch/loongarch/kernel/unaligned.c       | 30 ++++++++---
> >   arch/loongarch/lib/unaligned.S          | 72 ++++++++++++-------------
> >   arch/loongarch/pci/pci.c                |  8 +--
> >   arch/loongarch/power/suspend_asm.S      | 72 ++++++++++++-------------
> >   7 files changed, 116 insertions(+), 84 deletions(-)
> >
> > [snip]
> > diff --git a/arch/loongarch/pci/pci.c b/arch/loongarch/pci/pci.c
> > index 5bc9627a6cf9..d9fc5d520b37 100644
> > --- a/arch/loongarch/pci/pci.c
> > +++ b/arch/loongarch/pci/pci.c
> > @@ -50,11 +50,11 @@ static int __init pcibios_init(void)
> >        */
> >       lsize = cpu_last_level_cache_line_size();
> >
> > -     BUG_ON(!lsize);
> > +     if (lsize) {
> > +             pci_dfl_cache_line_size = lsize >> 2;
> >
> > -     pci_dfl_cache_line_size = lsize >> 2;
> > -
> > -     pr_debug("PCI: pci_cache_line_size set to %d bytes\n", lsize);
> > +             pr_debug("PCI: pci_cache_line_size set to %d bytes\n", lsize);
> > +     }
> >
> >       return 0;
> >   }
> Mind adding a few words about why this is no longer considered a BUG and
> why functionality isn't adversely affected by the change?
Yes, you are right, so I split this part into a separate patch.
https://lore.kernel.org/loongarch/20251120082039.2293136-1-chenhuacai@loongson.cn/T/#u

Huacai
>
> --
> WANG "xen0n" Xuerui
>
> Linux/LoongArch mailing list: https://lore.kernel.org/loongarch/
>

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH V2 09/14] LoongArch: Adjust system call for 32BIT/64BIT
  2025-11-20 10:40   ` WANG Xuerui
@ 2025-11-20 12:05     ` Huacai Chen
  0 siblings, 0 replies; 37+ messages in thread
From: Huacai Chen @ 2025-11-20 12:05 UTC (permalink / raw)
  To: WANG Xuerui
  Cc: Huacai Chen, Arnd Bergmann, loongarch, linux-arch, Xuefeng Li,
	Guo Ren, Jiaxun Yang, linux-kernel

On Thu, Nov 20, 2025 at 6:40 PM WANG Xuerui <kernel@xen0n.name> wrote:
>
> On 11/18/25 19:27, Huacai Chen wrote:
> > Adjust system call for both 32BIT and 64BIT, including: add the uapi
> > unistd_{32,64}.h and syscall_table_{32,64}.h inclusion, add sys_mmap2()
> > definition, change the system call entry routines, etc.
> >
> > Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> > Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
> > ---
> >   arch/loongarch/include/asm/Kbuild        |  1 +
> >   arch/loongarch/include/uapi/asm/Kbuild   |  1 +
> >   arch/loongarch/include/uapi/asm/unistd.h |  6 ++++++
> >   arch/loongarch/kernel/Makefile.syscalls  |  1 +
> >   arch/loongarch/kernel/entry.S            | 22 +++++++++++-----------
> >   arch/loongarch/kernel/syscall.c          | 13 +++++++++++++
> >   6 files changed, 33 insertions(+), 11 deletions(-)
> >
> > [snip]
> > diff --git a/arch/loongarch/kernel/syscall.c b/arch/loongarch/kernel/syscall.c
> > index ab94eb5ce039..1249d82c1cd0 100644
> > --- a/arch/loongarch/kernel/syscall.c
> > +++ b/arch/loongarch/kernel/syscall.c
> > @@ -34,9 +34,22 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, unsigned long,
> >       return ksys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
> >   }
> >
> > +SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, unsigned long,
> > +              prot, unsigned long, flags, unsigned long, fd, unsigned long, offset)
> > +{
> > +     if (offset & (~PAGE_MASK >> 12))
> > +             return -EINVAL;
> > +
> > +     return ksys_mmap_pgoff(addr, len, prot, flags, fd, offset >> (PAGE_SHIFT - 12));
> > +}
> > +
>
> Why not guard this with #ifdef CONFIG_32BIT?
Because it is not only used by CONFIG_32BIT, but also by CONFIG_COMPAT.

Huacai

>
> >   void *sys_call_table[__NR_syscalls] = {
> >       [0 ... __NR_syscalls - 1] = sys_ni_syscall,
> > +#ifdef CONFIG_32BIT
> > +#include <asm/syscall_table_32.h>
> > +#else
> >   #include <asm/syscall_table_64.h>
> > +#endif
> >   };
> >
> >   typedef long (*sys_call_fn)(unsigned long, unsigned long,
>
> --
> WANG "xen0n" Xuerui
>
> Linux/LoongArch mailing list: https://lore.kernel.org/loongarch/

^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2025-11-20 12:05 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-18 11:27 [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Huacai Chen
2025-11-18 11:27 ` [PATCH V2 01/14] LoongArch: Add atomic operations for 32BIT/64BIT Huacai Chen
2025-11-18 11:27 ` [PATCH V2 02/14] LoongArch: Add adaptive CSR accessors " Huacai Chen
2025-11-18 11:27 ` [PATCH V2 03/14] LoongArch: Adjust common macro definitions " Huacai Chen
2025-11-18 11:27 ` [PATCH V2 04/14] LoongArch: Adjust boot & setup " Huacai Chen
2025-11-18 17:09   ` Yao Zi
2025-11-19  4:28     ` Huacai Chen
2025-11-19  6:03       ` Jiaxun Yang
2025-11-19  7:51         ` Huacai Chen
2025-11-19 14:28           ` Yao Zi
2025-11-19 14:43             ` Huacai Chen
2025-11-18 11:27 ` [PATCH V2 05/14] LoongArch: Adjust memory management " Huacai Chen
2025-11-18 11:27 ` [PATCH V2 06/14] LoongArch: Adjust process " Huacai Chen
2025-11-18 11:27 ` [PATCH V2 07/14] LoongArch: Adjust time routines " Huacai Chen
2025-11-18 11:27 ` [PATCH V2 08/14] LoongArch: Adjust module loader " Huacai Chen
2025-11-18 11:27 ` [PATCH V2 09/14] LoongArch: Adjust system call " Huacai Chen
2025-11-20 10:40   ` WANG Xuerui
2025-11-20 12:05     ` Huacai Chen
2025-11-18 11:27 ` [PATCH V2 10/14] LoongArch: Adjust user accessors " Huacai Chen
2025-11-18 11:27 ` [PATCH V2 11/14] LoongArch: Adjust misc routines " Huacai Chen
2025-11-20 10:45   ` WANG Xuerui
2025-11-20 12:04     ` Huacai Chen
2025-11-18 11:27 ` [PATCH V2 12/14] LoongArch: Adjust VDSO/VSYSCALL " Huacai Chen
2025-11-18 13:41   ` Arnd Bergmann
2025-11-18 14:34     ` Huacai Chen
2025-11-18 11:27 ` [PATCH V2 13/14] LoongArch: Adjust default config files " Huacai Chen
2025-11-18 13:45   ` Arnd Bergmann
2025-11-19  8:01     ` Huacai Chen
2025-11-19  8:13       ` Arnd Bergmann
2025-11-19 14:13         ` Huacai Chen
2025-11-20  8:11   ` Thomas Weißschuh
2025-11-20  8:16     ` Huacai Chen
2025-11-20  8:26       ` Thomas Weißschuh
2025-11-20  8:54         ` Huacai Chen
2025-11-18 11:27 ` [PATCH V2 14/14] LoongArch: Adjust build infrastructure " Huacai Chen
2025-11-18 14:07 ` [PATCH V2 00/14] LoongArch: Add basic LoongArch32 support Arnd Bergmann
2025-11-18 14:30   ` Huacai Chen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox