diff options
Diffstat (limited to 'arch/parisc')
96 files changed, 798 insertions, 673 deletions
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index fcc5973f7519..d3afac2f0d9b 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -8,6 +8,7 @@ config PARISC select HAVE_FUNCTION_GRAPH_TRACER select HAVE_SYSCALL_TRACEPOINTS select ARCH_WANT_FRAME_POINTERS + select ARCH_WANTS_MODULES_TEXT_SECTIONS if !64BIT select ARCH_HAS_CPU_CACHE_ALIASING select ARCH_HAS_DMA_ALLOC if PA11 select ARCH_HAS_DMA_OPS @@ -31,6 +32,9 @@ config PARISC select HAVE_KERNEL_UNCOMPRESSED select HAVE_PCI select HAVE_PERF_EVENTS + select HAVE_PERF_REGS + select HAVE_PERF_USER_STACK_DUMP + select PERF_USE_VMALLOC select HAVE_KERNEL_BZIP2 select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZ4 @@ -44,6 +48,7 @@ config PARISC select ARCH_HAVE_NMI_SAFE_CMPXCHG select GENERIC_SMP_IDLE_THREAD select GENERIC_ARCH_TOPOLOGY if SMP + select ARCH_SUPPORTS_SCHED_MC if SMP && PA8X00 select GENERIC_CPU_DEVICES if !SMP select GENERIC_LIB_DEVMEM_IS_ALLOWED select SYSCTL_ARCH_UNALIGN_ALLOW @@ -75,13 +80,13 @@ config PARISC select GENERIC_CLOCKEVENTS select CPU_NO_EFFICIENT_FFS select THREAD_INFO_IN_TASK + select MMU_GATHER_RCU_TABLE_FREE select NEED_DMA_MAP_STATE select NEED_SG_DMA_LENGTH select HAVE_ARCH_KGDB select HAVE_KPROBES select HAVE_KRETPROBES select HAVE_DYNAMIC_FTRACE if $(cc-option,-fpatchable-function-entry=1,1) - select HAVE_FTRACE_MCOUNT_RECORD if HAVE_DYNAMIC_FTRACE select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY if DYNAMIC_FTRACE select HAVE_KPROBES_ON_FTRACE select HAVE_DYNAMIC_FTRACE_WITH_REGS @@ -126,6 +131,9 @@ config GENERIC_BUG config GENERIC_BUG_RELATIVE_POINTERS bool +config GENERIC_CSUM + def_bool y + config GENERIC_HWEIGHT bool default y @@ -320,14 +328,6 @@ config SMP If you don't know what to do here, say N. -config SCHED_MC - bool "Multi-core scheduler support" - depends on GENERIC_ARCH_TOPOLOGY && PA8X00 - help - Multi-core scheduler support improves the CPU scheduler's decision - making when dealing with multi-core CPU chips at a cost of slightly - increased overhead in some places. If unsure say N here. - config IRQSTACKS bool "Use separate kernel stacks when processing interrupts" default y @@ -358,7 +358,8 @@ config ARCH_SPARSEMEM_DEFAULT source "kernel/Kconfig.hz" config COMPAT - def_bool y + bool "Kernel support for 32-bit binaries" + default 64BIT depends on 64BIT config AUDIT_ARCH diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index 21b8166a6883..4391783521bd 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -39,7 +39,9 @@ endif export LD_BFD -# Set default 32 bits cross compilers for vdso +# Set default 32 bits cross compilers for vdso. +# This means that for 64BIT, both the 64-bit tools and the 32-bit tools +# need to be in the path. CC_ARCHES_32 = hppa hppa2.0 hppa1.1 CC_SUFFIXES = linux linux-gnu unknown-linux-gnu suse-linux CROSS32_COMPILE := $(call cc-cross-prefix, \ @@ -139,7 +141,7 @@ palo lifimage: vmlinuz fi @if test ! -f "$(PALOCONF)"; then \ cp $(srctree)/arch/parisc/defpalo.conf $(objtree)/palo.conf; \ - echo 'A generic palo config file ($(objree)/palo.conf) has been created for you.'; \ + echo 'A generic palo config file ($(objtree)/palo.conf) has been created for you.'; \ echo 'You should check it and re-run "make palo".'; \ echo 'WARNING: the "lifimage" file is now placed in this directory by default!'; \ false; \ @@ -172,13 +174,21 @@ ifeq ($(KBUILD_EXTMOD),) # this hack. prepare: vdso_prepare vdso_prepare: prepare0 - $(if $(CONFIG_64BIT),$(Q)$(MAKE) \ - $(build)=arch/parisc/kernel/vdso64 include/generated/vdso64-offsets.h) +ifdef CONFIG_64BIT + $(Q)$(MAKE) $(build)=arch/parisc/kernel/vdso64 include/generated/vdso64-offsets.h + $(if $(CONFIG_COMPAT),$(Q)$(MAKE) \ + $(build)=arch/parisc/kernel/vdso32 include/generated/vdso32-offsets.h) +else $(Q)$(MAKE) $(build)=arch/parisc/kernel/vdso32 include/generated/vdso32-offsets.h endif +endif +ifdef CONFIG_64BIT +vdso-install-y += arch/parisc/kernel/vdso64/vdso64.so +vdso-install-$(CONFIG_COMPAT) += arch/parisc/kernel/vdso32/vdso32.so +else vdso-install-y += arch/parisc/kernel/vdso32/vdso32.so -vdso-install-$(CONFIG_64BIT) += arch/parisc/kernel/vdso64/vdso64.so +endif install: KBUILD_IMAGE := vmlinux zinstall: KBUILD_IMAGE := vmlinuz diff --git a/arch/parisc/boot/compressed/Makefile b/arch/parisc/boot/compressed/Makefile index 92227fa813dc..14eefb5ed5d1 100644 --- a/arch/parisc/boot/compressed/Makefile +++ b/arch/parisc/boot/compressed/Makefile @@ -18,6 +18,7 @@ KBUILD_CFLAGS += -fno-PIE -mno-space-regs -mdisable-fpregs -Os ifndef CONFIG_64BIT KBUILD_CFLAGS += -mfast-indirect-calls endif +KBUILD_CFLAGS += $(CC_FLAGS_DIALECT) LDFLAGS_vmlinux := -X -e startup --as-needed -T $(obj)/vmlinux: $(obj)/vmlinux.lds $(addprefix $(obj)/, $(OBJECTS)) $(LIBGCC) FORCE diff --git a/arch/parisc/boot/compressed/misc.c b/arch/parisc/boot/compressed/misc.c index 9c83bd06ef15..111f267230a1 100644 --- a/arch/parisc/boot/compressed/misc.c +++ b/arch/parisc/boot/compressed/misc.c @@ -278,6 +278,19 @@ static void parse_elf(void *output) free(phdrs); } +/* + * The regular get_unaligned_le32 uses __builtin_memcpy which can trigger + * warnings when reading a byte/char output_len as an integer, as the size of a + * char is less than that of an integer. Use type punning and the packed + * attribute, which requires -fno-strict-aliasing, to work around the problem. + */ +static u32 punned_get_unaligned_le32(const void *p) +{ + const struct { __le32 x; } __packed * __get_pptr = p; + + return le32_to_cpu(__get_pptr->x); +} + asmlinkage unsigned long __visible decompress_kernel(unsigned int started_wide, unsigned int command_line, const unsigned int rd_start, @@ -309,7 +322,7 @@ asmlinkage unsigned long __visible decompress_kernel(unsigned int started_wide, * leave 2 MB for the stack. */ vmlinux_addr = (unsigned long) &_ebss + 2*1024*1024; - vmlinux_len = get_unaligned_le32(&output_len); + vmlinux_len = punned_get_unaligned_le32(&output_len); output = (char *) vmlinux_addr; /* diff --git a/arch/parisc/boot/compressed/vmlinux.lds.S b/arch/parisc/boot/compressed/vmlinux.lds.S index ab7b43990857..87d24cc824b6 100644 --- a/arch/parisc/boot/compressed/vmlinux.lds.S +++ b/arch/parisc/boot/compressed/vmlinux.lds.S @@ -90,6 +90,7 @@ SECTIONS /* Sections to be discarded */ DISCARDS /DISCARD/ : { + *(.modinfo) #ifdef CONFIG_64BIT /* temporary hack until binutils is fixed to not emit these * for static binaries diff --git a/arch/parisc/configs/generic-32bit_defconfig b/arch/parisc/configs/generic-32bit_defconfig index 5ce258f3fffa..3572a32f7849 100644 --- a/arch/parisc/configs/generic-32bit_defconfig +++ b/arch/parisc/configs/generic-32bit_defconfig @@ -78,7 +78,6 @@ CONFIG_DUMMY=m CONFIG_TUN=m # CONFIG_NET_VENDOR_3COM is not set # CONFIG_NET_VENDOR_ADAPTEC is not set -# CONFIG_NET_VENDOR_ALTEON is not set # CONFIG_NET_VENDOR_AMD is not set # CONFIG_NET_VENDOR_ATHEROS is not set # CONFIG_NET_VENDOR_BROADCOM is not set @@ -119,7 +118,6 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=m CONFIG_LEGACY_PTY_COUNT=64 CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=8 CONFIG_SERIAL_8250_EXTENDED=y @@ -132,11 +130,11 @@ CONFIG_I2C=y CONFIG_HWMON=m CONFIG_DRM=m CONFIG_DRM_DISPLAY_DP_AUX_CEC=y -# CONFIG_DRM_I2C_CH7006 is not set -# CONFIG_DRM_I2C_SIL164 is not set CONFIG_DRM_RADEON=m CONFIG_DRM_NOUVEAU=m # CONFIG_DRM_NOUVEAU_BACKLIGHT is not set +# CONFIG_DRM_NOUVEAU_CH7006 is not set +# CONFIG_DRM_NOUVEAU_SIL164 is not set CONFIG_DRM_VGEM=m CONFIG_DRM_UDL=m CONFIG_DRM_MGAG200=m @@ -232,8 +230,8 @@ CONFIG_AUXDISPLAY=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_SECURITY=y -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_SECURITY=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y CONFIG_QFMT_V2=y @@ -251,7 +249,7 @@ CONFIG_CIFS=m CONFIG_CIFS_XATTR=y CONFIG_CIFS_POSIX=y # CONFIG_CIFS_DEBUG is not set -CONFIG_CRYPTO_TEST=m +CONFIG_CRYPTO_BENCHMARK=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m @@ -260,12 +258,9 @@ CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRC_CCITT=m -CONFIG_CRC_T10DIF=y CONFIG_FONTS=y CONFIG_PRINTK_TIME=y CONFIG_MAGIC_SYSRQ=y diff --git a/arch/parisc/configs/generic-64bit_defconfig b/arch/parisc/configs/generic-64bit_defconfig index 19a804860ed5..406f8174a1d2 100644 --- a/arch/parisc/configs/generic-64bit_defconfig +++ b/arch/parisc/configs/generic-64bit_defconfig @@ -97,7 +97,6 @@ CONFIG_NETCONSOLE_DYNAMIC=y CONFIG_TUN=y # CONFIG_NET_VENDOR_3COM is not set # CONFIG_NET_VENDOR_ADAPTEC is not set -# CONFIG_NET_VENDOR_ALTEON is not set # CONFIG_NET_VENDOR_AMD is not set # CONFIG_NET_VENDOR_ATHEROS is not set # CONFIG_NET_VENDOR_BROADCOM is not set @@ -158,7 +157,6 @@ CONFIG_SERIO_SERPORT=m CONFIG_SERIO_RAW=m # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_8250=y -# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_NR_UARTS=8 CONFIG_SERIAL_8250_RUNTIME_UARTS=8 @@ -193,11 +191,11 @@ CONFIG_MEDIA_SUPPORT=m CONFIG_AGP=y CONFIG_AGP_PARISC=y CONFIG_DRM=y -# CONFIG_DRM_I2C_CH7006 is not set -# CONFIG_DRM_I2C_SIL164 is not set CONFIG_DRM_RADEON=y CONFIG_DRM_NOUVEAU=m # CONFIG_DRM_NOUVEAU_BACKLIGHT is not set +# CONFIG_DRM_NOUVEAU_CH7006 is not set +# CONFIG_DRM_NOUVEAU_SIL164 is not set CONFIG_DRM_MGAG200=m CONFIG_FB=y CONFIG_FB_PM2=m @@ -251,8 +249,8 @@ CONFIG_STAGING=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_SECURITY=y -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_SECURITY=y CONFIG_XFS_FS=m CONFIG_BTRFS_FS=m CONFIG_QUOTA=y @@ -268,7 +266,6 @@ CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_TMPFS_XATTR=y CONFIG_CONFIGFS_FS=y -CONFIG_SYSV_FS=y CONFIG_NFS_FS=m CONFIG_NFS_V4=m CONFIG_NFS_V4_1=y @@ -284,17 +281,11 @@ CONFIG_NLS_ASCII=m CONFIG_NLS_ISO8859_1=m CONFIG_NLS_ISO8859_2=m CONFIG_NLS_UTF8=m -CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_ECB=m -CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD5=y -CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_DEFLATE=m # CONFIG_CRYPTO_HW is not set -CONFIG_CRC_CCITT=m -CONFIG_LIBCRC32C=y CONFIG_PRINTK_TIME=y CONFIG_DEBUG_KERNEL=y CONFIG_STRIP_ASM_SYMS=y diff --git a/arch/parisc/include/asm/Kbuild b/arch/parisc/include/asm/Kbuild index 4fb596d94c89..d48d158f7241 100644 --- a/arch/parisc/include/asm/Kbuild +++ b/arch/parisc/include/asm/Kbuild @@ -4,4 +4,5 @@ generated-y += syscall_table_64.h generic-y += agp.h generic-y += kvm_para.h generic-y += mcs_spinlock.h +generic-y += ring_buffer.h generic-y += user.h diff --git a/arch/parisc/include/asm/alternative.h b/arch/parisc/include/asm/alternative.h index 1eb488f25b83..1601ae4b888d 100644 --- a/arch/parisc/include/asm/alternative.h +++ b/arch/parisc/include/asm/alternative.h @@ -13,7 +13,7 @@ #define INSN_PxTLB 0x02 /* modify pdtlb, pitlb */ #define INSN_NOP 0x08000240 /* nop */ -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include <linux/init.h> #include <linux/types.h> @@ -61,6 +61,6 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end, .word (new_instr_ptr - .) ! \ .previous -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* __ASM_PARISC_ALTERNATIVE_H */ diff --git a/arch/parisc/include/asm/assembly.h b/arch/parisc/include/asm/assembly.h index 000a28e1c5e8..c20261604f09 100644 --- a/arch/parisc/include/asm/assembly.h +++ b/arch/parisc/include/asm/assembly.h @@ -53,7 +53,7 @@ #define SR_TEMP2 2 #define SR_USER 3 -#ifdef __ASSEMBLY__ +#ifdef __ASSEMBLER__ #ifdef CONFIG_64BIT #define LDREG ldd @@ -582,5 +582,5 @@ .previous -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif diff --git a/arch/parisc/include/asm/barrier.h b/arch/parisc/include/asm/barrier.h index c705decf2bed..519b1903c5ed 100644 --- a/arch/parisc/include/asm/barrier.h +++ b/arch/parisc/include/asm/barrier.h @@ -4,7 +4,7 @@ #include <asm/alternative.h> -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ /* The synchronize caches instruction executes as a nop on systems in which all memory references are performed in order. */ @@ -93,5 +93,5 @@ do { \ }) #include <asm-generic/barrier.h> -#endif /* !__ASSEMBLY__ */ +#endif /* !__ASSEMBLER__ */ #endif /* __ASM_BARRIER_H */ diff --git a/arch/parisc/include/asm/bitops.h b/arch/parisc/include/asm/bitops.h index 0ec9cfc5131f..bd1280a8a5ec 100644 --- a/arch/parisc/include/asm/bitops.h +++ b/arch/parisc/include/asm/bitops.h @@ -123,7 +123,7 @@ static __inline__ int test_and_change_bit(int nr, volatile unsigned long * addr) * cycles for each mispredicted branch. */ -static __inline__ unsigned long __ffs(unsigned long x) +static __inline__ __attribute_const__ unsigned long __ffs(unsigned long x) { unsigned long ret; @@ -161,7 +161,7 @@ static __inline__ unsigned long __ffs(unsigned long x) * This is defined the same way as the libc and compiler builtin * ffs routines, therefore differs in spirit from the above ffz (man ffs). */ -static __inline__ int ffs(int x) +static __inline__ __attribute_const__ int ffs(int x) { return x ? (__ffs((unsigned long)x) + 1) : 0; } @@ -171,7 +171,7 @@ static __inline__ int ffs(int x) * fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. */ -static __inline__ int fls(unsigned int x) +static __inline__ __attribute_const__ int fls(unsigned int x) { int ret; if (!x) diff --git a/arch/parisc/include/asm/bug.h b/arch/parisc/include/asm/bug.h index 833555f74ffa..5cf35489ad80 100644 --- a/arch/parisc/include/asm/bug.h +++ b/arch/parisc/include/asm/bug.h @@ -2,8 +2,6 @@ #ifndef _PARISC_BUG_H #define _PARISC_BUG_H -#include <linux/kernel.h> /* for BUGFLAG_TAINT */ - /* * Tell the user there is some problem. * The offending file and line are encoded in the __bug_table section. @@ -50,7 +48,7 @@ #endif #ifdef CONFIG_DEBUG_BUGVERBOSE -#define __WARN_FLAGS(flags) \ +#define __WARN_FLAGS(cond_str, flags) \ do { \ asm volatile("\n" \ "1:\t" PARISC_BUG_BREAK_ASM "\n" \ @@ -61,12 +59,12 @@ "\t.short %1, %2\n" \ "\t.blockz %3-2*4-2*2\n" \ "\t.popsection" \ - : : "i" (__FILE__), "i" (__LINE__), \ + : : "i" (WARN_CONDITION_STR(cond_str) __FILE__), "i" (__LINE__), \ "i" (BUGFLAG_WARNING|(flags)), \ "i" (sizeof(struct bug_entry)) ); \ } while(0) #else -#define __WARN_FLAGS(flags) \ +#define __WARN_FLAGS(cond_str, flags) \ do { \ asm volatile("\n" \ "1:\t" PARISC_BUG_BREAK_ASM "\n" \ diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h index a3f0f100f219..3f8d3be6ef24 100644 --- a/arch/parisc/include/asm/cache.h +++ b/arch/parisc/include/asm/cache.h @@ -16,7 +16,7 @@ #define L1_CACHE_BYTES 16 #define L1_CACHE_SHIFT 4 -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #define SMP_CACHE_BYTES L1_CACHE_BYTES @@ -66,7 +66,7 @@ void parisc_setup_cache_timing(void); ALTERNATIVE(ALT_COND_NO_IOC_FDC, INSN_NOP) :::"memory") #define asm_syncdma() asm volatile("syncdma" :::"memory") -#endif /* ! __ASSEMBLY__ */ +#endif /* ! __ASSEMBLER__ */ /* Classes of processor wrt: disabling space register hashing */ diff --git a/arch/parisc/include/asm/checksum.h b/arch/parisc/include/asm/checksum.h index 2aceebcd695c..382758808726 100644 --- a/arch/parisc/include/asm/checksum.h +++ b/arch/parisc/include/asm/checksum.h @@ -4,73 +4,7 @@ #include <linux/in6.h> -/* - * computes the checksum of a memory block at buff, length len, - * and adds in "sum" (32-bit) - * - * returns a 32-bit number suitable for feeding into itself - * or csum_tcpudp_magic - * - * this function must be called with even lengths, except - * for the last fragment, which may be odd - * - * it's best to have buff aligned on a 32-bit boundary - */ -extern __wsum csum_partial(const void *, int, __wsum); - -/* - * Optimized for IP headers, which always checksum on 4 octet boundaries. - * - * Written by Randolph Chung <tausq@debian.org>, and then mucked with by - * LaMont Jones <lamont@debian.org> - */ -static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) -{ - unsigned int sum; - unsigned long t0, t1, t2; - - __asm__ __volatile__ ( -" ldws,ma 4(%1), %0\n" -" addib,<= -4, %2, 2f\n" -"\n" -" ldws 4(%1), %4\n" -" ldws 8(%1), %5\n" -" add %0, %4, %0\n" -" ldws,ma 12(%1), %3\n" -" addc %0, %5, %0\n" -" addc %0, %3, %0\n" -"1: ldws,ma 4(%1), %3\n" -" addib,> -1, %2, 1b\n" -" addc %0, %3, %0\n" -"\n" -" extru %0, 31, 16, %4\n" -" extru %0, 15, 16, %5\n" -" addc %4, %5, %0\n" -" extru %0, 15, 16, %5\n" -" add %0, %5, %0\n" -" subi -1, %0, %0\n" -"2:\n" - : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (t0), "=r" (t1), "=r" (t2) - : "1" (iph), "2" (ihl) - : "memory"); - - return (__force __sum16)sum; -} - -/* - * Fold a partial checksum - */ -static inline __sum16 csum_fold(__wsum csum) -{ - u32 sum = (__force u32)csum; - /* add the swapped two 16-bit halves of sum, - a possible carry from adding the two 16-bit halves, - will carry from the lower half into the upper half, - giving us the correct sum in the upper half. */ - sum += (sum << 16) + (sum >> 16); - return (__force __sum16)(~sum >> 16); -} - +#define csum_tcpudp_nofold csum_tcpudp_nofold static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len, __u8 proto, __wsum sum) @@ -85,26 +19,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, return sum; } -/* - * computes the checksum of the TCP/UDP pseudo-header - * returns a 16-bit checksum, already complemented - */ -static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, - __u32 len, __u8 proto, - __wsum sum) -{ - return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -} - -/* - * this routine is used for miscellaneous IP-like checksums, mainly - * in icmp.c - */ -static inline __sum16 ip_compute_csum(const void *buf, int len) -{ - return csum_fold (csum_partial(buf, len, 0)); -} - +#include <asm-generic/checksum.h> #define _HAVE_ARCH_IPV6_CSUM static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h index 339d1b833fa7..13a5a55dec65 100644 --- a/arch/parisc/include/asm/compat.h +++ b/arch/parisc/include/asm/compat.h @@ -130,7 +130,7 @@ typedef compat_ulong_t compat_elf_gregset_t[COMPAT_ELF_NGREG]; static inline int __is_compat_task(struct task_struct *t) { - return test_tsk_thread_flag(t, TIF_32BIT); + return IS_ENABLED(CONFIG_COMPAT) && test_tsk_thread_flag(t, TIF_32BIT); } static inline int is_compat_task(void) diff --git a/arch/parisc/include/asm/current.h b/arch/parisc/include/asm/current.h index dc7aea07c3f3..2814529a4c28 100644 --- a/arch/parisc/include/asm/current.h +++ b/arch/parisc/include/asm/current.h @@ -2,7 +2,7 @@ #ifndef _ASM_PARISC_CURRENT_H #define _ASM_PARISC_CURRENT_H -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ struct task_struct; static __always_inline struct task_struct *get_current(void) @@ -16,6 +16,6 @@ static __always_inline struct task_struct *get_current(void) #define current get_current() -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* _ASM_PARISC_CURRENT_H */ diff --git a/arch/parisc/include/asm/dwarf.h b/arch/parisc/include/asm/dwarf.h index f4512db86a19..526f4a79262c 100644 --- a/arch/parisc/include/asm/dwarf.h +++ b/arch/parisc/include/asm/dwarf.h @@ -6,7 +6,7 @@ #ifndef _ASM_PARISC_DWARF_H #define _ASM_PARISC_DWARF_H -#ifdef __ASSEMBLY__ +#ifdef __ASSEMBLER__ #define CFI_STARTPROC .cfi_startproc #define CFI_ENDPROC .cfi_endproc @@ -15,6 +15,6 @@ #define CFI_REL_OFFSET .cfi_rel_offset #define CFI_UNDEFINED .cfi_undefined -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* _ASM_PARISC_DWARF_H */ diff --git a/arch/parisc/include/asm/fixmap.h b/arch/parisc/include/asm/fixmap.h index 5cd80ce1163a..9cafa449c4a7 100644 --- a/arch/parisc/include/asm/fixmap.h +++ b/arch/parisc/include/asm/fixmap.h @@ -39,7 +39,7 @@ #define KERNEL_MAP_START (GATEWAY_PAGE_SIZE) #define KERNEL_MAP_END (FIXMAP_START) -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ enum fixed_addresses { @@ -59,6 +59,6 @@ extern void *parisc_vmalloc_start; void set_fixmap(enum fixed_addresses idx, phys_addr_t phys); void clear_fixmap(enum fixed_addresses idx); -#endif /*__ASSEMBLY__*/ +#endif /*__ASSEMBLER__*/ #endif /*_ASM_FIXMAP_H*/ diff --git a/arch/parisc/include/asm/floppy.h b/arch/parisc/include/asm/floppy.h index b318a7df52f6..f15b69fea901 100644 --- a/arch/parisc/include/asm/floppy.h +++ b/arch/parisc/include/asm/floppy.h @@ -8,9 +8,9 @@ #ifndef __ASM_PARISC_FLOPPY_H #define __ASM_PARISC_FLOPPY_H +#include <linux/sizes.h> #include <linux/vmalloc.h> - /* * The DMA channel used by the floppy controller cannot access data at * addresses >= 16MB @@ -20,15 +20,12 @@ * floppy accesses go through the track buffer. */ #define _CROSS_64KB(a,s,vdma) \ -(!(vdma) && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64)) - -#define CROSS_64KB(a,s) _CROSS_64KB(a,s,use_virtual_dma & 1) - + (!(vdma) && \ + ((unsigned long)(a) / SZ_64K != ((unsigned long)(a) + (s) - 1) / SZ_64K)) #define SW fd_routine[use_virtual_dma&1] #define CSW fd_routine[can_use_virtual_dma & 1] - #define fd_inb(base, reg) readb((base) + (reg)) #define fd_outb(value, base, reg) writeb(value, (base) + (reg)) @@ -206,7 +203,7 @@ static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io) static int hard_dma_setup(char *addr, unsigned long size, int mode, int io) { #ifdef FLOPPY_SANITY_CHECK - if (CROSS_64KB(addr, size)) { + if (_CROSS_64KB(addr, size, use_virtual_dma & 1)) { printk("DMA crossing 64-K boundary %p-%p\n", addr, addr+size); return -1; } diff --git a/arch/parisc/include/asm/ftrace.h b/arch/parisc/include/asm/ftrace.h index f1cc1ee3a647..8b89d2b642eb 100644 --- a/arch/parisc/include/asm/ftrace.h +++ b/arch/parisc/include/asm/ftrace.h @@ -2,7 +2,7 @@ #ifndef _ASM_PARISC_FTRACE_H #define _ASM_PARISC_FTRACE_H -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ extern void mcount(void); #define MCOUNT_ADDR ((unsigned long)mcount) @@ -29,6 +29,6 @@ unsigned long ftrace_call_adjust(unsigned long addr); #define ftrace_return_address(n) return_address(n) -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* _ASM_PARISC_FTRACE_H */ diff --git a/arch/parisc/include/asm/hardware.h b/arch/parisc/include/asm/hardware.h index a005ebc54779..a797c8753f29 100644 --- a/arch/parisc/include/asm/hardware.h +++ b/arch/parisc/include/asm/hardware.h @@ -2,7 +2,7 @@ #ifndef _PARISC_HARDWARE_H #define _PARISC_HARDWARE_H -#include <linux/mod_devicetable.h> +#include <linux/device-id/parisc.h> #define HWTYPE_ANY_ID PA_HWTYPE_ANY_ID #define HVERSION_ANY_ID PA_HVERSION_ANY_ID @@ -95,8 +95,6 @@ struct bc_module { #define HPHW_MC 15 #define HPHW_FAULTY 31 -struct parisc_device_id; - /* hardware.c: */ extern const char *parisc_hardware_description(struct parisc_device_id *id); extern enum cpu_type parisc_get_cpu_type(unsigned long hversion); diff --git a/arch/parisc/include/asm/io.h b/arch/parisc/include/asm/io.h index 3143cf29ce27..f01ad3ad60b5 100644 --- a/arch/parisc/include/asm/io.h +++ b/arch/parisc/include/asm/io.h @@ -131,13 +131,10 @@ static inline void gsc_writeq(unsigned long long val, unsigned long addr) _PAGE_ACCESSED | _PAGE_NO_CACHE) #define ioremap_wc(addr, size) \ - ioremap_prot((addr), (size), _PAGE_IOREMAP) + ioremap_prot((addr), (size), __pgprot(_PAGE_IOREMAP)) #define pci_iounmap pci_iounmap -void memcpy_fromio(void *dst, const volatile void __iomem *src, int count); -#define memcpy_fromio memcpy_fromio - /* Port-space IO */ #define inb_p inb @@ -227,36 +224,54 @@ extern void outsl (unsigned long port, const void *src, unsigned long count); #define F_EXTEND(x) ((unsigned long)((x) | (0xffffffff00000000ULL))) #ifdef CONFIG_64BIT -#define ioread64 ioread64 -#define ioread64be ioread64be -#define iowrite64 iowrite64 -#define iowrite64be iowrite64be extern u64 ioread64(const void __iomem *addr); extern u64 ioread64be(const void __iomem *addr); +#define ioread64 ioread64 +#define ioread64be ioread64be + extern void iowrite64(u64 val, void __iomem *addr); extern void iowrite64be(u64 val, void __iomem *addr); +#define iowrite64 iowrite64 +#define iowrite64be iowrite64be #endif -#include <asm-generic/iomap.h> -/* - * These get provided from <asm-generic/iomap.h> since parisc does not - * select GENERIC_IOMAP. - */ +extern void __iomem *ioport_map(unsigned long port, unsigned int nr); +extern void ioport_unmap(void __iomem *); #define ioport_map ioport_map #define ioport_unmap ioport_unmap + +extern unsigned int ioread8(const void __iomem *); +extern unsigned int ioread16(const void __iomem *); +extern unsigned int ioread16be(const void __iomem *); +extern unsigned int ioread32(const void __iomem *); +extern unsigned int ioread32be(const void __iomem *); #define ioread8 ioread8 #define ioread16 ioread16 #define ioread32 ioread32 #define ioread16be ioread16be #define ioread32be ioread32be + +extern void iowrite8(u8, void __iomem *); +extern void iowrite16(u16, void __iomem *); +extern void iowrite16be(u16, void __iomem *); +extern void iowrite32(u32, void __iomem *); +extern void iowrite32be(u32, void __iomem *); #define iowrite8 iowrite8 #define iowrite16 iowrite16 #define iowrite32 iowrite32 #define iowrite16be iowrite16be #define iowrite32be iowrite32be + +extern void ioread8_rep(const void __iomem *port, void *buf, unsigned long count); +extern void ioread16_rep(const void __iomem *port, void *buf, unsigned long count); +extern void ioread32_rep(const void __iomem *port, void *buf, unsigned long count); #define ioread8_rep ioread8_rep #define ioread16_rep ioread16_rep #define ioread32_rep ioread32_rep + +extern void iowrite8_rep(void __iomem *port, const void *buf, unsigned long count); +extern void iowrite16_rep(void __iomem *port, const void *buf, unsigned long count); +extern void iowrite32_rep(void __iomem *port, const void *buf, unsigned long count); #define iowrite8_rep iowrite8_rep #define iowrite16_rep iowrite16_rep #define iowrite32_rep iowrite32_rep diff --git a/arch/parisc/include/asm/jump_label.h b/arch/parisc/include/asm/jump_label.h index 317ebc5edc9f..f325ae3c622f 100644 --- a/arch/parisc/include/asm/jump_label.h +++ b/arch/parisc/include/asm/jump_label.h @@ -2,7 +2,7 @@ #ifndef _ASM_PARISC_JUMP_LABEL_H #define _ASM_PARISC_JUMP_LABEL_H -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include <linux/types.h> #include <linux/stringify.h> @@ -44,5 +44,5 @@ l_yes: return true; } -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif diff --git a/arch/parisc/include/asm/kexec.h b/arch/parisc/include/asm/kexec.h index 87e174006995..bf31e2d50df9 100644 --- a/arch/parisc/include/asm/kexec.h +++ b/arch/parisc/include/asm/kexec.h @@ -14,7 +14,7 @@ #define KEXEC_ARCH KEXEC_ARCH_PARISC #define ARCH_HAS_KIMAGE_ARCH -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ struct kimage_arch { unsigned long initrd_start; @@ -28,6 +28,6 @@ static inline void crash_setup_regs(struct pt_regs *newregs, /* Dummy implementation for now */ } -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* _ASM_PARISC_KEXEC_H */ diff --git a/arch/parisc/include/asm/kgdb.h b/arch/parisc/include/asm/kgdb.h index 317cd434bee3..9ece98bc6d9d 100644 --- a/arch/parisc/include/asm/kgdb.h +++ b/arch/parisc/include/asm/kgdb.h @@ -21,7 +21,7 @@ #define CACHE_FLUSH_IS_SAFE 1 -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ static inline void arch_kgdb_breakpoint(void) { diff --git a/arch/parisc/include/asm/linkage.h b/arch/parisc/include/asm/linkage.h index cd6fe4febead..d4cad492b971 100644 --- a/arch/parisc/include/asm/linkage.h +++ b/arch/parisc/include/asm/linkage.h @@ -15,7 +15,7 @@ */ #define ASM_NL ! -#ifdef __ASSEMBLY__ +#ifdef __ASSEMBLER__ #define ENTRY(name) \ ALIGN !\ @@ -35,6 +35,6 @@ name: ASM_NL\ .procend ASM_NL\ ENDPROC(name) -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* __ASM_PARISC_LINKAGE_H */ diff --git a/arch/parisc/include/asm/page.h b/arch/parisc/include/asm/page.h index 7fd447092630..3630b36d07da 100644 --- a/arch/parisc/include/asm/page.h +++ b/arch/parisc/include/asm/page.h @@ -8,7 +8,7 @@ #define HAVE_ARCH_HUGETLB_UNMAPPED_AREA -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include <asm/types.h> #include <asm/cache.h> @@ -21,7 +21,6 @@ struct vm_area_struct; void clear_page_asm(void *page); void copy_page_asm(void *to, void *from); -#define clear_user_page(vto, vaddr, page) clear_page_asm(vto) void copy_user_highpage(struct page *to, struct page *from, unsigned long vaddr, struct vm_area_struct *vma); #define __HAVE_ARCH_COPY_USER_HIGHPAGE @@ -93,7 +92,7 @@ typedef struct __physmem_range { extern physmem_range_t pmem_ranges[]; extern int npmem_ranges; -#endif /* !__ASSEMBLY__ */ +#endif /* !__ASSEMBLER__ */ /* WARNING: The definitions below must match exactly to sizeof(pte_t) * etc @@ -139,7 +138,7 @@ extern int npmem_ranges; #define KERNEL_BINARY_TEXT_START (__PAGE_OFFSET + 0x100000) /* These macros don't work for 64-bit C code -- don't allow in C at all */ -#ifdef __ASSEMBLY__ +#ifdef __ASSEMBLER__ # define PA(x) ((x)-__PAGE_OFFSET) # define VA(x) ((x)+__PAGE_OFFSET) #endif diff --git a/arch/parisc/include/asm/parisc-device.h b/arch/parisc/include/asm/parisc-device.h index 9e74cef4d774..4731420e55ad 100644 --- a/arch/parisc/include/asm/parisc-device.h +++ b/arch/parisc/include/asm/parisc-device.h @@ -3,6 +3,7 @@ #define _ASM_PARISC_PARISC_DEVICE_H_ #include <linux/device.h> +#include <linux/device-id/parisc.h> struct parisc_device { struct resource hpa; /* Hard Physical Address */ diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h index 5d2d9737e579..6080a1516b34 100644 --- a/arch/parisc/include/asm/pdc.h +++ b/arch/parisc/include/asm/pdc.h @@ -4,7 +4,7 @@ #include <uapi/asm/pdc.h> -#if !defined(__ASSEMBLY__) +#if !defined(__ASSEMBLER__) extern int parisc_narrow_firmware; @@ -109,5 +109,5 @@ static inline char * os_id_to_string(u16 os_id) { } } -#endif /* !defined(__ASSEMBLY__) */ +#endif /* !defined(__ASSEMBLER__) */ #endif /* _PARISC_PDC_H */ diff --git a/arch/parisc/include/asm/pdcpat.h b/arch/parisc/include/asm/pdcpat.h index 8f160375b865..ec97eefa4ef6 100644 --- a/arch/parisc/include/asm/pdcpat.h +++ b/arch/parisc/include/asm/pdcpat.h @@ -179,6 +179,7 @@ #define PDC_PAT_PD 74L /* Protection Domain Info */ #define PDC_PAT_PD_GET_ADDR_MAP 0L /* Get Address Map */ #define PDC_PAT_PD_GET_PDC_INTERF_REV 1L /* Get PDC Interface Revisions */ +#define PDC_PAT_PD_GET_PLATFORM_COUNTER 10L /* Get 64-bit free running counter */ #define PDC_PAT_CAPABILITY_BIT_PDC_SERIALIZE (1UL << 0) #define PDC_PAT_CAPABILITY_BIT_PDC_POLLING (1UL << 1) @@ -210,7 +211,7 @@ #define PDC_PAT_SYSTEM_INFO 76L /* PDC_PAT_SYSTEM_INFO uses the same options as PDC_SYSTEM_INFO function. */ -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include <linux/types.h> #ifdef CONFIG_64BIT @@ -373,9 +374,11 @@ extern int pdc_pat_pd_get_addr_map(unsigned long *actual_len, void *mem_addr, unsigned long count, unsigned long offset); extern int pdc_pat_pd_get_pdc_revisions(unsigned long *legacy_rev, unsigned long *pat_rev, unsigned long *pdc_cap); +extern int pdc_pat_pd_get_platform_counter(uint64_t **addr, + unsigned long *freq, unsigned long *uniq); -extern int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *val); -extern int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val); +extern int pdc_pat_io_pci_cfg_read(unsigned long pci_addr, int pci_size, u32 *val); +extern int pdc_pat_io_pci_cfg_write(unsigned long pci_addr, int pci_size, u32 val); extern int pdc_pat_mem_pdt_info(struct pdc_pat_mem_retinfo *rinfo); extern int pdc_pat_mem_pdt_cell_info(struct pdc_pat_mem_cell_pdt_retinfo *rinfo, @@ -389,6 +392,6 @@ extern int pdc_pat_mem_get_dimm_phys_location( struct pdc_pat_mem_phys_mem_location *pret, unsigned long phys_addr); -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* ! __PARISC_PATPDC_H */ diff --git a/arch/parisc/include/asm/perf_event.h b/arch/parisc/include/asm/perf_event.h index 1e0fd8ba6c03..8a2925029d15 100644 --- a/arch/parisc/include/asm/perf_event.h +++ b/arch/parisc/include/asm/perf_event.h @@ -1,6 +1,12 @@ #ifndef __ASM_PARISC_PERF_EVENT_H #define __ASM_PARISC_PERF_EVENT_H -/* Empty, just to avoid compiling error */ +#include <asm/psw.h> + +#define perf_arch_fetch_caller_regs(regs, __ip) { \ + (regs)->gr[0] = KERNEL_PSW; \ + (regs)->iaoq[0] = (__ip); \ + asm volatile("copy %%sp, %0\n":"=r"((regs)->gr[30])); \ +} #endif /* __ASM_PARISC_PERF_EVENT_H */ diff --git a/arch/parisc/include/asm/pgalloc.h b/arch/parisc/include/asm/pgalloc.h index 2ca74a56415c..3b84ee93edaa 100644 --- a/arch/parisc/include/asm/pgalloc.h +++ b/arch/parisc/include/asm/pgalloc.h @@ -39,7 +39,7 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address) ptdesc = pagetable_alloc(gfp, PMD_TABLE_ORDER); if (!ptdesc) return NULL; - if (!pagetable_pmd_ctor(ptdesc)) { + if (!pagetable_pmd_ctor(mm, ptdesc)) { pagetable_free(ptdesc); return NULL; } diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h index babf65751e81..467b8547ac8b 100644 --- a/arch/parisc/include/asm/pgtable.h +++ b/arch/parisc/include/asm/pgtable.h @@ -12,7 +12,7 @@ #include <asm/fixmap.h> -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ /* * we simulate an x86-style page table for the linux mm code */ @@ -73,7 +73,7 @@ extern void __update_cache(pte_t pte); mb(); \ } while(0) -#endif /* !__ASSEMBLY__ */ +#endif /* !__ASSEMBLER__ */ #define pte_ERROR(e) \ printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) @@ -85,7 +85,7 @@ extern void __update_cache(pte_t pte); printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e)) /* This is the size of the initially mapped kernel memory */ -#if defined(CONFIG_64BIT) +#if defined(CONFIG_64BIT) || defined(CONFIG_KALLSYMS) #define KERNEL_INITIAL_ORDER 26 /* 1<<26 = 64MB */ #else #define KERNEL_INITIAL_ORDER 25 /* 1<<25 = 32MB */ @@ -226,7 +226,7 @@ extern void __update_cache(pte_t pte); #define PxD_FLAG_SHIFT (4) #define PxD_VALUE_SHIFT (PFN_PTE_SHIFT-PxD_FLAG_SHIFT) -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #define PAGE_NONE __pgprot(_PAGE_PRESENT | _PAGE_USER) #define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE) @@ -262,21 +262,10 @@ extern pgd_t swapper_pg_dir[]; /* declared in init_task.c */ extern pte_t pg0[]; -/* zero page used for uninitialized stuff */ - -extern unsigned long *empty_zero_page; - -/* - * ZERO_PAGE is a global shared page that is always zero: used - * for zero-mapped memory areas etc.. - */ - -#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) - #define pte_none(x) (pte_val(x) == 0) #define pte_present(x) (pte_val(x) & _PAGE_PRESENT) #define pte_user(x) (pte_val(x) & _PAGE_USER) -#define pte_clear(mm, addr, xp) set_pte(xp, __pte(0)) +#define pte_clear(mm, addr, xp) set_pte_at((mm), (addr), (xp), __pte(0)) #define pmd_flag(x) (pmd_val(x) & PxD_FLAG_MASK) #define pmd_address(x) ((unsigned long)(pmd_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT) @@ -338,10 +327,6 @@ static inline pte_t pte_mkspecial(pte_t pte) { pte_val(pte) |= _PAGE_SPECIAL; re #endif -/* - * Conversion functions: convert a page and protection to a page entry, - * and a page entry and page directory to the page they refer to. - */ #define __mk_pte(addr,pgprot) \ ({ \ pte_t __pte; \ @@ -351,8 +336,6 @@ static inline pte_t pte_mkspecial(pte_t pte) { pte_val(pte) |= _PAGE_SPECIAL; re __pte; \ }) -#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) - static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) { pte_t pte; @@ -398,6 +381,7 @@ static inline void set_ptes(struct mm_struct *mm, unsigned long addr, } } #define set_ptes set_ptes +#define set_pte_at(mm, addr, ptep, pte) set_ptes(mm, addr, ptep, pte, 1) /* Used for deferring calls to flush_dcache_page() */ @@ -431,7 +415,7 @@ static inline void set_ptes(struct mm_struct *mm, unsigned long addr, #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) -static inline int pte_swp_exclusive(pte_t pte) +static inline bool pte_swp_exclusive(pte_t pte) { return pte_val(pte) & _PAGE_SWP_EXCLUSIVE; } @@ -454,30 +438,31 @@ static inline pte_t ptep_get(pte_t *ptep) } #define ptep_get ptep_get -static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) +static inline bool ptep_test_and_clear_young(struct vm_area_struct *vma, + unsigned long addr, pte_t *ptep) { pte_t pte; pte = ptep_get(ptep); if (!pte_young(pte)) { - return 0; + return false; } - set_pte(ptep, pte_mkold(pte)); - return 1; + set_pte_at(vma->vm_mm, addr, ptep, pte_mkold(pte)); + return true; } -int ptep_clear_flush_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep); +bool ptep_clear_flush_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep); pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep); struct mm_struct; static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - set_pte(ptep, pte_wrprotect(*ptep)); + set_pte_at(mm, addr, ptep, pte_wrprotect(*ptep)); } #define pte_same(A,B) (pte_val(A) == pte_val(B)) -#endif /* !__ASSEMBLY__ */ +#endif /* !__ASSEMBLER__ */ /* TLB page size encoding - see table 3-1 in parisc20.pdf */ diff --git a/arch/parisc/include/asm/prefetch.h b/arch/parisc/include/asm/prefetch.h index 6e63f720024d..748eefb27c68 100644 --- a/arch/parisc/include/asm/prefetch.h +++ b/arch/parisc/include/asm/prefetch.h @@ -16,7 +16,7 @@ #ifndef __ASM_PARISC_PREFETCH_H #define __ASM_PARISC_PREFETCH_H -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #ifdef CONFIG_PREFETCH #define ARCH_HAS_PREFETCH @@ -40,6 +40,6 @@ static inline void prefetchw(const void *addr) #endif /* CONFIG_PA20 */ #endif /* CONFIG_PREFETCH */ -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* __ASM_PARISC_PROCESSOR_H */ diff --git a/arch/parisc/include/asm/processor.h b/arch/parisc/include/asm/processor.h index 77fac02188e1..dd0b5e199559 100644 --- a/arch/parisc/include/asm/processor.h +++ b/arch/parisc/include/asm/processor.h @@ -9,7 +9,7 @@ #ifndef __ASM_PARISC_PROCESSOR_H #define __ASM_PARISC_PROCESSOR_H -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include <linux/threads.h> #include <linux/irqreturn.h> @@ -20,7 +20,7 @@ #include <asm/ptrace.h> #include <asm/types.h> #include <asm/percpu.h> -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #define HAVE_ARCH_PICK_MMAP_LAYOUT @@ -45,10 +45,10 @@ #define STACK_TOP TASK_SIZE #define STACK_TOP_MAX DEFAULT_TASK_SIZE -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ struct rlimit; -unsigned long mmap_upper_limit(struct rlimit *rlim_stack); +unsigned long mmap_upper_limit(const struct rlimit *rlim_stack); unsigned long calc_max_stack_size(unsigned long stack_max); /* @@ -325,6 +325,6 @@ extern void sba_directed_lmmio(struct parisc_device *, struct resource *); extern void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask); extern void ccio_cujo20_fixup(struct parisc_device *dev, u32 iovp); -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* __ASM_PARISC_PROCESSOR_H */ diff --git a/arch/parisc/include/asm/psw.h b/arch/parisc/include/asm/psw.h index 46921ffcc407..9140e1ab7e63 100644 --- a/arch/parisc/include/asm/psw.h +++ b/arch/parisc/include/asm/psw.h @@ -60,7 +60,7 @@ #define USER_PSW_MASK (WIDE_PSW | PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB) #define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I) -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ /* The program status word as bitfields. */ struct pa_psw { @@ -99,6 +99,6 @@ struct pa_psw { #define pa_psw(task) ((struct pa_psw *) ((char *) (task) + TASK_PT_PSW)) #endif -#endif /* !__ASSEMBLY__ */ +#endif /* !__ASSEMBLER__ */ #endif diff --git a/arch/parisc/include/asm/ptrace.h b/arch/parisc/include/asm/ptrace.h index eea3f3df0823..5e1f52b3922d 100644 --- a/arch/parisc/include/asm/ptrace.h +++ b/arch/parisc/include/asm/ptrace.h @@ -7,6 +7,7 @@ #include <asm/assembly.h> #include <uapi/asm/ptrace.h> +#include <linux/compiler.h> #define task_regs(task) ((struct pt_regs *) ((char *)(task) + TASK_REGS)) diff --git a/arch/parisc/include/asm/signal.h b/arch/parisc/include/asm/signal.h index e84883c6b4c7..85c3d7409bbc 100644 --- a/arch/parisc/include/asm/signal.h +++ b/arch/parisc/include/asm/signal.h @@ -4,12 +4,12 @@ #include <uapi/asm/signal.h> -# ifndef __ASSEMBLY__ +# ifndef __ASSEMBLER__ /* Most things should be clean enough to redefine this at will, if care is taken to make libc match. */ #include <asm/sigcontext.h> -#endif /* !__ASSEMBLY */ +#endif /* !__ASSEMBLER__ */ #endif /* _ASM_PARISC_SIGNAL_H */ diff --git a/arch/parisc/include/asm/smp.h b/arch/parisc/include/asm/smp.h index 94d1f21ce99a..0cf1c3a2696a 100644 --- a/arch/parisc/include/asm/smp.h +++ b/arch/parisc/include/asm/smp.h @@ -12,7 +12,7 @@ extern int init_per_cpu(int cpuid); #define PDC_OS_BOOT_RENDEZVOUS 0x10 #define PDC_OS_BOOT_RENDEZVOUS_HI 0x28 -#ifndef ASSEMBLY +#ifndef __ASSEMBLER__ #include <linux/bitops.h> #include <linux/threads.h> /* for NR_CPUS */ #include <linux/cpumask.h> @@ -34,7 +34,7 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); #define raw_smp_processor_id() (current_thread_info()->cpu) -#endif /* !ASSEMBLY */ +#endif /* !__ASSEMBLER__ */ #else /* CONFIG_SMP */ diff --git a/arch/parisc/include/asm/special_insns.h b/arch/parisc/include/asm/special_insns.h index 51f40eaf7780..1013eeba31e5 100644 --- a/arch/parisc/include/asm/special_insns.h +++ b/arch/parisc/include/asm/special_insns.h @@ -32,6 +32,34 @@ pa; \ }) +/** + * prober_user() - Probe user read access + * @sr: Space regster. + * @va: Virtual address. + * + * Return: Non-zero if address is accessible. + * + * Due to the way _PAGE_READ is handled in TLB entries, we need + * a special check to determine whether a user address is accessible. + * The ldb instruction does the initial access check. If it is + * successful, the probe instruction checks user access rights. + */ +#define prober_user(sr, va) ({ \ + unsigned long read_allowed; \ + __asm__ __volatile__( \ + "copy %%r0,%0\n" \ + "8:\tldb 0(%%sr%1,%2),%%r0\n" \ + "\tproberi (%%sr%1,%2),%3,%0\n" \ + "9:\n" \ + ASM_EXCEPTIONTABLE_ENTRY(8b, 9b, \ + "or %%r0,%%r0,%%r0") \ + : "=&r" (read_allowed) \ + : "i" (sr), "r" (va), "i" (PRIV_USER) \ + : "memory" \ + ); \ + read_allowed; \ +}) + #define CR_EIEM 15 /* External Interrupt Enable Mask */ #define CR_CR16 16 /* CR16 Interval Timer */ #define CR_EIRR 23 /* External Interrupt Request Register */ diff --git a/arch/parisc/include/asm/spinlock_types.h b/arch/parisc/include/asm/spinlock_types.h index 7b986b09dba8..8e6889bc23cc 100644 --- a/arch/parisc/include/asm/spinlock_types.h +++ b/arch/parisc/include/asm/spinlock_types.h @@ -6,7 +6,7 @@ #define SPINLOCK_BREAK_INSN 0x0000c006 /* break 6,6 */ -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ typedef struct { volatile unsigned int lock[4]; @@ -26,7 +26,7 @@ typedef struct { volatile unsigned int counter; } arch_rwlock_t; -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #define __ARCH_RW_LOCK_UNLOCKED__ 0x01000000 #define __ARCH_RW_LOCK_UNLOCKED { .lock_mutex = __ARCH_SPIN_LOCK_UNLOCKED, \ diff --git a/arch/parisc/include/asm/syscall.h b/arch/parisc/include/asm/syscall.h index 00b127a5e09b..c11222798ab2 100644 --- a/arch/parisc/include/asm/syscall.h +++ b/arch/parisc/include/asm/syscall.h @@ -17,6 +17,13 @@ static inline long syscall_get_nr(struct task_struct *tsk, return regs->gr[20]; } +static inline void syscall_set_nr(struct task_struct *tsk, + struct pt_regs *regs, + int nr) +{ + regs->gr[20] = nr; +} + static inline void syscall_get_arguments(struct task_struct *tsk, struct pt_regs *regs, unsigned long *args) @@ -29,6 +36,18 @@ static inline void syscall_get_arguments(struct task_struct *tsk, args[0] = regs->gr[26]; } +static inline void syscall_set_arguments(struct task_struct *tsk, + struct pt_regs *regs, + unsigned long *args) +{ + regs->gr[21] = args[5]; + regs->gr[22] = args[4]; + regs->gr[23] = args[3]; + regs->gr[24] = args[2]; + regs->gr[25] = args[1]; + regs->gr[26] = args[0]; +} + static inline long syscall_get_error(struct task_struct *task, struct pt_regs *regs) { diff --git a/arch/parisc/include/asm/thread_info.h b/arch/parisc/include/asm/thread_info.h index 1a58795f785c..b283738bb6da 100644 --- a/arch/parisc/include/asm/thread_info.h +++ b/arch/parisc/include/asm/thread_info.h @@ -2,7 +2,7 @@ #ifndef _ASM_PARISC_THREAD_INFO_H #define _ASM_PARISC_THREAD_INFO_H -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include <asm/processor.h> #include <asm/special_insns.h> @@ -20,7 +20,7 @@ struct thread_info { .preempt_count = INIT_PREEMPT_COUNT, \ } -#endif /* !__ASSEMBLY */ +#endif /* !__ASSEMBLER__ */ /* thread information allocation */ diff --git a/arch/parisc/include/asm/tlb.h b/arch/parisc/include/asm/tlb.h index 44235f367674..4501fee0a8fa 100644 --- a/arch/parisc/include/asm/tlb.h +++ b/arch/parisc/include/asm/tlb.h @@ -5,8 +5,8 @@ #include <asm-generic/tlb.h> #if CONFIG_PGTABLE_LEVELS == 3 -#define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tlb)->mm, pmd) +#define __pmd_free_tlb(tlb, pmd, addr) tlb_remove_ptdesc((tlb), virt_to_ptdesc(pmd)) #endif -#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte) +#define __pte_free_tlb(tlb, pte, addr) tlb_remove_ptdesc((tlb), page_ptdesc(pte)) #endif diff --git a/arch/parisc/include/asm/traps.h b/arch/parisc/include/asm/traps.h index 0ccdb738a9a3..10c8fb68e404 100644 --- a/arch/parisc/include/asm/traps.h +++ b/arch/parisc/include/asm/traps.h @@ -4,7 +4,7 @@ #define PARISC_ITLB_TRAP 6 /* defined by architecture. Do not change. */ -#if !defined(__ASSEMBLY__) +#if !defined(__ASSEMBLER__) struct pt_regs; /* traps.c */ diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h index 88d0ae5769dd..0d17f81c8b27 100644 --- a/arch/parisc/include/asm/uaccess.h +++ b/arch/parisc/include/asm/uaccess.h @@ -42,9 +42,24 @@ __gu_err; \ }) -#define __get_user(val, ptr) \ -({ \ - __get_user_internal(SR_USER, val, ptr); \ +#define __probe_user_internal(sr, error, ptr) \ +({ \ + __asm__("\tproberi (%%sr%1,%2),%3,%0\n" \ + "\tcmpiclr,= 1,%0,%0\n" \ + "\tldi %4,%0\n" \ + : "=r"(error) \ + : "i"(sr), "r"(ptr), "i"(PRIV_USER), \ + "i"(-EFAULT)); \ +}) + +#define __get_user(val, ptr) \ +({ \ + register long __gu_err; \ + \ + __gu_err = __get_user_internal(SR_USER, val, ptr); \ + if (likely(!__gu_err)) \ + __probe_user_internal(SR_USER, __gu_err, ptr); \ + __gu_err; \ }) #define __get_user_asm(sr, val, ldx, ptr) \ @@ -182,7 +197,6 @@ unsigned long __must_check raw_copy_to_user(void __user *dst, const void *src, unsigned long len); unsigned long __must_check raw_copy_from_user(void *dst, const void __user *src, unsigned long len); -#define INLINE_COPY_TO_USER -#define INLINE_COPY_FROM_USER +#define INLINE_COPY_USER #endif /* __PARISC_UACCESS_H */ diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h index a97c0fd55f91..3e46c6ea9df6 100644 --- a/arch/parisc/include/asm/unistd.h +++ b/arch/parisc/include/asm/unistd.h @@ -6,7 +6,7 @@ #define __NR_Linux_syscalls __NR_syscalls -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #define SYS_ify(syscall_name) __NR_##syscall_name @@ -144,7 +144,7 @@ #define __ARCH_WANT_SYS_UTIME #endif -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #undef STR diff --git a/arch/parisc/include/asm/vdso.h b/arch/parisc/include/asm/vdso.h index 2a2dc11b5545..e5cca3c9c8e7 100644 --- a/arch/parisc/include/asm/vdso.h +++ b/arch/parisc/include/asm/vdso.h @@ -2,19 +2,20 @@ #ifndef __PARISC_VDSO_H__ #define __PARISC_VDSO_H__ -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #ifdef CONFIG_64BIT #include <generated/vdso64-offsets.h> +#define VDSO64_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso64_offset_##name)) #endif +#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT) #include <generated/vdso32-offsets.h> - -#define VDSO64_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso64_offset_##name)) #define VDSO32_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso32_offset_##name)) +#else +#define VDSO32_SYMBOL(tsk, name) 0UL +#endif -extern struct vdso_data *vdso_data; - -#endif /* __ASSEMBLY __ */ +#endif /* __ASSEMBLER__ */ /* Default link addresses for the vDSOs */ #define VDSO_LBASE 0 diff --git a/arch/parisc/include/asm/video.h b/arch/parisc/include/asm/video.h index c5dff3223194..a9d50ebd6e76 100644 --- a/arch/parisc/include/asm/video.h +++ b/arch/parisc/include/asm/video.h @@ -6,7 +6,7 @@ struct device; -#if defined(CONFIG_STI_CORE) +#if defined(CONFIG_STI_CORE) && defined(CONFIG_VIDEO) bool video_is_primary_device(struct device *dev); #define video_is_primary_device video_is_primary_device #endif diff --git a/arch/parisc/include/uapi/asm/errno.h b/arch/parisc/include/uapi/asm/errno.h index 8d94739d75c6..93194fbb0a80 100644 --- a/arch/parisc/include/uapi/asm/errno.h +++ b/arch/parisc/include/uapi/asm/errno.h @@ -36,6 +36,7 @@ #define EDOTDOT 66 /* RFS specific error */ #define EBADMSG 67 /* Not a data message */ +#define EFSBADCRC EBADMSG /* Bad CRC detected */ #define EUSERS 68 /* Too many users */ #define EDQUOT 69 /* Quota exceeded */ #define ESTALE 70 /* Stale file handle */ @@ -62,6 +63,7 @@ #define ERESTART 175 /* Interrupted system call should be restarted */ #define ESTRPIPE 176 /* Streams pipe error */ #define EUCLEAN 177 /* Structure needs cleaning */ +#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */ #define ENOTNAM 178 /* Not a XENIX named type file */ #define ENAVAIL 179 /* No XENIX semaphores available */ #define EISNAM 180 /* Is a named type file */ @@ -122,4 +124,6 @@ #define EHWPOISON 257 /* Memory page has hardware error */ +#define EFTYPE 258 /* Wrong file type for the intended operation */ + #endif diff --git a/arch/parisc/include/uapi/asm/fcntl.h b/arch/parisc/include/uapi/asm/fcntl.h index 03dee816cb13..2e1bb18eefb8 100644 --- a/arch/parisc/include/uapi/asm/fcntl.h +++ b/arch/parisc/include/uapi/asm/fcntl.h @@ -2,23 +2,23 @@ #ifndef _PARISC_FCNTL_H #define _PARISC_FCNTL_H -#define O_APPEND 000000010 -#define O_CREAT 000000400 /* not fcntl */ -#define O_EXCL 000002000 /* not fcntl */ -#define O_LARGEFILE 000004000 -#define __O_SYNC 000100000 +#define O_APPEND (1 << 3) +#define O_CREAT (1 << 8) /* not fcntl */ +#define O_EXCL (1 << 10) /* not fcntl */ +#define O_LARGEFILE (1 << 11) +#define __O_SYNC (1 << 15) #define O_SYNC (__O_SYNC|O_DSYNC) -#define O_NONBLOCK 000200000 -#define O_NOCTTY 000400000 /* not fcntl */ -#define O_DSYNC 001000000 -#define O_NOATIME 004000000 -#define O_CLOEXEC 010000000 /* set close_on_exec */ +#define O_NONBLOCK (1 << 16) +#define O_NOCTTY (1 << 17) /* not fcntl */ +#define O_DSYNC (1 << 18) +#define O_NOATIME (1 << 20) +#define O_CLOEXEC (1 << 21) /* set close_on_exec */ -#define O_DIRECTORY 000010000 /* must be a directory */ -#define O_NOFOLLOW 000000200 /* don't follow links */ +#define O_DIRECTORY (1 << 12) /* must be a directory */ +#define O_NOFOLLOW (1 << 7) /* don't follow links */ -#define O_PATH 020000000 -#define __O_TMPFILE 040000000 +#define O_PATH (1 << 22) +#define __O_TMPFILE (1 << 23) #define F_GETLK64 8 #define F_SETLK64 9 diff --git a/arch/parisc/include/uapi/asm/ioctls.h b/arch/parisc/include/uapi/asm/ioctls.h index 82d1148c6379..74b4027a4e80 100644 --- a/arch/parisc/include/uapi/asm/ioctls.h +++ b/arch/parisc/include/uapi/asm/ioctls.h @@ -10,10 +10,10 @@ #define TCSETS _IOW('T', 17, struct termios) /* TCSETATTR */ #define TCSETSW _IOW('T', 18, struct termios) /* TCSETATTRD */ #define TCSETSF _IOW('T', 19, struct termios) /* TCSETATTRF */ -#define TCGETA _IOR('T', 1, struct termio) -#define TCSETA _IOW('T', 2, struct termio) -#define TCSETAW _IOW('T', 3, struct termio) -#define TCSETAF _IOW('T', 4, struct termio) +#define TCGETA 0x40125401 +#define TCSETA 0x80125402 +#define TCSETAW 0x80125403 +#define TCSETAF 0x80125404 #define TCSBRK _IO('T', 5) #define TCXONC _IO('T', 6) #define TCFLSH _IO('T', 7) diff --git a/arch/parisc/include/uapi/asm/pdc.h b/arch/parisc/include/uapi/asm/pdc.h index fef4f2e96160..65031ddf8372 100644 --- a/arch/parisc/include/uapi/asm/pdc.h +++ b/arch/parisc/include/uapi/asm/pdc.h @@ -361,7 +361,7 @@ /* size of the pdc_result buffer for firmware.c */ #define NUM_PDC_RESULT 32 -#if !defined(__ASSEMBLY__) +#if !defined(__ASSEMBLER__) /* flags for hardware_path */ #define PF_AUTOBOOT 0x80 @@ -741,6 +741,6 @@ struct pdc_firm_test_get_rtn_block { /* PDC_MODEL/PDC_FIRM_TEST_GET */ #define PIRANHA_CPU_ID 0x13 #define MAKO_CPU_ID 0x14 -#endif /* !defined(__ASSEMBLY__) */ +#endif /* !defined(__ASSEMBLER__) */ #endif /* _UAPI_PARISC_PDC_H */ diff --git a/arch/parisc/include/uapi/asm/perf_regs.h b/arch/parisc/include/uapi/asm/perf_regs.h new file mode 100644 index 000000000000..1ae687bb3d3c --- /dev/null +++ b/arch/parisc/include/uapi/asm/perf_regs.h @@ -0,0 +1,63 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI_ASM_PARISC_PERF_REGS_H +#define _UAPI_ASM_PARISC_PERF_REGS_H + +/* see struct user_regs_struct */ +enum perf_event_parisc_regs { + PERF_REG_PARISC_R0, /* PSW is in gr[0] */ + PERF_REG_PARISC_R1, + PERF_REG_PARISC_R2, + PERF_REG_PARISC_R3, + PERF_REG_PARISC_R4, + PERF_REG_PARISC_R5, + PERF_REG_PARISC_R6, + PERF_REG_PARISC_R7, + PERF_REG_PARISC_R8, + PERF_REG_PARISC_R9, + PERF_REG_PARISC_R10, + PERF_REG_PARISC_R11, + PERF_REG_PARISC_R12, + PERF_REG_PARISC_R13, + PERF_REG_PARISC_R14, + PERF_REG_PARISC_R15, + PERF_REG_PARISC_R16, + PERF_REG_PARISC_R17, + PERF_REG_PARISC_R18, + PERF_REG_PARISC_R19, + PERF_REG_PARISC_R20, + PERF_REG_PARISC_R21, + PERF_REG_PARISC_R22, + PERF_REG_PARISC_R23, + PERF_REG_PARISC_R24, + PERF_REG_PARISC_R25, + PERF_REG_PARISC_R26, + PERF_REG_PARISC_R27, + PERF_REG_PARISC_R28, + PERF_REG_PARISC_R29, + PERF_REG_PARISC_R30, + PERF_REG_PARISC_R31, + + PERF_REG_PARISC_SR0, + PERF_REG_PARISC_SR1, + PERF_REG_PARISC_SR2, + PERF_REG_PARISC_SR3, + PERF_REG_PARISC_SR4, + PERF_REG_PARISC_SR5, + PERF_REG_PARISC_SR6, + PERF_REG_PARISC_SR7, + + PERF_REG_PARISC_IAOQ0, + PERF_REG_PARISC_IAOQ1, + PERF_REG_PARISC_IASQ0, + PERF_REG_PARISC_IASQ1, + + PERF_REG_PARISC_SAR, /* CR11 */ + PERF_REG_PARISC_IIR, /* CR19 */ + PERF_REG_PARISC_ISR, /* CR20 */ + PERF_REG_PARISC_IOR, /* CR21 */ + PERF_REG_PARISC_IPSW, /* CR22 */ + + PERF_REG_PARISC_MAX +}; + +#endif /* _UAPI_ASM_PARISC_PERF_REGS_H */ diff --git a/arch/parisc/include/uapi/asm/signal.h b/arch/parisc/include/uapi/asm/signal.h index 40d7a574c5dd..d99accf37341 100644 --- a/arch/parisc/include/uapi/asm/signal.h +++ b/arch/parisc/include/uapi/asm/signal.h @@ -61,7 +61,7 @@ #define _NSIG_BPW (sizeof(unsigned long) * 8) #define _NSIG_WORDS (_NSIG / _NSIG_BPW) -# ifndef __ASSEMBLY__ +# ifndef __ASSEMBLER__ # include <linux/types.h> @@ -80,5 +80,5 @@ typedef struct sigaltstack { __kernel_size_t ss_size; } stack_t; -#endif /* !__ASSEMBLY */ +#endif /* !__ASSEMBLER__ */ #endif /* _UAPI_ASM_PARISC_SIGNAL_H */ diff --git a/arch/parisc/include/uapi/asm/socket.h b/arch/parisc/include/uapi/asm/socket.h index aa9cd4b951fe..c16ec36dfee6 100644 --- a/arch/parisc/include/uapi/asm/socket.h +++ b/arch/parisc/include/uapi/asm/socket.h @@ -132,15 +132,20 @@ #define SO_PASSPIDFD 0x404A #define SO_PEERPIDFD 0x404B -#define SO_DEVMEM_LINEAR 78 +#define SCM_TS_OPT_ID 0x404C + +#define SO_RCVPRIORITY 0x404D + +#define SO_DEVMEM_LINEAR 0x404E #define SCM_DEVMEM_LINEAR SO_DEVMEM_LINEAR -#define SO_DEVMEM_DMABUF 79 +#define SO_DEVMEM_DMABUF 0x404F #define SCM_DEVMEM_DMABUF SO_DEVMEM_DMABUF -#define SO_DEVMEM_DONTNEED 80 +#define SO_DEVMEM_DONTNEED 0x4050 -#define SCM_TS_OPT_ID 0x404C +#define SO_PASSRIGHTS 0x4051 -#define SO_RCVPRIORITY 0x404D +#define SO_INQ 0x4052 +#define SCM_INQ SO_INQ #if !defined(__KERNEL__) diff --git a/arch/parisc/kernel/Makefile b/arch/parisc/kernel/Makefile index 5ab0467be70a..49f937c2abbe 100644 --- a/arch/parisc/kernel/Makefile +++ b/arch/parisc/kernel/Makefile @@ -3,7 +3,7 @@ # Makefile for arch/parisc/kernel # -extra-y := vmlinux.lds +always-$(KBUILD_BUILTIN) := vmlinux.lds obj-y := head.o cache.o pacache.o setup.o pdt.o traps.o time.o irq.o \ syscall.o entry.o sys_parisc.o firmware.o \ @@ -38,6 +38,7 @@ obj-$(CONFIG_GENERIC_ARCH_TOPOLOGY) += topology.o obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o +obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_regs.o obj-$(CONFIG_KGDB) += kgdb.o obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_KEXEC_CORE) += kexec.o relocate_kernel.o @@ -45,5 +46,9 @@ obj-$(CONFIG_KEXEC_FILE) += kexec_file.o # vdso obj-y += vdso.o -obj-$(CONFIG_64BIT) += vdso64/ +ifdef CONFIG_64BIT +obj-y += vdso64/ +obj-$(CONFIG_COMPAT) += vdso32/ +else obj-y += vdso32/ +endif diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c index 757816a7bd4b..3de4b5933b10 100644 --- a/arch/parisc/kernel/asm-offsets.c +++ b/arch/parisc/kernel/asm-offsets.c @@ -13,6 +13,7 @@ * Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org> * Copyright (C) 2003 James Bottomley <jejb at parisc-linux.org> */ +#define COMPILE_OFFSETS #include <linux/types.h> #include <linux/sched.h> @@ -257,6 +258,8 @@ int main(void) BLANK(); DEFINE(TIF_BLOCKSTEP_PA_BIT, 31-TIF_BLOCKSTEP); DEFINE(TIF_SINGLESTEP_PA_BIT, 31-TIF_SINGLESTEP); + DEFINE(TIF_32BIT_PA_BIT, 31-TIF_32BIT); + BLANK(); DEFINE(ASM_PMD_SHIFT, PMD_SHIFT); DEFINE(ASM_PGDIR_SHIFT, PGDIR_SHIFT); diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index db531e58d70e..0170b69a21d3 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c @@ -122,10 +122,10 @@ void __update_cache(pte_t pte) pfn = folio_pfn(folio); nr = folio_nr_pages(folio); if (folio_flush_mapping(folio) && - test_bit(PG_dcache_dirty, &folio->flags)) { + test_bit(PG_dcache_dirty, &folio->flags.f)) { while (nr--) flush_kernel_dcache_page_addr(pfn_va(pfn + nr)); - clear_bit(PG_dcache_dirty, &folio->flags); + clear_bit(PG_dcache_dirty, &folio->flags.f); } else if (parisc_requires_coherency()) while (nr--) flush_kernel_dcache_page_addr(pfn_va(pfn + nr)); @@ -429,7 +429,7 @@ static inline pte_t *get_ptep(struct mm_struct *mm, unsigned long addr) return ptep; } -static inline bool pte_needs_flush(pte_t pte) +static inline bool pte_needs_cache_flush(pte_t pte) { return (pte_val(pte) & (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_NO_CACHE)) == (_PAGE_PRESENT | _PAGE_ACCESSED); @@ -481,7 +481,7 @@ void flush_dcache_folio(struct folio *folio) pgoff_t pgoff; if (mapping && !mapping_mapped(mapping)) { - set_bit(PG_dcache_dirty, &folio->flags); + set_bit(PG_dcache_dirty, &folio->flags.f); return; } @@ -630,7 +630,7 @@ static void flush_cache_page_if_present(struct vm_area_struct *vma, ptep = get_ptep(vma->vm_mm, vmaddr); if (ptep) { pte = ptep_get(ptep); - needs_flush = pte_needs_flush(pte); + needs_flush = pte_needs_cache_flush(pte); pte_unmap(ptep); } if (needs_flush) @@ -781,18 +781,18 @@ void flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned lon __flush_cache_page(vma, vmaddr, PFN_PHYS(page_to_pfn(page))); } -int ptep_clear_flush_young(struct vm_area_struct *vma, unsigned long addr, - pte_t *ptep) +bool ptep_clear_flush_young(struct vm_area_struct *vma, + unsigned long addr, pte_t *ptep) { pte_t pte = ptep_get(ptep); if (!pte_young(pte)) - return 0; + return false; set_pte(ptep, pte_mkold(pte)); #if CONFIG_FLUSH_PAGE_ACCESSED __flush_cache_page(vma, addr, PFN_PHYS(pte_pfn(pte))); #endif - return 1; + return true; } /* @@ -841,7 +841,7 @@ void flush_cache_vmap(unsigned long start, unsigned long end) } vm = find_vm_area((void *)start); - if (WARN_ON_ONCE(!vm)) { + if (!vm) { flush_cache_all(); return; } @@ -953,7 +953,7 @@ SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes, #else "1: cmpb,<<,n %0,%2,1b\n" #endif - " fic,m %3(%4,%0)\n" + " fdc,m %3(%4,%0)\n" "2: sync\n" ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 2b, "%1") : "+r" (start), "+r" (error) @@ -968,7 +968,7 @@ SYSCALL_DEFINE3(cacheflush, unsigned long, addr, unsigned long, bytes, #else "1: cmpb,<<,n %0,%2,1b\n" #endif - " fdc,m %3(%4,%0)\n" + " fic,m %3(%4,%0)\n" "2: sync\n" ASM_EXCEPTIONTABLE_ENTRY_EFAULT(1b, 2b, "%1") : "+r" (start), "+r" (error) diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c index 1e793f770f71..b52ad704ec8a 100644 --- a/arch/parisc/kernel/drivers.c +++ b/arch/parisc/kernel/drivers.c @@ -41,9 +41,7 @@ const struct dma_map_ops *hppa_dma_ops __ro_after_init; EXPORT_SYMBOL(hppa_dma_ops); -static struct device root = { - .init_name = "parisc", -}; +static struct device *root; static inline int check_dev(struct device *dev) { @@ -89,7 +87,7 @@ static int for_each_padev(int (*fn)(struct device *, void *), void * data) .obj = data, .fn = fn, }; - return device_for_each_child(&root, &recurse_data, descend_children); + return device_for_each_child(root, &recurse_data, descend_children); } /** @@ -290,7 +288,7 @@ const struct parisc_device * find_pa_parent_type(const struct parisc_device *padev, int type) { const struct device *dev = &padev->dev; - while (dev != &root) { + while (dev != root) { struct parisc_device *candidate = to_parisc_device(dev); if (candidate->id.hw_type == type) return candidate; @@ -319,7 +317,7 @@ static void get_node_path(struct device *dev, struct hardware_path *path) dev = dev->parent; } - while (dev != &root) { + while (dev != root) { if (dev_is_pci(dev)) { unsigned int devfn = to_pci_dev(dev)->devfn; path->bc[i--] = PCI_SLOT(devfn) | (PCI_FUNC(devfn)<< 5); @@ -418,7 +416,7 @@ static void setup_bus_id(struct parisc_device *padev) static struct parisc_device * __init create_tree_node(char id, struct device *parent) { - struct parisc_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL); + struct parisc_device *dev = kzalloc_obj(*dev); if (!dev) return NULL; @@ -435,7 +433,7 @@ static struct parisc_device * __init create_tree_node(char id, dev->dev.dma_mask = &dev->dma_mask; dev->dev.coherent_dma_mask = dev->dma_mask; if (device_register(&dev->dev)) { - kfree(dev); + put_device(&dev->dev); return NULL; } @@ -482,7 +480,7 @@ static struct parisc_device * __init alloc_tree_node( static struct parisc_device *create_parisc_device(struct hardware_path *modpath) { int i; - struct device *parent = &root; + struct device *parent = root; for (i = 0; i < 6; i++) { if (modpath->bc[i] == -1) continue; @@ -755,7 +753,7 @@ parse_tree_node(struct device *parent, int index, struct hardware_path *modpath) struct device *hwpath_to_device(struct hardware_path *modpath) { int i; - struct device *parent = &root; + struct device *parent = root; for (i = 0; i < 6; i++) { if (modpath->bc[i] == -1) continue; @@ -880,7 +878,7 @@ void __init walk_central_bus(void) { walk_native_bus(CENTRAL_BUS_ADDR, CENTRAL_BUS_ADDR + (MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET), - &root); + root); } static __init void print_parisc_device(struct parisc_device *dev) @@ -907,23 +905,28 @@ void __init init_parisc_bus(void) { if (bus_register(&parisc_bus_type)) panic("Could not register PA-RISC bus type\n"); - if (device_register(&root)) + + root = root_device_register("parisc"); + if (IS_ERR(root)) panic("Could not register PA-RISC root device\n"); - get_device(&root); } static __init void qemu_header(void) { int num; unsigned long *p; + char name_mpe[80]; pr_info("--- cut here ---\n"); pr_info("/* AUTO-GENERATED HEADER FILE FOR SEABIOS FIRMWARE */\n"); pr_cont("/* generated with Linux kernel */\n"); pr_cont("/* search for PARISC_QEMU_MACHINE_HEADER in Linux */\n\n"); - pr_info("#define PARISC_MODEL \"%s\"\n\n", + pr_info("#define PARISC_MODEL \"%s\"\n", boot_cpu_data.pdc.sys_model_name); + strcpy(name_mpe, boot_cpu_data.pdc.sys_model_name); + pdc_model_sysmodel(OS_ID_MPEXL, name_mpe); + pr_info("#define PARISC_MODEL_MPE \"%s\"\n\n", name_mpe); #define p ((unsigned long *)&boot_cpu_data.pdc.model) pr_info("#define PARISC_PDC_MODEL 0x%lx, 0x%lx, 0x%lx, " @@ -995,6 +998,7 @@ static __init int qemu_print_iodc_data(struct device *lin_dev, void *data) struct pdc_system_map_mod_info pdc_mod_info; struct pdc_module_path mod_path; + memset(&iodc_data, 0, sizeof(iodc_data)); status = pdc_iodc_read(&count, hpa, 0, &iodc_data, sizeof(iodc_data)); if (status != PDC_OK) { @@ -1012,6 +1016,11 @@ static __init int qemu_print_iodc_data(struct device *lin_dev, void *data) mod_index = 0; do { + /* initialize device path for old machines */ + memset(&mod_path, 0xff, sizeof(mod_path)); + get_node_path(dev->dev.parent, &mod_path.path); + mod_path.path.mod = dev->hw_path; + memset(&pdc_mod_info, 0, sizeof(pdc_mod_info)); status = pdc_system_map_find_mods(&pdc_mod_info, &mod_path, mod_index++); } while (status == PDC_OK && pdc_mod_info.mod_addr != hpa); @@ -1030,18 +1039,14 @@ static __init int qemu_print_iodc_data(struct device *lin_dev, void *data) "mod_path_hpa_%08lx = {\n", hpa); pr_cont("\t.path = { "); pr_cont(".flags = 0x%x, ", mod_path.path.flags); - pr_cont(".bc = { 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x }, ", + pr_cont(".bc = { 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x }, ", (unsigned char)mod_path.path.bc[0], (unsigned char)mod_path.path.bc[1], (unsigned char)mod_path.path.bc[2], (unsigned char)mod_path.path.bc[3], (unsigned char)mod_path.path.bc[4], (unsigned char)mod_path.path.bc[5]); - pr_cont(".mod = 0x%x ", mod_path.path.mod); - pr_cont(" },\n"); - pr_cont("\t.layers = { 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x }\n", - mod_path.layers[0], mod_path.layers[1], mod_path.layers[2], - mod_path.layers[3], mod_path.layers[4], mod_path.layers[5]); + pr_cont(".mod = 0x%02x }\n", (unsigned char)mod_path.path.mod); pr_cont("};\n"); pr_info("static struct pdc_iodc iodc_data_hpa_%08lx = {\n", hpa); @@ -1061,8 +1066,6 @@ static __init int qemu_print_iodc_data(struct device *lin_dev, void *data) DO(checksum); DO(length); #undef DO - pr_cont("\t/* pad: 0x%04x, 0x%04x */\n", - iodc_data.pad[0], iodc_data.pad[1]); pr_cont("};\n"); pr_info("#define HPA_%08lx_num_addr %d\n", hpa, dev->num_addrs); diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index ea57bcc21dc5..e04c5d806c10 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S @@ -499,6 +499,12 @@ * this happens is quite subtle, read below */ .macro make_insert_tlb spc,pte,prot,tmp space_to_prot \spc \prot /* create prot id from space */ + +#if _PAGE_SPECIAL_BIT == _PAGE_DMB_BIT + /* need to drop DMB bit, as it's used as SPECIAL flag */ + depi 0,_PAGE_SPECIAL_BIT,1,\pte +#endif + /* The following is the real subtlety. This is depositing * T <-> _PAGE_REFTRAP * D <-> _PAGE_DIRTY @@ -511,17 +517,18 @@ * Finally, _PAGE_READ goes in the top bit of PL1 (so we * trigger an access rights trap in user space if the user * tries to read an unreadable page */ -#if _PAGE_SPECIAL_BIT == _PAGE_DMB_BIT - /* need to drop DMB bit, as it's used as SPECIAL flag */ - depi 0,_PAGE_SPECIAL_BIT,1,\pte -#endif depd \pte,8,7,\prot /* PAGE_USER indicates the page can be read with user privileges, * so deposit X1|11 to PL1|PL2 (remember the upper bit of PL1 - * contains _PAGE_READ) */ + * contains _PAGE_READ). While the kernel can't directly write + * user pages which have _PAGE_WRITE zero, it can read pages + * which have _PAGE_READ zero (PL <= PL1). Thus, the kernel + * exception fault handler doesn't trigger when reading pages + * that aren't user read accessible */ extrd,u,*= \pte,_PAGE_USER_BIT+32,1,%r0 depdi 7,11,3,\prot + /* If we're a gateway page, drop PL2 back to zero for promotion * to kernel privilege (so we can execute the page as kernel). * Any privilege promotion page always denys read and write */ @@ -1052,8 +1059,6 @@ ENTRY_CFI(intr_save) /* for os_hpmc */ STREG %r17, PT_IOR(%r29) #if defined(CONFIG_64BIT) - b,n intr_save2 - skip_save_ior: /* We have a itlb miss, and when executing code above 4 Gb on ILP64, we * need to adjust iasq/iaoq here in the same way we adjusted isr/ior @@ -1062,10 +1067,17 @@ skip_save_ior: bb,COND(>=),n %r8,PSW_W_BIT,intr_save2 LDREG PT_IASQ0(%r29), %r16 LDREG PT_IAOQ0(%r29), %r17 - /* adjust iasq/iaoq */ + /* adjust iasq0/iaoq0 */ space_adjust %r16,%r17,%r1 STREG %r16, PT_IASQ0(%r29) STREG %r17, PT_IAOQ0(%r29) + + LDREG PT_IASQ1(%r29), %r16 + LDREG PT_IAOQ1(%r29), %r17 + /* adjust iasq1/iaoq1 */ + space_adjust %r16,%r17,%r1 + STREG %r16, PT_IASQ1(%r29) + STREG %r17, PT_IAOQ1(%r29) #else skip_save_ior: #endif @@ -1834,6 +1846,10 @@ syscall_restore_rfi: extru,= %r19,TIF_BLOCKSTEP_PA_BIT,1,%r0 depi -1,7,1,%r20 /* T bit */ +#ifdef CONFIG_64BIT + extru,<> %r19,TIF_32BIT_PA_BIT,1,%r0 + depi -1,4,1,%r20 /* W bit */ +#endif STREG %r20,TASK_PT_PSW(%r1) /* Always store space registers, since sr3 can be changed (e.g. fork) */ @@ -1847,7 +1863,6 @@ syscall_restore_rfi: STREG %r25,TASK_PT_IASQ0(%r1) STREG %r25,TASK_PT_IASQ1(%r1) - /* XXX W bit??? */ /* Now if old D bit is clear, it means we didn't save all registers * on syscall entry, so do that now. This only happens on TRACEME * calls, or if someone attached to us while we were on a syscall. diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index c69f6d5946e9..c35a34809743 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -464,7 +464,8 @@ int pdc_system_map_find_mods(struct pdc_system_map_mod_info *pdc_mod_info, unsigned long flags; spin_lock_irqsave(&pdc_lock, flags); - retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_MODULE, __pa(pdc_result), + memcpy(pdc_result2, mod_path, sizeof(*mod_path)); + retval = mem_pdc_call(PDC_SYSTEM_MAP, PDC_FIND_MODULE, __pa(pdc_result), __pa(pdc_result2), mod_index); convert_to_wide(pdc_result); memcpy(pdc_mod_info, pdc_result, sizeof(*pdc_mod_info)); @@ -1642,11 +1643,36 @@ int pdc_pat_pd_get_pdc_revisions(unsigned long *legacy_rev, return retval; } +/** + * pdc_pat_pd_get_platform_counter - Retrieve address of free-running 64-bit counter. + * @addr: The address of the 64-bit counter. + * @freq: The frequency of the counter, or -1 if unknown. + * @unique: Although monotonic growing, may it return the same number twice? + * + */ +int pdc_pat_pd_get_platform_counter(uint64_t **addr, + unsigned long *freq, unsigned long *unique) +{ + int retval; + unsigned long flags; + + spin_lock_irqsave(&pdc_lock, flags); + retval = mem_pdc_call(PDC_PAT_PD, PDC_PAT_PD_GET_PLATFORM_COUNTER, + __pa(pdc_result)); + if (retval == PDC_OK) { + *addr = (uint64_t *)pdc_result[0]; + *freq = pdc_result[1]; + *unique = pdc_result[2]; + } + spin_unlock_irqrestore(&pdc_lock, flags); + + return retval; +} /** * pdc_pat_io_pci_cfg_read - Read PCI configuration space. * @pci_addr: PCI configuration space address for which the read request is being made. - * @pci_size: Size of read in bytes. Valid values are 1, 2, and 4. + * @pci_size: Size of read in bytes. Valid values are 1, 2, and 4. * @mem_addr: Pointer to return memory buffer. * */ diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S index 96e0264ac961..9188c8d87437 100644 --- a/arch/parisc/kernel/head.S +++ b/arch/parisc/kernel/head.S @@ -56,6 +56,7 @@ ENTRY(parisc_kernel_start) .import __bss_start,data .import __bss_stop,data + .import __end,data load32 PA(__bss_start),%r3 load32 PA(__bss_stop),%r4 @@ -149,7 +150,11 @@ $cpu_ok: * everything ... it will get remapped correctly later */ ldo 0+_PAGE_KERNEL_RWX(%r0),%r3 /* Hardwired 0 phys addr start */ load32 (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */ - load32 PA(pg0),%r1 + load32 PA(_end),%r1 + SHRREG %r1,PAGE_SHIFT,%r1 /* %r1 is PFN count for _end symbol */ + cmpb,<<,n %r11,%r1,1f + copy %r1,%r11 /* %r1 PFN count smaller than %r11 */ +1: load32 PA(pg0),%r1 $pgt_fill_loop: STREGM %r3,ASM_PTE_ENTRY_SIZE(%r1) diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c index 7ab2f2a54400..103f58dac948 100644 --- a/arch/parisc/kernel/inventory.c +++ b/arch/parisc/kernel/inventory.c @@ -193,7 +193,7 @@ pat_query_module(ulong pcell_loc, ulong mod_index) long status; /* PDC return value status */ struct parisc_device *dev; - pa_pdc_cell = kmalloc(sizeof (*pa_pdc_cell), GFP_KERNEL); + pa_pdc_cell = kmalloc_obj(*pa_pdc_cell); if (!pa_pdc_cell) panic("couldn't allocate memory for PDC_PAT_CELL!"); @@ -207,6 +207,19 @@ pat_query_module(ulong pcell_loc, ulong mod_index) return status; } +#ifdef DEBUG_PAT + pr_debug("PAT INDEX: %lu: cba 0x%lx, " + "mod_info 0x%lx, mod_location 0x%lx, " + "mod: 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx " + "0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", + mod_index + 1, pa_pdc_cell->cba, + pa_pdc_cell->mod_info, pa_pdc_cell->mod_location, + pa_pdc_cell->mod[0], pa_pdc_cell->mod[1], pa_pdc_cell->mod[2], + pa_pdc_cell->mod[3], pa_pdc_cell->mod[4], pa_pdc_cell->mod[5], + pa_pdc_cell->mod[6], pa_pdc_cell->mod[7], pa_pdc_cell->mod[8], + pa_pdc_cell->mod[9], pa_pdc_cell->mod[10], pa_pdc_cell->mod[11]); +#endif + temp = pa_pdc_cell->cba; dev = alloc_pa_dev(PAT_GET_CBA(temp), &(pa_pdc_cell->mod_path)); if (!dev) { @@ -523,7 +536,7 @@ add_system_map_addresses(struct parisc_device *dev, int num_addrs, long status; struct pdc_system_map_addr_info addr_result; - dev->addr = kmalloc_array(num_addrs, sizeof(*dev->addr), GFP_KERNEL); + dev->addr = kmalloc_objs(*dev->addr, num_addrs); if(!dev->addr) { printk(KERN_ERR "%s %s(): memory allocation failure\n", __FILE__, __func__); diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index 1c366b0d3134..509146a52725 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c @@ -43,7 +43,6 @@ EXPORT_SYMBOL($global$); #endif #include <asm/io.h> -EXPORT_SYMBOL(memcpy_fromio); extern void $$divI(void); extern void $$divU(void); diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index cf285b17a5ae..b8007c7400d4 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c @@ -8,6 +8,7 @@ * Copyright (C) 1999-2001 Hewlett-Packard Company * Copyright (C) 1999-2001 Grant Grundler */ +#include <linux/align.h> #include <linux/eisa.h> #include <linux/init.h> #include <linux/module.h> @@ -196,9 +197,12 @@ void __ref pcibios_init_bridge(struct pci_dev *dev) * than res->start. */ resource_size_t pcibios_align_resource(void *data, const struct resource *res, - resource_size_t size, resource_size_t alignment) + const struct resource *empty_res, + resource_size_t size, + resource_size_t alignment) { - resource_size_t mask, align, start = res->start; + struct pci_dev *dev = data; + resource_size_t align, start = res->start; DBG_RES("pcibios_align_resource(%s, (%p) [%lx,%lx]/%x, 0x%lx, 0x%lx)\n", pci_name(((struct pci_dev *) data)), @@ -207,11 +211,10 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, /* If it's not IO, then it's gotta be MEM */ align = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; - - /* Align to largest of MIN or input size */ - mask = max(alignment, align) - 1; - start += mask; - start &= ~mask; + if (align > alignment) + start = ALIGN(start, align); + else + start = pci_align_resource(dev, res, empty_res, size, alignment); return start; } diff --git a/arch/parisc/kernel/pdt.c b/arch/parisc/kernel/pdt.c index 0f9b3b5914cf..b70b67adb855 100644 --- a/arch/parisc/kernel/pdt.c +++ b/arch/parisc/kernel/pdt.c @@ -63,6 +63,7 @@ static unsigned long pdt_entry[MAX_PDT_ENTRIES] __page_aligned_bss; #define PDT_ADDR_PERM_ERR (pdt_type != PDT_PDC ? 2UL : 0UL) #define PDT_ADDR_SINGLE_ERR 1UL +#ifdef CONFIG_PROC_FS /* report PDT entries via /proc/meminfo */ void arch_report_meminfo(struct seq_file *m) { @@ -74,6 +75,7 @@ void arch_report_meminfo(struct seq_file *m) seq_printf(m, "PDT_cur_entries: %7lu\n", pdt_status.pdt_entries); } +#endif static int get_info_pat_new(void) { diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c index 5e8e37a722ef..5e10f98ce7b5 100644 --- a/arch/parisc/kernel/perf.c +++ b/arch/parisc/kernel/perf.c @@ -475,9 +475,9 @@ static const struct file_operations perf_fops = { }; static struct miscdevice perf_dev = { - MISC_DYNAMIC_MINOR, - PA_PERF_DEV, - &perf_fops + .minor = MISC_DYNAMIC_MINOR, + .name = PA_PERF_DEV, + .fops = &perf_fops, }; /* diff --git a/arch/parisc/kernel/perf_event.c b/arch/parisc/kernel/perf_event.c new file mode 100644 index 000000000000..f90b83886ab4 --- /dev/null +++ b/arch/parisc/kernel/perf_event.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Performance event support for parisc + * + * Copyright (C) 2025 by Helge Deller <deller@gmx.de> + */ + +#include <linux/kernel.h> +#include <linux/perf_event.h> +#include <asm/unwind.h> + +void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, + struct pt_regs *regs) +{ + + struct unwind_frame_info info; + + unwind_frame_init_task(&info, current, NULL); + while (1) { + if (unwind_once(&info) < 0 || info.ip == 0) + break; + + if (!__kernel_text_address(info.ip) || + perf_callchain_store(entry, info.ip)) + return; + } +} diff --git a/arch/parisc/kernel/perf_regs.c b/arch/parisc/kernel/perf_regs.c new file mode 100644 index 000000000000..10a1a5f06a18 --- /dev/null +++ b/arch/parisc/kernel/perf_regs.c @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Copyright (C) 2025 by Helge Deller <deller@gmx.de> */ + +#include <linux/perf_event.h> +#include <linux/perf_regs.h> +#include <asm/ptrace.h> + +u64 perf_reg_value(struct pt_regs *regs, int idx) +{ + switch (idx) { + case PERF_REG_PARISC_R0 ... PERF_REG_PARISC_R31: + return regs->gr[idx - PERF_REG_PARISC_R0]; + case PERF_REG_PARISC_SR0 ... PERF_REG_PARISC_SR7: + return regs->sr[idx - PERF_REG_PARISC_SR0]; + case PERF_REG_PARISC_IASQ0 ... PERF_REG_PARISC_IASQ1: + return regs->iasq[idx - PERF_REG_PARISC_IASQ0]; + case PERF_REG_PARISC_IAOQ0 ... PERF_REG_PARISC_IAOQ1: + return regs->iasq[idx - PERF_REG_PARISC_IAOQ0]; + case PERF_REG_PARISC_SAR: /* CR11 */ + return regs->sar; + case PERF_REG_PARISC_IIR: /* CR19 */ + return regs->iir; + case PERF_REG_PARISC_ISR: /* CR20 */ + return regs->isr; + case PERF_REG_PARISC_IOR: /* CR21 */ + return regs->ior; + case PERF_REG_PARISC_IPSW: /* CR22 */ + return regs->ipsw; + } + WARN_ON_ONCE((u32)idx >= PERF_REG_PARISC_MAX); + return 0; +} + +#define REG_RESERVED (~((1ULL << PERF_REG_PARISC_MAX) - 1)) + +int perf_reg_validate(u64 mask) +{ + if (!mask || mask & REG_RESERVED) + return -EINVAL; + + return 0; +} + +u64 perf_reg_abi(struct task_struct *task) +{ + if (!IS_ENABLED(CONFIG_64BIT)) + return PERF_SAMPLE_REGS_ABI_32; + + if (test_tsk_thread_flag(task, TIF_32BIT)) + return PERF_SAMPLE_REGS_ABI_32; + + return PERF_SAMPLE_REGS_ABI_64; +} + +void perf_get_regs_user(struct perf_regs *regs_user, + struct pt_regs *regs) +{ + regs_user->regs = task_pt_regs(current); + regs_user->abi = perf_reg_abi(current); +} diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index ed93bd8c1545..703644e5bfc4 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c @@ -85,6 +85,9 @@ void machine_restart(char *cmd) #endif /* set up a new led state on systems shipped with a LED State panel */ pdc_chassis_send_status(PDC_CHASSIS_DIRECT_SHUTDOWN); + + /* prevent interrupts during reboot */ + set_eiem(0); /* "Normal" system reset */ pdc_do_reset(); @@ -201,7 +204,7 @@ arch_initcall(parisc_idle_init); int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) { - unsigned long clone_flags = args->flags; + u64 clone_flags = args->flags; unsigned long usp = args->stack; unsigned long tls = args->tls; struct pt_regs *cregs = &(p->thread.regs); diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c index bf73562706b2..d09be22babdb 100644 --- a/arch/parisc/kernel/processor.c +++ b/arch/parisc/kernel/processor.c @@ -3,7 +3,7 @@ * Initial setup-routines for HP 9000 based hardware. * * Copyright (C) 1991, 1992, 1995 Linus Torvalds - * Modifications for PA-RISC (C) 1999-2008 Helge Deller <deller@gmx.de> + * Modifications for PA-RISC (C) 1999-2026 Helge Deller <deller@gmx.de> * Modifications copyright 1999 SuSE GmbH (Philipp Rumpf) * Modifications copyright 2000 Martin K. Petersen <mkp@mkp.net> * Modifications copyright 2000 Philipp Rumpf <prumpf@tux.org> @@ -41,7 +41,7 @@ EXPORT_SYMBOL(_parisc_requires_coherency); DEFINE_PER_CPU(struct cpuinfo_parisc, cpu_data); /* -** PARISC CPU driver - claim "device" and initialize CPU data structures. +** PARISC CPU driver - claim "device" and initialize CPU data structures. ** ** Consolidate per CPU initialization into (mostly) one module. ** Monarch CPU will initialize boot_cpu_data which shouldn't @@ -74,8 +74,8 @@ init_percpu_prof(unsigned long cpunum) * processor_probe - Determine if processor driver should claim this device. * @dev: The device which has been found. * - * Determine if processor driver should claim this chip (return 0) or not - * (return 1). If so, initialize the chip and tell other partners in crime + * Determine if processor driver should claim this chip (return 0) or not + * (return 1). If so, initialize the chip and tell other partners in crime * they have work to do. */ static int __init processor_probe(struct parisc_device *dev) @@ -110,7 +110,7 @@ static int __init processor_probe(struct parisc_device *dev) unsigned long bytecnt; pdc_pat_cell_mod_maddr_block_t *pa_pdc_cell; - pa_pdc_cell = kmalloc(sizeof (*pa_pdc_cell), GFP_KERNEL); + pa_pdc_cell = kmalloc_obj(*pa_pdc_cell); if (!pa_pdc_cell) panic("couldn't allocate memory for PDC_PAT_CELL!"); @@ -207,7 +207,7 @@ static int __init processor_probe(struct parisc_device *dev) } #endif - /* + /* * Bring this CPU up now! (ignore bootstrap cpuid == 0) */ #ifdef CONFIG_SMP @@ -241,9 +241,10 @@ void __init collect_boot_cpu_data(void) /* get CPU-Model Information... */ #define p ((unsigned long *)&boot_cpu_data.pdc.model) if (pdc_model_info(&boot_cpu_data.pdc.model) == PDC_OK) { - printk(KERN_INFO - "model %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]); + pr_info("model 0x%04lx 0x%04lx 0x%04lx 0x%04lx 0x%04lx " + "0x%04lx 0x%04lx 0x%04lx 0x%04lx 0x%04lx\n", + p[0], p[1], p[2], p[3], p[4], + p[5], p[6], p[7], p[8], p[9]); add_device_randomness(&boot_cpu_data.pdc.model, sizeof(boot_cpu_data.pdc.model)); @@ -251,15 +252,14 @@ void __init collect_boot_cpu_data(void) #undef p if (pdc_model_versions(&boot_cpu_data.pdc.versions, 0) == PDC_OK) { - printk(KERN_INFO "vers %08lx\n", - boot_cpu_data.pdc.versions); + pr_info("vers 0x%04lx\n", boot_cpu_data.pdc.versions); add_device_randomness(&boot_cpu_data.pdc.versions, sizeof(boot_cpu_data.pdc.versions)); } if (pdc_model_cpuid(&boot_cpu_data.pdc.cpuid) == PDC_OK) { - printk(KERN_INFO "CPUID vers %ld rev %ld (0x%08lx)\n", + pr_info("CPUID vers %ld rev %ld (0x%04lx)\n", (boot_cpu_data.pdc.cpuid >> 5) & 127, boot_cpu_data.pdc.cpuid & 31, boot_cpu_data.pdc.cpuid); @@ -437,8 +437,8 @@ show_cpuinfo (struct seq_file *m, void *v) boot_cpu_data.pdc.sys_model_name, cpu_name); - seq_printf(m, "hversion\t: 0x%08x\n" - "sversion\t: 0x%08x\n", + seq_printf(m, "hversion\t: 0x%04x\n" + "sversion\t: 0x%04x\n", boot_cpu_data.hversion, boot_cpu_data.sversion ); diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index ceb45f51d52e..8a17ab7e6e0b 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c @@ -562,12 +562,12 @@ static int gpr_set(struct task_struct *target, static const struct user_regset native_regsets[] = { [REGSET_GENERAL] = { - .core_note_type = NT_PRSTATUS, .n = ELF_NGREG, + USER_REGSET_NOTE_TYPE(PRSTATUS), .n = ELF_NGREG, .size = sizeof(long), .align = sizeof(long), .regset_get = gpr_get, .set = gpr_set }, [REGSET_FP] = { - .core_note_type = NT_PRFPREG, .n = ELF_NFPREG, + USER_REGSET_NOTE_TYPE(PRFPREG), .n = ELF_NFPREG, .size = sizeof(__u64), .align = sizeof(__u64), .regset_get = fpr_get, .set = fpr_set } @@ -629,12 +629,12 @@ static int gpr32_set(struct task_struct *target, */ static const struct user_regset compat_regsets[] = { [REGSET_GENERAL] = { - .core_note_type = NT_PRSTATUS, .n = ELF_NGREG, + USER_REGSET_NOTE_TYPE(PRSTATUS), .n = ELF_NGREG, .size = sizeof(compat_long_t), .align = sizeof(compat_long_t), .regset_get = gpr32_get, .set = gpr32_set }, [REGSET_FP] = { - .core_note_type = NT_PRFPREG, .n = ELF_NFPREG, + USER_REGSET_NOTE_TYPE(PRFPREG), .n = ELF_NFPREG, .size = sizeof(__u64), .align = sizeof(__u64), .regset_get = fpr_get, .set = fpr_set } diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index ace483b6f19a..d3e17a7a8901 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -120,14 +120,6 @@ void __init setup_arch(char **cmdline_p) #endif printk(KERN_CONT ".\n"); - /* - * Check if initial kernel page mappings are sufficient. - * panic early if not, else we may access kernel functions - * and variables which can't be reached. - */ - if (__pa((unsigned long) &_end) >= KERNEL_INITIAL_SIZE) - panic("KERNEL_INITIAL_ORDER too small!"); - #ifdef CONFIG_64BIT if(parisc_narrow_firmware) { printk(KERN_INFO "Kernel is using PDC in 32-bit mode.\n"); @@ -279,6 +271,18 @@ void __init start_parisc(void) int ret, cpunum; struct pdc_coproc_cfg coproc_cfg; + /* + * Check if initial kernel page mapping is sufficient. + * Print warning if not, because we may access kernel functions and + * variables which can't be reached yet through the initial mappings. + * Note that the panic() and printk() functions are not functional + * yet, so we need to use direct iodc() firmware calls instead. + */ + const char warn1[] = "CRITICAL: Kernel may crash because " + "KERNEL_INITIAL_ORDER is too small.\n"; + if (__pa((unsigned long) &_end) >= KERNEL_INITIAL_SIZE) + pdc_iodc_print(warn1, sizeof(warn1) - 1); + /* check QEMU/SeaBIOS marker in PAGE0 */ running_on_qemu = (memcmp(&PAGE0->pad0, "SeaBIOS", 8) == 0); diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index e8d27def6c52..64a62006bb15 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c @@ -80,7 +80,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) sigset_t set; unsigned long usp = (regs->gr[30] & ~(0x01UL)); unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE; -#ifdef CONFIG_64BIT +#ifdef CONFIG_COMPAT struct compat_rt_sigframe __user * compat_frame; if (is_compat_task()) @@ -96,7 +96,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) regs->orig_r28 = 1; /* no restarts for sigreturn */ -#ifdef CONFIG_64BIT +#ifdef CONFIG_COMPAT compat_frame = (struct compat_rt_sigframe __user *)frame; if (is_compat_task()) { @@ -112,7 +112,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) set_current_blocked(&set); /* Good thing we saved the old gr[30], eh? */ -#ifdef CONFIG_64BIT +#ifdef CONFIG_COMPAT if (is_compat_task()) { DBG(1, "%s: compat_frame->uc.uc_mcontext 0x%p\n", __func__, &compat_frame->uc.uc_mcontext); @@ -218,13 +218,13 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs, unsigned long haddr, sigframe_size; unsigned long start; int err = 0; -#ifdef CONFIG_64BIT +#ifdef CONFIG_COMPAT struct compat_rt_sigframe __user * compat_frame; #endif - + usp = (regs->gr[30] & ~(0x01UL)); sigframe_size = PARISC_RT_SIGFRAME_SIZE; -#ifdef CONFIG_64BIT +#ifdef CONFIG_COMPAT if (is_compat_task()) { /* The gcc alloca implementation leaves garbage in the upper 32 bits of sp */ usp = (compat_uint_t)usp; @@ -239,7 +239,7 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs, if (start >= TASK_SIZE_MAX - sigframe_size) return -EFAULT; -#ifdef CONFIG_64BIT +#ifdef CONFIG_COMPAT compat_frame = (struct compat_rt_sigframe __user *)frame; @@ -349,8 +349,8 @@ setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs, regs->gr[2] = rp; /* userland return pointer */ regs->gr[26] = ksig->sig; /* signal number */ - -#ifdef CONFIG_64BIT + +#ifdef CONFIG_COMPAT if (is_compat_task()) { regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */ regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */ diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index f852fe274abe..1a676a9bf80c 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -50,9 +50,13 @@ static inline unsigned long COLOR_ALIGN(unsigned long addr, } +#ifdef CONFIG_COMPAT #define STACK_SIZE_DEFAULT (USER_WIDE_MODE \ ? (1 << 30) /* 1 GB */ \ : (CONFIG_STACK_MAX_DEFAULT_SIZE_MB*1024*1024)) +#else +#define STACK_SIZE_DEFAULT (1 << 30) +#endif unsigned long calc_max_stack_size(unsigned long stack_max) { @@ -77,7 +81,7 @@ unsigned long calc_max_stack_size(unsigned long stack_max) * indicating that "current" should be used instead of a passed-in * value from the exec bprm as done with arch_pick_mmap_layout(). */ -unsigned long mmap_upper_limit(struct rlimit *rlim_stack) +unsigned long mmap_upper_limit(const struct rlimit *rlim_stack) { unsigned long stack_base; @@ -216,7 +220,7 @@ asmlinkage long parisc_truncate64(const char __user * path, asmlinkage long parisc_ftruncate64(unsigned int fd, unsigned int high, unsigned int low) { - return ksys_ftruncate(fd, (long)high << 32 | low); + return ksys_ftruncate(fd, (long)high << 32 | low, FTRUNCATE_LFS); } /* stubs for the benefit of the syscall_table since truncate64 and truncate @@ -227,7 +231,7 @@ asmlinkage long sys_truncate64(const char __user * path, unsigned long length) } asmlinkage long sys_ftruncate64(unsigned int fd, unsigned long length) { - return ksys_ftruncate(fd, length); + return ksys_ftruncate(fd, length, FTRUNCATE_LFS); } asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg) { diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index 0fa81bf1466b..e11c88c34eb2 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S @@ -241,7 +241,7 @@ linux_gateway_entry: /* Note! We cannot use the syscall table that is mapped nearby since the gateway page is mapped execute-only. */ -#ifdef CONFIG_64BIT +#ifdef CONFIG_COMPAT ldil L%sys_call_table, %r1 or,ev %r2,%r2,%r2 ldil L%sys_call_table64, %r1 @@ -250,7 +250,7 @@ linux_gateway_entry: ldo R%sys_call_table64(%r1), %r19 #else load32 sys_call_table, %r19 -#endif +#endif comiclr,>> __NR_Linux_syscalls, %r20, %r0 b,n .Lsyscall_nosys @@ -374,7 +374,7 @@ tracesys_next: /* Note! We cannot use the syscall table that is mapped nearby since the gateway page is mapped execute-only. */ -#ifdef CONFIG_64BIT +#ifdef CONFIG_COMPAT LDREG TASK_PT_GR30(%r1), %r19 /* get users sp back */ extrd,u %r19,63,1,%r2 /* W hidden in bottom bit */ @@ -613,6 +613,9 @@ lws_compare_and_swap32: lws_compare_and_swap: /* Trigger memory reference interruptions without writing to memory */ 1: ldw 0(%r26), %r28 + proberi (%r26), PRIV_USER, %r28 + comb,=,n %r28, %r0, lws_fault /* backwards, likely not taken */ + nop 2: stbys,e %r0, 0(%r26) /* Calculate 8-bit hash index from virtual address */ @@ -767,6 +770,9 @@ cas2_lock_start: copy %r26, %r28 depi_safe 0, 31, 2, %r28 10: ldw 0(%r28), %r1 + proberi (%r28), PRIV_USER, %r1 + comb,=,n %r1, %r0, lws_fault /* backwards, likely not taken */ + nop 11: stbys,e %r0, 0(%r28) /* Calculate 8-bit hash index from virtual address */ @@ -951,41 +957,47 @@ atomic_xchg_begin: /* 8-bit exchange */ 1: ldb 0(%r24), %r20 + proberi (%r24), PRIV_USER, %r20 + comb,=,n %r20, %r0, lws_fault /* backwards, likely not taken */ + nop copy %r23, %r20 depi_safe 0, 31, 2, %r20 b atomic_xchg_start 2: stbys,e %r0, 0(%r20) - nop - nop - nop /* 16-bit exchange */ 3: ldh 0(%r24), %r20 + proberi (%r24), PRIV_USER, %r20 + comb,=,n %r20, %r0, lws_fault /* backwards, likely not taken */ + nop copy %r23, %r20 depi_safe 0, 31, 2, %r20 b atomic_xchg_start 4: stbys,e %r0, 0(%r20) - nop - nop - nop /* 32-bit exchange */ 5: ldw 0(%r24), %r20 + proberi (%r24), PRIV_USER, %r20 + comb,=,n %r20, %r0, lws_fault /* backwards, likely not taken */ + nop b atomic_xchg_start 6: stbys,e %r0, 0(%r23) nop nop - nop - nop - nop /* 64-bit exchange */ #ifdef CONFIG_64BIT 7: ldd 0(%r24), %r20 + proberi (%r24), PRIV_USER, %r20 + comb,=,n %r20, %r0, lws_fault /* backwards, likely not taken */ + nop 8: stdby,e %r0, 0(%r23) #else 7: ldw 0(%r24), %r20 8: ldw 4(%r24), %r20 + proberi (%r24), PRIV_USER, %r20 + comb,=,n %r20, %r0, lws_fault /* backwards, likely not taken */ + nop copy %r23, %r20 depi_safe 0, 31, 2, %r20 9: stbys,e %r0, 0(%r20) @@ -1314,16 +1326,19 @@ ENTRY(lws_table) END(lws_table) /* End of lws table */ -#ifdef CONFIG_64BIT +#ifdef CONFIG_COMPAT #define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, compat) #else #define __SYSCALL_WITH_COMPAT(nr, native, compat) __SYSCALL(nr, native) #endif #define __SYSCALL(nr, entry) ASM_ULONG_INSN entry + .align 8 ENTRY(sys_call_table) .export sys_call_table,data +#if defined(CONFIG_COMPAT) || !defined(CONFIG_64BIT) #include <asm/syscall_table_32.h> /* 32-bit syscalls */ +#endif END(sys_call_table) #ifdef CONFIG_64BIT diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl index d9fc94c86965..c6331dad9461 100644 --- a/arch/parisc/kernel/syscalls/syscall.tbl +++ b/arch/parisc/kernel/syscalls/syscall.tbl @@ -154,7 +154,7 @@ # 137 was afs_syscall 138 common setfsuid sys_setfsuid 139 common setfsgid sys_setfsgid -140 common _llseek sys_llseek +140 32 _llseek sys_llseek 141 common getdents sys_getdents compat_sys_getdents 142 common _newselect sys_select compat_sys_select 143 common flock sys_flock @@ -465,3 +465,8 @@ 464 common getxattrat sys_getxattrat 465 common listxattrat sys_listxattrat 466 common removexattrat sys_removexattrat +467 common open_tree_attr sys_open_tree_attr +468 common file_getattr sys_file_getattr +469 common file_setattr sys_file_setattr +470 common listns sys_listns +471 common rseq_slice_yield sys_rseq_slice_yield diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index c17e2249115f..71c9d5426995 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -16,6 +16,7 @@ #include <linux/rtc.h> #include <linux/platform_device.h> #include <asm/processor.h> +#include <asm/pdcpat.h> static u64 cr16_clock_freq; static unsigned long clocktick; @@ -99,6 +100,22 @@ void parisc_clockevent_init(void) clockevents_config_and_register(cd, cr16_clock_freq, min_delta, max_delta); } +static void parisc_find_64bit_counter(void) +{ +#ifdef CONFIG_64BIT + uint64_t *pclock; + unsigned long freq, unique; + int ret; + + ret = pdc_pat_pd_get_platform_counter(&pclock, &freq, &unique); + if (ret == PDC_OK) + pr_info("64-bit counter found at %px, freq: %lu, unique: %lu\n", + pclock, freq, unique); + else + pr_info("64-bit counter not found.\n"); +#endif +} + unsigned long notrace profile_pc(struct pt_regs *regs) { unsigned long pc = instruction_pointer(regs); @@ -193,12 +210,9 @@ static struct clocksource clocksource_cr16 = { .read = read_cr16, .mask = CLOCKSOURCE_MASK(BITS_PER_LONG), .flags = CLOCK_SOURCE_IS_CONTINUOUS | - CLOCK_SOURCE_VALID_FOR_HRES | - CLOCK_SOURCE_MUST_VERIFY | - CLOCK_SOURCE_VERIFY_PERCPU, + CLOCK_SOURCE_VALID_FOR_HRES, }; - /* * timer interrupt and sched_clock() initialization */ @@ -213,6 +227,9 @@ void __init time_init(void) parisc_clockevent_init(); + /* check for free-running 64-bit platform counter */ + parisc_find_64bit_counter(); + /* register at clocksource framework */ clocksource_register_hz(&clocksource_cr16, cr16_clock_freq); } diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index b9b3d527bc90..4c7c5df80bd0 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c @@ -31,6 +31,7 @@ #include <linux/uaccess.h> #include <linux/kdebug.h> #include <linux/kfence.h> +#include <linux/perf_event.h> #include <asm/assembly.h> #include <asm/io.h> @@ -633,6 +634,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs) /* Assist Exception Trap, i.e. floating point exception. */ die_if_kernel("Floating point exception", regs, 0); /* quiet */ __inc_irq_stat(irq_fpassist_count); + perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0); handle_fpe(regs); return; diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c index f4626943633a..fb64d9ce0b17 100644 --- a/arch/parisc/kernel/unaligned.c +++ b/arch/parisc/kernel/unaligned.c @@ -13,6 +13,7 @@ #include <linux/uaccess.h> #include <linux/sysctl.h> #include <linux/unaligned.h> +#include <linux/perf_event.h> #include <asm/hardirq.h> #include <asm/traps.h> #include "unaligned.h" @@ -25,7 +26,7 @@ #define DPRINTF(fmt, args...) #endif -#define RFMT "%#08lx" +#define RFMT "0x%08lx" /* 1111 1100 0000 0000 0001 0011 1100 0000 */ #define OPCODE1(a,b,c) ((a)<<26|(b)<<12|(c)<<6) @@ -378,6 +379,7 @@ void handle_unaligned(struct pt_regs *regs) int ret = ERR_NOTHANDLED; __inc_irq_stat(irq_unaligned_count); + perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, regs->ior); /* log a message with pacing */ if (user_mode(regs)) { diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c index f7e0fee5ee55..32103a270a8e 100644 --- a/arch/parisc/kernel/unwind.c +++ b/arch/parisc/kernel/unwind.c @@ -35,6 +35,8 @@ #define KERNEL_START (KERNEL_BINARY_TEXT_START) +#define ALIGNMENT_OK(ptr, type) (((ptr) & (sizeof(type) - 1)) == 0) + extern struct unwind_table_entry __start___unwind[]; extern struct unwind_table_entry __stop___unwind[]; @@ -155,7 +157,7 @@ unwind_table_add(const char *name, unsigned long base_addr, unwind_table_sort(s, e); - table = kmalloc(sizeof(struct unwind_table), GFP_USER); + table = kmalloc_obj(struct unwind_table, GFP_USER); if (table == NULL) return NULL; unwind_table_init(table, name, base_addr, gp, start, end); @@ -257,12 +259,15 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int if (pc_is_kernel_fn(pc, _switch_to) || pc == (unsigned long)&_switch_to_ret) { info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE; - info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET); + if (ALIGNMENT_OK(info->prev_sp, long)) + info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET); + else + info->prev_ip = info->prev_sp = 0; return 1; } #ifdef CONFIG_IRQSTACKS - if (pc == (unsigned long)&_call_on_stack) { + if (pc == (unsigned long)&_call_on_stack && ALIGNMENT_OK(info->sp, long)) { info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ); info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET); return 1; @@ -370,8 +375,10 @@ static void unwind_frame_regs(struct unwind_frame_info *info) info->prev_sp = info->sp - frame_size; if (e->Millicode) info->rp = info->r31; - else if (rpoffset) + else if (rpoffset && ALIGNMENT_OK(info->prev_sp, long)) info->rp = *(unsigned long *)(info->prev_sp - rpoffset); + else + info->rp = 0; info->prev_ip = info->rp; info->rp = 0; } @@ -401,7 +408,7 @@ void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct struct pt_regs *r = &t->thread.regs; struct pt_regs *r2; - r2 = kmalloc(sizeof(struct pt_regs), GFP_ATOMIC); + r2 = kmalloc_obj(struct pt_regs, GFP_ATOMIC); if (!r2) return; *r2 = *r; diff --git a/arch/parisc/kernel/vdso.c b/arch/parisc/kernel/vdso.c index c5cbfce7a84c..54c18574424a 100644 --- a/arch/parisc/kernel/vdso.c +++ b/arch/parisc/kernel/vdso.c @@ -102,7 +102,7 @@ static struct page ** __init vdso_setup_pages(void *start, void *end) struct page **pagelist; int i; - pagelist = kcalloc(pages + 1, sizeof(struct page *), GFP_KERNEL); + pagelist = kzalloc_objs(struct page *, pages + 1); if (!pagelist) panic("%s: Cannot allocate page list for VDSO", __func__); for (i = 0; i < pages; i++) diff --git a/arch/parisc/kernel/vdso32/Makefile b/arch/parisc/kernel/vdso32/Makefile index 288f8b85978f..4ee8d17da229 100644 --- a/arch/parisc/kernel/vdso32/Makefile +++ b/arch/parisc/kernel/vdso32/Makefile @@ -1,5 +1,5 @@ # Include the generic Makefile to check the built vdso. -include $(srctree)/lib/vdso/Makefile +include $(srctree)/lib/vdso/Makefile.include KCOV_INSTRUMENT := n diff --git a/arch/parisc/kernel/vdso64/Makefile b/arch/parisc/kernel/vdso64/Makefile index bc5d9553f311..c63f4069170f 100644 --- a/arch/parisc/kernel/vdso64/Makefile +++ b/arch/parisc/kernel/vdso64/Makefile @@ -1,5 +1,5 @@ # Include the generic Makefile to check the built vdso. -include $(srctree)/lib/vdso/Makefile +include $(srctree)/lib/vdso/Makefile.include KCOV_INSTRUMENT := n diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index b445e47903cf..0ca93d6d7235 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S @@ -165,6 +165,7 @@ SECTIONS _end = . ; STABS_DEBUG + MODINFO ELF_DETAILS .note 0 : { *(.note) } diff --git a/arch/parisc/lib/Makefile b/arch/parisc/lib/Makefile index 7b197667faf6..d5975d1fb406 100644 --- a/arch/parisc/lib/Makefile +++ b/arch/parisc/lib/Makefile @@ -3,7 +3,7 @@ # Makefile for parisc-specific library files # -lib-y := lusercopy.o bitops.o checksum.o io.o memset.o memcpy.o \ +lib-y := lusercopy.o bitops.o io.o memset.o memcpy.o \ ucmpdi2.o delay.o obj-y := iomap.o diff --git a/arch/parisc/lib/checksum.c b/arch/parisc/lib/checksum.c deleted file mode 100644 index 59d8c15d81bd..000000000000 --- a/arch/parisc/lib/checksum.c +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * MIPS specific IP/TCP/UDP checksumming routines - * - * Authors: Ralf Baechle, <ralf@waldorf-gmbh.de> - * Lots of code moved from tcp.c and ip.c; see those files - * for more names. - */ -#include <linux/module.h> -#include <linux/types.h> - -#include <net/checksum.h> -#include <asm/byteorder.h> -#include <asm/string.h> -#include <linux/uaccess.h> - -#define addc(_t,_r) \ - __asm__ __volatile__ ( \ -" add %0, %1, %0\n" \ -" addc %0, %%r0, %0\n" \ - : "=r"(_t) \ - : "r"(_r), "0"(_t)); - -static inline unsigned int do_csum(const unsigned char * buff, int len) -{ - int odd, count; - unsigned int result = 0; - - if (len <= 0) - goto out; - odd = 1 & (unsigned long) buff; - if (odd) { - result = be16_to_cpu(*buff); - len--; - buff++; - } - count = len >> 1; /* nr of 16-bit words.. */ - if (count) { - if (2 & (unsigned long) buff) { - result += *(unsigned short *) buff; - count--; - len -= 2; - buff += 2; - } - count >>= 1; /* nr of 32-bit words.. */ - if (count) { - while (count >= 4) { - unsigned int r1, r2, r3, r4; - r1 = *(unsigned int *)(buff + 0); - r2 = *(unsigned int *)(buff + 4); - r3 = *(unsigned int *)(buff + 8); - r4 = *(unsigned int *)(buff + 12); - addc(result, r1); - addc(result, r2); - addc(result, r3); - addc(result, r4); - count -= 4; - buff += 16; - } - while (count) { - unsigned int w = *(unsigned int *) buff; - count--; - buff += 4; - addc(result, w); - } - result = (result & 0xffff) + (result >> 16); - } - if (len & 2) { - result += *(unsigned short *) buff; - buff += 2; - } - } - if (len & 1) - result += le16_to_cpu(*buff); - result = csum_from32to16(result); - if (odd) - result = swab16(result); -out: - return result; -} - -/* - * computes a partial checksum, e.g. for TCP/UDP fragments - */ -/* - * why bother folding? - */ -__wsum csum_partial(const void *buff, int len, __wsum sum) -{ - unsigned int result = do_csum(buff, len); - addc(result, sum); - return (__force __wsum)csum_from32to16(result); -} - -EXPORT_SYMBOL(csum_partial); diff --git a/arch/parisc/lib/io.c b/arch/parisc/lib/io.c index 7461366a65c9..3c7e617f5a93 100644 --- a/arch/parisc/lib/io.c +++ b/arch/parisc/lib/io.c @@ -13,67 +13,6 @@ #include <asm/io.h> /* -** Copies a block of memory from a device in an efficient manner. -** Assumes the device can cope with 32-bit transfers. If it can't, -** don't use this function. -** -** CR16 counts on C3000 reading 256 bytes from Symbios 896 RAM: -** 27341/64 = 427 cyc per int -** 61311/128 = 478 cyc per short -** 122637/256 = 479 cyc per byte -** Ergo bus latencies dominant (not transfer size). -** Minimize total number of transfers at cost of CPU cycles. -** TODO: only look at src alignment and adjust the stores to dest. -*/ -void memcpy_fromio(void *dst, const volatile void __iomem *src, int count) -{ - /* first compare alignment of src/dst */ - if ( (((unsigned long)dst ^ (unsigned long)src) & 1) || (count < 2) ) - goto bytecopy; - - if ( (((unsigned long)dst ^ (unsigned long)src) & 2) || (count < 4) ) - goto shortcopy; - - /* Then check for misaligned start address */ - if ((unsigned long)src & 1) { - *(u8 *)dst = readb(src); - src++; - dst++; - count--; - if (count < 2) goto bytecopy; - } - - if ((unsigned long)src & 2) { - *(u16 *)dst = __raw_readw(src); - src += 2; - dst += 2; - count -= 2; - } - - while (count > 3) { - *(u32 *)dst = __raw_readl(src); - dst += 4; - src += 4; - count -= 4; - } - - shortcopy: - while (count > 1) { - *(u16 *)dst = __raw_readw(src); - src += 2; - dst += 2; - count -= 2; - } - - bytecopy: - while (count--) { - *(char *)dst = readb(src); - src++; - dst++; - } -} - -/* * Read COUNT 8-bit bytes from port PORT into memory starting at * SRC. */ @@ -123,15 +62,15 @@ void insw (unsigned long port, void *dst, unsigned long count) unsigned char *p; p = (unsigned char *)dst; - + if (!count) return; - + switch (((unsigned long)p) & 0x3) { case 0x00: /* Buffer 32-bit aligned */ while (count>=2) { - + count -= 2; l = cpu_to_le16(inw(port)) << 16; l |= cpu_to_le16(inw(port)); @@ -142,13 +81,13 @@ void insw (unsigned long port, void *dst, unsigned long count) *(unsigned short *)p = cpu_to_le16(inw(port)); } break; - + case 0x02: /* Buffer 16-bit aligned */ *(unsigned short *)p = cpu_to_le16(inw(port)); p += 2; count--; while (count>=2) { - + count -= 2; l = cpu_to_le16(inw(port)) << 16; l |= cpu_to_le16(inw(port)); @@ -159,13 +98,13 @@ void insw (unsigned long port, void *dst, unsigned long count) *(unsigned short *)p = cpu_to_le16(inw(port)); } break; - + case 0x01: /* Buffer 8-bit aligned */ case 0x03: /* I don't bother with 32bit transfers * in this case, 16bit will have to do -- DE */ --count; - + l = cpu_to_le16(inw(port)); *p = l >> 8; p++; @@ -195,10 +134,10 @@ void insl (unsigned long port, void *dst, unsigned long count) unsigned char *p; p = (unsigned char *)dst; - + if (!count) return; - + switch (((unsigned long) dst) & 0x3) { case 0x00: /* Buffer 32-bit aligned */ @@ -208,14 +147,14 @@ void insl (unsigned long port, void *dst, unsigned long count) p += 4; } break; - + case 0x02: /* Buffer 16-bit aligned */ --count; - + l = cpu_to_le32(inl(port)); *(unsigned short *)p = l >> 16; p += 2; - + while (count--) { l2 = cpu_to_le32(inl(port)); @@ -227,7 +166,7 @@ void insl (unsigned long port, void *dst, unsigned long count) break; case 0x01: /* Buffer 8-bit aligned */ --count; - + l = cpu_to_le32(inl(port)); *(unsigned char *)p = l >> 24; p++; @@ -244,7 +183,7 @@ void insl (unsigned long port, void *dst, unsigned long count) break; case 0x03: /* Buffer 8-bit aligned */ --count; - + l = cpu_to_le32(inl(port)); *p = l >> 24; p++; @@ -293,10 +232,10 @@ void outsw (unsigned long port, const void *src, unsigned long count) const unsigned char *p; p = (const unsigned char *)src; - + if (!count) return; - + switch (((unsigned long)p) & 0x3) { case 0x00: /* Buffer 32-bit aligned */ @@ -311,13 +250,13 @@ void outsw (unsigned long port, const void *src, unsigned long count) outw(le16_to_cpu(*(unsigned short*)p), port); } break; - + case 0x02: /* Buffer 16-bit aligned */ - + outw(le16_to_cpu(*(unsigned short*)p), port); p += 2; count--; - + while (count>=2) { count -= 2; l = *(unsigned int *)p; @@ -329,11 +268,11 @@ void outsw (unsigned long port, const void *src, unsigned long count) outw(le16_to_cpu(*(unsigned short *)p), port); } break; - - case 0x01: /* Buffer 8-bit aligned */ + + case 0x01: /* Buffer 8-bit aligned */ /* I don't bother with 32bit transfers * in this case, 16bit will have to do -- DE */ - + l = *p << 8; p++; count--; @@ -348,7 +287,7 @@ void outsw (unsigned long port, const void *src, unsigned long count) l2 = *(unsigned char *)p; outw (le16_to_cpu(l | l2>>8), port); break; - + } } @@ -365,10 +304,10 @@ void outsl (unsigned long port, const void *src, unsigned long count) const unsigned char *p; p = (const unsigned char *)src; - + if (!count) return; - + switch (((unsigned long)p) & 0x3) { case 0x00: /* Buffer 32-bit aligned */ @@ -378,13 +317,13 @@ void outsl (unsigned long port, const void *src, unsigned long count) p += 4; } break; - + case 0x02: /* Buffer 16-bit aligned */ --count; - + l = *(unsigned short *)p; p += 2; - + while (count--) { l2 = *(unsigned int *)p; @@ -415,7 +354,7 @@ void outsl (unsigned long port, const void *src, unsigned long count) break; case 0x03: /* Buffer 8-bit aligned */ --count; - + l = *p << 24; p++; diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c index 5fc0c852c84c..03165c82dfdb 100644 --- a/arch/parisc/lib/memcpy.c +++ b/arch/parisc/lib/memcpy.c @@ -12,6 +12,7 @@ #include <linux/module.h> #include <linux/compiler.h> #include <linux/uaccess.h> +#include <linux/mm.h> #define get_user_space() mfsp(SR_USER) #define get_kernel_space() SR_KERNEL @@ -32,9 +33,24 @@ EXPORT_SYMBOL(raw_copy_to_user); unsigned long raw_copy_from_user(void *dst, const void __user *src, unsigned long len) { + unsigned long start = (unsigned long) src; + unsigned long end = start + len; + unsigned long newlen = len; + mtsp(get_user_space(), SR_TEMP1); mtsp(get_kernel_space(), SR_TEMP2); - return pa_memcpy(dst, (void __force *)src, len); + + /* Check region is user accessible */ + while (start < end) { + if (!prober_user(SR_TEMP1, start)) { + newlen = (start - (unsigned long) src); + break; + } + start += PAGE_SIZE; + /* align to page boundry which may have different permission */ + start = PAGE_ALIGN_DOWN(start); + } + return len - newlen + pa_memcpy(dst, (void __force *)src, newlen); } EXPORT_SYMBOL(raw_copy_from_user); diff --git a/arch/parisc/math-emu/driver.c b/arch/parisc/math-emu/driver.c index 34495446e051..71829cb7bc81 100644 --- a/arch/parisc/math-emu/driver.c +++ b/arch/parisc/math-emu/driver.c @@ -97,9 +97,19 @@ handle_fpe(struct pt_regs *regs) memcpy(regs->fr, frcopy, sizeof regs->fr); if (signalcode != 0) { - force_sig_fault(signalcode >> 24, signalcode & 0xffffff, - (void __user *) regs->iaoq[0]); - return -1; + int sig = signalcode >> 24; + + if (sig == SIGFPE) { + /* + * Clear floating point trap bit to avoid trapping + * again on the first floating-point instruction in + * the userspace signal handler. + */ + regs->fr[0] &= ~(1ULL << 38); + } + force_sig_fault(sig, signalcode & 0xffffff, + (void __user *) regs->iaoq[0]); + return -1; } return signalcode ? -1 : 0; diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index c39de84e98b0..f1785640b049 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c @@ -363,6 +363,10 @@ bad_area: mmap_read_unlock(mm); bad_area_nosemaphore: + if (!user_mode(regs) && fixup_exception(regs)) { + return; + } + if (user_mode(regs)) { int signo, si_code; diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 61c0a2477072..be3380c9bcda 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c @@ -562,10 +562,6 @@ void __init mem_init(void) BUILD_BUG_ON(TMPALIAS_MAP_START >= 0x80000000); #endif - high_memory = __va((max_pfn << PAGE_SHIFT)); - set_max_mapnr(max_low_pfn); - memblock_free_all(); - #ifdef CONFIG_PA11 if (boot_cpu_data.cpu_type == pcxl2 || boot_cpu_data.cpu_type == pcxl) { pcxl_dma_start = (unsigned long)SET_MAP_OFFSET(MAP_START); @@ -608,9 +604,6 @@ void __init mem_init(void) #endif } -unsigned long *empty_zero_page __ro_after_init; -EXPORT_SYMBOL(empty_zero_page); - /* * pagetable_init() sets up the page tables * @@ -643,9 +636,6 @@ static void __init pagetable_init(void) initrd_end - initrd_start, PAGE_KERNEL, 0); } #endif - - empty_zero_page = memblock_alloc_or_panic(PAGE_SIZE, PAGE_SIZE); - } static void __init gateway_init(void) @@ -697,13 +687,9 @@ static void __init fixmap_init(void) } while (addr < end); } -static void __init parisc_bootmem_free(void) +void __init arch_zone_limits_init(unsigned long *max_zone_pfns) { - unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0, }; - - max_zone_pfn[0] = memblock_end_of_DRAM(); - - free_area_init(max_zone_pfn); + max_zone_pfns[ZONE_NORMAL] = PFN_DOWN(memblock_end_of_DRAM()); } void __init paging_init(void) @@ -714,9 +700,6 @@ void __init paging_init(void) fixmap_init(); flush_cache_all_local(); /* start with known state */ flush_tlb_all_local(NULL); - - sparse_init(); - parisc_bootmem_free(); } static void alloc_btlb(unsigned long start, unsigned long end, int *slot, diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c index fd996472dfe7..0b65c4b3baee 100644 --- a/arch/parisc/mm/ioremap.c +++ b/arch/parisc/mm/ioremap.c @@ -14,7 +14,7 @@ #include <linux/mm.h> void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size, - unsigned long prot) + pgprot_t prot) { #ifdef CONFIG_EISA unsigned long end = phys_addr + size - 1; @@ -41,6 +41,6 @@ void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size, } } - return generic_ioremap_prot(phys_addr, size, __pgprot(prot)); + return generic_ioremap_prot(phys_addr, size, prot); } EXPORT_SYMBOL(ioremap_prot); diff --git a/arch/parisc/net/bpf_jit_core.c b/arch/parisc/net/bpf_jit_core.c index 06cbcd6fe87b..172770132440 100644 --- a/arch/parisc/net/bpf_jit_core.c +++ b/arch/parisc/net/bpf_jit_core.c @@ -41,33 +41,22 @@ bool bpf_jit_needs_zext(void) return true; } -struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) +struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_prog *prog) { unsigned int prog_size = 0, extable_size = 0; - bool tmp_blinded = false, extra_pass = false; - struct bpf_prog *tmp, *orig_prog = prog; + bool extra_pass = false; int pass = 0, prev_ninsns = 0, prologue_len, i; struct hppa_jit_data *jit_data; struct hppa_jit_context *ctx; if (!prog->jit_requested) - return orig_prog; - - tmp = bpf_jit_blind_constants(prog); - if (IS_ERR(tmp)) - return orig_prog; - if (tmp != prog) { - tmp_blinded = true; - prog = tmp; - } + return prog; jit_data = prog->aux->jit_data; if (!jit_data) { - jit_data = kzalloc(sizeof(*jit_data), GFP_KERNEL); - if (!jit_data) { - prog = orig_prog; - goto out; - } + jit_data = kzalloc_obj(*jit_data); + if (!jit_data) + return prog; prog->aux->jit_data = jit_data; } @@ -80,11 +69,9 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) } ctx->prog = prog; - ctx->offset = kcalloc(prog->len, sizeof(int), GFP_KERNEL); - if (!ctx->offset) { - prog = orig_prog; - goto out_offset; - } + ctx->offset = kzalloc_objs(int, prog->len); + if (!ctx->offset) + goto out_err; for (i = 0; i < prog->len; i++) { prev_ninsns += 20; ctx->offset[i] = prev_ninsns; @@ -93,10 +80,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) for (i = 0; i < NR_JIT_ITERATIONS; i++) { pass++; ctx->ninsns = 0; - if (build_body(ctx, extra_pass, ctx->offset)) { - prog = orig_prog; - goto out_offset; - } + if (build_body(ctx, extra_pass, ctx->offset)) + goto out_err; ctx->body_len = ctx->ninsns; bpf_jit_build_prologue(ctx); ctx->prologue_len = ctx->ninsns - ctx->body_len; @@ -116,10 +101,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) &jit_data->image, sizeof(long), bpf_fill_ill_insns); - if (!jit_data->header) { - prog = orig_prog; - goto out_offset; - } + if (!jit_data->header) + goto out_err; ctx->insns = (u32 *)jit_data->image; /* @@ -134,8 +117,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) pr_err("bpf-jit: image did not converge in <%d passes!\n", i); if (jit_data->header) bpf_jit_binary_free(jit_data->header); - prog = orig_prog; - goto out_offset; + goto out_err; } if (extable_size) @@ -148,8 +130,7 @@ skip_init_ctx: bpf_jit_build_prologue(ctx); if (build_body(ctx, extra_pass, NULL)) { bpf_jit_binary_free(jit_data->header); - prog = orig_prog; - goto out_offset; + goto out_err; } bpf_jit_build_epilogue(ctx); @@ -160,20 +141,19 @@ skip_init_ctx: { extern int machine_restart(char *); machine_restart(""); } } + if (!prog->is_func || extra_pass) { + if (bpf_jit_binary_lock_ro(jit_data->header)) { + bpf_jit_binary_free(jit_data->header); + goto out_err; + } + bpf_flush_icache(jit_data->header, ctx->insns + ctx->ninsns); + } + prog->bpf_func = (void *)ctx->insns; prog->jited = 1; prog->jited_len = prog_size; - bpf_flush_icache(jit_data->header, ctx->insns + ctx->ninsns); - if (!prog->is_func || extra_pass) { - if (bpf_jit_binary_lock_ro(jit_data->header)) { - bpf_jit_binary_free(jit_data->header); - prog->bpf_func = NULL; - prog->jited = 0; - prog->jited_len = 0; - goto out_offset; - } prologue_len = ctx->epilogue_offset - ctx->body_len; for (i = 0; i < prog->len; i++) ctx->offset[i] += prologue_len; @@ -183,14 +163,19 @@ out_offset: kfree(jit_data); prog->aux->jit_data = NULL; } -out: + if (HPPA_JIT_REBOOT) { extern int machine_restart(char *); machine_restart(""); } - if (tmp_blinded) - bpf_jit_prog_release_other(prog, prog == orig_prog ? - tmp : orig_prog); return prog; + +out_err: + if (extra_pass) { + prog->bpf_func = NULL; + prog->jited = 0; + prog->jited_len = 0; + } + goto out_offset; } u64 hppa_div64(u64 div, u64 divisor) |
