diff options
Diffstat (limited to 'arch/hexagon')
125 files changed, 1232 insertions, 3475 deletions
diff --git a/arch/hexagon/Kbuild b/arch/hexagon/Kbuild new file mode 100644 index 000000000000..8421baba1351 --- /dev/null +++ b/arch/hexagon/Kbuild @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-y += kernel/ mm/ lib/ diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig index 33a97929d055..d987ba368ed6 100644 --- a/arch/hexagon/Kconfig +++ b/arch/hexagon/Kconfig @@ -1,80 +1,67 @@ +# SPDX-License-Identifier: GPL-2.0 # Hexagon configuration comment "Linux Kernel Configuration for Hexagon" config HEXAGON def_bool y - select HAVE_OPROFILE - select USE_GENERIC_SMP_HELPERS if SMP + select ARCH_32BIT_OFF_T + select ARCH_HAS_SYNC_DMA_FOR_DEVICE + select ARCH_NO_PREEMPT + select ARCH_WANT_FRAME_POINTERS + select DMA_GLOBAL_POOL + select HAVE_PAGE_SIZE_4KB + select HAVE_PAGE_SIZE_16KB + select HAVE_PAGE_SIZE_64KB + select HAVE_PAGE_SIZE_256KB + select FRAME_POINTER # Other pending projects/to-do items. # select HAVE_REGS_AND_STACK_ACCESS_API # select HAVE_HW_BREAKPOINT if PERF_EVENTS # select ARCH_HAS_CPU_IDLE_WAIT - # select ARCH_WANT_OPTIONAL_GPIOLIB - # select ARCH_REQUIRE_GPIOLIB + # select GPIOLIB # select HAVE_CLK - # select GENERIC_PENDING_IRQ if SMP select GENERIC_ATOMIC64 select HAVE_PERF_EVENTS - select HAVE_GENERIC_HARDIRQS # GENERIC_ALLOCATOR is used by dma_alloc_coherent() select GENERIC_ALLOCATOR + select GENERIC_IRQ_PROBE select GENERIC_IRQ_SHOW select HAVE_ARCH_KGDB select HAVE_ARCH_TRACEHOOK - select NO_IOPORT - select GENERIC_IOMAP + select NEED_SG_DMA_LENGTH + select GENERIC_IOREMAP select GENERIC_SMP_IDLE_THREAD select STACKTRACE_SUPPORT - select KTIME_SCALAR - select GENERIC_CLOCKEVENTS select GENERIC_CLOCKEVENTS_BROADCAST + select LOCK_MM_AND_FIND_VMA select MODULES_USE_ELF_RELA select GENERIC_CPU_DEVICES - ---help--- + select ARCH_WANT_LD_ORPHAN_WARN + select TRACE_IRQFLAGS_SUPPORT + help Qualcomm Hexagon is a processor architecture designed for high performance and low power across a wide variety of applications. config HEXAGON_PHYS_OFFSET def_bool y - ---help--- + help Platforms that don't load the kernel at zero set this. -config FRAME_POINTER - def_bool y - config LOCKDEP_SUPPORT def_bool y -config PCI - def_bool n - config EARLY_PRINTK def_bool y config MMU def_bool y -config TRACE_IRQFLAGS_SUPPORT +config NO_IOPORT_MAP def_bool y config GENERIC_CSUM def_bool y -# -# Use the generic interrupt handling code in kernel/irq/: -# -config GENERIC_IRQ_PROBE - def_bool y - -config NEED_SG_DMA_LENGTH - def_bool y - -config RWSEM_GENERIC_SPINLOCK - def_bool n - -config RWSEM_XCHGADD_ALGORITHM - def_bool y - config GENERIC_HWEIGHT def_bool y @@ -94,7 +81,7 @@ choice config HEXAGON_COMET bool "Comet Board" - ---help--- + help Support for the Comet platform. endchoice @@ -115,7 +102,7 @@ config CMDLINE config SMP bool "Multi-Processing support" - ---help--- + help Enables SMP support in the kernel. If unsure, say "Y" config NR_CPUS @@ -123,7 +110,7 @@ config NR_CPUS range 2 6 if SMP default "1" if !SMP default "6" if SMP - ---help--- + help This allows you to specify the maximum number of CPUs which this kernel will support. The maximum supported value is 6 and the minimum value which makes sense is 2. @@ -131,45 +118,6 @@ config NR_CPUS This is purely to save memory - each supported CPU adds approximately eight kilobytes to the kernel image. -choice - prompt "Kernel page size" - default PAGE_SIZE_4KB - ---help--- - Changes the default page size; use with caution. - -config PAGE_SIZE_4KB - bool "4KB" - -config PAGE_SIZE_16KB - bool "16KB" - -config PAGE_SIZE_64KB - bool "64KB" - -config PAGE_SIZE_256KB - bool "256KB" - -endchoice - -source "mm/Kconfig" - source "kernel/Kconfig.hz" endmenu - -source "init/Kconfig" -source "drivers/Kconfig" -source "fs/Kconfig" - -menu "Executable File Formats" -source "fs/Kconfig.binfmt" -endmenu - -source "net/Kconfig" -source "security/Kconfig" -source "crypto/Kconfig" -source "lib/Kconfig" - -menu "Kernel hacking" -source "lib/Kconfig.debug" -endmenu diff --git a/arch/hexagon/Kconfig.debug b/arch/hexagon/Kconfig.debug new file mode 100644 index 000000000000..295942fe3fd5 --- /dev/null +++ b/arch/hexagon/Kconfig.debug @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +# dummy file, do not delete diff --git a/arch/hexagon/Makefile b/arch/hexagon/Makefile index 207711a0fd0c..ff172cbe5881 100644 --- a/arch/hexagon/Makefile +++ b/arch/hexagon/Makefile @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 # Makefile for the Hexagon arch KBUILD_DEFCONFIG = comet_defconfig @@ -9,11 +10,14 @@ LDFLAGS_vmlinux += -G0 # Do not use single-byte enums; these will overflow. KBUILD_CFLAGS += -fno-short-enums +# We must use long-calls: +KBUILD_CFLAGS += -mlong-calls + # Modules must use either long-calls, or use pic/plt. # Use long-calls for now, it's easier. And faster. -# CFLAGS_MODULE += -fPIC -# LDFLAGS_MODULE += -shared -CFLAGS_MODULE += -mlong-calls +# KBUILD_CFLAGS_MODULE += -fPIC +# KBUILD_LDFLAGS_MODULE += -shared +KBUILD_CFLAGS_MODULE += -mlong-calls cflags-y += $(call cc-option,-mv${CONFIG_HEXAGON_ARCH_VERSION}) aflags-y += $(call cc-option,-mv${CONFIG_HEXAGON_ARCH_VERSION}) @@ -21,9 +25,7 @@ ldflags-y += $(call cc-option,-mv${CONFIG_HEXAGON_ARCH_VERSION}) KBUILD_CFLAGS += $(cflags-y) KBUILD_AFLAGS += $(aflags-y) - -# no KBUILD_LDFLAGS? -LDFLAGS += $(ldflags-y) +KBUILD_LDFLAGS += $(ldflags-y) # Thread-info register will be r19. This value is not configureable; # it is hard-coded in several files. @@ -31,11 +33,8 @@ TIR_NAME := r19 KBUILD_CFLAGS += -ffixed-$(TIR_NAME) -DTHREADINFO_REG=$(TIR_NAME) -D__linux__ KBUILD_AFLAGS += -DTHREADINFO_REG=$(TIR_NAME) -LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) -libs-y += $(LIBGCC) - -head-y := arch/hexagon/kernel/head.o - -core-y += arch/hexagon/kernel/ \ - arch/hexagon/mm/ \ - arch/hexagon/lib/ +# Disable HexagonConstExtenders pass for LLVM versions prior to 19.1.0 +# https://github.com/llvm/llvm-project/issues/99714 +ifneq ($(call clang-min-version, 190100),y) +KBUILD_CFLAGS += -mllvm -hexagon-cext=false +endif diff --git a/arch/hexagon/configs/comet_defconfig b/arch/hexagon/configs/comet_defconfig index e324f65f41e7..83b7626550c8 100644 --- a/arch/hexagon/configs/comet_defconfig +++ b/arch/hexagon/configs/comet_defconfig @@ -1,7 +1,6 @@ CONFIG_SMP=y CONFIG_DEFAULT_MMAP_MIN_ADDR=0 CONFIG_HZ_100=y -CONFIG_EXPERIMENTAL=y CONFIG_CROSS_COMPILE="hexagon-" CONFIG_LOCALVERSION="-smp" # CONFIG_LOCALVERSION_AUTO is not set @@ -15,7 +14,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=18 CONFIG_BLK_DEV_INITRD=y -CONFIG_EMBEDDED=y +CONFIG_EXPERT=y # CONFIG_VM_EVENT_COUNTERS is not set # CONFIG_BLK_DEV_BSG is not set CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" @@ -35,7 +34,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_SERIO is not set # CONFIG_CONSOLE_TRANSLATIONS is not set CONFIG_LEGACY_PTY_COUNT=64 -# CONFIG_DEVKMEM is not set # CONFIG_HW_RANDOM is not set CONFIG_SPI=y CONFIG_SPI_DEBUG=y @@ -48,10 +46,9 @@ CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y CONFIG_QUOTA=y CONFIG_PROC_KCORE=y CONFIG_TMPFS=y @@ -72,14 +69,8 @@ CONFIG_INET=y # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set CONFIG_CRYPTO_MD5=y -# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_HW is not set -CONFIG_CRC_CCITT=y -CONFIG_CRC16=y -CONFIG_CRC_T10DIF=y -CONFIG_LIBCRC32C=y CONFIG_FRAME_WARN=0 CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_FS=y # CONFIG_SCHED_DEBUG is not set -CONFIG_DEBUG_INFO=y diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild index 1da17caac23c..1efa1e993d4b 100644 --- a/arch/hexagon/include/asm/Kbuild +++ b/arch/hexagon/include/asm/Kbuild @@ -1,55 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 +syscall-y += syscall_table_32.h -header-y += ucontext.h - -generic-y += auxvec.h -generic-y += bug.h -generic-y += bugs.h -generic-y += clkdev.h -generic-y += cputime.h -generic-y += current.h -generic-y += device.h -generic-y += div64.h -generic-y += emergency-restart.h -generic-y += errno.h -generic-y += fb.h -generic-y += fcntl.h -generic-y += ftrace.h -generic-y += hardirq.h -generic-y += hw_irq.h -generic-y += ioctl.h -generic-y += ioctls.h +generic-y += extable.h generic-y += iomap.h -generic-y += ipcbuf.h -generic-y += irq_regs.h -generic-y += kdebug.h -generic-y += kmap_types.h -generic-y += local64.h -generic-y += local.h -generic-y += mman.h -generic-y += msgbuf.h -generic-y += pci.h -generic-y += percpu.h -generic-y += poll.h -generic-y += posix_types.h -generic-y += resource.h -generic-y += rwsem.h -generic-y += scatterlist.h -generic-y += sections.h -generic-y += segment.h -generic-y += sembuf.h -generic-y += shmbuf.h -generic-y += shmparam.h -generic-y += siginfo.h -generic-y += sizes.h -generic-y += socket.h -generic-y += sockios.h -generic-y += statfs.h -generic-y += stat.h -generic-y += termbits.h -generic-y += termios.h -generic-y += topology.h -generic-y += trace_clock.h -generic-y += types.h -generic-y += ucontext.h -generic-y += unaligned.h -generic-y += xor.h +generic-y += kvm_para.h +generic-y += mcs_spinlock.h +generic-y += text-patching.h diff --git a/arch/hexagon/include/asm/atomic.h b/arch/hexagon/include/asm/atomic.h index 8a64ff2337f6..2447d083c432 100644 --- a/arch/hexagon/include/asm/atomic.h +++ b/arch/hexagon/include/asm/atomic.h @@ -1,22 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Atomic operations for the Hexagon architecture * * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_ATOMIC_H @@ -24,109 +10,103 @@ #include <linux/types.h> #include <asm/cmpxchg.h> +#include <asm/barrier.h> -#define ATOMIC_INIT(i) { (i) } -#define atomic_set(v, i) ((v)->counter = (i)) - -/** - * atomic_read - reads a word, atomically - * @v: pointer to atomic value - * - * Assumes all word reads on our architecture are atomic. - */ -#define atomic_read(v) ((v)->counter) - -/** - * atomic_xchg - atomic - * @v: pointer to memory to change - * @new: new value (technically passed in a register -- see xchg) - */ -#define atomic_xchg(v, new) (xchg(&((v)->counter), (new))) - +/* Normal writes in our arch don't clear lock reservations */ -/** - * atomic_cmpxchg - atomic compare-and-exchange values - * @v: pointer to value to change - * @old: desired old value to match - * @new: new value to put in - * - * Parameters are then pointer, value-in-register, value-in-register, - * and the output is the old value. - * - * Apparently this is complicated for archs that don't support - * the memw_locked like we do (or it's broken or whatever). - * - * Kind of the lynchpin of the rest of the generically defined routines. - * Remember V2 had that bug with dotnew predicate set by memw_locked. - * - * "old" is "expected" old val, __oldval is actual old value - */ -static inline int atomic_cmpxchg(atomic_t *v, int old, int new) +static inline void arch_atomic_set(atomic_t *v, int new) { - int __oldval; - asm volatile( - "1: %0 = memw_locked(%1);\n" - " { P0 = cmp.eq(%0,%2);\n" - " if (!P0.new) jump:nt 2f; }\n" - " memw_locked(%1,P0) = %3;\n" + "1: r6 = memw_locked(%0);\n" + " memw_locked(%0,p0) = %1;\n" " if (!P0) jump 1b;\n" - "2:\n" - : "=&r" (__oldval) - : "r" (&v->counter), "r" (old), "r" (new) - : "memory", "p0" + : + : "r" (&v->counter), "r" (new) + : "memory", "p0", "r6" ); - - return __oldval; } -static inline int atomic_add_return(int i, atomic_t *v) -{ - int output; - - __asm__ __volatile__ ( - "1: %0 = memw_locked(%1);\n" - " %0 = add(%0,%2);\n" - " memw_locked(%1,P3)=%0;\n" - " if !P3 jump 1b;\n" - : "=&r" (output) - : "r" (&v->counter), "r" (i) - : "memory", "p3" - ); - return output; +#define arch_atomic_set_release(v, i) arch_atomic_set((v), (i)) + +#define arch_atomic_read(v) READ_ONCE((v)->counter) + +#define ATOMIC_OP(op) \ +static inline void arch_atomic_##op(int i, atomic_t *v) \ +{ \ + int output; \ + \ + __asm__ __volatile__ ( \ + "1: %0 = memw_locked(%1);\n" \ + " %0 = "#op "(%0,%2);\n" \ + " memw_locked(%1,P3)=%0;\n" \ + " if (!P3) jump 1b;\n" \ + : "=&r" (output) \ + : "r" (&v->counter), "r" (i) \ + : "memory", "p3" \ + ); \ +} \ + +#define ATOMIC_OP_RETURN(op) \ +static inline int arch_atomic_##op##_return(int i, atomic_t *v) \ +{ \ + int output; \ + \ + __asm__ __volatile__ ( \ + "1: %0 = memw_locked(%1);\n" \ + " %0 = "#op "(%0,%2);\n" \ + " memw_locked(%1,P3)=%0;\n" \ + " if (!P3) jump 1b;\n" \ + : "=&r" (output) \ + : "r" (&v->counter), "r" (i) \ + : "memory", "p3" \ + ); \ + return output; \ +} +#define ATOMIC_FETCH_OP(op) \ +static inline int arch_atomic_fetch_##op(int i, atomic_t *v) \ +{ \ + int output, val; \ + \ + __asm__ __volatile__ ( \ + "1: %0 = memw_locked(%2);\n" \ + " %1 = "#op "(%0,%3);\n" \ + " memw_locked(%2,P3)=%1;\n" \ + " if (!P3) jump 1b;\n" \ + : "=&r" (output), "=&r" (val) \ + : "r" (&v->counter), "r" (i) \ + : "memory", "p3" \ + ); \ + return output; \ } -#define atomic_add(i, v) atomic_add_return(i, (v)) +#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) ATOMIC_FETCH_OP(op) -static inline int atomic_sub_return(int i, atomic_t *v) -{ - int output; - __asm__ __volatile__ ( - "1: %0 = memw_locked(%1);\n" - " %0 = sub(%0,%2);\n" - " memw_locked(%1,P3)=%0\n" - " if !P3 jump 1b;\n" - : "=&r" (output) - : "r" (&v->counter), "r" (i) - : "memory", "p3" - ); - return output; -} +ATOMIC_OPS(add) +ATOMIC_OPS(sub) -#define atomic_sub(i, v) atomic_sub_return(i, (v)) +#define arch_atomic_add_return arch_atomic_add_return +#define arch_atomic_sub_return arch_atomic_sub_return +#define arch_atomic_fetch_add arch_atomic_fetch_add +#define arch_atomic_fetch_sub arch_atomic_fetch_sub -/** - * __atomic_add_unless - add unless the number is a given value - * @v: pointer to value - * @a: amount to add - * @u: unless value is equal to u - * - * Returns old value. - * - */ +#undef ATOMIC_OPS +#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_FETCH_OP(op) + +ATOMIC_OPS(and) +ATOMIC_OPS(or) +ATOMIC_OPS(xor) + +#define arch_atomic_fetch_and arch_atomic_fetch_and +#define arch_atomic_fetch_or arch_atomic_fetch_or +#define arch_atomic_fetch_xor arch_atomic_fetch_xor -static inline int __atomic_add_unless(atomic_t *v, int a, int u) +#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 __oldval; register int tmp; @@ -140,7 +120,7 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u) " }" " memw_locked(%2, p3) = %1;" " {" - " if !p3 jump 1b;" + " if (!p3) jump 1b;" " }" "2:" : "=&r" (__oldval), "=&r" (tmp) @@ -149,19 +129,6 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u) ); return __oldval; } - -#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) - -#define atomic_inc(v) atomic_add(1, (v)) -#define atomic_dec(v) atomic_sub(1, (v)) - -#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0) -#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0) -#define atomic_sub_and_test(i, v) (atomic_sub_return(i, (v)) == 0) -#define atomic_add_negative(i, v) (atomic_add_return(i, (v)) < 0) - - -#define atomic_inc_return(v) (atomic_add_return(1, v)) -#define atomic_dec_return(v) (atomic_sub_return(1, v)) +#define arch_atomic_fetch_add_unless arch_atomic_fetch_add_unless #endif diff --git a/arch/hexagon/include/asm/barrier.h b/arch/hexagon/include/asm/barrier.h deleted file mode 100644 index 1041a8e70ce8..000000000000 --- a/arch/hexagon/include/asm/barrier.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Memory barrier definitions for the Hexagon architecture - * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef _ASM_BARRIER_H -#define _ASM_BARRIER_H - -#define rmb() barrier() -#define read_barrier_depends() barrier() -#define wmb() barrier() -#define mb() barrier() -#define smp_rmb() barrier() -#define smp_read_barrier_depends() barrier() -#define smp_wmb() barrier() -#define smp_mb() barrier() -#define smp_mb__before_atomic_dec() barrier() -#define smp_mb__after_atomic_dec() barrier() -#define smp_mb__before_atomic_inc() barrier() -#define smp_mb__after_atomic_inc() barrier() - -/* Set a value and use a memory barrier. Used by the scheduler somewhere. */ -#define set_mb(var, value) \ - do { var = value; mb(); } while (0) - -#endif /* _ASM_BARRIER_H */ diff --git a/arch/hexagon/include/asm/bitops.h b/arch/hexagon/include/asm/bitops.h index 9b1e4afbab3c..b23cb13833af 100644 --- a/arch/hexagon/include/asm/bitops.h +++ b/arch/hexagon/include/asm/bitops.h @@ -1,22 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Bit operations for the Hexagon architecture * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_BITOPS_H @@ -25,12 +11,10 @@ #include <linux/compiler.h> #include <asm/byteorder.h> #include <asm/atomic.h> +#include <asm/barrier.h> #ifdef __KERNEL__ -#define smp_mb__before_clear_bit() barrier() -#define smp_mb__after_clear_bit() barrier() - /* * The offset calculations for these are based on BITS_PER_LONG == 32 * (i.e. I get to shift by #5-2 (32 bits per long, 4 bytes per access), @@ -54,7 +38,7 @@ static inline int test_and_clear_bit(int nr, volatile void *addr) "1: R12 = memw_locked(R10);\n" " { P0 = tstbit(R12,R11); R12 = clrbit(R12,R11); }\n" " memw_locked(R10,P1) = R12;\n" - " {if !P1 jump 1b; %0 = mux(P0,#1,#0);}\n" + " {if (!P1) jump 1b; %0 = mux(P0,#1,#0);}\n" : "=&r" (oldval) : "r" (addr), "r" (nr) : "r10", "r11", "r12", "p0", "p1", "memory" @@ -78,7 +62,7 @@ static inline int test_and_set_bit(int nr, volatile void *addr) "1: R12 = memw_locked(R10);\n" " { P0 = tstbit(R12,R11); R12 = setbit(R12,R11); }\n" " memw_locked(R10,P1) = R12;\n" - " {if !P1 jump 1b; %0 = mux(P0,#1,#0);}\n" + " {if (!P1) jump 1b; %0 = mux(P0,#1,#0);}\n" : "=&r" (oldval) : "r" (addr), "r" (nr) : "r10", "r11", "r12", "p0", "p1", "memory" @@ -104,7 +88,7 @@ static inline int test_and_change_bit(int nr, volatile void *addr) "1: R12 = memw_locked(R10);\n" " { P0 = tstbit(R12,R11); R12 = togglebit(R12,R11); }\n" " memw_locked(R10,P1) = R12;\n" - " {if !P1 jump 1b; %0 = mux(P0,#1,#0);}\n" + " {if (!P1) jump 1b; %0 = mux(P0,#1,#0);}\n" : "=&r" (oldval) : "r" (addr), "r" (nr) : "r10", "r11", "r12", "p0", "p1", "memory" @@ -143,38 +127,45 @@ static inline void change_bit(int nr, volatile void *addr) * be atomic, particularly for things like slab_lock and slab_unlock. * */ -static inline void __clear_bit(int nr, volatile unsigned long *addr) +static __always_inline void +arch___clear_bit(unsigned long nr, volatile unsigned long *addr) { test_and_clear_bit(nr, addr); } -static inline void __set_bit(int nr, volatile unsigned long *addr) +static __always_inline void +arch___set_bit(unsigned long nr, volatile unsigned long *addr) { test_and_set_bit(nr, addr); } -static inline void __change_bit(int nr, volatile unsigned long *addr) +static __always_inline void +arch___change_bit(unsigned long nr, volatile unsigned long *addr) { test_and_change_bit(nr, addr); } /* Apparently, at least some of these are allowed to be non-atomic */ -static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr) +static __always_inline bool +arch___test_and_clear_bit(unsigned long nr, volatile unsigned long *addr) { return test_and_clear_bit(nr, addr); } -static inline int __test_and_set_bit(int nr, volatile unsigned long *addr) +static __always_inline bool +arch___test_and_set_bit(unsigned long nr, volatile unsigned long *addr) { return test_and_set_bit(nr, addr); } -static inline int __test_and_change_bit(int nr, volatile unsigned long *addr) +static __always_inline bool +arch___test_and_change_bit(unsigned long nr, volatile unsigned long *addr) { return test_and_change_bit(nr, addr); } -static inline int __test_bit(int nr, const volatile unsigned long *addr) +static __always_inline bool +arch_test_bit(unsigned long nr, const volatile unsigned long *addr) { int retval; @@ -188,7 +179,20 @@ static inline int __test_bit(int nr, const volatile unsigned long *addr) return retval; } -#define test_bit(nr, addr) __test_bit(nr, addr) +static __always_inline bool +arch_test_bit_acquire(unsigned long nr, const volatile unsigned long *addr) +{ + int retval; + + asm volatile( + "{P0 = tstbit(%1,%2); if (P0.new) %0 = #1; if (!P0.new) %0 = #0;}\n" + : "=&r" (retval) + : "r" (addr[BIT_WORD(nr)]), "r" (nr % BITS_PER_LONG) + : "p0", "memory" + ); + + return retval; +} /* * ffz - find first zero in word. @@ -196,7 +200,7 @@ static inline int __test_bit(int nr, const volatile unsigned long *addr) * * Undefined if no zero exists, so code should check against ~0UL first. */ -static inline long ffz(int x) +static inline long __attribute_const__ ffz(int x) { int r; @@ -213,7 +217,7 @@ static inline long ffz(int x) * This is defined the same way as ffs. * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. */ -static inline long fls(int x) +static inline __attribute_const__ int fls(unsigned int x) { int r; @@ -234,12 +238,12 @@ static inline long fls(int x) * the libc and compiler builtin ffs routines, therefore * differs in spirit from the above ffz (man ffs). */ -static inline long ffs(int x) +static inline __attribute_const__ int ffs(int x) { int r; asm("{ P0 = cmp.eq(%1,#0); %0 = ct0(%1);}\n" - "{ if P0 %0 = #0; if !P0 %0 = add(%0,#1);}\n" + "{ if (P0) %0 = #0; if (!P0) %0 = add(%0,#1);}\n" : "=&r" (r) : "r" (x) : "p0"); @@ -256,7 +260,7 @@ static inline long ffs(int x) * bits_per_long assumed to be 32 * numbering starts at 0 I think (instead of 1 like ffs) */ -static inline unsigned long __ffs(unsigned long word) +static inline __attribute_const__ unsigned long __ffs(unsigned long word) { int num; @@ -274,7 +278,7 @@ static inline unsigned long __ffs(unsigned long word) * Undefined if no set bit exists, so code should check against 0 first. * bits_per_long assumed to be 32 */ -static inline unsigned long __fls(unsigned long word) +static inline __attribute_const__ unsigned long __fls(unsigned long word) { int num; @@ -287,7 +291,7 @@ static inline unsigned long __fls(unsigned long word) } #include <asm-generic/bitops/lock.h> -#include <asm-generic/bitops/find.h> +#include <asm-generic/bitops/non-instrumented-non-atomic.h> #include <asm-generic/bitops/fls64.h> #include <asm-generic/bitops/sched.h> diff --git a/arch/hexagon/include/asm/cache.h b/arch/hexagon/include/asm/cache.h index f4ca594fdf8c..931719dfad28 100644 --- a/arch/hexagon/include/asm/cache.h +++ b/arch/hexagon/include/asm/cache.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Cache definitions for the Hexagon architecture * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * Copyright (c) 2010-2011,2014 The Linux Foundation. All rights reserved. */ #ifndef __ASM_CACHE_H @@ -25,10 +12,12 @@ #define L1_CACHE_SHIFT (5) #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) +#define ARCH_DMA_MINALIGN L1_CACHE_BYTES + #define __cacheline_aligned __aligned(L1_CACHE_BYTES) #define ____cacheline_aligned __aligned(L1_CACHE_BYTES) -/* See http://kerneltrap.org/node/15100 */ +/* See http://lwn.net/Articles/262554/ */ #define __read_mostly #endif diff --git a/arch/hexagon/include/asm/cacheflush.h b/arch/hexagon/include/asm/cacheflush.h index 49e0896ec240..bfff514a81c8 100644 --- a/arch/hexagon/include/asm/cacheflush.h +++ b/arch/hexagon/include/asm/cacheflush.h @@ -1,30 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Cache flush operations for the Hexagon architecture * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_CACHEFLUSH_H #define _ASM_CACHEFLUSH_H -#include <linux/cache.h> -#include <linux/mm.h> -#include <asm/string.h> -#include <asm-generic/cacheflush.h> +#include <linux/mm_types.h> /* Cache flushing: * @@ -34,7 +18,7 @@ * - flush_cache_range(vma, start, end) flushes a range of pages * - flush_icache_range(start, end) flush a range of instructions * - flush_dcache_page(pg) flushes(wback&invalidates) a page for dcache - * - flush_icache_page(vma, pg) flushes(invalidates) a page for icache + * - flush_icache_pages(vma, pg, nr) flushes(invalidates) nr pages for icache * * Need to doublecheck which one is really needed for ptrace stuff to work. */ @@ -45,12 +29,13 @@ * Flush Dcache range through current map. */ extern void flush_dcache_range(unsigned long start, unsigned long end); +#define flush_dcache_range flush_dcache_range /* * Flush Icache range through current map. */ -#undef flush_icache_range extern void flush_icache_range(unsigned long start, unsigned long end); +#define flush_icache_range flush_icache_range /* * Memory-management related flushes are there to ensure in non-physically @@ -73,27 +58,26 @@ extern void flush_cache_all_hexagon(void); * clean the cache when the PTE is set. * */ -static inline void update_mmu_cache(struct vm_area_struct *vma, - unsigned long address, pte_t *ptep) +static inline void update_mmu_cache_range(struct vm_fault *vmf, + struct vm_area_struct *vma, unsigned long address, + pte_t *ptep, unsigned int nr) { /* generic_ptrace_pokedata doesn't wind up here, does it? */ } -#undef copy_to_user_page -static inline void copy_to_user_page(struct vm_area_struct *vma, - struct page *page, - unsigned long vaddr, - void *dst, void *src, int len) -{ - memcpy(dst, src, len); - if (vma->vm_flags & VM_EXEC) { - flush_icache_range((unsigned long) dst, - (unsigned long) dst + len); - } -} +#define update_mmu_cache(vma, addr, ptep) \ + update_mmu_cache_range(NULL, vma, addr, ptep, 1) + +void copy_to_user_page(struct vm_area_struct *vma, struct page *page, + unsigned long vaddr, void *dst, void *src, int len); +#define copy_to_user_page copy_to_user_page +#define copy_from_user_page(vma, page, vaddr, dst, src, len) \ + memcpy(dst, src, len) extern void hexagon_inv_dcache_range(unsigned long start, unsigned long end); extern void hexagon_clean_dcache_range(unsigned long start, unsigned long end); +#include <asm-generic/cacheflush.h> + #endif diff --git a/arch/hexagon/include/asm/checksum.h b/arch/hexagon/include/asm/checksum.h index 46ec8a7fd65f..4bc6ad96c4c5 100644 --- a/arch/hexagon/include/asm/checksum.h +++ b/arch/hexagon/include/asm/checksum.h @@ -1,19 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_CHECKSUM_H @@ -23,27 +10,16 @@ unsigned int do_csum(const void *voidptr, int len); /* - * the same as csum_partial, but copies from src while it - * checksums - * - * here even more important to align src and dst on a 32-bit (or even - * better 64-bit) boundary - */ -#define csum_partial_copy_nocheck csum_partial_copy_nocheck -__wsum csum_partial_copy_nocheck(const void *src, void *dst, - int len, __wsum sum); - -/* * computes the checksum of the TCP/UDP pseudo-header * returns a 16-bit checksum, already complemented */ #define csum_tcpudp_nofold csum_tcpudp_nofold -__wsum csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, - unsigned short len, unsigned short proto, __wsum sum); +__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, + __u32 len, __u8 proto, __wsum sum); #define csum_tcpudp_magic csum_tcpudp_magic -__sum16 csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, - unsigned short len, unsigned short proto, __wsum sum); +__sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, + __u32 len, __u8 proto, __wsum sum); #include <asm-generic/checksum.h> diff --git a/arch/hexagon/include/asm/cmpxchg.h b/arch/hexagon/include/asm/cmpxchg.h index 9e7802911a57..9c58fb81f7fd 100644 --- a/arch/hexagon/include/asm/cmpxchg.h +++ b/arch/hexagon/include/asm/cmpxchg.h @@ -1,29 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * xchg/cmpxchg operations for the Hexagon architecture * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_CMPXCHG_H #define _ASM_CMPXCHG_H /* - * __xchg - atomically exchange a register and a memory location + * __arch_xchg - atomically exchange a register and a memory location * @x: value to swap * @ptr: pointer to memory * @size: size of the value @@ -33,8 +19,8 @@ * Note: there was an errata for V2 about .new's and memw_locked. * */ -static inline unsigned long __xchg(unsigned long x, volatile void *ptr, - int size) +static inline unsigned long +__arch_xchg(unsigned long x, volatile void *ptr, int size) { unsigned long retval; @@ -44,7 +30,7 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, __asm__ __volatile__ ( "1: %0 = memw_locked(%1);\n" /* load into retval */ " memw_locked(%1,P0) = %2;\n" /* store into memory */ - " if !P0 jump 1b;\n" + " if (!P0) jump 1b;\n" : "=&r" (retval) : "r" (ptr), "r" (x) : "memory", "p0" @@ -56,22 +42,21 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, * Atomically swap the contents of a register with memory. Should be atomic * between multiple CPU's and within interrupts on the same CPU. */ -#define xchg(ptr, v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v), (ptr), \ - sizeof(*(ptr)))) +#define arch_xchg(ptr, v) ((__typeof__(*(ptr)))__arch_xchg((unsigned long)(v), (ptr), \ + sizeof(*(ptr)))) /* * see rt-mutex-design.txt; cmpxchg supposedly checks if *ptr == A and swaps. * looks just like atomic_cmpxchg on our arch currently with a bunch of * variable casting. */ -#define __HAVE_ARCH_CMPXCHG 1 -#define cmpxchg(ptr, old, new) \ +#define arch_cmpxchg(ptr, old, new) \ ({ \ __typeof__(ptr) __ptr = (ptr); \ __typeof__(*(ptr)) __old = (old); \ __typeof__(*(ptr)) __new = (new); \ - __typeof__(*(ptr)) __oldval = 0; \ + __typeof__(*(ptr)) __oldval = (__typeof__(*(ptr))) 0; \ \ asm volatile( \ "1: %0 = memw_locked(%1);\n" \ diff --git a/arch/hexagon/include/asm/delay.h b/arch/hexagon/include/asm/delay.h index 53079719d667..2f24bbf9f375 100644 --- a/arch/hexagon/include/asm/delay.h +++ b/arch/hexagon/include/asm/delay.h @@ -1,19 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_DELAY_H @@ -21,6 +8,7 @@ #include <asm/param.h> +extern void __delay(unsigned long cycles); extern void __udelay(unsigned long usecs); #define udelay(usecs) __udelay((usecs)) diff --git a/arch/hexagon/include/asm/dma-mapping.h b/arch/hexagon/include/asm/dma-mapping.h deleted file mode 100644 index 85e9935660cb..000000000000 --- a/arch/hexagon/include/asm/dma-mapping.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * DMA operations for the Hexagon architecture - * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef _ASM_DMA_MAPPING_H -#define _ASM_DMA_MAPPING_H - -#include <linux/types.h> -#include <linux/cache.h> -#include <linux/mm.h> -#include <linux/scatterlist.h> -#include <linux/dma-mapping.h> -#include <linux/dma-debug.h> -#include <linux/dma-attrs.h> -#include <asm/io.h> - -struct device; -extern int bad_dma_address; - -extern struct dma_map_ops *dma_ops; - -#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) -#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) - -static inline struct dma_map_ops *get_dma_ops(struct device *dev) -{ - if (unlikely(dev == NULL)) - return NULL; - - return dma_ops; -} - -extern int dma_supported(struct device *dev, u64 mask); -extern int dma_set_mask(struct device *dev, u64 mask); -extern int dma_is_consistent(struct device *dev, dma_addr_t dma_handle); -extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, - enum dma_data_direction direction); - -#include <asm-generic/dma-mapping-common.h> - -static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) -{ - if (!dev->dma_mask) - return 0; - return addr + size - 1 <= *dev->dma_mask; -} - -static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) -{ - struct dma_map_ops *dma_ops = get_dma_ops(dev); - - if (dma_ops->mapping_error) - return dma_ops->mapping_error(dev, dma_addr); - - return (dma_addr == bad_dma_address); -} - -#define dma_alloc_coherent(d,s,h,f) dma_alloc_attrs(d,s,h,f,NULL) - -static inline void *dma_alloc_attrs(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag, - struct dma_attrs *attrs) -{ - void *ret; - struct dma_map_ops *ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - - ret = ops->alloc(dev, size, dma_handle, flag, attrs); - - debug_dma_alloc_coherent(dev, size, *dma_handle, ret); - - return ret; -} - -#define dma_free_coherent(d,s,c,h) dma_free_attrs(d,s,c,h,NULL) - -static inline void dma_free_attrs(struct device *dev, size_t size, - void *cpu_addr, dma_addr_t dma_handle, - struct dma_attrs *attrs) -{ - struct dma_map_ops *dma_ops = get_dma_ops(dev); - - BUG_ON(!dma_ops); - - dma_ops->free(dev, size, cpu_addr, dma_handle, attrs); - - debug_dma_free_coherent(dev, size, cpu_addr, dma_handle); -} - -#endif diff --git a/arch/hexagon/include/asm/dma.h b/arch/hexagon/include/asm/dma.h index 9e34ff49f3b7..686ae566a711 100644 --- a/arch/hexagon/include/asm/dma.h +++ b/arch/hexagon/include/asm/dma.h @@ -1,19 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_DMA_H diff --git a/arch/hexagon/include/asm/elf.h b/arch/hexagon/include/asm/elf.h index e1b933a0e121..5bfdd9b147fd 100644 --- a/arch/hexagon/include/asm/elf.h +++ b/arch/hexagon/include/asm/elf.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * ELF definitions for the Hexagon architecture * - * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. */ #ifndef __ASM_ELF_H @@ -23,11 +10,7 @@ #include <asm/ptrace.h> #include <asm/user.h> - -/* - * This should really be in linux/elf-em.h. - */ -#define EM_HEXAGON 164 /* QUALCOMM Hexagon */ +#include <linux/elf-em.h> struct elf32_hdr; @@ -198,11 +181,10 @@ do { \ */ #define ELF_PLAT_INIT(regs, load_addr) do { } while (0) -#define USE_ELF_CORE_DUMP #define CORE_DUMP_USE_REGSET /* Hrm is this going to cause problems for changing PAGE_SIZE? */ -#define ELF_EXEC_PAGESIZE 4096 +#define ELF_EXEC_PAGESIZE PAGE_SIZE /* * This is the location that an ET_DYN program is loaded if exec'ed. Typical diff --git a/arch/hexagon/include/asm/exec.h b/arch/hexagon/include/asm/exec.h index c32b2132614b..bb79e23db090 100644 --- a/arch/hexagon/include/asm/exec.h +++ b/arch/hexagon/include/asm/exec.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Process execution related definitions for the Hexagon architecture * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_EXEC_H diff --git a/arch/hexagon/include/asm/fixmap.h b/arch/hexagon/include/asm/fixmap.h index b75b6bf4269c..920660a04aa4 100644 --- a/arch/hexagon/include/asm/fixmap.h +++ b/arch/hexagon/include/asm/fixmap.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Fixmap support for Hexagon - enough to support highmem features * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_FIXMAP_H @@ -26,48 +13,6 @@ */ #include <asm/mem-layout.h> -/* - * Full fixmap support involves set_fixmap() functions, but - * these may not be needed if all we're after is an area for - * highmem kernel mappings. - */ -#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) -#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT) - -extern void __this_fixmap_does_not_exist(void); - -/** - * fix_to_virt -- "index to address" translation. - * - * If anyone tries to use the idx directly without translation, - * we catch the bug with a NULL-deference kernel oops. Illegal - * ranges of incoming indices are caught too. - */ -static inline unsigned long fix_to_virt(const unsigned int idx) -{ - /* - * This branch gets completely eliminated after inlining, - * except when someone tries to use fixaddr indices in an - * illegal way. (such as mixing up address types or using - * out-of-range indices). - * - * If it doesn't get removed, the linker will complain - * loudly with a reasonably clear error message.. - */ - if (idx >= __end_of_fixed_addresses) - __this_fixmap_does_not_exist(); - - return __fix_to_virt(idx); -} - -static inline unsigned long virt_to_fix(const unsigned long vaddr) -{ - BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); - return __virt_to_fix(vaddr); -} - -#define kmap_get_fixmap_pte(vaddr) \ - pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), \ - (vaddr)), (vaddr)), (vaddr)) +#include <asm-generic/fixmap.h> #endif diff --git a/arch/hexagon/include/asm/futex.h b/arch/hexagon/include/asm/futex.h index 7e597f8434da..9fb00a0ae89f 100644 --- a/arch/hexagon/include/asm/futex.h +++ b/arch/hexagon/include/asm/futex.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_HEXAGON_FUTEX_H #define _ASM_HEXAGON_FUTEX_H @@ -15,12 +16,12 @@ /* For example: %1 = %4 */ \ insn \ "2: memw_locked(%3,p2) = %1;\n" \ - " if !p2 jump 1b;\n" \ + " if (!p2) jump 1b;\n" \ " %1 = #0;\n" \ "3:\n" \ ".section .fixup,\"ax\"\n" \ "4: %1 = #%5;\n" \ - " jump 3b\n" \ + " jump ##3b\n" \ ".previous\n" \ ".section __ex_table,\"a\"\n" \ ".long 1b,4b,2b,4b\n" \ @@ -31,21 +32,13 @@ static inline int -futex_atomic_op_inuser(int encoded_op, int __user *uaddr) +arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) { - int op = (encoded_op >> 28) & 7; - int cmp = (encoded_op >> 24) & 15; - int oparg = (encoded_op << 8) >> 20; - int cmparg = (encoded_op << 20) >> 20; int oldval = 0, ret; - if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) - oparg = 1 << oparg; - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) + if (!access_ok(uaddr, sizeof(u32))) return -EFAULT; - pagefault_disable(); - switch (op) { case FUTEX_OP_SET: __futex_atomic_op("%1 = %4\n", ret, oldval, uaddr, oparg); @@ -70,32 +63,9 @@ futex_atomic_op_inuser(int encoded_op, int __user *uaddr) ret = -ENOSYS; } - pagefault_enable(); + if (!ret) + *oval = oldval; - if (!ret) { - switch (cmp) { - case FUTEX_OP_CMP_EQ: - ret = (oldval == cmparg); - break; - case FUTEX_OP_CMP_NE: - ret = (oldval != cmparg); - break; - case FUTEX_OP_CMP_LT: - ret = (oldval < cmparg); - break; - case FUTEX_OP_CMP_GE: - ret = (oldval >= cmparg); - break; - case FUTEX_OP_CMP_LE: - ret = (oldval <= cmparg); - break; - case FUTEX_OP_CMP_GT: - ret = (oldval > cmparg); - break; - default: - ret = -ENOSYS; - } - } return ret; } @@ -106,21 +76,21 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, int prev; int ret; - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) + if (!access_ok(uaddr, sizeof(u32))) return -EFAULT; __asm__ __volatile__ ( "1: %1 = memw_locked(%3)\n" " {\n" " p2 = cmp.eq(%1,%4)\n" - " if !p2.new jump:NT 3f\n" + " if (!p2.new) jump:NT 3f\n" " }\n" "2: memw_locked(%3,p2) = %5\n" - " if !p2 jump 1b\n" + " if (!p2) jump 1b\n" "3:\n" ".section .fixup,\"ax\"\n" "4: %0 = #%6\n" - " jump 3b\n" + " jump ##3b\n" ".previous\n" ".section __ex_table,\"a\"\n" ".long 1b,4b,2b,4b\n" diff --git a/arch/hexagon/include/asm/hexagon_vm.h b/arch/hexagon/include/asm/hexagon_vm.h index 67bb6d6f3337..9aa2493fe786 100644 --- a/arch/hexagon/include/asm/hexagon_vm.h +++ b/arch/hexagon/include/asm/hexagon_vm.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Declarations for to Hexagon Virtal Machine. * * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef ASM_HEXAGON_VM_H @@ -55,27 +42,27 @@ #ifndef __ASSEMBLY__ enum VM_CACHE_OPS { - ickill, - dckill, - l2kill, - dccleaninva, - icinva, - idsync, - fetch_cfg + hvmc_ickill, + hvmc_dckill, + hvmc_l2kill, + hvmc_dccleaninva, + hvmc_icinva, + hvmc_idsync, + hvmc_fetch_cfg }; enum VM_INT_OPS { - nop, - globen, - globdis, - locen, - locdis, - affinity, - get, - peek, - status, - post, - clear + hvmi_nop, + hvmi_globen, + hvmi_globdis, + hvmi_locen, + hvmi_locdis, + hvmi_affinity, + hvmi_get, + hvmi_peek, + hvmi_status, + hvmi_post, + hvmi_clear }; extern void _K_VM_event_vector(void); @@ -98,95 +85,95 @@ long __vmvpid(void); static inline long __vmcache_ickill(void) { - return __vmcache(ickill, 0, 0); + return __vmcache(hvmc_ickill, 0, 0); } static inline long __vmcache_dckill(void) { - return __vmcache(dckill, 0, 0); + return __vmcache(hvmc_dckill, 0, 0); } static inline long __vmcache_l2kill(void) { - return __vmcache(l2kill, 0, 0); + return __vmcache(hvmc_l2kill, 0, 0); } static inline long __vmcache_dccleaninva(unsigned long addr, unsigned long len) { - return __vmcache(dccleaninva, addr, len); + return __vmcache(hvmc_dccleaninva, addr, len); } static inline long __vmcache_icinva(unsigned long addr, unsigned long len) { - return __vmcache(icinva, addr, len); + return __vmcache(hvmc_icinva, addr, len); } static inline long __vmcache_idsync(unsigned long addr, unsigned long len) { - return __vmcache(idsync, addr, len); + return __vmcache(hvmc_idsync, addr, len); } static inline long __vmcache_fetch_cfg(unsigned long val) { - return __vmcache(fetch_cfg, val, 0); + return __vmcache(hvmc_fetch_cfg, val, 0); } /* interrupt operations */ static inline long __vmintop_nop(void) { - return __vmintop(nop, 0, 0, 0, 0); + return __vmintop(hvmi_nop, 0, 0, 0, 0); } static inline long __vmintop_globen(long i) { - return __vmintop(globen, i, 0, 0, 0); + return __vmintop(hvmi_globen, i, 0, 0, 0); } static inline long __vmintop_globdis(long i) { - return __vmintop(globdis, i, 0, 0, 0); + return __vmintop(hvmi_globdis, i, 0, 0, 0); } static inline long __vmintop_locen(long i) { - return __vmintop(locen, i, 0, 0, 0); + return __vmintop(hvmi_locen, i, 0, 0, 0); } static inline long __vmintop_locdis(long i) { - return __vmintop(locdis, i, 0, 0, 0); + return __vmintop(hvmi_locdis, i, 0, 0, 0); } static inline long __vmintop_affinity(long i, long cpu) { - return __vmintop(locdis, i, cpu, 0, 0); + return __vmintop(hvmi_affinity, i, cpu, 0, 0); } static inline long __vmintop_get(void) { - return __vmintop(get, 0, 0, 0, 0); + return __vmintop(hvmi_get, 0, 0, 0, 0); } static inline long __vmintop_peek(void) { - return __vmintop(peek, 0, 0, 0, 0); + return __vmintop(hvmi_peek, 0, 0, 0, 0); } static inline long __vmintop_status(long i) { - return __vmintop(status, i, 0, 0, 0); + return __vmintop(hvmi_status, i, 0, 0, 0); } static inline long __vmintop_post(long i) { - return __vmintop(post, i, 0, 0, 0); + return __vmintop(hvmi_post, i, 0, 0, 0); } static inline long __vmintop_clear(long i) { - return __vmintop(clear, i, 0, 0, 0); + return __vmintop(hvmi_clear, i, 0, 0, 0); } #else /* Only assembly code should reference these */ @@ -237,7 +224,7 @@ static inline long __vmintop_clear(long i) /* * The initial program gets to find a system environment descriptor - * on its stack when it begins exection. The first word is a version + * on its stack when it begins execution. The first word is a version * code to indicate what is there. Zero means nothing more. */ diff --git a/arch/hexagon/include/asm/intrinsics.h b/arch/hexagon/include/asm/intrinsics.h index ca587737fb2a..e8d668392698 100644 --- a/arch/hexagon/include/asm/intrinsics.h +++ b/arch/hexagon/include/asm/intrinsics.h @@ -1,19 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_HEXAGON_INTRINSICS_H diff --git a/arch/hexagon/include/asm/io.h b/arch/hexagon/include/asm/io.h index 1b7698e19139..83b2eb5de60c 100644 --- a/arch/hexagon/include/asm/io.h +++ b/arch/hexagon/include/asm/io.h @@ -1,65 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * IO definitions for the Hexagon architecture * * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_IO_H #define _ASM_IO_H -#ifdef __KERNEL__ - #include <linux/types.h> -#include <linux/delay.h> -#include <linux/vmalloc.h> -#include <asm/string.h> -#include <asm/mem-layout.h> -#include <asm/iomap.h> #include <asm/page.h> #include <asm/cacheflush.h> -#include <asm/tlbflush.h> - -/* - * We don't have PCI yet. - * _IO_BASE is pointing at what should be unused virtual space. - */ -#define IO_SPACE_LIMIT 0xffff -#define _IO_BASE ((void __iomem *)0xfe000000) - -#define IOMEM(x) ((void __force __iomem *)(x)) extern int remap_area_pages(unsigned long start, unsigned long phys_addr, unsigned long end, unsigned long flags); -extern void __iounmap(const volatile void __iomem *addr); - -/* Defined in lib/io.c, needed for smc91x driver. */ -extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen); -extern void __raw_writesw(void __iomem *addr, const void *data, int wordlen); - -extern void __raw_readsl(const void __iomem *addr, void *data, int wordlen); -extern void __raw_writesl(void __iomem *addr, const void *data, int wordlen); - -#define readsw(p, d, l) __raw_readsw(p, d, l) -#define writesw(p, d, l) __raw_writesw(p, d, l) - -#define readsl(p, d, l) __raw_readsl(p, d, l) -#define writesl(p, d, l) __raw_writesl(p, d, l) - /* * virt_to_phys - map virtual address to physical * @address: address to map @@ -79,27 +34,11 @@ static inline void *phys_to_virt(unsigned long address) } /* - * convert a physical pointer to a virtual kernel pointer for - * /dev/mem access. - */ -#define xlate_dev_kmem_ptr(p) __va(p) -#define xlate_dev_mem_ptr(p) __va(p) - -/* - * IO port access primitives. Hexagon doesn't have special IO access - * instructions; all I/O is memory mapped. - * - * in/out are used for "ports", but we don't have "port instructions", - * so these are really just memory mapped too. - */ - -/* * readb - read byte from memory mapped device * @addr: pointer to memory * - * Operates on "I/O bus memory space" */ -static inline u8 readb(const volatile void __iomem *addr) +static inline u8 __raw_readb(const volatile void __iomem *addr) { u8 val; asm volatile( @@ -109,8 +48,9 @@ static inline u8 readb(const volatile void __iomem *addr) ); return val; } +#define __raw_readb __raw_readb -static inline u16 readw(const volatile void __iomem *addr) +static inline u16 __raw_readw(const volatile void __iomem *addr) { u16 val; asm volatile( @@ -120,8 +60,9 @@ static inline u16 readw(const volatile void __iomem *addr) ); return val; } +#define __raw_readw __raw_readw -static inline u32 readl(const volatile void __iomem *addr) +static inline u32 __raw_readl(const volatile void __iomem *addr) { u32 val; asm volatile( @@ -131,6 +72,7 @@ static inline u32 readl(const volatile void __iomem *addr) ); return val; } +#define __raw_readl __raw_readl /* * writeb - write a byte to a memory location @@ -138,7 +80,7 @@ static inline u32 readl(const volatile void __iomem *addr) * @addr: pointer to memory * */ -static inline void writeb(u8 data, volatile void __iomem *addr) +static inline void __raw_writeb(u8 data, volatile void __iomem *addr) { asm volatile( "memb(%0) = %1;" @@ -147,8 +89,9 @@ static inline void writeb(u8 data, volatile void __iomem *addr) : "memory" ); } +#define __raw_writeb __raw_writeb -static inline void writew(u16 data, volatile void __iomem *addr) +static inline void __raw_writew(u16 data, volatile void __iomem *addr) { asm volatile( "memh(%0) = %1;" @@ -158,8 +101,9 @@ static inline void writew(u16 data, volatile void __iomem *addr) ); } +#define __raw_writew __raw_writew -static inline void writel(u32 data, volatile void __iomem *addr) +static inline void __raw_writel(u32 data, volatile void __iomem *addr) { asm volatile( "memw(%0) = %1;" @@ -168,173 +112,22 @@ static inline void writel(u32 data, volatile void __iomem *addr) : "memory" ); } - -#define __raw_writeb writeb -#define __raw_writew writew -#define __raw_writel writel - -#define __raw_readb readb -#define __raw_readw readw -#define __raw_readl readl - -/* - * http://comments.gmane.org/gmane.linux.ports.arm.kernel/117626 - */ - -#define readb_relaxed __raw_readb -#define readw_relaxed __raw_readw -#define readl_relaxed __raw_readl - -#define writeb_relaxed __raw_writeb -#define writew_relaxed __raw_writew -#define writel_relaxed __raw_writel - -/* - * Need an mtype somewhere in here, for cache type deals? - * This is probably too long for an inline. - */ -void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size); - -static inline void __iomem *ioremap(unsigned long phys_addr, unsigned long size) -{ - return ioremap_nocache(phys_addr, size); -} - -static inline void iounmap(volatile void __iomem *addr) -{ - __iounmap(addr); -} - -#define __raw_writel writel - -static inline void memcpy_fromio(void *dst, const volatile void __iomem *src, - int count) -{ - memcpy(dst, (void *) src, count); -} - -static inline void memcpy_toio(volatile void __iomem *dst, const void *src, - int count) -{ - memcpy((void *) dst, src, count); -} - -#define PCI_IO_ADDR (volatile void __iomem *) +#define __raw_writel __raw_writel /* - * inb - read byte from I/O port or something - * @port: address in I/O space - * - * Operates on "I/O bus I/O space" + * I/O memory mapping functions. */ -static inline u8 inb(unsigned long port) -{ - return readb(_IO_BASE + (port & IO_SPACE_LIMIT)); -} - -static inline u16 inw(unsigned long port) -{ - return readw(_IO_BASE + (port & IO_SPACE_LIMIT)); -} - -static inline u32 inl(unsigned long port) -{ - return readl(_IO_BASE + (port & IO_SPACE_LIMIT)); -} +#define _PAGE_IOREMAP (_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE | \ + (__HEXAGON_C_DEV << 6)) /* - * outb - write a byte to a memory location - * @data: data to write to - * @addr: address in I/O space + * These defines are necessary to use the generic io.h for filling in + * the missing parts of the API contract. This is because the platform + * uses (inline) functions rather than defines and the generic helper + * fills in the undefined. */ -static inline void outb(u8 data, unsigned long port) -{ - writeb(data, _IO_BASE + (port & IO_SPACE_LIMIT)); -} - -static inline void outw(u16 data, unsigned long port) -{ - writew(data, _IO_BASE + (port & IO_SPACE_LIMIT)); -} - -static inline void outl(u32 data, unsigned long port) -{ - writel(data, _IO_BASE + (port & IO_SPACE_LIMIT)); -} - -#define outb_p outb -#define outw_p outw -#define outl_p outl - -#define inb_p inb -#define inw_p inw -#define inl_p inl - -static inline void insb(unsigned long port, void *buffer, int count) -{ - if (count) { - u8 *buf = buffer; - do { - u8 x = inb(port); - *buf++ = x; - } while (--count); - } -} - -static inline void insw(unsigned long port, void *buffer, int count) -{ - if (count) { - u16 *buf = buffer; - do { - u16 x = inw(port); - *buf++ = x; - } while (--count); - } -} - -static inline void insl(unsigned long port, void *buffer, int count) -{ - if (count) { - u32 *buf = buffer; - do { - u32 x = inw(port); - *buf++ = x; - } while (--count); - } -} - -static inline void outsb(unsigned long port, const void *buffer, int count) -{ - if (count) { - const u8 *buf = buffer; - do { - outb(*buf++, port); - } while (--count); - } -} - -static inline void outsw(unsigned long port, const void *buffer, int count) -{ - if (count) { - const u16 *buf = buffer; - do { - outw(*buf++, port); - } while (--count); - } -} - -static inline void outsl(unsigned long port, const void *buffer, int count) -{ - if (count) { - const u32 *buf = buffer; - do { - outl(*buf++, port); - } while (--count); - } -} - -#define flush_write_buffers() do { } while (0) - -#endif /* __KERNEL__ */ +#define virt_to_phys virt_to_phys +#define phys_to_virt phys_to_virt +#include <asm-generic/io.h> #endif diff --git a/arch/hexagon/include/asm/irq.h b/arch/hexagon/include/asm/irq.h index 51661db389d6..a60d26754caa 100644 --- a/arch/hexagon/include/asm/irq.h +++ b/arch/hexagon/include/asm/irq.h @@ -1,19 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_IRQ_H_ @@ -33,4 +20,7 @@ #include <asm-generic/irq.h> +struct pt_regs; +void arch_do_IRQ(struct pt_regs *); + #endif diff --git a/arch/hexagon/include/asm/irqflags.h b/arch/hexagon/include/asm/irqflags.h index e5fd9492d60f..c4d2a4de139f 100644 --- a/arch/hexagon/include/asm/irqflags.h +++ b/arch/hexagon/include/asm/irqflags.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * IRQ support for the Hexagon architecture * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_IRQFLAGS_H diff --git a/arch/hexagon/include/asm/kgdb.h b/arch/hexagon/include/asm/kgdb.h index 32a6fb66944a..30cc387b3423 100644 --- a/arch/hexagon/include/asm/kgdb.h +++ b/arch/hexagon/include/asm/kgdb.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * arch/hexagon/include/asm/kgdb.h - Hexagon KGDB Support * * Copyright (c) 2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef __HEXAGON_KGDB_H__ @@ -34,10 +21,11 @@ static inline void arch_kgdb_breakpoint(void) * 32 gpr + sa0/1 + lc0/1 + m0/1 + gp + ugp + pred + pc = 42 total. * vm regs = psp+elr+est+badva = 4 * syscall+restart = 2 more - * so 48 = 42 +4 + 2 + * also add cs0/1 = 2 + * so 48 = 42 + 4 + 2 + 2 */ #define DBG_USER_REGS 42 -#define DBG_MAX_REG_NUM (DBG_USER_REGS + 6) +#define DBG_MAX_REG_NUM (DBG_USER_REGS + 8) #define NUMREGBYTES (DBG_MAX_REG_NUM*4) #endif /* __HEXAGON_KGDB_H__ */ diff --git a/arch/hexagon/include/asm/linkage.h b/arch/hexagon/include/asm/linkage.h index 31b4cbe7e583..ebdb581939e8 100644 --- a/arch/hexagon/include/asm/linkage.h +++ b/arch/hexagon/include/asm/linkage.h @@ -1,19 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef __ASM_LINKAGE_H diff --git a/arch/hexagon/include/asm/mem-layout.h b/arch/hexagon/include/asm/mem-layout.h index 60556f8c45d8..e2f99413fe56 100644 --- a/arch/hexagon/include/asm/mem-layout.h +++ b/arch/hexagon/include/asm/mem-layout.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Memory layout definitions for the Hexagon architecture * * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_HEXAGON_MEM_LAYOUT_H diff --git a/arch/hexagon/include/asm/mmu.h b/arch/hexagon/include/asm/mmu.h index 2288b19fd0f2..dfa46660d695 100644 --- a/arch/hexagon/include/asm/mmu.h +++ b/arch/hexagon/include/asm/mmu.h @@ -1,19 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_MMU_H diff --git a/arch/hexagon/include/asm/mmu_context.h b/arch/hexagon/include/asm/mmu_context.h index d423d2e73c30..81947764c47d 100644 --- a/arch/hexagon/include/asm/mmu_context.h +++ b/arch/hexagon/include/asm/mmu_context.h @@ -1,64 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * MM context support for the Hexagon architecture * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_MMU_CONTEXT_H #define _ASM_MMU_CONTEXT_H +#include <linux/mm_types.h> + #include <asm/setup.h> #include <asm/page.h> #include <asm/pgalloc.h> #include <asm/mem-layout.h> -static inline void destroy_context(struct mm_struct *mm) -{ -} - /* * VM port hides all TLB management, so "lazy TLB" isn't very * meaningful. Even for ports to architectures with visble TLBs, * this is almost invariably a null function. + * + * mm->context is set up by pgd_alloc, so no init_new_context required. */ -static inline void enter_lazy_tlb(struct mm_struct *mm, - struct task_struct *tsk) -{ -} - -/* - * Architecture-specific actions, if any, for memory map deactivation. - */ -static inline void deactivate_mm(struct task_struct *tsk, - struct mm_struct *mm) -{ -} - -/** - * init_new_context - initialize context related info for new mm_struct instance - * @tsk: pointer to a task struct - * @mm: pointer to a new mm struct - */ -static inline int init_new_context(struct task_struct *tsk, - struct mm_struct *mm) -{ - /* mm->context is set up by pgd_alloc */ - return 0; -} /* * Switch active mm context @@ -85,6 +48,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, /* * Activate new memory map for task */ +#define activate_mm activate_mm static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) { unsigned long flags; @@ -97,4 +61,6 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) /* Generic hooks for arch_dup_mmap and arch_exit_mmap */ #include <asm-generic/mm_hooks.h> +#include <asm-generic/mmu_context.h> + #endif diff --git a/arch/hexagon/include/asm/module.h b/arch/hexagon/include/asm/module.h deleted file mode 100644 index 6b4323acef44..000000000000 --- a/arch/hexagon/include/asm/module.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef _ASM_MODULE_H -#define _ASM_MODULE_H - -#include <asm-generic/module.h> - -#define MODULE_ARCH_VERMAGIC __stringify(PROCESSOR_MODEL_NAME) " " - -#endif diff --git a/arch/hexagon/include/asm/mutex.h b/arch/hexagon/include/asm/mutex.h deleted file mode 100644 index 58b52de1bc22..000000000000 --- a/arch/hexagon/include/asm/mutex.h +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Pull in the generic implementation for the mutex fastpath. - * - * TODO: implement optimized primitives instead, or leave the generic - * implementation in place, or pick the atomic_xchg() based generic - * implementation. (see asm-generic/mutex-xchg.h for details) - */ -#include <asm-generic/mutex-xchg.h> diff --git a/arch/hexagon/include/asm/page.h b/arch/hexagon/include/asm/page.h index 93f5669b4aa1..137ba7c5de48 100644 --- a/arch/hexagon/include/asm/page.h +++ b/arch/hexagon/include/asm/page.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Page management definitions for the Hexagon architecture * * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_PAGE_H @@ -26,27 +13,22 @@ /* This is probably not the most graceful way to handle this. */ #ifdef CONFIG_PAGE_SIZE_4KB -#define PAGE_SHIFT 12 #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_4KB #endif #ifdef CONFIG_PAGE_SIZE_16KB -#define PAGE_SHIFT 14 #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_16KB #endif #ifdef CONFIG_PAGE_SIZE_64KB -#define PAGE_SHIFT 16 #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_64KB #endif #ifdef CONFIG_PAGE_SIZE_256KB -#define PAGE_SHIFT 18 #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_256KB #endif #ifdef CONFIG_PAGE_SIZE_1MB -#define PAGE_SHIFT 20 #define HEXAGON_L1_PTE_SIZE __HVM_PDE_S_1MB #endif @@ -63,8 +45,7 @@ #define HVM_HUGEPAGE_SIZE 0x5 #endif -#define PAGE_SIZE (1UL << PAGE_SHIFT) -#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1)) +#include <vdso/page.h> #ifdef __KERNEL__ #ifndef __ASSEMBLY__ @@ -91,6 +72,9 @@ typedef struct page *pgtable_t; #define __pgd(x) ((pgd_t) { (x) }) #define __pgprot(x) ((pgprot_t) { (x) }) +/* Needed for PAGE_OFFSET used in the macro right below */ +#include <asm/mem-layout.h> + /* * We need a __pa and a __va routine for kernel space. * MIPS says they're only used during mem_init. @@ -106,10 +90,8 @@ struct page; #define virt_to_page(kaddr) pfn_to_page(PFN_DOWN(__pa(kaddr))) /* Default vm area behavior is non-executable. */ -#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_NON_EXEC -#define pfn_valid(pfn) ((pfn) < max_mapnr) #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) /* Need to not use a define for linesize; may move this to another file. */ @@ -134,24 +116,13 @@ static inline void clear_page(void *page) #define clear_user_page(page, vaddr, pg) clear_page(page) #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) -/* - * page_to_phys - convert page to physical address - * @page - pointer to page entry in mem_map - */ -#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) - -#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT) -#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT) +static inline unsigned long virt_to_pfn(const void *kaddr) +{ + return __pa(kaddr) >> PAGE_SHIFT; +} #define page_to_virt(page) __va(page_to_phys(page)) -/* - * For port to Hexagon Virtual Machine, MAYBE we check for attempts - * to reference reserved HVM space, but in any case, the VM will be - * protected. - */ -#define kern_addr_valid(addr) (1) - #include <asm/mem-layout.h> #include <asm-generic/memory_model.h> /* XXX Todo: implement assembly-optimized version of getorder. */ diff --git a/arch/hexagon/include/asm/perf_event.h b/arch/hexagon/include/asm/perf_event.h index 430978b1de38..81db312b8162 100644 --- a/arch/hexagon/include/asm/perf_event.h +++ b/arch/hexagon/include/asm/perf_event.h @@ -1,19 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_PERF_EVENT_H diff --git a/arch/hexagon/include/asm/pgalloc.h b/arch/hexagon/include/asm/pgalloc.h index 679bf6d66487..937a11ef4c33 100644 --- a/arch/hexagon/include/asm/pgalloc.h +++ b/arch/hexagon/include/asm/pgalloc.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Page table support for the Hexagon architecture * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_PGALLOC_H @@ -24,7 +11,7 @@ #include <asm/mem-layout.h> #include <asm/atomic.h> -#define check_pgt_cache() do {} while (0) +#include <asm-generic/pgalloc.h> extern unsigned long long kmap_generation; @@ -35,7 +22,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) { pgd_t *pgd; - pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO); + pgd = __pgd_alloc(mm, 0); /* * There may be better ways to do this, but to ensure @@ -45,7 +32,7 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) * map with a copy of the kernel's persistent map. */ - memcpy(pgd, swapper_pg_dir, PTRS_PER_PGD*sizeof(pgd_t *)); + memcpy(pgd, swapper_pg_dir, PTRS_PER_PGD*sizeof(pgd_t)); mm->context.generation = kmap_generation; /* Physical version is what is passed to virtual machine on switch */ @@ -54,43 +41,6 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) return pgd; } -static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) -{ - free_page((unsigned long) pgd); -} - -static inline struct page *pte_alloc_one(struct mm_struct *mm, - unsigned long address) -{ - struct page *pte; - - pte = alloc_page(GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO); - - if (pte) - pgtable_page_ctor(pte); - - return pte; -} - -/* _kernel variant gets to use a different allocator */ -static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, - unsigned long address) -{ - gfp_t flags = GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO; - return (pte_t *) __get_free_page(flags); -} - -static inline void pte_free(struct mm_struct *mm, struct page *pte) -{ - pgtable_page_dtor(pte); - __free_page(pte); -} - -static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) -{ - free_page((unsigned long)pte); -} - static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd, pgtable_t pte) { @@ -137,10 +87,7 @@ static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, max_kernel_seg = pmdindex; } -#define __pte_free_tlb(tlb, pte, addr) \ -do { \ - pgtable_page_dtor((pte)); \ - tlb_remove_page((tlb), (pte)); \ -} while (0) +#define __pte_free_tlb(tlb, pte, addr) \ + tlb_remove_ptdesc((tlb), page_ptdesc(pte)) #endif diff --git a/arch/hexagon/include/asm/pgtable.h b/arch/hexagon/include/asm/pgtable.h index d8bd54fa431e..fbf24d1d1ca6 100644 --- a/arch/hexagon/include/asm/pgtable.h +++ b/arch/hexagon/include/asm/pgtable.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Page table support for the Hexagon architecture * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_PGTABLE_H @@ -24,13 +11,11 @@ /* * Page table definitions for Qualcomm Hexagon processor. */ -#include <linux/swap.h> #include <asm/page.h> #include <asm-generic/pgtable-nopmd.h> /* A handy thing to have if one has the RAM. Declared in head.S */ extern unsigned long empty_zero_page; -extern unsigned long zero_page_mask; /* * The PTE model described here is that of the Hexagon Virtual Machine, @@ -62,13 +47,6 @@ extern unsigned long zero_page_mask; #define _PAGE_ACCESSED (1<<2) /* - * _PAGE_FILE is only meaningful if _PAGE_PRESENT is false, while - * _PAGE_DIRTY is only meaningful if _PAGE_PRESENT is true. - * So we can overload the bit... - */ -#define _PAGE_FILE _PAGE_DIRTY /* set: pagecache, unset = swap */ - -/* * For now, let's say that Valid and Present are the same thing. * Alternatively, we could say that it's the "or" of R, W, and X * permissions. @@ -83,6 +61,9 @@ extern unsigned long zero_page_mask; * So we'll put up with a bit of inefficiency for now... */ +/* We borrow bit 6 to store the exclusive marker in swap PTEs. */ +#define _PAGE_SWP_EXCLUSIVE (1<<6) + /* * Top "FOURTH" level (pgd), which for the Hexagon VM is really * only the second from the bottom, pgd and pud both being collapsed. @@ -148,40 +129,8 @@ extern unsigned long _dflt_cache_att; */ #define CACHEDEF (CACHE_DEFAULT << 6) -/* Private (copy-on-write) page protections. */ -#define __P000 __pgprot(_PAGE_PRESENT | _PAGE_USER | CACHEDEF) -#define __P001 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | CACHEDEF) -#define __P010 __P000 /* Write-only copy-on-write */ -#define __P011 __P001 /* Read/Write copy-on-write */ -#define __P100 __pgprot(_PAGE_PRESENT | _PAGE_USER | \ - _PAGE_EXECUTE | CACHEDEF) -#define __P101 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_EXECUTE | \ - _PAGE_READ | CACHEDEF) -#define __P110 __P100 /* Write/execute copy-on-write */ -#define __P111 __P101 /* Read/Write/Execute, copy-on-write */ - -/* Shared page protections. */ -#define __S000 __P000 -#define __S001 __P001 -#define __S010 __pgprot(_PAGE_PRESENT | _PAGE_USER | \ - _PAGE_WRITE | CACHEDEF) -#define __S011 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | \ - _PAGE_WRITE | CACHEDEF) -#define __S100 __pgprot(_PAGE_PRESENT | _PAGE_USER | \ - _PAGE_EXECUTE | CACHEDEF) -#define __S101 __P101 -#define __S110 __pgprot(_PAGE_PRESENT | _PAGE_USER | \ - _PAGE_EXECUTE | _PAGE_WRITE | CACHEDEF) -#define __S111 __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | \ - _PAGE_EXECUTE | _PAGE_WRITE | CACHEDEF) - extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; /* located in head.S */ -/* Seems to be zero even in architectures where the zero page is firewalled? */ -#define FIRST_USER_ADDRESS 0 -#define pte_special(pte) 0 -#define pte_mkspecial(pte) (pte) - /* HUGETLB not working currently */ #ifdef CONFIG_HUGETLB_PAGE #define pte_mkhuge(pte) __pte((pte_val(pte) & ~0x3) | HVM_HUGEPAGE_SIZE) @@ -230,33 +179,6 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_val(*ptep) = _NULL_PTE; } -#ifdef NEED_PMD_INDEX_DESPITE_BEING_2_LEVEL -/** - * pmd_index - returns the index of the entry in the PMD page - * which would control the given virtual address - */ -#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) - -#endif - -/** - * pgd_index - returns the index of the entry in the PGD page - * which would control the given virtual address - * - * This returns the *index* for the address in the pgd_t - */ -#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) - -/* - * pgd_offset - find an offset in a page-table-directory - */ -#define pgd_offset(mm, addr) ((mm)->pgd + pgd_index(addr)) - -/* - * pgd_offset_k - get kernel (init_mm) pgd entry pointer for addr - */ -#define pgd_offset_k(address) pgd_offset(&init_mm, address) - /** * pmd_none - check if pmd_entry is mapped * @pmd_entry: pmd entry @@ -290,10 +212,14 @@ static inline int pmd_bad(pmd_t pmd) } /* + * pmd_pfn - converts a PMD entry to a page frame number + */ +#define pmd_pfn(pmd) (pmd_val(pmd) >> PAGE_SHIFT) + +/* * pmd_page - converts a PMD entry to a page pointer */ #define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)) -#define pmd_pgtable(pmd) pmd_page(pmd) /** * pte_none - check if pte is mapped @@ -312,9 +238,6 @@ static inline int pte_present(pte_t pte) return pte_val(pte) & _PAGE_PRESENT; } -/* mk_pte - make a PTE out of a page pointer and protection bits */ -#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) - /* pte_page - returns a page (frame pointer/descriptor?) based on a PTE */ #define pte_page(x) pfn_to_page(pte_pfn(x)) @@ -374,7 +297,7 @@ static inline pte_t pte_wrprotect(pte_t pte) } /* pte_mkwrite - mark page as writable */ -static inline pte_t pte_mkwrite(pte_t pte) +static inline pte_t pte_mkwrite_novma(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; return pte; @@ -412,6 +335,7 @@ static inline int pte_exec(pte_t pte) /* __swp_entry_to_pte - extract PTE from swap entry */ #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) +#define PFN_PTE_SHIFT PAGE_SHIFT /* pfn_pte - convert page number and protection value to page table entry */ #define pfn_pte(pfn, pgprot) __pte((pfn << PAGE_SHIFT) | pgprot_val(pgprot)) @@ -419,96 +343,65 @@ static inline int pte_exec(pte_t pte) #define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) #define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval)) -/* - * set_pte_at - update page table and do whatever magic may be - * necessary to make the underlying hardware/firmware take note. - * - * VM may require a virtual instruction to alert the MMU. - */ -#define set_pte_at(mm, addr, ptep, pte) set_pte(ptep, pte) - -/* - * May need to invoke the virtual machine as well... - */ -#define pte_unmap(pte) do { } while (0) -#define pte_unmap_nested(pte) do { } while (0) - -/* - * pte_offset_map - returns the linear address of the page table entry - * corresponding to an address - */ -#define pte_offset_map(dir, address) \ - ((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address)) - -#define pte_offset_map_nested(pmd, addr) pte_offset_map(pmd, addr) - -/* pte_offset_kernel - kernel version of pte_offset */ -#define pte_offset_kernel(dir, address) \ - ((pte_t *) (unsigned long) __va(pmd_val(*dir) & PAGE_MASK) \ - + __pte_offset(address)) +static inline unsigned long pmd_page_vaddr(pmd_t pmd) +{ + return (unsigned long)__va(pmd_val(pmd) & PAGE_MASK); +} /* ZERO_PAGE - returns the globally shared zero page */ #define ZERO_PAGE(vaddr) (virt_to_page(&empty_zero_page)) -#define __pte_offset(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) - -/* I think this is in case we have page table caches; needed by init/main.c */ -#define pgtable_cache_init() do { } while (0) - /* - * Swap/file PTE definitions. If _PAGE_PRESENT is zero, the rest of the - * PTE is interpreted as swap information. Depending on the _PAGE_FILE - * bit, the remaining free bits are eitehr interpreted as a file offset - * or a swap type/offset tuple. Rather than have the TLB fill handler - * test _PAGE_PRESENT, we're going to reserve the permissions bits - * and set them to all zeros for swap entries, which speeds up the - * miss handler at the cost of 3 bits of offset. That trade-off can - * be revisited if necessary, but Hexagon processor architecture and - * target applications suggest a lot of TLB misses and not much swap space. + * Encode/decode swap entries and swap PTEs. Swap PTEs are all PTEs that + * are !pte_none() && !pte_present(). + * + * Swap/file PTE definitions. If _PAGE_PRESENT is zero, the rest of the PTE is + * interpreted as swap information. The remaining free bits are interpreted as + * listed below. Rather than have the TLB fill handler test + * _PAGE_PRESENT, we're going to reserve the permissions bits and set them to + * all zeros for swap entries, which speeds up the miss handler at the cost of + * 3 bits of offset. That trade-off can be revisited if necessary, but Hexagon + * processor architecture and target applications suggest a lot of TLB misses + * and not much swap space. * * Format of swap PTE: * bit 0: Present (zero) - * bit 1: _PAGE_FILE (zero) - * bits 2-6: swap type (arch independent layer uses 5 bits max) + * bits 1-5: swap type (arch independent layer uses 5 bits max) + * bit 6: exclusive marker * bits 7-9: bits 2:0 of offset - * bits 10-12: effectively _PAGE_PROTNONE (all zero) - * bits 13-31: bits 21:3 of swap offset - * - * Format of file PTE: - * bit 0: Present (zero) - * bit 1: _PAGE_FILE (zero) - * bits 2-9: bits 7:0 of offset - * bits 10-12: effectively _PAGE_PROTNONE (all zero) - * bits 13-31: bits 26:8 of swap offset + * bits 10-12: effectively _PAGE_PROTNONE (all zero) + * bits 13-31: bits 21:3 of swap offset * * The split offset makes some of the following macros a little gnarly, * but there's plenty of precedent for this sort of thing. */ -#define PTE_FILE_MAX_BITS 27 /* Used for swap PTEs */ -#define __swp_type(swp_pte) (((swp_pte).val >> 2) & 0x1f) +#define __swp_type(swp_pte) (((swp_pte).val >> 1) & 0x1f) #define __swp_offset(swp_pte) \ - ((((swp_pte).val >> 7) & 0x7) | (((swp_pte).val >> 10) & 0x003ffff8)) + ((((swp_pte).val >> 7) & 0x7) | (((swp_pte).val >> 10) & 0x3ffff8)) #define __swp_entry(type, offset) \ ((swp_entry_t) { \ - ((type << 2) | \ + (((type & 0x1f) << 1) | \ ((offset & 0x3ffff8) << 10) | ((offset & 0x7) << 7)) }) -/* Used for file PTEs */ -#define pte_file(pte) \ - ((pte_val(pte) & (_PAGE_FILE | _PAGE_PRESENT)) == _PAGE_FILE) - -#define pte_to_pgoff(pte) \ - (((pte_val(pte) >> 2) & 0xff) | ((pte_val(pte) >> 5) & 0x07ffff00)) +static inline bool pte_swp_exclusive(pte_t pte) +{ + return pte_val(pte) & _PAGE_SWP_EXCLUSIVE; +} -#define pgoff_to_pte(off) \ - ((pte_t) { ((((off) & 0x7ffff00) << 5) | (((off) & 0xff) << 2)\ - | _PAGE_FILE) }) +static inline pte_t pte_swp_mkexclusive(pte_t pte) +{ + pte_val(pte) |= _PAGE_SWP_EXCLUSIVE; + return pte; +} -/* Oh boy. There are a lot of possible arch overrides found in this file. */ -#include <asm-generic/pgtable.h> +static inline pte_t pte_swp_clear_exclusive(pte_t pte) +{ + pte_val(pte) &= ~_PAGE_SWP_EXCLUSIVE; + return pte; +} #endif diff --git a/arch/hexagon/include/asm/processor.h b/arch/hexagon/include/asm/processor.h index 45a825402f63..0cd39c2cdf8f 100644 --- a/arch/hexagon/include/asm/processor.h +++ b/arch/hexagon/include/asm/processor.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Process/processor support for the Hexagon architecture * * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_PROCESSOR_H @@ -27,15 +14,9 @@ #include <asm/registers.h> #include <asm/hexagon_vm.h> -/* must be a macro */ -#define current_text_addr() ({ __label__ _l; _l: &&_l; }) - /* task_struct, defined elsewhere, is the "process descriptor" */ struct task_struct; -/* this is defined in arch/process.c */ -extern unsigned long thread_saved_pc(struct task_struct *tsk); - extern void start_thread(struct pt_regs *, unsigned long, unsigned long); /* @@ -79,11 +60,7 @@ struct thread_struct { #define KSTK_EIP(tsk) (pt_elr(task_pt_regs(tsk))) #define KSTK_ESP(tsk) (pt_psp(task_pt_regs(tsk))) -/* Free all resources held by a thread; defined in process.c */ -extern void release_thread(struct task_struct *dead_task); - -/* Get wait channel for task P. */ -extern unsigned long get_wchan(struct task_struct *p); +extern unsigned long __get_wchan(struct task_struct *p); /* The following stuff is pretty HEXAGON specific. */ diff --git a/arch/hexagon/include/asm/ptrace.h b/arch/hexagon/include/asm/ptrace.h new file mode 100644 index 000000000000..ed35da1ee685 --- /dev/null +++ b/arch/hexagon/include/asm/ptrace.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Ptrace definitions for the Hexagon architecture + * + * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + */ + +#ifndef _ASM_HEXAGON_PTRACE_H +#define _ASM_HEXAGON_PTRACE_H + +#include <uapi/asm/ptrace.h> + +/* kprobe-based event tracer support */ +extern int regs_query_register_offset(const char *name); +extern const char *regs_query_register_name(unsigned int offset); + +#define current_pt_regs() \ + ((struct pt_regs *) \ + ((unsigned long)current_thread_info() + THREAD_SIZE) - 1) + +#if CONFIG_HEXAGON_ARCH_VERSION >= 4 +#define arch_has_single_step() (1) +#endif + +#endif diff --git a/arch/hexagon/include/asm/setup.h b/arch/hexagon/include/asm/setup.h new file mode 100644 index 000000000000..9f2749cd4052 --- /dev/null +++ b/arch/hexagon/include/asm/setup.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + */ + +#ifndef _ASM_HEXAGON_SETUP_H +#define _ASM_HEXAGON_SETUP_H + +#include <linux/init.h> +#include <uapi/asm/setup.h> + +extern char external_cmdline_buffer; + +void __init setup_arch_memory(void); + +#endif diff --git a/arch/hexagon/include/asm/smp.h b/arch/hexagon/include/asm/smp.h index 2b9b974e0952..60d6c948648a 100644 --- a/arch/hexagon/include/asm/smp.h +++ b/arch/hexagon/include/asm/smp.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * SMP definitions for the Hexagon architecture * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef __ASM_SMP_H @@ -29,7 +16,6 @@ enum ipi_message_type { IPI_NOP = 0, IPI_RESCHEDULE = 1, IPI_CALL_FUNC, - IPI_CALL_FUNC_SINGLE, IPI_CPU_STOP, IPI_TIMER, }; diff --git a/arch/hexagon/include/asm/spinlock.h b/arch/hexagon/include/asm/spinlock.h index 12ca4ebc0338..ef103b73bec8 100644 --- a/arch/hexagon/include/asm/spinlock.h +++ b/arch/hexagon/include/asm/spinlock.h @@ -1,28 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Spinlock support for the Hexagon architecture * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_SPINLOCK_H #define _ASM_SPINLOCK_H #include <asm/irqflags.h> +#include <asm/barrier.h> +#include <asm/processor.h> /* * This file is pulled in for SMP builds. @@ -42,9 +30,9 @@ static inline void arch_read_lock(arch_rwlock_t *lock) __asm__ __volatile__( "1: R6 = memw_locked(%0);\n" " { P3 = cmp.ge(R6,#0); R6 = add(R6,#1);}\n" - " { if !P3 jump 1b; }\n" + " { if (!P3) jump 1b; }\n" " memw_locked(%0,P3) = R6;\n" - " { if !P3 jump 1b; }\n" + " { if (!P3) jump 1b; }\n" : : "r" (&lock->lock) : "memory", "r6", "p3" @@ -58,7 +46,7 @@ static inline void arch_read_unlock(arch_rwlock_t *lock) "1: R6 = memw_locked(%0);\n" " R6 = add(R6,#-1);\n" " memw_locked(%0,P3) = R6\n" - " if !P3 jump 1b;\n" + " if (!P3) jump 1b;\n" : : "r" (&lock->lock) : "memory", "r6", "p3" @@ -73,7 +61,7 @@ static inline int arch_read_trylock(arch_rwlock_t *lock) __asm__ __volatile__( " R6 = memw_locked(%1);\n" " { %0 = #0; P3 = cmp.ge(R6,#0); R6 = add(R6,#1);}\n" - " { if !P3 jump 1f; }\n" + " { if (!P3) jump 1f; }\n" " memw_locked(%1,P3) = R6;\n" " { %0 = P3 }\n" "1:\n" @@ -84,25 +72,15 @@ static inline int arch_read_trylock(arch_rwlock_t *lock) return temp; } -static inline int arch_read_can_lock(arch_rwlock_t *rwlock) -{ - return rwlock->lock == 0; -} - -static inline int arch_write_can_lock(arch_rwlock_t *rwlock) -{ - return rwlock->lock == 0; -} - /* Stuffs a -1 in the lock value? */ static inline void arch_write_lock(arch_rwlock_t *lock) { __asm__ __volatile__( "1: R6 = memw_locked(%0)\n" " { P3 = cmp.eq(R6,#0); R6 = #-1;}\n" - " { if !P3 jump 1b; }\n" + " { if (!P3) jump 1b; }\n" " memw_locked(%0,P3) = R6;\n" - " { if !P3 jump 1b; }\n" + " { if (!P3) jump 1b; }\n" : : "r" (&lock->lock) : "memory", "r6", "p3" @@ -116,7 +94,7 @@ static inline int arch_write_trylock(arch_rwlock_t *lock) __asm__ __volatile__( " R6 = memw_locked(%1)\n" " { %0 = #0; P3 = cmp.eq(R6,#0); R6 = #-1;}\n" - " { if !P3 jump 1f; }\n" + " { if (!P3) jump 1f; }\n" " memw_locked(%1,P3) = R6;\n" " %0 = P3;\n" "1:\n" @@ -139,9 +117,9 @@ static inline void arch_spin_lock(arch_spinlock_t *lock) __asm__ __volatile__( "1: R6 = memw_locked(%0);\n" " P3 = cmp.eq(R6,#0);\n" - " { if !P3 jump 1b; R6 = #1; }\n" + " { if (!P3) jump 1b; R6 = #1; }\n" " memw_locked(%0,P3) = R6;\n" - " { if !P3 jump 1b; }\n" + " { if (!P3) jump 1b; }\n" : : "r" (&lock->lock) : "memory", "r6", "p3" @@ -161,7 +139,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) __asm__ __volatile__( " R6 = memw_locked(%1);\n" " P3 = cmp.eq(R6,#0);\n" - " { if !P3 jump 1f; R6 = #1; %0 = #0; }\n" + " { if (!P3) jump 1f; R6 = #1; %0 = #0; }\n" " memw_locked(%1,P3) = R6;\n" " %0 = P3;\n" "1:\n" @@ -175,12 +153,6 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock) /* * SMP spinlocks are intended to allow only a single CPU at the lock */ -#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) -#define arch_spin_unlock_wait(lock) \ - do {while (arch_spin_is_locked(lock)) cpu_relax(); } while (0) #define arch_spin_is_locked(x) ((x)->lock != 0) -#define arch_read_lock_flags(lock, flags) arch_read_lock(lock) -#define arch_write_lock_flags(lock, flags) arch_write_lock(lock) - #endif diff --git a/arch/hexagon/include/asm/spinlock_types.h b/arch/hexagon/include/asm/spinlock_types.h index 7a906b5214a4..63add2d863e8 100644 --- a/arch/hexagon/include/asm/spinlock_types.h +++ b/arch/hexagon/include/asm/spinlock_types.h @@ -1,28 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Spinlock support for the Hexagon architecture * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_SPINLOCK_TYPES_H #define _ASM_SPINLOCK_TYPES_H -#ifndef __LINUX_SPINLOCK_TYPES_H -# error "please don't include this file directly" +#ifndef __LINUX_SPINLOCK_TYPES_RAW_H +# error "Please do not include this file directly." #endif typedef struct { diff --git a/arch/hexagon/include/asm/string.h b/arch/hexagon/include/asm/string.h index 7d37f47a1d07..5972cca79629 100644 --- a/arch/hexagon/include/asm/string.h +++ b/arch/hexagon/include/asm/string.h @@ -1,19 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_STRING_H_ diff --git a/arch/hexagon/include/asm/suspend.h b/arch/hexagon/include/asm/suspend.h index 18b44b557fbc..57b1e11522e7 100644 --- a/arch/hexagon/include/asm/suspend.h +++ b/arch/hexagon/include/asm/suspend.h @@ -1,19 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_SUSPEND_H diff --git a/arch/hexagon/include/asm/switch_to.h b/arch/hexagon/include/asm/switch_to.h index 96745e7b3e3c..8c7d13fe42e4 100644 --- a/arch/hexagon/include/asm/switch_to.h +++ b/arch/hexagon/include/asm/switch_to.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Task switching definitions for the Hexagon architecture * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_SWITCH_TO_H diff --git a/arch/hexagon/include/asm/syscall.h b/arch/hexagon/include/asm/syscall.h index 4af9c7b6f13a..70637261817a 100644 --- a/arch/hexagon/include/asm/syscall.h +++ b/arch/hexagon/include/asm/syscall.h @@ -1,26 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Syscall support for the Hexagon architecture * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_HEXAGON_SYSCALL_H #define _ASM_HEXAGON_SYSCALL_H +#include <uapi/linux/audit.h> +#include <linux/err.h> +#include <asm/ptrace.h> + typedef long (*syscall_fn)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); @@ -35,12 +26,49 @@ static inline long syscall_get_nr(struct task_struct *task, return regs->r06; } +static inline void syscall_set_nr(struct task_struct *task, + struct pt_regs *regs, + int nr) +{ + regs->r06 = nr; +} + static inline void syscall_get_arguments(struct task_struct *task, struct pt_regs *regs, - unsigned int i, unsigned int n, unsigned long *args) { - BUG_ON(i + n > 6); - memcpy(args, &(®s->r00)[i], n * sizeof(args[0])); + memcpy(args, &(®s->r00)[0], 6 * sizeof(args[0])); } + +static inline void syscall_set_arguments(struct task_struct *task, + struct pt_regs *regs, + unsigned long *args) +{ + memcpy(&(®s->r00)[0], args, 6 * sizeof(args[0])); +} + +static inline long syscall_get_error(struct task_struct *task, + struct pt_regs *regs) +{ + return IS_ERR_VALUE(regs->r00) ? regs->r00 : 0; +} + +static inline long syscall_get_return_value(struct task_struct *task, + struct pt_regs *regs) +{ + return regs->r00; +} + +static inline void syscall_set_return_value(struct task_struct *task, + struct pt_regs *regs, + int error, long val) +{ + regs->r00 = (long) error ?: val; +} + +static inline int syscall_get_arch(struct task_struct *task) +{ + return AUDIT_ARCH_HEXAGON; +} + #endif diff --git a/arch/hexagon/include/asm/syscalls.h b/arch/hexagon/include/asm/syscalls.h new file mode 100644 index 000000000000..40f2d08bec92 --- /dev/null +++ b/arch/hexagon/include/asm/syscalls.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include <asm-generic/syscalls.h> + +asmlinkage long sys_hexagon_fadvise64_64(int fd, int advice, + u32 a2, u32 a3, u32 a4, u32 a5); diff --git a/arch/hexagon/include/asm/thread_info.h b/arch/hexagon/include/asm/thread_info.h index f7c32406a711..e90f280b9ce3 100644 --- a/arch/hexagon/include/asm/thread_info.h +++ b/arch/hexagon/include/asm/thread_info.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Thread support for the Hexagon architecture * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_THREAD_INFO_H @@ -35,10 +22,6 @@ #ifndef __ASSEMBLY__ -typedef struct { - unsigned long seg; -} mm_segment_t; - /* * This is union'd with the "bottom" of the kernel stack. * It keeps track of thread info which is handy for routines @@ -47,16 +30,13 @@ typedef struct { struct thread_info { struct task_struct *task; /* main task structure */ - struct exec_domain *exec_domain; /* execution domain */ unsigned long flags; /* low level flags */ __u32 cpu; /* current cpu */ int preempt_count; /* 0=>preemptible,<0=>BUG */ - mm_segment_t addr_limit; /* segmentation sux */ /* * used for syscalls somehow; * seems to have a function pointer and four arguments */ - struct restart_block restart_block; /* Points to the current pt_regs frame */ struct pt_regs *regs; /* @@ -73,30 +53,18 @@ struct thread_info { #endif /* __ASSEMBLY__ */ -/* looks like "linux/hardirq.h" uses this. */ - -#define PREEMPT_ACTIVE 0x10000000 - #ifndef __ASSEMBLY__ #define INIT_THREAD_INFO(tsk) \ { \ .task = &tsk, \ - .exec_domain = &default_exec_domain, \ .flags = 0, \ .cpu = 0, \ .preempt_count = 1, \ - .addr_limit = KERNEL_DS, \ - .restart_block = { \ - .fn = do_no_restart_syscall, \ - }, \ .sp = 0, \ .regs = NULL, \ } -#define init_thread_info (init_thread_union.thread_info) -#define init_stack (init_thread_union.stack) - /* Tacky preprocessor trickery */ #define qqstr(s) qstr(s) #define qstr(s) #s @@ -121,6 +89,7 @@ register struct thread_info *__current_thread_info asm(QUOTED_THREADINFO_REG); #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_SINGLESTEP 4 /* restore ss @ return to usr mode */ #define TIF_RESTORE_SIGMASK 6 /* restore sig mask in do_signal() */ +#define TIF_NOTIFY_SIGNAL 7 /* signal notifications exist */ /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_MEMDIE 17 /* OOM killer killed process */ @@ -129,6 +98,7 @@ register struct thread_info *__current_thread_info asm(QUOTED_THREADINFO_REG); #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) +#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL) /* work to do on interrupt/exception return - All but TIF_SYSCALL_TRACE */ #define _TIF_WORK_MASK (0x0000FFFF & ~_TIF_SYSCALL_TRACE) diff --git a/arch/hexagon/include/asm/time.h b/arch/hexagon/include/asm/time.h index deda170c03b8..7d3d22d472bf 100644 --- a/arch/hexagon/include/asm/time.h +++ b/arch/hexagon/include/asm/time.h @@ -1,19 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef ASM_TIME_H diff --git a/arch/hexagon/include/asm/timer-regs.h b/arch/hexagon/include/asm/timer-regs.h deleted file mode 100644 index 79912b8c1e5b..000000000000 --- a/arch/hexagon/include/asm/timer-regs.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Timer support for Hexagon - * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef _ASM_TIMER_REGS_H -#define _ASM_TIMER_REGS_H - -/* This stuff should go into a platform specific file */ -#define TCX0_CLK_RATE 19200 -#define TIMER_ENABLE 0 -#define TIMER_CLR_ON_MATCH 1 - -/* - * 8x50 HDD Specs 5-8. Simulator co-sim not fixed until - * release 1.1, and then it's "adjustable" and probably not defaulted. - */ -#define RTOS_TIMER_INT 3 -#ifdef CONFIG_HEXAGON_COMET -#define RTOS_TIMER_REGS_ADDR 0xAB000000UL -#endif -#define SLEEP_CLK_RATE 32000 - -#endif diff --git a/arch/hexagon/include/asm/timex.h b/arch/hexagon/include/asm/timex.h index f63fe132f072..dfe69e118b2b 100644 --- a/arch/hexagon/include/asm/timex.h +++ b/arch/hexagon/include/asm/timex.h @@ -1,35 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_TIMEX_H #define _ASM_TIMEX_H #include <asm-generic/timex.h> -#include <asm/timer-regs.h> +#include <asm/hexagon_vm.h> /* Using TCX0 as our clock. CLOCK_TICK_RATE scheduled to be removed. */ -#define CLOCK_TICK_RATE TCX0_CLK_RATE +#define CLOCK_TICK_RATE 19200 #define ARCH_HAS_READ_CURRENT_TIMER static inline int read_current_timer(unsigned long *timer_val) { - *timer_val = (unsigned long) __vmgettime(); + *timer_val = __vmgettime(); return 0; } diff --git a/arch/hexagon/include/asm/tlb.h b/arch/hexagon/include/asm/tlb.h index 2f00772cc08a..2c9390e7ca8d 100644 --- a/arch/hexagon/include/asm/tlb.h +++ b/arch/hexagon/include/asm/tlb.h @@ -1,19 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_TLB_H @@ -22,18 +9,6 @@ #include <linux/pagemap.h> #include <asm/tlbflush.h> -/* - * We don't need any special per-pte or per-vma handling... - */ -#define tlb_start_vma(tlb, vma) do { } while (0) -#define tlb_end_vma(tlb, vma) do { } while (0) -#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) - -/* - * .. because we flush the whole mm when it fills up - */ -#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) - #include <asm-generic/tlb.h> #endif diff --git a/arch/hexagon/include/asm/tlbflush.h b/arch/hexagon/include/asm/tlbflush.h index 62d95a9705c4..a7c9ab398cab 100644 --- a/arch/hexagon/include/asm/tlbflush.h +++ b/arch/hexagon/include/asm/tlbflush.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * TLB flush support for Hexagon * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_TLBFLUSH_H diff --git a/arch/hexagon/include/asm/traps.h b/arch/hexagon/include/asm/traps.h index ec11285012cf..3ea5fc84c328 100644 --- a/arch/hexagon/include/asm/traps.h +++ b/arch/hexagon/include/asm/traps.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Trap support for Hexagon * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_HEXAGON_TRAPS_H diff --git a/arch/hexagon/include/asm/uaccess.h b/arch/hexagon/include/asm/uaccess.h index e4127e4d6a5b..bff77efc0d9a 100644 --- a/arch/hexagon/include/asm/uaccess.h +++ b/arch/hexagon/include/asm/uaccess.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * User memory access support for Hexagon * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_UACCESS_H @@ -23,41 +10,9 @@ /* * User space memory access functions */ -#include <linux/sched.h> -#include <linux/mm.h> -#include <asm/segment.h> #include <asm/sections.h> /* - * access_ok: - Checks if a user space pointer is valid - * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE. Note that - * %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe - * to write to a block, it is always safe to read from it. - * @addr: User space pointer to start of block to check - * @size: Size of block to check - * - * Context: User context only. This function may sleep. - * - * Checks if a pointer to a block of memory in user space is valid. - * - * Returns true (nonzero) if the memory block *may* be valid, false (zero) - * if it is definitely invalid. - * - * User address space in Hexagon, like x86, goes to 0xbfffffff, so the - * simple MSB-based tests used by MIPS won't work. Some further - * optimization is probably possible here, but for now, keep it - * reasonably simple and not *too* slow. After all, we've got the - * MMU for backup. - */ -#define VERIFY_READ 0 -#define VERIFY_WRITE 1 - -#define __access_ok(addr, size) \ - ((get_fs().seg == KERNEL_DS.seg) || \ - (((unsigned long)addr < get_fs().seg) && \ - (unsigned long)size < (get_fs().seg - (unsigned long)addr))) - -/* * When a kernel-mode page fault is taken, the faulting instruction * address is checked against a table of exception_table_entries. * Each entry is a tuple of the address of an instruction that may @@ -67,50 +22,17 @@ */ /* Assembly somewhat optimized copy routines */ -unsigned long __copy_from_user_hexagon(void *to, const void __user *from, +unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n); -unsigned long __copy_to_user_hexagon(void __user *to, const void *from, +unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n); - -#define __copy_from_user(to, from, n) __copy_from_user_hexagon(to, from, n) -#define __copy_to_user(to, from, n) __copy_to_user_hexagon(to, from, n) - -/* - * XXX todo: some additonal performance gain is possible by - * implementing __copy_to/from_user_inatomic, which is much - * like __copy_to/from_user, but performs slightly less checking. - */ +#define INLINE_COPY_FROM_USER +#define INLINE_COPY_TO_USER __kernel_size_t __clear_user_hexagon(void __user *dest, unsigned long count); #define __clear_user(a, s) __clear_user_hexagon((a), (s)) -#define __strncpy_from_user(dst, src, n) hexagon_strncpy_from_user(dst, src, n) - -/* get around the ifndef in asm-generic/uaccess.h */ -#define __strnlen_user __strnlen_user - -extern long __strnlen_user(const char __user *src, long n); - -static inline long hexagon_strncpy_from_user(char *dst, const char __user *src, - long n); - #include <asm-generic/uaccess.h> -/* Todo: an actual accelerated version of this. */ -static inline long hexagon_strncpy_from_user(char *dst, const char __user *src, - long n) -{ - long res = __strnlen_user(src, n); - - /* return from strnlen can't be zero -- that would be rubbish. */ - - if (res > n) { - copy_from_user(dst, src, n); - return n; - } else { - copy_from_user(dst, src, res); - return res-1; - } -} #endif diff --git a/arch/hexagon/include/asm/unistd.h b/arch/hexagon/include/asm/unistd.h new file mode 100644 index 000000000000..1f462bade75c --- /dev/null +++ b/arch/hexagon/include/asm/unistd.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ + +#define __ARCH_WANT_STAT64 +#define __ARCH_WANT_SYS_CLONE +#define __ARCH_WANT_SYS_VFORK +#define __ARCH_WANT_SYS_FORK + +#define __ARCH_BROKEN_SYS_CLONE3 + +#include <uapi/asm/unistd.h> diff --git a/arch/hexagon/include/asm/vdso.h b/arch/hexagon/include/asm/vdso.h index ed08e6c6886d..e8f621f9fe55 100644 --- a/arch/hexagon/include/asm/vdso.h +++ b/arch/hexagon/include/asm/vdso.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * vDSO implementation for Hexagon * * Copyright (c) 2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef __ASM_VDSO_H diff --git a/arch/hexagon/include/asm/vermagic.h b/arch/hexagon/include/asm/vermagic.h new file mode 100644 index 000000000000..0e8dedc8c486 --- /dev/null +++ b/arch/hexagon/include/asm/vermagic.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + */ + +#ifndef _ASM_VERMAGIC_H +#define _ASM_VERMAGIC_H + +#include <linux/stringify.h> + +#define MODULE_ARCH_VERMAGIC __stringify(PROCESSOR_MODEL_NAME) " " + +#endif /* _ASM_VERMAGIC_H */ diff --git a/arch/hexagon/include/asm/vm_fault.h b/arch/hexagon/include/asm/vm_fault.h index 9b0e9c50ceda..27842ef1dd2e 100644 --- a/arch/hexagon/include/asm/vm_fault.h +++ b/arch/hexagon/include/asm/vm_fault.h @@ -1,19 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_HEXAGON_VM_FAULT_H diff --git a/arch/hexagon/include/asm/vm_mmu.h b/arch/hexagon/include/asm/vm_mmu.h index 096537d8f4c5..c3531384f049 100644 --- a/arch/hexagon/include/asm/vm_mmu.h +++ b/arch/hexagon/include/asm/vm_mmu.h @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Hexagon VM page table entry definitions * * Copyright (c) 2010-2011,2013 The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #ifndef _ASM_VM_MMU_H @@ -78,7 +65,7 @@ #define __HEXAGON_C_WB_L2 0x7 /* Write-back, with L2 */ /* - * This can be overriden, but we're defaulting to the most aggressive + * This can be overridden, but we're defaulting to the most aggressive * cache policy, the better to find bugs sooner. */ diff --git a/arch/hexagon/include/asm/vmalloc.h b/arch/hexagon/include/asm/vmalloc.h new file mode 100644 index 000000000000..7b04609e525c --- /dev/null +++ b/arch/hexagon/include/asm/vmalloc.h @@ -0,0 +1,4 @@ +#ifndef _ASM_HEXAGON_VMALLOC_H +#define _ASM_HEXAGON_VMALLOC_H + +#endif /* _ASM_HEXAGON_VMALLOC_H */ diff --git a/arch/hexagon/include/uapi/asm/Kbuild b/arch/hexagon/include/uapi/asm/Kbuild index c31706c38631..2501e82a1a0a 100644 --- a/arch/hexagon/include/uapi/asm/Kbuild +++ b/arch/hexagon/include/uapi/asm/Kbuild @@ -1,15 +1,4 @@ -# UAPI Header export list -include include/uapi/asm-generic/Kbuild.asm +# SPDX-License-Identifier: GPL-2.0 +syscall-y += unistd_32.h -header-y += bitsperlong.h -header-y += byteorder.h -header-y += kvm_para.h -header-y += param.h -header-y += ptrace.h -header-y += registers.h -header-y += setup.h -header-y += sigcontext.h -header-y += signal.h -header-y += swab.h -header-y += unistd.h -header-y += user.h +generic-y += ucontext.h diff --git a/arch/hexagon/include/uapi/asm/bitsperlong.h b/arch/hexagon/include/uapi/asm/bitsperlong.h deleted file mode 100644 index 4a658151383d..000000000000 --- a/arch/hexagon/include/uapi/asm/bitsperlong.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef __ASM_HEXAGON_BITSPERLONG_H -#define __ASM_HEXAGON_BITSPERLONG_H - -#define __BITS_PER_LONG 32 - -#include <asm-generic/bitsperlong.h> - -#endif diff --git a/arch/hexagon/include/uapi/asm/byteorder.h b/arch/hexagon/include/uapi/asm/byteorder.h index e31f3f7d9a45..1364fa4b27e8 100644 --- a/arch/hexagon/include/uapi/asm/byteorder.h +++ b/arch/hexagon/include/uapi/asm/byteorder.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. * diff --git a/arch/hexagon/include/uapi/asm/kvm_para.h b/arch/hexagon/include/uapi/asm/kvm_para.h deleted file mode 100644 index 14fab8f0b957..000000000000 --- a/arch/hexagon/include/uapi/asm/kvm_para.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/kvm_para.h> diff --git a/arch/hexagon/include/uapi/asm/param.h b/arch/hexagon/include/uapi/asm/param.h index 5cec8c0417fb..a1283866d599 100644 --- a/arch/hexagon/include/uapi/asm/param.h +++ b/arch/hexagon/include/uapi/asm/param.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. * diff --git a/arch/hexagon/include/uapi/asm/ptrace.h b/arch/hexagon/include/uapi/asm/ptrace.h index 065e5b32313f..2a3ea14ad9b9 100644 --- a/arch/hexagon/include/uapi/asm/ptrace.h +++ b/arch/hexagon/include/uapi/asm/ptrace.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Ptrace definitions for the Hexagon architecture * @@ -28,17 +29,4 @@ #define profile_pc(regs) instruction_pointer(regs) -/* kprobe-based event tracer support */ -extern int regs_query_register_offset(const char *name); -extern const char *regs_query_register_name(unsigned int offset); - -#define current_pt_regs() \ - ((struct pt_regs *) \ - ((unsigned long)current_thread_info() + THREAD_SIZE) - 1) - -#if CONFIG_HEXAGON_ARCH_VERSION >= 4 -#define arch_has_single_step() (1) -#endif - - #endif diff --git a/arch/hexagon/include/uapi/asm/registers.h b/arch/hexagon/include/uapi/asm/registers.h index 487d6ceca5e7..d51270f3b358 100644 --- a/arch/hexagon/include/uapi/asm/registers.h +++ b/arch/hexagon/include/uapi/asm/registers.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Register definitions for the Hexagon architecture */ @@ -6,8 +7,6 @@ #ifndef _ASM_REGISTERS_H #define _ASM_REGISTERS_H -#define SP r29 - #ifndef __ASSEMBLY__ /* See kernel/entry.S for further documentation. */ @@ -215,7 +214,7 @@ struct pt_regs { #define pt_clr_singlestep(regs) ((regs)->hvmer.vmest &= ~(1<<HVM_VMEST_SS_SFT)) #define pt_set_rte_sp(regs, sp) do {\ - pt_psp(regs) = (regs)->SP = (sp);\ + pt_psp(regs) = (regs)->r29 = (sp);\ } while (0) #define pt_set_kmode(regs) \ diff --git a/arch/hexagon/include/uapi/asm/setup.h b/arch/hexagon/include/uapi/asm/setup.h index e48285e4af96..598f74f671f6 100644 --- a/arch/hexagon/include/uapi/asm/setup.h +++ b/arch/hexagon/include/uapi/asm/setup.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. * @@ -16,14 +17,9 @@ * 02110-1301, USA. */ -#ifndef _ASM_SETUP_H -#define _ASM_SETUP_H +#ifndef _UAPI_ASM_HEXAGON_SETUP_H +#define _UAPI_ASM_HEXAGON_SETUP_H -#include <linux/init.h> #include <asm-generic/setup.h> -extern char external_cmdline_buffer; - -void __init setup_arch_memory(void); - #endif diff --git a/arch/hexagon/include/uapi/asm/sigcontext.h b/arch/hexagon/include/uapi/asm/sigcontext.h index b6ba5369ccc6..7171edb1b8b7 100644 --- a/arch/hexagon/include/uapi/asm/sigcontext.h +++ b/arch/hexagon/include/uapi/asm/sigcontext.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. * diff --git a/arch/hexagon/include/uapi/asm/signal.h b/arch/hexagon/include/uapi/asm/signal.h index 98106e55ad4f..a08fc425387d 100644 --- a/arch/hexagon/include/uapi/asm/signal.h +++ b/arch/hexagon/include/uapi/asm/signal.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. * @@ -19,8 +20,6 @@ #ifndef _ASM_SIGNAL_H #define _ASM_SIGNAL_H -#include <uapi/asm/registers.h> - extern unsigned long __rt_sigtramp_template[2]; void do_signal(struct pt_regs *regs); diff --git a/arch/hexagon/include/uapi/asm/swab.h b/arch/hexagon/include/uapi/asm/swab.h index 9069e9247a2e..b39f12104da4 100644 --- a/arch/hexagon/include/uapi/asm/swab.h +++ b/arch/hexagon/include/uapi/asm/swab.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. * diff --git a/arch/hexagon/include/uapi/asm/unistd.h b/arch/hexagon/include/uapi/asm/unistd.h index ffee405d6803..a3b0cac25580 100644 --- a/arch/hexagon/include/uapi/asm/unistd.h +++ b/arch/hexagon/include/uapi/asm/unistd.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * Syscall support for Hexagon * @@ -26,10 +27,7 @@ * See also: syscalltab.c */ -#define sys_mmap2 sys_mmap_pgoff -#define __ARCH_WANT_SYS_EXECVE -#define __ARCH_WANT_SYS_CLONE -#define __ARCH_WANT_SYS_VFORK -#define __ARCH_WANT_SYS_FORK +#include <asm/unistd_32.h> -#include <asm-generic/unistd.h> +#define __NR_sync_file_range2 84 +#undef __NR_sync_file_range diff --git a/arch/hexagon/include/uapi/asm/user.h b/arch/hexagon/include/uapi/asm/user.h index 3dae94d9ced7..abae6a4b5813 100644 --- a/arch/hexagon/include/uapi/asm/user.h +++ b/arch/hexagon/include/uapi/asm/user.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ #ifndef HEXAGON_ASM_USER_H #define HEXAGON_ASM_USER_H @@ -55,15 +56,10 @@ struct user_regs_struct { unsigned long pc; unsigned long cause; unsigned long badva; -#if CONFIG_HEXAGON_ARCH_VERSION < 4 - unsigned long pad1; /* pad out to 48 words total */ - unsigned long pad2; /* pad out to 48 words total */ - unsigned long pad3; /* pad out to 48 words total */ -#else + /* cs0 and cs1 are only available with HEXAGON_ARCH_VERSION >= 4 */ unsigned long cs0; unsigned long cs1; unsigned long pad1; /* pad out to 48 words total */ -#endif }; #endif diff --git a/arch/hexagon/kernel/.gitignore b/arch/hexagon/kernel/.gitignore new file mode 100644 index 000000000000..c5f676c3c224 --- /dev/null +++ b/arch/hexagon/kernel/.gitignore @@ -0,0 +1 @@ +vmlinux.lds diff --git a/arch/hexagon/kernel/Makefile b/arch/hexagon/kernel/Makefile index 29fc933a7722..8e0fb4a62315 100644 --- a/arch/hexagon/kernel/Makefile +++ b/arch/hexagon/kernel/Makefile @@ -1,5 +1,7 @@ -extra-y := head.o vmlinux.lds +# SPDX-License-Identifier: GPL-2.0 +always-$(KBUILD_BUILTIN) := vmlinux.lds +obj-y += head.o obj-$(CONFIG_SMP) += smp.o obj-y += setup.o irq_cpu.o traps.o syscalltab.o signal.o time.o diff --git a/arch/hexagon/kernel/Makefile.syscalls b/arch/hexagon/kernel/Makefile.syscalls new file mode 100644 index 000000000000..d2b7c5d44d95 --- /dev/null +++ b/arch/hexagon/kernel/Makefile.syscalls @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +syscall_abis_32 += hexagon time32 stat64 rlimit renameat diff --git a/arch/hexagon/kernel/asm-offsets.c b/arch/hexagon/kernel/asm-offsets.c index 308be68d4fb3..50eea9fa6f13 100644 --- a/arch/hexagon/kernel/asm-offsets.c +++ b/arch/hexagon/kernel/asm-offsets.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 1996 David S. Miller * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Ralf Baechle @@ -6,26 +7,12 @@ * Copyright (C) 2000 MIPS Technologies, Inc. * * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ +#define COMPILE_OFFSETS #include <linux/compat.h> #include <linux/types.h> #include <linux/sched.h> -#include <linux/mm.h> #include <linux/interrupt.h> #include <linux/kbuild.h> #include <asm/ptrace.h> diff --git a/arch/hexagon/kernel/dma.c b/arch/hexagon/kernel/dma.c index b74f9bae31a3..882680e81a30 100644 --- a/arch/hexagon/kernel/dma.c +++ b/arch/hexagon/kernel/dma.c @@ -1,148 +1,19 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * DMA implementation for Hexagon * * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ -#include <linux/dma-mapping.h> -#include <linux/bootmem.h> -#include <linux/genalloc.h> -#include <asm/dma-mapping.h> -#include <linux/module.h> +#include <linux/dma-map-ops.h> +#include <linux/memblock.h> #include <asm/page.h> -struct dma_map_ops *dma_ops; -EXPORT_SYMBOL(dma_ops); - -int bad_dma_address; /* globals are automatically initialized to zero */ - -static inline void *dma_addr_to_virt(dma_addr_t dma_addr) +void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, + enum dma_data_direction dir) { - return phys_to_virt((unsigned long) dma_addr); -} - -int dma_supported(struct device *dev, u64 mask) -{ - if (mask == DMA_BIT_MASK(32)) - return 1; - else - return 0; -} -EXPORT_SYMBOL(dma_supported); - -int dma_set_mask(struct device *dev, u64 mask) -{ - if (!dev->dma_mask || !dma_supported(dev, mask)) - return -EIO; - - *dev->dma_mask = mask; - - return 0; -} -EXPORT_SYMBOL(dma_set_mask); - -static struct gen_pool *coherent_pool; - - -/* Allocates from a pool of uncached memory that was reserved at boot time */ + void *addr = phys_to_virt(paddr); -static void *hexagon_dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_addr, gfp_t flag, - struct dma_attrs *attrs) -{ - void *ret; - - /* - * Our max_low_pfn should have been backed off by 16MB in - * mm/init.c to create DMA coherent space. Use that as the VA - * for the pool. - */ - - if (coherent_pool == NULL) { - coherent_pool = gen_pool_create(PAGE_SHIFT, -1); - - if (coherent_pool == NULL) - panic("Can't create %s() memory pool!", __func__); - else - gen_pool_add(coherent_pool, - pfn_to_virt(max_low_pfn), - hexagon_coherent_pool_size, -1); - } - - ret = (void *) gen_pool_alloc(coherent_pool, size); - - if (ret) { - memset(ret, 0, size); - *dma_addr = (dma_addr_t) virt_to_phys(ret); - } else - *dma_addr = ~0; - - return ret; -} - -static void hexagon_free_coherent(struct device *dev, size_t size, void *vaddr, - dma_addr_t dma_addr, struct dma_attrs *attrs) -{ - gen_pool_free(coherent_pool, (unsigned long) vaddr, size); -} - -static int check_addr(const char *name, struct device *hwdev, - dma_addr_t bus, size_t size) -{ - if (hwdev && hwdev->dma_mask && !dma_capable(hwdev, bus, size)) { - if (*hwdev->dma_mask >= DMA_BIT_MASK(32)) - printk(KERN_ERR - "%s: overflow %Lx+%zu of device mask %Lx\n", - name, (long long)bus, size, - (long long)*hwdev->dma_mask); - return 0; - } - return 1; -} - -static int hexagon_map_sg(struct device *hwdev, struct scatterlist *sg, - int nents, enum dma_data_direction dir, - struct dma_attrs *attrs) -{ - struct scatterlist *s; - int i; - - WARN_ON(nents == 0 || sg[0].length == 0); - - for_each_sg(sg, s, nents, i) { - s->dma_address = sg_phys(s); - if (!check_addr("map_sg", hwdev, s->dma_address, s->length)) - return 0; - - s->dma_length = s->length; - - flush_dcache_range(dma_addr_to_virt(s->dma_address), - dma_addr_to_virt(s->dma_address + s->length)); - } - - return nents; -} - -/* - * address is virtual - */ -static inline void dma_sync(void *addr, size_t size, - enum dma_data_direction dir) -{ switch (dir) { case DMA_TO_DEVICE: hexagon_clean_dcache_range((unsigned long) addr, @@ -161,69 +32,13 @@ static inline void dma_sync(void *addr, size_t size, } } -/** - * hexagon_map_page() - maps an address for device DMA - * @dev: pointer to DMA device - * @page: pointer to page struct of DMA memory - * @offset: offset within page - * @size: size of memory to map - * @dir: transfer direction - * @attrs: pointer to DMA attrs (not used) - * - * Called to map a memory address to a DMA address prior - * to accesses to/from device. - * - * We don't particularly have many hoops to jump through - * so far. Straight translation between phys and virtual. - * - * DMA is not cache coherent so sync is necessary; this - * seems to be a convenient place to do it. - * +/* + * Our max_low_pfn should have been backed off by 16MB in mm/init.c to create + * DMA coherent space. Use that for the pool. */ -static dma_addr_t hexagon_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, - enum dma_data_direction dir, - struct dma_attrs *attrs) -{ - dma_addr_t bus = page_to_phys(page) + offset; - WARN_ON(size == 0); - - if (!check_addr("map_single", dev, bus, size)) - return bad_dma_address; - - dma_sync(dma_addr_to_virt(bus), size, dir); - - return bus; -} - -static void hexagon_sync_single_for_cpu(struct device *dev, - dma_addr_t dma_handle, size_t size, - enum dma_data_direction dir) +static int __init hexagon_dma_init(void) { - dma_sync(dma_addr_to_virt(dma_handle), size, dir); -} - -static void hexagon_sync_single_for_device(struct device *dev, - dma_addr_t dma_handle, size_t size, - enum dma_data_direction dir) -{ - dma_sync(dma_addr_to_virt(dma_handle), size, dir); -} - -struct dma_map_ops hexagon_dma_ops = { - .alloc = hexagon_dma_alloc_coherent, - .free = hexagon_free_coherent, - .map_sg = hexagon_map_sg, - .map_page = hexagon_map_page, - .sync_single_for_cpu = hexagon_sync_single_for_cpu, - .sync_single_for_device = hexagon_sync_single_for_device, - .is_phys = 1, -}; - -void __init hexagon_dma_init(void) -{ - if (dma_ops) - return; - - dma_ops = &hexagon_dma_ops; + return dma_init_global_coherent(PFN_PHYS(max_low_pfn), + hexagon_coherent_pool_size); } +core_initcall(hexagon_dma_init); diff --git a/arch/hexagon/kernel/head.S b/arch/hexagon/kernel/head.S index b9b63d085db2..0b016308cc79 100644 --- a/arch/hexagon/kernel/head.S +++ b/arch/hexagon/kernel/head.S @@ -1,22 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Early kernel startup code for Hexagon * * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include <linux/linkage.h> diff --git a/arch/hexagon/kernel/hexagon_ksyms.c b/arch/hexagon/kernel/hexagon_ksyms.c index 32b1379d6877..36a80e31d187 100644 --- a/arch/hexagon/kernel/hexagon_ksyms.c +++ b/arch/hexagon/kernel/hexagon_ksyms.c @@ -1,40 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Export of symbols defined in assembly files and/or libgcc. * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ +#include <linux/dma-mapping.h> #include <asm/hexagon_vm.h> -#include <asm/uaccess.h> +#include <asm/io.h> +#include <linux/uaccess.h> -EXPORT_SYMBOL(__copy_from_user_hexagon); -EXPORT_SYMBOL(__copy_to_user_hexagon); +/* Additional functions */ +EXPORT_SYMBOL(__clear_user_hexagon); +EXPORT_SYMBOL(raw_copy_from_user); +EXPORT_SYMBOL(raw_copy_to_user); EXPORT_SYMBOL(__vmgetie); EXPORT_SYMBOL(__vmsetie); +EXPORT_SYMBOL(__vmyield); +EXPORT_SYMBOL(empty_zero_page); EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memset); +/* Additional variables */ +EXPORT_SYMBOL(__phys_offset); +EXPORT_SYMBOL(_dflt_cache_att); + #define DECLARE_EXPORT(name) \ extern void name(void); EXPORT_SYMBOL(name) /* Symbols found in libgcc that assorted kernel modules need */ DECLARE_EXPORT(__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes); +/* Additional functions */ DECLARE_EXPORT(__hexagon_divsi3); DECLARE_EXPORT(__hexagon_modsi3); DECLARE_EXPORT(__hexagon_udivsi3); DECLARE_EXPORT(__hexagon_umodsi3); +DECLARE_EXPORT(csum_tcpudp_magic); diff --git a/arch/hexagon/kernel/irq_cpu.c b/arch/hexagon/kernel/irq_cpu.c index 85883e1fdc12..9c92f2fc7e05 100644 --- a/arch/hexagon/kernel/irq_cpu.c +++ b/arch/hexagon/kernel/irq_cpu.c @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * First-level interrupt controller model for Hexagon. * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include <linux/interrupt.h> diff --git a/arch/hexagon/kernel/kgdb.c b/arch/hexagon/kernel/kgdb.c index 82d5c2593323..903609fbbbdc 100644 --- a/arch/hexagon/kernel/kgdb.c +++ b/arch/hexagon/kernel/kgdb.c @@ -1,23 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * arch/hexagon/kernel/kgdb.c - Hexagon KGDB Support * * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ +#include <linux/irq.h> +#include <linux/sched.h> +#include <linux/sched/task_stack.h> #include <linux/kdebug.h> #include <linux/kgdb.h> @@ -80,7 +70,7 @@ struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { { "syscall_nr", GDB_SIZEOF_REG, offsetof(struct pt_regs, syscall_nr)}, }; -struct kgdb_arch arch_kgdb_ops = { +const struct kgdb_arch arch_kgdb_ops = { /* trap0(#0xDB) 0x0cdb0054 */ .gdb_bpt_instr = {0x54, 0x00, 0xdb, 0x0c}, }; @@ -112,38 +102,6 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc) instruction_pointer(regs) = pc; } -#ifdef CONFIG_SMP - -/** - * kgdb_roundup_cpus - Get other CPUs into a holding pattern - * @flags: Current IRQ state - * - * On SMP systems, we need to get the attention of the other CPUs - * and get them be in a known state. This should do what is needed - * to get the other CPUs to call kgdb_wait(). Note that on some arches, - * the NMI approach is not used for rounding up all the CPUs. For example, - * in case of MIPS, smp_call_function() is used to roundup CPUs. In - * this case, we have to make sure that interrupts are enabled before - * calling smp_call_function(). The argument to this function is - * the flags that will be used when restoring the interrupts. There is - * local_irq_save() call before kgdb_roundup_cpus(). - * - * On non-SMP systems, this is not called. - */ - -static void hexagon_kgdb_nmi_hook(void *ignored) -{ - kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs()); -} - -void kgdb_roundup_cpus(unsigned long flags) -{ - local_irq_enable(); - smp_call_function(hexagon_kgdb_nmi_hook, NULL, 0); - local_irq_disable(); -} -#endif - /* Not yet working */ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, @@ -234,9 +192,9 @@ static struct notifier_block kgdb_notifier = { }; /** - * kgdb_arch_init - Perform any architecture specific initalization. + * kgdb_arch_init - Perform any architecture specific initialization. * - * This function will handle the initalization of any architecture + * This function will handle the initialization of any architecture * specific callbacks. */ int kgdb_arch_init(void) diff --git a/arch/hexagon/kernel/module.c b/arch/hexagon/kernel/module.c index 477d07a5646c..cb3bf19b0640 100644 --- a/arch/hexagon/kernel/module.c +++ b/arch/hexagon/kernel/module.c @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Kernel module loader for Hexagon * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include <asm/module.h> @@ -133,7 +120,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, } case R_HEXAGON_HI16: value = (value>>16) & 0xffff; - /* fallthrough */ + fallthrough; case R_HEXAGON_LO16: *location &= ~0x00c03fff; *location |= value & 0x3fff; diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c index 0a0dd5c05b46..15b4992bfa29 100644 --- a/arch/hexagon/kernel/process.c +++ b/arch/hexagon/kernel/process.c @@ -1,30 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Process creation support for Hexagon * * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ +#include <linux/cpu.h> #include <linux/sched.h> +#include <linux/sched/debug.h> +#include <linux/sched/task.h> +#include <linux/sched/task_stack.h> #include <linux/types.h> #include <linux/module.h> #include <linux/tick.h> #include <linux/uaccess.h> #include <linux/slab.h> -#include <linux/tracehook.h> +#include <linux/resume_user_mode.h> /* * Program thread launch. Often defined as a macro in processor.h, @@ -37,8 +28,6 @@ */ void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp) { - /* Set to run with user-mode data segmentation */ - set_fs(USER_DS); /* We want to zero all data-containing registers. Is this overkill? */ memset(regs, 0, sizeof(*regs)); /* We might want to also zero all Processor registers here */ @@ -56,23 +45,16 @@ void arch_cpu_idle(void) { __vmwait(); /* interrupts wake us up, but irqs are still disabled */ - local_irq_enable(); -} - -/* - * Return saved PC of a blocked thread - */ -unsigned long thread_saved_pc(struct task_struct *tsk) -{ - return 0; } /* * Copy architecture-specific thread state */ -int copy_thread(unsigned long clone_flags, unsigned long usp, - unsigned long arg, struct task_struct *p) +int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) { + u64 clone_flags = args->flags; + unsigned long usp = args->stack; + unsigned long tls = args->tls; struct thread_info *ti = task_thread_info(p); struct hexagon_switch_stack *ss; struct pt_regs *childregs; @@ -93,11 +75,11 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, sizeof(*ss)); ss->lr = (unsigned long)ret_from_fork; p->thread.switch_sp = ss; - if (unlikely(p->flags & PF_KTHREAD)) { + if (unlikely(args->fn)) { memset(childregs, 0, sizeof(struct pt_regs)); /* r24 <- fn, r25 <- arg */ - ss->r24 = usp; - ss->r25 = arg; + ss->r24 = (unsigned long)args->fn; + ss->r25 = (unsigned long)args->fn_arg; pt_set_kmode(childregs); return 0; } @@ -120,32 +102,17 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, * ugp is used to provide TLS support. */ if (clone_flags & CLONE_SETTLS) - childregs->ugp = childregs->r04; + childregs->ugp = tls; /* * Parent sees new pid -- not necessary, not even possible at * this point in the fork process - * Might also want to set things like ti->addr_limit */ return 0; } /* - * Release any architecture-specific resources locked by thread - */ -void release_thread(struct task_struct *dead_task) -{ -} - -/* - * Free any architecture-specific thread data structures, etc. - */ -void exit_thread(void) -{ -} - -/* * Some archs flush debug and FPU info here */ void flush_thread(void) @@ -157,13 +124,11 @@ void flush_thread(void) * is an identification of the point at which the scheduler * was invoked by a blocked thread. */ -unsigned long get_wchan(struct task_struct *p) +unsigned long __get_wchan(struct task_struct *p) { unsigned long fp, pc; unsigned long stack_page; int count = 0; - if (!p || p == current || p->state == TASK_RUNNING) - return 0; stack_page = (unsigned long)task_stack_page(p); fp = ((struct hexagon_switch_stack *)p->thread.switch_sp)->fp; @@ -181,15 +146,6 @@ unsigned long get_wchan(struct task_struct *p) } /* - * Required placeholder. - */ -int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) -{ - return 0; -} - - -/* * Called on the exit path of event entry; see vm_entry.S * * Interrupts will already be disabled. @@ -197,6 +153,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) * Returns 0 if there's no need to re-check for more work. */ +int do_work_pending(struct pt_regs *regs, u32 thread_info_flags); int do_work_pending(struct pt_regs *regs, u32 thread_info_flags) { if (!(thread_info_flags & _TIF_WORK_MASK)) { @@ -210,14 +167,13 @@ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags) return 1; } - if (thread_info_flags & _TIF_SIGPENDING) { + if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) { do_signal(regs); return 1; } if (thread_info_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); - tracehook_notify_resume(regs); + resume_user_mode_work(regs); return 1; } diff --git a/arch/hexagon/kernel/ptrace.c b/arch/hexagon/kernel/ptrace.c index de829eb7f185..2093eee143e1 100644 --- a/arch/hexagon/kernel/ptrace.c +++ b/arch/hexagon/kernel/ptrace.c @@ -1,27 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Ptrace support for Hexagon * * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ -#include <generated/compile.h> - #include <linux/kernel.h> #include <linux/sched.h> +#include <linux/sched/task_stack.h> #include <linux/mm.h> #include <linux/smp.h> #include <linux/errno.h> @@ -49,58 +35,38 @@ void user_disable_single_step(struct task_struct *child) static int genregs_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { - int ret; - unsigned int dummy; struct pt_regs *regs = task_pt_regs(target); - - if (!regs) - return -EIO; - /* The general idea here is that the copyout must happen in * exactly the same order in which the userspace expects these * regs. Now, the sequence in userspace does not match the * sequence in the kernel, so everything past the 32 gprs * happens one at a time. */ - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - ®s->r00, 0, 32*sizeof(unsigned long)); - -#define ONEXT(KPT_REG, USR_REG) \ - if (!ret) \ - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, \ - KPT_REG, offsetof(struct user_regs_struct, USR_REG), \ - offsetof(struct user_regs_struct, USR_REG) + \ - sizeof(unsigned long)); - + membuf_write(&to, ®s->r00, 32*sizeof(unsigned long)); /* Must be exactly same sequence as struct user_regs_struct */ - ONEXT(®s->sa0, sa0); - ONEXT(®s->lc0, lc0); - ONEXT(®s->sa1, sa1); - ONEXT(®s->lc1, lc1); - ONEXT(®s->m0, m0); - ONEXT(®s->m1, m1); - ONEXT(®s->usr, usr); - ONEXT(®s->preds, p3_0); - ONEXT(®s->gp, gp); - ONEXT(®s->ugp, ugp); - ONEXT(&pt_elr(regs), pc); - dummy = pt_cause(regs); - ONEXT(&dummy, cause); - ONEXT(&pt_badva(regs), badva); + membuf_store(&to, regs->sa0); + membuf_store(&to, regs->lc0); + membuf_store(&to, regs->sa1); + membuf_store(&to, regs->lc1); + membuf_store(&to, regs->m0); + membuf_store(&to, regs->m1); + membuf_store(&to, regs->usr); + membuf_store(&to, regs->preds); + membuf_store(&to, regs->gp); + membuf_store(&to, regs->ugp); + membuf_store(&to, pt_elr(regs)); // pc + membuf_store(&to, (unsigned long)pt_cause(regs)); // cause + membuf_store(&to, pt_badva(regs)); // badva #if CONFIG_HEXAGON_ARCH_VERSION >=4 - ONEXT(®s->cs0, cs0); - ONEXT(®s->cs1, cs1); + membuf_store(&to, regs->cs0); + membuf_store(&to, regs->cs1); + return membuf_zero(&to, sizeof(unsigned long)); +#else + return membuf_zero(&to, 3 * sizeof(unsigned long)); #endif - - /* Pad the rest with zeros, if needed */ - if (!ret) - ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, - offsetof(struct user_regs_struct, pad1), -1); - return ret; } static int genregs_set(struct task_struct *target, @@ -108,7 +74,7 @@ static int genregs_set(struct task_struct *target, unsigned int pos, unsigned int count, const void *kbuf, const void __user *ubuf) { - int ret; + int ret, ignore_offset; unsigned long bucket; struct pt_regs *regs = task_pt_regs(target); @@ -145,14 +111,16 @@ static int genregs_set(struct task_struct *target, #if CONFIG_HEXAGON_ARCH_VERSION >=4 INEXT(®s->cs0, cs0); INEXT(®s->cs1, cs1); + ignore_offset = offsetof(struct user_regs_struct, pad1); +#else + ignore_offset = offsetof(struct user_regs_struct, cs0); #endif /* Ignore the rest, if needed */ if (!ret) - ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, - offsetof(struct user_regs_struct, pad1), -1); - - if (ret) + user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, + ignore_offset, -1); + else return ret; /* @@ -169,20 +137,21 @@ enum hexagon_regset { static const struct user_regset hexagon_regsets[] = { [REGSET_GENERAL] = { - .core_note_type = NT_PRSTATUS, + USER_REGSET_NOTE_TYPE(PRSTATUS), .n = ELF_NGREG, .size = sizeof(unsigned long), .align = sizeof(unsigned long), - .get = genregs_get, + .regset_get = genregs_get, .set = genregs_set, }, }; static const struct user_regset_view hexagon_user_view = { - .name = UTS_MACHINE, + .name = "hexagon", .e_machine = ELF_ARCH, .ei_osabi = ELF_OSABI, .regsets = hexagon_regsets, + .e_flags = ELF_CORE_EFLAGS, .n = ARRAY_SIZE(hexagon_regsets) }; diff --git a/arch/hexagon/kernel/reset.c b/arch/hexagon/kernel/reset.c index 6aeabc962b3b..efd70a8d2526 100644 --- a/arch/hexagon/kernel/reset.c +++ b/arch/hexagon/kernel/reset.c @@ -1,21 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ +#include <linux/reboot.h> #include <linux/smp.h> #include <asm/hexagon_vm.h> @@ -33,6 +21,5 @@ void machine_restart(char *cmd) { } -void pm_power_off(void) -{ -} +void (*pm_power_off)(void) = NULL; +EXPORT_SYMBOL(pm_power_off); diff --git a/arch/hexagon/kernel/setup.c b/arch/hexagon/kernel/setup.c index bfe13311d70d..621674e86232 100644 --- a/arch/hexagon/kernel/setup.c +++ b/arch/hexagon/kernel/setup.c @@ -1,25 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Arch related setup for Hexagon * * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include <linux/init.h> -#include <linux/bootmem.h> +#include <linux/delay.h> +#include <linux/memblock.h> #include <linux/mmzone.h> #include <linux/mm.h> #include <linux/seq_file.h> @@ -32,16 +20,13 @@ #include <asm/hexagon_vm.h> #include <asm/vm_mmu.h> #include <asm/time.h> -#ifdef CONFIG_OF -#include <asm/prom.h> -#endif char cmd_line[COMMAND_LINE_SIZE]; static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; int on_simulator; -void __cpuinit calibrate_delay(void) +void calibrate_delay(void) { loops_per_jiffy = thread_freq_mhz * 1000000 / HZ; } @@ -68,7 +53,7 @@ void __init setup_arch(char **cmdline_p) */ __vmsetvec(_K_VM_event_vector); - printk(KERN_INFO "PHYS_OFFSET=0x%08x\n", PHYS_OFFSET); + printk(KERN_INFO "PHYS_OFFSET=0x%08lx\n", PHYS_OFFSET); /* * Simulator has a few differences from the hardware. @@ -81,9 +66,9 @@ void __init setup_arch(char **cmdline_p) on_simulator = 0; if (p[0] != '\0') - strlcpy(boot_command_line, p, COMMAND_LINE_SIZE); + strscpy(boot_command_line, p, COMMAND_LINE_SIZE); else - strlcpy(boot_command_line, default_command_line, + strscpy(boot_command_line, default_command_line, COMMAND_LINE_SIZE); /* @@ -91,7 +76,7 @@ void __init setup_arch(char **cmdline_p) * are both picked up by the init code. If no reason to * make them different, pass the same pointer back. */ - strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE); + strscpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE); *cmdline_p = cmd_line; parse_early_param(); diff --git a/arch/hexagon/kernel/signal.c b/arch/hexagon/kernel/signal.c index d7c73874b515..d301f4621553 100644 --- a/arch/hexagon/kernel/signal.c +++ b/arch/hexagon/kernel/signal.c @@ -1,30 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Signal support for Hexagon processor * * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include <linux/linkage.h> #include <linux/syscalls.h> -#include <linux/tracehook.h> +#include <linux/sched/task_stack.h> + #include <asm/registers.h> #include <asm/thread_info.h> #include <asm/unistd.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #include <asm/ucontext.h> #include <asm/cacheflush.h> #include <asm/signal.h> @@ -36,18 +24,10 @@ struct rt_sigframe { struct ucontext uc; }; -static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, +static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, size_t frame_size) { - unsigned long sp = regs->r29; - - /* check if we would overflow the alt stack */ - if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size))) - return (void __user __force *)-1UL; - - /* Switch to signal stack if appropriate */ - if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0)) - sp = current->sas_ss_sp + current->sas_ss_size; + unsigned long sp = sigsp(regs->r29, ksig); return (void __user *)((sp - frame_size) & ~(sizeof(long long) - 1)); } @@ -112,20 +92,20 @@ static int restore_sigcontext(struct pt_regs *regs, /* * Setup signal stack frame with siginfo structure */ -static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info, - sigset_t *set, struct pt_regs *regs) +static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, + struct pt_regs *regs) { int err = 0; struct rt_sigframe __user *frame; struct hexagon_vdso *vdso = current->mm->context.vdso; - frame = get_sigframe(ka, regs, sizeof(struct rt_sigframe)); + frame = get_sigframe(ksig, regs, sizeof(struct rt_sigframe)); - if (!access_ok(VERIFY_WRITE, frame, sizeof(struct rt_sigframe))) - goto sigsegv; + if (!access_ok(frame, sizeof(struct rt_sigframe))) + return -EFAULT; - if (copy_siginfo_to_user(&frame->info, info)) - goto sigsegv; + if (copy_siginfo_to_user(&frame->info, &ksig->info)) + return -EFAULT; /* The on-stack signal trampoline is no longer executed; * however, the libgcc signal frame unwinding code checks for @@ -137,29 +117,26 @@ static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info, err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); err |= __save_altstack(&frame->uc.uc_stack, user_stack_pointer(regs)); if (err) - goto sigsegv; + return -EFAULT; /* Load r0/r1 pair with signumber/siginfo pointer... */ regs->r0100 = ((unsigned long long)((unsigned long)&frame->info) << 32) - | (unsigned long long)signr; + | (unsigned long long)ksig->sig; regs->r02 = (unsigned long) &frame->uc; regs->r31 = (unsigned long) vdso->rt_signal_trampoline; pt_psp(regs) = (unsigned long) frame; - pt_set_elr(regs, (unsigned long)ka->sa.sa_handler); + pt_set_elr(regs, (unsigned long)ksig->ka.sa.sa_handler); return 0; - -sigsegv: - force_sigsegv(signr, current); - return -EFAULT; } /* * Setup invocation of signal handler */ -static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, - struct pt_regs *regs) +static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) { + int ret; + /* * If we're handling a signal that aborted a system call, * set up the error return value before adding the signal @@ -173,11 +150,11 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, regs->r00 = -EINTR; break; case -ERESTARTSYS: - if (!(ka->sa.sa_flags & SA_RESTART)) { + if (!(ksig->ka.sa.sa_flags & SA_RESTART)) { regs->r00 = -EINTR; break; } - /* Fall through */ + fallthrough; case -ERESTARTNOINTR: regs->r06 = regs->syscall_nr; pt_set_elr(regs, pt_elr(regs) - 4); @@ -193,11 +170,9 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, * only set up the rt_frame flavor. */ /* If there was an error on setup, no signal was delivered. */ - if (setup_rt_frame(sig, ka, info, sigmask_to_save(), regs) < 0) - return; + ret = setup_rt_frame(ksig, sigmask_to_save(), regs); - signal_delivered(sig, info, ka, regs, - test_thread_flag(TIF_SINGLESTEP)); + signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP)); } /* @@ -205,17 +180,13 @@ static void handle_signal(int sig, siginfo_t *info, struct k_sigaction *ka, */ void do_signal(struct pt_regs *regs) { - struct k_sigaction sigact; - siginfo_t info; - int signo; + struct ksignal ksig; if (!user_mode(regs)) return; - signo = get_signal_to_deliver(&info, &sigact, regs, NULL); - - if (signo > 0) { - handle_signal(signo, &info, &sigact, regs); + if (get_signal(&ksig)) { + handle_signal(&ksig, regs); return; } @@ -249,17 +220,17 @@ no_restart: * Architecture-specific wrappers for signal-related system calls */ -asmlinkage int sys_rt_sigreturn(void) +SYSCALL_DEFINE0(rt_sigreturn) { struct pt_regs *regs = current_pt_regs(); struct rt_sigframe __user *frame; sigset_t blocked; /* Always make any pending restarted system calls return -EINTR */ - current_thread_info()->restart_block.fn = do_no_restart_syscall; + current->restart_block.fn = do_no_restart_syscall; frame = (struct rt_sigframe __user *)pt_psp(regs); - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) + if (!access_ok(frame, sizeof(*frame))) goto badframe; if (__copy_from_user(&blocked, &frame->uc.uc_sigmask, sizeof(blocked))) goto badframe; @@ -280,6 +251,6 @@ asmlinkage int sys_rt_sigreturn(void) return regs->r00; badframe: - force_sig(SIGSEGV, current); + force_sig(SIGSEGV); return 0; } diff --git a/arch/hexagon/kernel/smp.c b/arch/hexagon/kernel/smp.c index 0e364ca43198..65e1fdf9fdb2 100644 --- a/arch/hexagon/kernel/smp.c +++ b/arch/hexagon/kernel/smp.c @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * SMP support for Hexagon * * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include <linux/err.h> @@ -25,10 +12,11 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/percpu.h> -#include <linux/sched.h> +#include <linux/sched/mm.h> #include <linux/smp.h> #include <linux/spinlock.h> #include <linux/cpu.h> +#include <linux/mm_types.h> #include <asm/time.h> /* timer_interrupt */ #include <asm/hexagon_vm.h> @@ -64,10 +52,6 @@ static inline void __handle_ipi(unsigned long *ops, struct ipi_data *ipi, generic_smp_call_function_interrupt(); break; - case IPI_CALL_FUNC_SINGLE: - generic_smp_call_function_single_interrupt(); - break; - case IPI_CPU_STOP: /* * call vmstop() @@ -95,7 +79,7 @@ void smp_vm_unmask_irq(void *info) * Specifically, first arg is irq, second is the irq_desc. */ -irqreturn_t handle_ipi(int irq, void *desc) +static irqreturn_t handle_ipi(int irq, void *desc) { int cpu = smp_processor_id(); struct ipi_data *ipi = &per_cpu(ipi_data, cpu); @@ -130,26 +114,16 @@ void send_ipi(const struct cpumask *cpumask, enum ipi_message_type msg) local_irq_restore(flags); } -static struct irqaction ipi_intdesc = { - .handler = handle_ipi, - .flags = IRQF_TRIGGER_RISING, - .name = "ipi_handler" -}; - -void __init smp_prepare_boot_cpu(void) -{ -} - /* * interrupts should already be disabled from the VM * SP should already be correct; need to set THREADINFO_REG * to point to current thread info */ -void __cpuinit start_secondary(void) +static void start_secondary(void) { - unsigned int cpu; unsigned long thread_ptr; + unsigned int cpu, irq; /* Calculate thread_info pointer from stack pointer */ __asm__ __volatile__( @@ -166,12 +140,15 @@ void __cpuinit start_secondary(void) ); /* Set the memory struct */ - atomic_inc(&init_mm.mm_count); + mmgrab(&init_mm); current->active_mm = &init_mm; cpu = smp_processor_id(); - setup_irq(BASE_IPI_IRQ + cpu, &ipi_intdesc); + irq = BASE_IPI_IRQ + cpu; + if (request_irq(irq, handle_ipi, IRQF_TRIGGER_RISING, "ipi_handler", + NULL)) + pr_err("Failed to request irq %u (ipi_handler)\n", irq); /* Register the clock_event dummy */ setup_percpu_clockdev(); @@ -184,7 +161,7 @@ void __cpuinit start_secondary(void) local_irq_enable(); - cpu_startup_entry(CPUHP_ONLINE); + cpu_startup_entry(CPUHP_AP_ONLINE_IDLE); } @@ -194,7 +171,7 @@ void __cpuinit start_secondary(void) * maintains control until "cpu_online(cpu)" is set. */ -int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle) +int __cpu_up(unsigned int cpu, struct task_struct *idle) { struct thread_info *thread = (struct thread_info *)idle->stack; void *stack_start; @@ -217,7 +194,7 @@ void __init smp_cpus_done(unsigned int max_cpus) void __init smp_prepare_cpus(unsigned int max_cpus) { - int i; + int i, irq = BASE_IPI_IRQ; /* * should eventually have some sort of machine @@ -229,11 +206,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus) set_cpu_present(i, true); /* Also need to register the interrupts for IPI */ - if (max_cpus > 1) - setup_irq(BASE_IPI_IRQ, &ipi_intdesc); + if (max_cpus > 1) { + if (request_irq(irq, handle_ipi, IRQF_TRIGGER_RISING, + "ipi_handler", NULL)) + pr_err("Failed to request irq %d (ipi_handler)\n", irq); + } } -void smp_send_reschedule(int cpu) +void arch_smp_send_reschedule(int cpu) { send_ipi(cpumask_of(cpu), IPI_RESCHEDULE); } @@ -248,7 +228,7 @@ void smp_send_stop(void) void arch_send_call_function_single_ipi(int cpu) { - send_ipi(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); + send_ipi(cpumask_of(cpu), IPI_CALL_FUNC); } void arch_send_call_function_ipi_mask(const struct cpumask *mask) @@ -256,11 +236,6 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask) send_ipi(mask, IPI_CALL_FUNC); } -int setup_profiling_timer(unsigned int multiplier) -{ - return -EINVAL; -} - void smp_start_cpus(void) { int i; diff --git a/arch/hexagon/kernel/stacktrace.c b/arch/hexagon/kernel/stacktrace.c index f94918b449a8..5ed02f699479 100644 --- a/arch/hexagon/kernel/stacktrace.c +++ b/arch/hexagon/kernel/stacktrace.c @@ -1,30 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Stacktrace support for Hexagon * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include <linux/sched.h> +#include <linux/sched/task_stack.h> #include <linux/stacktrace.h> #include <linux/thread_info.h> #include <linux/module.h> -register unsigned long current_frame_pointer asm("r30"); - struct stackframe { unsigned long fp; unsigned long rets; @@ -42,7 +28,7 @@ void save_stack_trace(struct stack_trace *trace) low = (unsigned long)task_stack_page(current); high = low + THREAD_SIZE; - fp = current_frame_pointer; + fp = (unsigned long)__builtin_frame_address(0); while (fp >= low && fp <= (high - sizeof(*frame))) { frame = (struct stackframe *)fp; diff --git a/arch/hexagon/kernel/syscalltab.c b/arch/hexagon/kernel/syscalltab.c index 7024b1ddc08a..b53e2eead4ac 100644 --- a/arch/hexagon/kernel/syscalltab.c +++ b/arch/hexagon/kernel/syscalltab.c @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * System call table for Hexagon * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include <linux/syscalls.h> @@ -24,9 +11,20 @@ #include <asm/syscall.h> -#undef __SYSCALL #define __SYSCALL(nr, call) [nr] = (call), +#define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native) + +#define sys_mmap2 sys_mmap_pgoff + +SYSCALL_DEFINE6(hexagon_fadvise64_64, int, fd, int, advice, + SC_ARG64(offset), SC_ARG64(len)) +{ + return ksys_fadvise64_64(fd, SC_VAL64(loff_t, offset), SC_VAL64(loff_t, len), advice); +} +#define sys_fadvise64_64 sys_hexagon_fadvise64_64 + +#define sys_sync_file_range sys_sync_file_range2 void *sys_call_table[__NR_syscalls] = { -#include <asm/unistd.h> +#include <asm/syscall_table_32.h> }; diff --git a/arch/hexagon/kernel/time.c b/arch/hexagon/kernel/time.c index 9903fad997f3..6f851e1cd4ee 100644 --- a/arch/hexagon/kernel/time.c +++ b/arch/hexagon/kernel/time.c @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Time related functions for Hexagon architecture * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include <linux/init.h> @@ -30,8 +17,11 @@ #include <linux/of_irq.h> #include <linux/module.h> -#include <asm/timer-regs.h> +#include <asm/delay.h> #include <asm/hexagon_vm.h> +#include <asm/time.h> + +#define TIMER_ENABLE BIT(0) /* * For the clocksource we need: @@ -46,6 +36,13 @@ cycles_t pcycle_freq_mhz; cycles_t thread_freq_mhz; cycles_t sleep_clk_freq; +/* + * 8x50 HDD Specs 5-8. Simulator co-sim not fixed until + * release 1.1, and then it's "adjustable" and probably not defaulted. + */ +#define RTOS_TIMER_INT 3 +#define RTOS_TIMER_REGS_ADDR 0xAB000000UL + static struct resource rtos_timer_resources[] = { { .start = RTOS_TIMER_REGS_ADDR, @@ -72,9 +69,9 @@ struct adsp_hw_timer_struct { /* Look for "TCX0" for related constants. */ static __iomem struct adsp_hw_timer_struct *rtos_timer; -static cycle_t timer_get_cycles(struct clocksource *cs) +static u64 timer_get_cycles(struct clocksource *cs) { - return (cycle_t) __vmgettime(); + return (u64) __vmgettime(); } static struct clocksource hexagon_clocksource = { @@ -93,24 +90,10 @@ static int set_next_event(unsigned long delta, struct clock_event_device *evt) iowrite32(0, &rtos_timer->clear); iowrite32(delta, &rtos_timer->match); - iowrite32(1 << TIMER_ENABLE, &rtos_timer->enable); + iowrite32(TIMER_ENABLE, &rtos_timer->enable); return 0; } -/* - * Sets the mode (periodic, shutdown, oneshot, etc) of a timer. - */ -static void set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - switch (mode) { - case CLOCK_EVT_MODE_SHUTDOWN: - /* XXX implement me */ - default: - break; - } -} - #ifdef CONFIG_SMP /* Broadcast mechanism */ static void broadcast(const struct cpumask *mask) @@ -119,13 +102,13 @@ static void broadcast(const struct cpumask *mask) } #endif +/* XXX Implement set_state_shutdown() */ static struct clock_event_device hexagon_clockevent_dev = { .name = "clockevent", .features = CLOCK_EVT_FEAT_ONESHOT, .rating = 400, .irq = RTOS_TIMER_INT, .set_next_event = set_next_event, - .set_mode = set_mode, #ifdef CONFIG_SMP .broadcast = broadcast, #endif @@ -146,7 +129,6 @@ void setup_percpu_clockdev(void) dummy_clock_dev->features = CLOCK_EVT_FEAT_DUMMY; dummy_clock_dev->cpumask = cpumask_of(cpu); - dummy_clock_dev->mode = CLOCK_EVT_MODE_UNUSED; clockevents_register_device(dummy_clock_dev); } @@ -171,13 +153,6 @@ static irqreturn_t timer_interrupt(int irq, void *devid) return IRQ_HANDLED; } -/* This should also be pulled from devtree */ -static struct irqaction rtos_timer_intdesc = { - .handler = timer_interrupt, - .flags = IRQF_TIMER | IRQF_TRIGGER_RISING, - .name = "rtos_timer" -}; - /* * time_init_deferred - called by start_kernel to set up timer/clock source * @@ -187,18 +162,15 @@ static struct irqaction rtos_timer_intdesc = { * This runs just before the delay loop is calibrated, and * is used for delay calibration. */ -void __init time_init_deferred(void) +static void __init time_init_deferred(void) { struct resource *resource = NULL; struct clock_event_device *ce_dev = &hexagon_clockevent_dev; - struct device_node *dn; - struct resource r; - int err; + unsigned long flag = IRQF_TIMER | IRQF_TRIGGER_RISING; ce_dev->cpumask = cpu_all_mask; - if (!resource) - resource = rtos_timer_device.resource; + resource = rtos_timer_device.resource; /* ioremap here means this has to run later, after paging init */ rtos_timer = ioremap(resource->start, resource_size(resource)); @@ -217,14 +189,17 @@ void __init time_init_deferred(void) clockevents_calc_mult_shift(ce_dev, sleep_clk_freq, 4); ce_dev->max_delta_ns = clockevent_delta2ns(0x7fffffff, ce_dev); + ce_dev->max_delta_ticks = 0x7fffffff; ce_dev->min_delta_ns = clockevent_delta2ns(0xf, ce_dev); + ce_dev->min_delta_ticks = 0xf; #ifdef CONFIG_SMP setup_percpu_clockdev(); #endif clockevents_register_device(ce_dev); - setup_irq(ce_dev->irq, &rtos_timer_intdesc); + if (request_irq(ce_dev->irq, timer_interrupt, flag, "rtos_timer", NULL)) + pr_err("Failed to register rtos_timer interrupt\n"); } void __init time_init(void) @@ -232,6 +207,15 @@ void __init time_init(void) late_time_init = time_init_deferred; } +void __delay(unsigned long cycles) +{ + unsigned long long start = __vmgettime(); + + while ((__vmgettime() - start) < cycles) + cpu_relax(); +} +EXPORT_SYMBOL(__delay); + /* * This could become parametric or perhaps even computed at run-time, * but for now we take the observed simulator jitter. diff --git a/arch/hexagon/kernel/trampoline.S b/arch/hexagon/kernel/trampoline.S index 18110a9056b0..58f631870f7e 100644 --- a/arch/hexagon/kernel/trampoline.S +++ b/arch/hexagon/kernel/trampoline.S @@ -1,19 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ /* diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c index 7858663352b9..e732aa01c2ff 100644 --- a/arch/hexagon/kernel/traps.c +++ b/arch/hexagon/kernel/traps.c @@ -1,31 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Kernel traps/events for Hexagon processor * - * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. */ #include <linux/init.h> -#include <linux/sched.h> +#include <linux/sched/signal.h> +#include <linux/sched/debug.h> +#include <linux/sched/task_stack.h> #include <linux/module.h> #include <linux/kallsyms.h> #include <linux/kdebug.h> #include <linux/syscalls.h> #include <linux/signal.h> -#include <linux/tracehook.h> +#include <linux/ptrace.h> #include <asm/traps.h> #include <asm/vm_fault.h> #include <asm/syscall.h> @@ -39,10 +28,6 @@ #define TRAP_SYSCALL 1 #define TRAP_DEBUG 0xdb -void __init trap_init(void) -{ -} - #ifdef CONFIG_GENERIC_BUG /* Maybe should resemble arch/sh/kernel/traps.c ?? */ int is_valid_bugaddr(unsigned long addr) @@ -90,7 +75,7 @@ static const char *ex_name(int ex) } static void do_show_stack(struct task_struct *task, unsigned long *fp, - unsigned long ip) + unsigned long ip, const char *loglvl) { int kstack_depth_to_print = 24; unsigned long offset, size; @@ -104,9 +89,8 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp, if (task == NULL) task = current; - printk(KERN_INFO "CPU#%d, %s/%d, Call Trace:\n", - raw_smp_processor_id(), task->comm, - task_pid_nr(task)); + printk("%sCPU#%d, %s/%d, Call Trace:\n", loglvl, raw_smp_processor_id(), + task->comm, task_pid_nr(task)); if (fp == NULL) { if (task == current) { @@ -119,7 +103,7 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp, } if ((((unsigned long) fp) & 0x3) || ((unsigned long) fp < 0x1000)) { - printk(KERN_INFO "-- Corrupt frame pointer %p\n", fp); + printk("%s-- Corrupt frame pointer %p\n", loglvl, fp); return; } @@ -136,8 +120,7 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp, name = kallsyms_lookup(ip, &size, &offset, &modname, tmpstr); - printk(KERN_INFO "[%p] 0x%lx: %s + 0x%lx", fp, ip, name, - offset); + printk("%s[%p] 0x%lx: %s + 0x%lx", loglvl, fp, ip, name, offset); if (((unsigned long) fp < low) || (high < (unsigned long) fp)) printk(KERN_CONT " (FP out of bounds!)"); if (modname) @@ -147,18 +130,17 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp, newfp = (unsigned long *) *fp; if (((unsigned long) newfp) & 0x3) { - printk(KERN_INFO "-- Corrupt frame pointer %p\n", - newfp); + printk("%s-- Corrupt frame pointer %p\n", loglvl, newfp); break; } /* Attempt to continue past exception. */ - if (0 == newfp) { + if (!newfp) { struct pt_regs *regs = (struct pt_regs *) (((void *)fp) + 8); if (regs->syscall_nr != -1) { - printk(KERN_INFO "-- trap0 -- syscall_nr: %ld", + printk("%s-- trap0 -- syscall_nr: %ld", loglvl, regs->syscall_nr); printk(KERN_CONT " psp: %lx elr: %lx\n", pt_psp(regs), pt_elr(regs)); @@ -166,7 +148,7 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp, } else { /* really want to see more ... */ kstack_depth_to_print += 6; - printk(KERN_INFO "-- %s (0x%lx) badva: %lx\n", + printk("%s-- %s (0x%lx) badva: %lx\n", loglvl, ex_name(pt_cause(regs)), pt_cause(regs), pt_badva(regs)); } @@ -189,10 +171,10 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp, } } -void show_stack(struct task_struct *task, unsigned long *fp) +void show_stack(struct task_struct *task, unsigned long *fp, const char *loglvl) { /* Saved link reg is one word above FP */ - do_show_stack(task, fp, 0); + do_show_stack(task, fp, 0, loglvl); } int die(const char *str, struct pt_regs *regs, long err) @@ -213,12 +195,14 @@ int die(const char *str, struct pt_regs *regs, long err) printk(KERN_EMERG "Oops: %s[#%d]:\n", str, ++die.counter); if (notify_die(DIE_OOPS, str, regs, err, pt_cause(regs), SIGSEGV) == - NOTIFY_STOP) + NOTIFY_STOP) { + spin_unlock_irq(&die.lock); return 1; + } print_modules(); show_regs(regs); - do_show_stack(current, ®s->r30, pt_elr(regs)); + do_show_stack(current, ®s->r30, pt_elr(regs), KERN_EMERG); bust_spinlocks(0); add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); @@ -232,7 +216,7 @@ int die(const char *str, struct pt_regs *regs, long err) panic("Fatal exception"); oops_exit(); - do_exit(err); + make_task_dead(err); return 0; } @@ -250,7 +234,7 @@ int die_if_kernel(char *str, struct pt_regs *regs, long err) static void misaligned_instruction(struct pt_regs *regs) { die_if_kernel("Misaligned Instruction", regs, 0); - force_sig(SIGBUS, current); + force_sig(SIGBUS); } /* @@ -261,19 +245,19 @@ static void misaligned_instruction(struct pt_regs *regs) static void misaligned_data_load(struct pt_regs *regs) { die_if_kernel("Misaligned Data Load", regs, 0); - force_sig(SIGBUS, current); + force_sig(SIGBUS); } static void misaligned_data_store(struct pt_regs *regs) { die_if_kernel("Misaligned Data Store", regs, 0); - force_sig(SIGBUS, current); + force_sig(SIGBUS); } static void illegal_instruction(struct pt_regs *regs) { die_if_kernel("Illegal Instruction", regs, 0); - force_sig(SIGILL, current); + force_sig(SIGILL); } /* @@ -283,7 +267,7 @@ static void illegal_instruction(struct pt_regs *regs) static void precise_bus_error(struct pt_regs *regs) { die_if_kernel("Precise Bus Error", regs, 0); - force_sig(SIGBUS, current); + force_sig(SIGBUS); } /* @@ -299,6 +283,7 @@ static void cache_error(struct pt_regs *regs) /* * General exception handler */ +void do_genex(struct pt_regs *regs); void do_genex(struct pt_regs *regs) { /* @@ -349,13 +334,7 @@ void do_genex(struct pt_regs *regs) } } -/* Indirect system call dispatch */ -long sys_syscall(void) -{ - printk(KERN_ERR "sys_syscall invoked!\n"); - return -ENOSYS; -} - +void do_trap0(struct pt_regs *regs); void do_trap0(struct pt_regs *regs) { syscall_fn syscall; @@ -366,7 +345,7 @@ void do_trap0(struct pt_regs *regs) /* allow strace to catch syscall args */ if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE) && - tracehook_report_syscall_entry(regs))) + ptrace_report_syscall_entry(regs))) return; /* return -ENOSYS somewhere? */ /* Interrupts should be re-enabled for syscall processing */ @@ -404,16 +383,12 @@ void do_trap0(struct pt_regs *regs) /* allow strace to get the syscall return state */ if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE))) - tracehook_report_syscall_exit(regs, 0); + ptrace_report_syscall_exit(regs, 0); break; case TRAP_DEBUG: /* Trap0 0xdb is debug breakpoint */ if (user_mode(regs)) { - struct siginfo info; - - info.si_signo = SIGTRAP; - info.si_errno = 0; /* * Some architecures add some per-thread state * to distinguish between breakpoint traps and @@ -421,9 +396,8 @@ void do_trap0(struct pt_regs *regs) * set the si_code value appropriately, or we * may want to use a different trap0 flavor. */ - info.si_code = TRAP_BRKPT; - info.si_addr = (void __user *) pt_elr(regs); - send_sig_info(SIGTRAP, &info, current); + force_sig_fault(SIGTRAP, TRAP_BRKPT, + (void __user *) pt_elr(regs)); } else { #ifdef CONFIG_KGDB kgdb_handle_exception(pt_cause(regs), SIGTRAP, @@ -438,6 +412,7 @@ void do_trap0(struct pt_regs *regs) /* * Machine check exception handler */ +void do_machcheck(struct pt_regs *regs); void do_machcheck(struct pt_regs *regs) { /* Halt and catch fire */ @@ -448,6 +423,7 @@ void do_machcheck(struct pt_regs *regs) * Treat this like the old 0xdb trap. */ +void do_debug_exception(struct pt_regs *regs); void do_debug_exception(struct pt_regs *regs) { regs->hvmer.vmest &= ~HVM_VMEST_CAUSE_MSK; diff --git a/arch/hexagon/kernel/vdso.c b/arch/hexagon/kernel/vdso.c index 0bf5a87e4d0a..8119084dc519 100644 --- a/arch/hexagon/kernel/vdso.c +++ b/arch/hexagon/kernel/vdso.c @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * vDSO implementation for Hexagon * * Copyright (c) 2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include <linux/err.h> @@ -23,6 +10,7 @@ #include <linux/vmalloc.h> #include <linux/binfmts.h> +#include <asm/elf.h> #include <asm/vdso.h> static struct page *vdso_page; @@ -63,9 +51,14 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) { int ret; unsigned long vdso_base; + struct vm_area_struct *vma; struct mm_struct *mm = current->mm; + static struct vm_special_mapping vdso_mapping = { + .name = "[vdso]", + }; - down_write(&mm->mmap_sem); + if (mmap_write_lock_killable(mm)) + return -EINTR; /* Try to get it loaded right near ld.so/glibc. */ vdso_base = STACK_TOP; @@ -77,18 +70,20 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) } /* MAYWRITE to allow gdb to COW and set breakpoints. */ - ret = install_special_mapping(mm, vdso_base, PAGE_SIZE, + vdso_mapping.pages = &vdso_page; + vma = _install_special_mapping(mm, vdso_base, PAGE_SIZE, VM_READ|VM_EXEC| VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, - &vdso_page); + &vdso_mapping); - if (ret) + ret = PTR_ERR(vma); + if (IS_ERR(vma)) goto up_fail; mm->context.vdso = (void *)vdso_base; - + ret = 0; up_fail: - up_write(&mm->mmap_sem); + mmap_write_unlock(mm); return ret; } diff --git a/arch/hexagon/kernel/vm_entry.S b/arch/hexagon/kernel/vm_entry.S index 67c6ccc14770..554371d92bed 100644 --- a/arch/hexagon/kernel/vm_entry.S +++ b/arch/hexagon/kernel/vm_entry.S @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Event entry/exit for Hexagon * * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include <asm/asm-offsets.h> /* assembly-safer versions of C defines */ @@ -278,12 +265,12 @@ event_dispatch: * should be in the designated register (usually R19) * * If we were in kernel mode, we don't need to check scheduler - * or signals if CONFIG_PREEMPT is not set. If set, then it has + * or signals if CONFIG_PREEMPTION is not set. If set, then it has * to jump to a need_resched kind of block. - * BTW, CONFIG_PREEMPT is not supported yet. + * BTW, CONFIG_PREEMPTION is not supported yet. */ -#ifdef CONFIG_PREEMPT +#ifdef CONFIG_PREEMPTION R0 = #VM_INT_DISABLE trap1(#HVM_TRAP1_VMSETIE) #endif @@ -382,7 +369,7 @@ ret_from_fork: R26.L = #LO(do_work_pending); R0 = #VM_INT_DISABLE; } - if P0 jump check_work_pending + if (P0) jump check_work_pending { R0 = R25; callr R24 diff --git a/arch/hexagon/kernel/vm_events.c b/arch/hexagon/kernel/vm_events.c index 741aaa917cda..2b881a89b206 100644 --- a/arch/hexagon/kernel/vm_events.c +++ b/arch/hexagon/kernel/vm_events.c @@ -1,24 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Mostly IRQ support for Hexagon * * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include <linux/kernel.h> +#include <linux/sched/debug.h> #include <asm/registers.h> #include <linux/irq.h> #include <linux/hardirq.h> @@ -85,13 +73,6 @@ void show_regs(struct pt_regs *regs) pt_psp(regs), pt_badva(regs), ints_enabled(regs)); } -void dummy_handler(struct pt_regs *regs) -{ - unsigned int elr = pt_elr(regs); - printk(KERN_ERR "Unimplemented handler; ELR=0x%08x\n", elr); -} - - void arch_do_IRQ(struct pt_regs *regs) { int irq = pt_cause(regs); diff --git a/arch/hexagon/kernel/vm_init_segtable.S b/arch/hexagon/kernel/vm_init_segtable.S index 80967f2192b3..2638a0906361 100644 --- a/arch/hexagon/kernel/vm_init_segtable.S +++ b/arch/hexagon/kernel/vm_init_segtable.S @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Initial page table for Linux kernel under Hexagon VM, * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ /* diff --git a/arch/hexagon/kernel/vm_ops.S b/arch/hexagon/kernel/vm_ops.S index 9fb77b3f6cf2..f61c04d485f6 100644 --- a/arch/hexagon/kernel/vm_ops.S +++ b/arch/hexagon/kernel/vm_ops.S @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Hexagon VM instruction support * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include <linux/linkage.h> @@ -26,7 +13,7 @@ * could be, and perhaps some day will be, handled as in-line * macros, but for tracing/debugging it's handy to have * a single point of invocation for each of them. - * Conveniently, they take paramters and return values + * Conveniently, they take parameters and return values * consistent with the ABI calling convention. */ diff --git a/arch/hexagon/kernel/vm_switch.S b/arch/hexagon/kernel/vm_switch.S index 62c6df91b3bb..5ec2d43fee1f 100644 --- a/arch/hexagon/kernel/vm_switch.S +++ b/arch/hexagon/kernel/vm_switch.S @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Context switch support for Hexagon * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include <asm/asm-offsets.h> diff --git a/arch/hexagon/kernel/vm_vectors.S b/arch/hexagon/kernel/vm_vectors.S index 791a7422dde4..fba33745ce57 100644 --- a/arch/hexagon/kernel/vm_vectors.S +++ b/arch/hexagon/kernel/vm_vectors.S @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Event jump tables * * Copyright (c) 2010-2012,2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include <asm/hexagon_vm.h> diff --git a/arch/hexagon/kernel/vmlinux.lds.S b/arch/hexagon/kernel/vmlinux.lds.S index 44d8c47bae2f..1150b77fa281 100644 --- a/arch/hexagon/kernel/vmlinux.lds.S +++ b/arch/hexagon/kernel/vmlinux.lds.S @@ -1,27 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Linker script for Hexagon kernel * - * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. + * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved. */ #include <asm-generic/vmlinux.lds.h> #include <asm/asm-offsets.h> /* Most of the kernel defines are here */ #include <asm/mem-layout.h> /* except for page_offset */ #include <asm/cache.h> /* and now we're pulling cache line size */ +#include <asm/thread_info.h> /* and we need THREAD_SIZE too */ + OUTPUT_ARCH(hexagon) ENTRY(stext) @@ -49,6 +38,8 @@ SECTIONS .text : AT(ADDR(.text)) { _text = .; TEXT_TEXT + IRQENTRY_TEXT + SOFTIRQENTRY_TEXT SCHED_TEXT LOCK_TEXT KPROBES_TEXT @@ -59,24 +50,20 @@ SECTIONS INIT_DATA_SECTION(PAGE_SIZE) _sdata = .; - RW_DATA_SECTION(32,PAGE_SIZE,PAGE_SIZE) - RO_DATA_SECTION(PAGE_SIZE) + RW_DATA(32,PAGE_SIZE,_THREAD_SIZE) + RO_DATA(PAGE_SIZE) _edata = .; EXCEPTION_TABLE(16) - NOTES BSS_SECTION(_PAGE_SIZE, _PAGE_SIZE, _PAGE_SIZE) _end = .; - /DISCARD/ : { - EXIT_TEXT - EXIT_DATA - EXIT_CALL - } - STABS_DEBUG DWARF_DEBUG + ELF_DETAILS + .hexagon.attributes 0 : { *(.hexagon.attributes) } + DISCARDS } diff --git a/arch/hexagon/lib/Makefile b/arch/hexagon/lib/Makefile index 874655e85671..107894c0910e 100644 --- a/arch/hexagon/lib/Makefile +++ b/arch/hexagon/lib/Makefile @@ -1,4 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-only # # Makefile for hexagon-specific library files. # -obj-y = checksum.o io.o memcpy.o memset.o +obj-y = checksum.o memcpy.o memset.o memcpy_likely_aligned.o \ + divsi3.o modsi3.o udivsi3.o umodsi3.o diff --git a/arch/hexagon/lib/checksum.c b/arch/hexagon/lib/checksum.c index 8169f78a46a7..ba50822a0800 100644 --- a/arch/hexagon/lib/checksum.c +++ b/arch/hexagon/lib/checksum.c @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Checksum functions for Hexagon * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ /* This was derived from arch/alpha/lib/checksum.c */ @@ -60,18 +47,16 @@ static inline unsigned short from64to16(u64 x) * computes the checksum of the TCP/UDP pseudo-header * returns a 16-bit checksum, already complemented. */ -__sum16 csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, - unsigned short len, unsigned short proto, - __wsum sum) +__sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, + __u32 len, __u8 proto, __wsum sum) { return (__force __sum16)~from64to16( (__force u64)saddr + (__force u64)daddr + (__force u64)sum + ((len + proto) << 8)); } -__wsum csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, - unsigned short len, unsigned short proto, - __wsum sum) +__wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, + __u32 len, __u8 proto, __wsum sum) { u64 result; @@ -191,13 +176,3 @@ unsigned int do_csum(const void *voidptr, int len) return 0xFFFF & sum0; } - -/* - * copy from ds while checksumming, otherwise like csum_partial - */ -__wsum -csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) -{ - memcpy(dst, src, len); - return csum_partial(dst, len, sum); -} diff --git a/arch/hexagon/lib/divsi3.S b/arch/hexagon/lib/divsi3.S new file mode 100644 index 000000000000..783e09424c2c --- /dev/null +++ b/arch/hexagon/lib/divsi3.S @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include <linux/linkage.h> + +SYM_FUNC_START(__hexagon_divsi3) + { + p0 = cmp.gt(r0,#-1) + p1 = cmp.gt(r1,#-1) + r3:2 = vabsw(r1:0) + } + { + p3 = xor(p0,p1) + r4 = sub(r2,r3) + r6 = cl0(r2) + p0 = cmp.gtu(r3,r2) + } + { + r0 = mux(p3,#-1,#1) + r7 = cl0(r3) + p1 = cmp.gtu(r3,r4) + } + { + r0 = mux(p0,#0,r0) + p0 = or(p0,p1) + if (p0.new) jumpr:nt r31 + r6 = sub(r7,r6) + } + { + r7 = r6 + r5:4 = combine(#1,r3) + r6 = add(#1,lsr(r6,#1)) + p0 = cmp.gtu(r6,#4) + } + { + r5:4 = vaslw(r5:4,r7) + if (!p0) r6 = #3 + } + { + loop0(1f,r6) + r7:6 = vlsrw(r5:4,#1) + r1:0 = #0 + } + .falign +1: + { + r5:4 = vlsrw(r5:4,#2) + if (!p0.new) r0 = add(r0,r5) + if (!p0.new) r2 = sub(r2,r4) + p0 = cmp.gtu(r4,r2) + } + { + r7:6 = vlsrw(r7:6,#2) + if (!p0.new) r0 = add(r0,r7) + if (!p0.new) r2 = sub(r2,r6) + p0 = cmp.gtu(r6,r2) + }:endloop0 + { + if (!p0) r0 = add(r0,r7) + } + { + if (p3) r0 = sub(r1,r0) + jumpr r31 + } +SYM_FUNC_END(__hexagon_divsi3) diff --git a/arch/hexagon/lib/io.c b/arch/hexagon/lib/io.c deleted file mode 100644 index 885c9626d5e0..000000000000 --- a/arch/hexagon/lib/io.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * I/O access functions for Hexagon - * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include <asm/io.h> - -/* These are all FIFO routines! */ - -/* - * __raw_readsw - read words a short at a time - * @addr: source address - * @data: data address - * @len: number of shorts to read - */ -void __raw_readsw(const void __iomem *addr, void *data, int len) -{ - const volatile short int *src = (short int *) addr; - short int *dst = (short int *) data; - - if ((u32)data & 0x1) - panic("unaligned pointer to readsw"); - - while (len-- > 0) - *dst++ = *src; - -} - -/* - * __raw_writesw - read words a short at a time - * @addr: source address - * @data: data address - * @len: number of shorts to read - */ -void __raw_writesw(void __iomem *addr, const void *data, int len) -{ - const short int *src = (short int *)data; - volatile short int *dst = (short int *)addr; - - if ((u32)data & 0x1) - panic("unaligned pointer to writesw"); - - while (len-- > 0) - *dst = *src++; - - -} - -/* Pretty sure len is pre-adjusted for the length of the access already */ -void __raw_readsl(const void __iomem *addr, void *data, int len) -{ - const volatile long *src = (long *) addr; - long *dst = (long *) data; - - if ((u32)data & 0x3) - panic("unaligned pointer to readsl"); - - while (len-- > 0) - *dst++ = *src; - - -} - -void __raw_writesl(void __iomem *addr, const void *data, int len) -{ - const long *src = (long *)data; - volatile long *dst = (long *)addr; - - if ((u32)data & 0x3) - panic("unaligned pointer to writesl"); - - while (len-- > 0) - *dst = *src++; - - -} diff --git a/arch/hexagon/lib/memcpy.S b/arch/hexagon/lib/memcpy.S index 81c561c4b4d6..f8b3c02a8ad1 100644 --- a/arch/hexagon/lib/memcpy.S +++ b/arch/hexagon/lib/memcpy.S @@ -1,20 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ /* @@ -39,7 +25,7 @@ * DJH 10/14/09 Version 1.3 added special loop for aligned case, was * overreading bloated codesize back up to 892 * DJH 4/20/10 Version 1.4 fixed Ldword_loop_epilog loop to prevent loads - * occuring if only 1 left outstanding, fixes bug + * occurring if only 1 left outstanding, fixes bug * # 3888, corrected for all alignments. Peeled off * 1 32byte chunk from kernel loop and extended 8byte * loop at end to solve all combinations and prevent diff --git a/arch/hexagon/lib/memcpy_likely_aligned.S b/arch/hexagon/lib/memcpy_likely_aligned.S new file mode 100644 index 000000000000..6a541fb90a54 --- /dev/null +++ b/arch/hexagon/lib/memcpy_likely_aligned.S @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include <linux/linkage.h> + +SYM_FUNC_START(__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes) + { + p0 = bitsclr(r1,#7) + p0 = bitsclr(r0,#7) + if (p0.new) r5:4 = memd(r1) + if (p0.new) r7:6 = memd(r1+#8) + } + { + if (!p0) jump:nt .Lmemcpy_call + if (p0) r9:8 = memd(r1+#16) + if (p0) r11:10 = memd(r1+#24) + p0 = cmp.gtu(r2,#64) + } + { + if (p0) jump:nt .Lmemcpy_call + if (!p0) memd(r0) = r5:4 + if (!p0) memd(r0+#8) = r7:6 + p0 = cmp.gtu(r2,#32) + } + { + p1 = cmp.gtu(r2,#40) + p2 = cmp.gtu(r2,#48) + if (p0) r13:12 = memd(r1+#32) + if (p1.new) r15:14 = memd(r1+#40) + } + { + memd(r0+#16) = r9:8 + memd(r0+#24) = r11:10 + } + { + if (p0) memd(r0+#32) = r13:12 + if (p1) memd(r0+#40) = r15:14 + if (!p2) jumpr:t r31 + } + { + p0 = cmp.gtu(r2,#56) + r5:4 = memd(r1+#48) + if (p0.new) r7:6 = memd(r1+#56) + } + { + memd(r0+#48) = r5:4 + if (p0) memd(r0+#56) = r7:6 + jumpr r31 + } + +.Lmemcpy_call: + jump memcpy + +SYM_FUNC_END(__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes) diff --git a/arch/hexagon/lib/memset.S b/arch/hexagon/lib/memset.S index 9341889ea3f6..e67304e3f7cf 100644 --- a/arch/hexagon/lib/memset.S +++ b/arch/hexagon/lib/memset.S @@ -1,19 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ diff --git a/arch/hexagon/lib/modsi3.S b/arch/hexagon/lib/modsi3.S new file mode 100644 index 000000000000..9ea1c86efac2 --- /dev/null +++ b/arch/hexagon/lib/modsi3.S @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include <linux/linkage.h> + +SYM_FUNC_START(__hexagon_modsi3) + { + p2 = cmp.ge(r0,#0) + r2 = abs(r0) + r1 = abs(r1) + } + { + r3 = cl0(r2) + r4 = cl0(r1) + p0 = cmp.gtu(r1,r2) + } + { + r3 = sub(r4,r3) + if (p0) jumpr r31 + } + { + p1 = cmp.eq(r3,#0) + loop0(1f,r3) + r0 = r2 + r2 = lsl(r1,r3) + } + .falign +1: + { + p0 = cmp.gtu(r2,r0) + if (!p0.new) r0 = sub(r0,r2) + r2 = lsr(r2,#1) + if (p1) r1 = #0 + }:endloop0 + { + p0 = cmp.gtu(r2,r0) + if (!p0.new) r0 = sub(r0,r1) + if (p2) jumpr r31 + } + { + r0 = neg(r0) + jumpr r31 + } +SYM_FUNC_END(__hexagon_modsi3) diff --git a/arch/hexagon/lib/udivsi3.S b/arch/hexagon/lib/udivsi3.S new file mode 100644 index 000000000000..477f27b9311c --- /dev/null +++ b/arch/hexagon/lib/udivsi3.S @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include <linux/linkage.h> + +SYM_FUNC_START(__hexagon_udivsi3) + { + r2 = cl0(r0) + r3 = cl0(r1) + r5:4 = combine(#1,#0) + p0 = cmp.gtu(r1,r0) + } + { + r6 = sub(r3,r2) + r4 = r1 + r1:0 = combine(r0,r4) + if (p0) jumpr r31 + } + { + r3:2 = vlslw(r5:4,r6) + loop0(1f,r6) + } + .falign +1: + { + p0 = cmp.gtu(r2,r1) + if (!p0.new) r1 = sub(r1,r2) + if (!p0.new) r0 = add(r0,r3) + r3:2 = vlsrw(r3:2,#1) + }:endloop0 + { + p0 = cmp.gtu(r2,r1) + if (!p0.new) r0 = add(r0,r3) + jumpr r31 + } +SYM_FUNC_END(__hexagon_udivsi3) diff --git a/arch/hexagon/lib/umodsi3.S b/arch/hexagon/lib/umodsi3.S new file mode 100644 index 000000000000..280bf06a55e7 --- /dev/null +++ b/arch/hexagon/lib/umodsi3.S @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include <linux/linkage.h> + +SYM_FUNC_START(__hexagon_umodsi3) + { + r2 = cl0(r0) + r3 = cl0(r1) + p0 = cmp.gtu(r1,r0) + } + { + r2 = sub(r3,r2) + if (p0) jumpr r31 + } + { + loop0(1f,r2) + p1 = cmp.eq(r2,#0) + r2 = lsl(r1,r2) + } + .falign +1: + { + p0 = cmp.gtu(r2,r0) + if (!p0.new) r0 = sub(r0,r2) + r2 = lsr(r2,#1) + if (p1) r1 = #0 + }:endloop0 + { + p0 = cmp.gtu(r2,r0) + if (!p0.new) r0 = sub(r0,r1) + jumpr r31 + } +SYM_FUNC_END(__hexagon_umodsi3) diff --git a/arch/hexagon/mm/Makefile b/arch/hexagon/mm/Makefile index 1a0be4d576e1..ba4b04d962d6 100644 --- a/arch/hexagon/mm/Makefile +++ b/arch/hexagon/mm/Makefile @@ -1,6 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-only # # Makefile for Hexagon memory management subsystem # -obj-y := init.o pgalloc.o ioremap.o uaccess.o vm_fault.o cache.o -obj-y += copy_to_user.o copy_from_user.o strnlen_user.o vm_tlb.o +obj-y := init.o uaccess.o vm_fault.o cache.o +obj-y += copy_to_user.o copy_from_user.o vm_tlb.o diff --git a/arch/hexagon/mm/cache.c b/arch/hexagon/mm/cache.c index fe14ccf28561..7e46f40c8b54 100644 --- a/arch/hexagon/mm/cache.c +++ b/arch/hexagon/mm/cache.c @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Cache management functions for Hexagon * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include <linux/mm.h> @@ -68,6 +55,7 @@ void flush_icache_range(unsigned long start, unsigned long end) ); local_irq_restore(flags); } +EXPORT_SYMBOL(flush_icache_range); void hexagon_clean_dcache_range(unsigned long start, unsigned long end) { @@ -126,3 +114,13 @@ void flush_cache_all_hexagon(void) local_irq_restore(flags); mb(); } + +void copy_to_user_page(struct vm_area_struct *vma, struct page *page, + unsigned long vaddr, void *dst, void *src, int len) +{ + memcpy(dst, src, len); + if (vma->vm_flags & VM_EXEC) { + flush_icache_range((unsigned long) dst, + (unsigned long) dst + len); + } +} diff --git a/arch/hexagon/mm/copy_from_user.S b/arch/hexagon/mm/copy_from_user.S index 7fc94f3e6642..1a49bf24f68b 100644 --- a/arch/hexagon/mm/copy_from_user.S +++ b/arch/hexagon/mm/copy_from_user.S @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * User memory copy functions for kernel * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ /* @@ -44,7 +31,7 @@ #define bytes r2 #define loopcount r5 -#define FUNCNAME __copy_from_user_hexagon +#define FUNCNAME raw_copy_from_user #include "copy_user_template.S" /* LOAD FAULTS from COPY_FROM_USER */ diff --git a/arch/hexagon/mm/copy_to_user.S b/arch/hexagon/mm/copy_to_user.S index 0cfbcc09d1d9..ed8e3cafb36e 100644 --- a/arch/hexagon/mm/copy_to_user.S +++ b/arch/hexagon/mm/copy_to_user.S @@ -1,21 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * User memory copying routines for the Hexagon Kernel * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ /* The right way to do this involves valignb @@ -43,7 +30,7 @@ #define bytes r2 #define loopcount r5 -#define FUNCNAME __copy_to_user_hexagon +#define FUNCNAME raw_copy_to_user #include "copy_user_template.S" /* STORE FAULTS from COPY_TO_USER */ diff --git a/arch/hexagon/mm/copy_user_template.S b/arch/hexagon/mm/copy_user_template.S index 254d8cc766bb..d297df01b43f 100644 --- a/arch/hexagon/mm/copy_user_template.S +++ b/arch/hexagon/mm/copy_user_template.S @@ -1,19 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ /* Numerology: diff --git a/arch/hexagon/mm/init.c b/arch/hexagon/mm/init.c index 88977e42af0a..34eb9d424b96 100644 --- a/arch/hexagon/mm/init.c +++ b/arch/hexagon/mm/init.c @@ -1,30 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Memory subsystem initialization for Hexagon * * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ #include <linux/init.h> #include <linux/mm.h> -#include <linux/bootmem.h> +#include <linux/memblock.h> #include <asm/atomic.h> #include <linux/highmem.h> #include <asm/tlb.h> #include <asm/sections.h> +#include <asm/setup.h> #include <asm/vm_mmu.h> /* @@ -39,14 +27,9 @@ unsigned long __phys_offset; /* physical kernel offset >> 12 */ /* Set as variable to limit PMD copies */ int max_kernel_seg = 0x303; -/* think this should be (page_size-1) the way it's used...*/ -unsigned long zero_page_mask; - /* indicate pfn's of high memory */ unsigned long highstart_pfn, highend_pfn; -DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); - /* Default cache attribute for newly created page tables */ unsigned long _dflt_cache_att = CACHEDEF; @@ -60,56 +43,6 @@ DEFINE_SPINLOCK(kmap_gen_lock); /* checkpatch says don't init this to 0. */ unsigned long long kmap_generation; -/* - * mem_init - initializes memory - * - * Frees up bootmem - * Fixes up more stuff for HIGHMEM - * Calculates and displays memory available/used - */ -void __init mem_init(void) -{ - /* No idea where this is actually declared. Seems to evade LXR. */ - free_all_bootmem(); - mem_init_print_info(NULL); - - /* - * To-Do: someone somewhere should wipe out the bootmem map - * after we're done? - */ - - /* - * This can be moved to some more virtual-memory-specific - * initialization hook at some point. Set the init_mm - * descriptors "context" value to point to the initial - * kernel segment table's physical address. - */ - init_mm.context.ptbase = __pa(init_mm.pgd); -} - -/* - * free_initmem - frees memory used by stuff declared with __init - * - * Todo: free pages between __init_begin and __init_end; possibly - * some devtree related stuff as well. - */ -void __init_refok free_initmem(void) -{ -} - -/* - * free_initrd_mem - frees... initrd memory. - * @start - start of init memory - * @end - end of init memory - * - * Apparently has to be passed the address of the initrd memory. - * - * Wrapped by #ifdef CONFIG_BLKDEV_INITRD - */ -void free_initrd_mem(unsigned long start, unsigned long end) -{ -} - void sync_icache_dcache(pte_t pte) { unsigned long addr; @@ -128,9 +61,9 @@ void sync_icache_dcache(pte_t pte) * In this mode, we only have one pg_data_t * structure: contig_mem_data. */ -void __init paging_init(void) +static void __init paging_init(void) { - unsigned long zones_sizes[MAX_NR_ZONES] = {0, }; + unsigned long max_zone_pfn[MAX_NR_ZONES] = {0, }; /* * This is not particularly well documented anywhere, but @@ -140,15 +73,15 @@ void __init paging_init(void) * adjust accordingly. */ - zones_sizes[ZONE_NORMAL] = max_low_pfn; + max_zone_pfn[ZONE_NORMAL] = max_low_pfn; - free_area_init(zones_sizes); /* sets up the zonelists and mem_map */ + free_area_init(max_zone_pfn); /* sets up the zonelists and mem_map */ /* - * Start of high memory area. Will probably need something more - * fancy if we... get more fancy. + * Set the init_mm descriptors "context" value to point to the + * initial kernel segment table's physical address. */ - high_memory = (void *)((bootmem_lastpg + 1) << PAGE_SHIFT); + init_mm.context.ptbase = __pa(init_mm.pgd); } #ifndef DMA_RESERVE @@ -179,7 +112,6 @@ size_t hexagon_coherent_pool_size = (size_t) (DMA_RESERVE << 22); void __init setup_arch_memory(void) { - int bootmap_size; /* XXX Todo: this probably should be cleaned up */ u32 *segtable = (u32 *) &swapper_pg_dir[0]; u32 *segtable_end; @@ -198,18 +130,22 @@ void __init setup_arch_memory(void) bootmem_lastpg = PFN_DOWN((bootmem_lastpg << PAGE_SHIFT) & ~((BIG_KERNEL_PAGE_SIZE) - 1)); + memblock_add(PHYS_OFFSET, + (bootmem_lastpg - ARCH_PFN_OFFSET) << PAGE_SHIFT); + + /* Reserve kernel text/data/bss */ + memblock_reserve(PHYS_OFFSET, + (bootmem_startpg - ARCH_PFN_OFFSET) << PAGE_SHIFT); /* * Reserve the top DMA_RESERVE bytes of RAM for DMA (uncached) * memory allocation */ - max_low_pfn = bootmem_lastpg - PFN_DOWN(DMA_RESERVED_BYTES); min_low_pfn = ARCH_PFN_OFFSET; - bootmap_size = init_bootmem_node(NODE_DATA(0), bootmem_startpg, min_low_pfn, max_low_pfn); + memblock_reserve(PFN_PHYS(max_low_pfn), DMA_RESERVED_BYTES); printk(KERN_INFO "bootmem_startpg: 0x%08lx\n", bootmem_startpg); printk(KERN_INFO "bootmem_lastpg: 0x%08lx\n", bootmem_lastpg); - printk(KERN_INFO "bootmap_size: %d\n", bootmap_size); printk(KERN_INFO "min_low_pfn: 0x%08lx\n", min_low_pfn); printk(KERN_INFO "max_low_pfn: 0x%08lx\n", max_low_pfn); @@ -260,14 +196,6 @@ void __init setup_arch_memory(void) #endif /* - * Free all the memory that wasn't taken up by the bootmap, the DMA - * reserve, or kernel itself. - */ - free_bootmem(PFN_PHYS(bootmem_startpg) + bootmap_size, - PFN_PHYS(bootmem_lastpg - bootmem_startpg) - bootmap_size - - DMA_RESERVED_BYTES); - - /* * The bootmem allocator seemingly just lives to feed memory * to the paging system */ @@ -281,3 +209,45 @@ void __init setup_arch_memory(void) * which is called by start_kernel() later on in the process */ } + +static const pgprot_t protection_map[16] = { + [VM_NONE] = __pgprot(_PAGE_PRESENT | _PAGE_USER | + CACHEDEF), + [VM_READ] = __pgprot(_PAGE_PRESENT | _PAGE_USER | + _PAGE_READ | CACHEDEF), + [VM_WRITE] = __pgprot(_PAGE_PRESENT | _PAGE_USER | + CACHEDEF), + [VM_WRITE | VM_READ] = __pgprot(_PAGE_PRESENT | _PAGE_USER | + _PAGE_READ | CACHEDEF), + [VM_EXEC] = __pgprot(_PAGE_PRESENT | _PAGE_USER | + _PAGE_EXECUTE | CACHEDEF), + [VM_EXEC | VM_READ] = __pgprot(_PAGE_PRESENT | _PAGE_USER | + _PAGE_EXECUTE | _PAGE_READ | + CACHEDEF), + [VM_EXEC | VM_WRITE] = __pgprot(_PAGE_PRESENT | _PAGE_USER | + _PAGE_EXECUTE | CACHEDEF), + [VM_EXEC | VM_WRITE | VM_READ] = __pgprot(_PAGE_PRESENT | _PAGE_USER | + _PAGE_EXECUTE | _PAGE_READ | + CACHEDEF), + [VM_SHARED] = __pgprot(_PAGE_PRESENT | _PAGE_USER | + CACHEDEF), + [VM_SHARED | VM_READ] = __pgprot(_PAGE_PRESENT | _PAGE_USER | + _PAGE_READ | CACHEDEF), + [VM_SHARED | VM_WRITE] = __pgprot(_PAGE_PRESENT | _PAGE_USER | + _PAGE_WRITE | CACHEDEF), + [VM_SHARED | VM_WRITE | VM_READ] = __pgprot(_PAGE_PRESENT | _PAGE_USER | + _PAGE_READ | _PAGE_WRITE | + CACHEDEF), + [VM_SHARED | VM_EXEC] = __pgprot(_PAGE_PRESENT | _PAGE_USER | + _PAGE_EXECUTE | CACHEDEF), + [VM_SHARED | VM_EXEC | VM_READ] = __pgprot(_PAGE_PRESENT | _PAGE_USER | + _PAGE_EXECUTE | _PAGE_READ | + CACHEDEF), + [VM_SHARED | VM_EXEC | VM_WRITE] = __pgprot(_PAGE_PRESENT | _PAGE_USER | + _PAGE_EXECUTE | _PAGE_WRITE | + CACHEDEF), + [VM_SHARED | VM_EXEC | VM_WRITE | VM_READ] = __pgprot(_PAGE_PRESENT | _PAGE_USER | + _PAGE_READ | _PAGE_EXECUTE | + _PAGE_WRITE | CACHEDEF) +}; +DECLARE_VM_GET_PAGE_PROT diff --git a/arch/hexagon/mm/ioremap.c b/arch/hexagon/mm/ioremap.c deleted file mode 100644 index 5905fd5f97f6..000000000000 --- a/arch/hexagon/mm/ioremap.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * I/O remap functions for Hexagon - * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include <linux/io.h> -#include <linux/vmalloc.h> - -void __iomem *ioremap_nocache(unsigned long phys_addr, unsigned long size) -{ - unsigned long last_addr, addr; - unsigned long offset = phys_addr & ~PAGE_MASK; - struct vm_struct *area; - - pgprot_t prot = __pgprot(_PAGE_PRESENT|_PAGE_READ|_PAGE_WRITE - |(__HEXAGON_C_DEV << 6)); - - last_addr = phys_addr + size - 1; - - /* Wrapping not allowed */ - if (!size || (last_addr < phys_addr)) - return NULL; - - /* Rounds up to next page size, including whole-page offset */ - size = PAGE_ALIGN(offset + size); - - area = get_vm_area(size, VM_IOREMAP); - addr = (unsigned long)area->addr; - - if (ioremap_page_range(addr, addr+size, phys_addr, prot)) { - vunmap((void *)addr); - return NULL; - } - - return (void __iomem *) (offset + addr); -} - -void __iounmap(const volatile void __iomem *addr) -{ - vunmap((void *) ((unsigned long) addr & PAGE_MASK)); -} diff --git a/arch/hexagon/mm/pgalloc.c b/arch/hexagon/mm/pgalloc.c deleted file mode 100644 index 19760a4611d9..000000000000 --- a/arch/hexagon/mm/pgalloc.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include <linux/init.h> - -void __init pgtable_cache_init(void) -{ -} diff --git a/arch/hexagon/mm/strnlen_user.S b/arch/hexagon/mm/strnlen_user.S deleted file mode 100644 index 0eecb7a768fe..000000000000 --- a/arch/hexagon/mm/strnlen_user.S +++ /dev/null @@ -1,139 +0,0 @@ -/* - * User string length functions for kernel - * - * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#define isrc r0 -#define max r1 /* Do not change! */ - -#define end r2 -#define tmp1 r3 - -#define obo r6 /* off-by-one */ -#define start r7 -#define mod8 r8 -#define dbuf r15:14 -#define dcmp r13:12 - -/* - * The vector mask version of this turned out *really* badly. - * The hardware loop version also turned out *really* badly. - * Seems straight pointer arithmetic basically wins here. - */ - -#define fname __strnlen_user - - .text - .global fname - .type fname, @function - .p2align 5 /* why? */ -fname: - { - mod8 = and(isrc,#7); - end = add(isrc,max); - start = isrc; - } - { - P0 = cmp.eq(mod8,#0); - mod8 = and(end,#7); - dcmp = #0; - if (P0.new) jump:t dw_loop; /* fire up the oven */ - } - -alignment_loop: -fail_1: { - tmp1 = memb(start++#1); - } - { - P0 = cmp.eq(tmp1,#0); - if (P0.new) jump:nt exit_found; - P1 = cmp.gtu(end,start); - mod8 = and(start,#7); - } - { - if (!P1) jump exit_error; /* hit the end */ - P0 = cmp.eq(mod8,#0); - } - { - if (!P0) jump alignment_loop; - } - - - -dw_loop: -fail_2: { - dbuf = memd(start); - obo = add(start,#1); - } - { - P0 = vcmpb.eq(dbuf,dcmp); - } - { - tmp1 = P0; - P0 = cmp.gtu(end,start); - } - { - tmp1 = ct0(tmp1); - mod8 = and(end,#7); - if (!P0) jump end_check; - } - { - P0 = cmp.eq(tmp1,#32); - if (!P0.new) jump:nt exit_found; - if (!P0.new) start = add(obo,tmp1); - } - { - start = add(start,#8); - jump dw_loop; - } /* might be nice to combine these jumps... */ - - -end_check: - { - P0 = cmp.gt(tmp1,mod8); - if (P0.new) jump:nt exit_error; /* neverfound! */ - start = add(obo,tmp1); - } - -exit_found: - { - R0 = sub(start,isrc); - jumpr R31; - } - -exit_error: - { - R0 = add(max,#1); - jumpr R31; - } - - /* Uh, what does the "fixup" return here? */ - .falign -fix_1: - { - R0 = #0; - jumpr R31; - } - - .size fname,.-fname - - -.section __ex_table,"a" -.long fail_1,fix_1 -.long fail_2,fix_1 -.previous diff --git a/arch/hexagon/mm/uaccess.c b/arch/hexagon/mm/uaccess.c index 34127261c2b7..3204e9ba6d6f 100644 --- a/arch/hexagon/mm/uaccess.c +++ b/arch/hexagon/mm/uaccess.c @@ -1,19 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ /* @@ -23,8 +10,8 @@ * we implement here as subroutines. */ #include <linux/types.h> -#include <asm/uaccess.h> -#include <asm/pgtable.h> +#include <linux/uaccess.h> +#include <linux/pgtable.h> /* * For clear_user(), exploit previously defined copy_to_user function @@ -37,23 +24,14 @@ __kernel_size_t __clear_user_hexagon(void __user *dest, unsigned long count) long uncleared; while (count > PAGE_SIZE) { - uncleared = __copy_to_user_hexagon(dest, &empty_zero_page, - PAGE_SIZE); + uncleared = raw_copy_to_user(dest, &empty_zero_page, PAGE_SIZE); if (uncleared) return count - (PAGE_SIZE - uncleared); count -= PAGE_SIZE; dest += PAGE_SIZE; } if (count) - count = __copy_to_user_hexagon(dest, &empty_zero_page, count); + count = raw_copy_to_user(dest, &empty_zero_page, count); return count; } - -unsigned long clear_user_hexagon(void __user *dest, unsigned long count) -{ - if (!access_ok(VERIFY_WRITE, dest, count)) - return count; - else - return __clear_user_hexagon(dest, count); -} diff --git a/arch/hexagon/mm/vm_fault.c b/arch/hexagon/mm/vm_fault.c index 1bd276dbec7d..3771fb453898 100644 --- a/arch/hexagon/mm/vm_fault.c +++ b/arch/hexagon/mm/vm_fault.c @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Memory fault handling for Hexagon * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ /* @@ -24,13 +11,15 @@ * execptions. */ -#include <asm/pgtable.h> #include <asm/traps.h> -#include <asm/uaccess.h> +#include <asm/vm_fault.h> +#include <linux/uaccess.h> #include <linux/mm.h> +#include <linux/sched/signal.h> #include <linux/signal.h> -#include <linux/module.h> +#include <linux/extable.h> #include <linux/hardirq.h> +#include <linux/perf_event.h> /* * Decode of hardware exception sends us to one of several @@ -45,16 +34,15 @@ /* * Canonical page fault handler */ -void do_page_fault(unsigned long address, long cause, struct pt_regs *regs) +static void do_page_fault(unsigned long address, long cause, struct pt_regs *regs) { struct vm_area_struct *vma; struct mm_struct *mm = current->mm; - siginfo_t info; + int si_signo; int si_code = SEGV_MAPERR; - int fault; + vm_fault_t fault; const struct exception_table_entry *fixup; - unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | - (cause > 0 ? FAULT_FLAG_WRITE : 0); + unsigned int flags = FAULT_FLAG_DEFAULT; /* * If we're in an interrupt or have no user context, @@ -65,22 +53,15 @@ void do_page_fault(unsigned long address, long cause, struct pt_regs *regs) local_irq_enable(); -retry: - down_read(&mm->mmap_sem); - vma = find_vma(mm, address); - if (!vma) - goto bad_area; - - if (vma->vm_start <= address) - goto good_area; + if (user_mode(regs)) + flags |= FAULT_FLAG_USER; - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; - - if (expand_stack(vma, address)) - goto bad_area; + perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address); +retry: + vma = lock_mm_and_find_vma(mm, address, regs); + if (unlikely(!vma)) + goto bad_area_nosemaphore; -good_area: /* Address space is OK. Now check access rights. */ si_code = SEGV_ACCERR; @@ -96,33 +77,34 @@ good_area: case FLT_STORE: if (!(vma->vm_flags & VM_WRITE)) goto bad_area; + flags |= FAULT_FLAG_WRITE; break; } - fault = handle_mm_fault(mm, vma, address, flags); + fault = handle_mm_fault(vma, address, flags, regs); + + if (fault_signal_pending(fault, regs)) { + if (!user_mode(regs)) + goto no_context; + return; + } - if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) + /* The fault is fully completed (including releasing mmap lock) */ + if (fault & VM_FAULT_COMPLETED) return; /* The most common case -- we are done. */ if (likely(!(fault & VM_FAULT_ERROR))) { - if (flags & FAULT_FLAG_ALLOW_RETRY) { - if (fault & VM_FAULT_MAJOR) - current->maj_flt++; - else - current->min_flt++; - if (fault & VM_FAULT_RETRY) { - flags &= ~FAULT_FLAG_ALLOW_RETRY; - flags |= FAULT_FLAG_TRIED; - goto retry; - } + if (fault & VM_FAULT_RETRY) { + flags |= FAULT_FLAG_TRIED; + goto retry; } - up_read(&mm->mmap_sem); + mmap_read_unlock(mm); return; } - up_read(&mm->mmap_sem); + mmap_read_unlock(mm); /* Handle copyin/out exception cases */ if (!user_mode(regs)) @@ -137,28 +119,23 @@ good_area: * unable to fix up the page fault. */ if (fault & VM_FAULT_SIGBUS) { - info.si_signo = SIGBUS; - info.si_code = BUS_ADRERR; + si_signo = SIGBUS; + si_code = BUS_ADRERR; } /* Address is not in the memory map */ else { - info.si_signo = SIGSEGV; - info.si_code = SEGV_ACCERR; + si_signo = SIGSEGV; + si_code = SEGV_ACCERR; } - info.si_errno = 0; - info.si_addr = (void __user *)address; - force_sig_info(info.si_signo, &info, current); + force_sig_fault(si_signo, si_code, (void __user *)address); return; bad_area: - up_read(&mm->mmap_sem); + mmap_read_unlock(mm); +bad_area_nosemaphore: if (user_mode(regs)) { - info.si_signo = SIGSEGV; - info.si_errno = 0; - info.si_code = si_code; - info.si_addr = (void *)address; - force_sig_info(info.si_signo, &info, current); + force_sig_fault(SIGSEGV, si_code, (void __user *)address); return; } /* Kernel-mode fault falls through */ diff --git a/arch/hexagon/mm/vm_tlb.c b/arch/hexagon/mm/vm_tlb.c index 9647d00cb761..8b6405e2234b 100644 --- a/arch/hexagon/mm/vm_tlb.c +++ b/arch/hexagon/mm/vm_tlb.c @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Hexagon Virtual Machine TLB functions * * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. */ /* @@ -24,8 +11,10 @@ * be instantiated for it, differently from a native build. */ #include <linux/mm.h> +#include <linux/sched.h> #include <asm/page.h> #include <asm/hexagon_vm.h> +#include <asm/tlbflush.h> /* * Initial VM implementation has only one map active at a time, with |
