From 0b6c8e21157fb6dfa35163fdfe5c10387bcc6c41 Mon Sep 17 00:00:00 2001 From: Kexin Sun Date: Sat, 21 Mar 2026 18:58:31 +0800 Subject: [PATCH 01/12] parisc: update outdated comments for renamed ccio_alloc_consistent() The function ccio_alloc_consistent() was renamed to ccio_alloc() by commit 79387179e2e4 ("parisc: convert to dma_map_ops"). Update the three stale references in ccio-dma.c. Also replace the obsolete PCI_DMA_TODEVICE constant name with DMA_TO_DEVICE in a nearby comment to match the code. Assisted-by: unnamed:deepseek-v3.2 coccinelle Signed-off-by: Kexin Sun Signed-off-by: Helge Deller --- drivers/parisc/ccio-dma.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index d5b95e63c24e..dc1b6d11f9ab 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -503,8 +503,8 @@ typedef unsigned long space_t; /* -** Use direction (ie PCI_DMA_TODEVICE) to pick hint. -** ccio_alloc_consistent() depends on this to get SAFE_DMA +** Use direction (ie DMA_TO_DEVICE) to pick hint. +** ccio_alloc() depends on this to get SAFE_DMA ** when it passes in BIDIRECTIONAL flag. */ static u32 hint_lookup[] = { @@ -865,8 +865,8 @@ ccio_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag, * ccio_free - Free a consistent DMA mapping. * @dev: The PCI device. * @size: The length of the DMA region. - * @cpu_addr: The cpu address returned from the ccio_alloc_consistent. - * @dma_handle: The device address returned from the ccio_alloc_consistent. + * @cpu_addr: The cpu address returned from ccio_alloc(). + * @dma_handle: The device address returned from ccio_alloc(). * @attrs: attributes * * This function implements the pci_free_consistent function. From 3dd31a370c1dccb580f729af7c580ccb1ae3c0c9 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 10 Apr 2026 16:12:31 +0200 Subject: [PATCH 02/12] parisc: Drop ip_fast_csum() inline assembly implementation The assembly code of ip_fast_csum() triggers unaligned access warnings if the IP header isn't correctly aligned: Kernel: unaligned access to 0x173d22e76 in inet_gro_receive+0xbc/0x2e8 (iir 0x0e8810b6) Kernel: unaligned access to 0x173d22e7e in inet_gro_receive+0xc4/0x2e8 (iir 0x0e88109a) Kernel: unaligned access to 0x173d22e82 in inet_gro_receive+0xc8/0x2e8 (iir 0x0e90109d) Kernel: unaligned access to 0x173d22e7a in inet_gro_receive+0xd0/0x2e8 (iir 0x0e9810b8) Kernel: unaligned access to 0x173d22e86 in inet_gro_receive+0xdc/0x2e8 (iir 0x0e8810b8) We have the option to a) ignore the warnings, b) work around it by adding more code to check for alignment, or c) to switch to the generic implementation and rely on the compiler to optimize the code. Let's go with c), because a) isn't nice, and b) would effectively lead to an implementation which is basically equal to c). Signed-off-by: Helge Deller Cc: stable@vger.kernel.org # v7.0+ --- arch/parisc/Kconfig | 3 + arch/parisc/include/asm/checksum.h | 89 +-------------------------- arch/parisc/lib/Makefile | 2 +- arch/parisc/lib/checksum.c | 99 ------------------------------ 4 files changed, 6 insertions(+), 187 deletions(-) delete mode 100644 arch/parisc/lib/checksum.c diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 62d5a89d5c7b..d7ee2f18bccd 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -130,6 +130,9 @@ config GENERIC_BUG config GENERIC_BUG_RELATIVE_POINTERS bool +config GENERIC_CSUM + def_bool y + config GENERIC_HWEIGHT bool default y diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h index 2aceebcd695c..382758808726 100644 --- a/arch/parisc/include/asm/checksum.h +++ b/arch/parisc/include/asm/checksum.h @@ -4,73 +4,7 @@ #include -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -extern __wsum csum_partial(const void *, int, __wsum); - -/* - * Optimized for IP headers, which always checksum on 4 octet boundaries. - * - * Written by Randolph Chung , and then mucked with by - * LaMont Jones - */ -static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) -{ - unsigned int sum; - unsigned long t0, t1, t2; - - __asm__ __volatile__ ( -" ldws,ma 4(%1), %0\n" -" addib,<= -4, %2, 2f\n" -"\n" -" ldws 4(%1), %4\n" -" ldws 8(%1), %5\n" -" add %0, %4, %0\n" -" ldws,ma 12(%1), %3\n" -" addc %0, %5, %0\n" -" addc %0, %3, %0\n" -"1: ldws,ma 4(%1), %3\n" -" addib,> -1, %2, 1b\n" -" addc %0, %3, %0\n" -"\n" -" extru %0, 31, 16, %4\n" -" extru %0, 15, 16, %5\n" -" addc %4, %5, %0\n" -" extru %0, 15, 16, %5\n" -" add %0, %5, %0\n" -" subi -1, %0, %0\n" -"2:\n" - : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (t0), "=r" (t1), "=r" (t2) - : "1" (iph), "2" (ihl) - : "memory"); - - return (__force __sum16)sum; -} - -/* - * Fold a partial checksum - */ -static inline __sum16 csum_fold(__wsum csum) -{ - u32 sum = (__force u32)csum; - /* add the swapped two 16-bit halves of sum, - a possible carry from adding the two 16-bit halves, - will carry from the lower half into the upper half, - giving us the correct sum in the upper half. */ - sum += (sum << 16) + (sum >> 16); - return (__force __sum16)(~sum >> 16); -} - +#define csum_tcpudp_nofold csum_tcpudp_nofold static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, __u8 proto, __wsum sum) @@ -85,26 +19,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, return sum; } -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ -static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - __u32 len, __u8 proto, - __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -} - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ -static inline __sum16 ip_compute_csum(const void *buf, int len) -{ - return csum_fold (csum_partial(buf, len, 0)); -} - +#include #define _HAVE_ARCH_IPV6_CSUM static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, diff --git a/arch/parisc/lib/Makefile b/arch/parisc/lib/Makefile index 7b197667faf6..d5975d1fb406 100644 --- a/arch/parisc/lib/Makefile +++ b/arch/parisc/lib/Makefile @@ -3,7 +3,7 @@ # Makefile for parisc-specific library files # -lib-y := lusercopy.o bitops.o checksum.o io.o memset.o memcpy.o \ +lib-y := lusercopy.o bitops.o io.o memset.o memcpy.o \ ucmpdi2.o delay.o obj-y := iomap.o diff --git a/arch/parisc/lib/checksum.c b/arch/parisc/lib/checksum.c deleted file mode 100644 index 59d8c15d81bd..000000000000 --- a/arch/parisc/lib/checksum.c +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * MIPS specific IP/TCP/UDP checksumming routines - * - * Authors: Ralf Baechle, - * Lots of code moved from tcp.c and ip.c; see those files - * for more names. - */ -#include -#include - -#include -#include -#include -#include - -#define addc(_t,_r) \ - __asm__ __volatile__ ( \ -" add %0, %1, %0\n" \ -" addc %0, %%r0, %0\n" \ - : "=r"(_t) \ - : "r"(_r), "0"(_t)); - -static inline unsigned int do_csum(const unsigned char * buff, int len) -{ - int odd, count; - unsigned int result = 0; - - if (len <= 0) - goto out; - odd = 1 & (unsigned long) buff; - if (odd) { - result = be16_to_cpu(*buff); - len--; - buff++; - } - count = len >> 1; /* nr of 16-bit words.. */ - if (count) { - if (2 & (unsigned long) buff) { - result += *(unsigned short *) buff; - count--; - len -= 2; - buff += 2; - } - count >>= 1; /* nr of 32-bit words.. */ - if (count) { - while (count >= 4) { - unsigned int r1, r2, r3, r4; - r1 = *(unsigned int *)(buff + 0); - r2 = *(unsigned int *)(buff + 4); - r3 = *(unsigned int *)(buff + 8); - r4 = *(unsigned int *)(buff + 12); - addc(result, r1); - addc(result, r2); - addc(result, r3); - addc(result, r4); - count -= 4; - buff += 16; - } - while (count) { - unsigned int w = *(unsigned int *) buff; - count--; - buff += 4; - addc(result, w); - } - result = (result & 0xffff) + (result >> 16); - } - if (len & 2) { - result += *(unsigned short *) buff; - buff += 2; - } - } - if (len & 1) - result += le16_to_cpu(*buff); - result = csum_from32to16(result); - if (odd) - result = swab16(result); -out: - return result; -} - -/* - * computes a partial checksum, e.g. for TCP/UDP fragments - */ -/* - * why bother folding? - */ -__wsum csum_partial(const void *buff, int len, __wsum sum) -{ - unsigned int result = do_csum(buff, len); - addc(result, sum); - return (__force __wsum)csum_from32to16(result); -} - -EXPORT_SYMBOL(csum_partial); From da3680f564bd787ce974f9931e6e924d908b3b2a Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 7 Apr 2026 23:56:28 +0200 Subject: [PATCH 03/12] parisc: _llseek syscall is only available for 32-bit userspace Cc: stable@vger.kernel.org Signed-off-by: Helge Deller --- arch/parisc/kernel/syscalls/syscall.tbl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl index f6e2d0379d57..c6331dad9461 100644 --- a/arch/parisc/kernel/syscalls/syscall.tbl +++ b/arch/parisc/kernel/syscalls/syscall.tbl @@ -154,7 +154,7 @@ # 137 was afs_syscall 138 common setfsuid sys_setfsuid 139 common setfsgid sys_setfsgid -140 common _llseek sys_llseek +140 32 _llseek sys_llseek 141 common getdents sys_getdents compat_sys_getdents 142 common _newselect sys_select compat_sys_select 143 common flock sys_flock From 97bfda452054ae0c20ab5318337e9b95ed32f616 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 8 Apr 2026 00:01:28 +0200 Subject: [PATCH 04/12] parisc: Avoid compat syscalls when COMPAT=n Drop unnecessary code and syscall tables when we run a 64-bit kernel with conpat mode disabled. Signed-off-by: Helge Deller --- arch/parisc/kernel/syscall.S | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index f58c4bccfbce..e11c88c34eb2 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -241,7 +241,7 @@ linux_gateway_entry: /* Note! We cannot use the syscall table that is mapped nearby since the gateway page is mapped execute-only. */ -#ifdef CONFIG_64BIT +#ifdef CONFIG_COMPAT ldil L%sys_call_table, %r1 or,ev %r2,%r2,%r2 ldil L%sys_call_table64, %r1 @@ -250,7 +250,7 @@ linux_gateway_entry: ldo R%sys_call_table64(%r1), %r19 #else load32 sys_call_table, %r19 -#endif +#endif comiclr,>> __NR_Linux_syscalls, %r20, %r0 b,n .Lsyscall_nosys @@ -374,7 +374,7 @@ tracesys_next: /* Note! We cannot use the syscall table that is mapped nearby since the gateway page is mapped execute-only. */ -#ifdef CONFIG_64BIT +#ifdef CONFIG_COMPAT LDREG TASK_PT_GR30(%r1), %r19 /* get users sp back */ extrd,u %r19,63,1,%r2 /* W hidden in bottom bit */ @@ -1326,16 +1326,19 @@ ENTRY(lws_table) END(lws_table) /* End of lws table */ -#ifdef CONFIG_64BIT +#ifdef CONFIG_COMPAT #define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, compat) #else #define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native) #endif #define __SYSCALL(nr, entry) ASM_ULONG_INSN entry + .align 8 ENTRY(sys_call_table) .export sys_call_table,data +#if defined(CONFIG_COMPAT) || !defined(CONFIG_64BIT) #include /* 32-bit syscalls */ +#endif END(sys_call_table) #ifdef CONFIG_64BIT From b5d5faba0f774f3216d8d699e130b01021e79f6c Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 8 Apr 2026 00:03:41 +0200 Subject: [PATCH 05/12] parisc: is_compat_task() shall return false for COMPAT=n Signed-off-by: Helge Deller --- arch/parisc/include/asm/compat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h index 339d1b833fa7..13a5a55dec65 100644 --- a/arch/parisc/include/asm/compat.h +++ b/arch/parisc/include/asm/compat.h @@ -130,7 +130,7 @@ typedef compat_ulong_t compat_elf_gregset_t[COMPAT_ELF_NGREG]; static inline int __is_compat_task(struct task_struct *t) { - return test_tsk_thread_flag(t, TIF_32BIT); + return IS_ENABLED(CONFIG_COMPAT) && test_tsk_thread_flag(t, TIF_32BIT); } static inline int is_compat_task(void) From 7dc9ee6e5e22722f219e4cdcab37e2476d6baaf6 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 8 Apr 2026 00:04:55 +0200 Subject: [PATCH 06/12] parisc: Fix signal code to depend on CONFIG_COMPAT instead of CONFIG_64BIT The signal handler code used CONFIG_64BIT to decide if compat handling code should be compiled in. Fix it to use CONFIG_COMPAT instead. This allows to disable CONFIG_COMPAT even when running a 64-bit kernel. Signed-off-by: Helge Deller --- arch/parisc/kernel/signal.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index e8d27def6c52..64a62006bb15 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -80,7 +80,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) sigset_t set; unsigned long usp = (regs->gr[30] & ~(0x01UL)); unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE; -#ifdef CONFIG_64BIT +#ifdef CONFIG_COMPAT struct compat_rt_sigframe __user * compat_frame; if (is_compat_task()) @@ -96,7 +96,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) regs->orig_r28 = 1; /* no restarts for sigreturn */ -#ifdef CONFIG_64BIT +#ifdef CONFIG_COMPAT compat_frame = (struct compat_rt_sigframe __user *)frame; if (is_compat_task()) { @@ -112,7 +112,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) set_current_blocked(&set); /* Good thing we saved the old gr[30], eh? */ -#ifdef CONFIG_64BIT +#ifdef CONFIG_COMPAT if (is_compat_task()) { DBG(1, "%s: compat_frame->uc.uc_mcontext 0x%p\n", __func__, &compat_frame->uc.uc_mcontext); @@ -218,13 +218,13 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs, unsigned long haddr, sigframe_size; unsigned long start; int err = 0; -#ifdef CONFIG_64BIT +#ifdef CONFIG_COMPAT struct compat_rt_sigframe __user * compat_frame; #endif - + usp = (regs->gr[30] & ~(0x01UL)); sigframe_size = PARISC_RT_SIGFRAME_SIZE; -#ifdef CONFIG_64BIT +#ifdef CONFIG_COMPAT if (is_compat_task()) { /* The gcc alloca implementation leaves garbage in the upper 32 bits of sp */ usp = (compat_uint_t)usp; @@ -239,7 +239,7 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs, if (start >= TASK_SIZE_MAX - sigframe_size) return -EFAULT; -#ifdef CONFIG_64BIT +#ifdef CONFIG_COMPAT compat_frame = (struct compat_rt_sigframe __user *)frame; @@ -349,8 +349,8 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs, regs->gr[2] = rp; /* userland return pointer */ regs->gr[26] = ksig->sig; /* signal number */ - -#ifdef CONFIG_64BIT + +#ifdef CONFIG_COMPAT if (is_compat_task()) { regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */ regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */ From 35493b28e71c3e7d376f98e58bb3c227511177c1 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 8 Apr 2026 00:15:39 +0200 Subject: [PATCH 07/12] parisc: Fix default stack size when COMPAT=n The CONFIG_STACK_MAX_DEFAULT_SIZE_MB config option does not exist when CONFIG_COMPAT is disabled. Use default 1 GB stack in this case. Signed-off-by: Helge Deller --- arch/parisc/kernel/sys_parisc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index fcb0d8069139..1a676a9bf80c 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -50,9 +50,13 @@ static inline unsigned long COLOR_ALIGN(unsigned long addr, } +#ifdef CONFIG_COMPAT #define STACK_SIZE_DEFAULT (USER_WIDE_MODE \ ? (1 << 30) /* 1 GB */ \ : (CONFIG_STACK_MAX_DEFAULT_SIZE_MB*1024*1024)) +#else +#define STACK_SIZE_DEFAULT (1 << 30) +#endif unsigned long calc_max_stack_size(unsigned long stack_max) { From bc4021c4e992960f1b8902bd613630c1e8edf7e7 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 8 Apr 2026 00:17:03 +0200 Subject: [PATCH 08/12] parisc: Allow to disable COMPAT mode on 64-bit kernel Although we don't yet have a 64-bit userspace, allowing to disable the compat mode should be possible. Signed-off-by: Helge Deller --- arch/parisc/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index d7ee2f18bccd..3e929eb5a7fe 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -357,7 +357,8 @@ config ARCH_SPARSEMEM_DEFAULT source "kernel/Kconfig.hz" config COMPAT - def_bool y + bool "Kernel support for 32-bit binaries" + default 64BIT depends on 64BIT config AUDIT_ARCH From ba56cdf133646565dde354433bb80fcbd459474b Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 14 Apr 2026 18:28:03 +0200 Subject: [PATCH 09/12] parisc: Include 32-bit VDSO only when building for 32-bit or compat mode Signed-off-by: Helge Deller --- arch/parisc/include/asm/vdso.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/parisc/include/asm/vdso.h b/arch/parisc/include/asm/vdso.h index 81bc1d42802a..5501560f5ffe 100644 --- a/arch/parisc/include/asm/vdso.h +++ b/arch/parisc/include/asm/vdso.h @@ -7,7 +7,9 @@ #ifdef CONFIG_64BIT #include #endif +#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT) #include +#endif #define VDSO64_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso64_offset_##name)) #define VDSO32_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso32_offset_##name)) From 3dce917902056ca7e46685f86f1f94b5953092e2 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Wed, 8 Apr 2026 18:19:01 +0200 Subject: [PATCH 10/12] parisc: Allow to build without VDSO32 When building for 64-bit and without CONFIG_COMPAT, leave out the vdso32 binary. Signed-off-by: Helge Deller --- arch/parisc/Makefile | 6 ++++-- arch/parisc/kernel/Makefile | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index 48ae3c79557a..edab2a948352 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -176,10 +176,12 @@ prepare: vdso_prepare vdso_prepare: prepare0 $(if $(CONFIG_64BIT),$(Q)$(MAKE) \ $(build)=arch/parisc/kernel/vdso64 include/generated/vdso64-offsets.h) - $(Q)$(MAKE) $(build)=arch/parisc/kernel/vdso32 include/generated/vdso32-offsets.h + $(if $(CONFIG_PA11)$(CONFIG_COMPAT),$(Q)$(MAKE) \ + $(build)=arch/parisc/kernel/vdso32 include/generated/vdso32-offsets.h) endif -vdso-install-y += arch/parisc/kernel/vdso32/vdso32.so +vdso-install-$(CONFIG_PA11) += arch/parisc/kernel/vdso32/vdso32.so +vdso-install-$(CONFIG_COMPAT) += arch/parisc/kernel/vdso32/vdso32.so vdso-install-$(CONFIG_64BIT) += arch/parisc/kernel/vdso64/vdso64.so install: KBUILD_IMAGE := vmlinux diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile index 9157bc8bdf41..2f3441769ac5 100644 --- a/arch/parisc/kernel/Makefile +++ b/arch/parisc/kernel/Makefile @@ -47,4 +47,5 @@ obj-$(CONFIG_KEXEC_FILE) += kexec_file.o # vdso obj-y += vdso.o obj-$(CONFIG_64BIT) += vdso64/ -obj-y += vdso32/ +obj-$(CONFIG_PA11) += vdso32/ +obj-$(CONFIG_COMPAT) += vdso32/ From 1221365f55281349da4f4ba41c05b57cd15f5c28 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Tue, 7 Apr 2026 22:07:22 +0200 Subject: [PATCH 11/12] module.lds.S: Fix modules on 32-bit parisc architecture On the 32-bit parisc architecture, we always used the -ffunction-sections compiler option to tell the compiler to put the functions into seperate text sections. This is necessary, otherwise "big" kernel modules like ext4 or ipv6 fail to load because some branches won't be able to reach their stubs. Commit 1ba9f8979426 ("vmlinux.lds: Unify TEXT_MAIN, DATA_MAIN, and related macros") broke this for parisc because all text sections will get unconditionally merged now. Introduce the ARCH_WANTS_MODULES_TEXT_SECTIONS config option which avoids the text section merge for modules, and fix this issue by enabling this option by default for 32-bit parisc. Fixes: 1ba9f8979426 ("vmlinux.lds: Unify TEXT_MAIN, DATA_MAIN, and related macros") Cc: Josh Poimboeuf Cc: stable@vger.kernel.org # v6.19+ Suggested-by: Sami Tolvanen Reviewed-by: Petr Pavlu Signed-off-by: Helge Deller --- arch/Kconfig | 7 +++++++ arch/parisc/Kconfig | 1 + scripts/module.lds.S | 2 ++ 3 files changed, 10 insertions(+) diff --git a/arch/Kconfig b/arch/Kconfig index 334b69505381..4eb2e51e28f1 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -1127,6 +1127,13 @@ config ARCH_WANTS_MODULES_DATA_IN_VMALLOC For architectures like powerpc/32 which have constraints on module allocation and need to allocate module data outside of module area. +config ARCH_WANTS_MODULES_TEXT_SECTIONS + bool + help + For architectures like 32-bit parisc which require that functions in + modules have to keep code in own text sections (-ffunction-sections) + and to avoid merging all text into one big text section, + config ARCH_WANTS_EXECMEM_LATE bool help diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 3e929eb5a7fe..d3afac2f0d9b 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -8,6 +8,7 @@ config PARISC select HAVE_FUNCTION_GRAPH_TRACER select HAVE_SYSCALL_TRACEPOINTS select ARCH_WANT_FRAME_POINTERS + select ARCH_WANTS_MODULES_TEXT_SECTIONS if !64BIT select ARCH_HAS_CPU_CACHE_ALIASING select ARCH_HAS_DMA_ALLOC if PA11 select ARCH_HAS_DMA_OPS diff --git a/scripts/module.lds.S b/scripts/module.lds.S index 2dc4c8c3e667..b62683061d79 100644 --- a/scripts/module.lds.S +++ b/scripts/module.lds.S @@ -40,9 +40,11 @@ SECTIONS { __kcfi_traps 0 : { KEEP(*(.kcfi_traps)) } #endif +#ifndef CONFIG_ARCH_WANTS_MODULES_TEXT_SECTIONS .text 0 : { *(.text .text.[0-9a-zA-Z_]*) } +#endif .bss 0 : { *(.bss .bss.[0-9a-zA-Z_]*) From 707610bcccbd0327530938e33f3f33211a640a4e Mon Sep 17 00:00:00 2001 From: Guangshuo Li Date: Thu, 16 Apr 2026 01:05:15 +0800 Subject: [PATCH 12/12] parisc: led: fix reference leak on failed device registration When platform_device_register() fails in startup_leds(), the embedded struct device in platform_leds has already been initialized by device_initialize(), but the failure path only reports the error and does not drop the device reference for the current platform device: startup_leds() -> platform_device_register(&platform_leds) -> device_initialize(&platform_leds.dev) -> setup_pdev_dma_masks(&platform_leds) -> platform_device_add(&platform_leds) This leads to a reference leak when platform_device_register() fails. Fix this by calling platform_device_put() after reporting the error. The issue was identified by a static analysis tool I developed and confirmed by manual review. Fixes: 789e527adfc33 ("parisc: led: Rewrite LED/LCD driver to utilizize Linux LED subsystem") Cc: stable@vger.kernel.org Signed-off-by: Guangshuo Li Signed-off-by: Helge Deller --- drivers/parisc/led.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c index 016c9d5a60a8..b299fcc48b08 100644 --- a/drivers/parisc/led.c +++ b/drivers/parisc/led.c @@ -543,8 +543,10 @@ static void __init register_led_regions(void) static int __init startup_leds(void) { - if (platform_device_register(&platform_leds)) - printk(KERN_INFO "LED: failed to register LEDs\n"); + if (platform_device_register(&platform_leds)) { + pr_info("LED: failed to register LEDs\n"); + platform_device_put(&platform_leds); + } register_led_regions(); return 0; }