summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/Kconfig7
-rw-r--r--arch/parisc/Kconfig7
-rw-r--r--arch/parisc/Makefile6
-rw-r--r--arch/parisc/include/asm/checksum.h89
-rw-r--r--arch/parisc/include/asm/compat.h2
-rw-r--r--arch/parisc/include/asm/vdso.h2
-rw-r--r--arch/parisc/kernel/Makefile3
-rw-r--r--arch/parisc/kernel/signal.c18
-rw-r--r--arch/parisc/kernel/sys_parisc.c4
-rw-r--r--arch/parisc/kernel/syscall.S11
-rw-r--r--arch/parisc/kernel/syscalls/syscall.tbl2
-rw-r--r--arch/parisc/lib/Makefile2
-rw-r--r--arch/parisc/lib/checksum.c99
-rw-r--r--drivers/parisc/ccio-dma.c8
-rw-r--r--drivers/parisc/led.c6
-rw-r--r--scripts/module.lds.S2
16 files changed, 56 insertions, 212 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index fa1d4bc77877..e86880045158 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 62d5a89d5c7b..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
@@ -130,6 +131,9 @@ config GENERIC_BUG
config GENERIC_BUG_RELATIVE_POINTERS
bool
+config GENERIC_CSUM
+ def_bool y
+
config GENERIC_HWEIGHT
bool
default y
@@ -354,7 +358,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
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/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 <linux/in6.h>
-/*
- * 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 <tausq@debian.org>, and then mucked with by
- * LaMont Jones <lamont@debian.org>
- */
-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 <asm-generic/checksum.h>
#define _HAVE_ARCH_IPV6_CSUM
static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
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)
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 <generated/vdso64-offsets.h>
#endif
+#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
#include <generated/vdso32-offsets.h>
+#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))
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/
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 */
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)
{
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 <asm/syscall_table_32.h> /* 32-bit syscalls */
+#endif
END(sys_call_table)
#ifdef CONFIG_64BIT
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
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, <ralf@waldorf-gmbh.de>
- * Lots of code moved from tcp.c and ip.c; see those files
- * for more names.
- */
-#include <linux/module.h>
-#include <linux/types.h>
-
-#include <net/checksum.h>
-#include <asm/byteorder.h>
-#include <asm/string.h>
-#include <linux/uaccess.h>
-
-#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);
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.
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;
}
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_]*)