parisc architecture updates for kernel v5.16-rc1

Lots of new features and fixes:
 * Added TOC (table of content) support, which is a debugging feature which is
   either initiated by pressing the TOC button or via command in the BMC. If
   pressed the Linux built-in KDB/KGDB will be called (Sven Schnelle)
 * Fix CONFIG_PREEMPT (Sven)
 * Fix unwinder on 64-bit kernels (Sven)
 * Various kgdb fixes (Sven)
 * Added KFENCE support (me)
 * Switch to ARCH_STACKWALK implementation (me)
 * Fix ptrace check on syscall return (me)
 * Fix kernel crash with fixmaps on PA1.x machines (me)
 * Move thread_info into task struct, aka CONFIG_THREAD_INFO_IN_TASK (me)
 * Updated defconfigs
 * Smaller cleanups, including Makefile cleanups (Masahiro Yamada),
   use kthread_run() macro (Cai Huoqing), use swap() macro (Yihao Han).
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYIAB0WIQS86RI+GtKfB8BJu973ErUQojoPXwUCYYALowAKCRD3ErUQojoP
 X3o1APwK7wJBdFKAV2hMEouFNZLz2ZTkSQrCMhPTxRupkwJ71QD+JeXvyPLZBLIu
 hlvi9mw9DKUKgCV+/Z65s8zjSHYC4wg=
 =A4Ci
 -----END PGP SIGNATURE-----

Merge tag 'for-5.16/parisc-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux

Pull parisc updates from Helge Deller:
 "Lots of new features and fixes:

   - Added TOC (table of content) support, which is a debugging feature
     which is either initiated by pressing the TOC button or via command
     in the BMC. If pressed the Linux built-in KDB/KGDB will be called
     (Sven Schnelle)

   - Fix CONFIG_PREEMPT (Sven)

   - Fix unwinder on 64-bit kernels (Sven)

   - Various kgdb fixes (Sven)

   - Added KFENCE support (me)

   - Switch to ARCH_STACKWALK implementation (me)

   - Fix ptrace check on syscall return (me)

   - Fix kernel crash with fixmaps on PA1.x machines (me)

   - Move thread_info into task struct, aka CONFIG_THREAD_INFO_IN_TASK
     (me)

   - Updated defconfigs

   - Smaller cleanups, including Makefile cleanups (Masahiro Yamada),
     use kthread_run() macro (Cai Huoqing), use swap() macro (Yihao
     Han)"

* tag 'for-5.16/parisc-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux: (36 commits)
  parisc: Fix set_fixmap() on PA1.x CPUs
  parisc: Use swap() to swap values in setup_bootmem()
  parisc: Update defconfigs
  parisc: decompressor: clean up Makefile
  parisc: decompressor: remove repeated depenency of misc.o
  parisc: Remove unused constants from asm-offsets.c
  parisc/ftrace: use static key to enable/disable function graph tracer
  parisc/ftrace: set function trace function
  parisc: Make use of the helper macro kthread_run()
  parisc: mark xchg functions notrace
  parisc: enhance warning regarding usage of O_NONBLOCK
  parisc: Drop ifdef __KERNEL__ from non-uapi kernel headers
  parisc: Use PRIV_USER and PRIV_KERNEL in ptrace.h
  parisc: Use PRIV_USER in syscall.S
  parisc/kgdb: add kgdb_roundup() to make kgdb work with idle polling
  parisc: Move thread_info into task struct
  parisc: add support for TOC (transfer of control)
  parisc/firmware: add functions to retrieve TOC data
  parisc: add PIM TOC data structures
  parisc: move virt_map macro to assembly.h
  ...
This commit is contained in:
Linus Torvalds 2021-11-01 16:51:13 -07:00
commit 552ebfe022
44 changed files with 622 additions and 321 deletions

View File

@ -20,7 +20,7 @@
| nds32: | ok | | nds32: | ok |
| nios2: | TODO | | nios2: | TODO |
| openrisc: | TODO | | openrisc: | TODO |
| parisc: | TODO | | parisc: | ok |
| powerpc: | ok | | powerpc: | ok |
| riscv: | ok | | riscv: | ok |
| s390: | ok | | s390: | ok |

View File

@ -13,6 +13,8 @@ config PARISC
select ARCH_NO_SG_CHAIN select ARCH_NO_SG_CHAIN
select ARCH_SUPPORTS_HUGETLBFS if PA20 select ARCH_SUPPORTS_HUGETLBFS if PA20
select ARCH_SUPPORTS_MEMORY_FAILURE select ARCH_SUPPORTS_MEMORY_FAILURE
select ARCH_STACKWALK
select HAVE_RELIABLE_STACKTRACE
select DMA_OPS select DMA_OPS
select RTC_CLASS select RTC_CLASS
select RTC_DRV_GENERIC select RTC_DRV_GENERIC
@ -46,6 +48,7 @@ config PARISC
select HAVE_ARCH_HASH select HAVE_ARCH_HASH
select HAVE_ARCH_JUMP_LABEL select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_JUMP_LABEL_RELATIVE select HAVE_ARCH_JUMP_LABEL_RELATIVE
select HAVE_ARCH_KFENCE
select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRACEHOOK
select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_REGS_AND_STACK_ACCESS_API
@ -53,6 +56,7 @@ config PARISC
select HAVE_UNSTABLE_SCHED_CLOCK if SMP select HAVE_UNSTABLE_SCHED_CLOCK if SMP
select LEGACY_TIMER_TICK select LEGACY_TIMER_TICK
select CPU_NO_EFFICIENT_FFS select CPU_NO_EFFICIENT_FFS
select THREAD_INFO_IN_TASK
select NEED_DMA_MAP_STATE select NEED_DMA_MAP_STATE
select NEED_SG_DMA_LENGTH select NEED_SG_DMA_LENGTH
select HAVE_ARCH_KGDB select HAVE_ARCH_KGDB
@ -252,11 +256,11 @@ config PARISC_PAGE_SIZE_4KB
config PARISC_PAGE_SIZE_16KB config PARISC_PAGE_SIZE_16KB
bool "16KB" bool "16KB"
depends on PA8X00 && BROKEN depends on PA8X00 && BROKEN && !KFENCE
config PARISC_PAGE_SIZE_64KB config PARISC_PAGE_SIZE_64KB
bool "64KB" bool "64KB"
depends on PA8X00 && BROKEN depends on PA8X00 && BROKEN && !KFENCE
endchoice endchoice
@ -288,6 +292,20 @@ config SMP
If you don't know what to do here, say N. If you don't know what to do here, say N.
config TOC
bool "Support TOC switch"
default y if 64BIT || !SMP
help
Most PA-RISC machines have either a switch at the back of the machine
or a command in BMC to trigger a TOC interrupt. If you say Y here a
handler will be installed which will either show a backtrace on all
CPUs, or enter a possible configured debugger like kgdb/kdb.
Note that with this option enabled, the kernel will use an additional 16KB
per possible CPU as a special stack for the TOC handler.
If you don't want to debug the Kernel, say N.
config PARISC_CPU_TOPOLOGY config PARISC_CPU_TOPOLOGY
bool "Support cpu topology definition" bool "Support cpu topology definition"
depends on SMP depends on SMP

View File

@ -9,9 +9,10 @@ KCOV_INSTRUMENT := n
GCOV_PROFILE := n GCOV_PROFILE := n
UBSAN_SANITIZE := n UBSAN_SANITIZE := n
OBJECTS := head.o real2.o firmware.o misc.o piggy.o
targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2
targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4 targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4
targets += misc.o piggy.o sizes.h head.o real2.o firmware.o targets += $(OBJECTS) sizes.h
targets += real2.S firmware.c targets += real2.S firmware.c
KBUILD_CFLAGS := -D__KERNEL__ -O2 -DBOOTLOADER KBUILD_CFLAGS := -D__KERNEL__ -O2 -DBOOTLOADER
@ -23,10 +24,8 @@ ifndef CONFIG_64BIT
KBUILD_CFLAGS += -mfast-indirect-calls KBUILD_CFLAGS += -mfast-indirect-calls
endif endif
OBJECTS += $(obj)/head.o $(obj)/real2.o $(obj)/firmware.o $(obj)/misc.o $(obj)/piggy.o
LDFLAGS_vmlinux := -X -e startup --as-needed -T LDFLAGS_vmlinux := -X -e startup --as-needed -T
$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS) $(LIBGCC) FORCE $(obj)/vmlinux: $(obj)/vmlinux.lds $(addprefix $(obj)/, $(OBJECTS)) $(LIBGCC) FORCE
$(call if_changed,ld) $(call if_changed,ld)
sed-sizes := -e 's/^\([0-9a-fA-F]*\) . \(__bss_start\|_end\|parisc_kernel_start\)$$/\#define SZ\2 0x\1/p' sed-sizes := -e 's/^\([0-9a-fA-F]*\) . \(__bss_start\|_end\|parisc_kernel_start\)$$/\#define SZ\2 0x\1/p'
@ -52,8 +51,6 @@ $(obj)/real2.o: $(obj)/real2.S
$(obj)/real2.S: $(srctree)/arch/$(SRCARCH)/kernel/real2.S $(obj)/real2.S: $(srctree)/arch/$(SRCARCH)/kernel/real2.S
$(call cmd,shipped) $(call cmd,shipped)
$(obj)/misc.o: $(obj)/sizes.h
CPPFLAGS_vmlinux.lds += -I$(objtree)/$(obj) -DBOOTLOADER CPPFLAGS_vmlinux.lds += -I$(objtree)/$(obj) -DBOOTLOADER
$(obj)/vmlinux.lds: $(obj)/sizes.h $(obj)/vmlinux.lds: $(obj)/sizes.h

View File

@ -22,7 +22,6 @@ CONFIG_PCI_LBA=y
CONFIG_MODULES=y CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_MISC=m CONFIG_BINFMT_MISC=m
CONFIG_NET=y CONFIG_NET=y
@ -55,13 +54,14 @@ CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y CONFIG_CHR_DEV_ST=y
CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR=y
CONFIG_CHR_DEV_SG=y CONFIG_CHR_DEV_SG=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_SCSI_LASI700=y CONFIG_SCSI_LASI700=y
CONFIG_SCSI_SYM53C8XX_2=y CONFIG_SCSI_SYM53C8XX_2=y
CONFIG_SCSI_ZALON=y CONFIG_SCSI_ZALON=y
CONFIG_SCSI_DH=y CONFIG_SCSI_DH=y
CONFIG_ATA=y CONFIG_ATA=y
CONFIG_ATA_GENERIC=y
CONFIG_PATA_NS87415=y CONFIG_PATA_NS87415=y
CONFIG_ATA_GENERIC=y
CONFIG_MD=y CONFIG_MD=y
CONFIG_BLK_DEV_MD=m CONFIG_BLK_DEV_MD=m
CONFIG_MD_LINEAR=m CONFIG_MD_LINEAR=m
@ -212,7 +212,6 @@ CONFIG_NFS_FS=m
CONFIG_NFSD=m CONFIG_NFSD=m
CONFIG_NFSD_V3=y CONFIG_NFSD_V3=y
CONFIG_CIFS=m CONFIG_CIFS=m
CONFIG_CIFS_WEAK_PW_HASH=y
CONFIG_CIFS_XATTR=y CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y CONFIG_CIFS_POSIX=y
# CONFIG_CIFS_DEBUG is not set # CONFIG_CIFS_DEBUG is not set
@ -221,16 +220,12 @@ CONFIG_CRYPTO_HMAC=y
CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_TGR192=m
CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_WP512=m
CONFIG_CRYPTO_ANUBIS=m
CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_BLOWFISH=m
CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST5=m
CONFIG_CRYPTO_CAST6=m CONFIG_CRYPTO_CAST6=m
CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_DES=y
CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRC_CCITT=m CONFIG_CRC_CCITT=m

View File

@ -8,9 +8,10 @@ CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_CGROUPS=y CONFIG_CGROUPS=y
CONFIG_MEMCG=y CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
CONFIG_CGROUP_PIDS=y CONFIG_CGROUP_PIDS=y
CONFIG_CPUSETS=y CONFIG_CPUSETS=y
CONFIG_RELAY=y CONFIG_RELAY=y
@ -124,14 +125,13 @@ CONFIG_QLCNIC=m
# CONFIG_NET_VENDOR_TI is not set # CONFIG_NET_VENDOR_TI is not set
# CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_VIA is not set
# CONFIG_NET_VENDOR_WIZNET is not set # CONFIG_NET_VENDOR_WIZNET is not set
CONFIG_MDIO_BITBANG=m
CONFIG_PHYLIB=y CONFIG_PHYLIB=y
CONFIG_BROADCOM_PHY=m CONFIG_BROADCOM_PHY=m
CONFIG_CICADA_PHY=m CONFIG_CICADA_PHY=m
CONFIG_DAVICOM_PHY=m CONFIG_DAVICOM_PHY=m
CONFIG_ICPLUS_PHY=m CONFIG_ICPLUS_PHY=m
CONFIG_LSI_ET1011C_PHY=m
CONFIG_LXT_PHY=m CONFIG_LXT_PHY=m
CONFIG_LSI_ET1011C_PHY=m
CONFIG_MARVELL_PHY=m CONFIG_MARVELL_PHY=m
CONFIG_NATIONAL_PHY=m CONFIG_NATIONAL_PHY=m
CONFIG_QSEMI_PHY=m CONFIG_QSEMI_PHY=m
@ -139,6 +139,7 @@ CONFIG_REALTEK_PHY=m
CONFIG_SMSC_PHY=m CONFIG_SMSC_PHY=m
CONFIG_STE10XP=m CONFIG_STE10XP=m
CONFIG_VITESSE_PHY=m CONFIG_VITESSE_PHY=m
CONFIG_MDIO_BITBANG=m
CONFIG_SLIP=m CONFIG_SLIP=m
# CONFIG_WLAN is not set # CONFIG_WLAN is not set
CONFIG_INPUT_EVDEV=y CONFIG_INPUT_EVDEV=y
@ -150,7 +151,6 @@ CONFIG_SERIO_SERPORT=m
# CONFIG_HP_SDC is not set # CONFIG_HP_SDC is not set
CONFIG_SERIO_RAW=m CONFIG_SERIO_RAW=m
# CONFIG_LEGACY_PTYS is not set # CONFIG_LEGACY_PTYS is not set
CONFIG_NOZOMI=m
CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250=y
# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CONSOLE=y
@ -160,6 +160,7 @@ CONFIG_SERIAL_8250_EXTENDED=y
CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_MANY_PORTS=y
CONFIG_SERIAL_8250_SHARE_IRQ=y CONFIG_SERIAL_8250_SHARE_IRQ=y
CONFIG_SERIAL_JSM=m CONFIG_SERIAL_JSM=m
CONFIG_NOZOMI=m
CONFIG_IPMI_HANDLER=y CONFIG_IPMI_HANDLER=y
CONFIG_IPMI_DEVICE_INTERFACE=y CONFIG_IPMI_DEVICE_INTERFACE=y
CONFIG_IPMI_SI=y CONFIG_IPMI_SI=y
@ -188,9 +189,13 @@ CONFIG_AGP=y
CONFIG_AGP_PARISC=y CONFIG_AGP_PARISC=y
CONFIG_DRM=y CONFIG_DRM=y
CONFIG_DRM_RADEON=y CONFIG_DRM_RADEON=y
CONFIG_FIRMWARE_EDID=y CONFIG_FB=y
CONFIG_FB_MODE_HELPERS=y CONFIG_FB_MATROX=y
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_FB_MATROX_MYSTIQUE=y
CONFIG_FB_MATROX_G=y
CONFIG_FB_MATROX_I2C=y
CONFIG_FB_MATROX_MAVEN=y
CONFIG_FB_RADEON=y
CONFIG_HIDRAW=y CONFIG_HIDRAW=y
CONFIG_HID_PID=y CONFIG_HID_PID=y
CONFIG_USB_HIDDEV=y CONFIG_USB_HIDDEV=y
@ -202,7 +207,6 @@ CONFIG_UIO_SERCOS3=m
CONFIG_UIO_PCI_GENERIC=m CONFIG_UIO_PCI_GENERIC=m
CONFIG_STAGING=y CONFIG_STAGING=y
CONFIG_QLGE=m CONFIG_QLGE=m
CONFIG_HP100=m
CONFIG_EXT2_FS=y CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_SECURITY=y CONFIG_EXT2_FS_SECURITY=y
@ -245,7 +249,6 @@ CONFIG_CRYPTO_PCBC=m
CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MD4=m
CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_MICHAEL_MIC=m
CONFIG_CRYPTO_ARC4=m
CONFIG_CRYPTO_FCRYPT=m CONFIG_CRYPTO_FCRYPT=m
CONFIG_CRYPTO_DEFLATE=m CONFIG_CRYPTO_DEFLATE=m
# CONFIG_CRYPTO_HW is not set # CONFIG_CRYPTO_HW is not set

View File

@ -42,6 +42,9 @@
#define ASM_ULONG_INSN .word #define ASM_ULONG_INSN .word
#endif #endif
/* Frame alignment for 32- and 64-bit */
#define FRAME_ALIGN 64
#define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE) #define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE)
#ifdef CONFIG_PA20 #ifdef CONFIG_PA20
@ -58,6 +61,10 @@
#define PA_ASM_LEVEL 1.1 #define PA_ASM_LEVEL 1.1
#endif #endif
/* Privilege level field in the rightmost two bits of the IA queues */
#define PRIV_USER 3
#define PRIV_KERNEL 0
#ifdef __ASSEMBLY__ #ifdef __ASSEMBLY__
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
@ -71,6 +78,7 @@
#include <asm/types.h> #include <asm/types.h>
#include <asm/asmregs.h> #include <asm/asmregs.h>
#include <asm/psw.h>
sp = 30 sp = 30
gp = 27 gp = 27
@ -497,6 +505,30 @@
nop /* 7 */ nop /* 7 */
.endm .endm
/* Switch to virtual mapping, trashing only %r1 */
.macro virt_map
/* pcxt_ssm_bug */
rsm PSW_SM_I, %r0 /* barrier for "Relied upon Translation */
mtsp %r0, %sr4
mtsp %r0, %sr5
mtsp %r0, %sr6
tovirt_r1 %r29
load32 KERNEL_PSW, %r1
rsm PSW_SM_QUIET,%r0 /* second "heavy weight" ctl op */
mtctl %r0, %cr17 /* Clear IIASQ tail */
mtctl %r0, %cr17 /* Clear IIASQ head */
mtctl %r1, %ipsw
load32 4f, %r1
mtctl %r1, %cr18 /* Set IIAOQ tail */
ldo 4(%r1), %r1
mtctl %r1, %cr18 /* Set IIAOQ head */
rfir
nop
4:
.endm
/* /*
* ASM_EXCEPTIONTABLE_ENTRY * ASM_EXCEPTIONTABLE_ENTRY
* *

View File

@ -104,8 +104,6 @@ static __inline__ int test_and_change_bit(int nr, volatile unsigned long * addr)
#include <asm-generic/bitops/non-atomic.h> #include <asm-generic/bitops/non-atomic.h>
#ifdef __KERNEL__
/** /**
* __ffs - find first bit in word. returns 0 to "BITS_PER_LONG-1". * __ffs - find first bit in word. returns 0 to "BITS_PER_LONG-1".
* @word: The word to search * @word: The word to search
@ -205,16 +203,8 @@ static __inline__ int fls(unsigned int x)
#include <asm-generic/bitops/hweight.h> #include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h> #include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/sched.h> #include <asm-generic/bitops/sched.h>
#endif /* __KERNEL__ */
#include <asm-generic/bitops/find.h> #include <asm-generic/bitops/find.h>
#ifdef __KERNEL__
#include <asm-generic/bitops/le.h> #include <asm-generic/bitops/le.h>
#include <asm-generic/bitops/ext2-atomic-setbit.h> #include <asm-generic/bitops/ext2-atomic-setbit.h>
#endif /* __KERNEL__ */
#endif /* _PARISC_BITOPS_H */ #endif /* _PARISC_BITOPS_H */

View File

@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_PARISC_CURRENT_H
#define _ASM_PARISC_CURRENT_H
#include <asm/special_insns.h>
#ifndef __ASSEMBLY__
struct task_struct;
static __always_inline struct task_struct *get_current(void)
{
return (struct task_struct *) mfctl(30);
}
#define current get_current()
#endif /* __ASSEMBLY__ */
#endif /* _ASM_PARISC_CURRENT_H */

View File

@ -2,8 +2,6 @@
#ifndef _ASM_PARISC_FUTEX_H #ifndef _ASM_PARISC_FUTEX_H
#define _ASM_PARISC_FUTEX_H #define _ASM_PARISC_FUTEX_H
#ifdef __KERNEL__
#include <linux/futex.h> #include <linux/futex.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/atomic.h> #include <asm/atomic.h>
@ -119,5 +117,4 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
return 0; return 0;
} }
#endif /*__KERNEL__*/
#endif /*_ASM_PARISC_FUTEX_H*/ #endif /*_ASM_PARISC_FUTEX_H*/

View File

@ -12,8 +12,6 @@
#ifndef __ASM_PARISC_IDE_H #ifndef __ASM_PARISC_IDE_H
#define __ASM_PARISC_IDE_H #define __ASM_PARISC_IDE_H
#ifdef __KERNEL__
/* Generic I/O and MEMIO string operations. */ /* Generic I/O and MEMIO string operations. */
#define __ide_insw insw #define __ide_insw insw
@ -53,6 +51,4 @@ static __inline__ void __ide_mm_outsl(void __iomem *port, void *addr, u32 count)
} }
} }
#endif /* __KERNEL__ */
#endif /* __ASM_PARISC_IDE_H */ #endif /* __ASM_PARISC_IDE_H */

View File

@ -0,0 +1,44 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* PA-RISC KFENCE support.
*
* Copyright (C) 2021, Helge Deller <deller@gmx.de>
*/
#ifndef _ASM_PARISC_KFENCE_H
#define _ASM_PARISC_KFENCE_H
#include <linux/kfence.h>
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
static inline bool arch_kfence_init_pool(void)
{
return true;
}
/* Protect the given page and flush TLB. */
static inline bool kfence_protect_page(unsigned long addr, bool protect)
{
pte_t *pte = virt_to_kpte(addr);
if (WARN_ON(!pte))
return false;
/*
* We need to avoid IPIs, as we may get KFENCE allocations or faults
* with interrupts disabled.
*/
if (protect)
set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_PRESENT));
else
set_pte(pte, __pte(pte_val(*pte) | _PAGE_PRESENT));
flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
return true;
}
#endif /* _ASM_PARISC_KFENCE_H */

View File

@ -1,10 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */
#ifndef ASM_PARISC_MCKINLEY_H #ifndef ASM_PARISC_MCKINLEY_H
#define ASM_PARISC_MCKINLEY_H #define ASM_PARISC_MCKINLEY_H
#ifdef __KERNEL__
/* declared in arch/parisc/kernel/setup.c */ /* declared in arch/parisc/kernel/setup.c */
extern struct proc_dir_entry * proc_mckinley_root; extern struct proc_dir_entry * proc_mckinley_root;
#endif /*__KERNEL__*/
#endif /*ASM_PARISC_MCKINLEY_H*/ #endif /*ASM_PARISC_MCKINLEY_H*/

View File

@ -51,6 +51,8 @@ int pdc_spaceid_bits(unsigned long *space_bits);
int pdc_btlb_info(struct pdc_btlb_info *btlb); int pdc_btlb_info(struct pdc_btlb_info *btlb);
int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path); int pdc_mem_map_hpa(struct pdc_memory_map *r_addr, struct pdc_module_path *mod_path);
#endif /* !CONFIG_PA20 */ #endif /* !CONFIG_PA20 */
int pdc_pim_toc11(struct pdc_toc_pim_11 *ret);
int pdc_pim_toc20(struct pdc_toc_pim_20 *ret);
int pdc_lan_station_id(char *lan_addr, unsigned long net_hpa); int pdc_lan_station_id(char *lan_addr, unsigned long net_hpa);
int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count); int pdc_stable_read(unsigned long staddr, void *memaddr, unsigned long count);

View File

@ -12,6 +12,7 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <linux/threads.h> #include <linux/threads.h>
#include <asm/assembly.h>
#include <asm/prefetch.h> #include <asm/prefetch.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/pdc.h> #include <asm/pdc.h>
@ -37,16 +38,12 @@
#define DEFAULT_MAP_BASE DEFAULT_MAP_BASE32 #define DEFAULT_MAP_BASE DEFAULT_MAP_BASE32
#endif #endif
#ifdef __KERNEL__
/* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc. /* XXX: STACK_TOP actually should be STACK_BOTTOM for parisc.
* prumpf */ * prumpf */
#define STACK_TOP TASK_SIZE #define STACK_TOP TASK_SIZE
#define STACK_TOP_MAX DEFAULT_TASK_SIZE #define STACK_TOP_MAX DEFAULT_TASK_SIZE
#endif
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
unsigned long calc_max_stack_size(unsigned long stack_max); unsigned long calc_max_stack_size(unsigned long stack_max);
@ -101,8 +98,6 @@ DECLARE_PER_CPU(struct cpuinfo_parisc, cpu_data);
#define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF) #define CPU_HVERSION ((boot_cpu_data.hversion >> 4) & 0x0FFF)
#define ARCH_MIN_TASKALIGN 8
struct thread_struct { struct thread_struct {
struct pt_regs regs; struct pt_regs regs;
unsigned long task_size; unsigned long task_size;
@ -294,6 +289,10 @@ extern int _parisc_requires_coherency;
extern int running_on_qemu; extern int running_on_qemu;
extern void toc_handler(void);
extern unsigned int toc_handler_size;
extern unsigned int toc_handler_csum;
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* __ASM_PARISC_PROCESSOR_H */ #endif /* __ASM_PARISC_PROCESSOR_H */

View File

@ -5,17 +5,17 @@
#ifndef _PARISC_PTRACE_H #ifndef _PARISC_PTRACE_H
#define _PARISC_PTRACE_H #define _PARISC_PTRACE_H
#include <asm/assembly.h>
#include <uapi/asm/ptrace.h> #include <uapi/asm/ptrace.h>
#define task_regs(task) ((struct pt_regs *) ((char *)(task) + TASK_REGS)) #define task_regs(task) ((struct pt_regs *) ((char *)(task) + TASK_REGS))
#define arch_has_single_step() 1 #define arch_has_single_step() 1
#define arch_has_block_step() 1 #define arch_has_block_step() 1
/* XXX should we use iaoq[1] or iaoq[0] ? */ /* XXX should we use iaoq[1] or iaoq[0] ? */
#define user_mode(regs) (((regs)->iaoq[0] & 3) ? 1 : 0) #define user_mode(regs) (((regs)->iaoq[0] & 3) != PRIV_KERNEL)
#define user_space(regs) (((regs)->iasq[1] != 0) ? 1 : 0) #define user_space(regs) ((regs)->iasq[1] != PRIV_KERNEL)
#define instruction_pointer(regs) ((regs)->iaoq[0] & ~3) #define instruction_pointer(regs) ((regs)->iaoq[0] & ~3)
#define user_stack_pointer(regs) ((regs)->gr[30]) #define user_stack_pointer(regs) ((regs)->gr[30])
unsigned long profile_pc(struct pt_regs *); unsigned long profile_pc(struct pt_regs *);

View File

@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */ /* SPDX-License-Identifier: GPL-2.0 */
#ifndef ASM_PARISC_RUNWAY_H #ifndef ASM_PARISC_RUNWAY_H
#define ASM_PARISC_RUNWAY_H #define ASM_PARISC_RUNWAY_H
#ifdef __KERNEL__
/* declared in arch/parisc/kernel/setup.c */ /* declared in arch/parisc/kernel/setup.c */
extern struct proc_dir_entry * proc_runway_root; extern struct proc_dir_entry * proc_runway_root;
@ -9,5 +8,4 @@ extern struct proc_dir_entry * proc_runway_root;
#define RUNWAY_STATUS 0x10 #define RUNWAY_STATUS 0x10
#define RUNWAY_DEBUG 0x40 #define RUNWAY_DEBUG 0x40
#endif /* __KERNEL__ */
#endif /* ASM_PARISC_RUNWAY_H */ #endif /* ASM_PARISC_RUNWAY_H */

View File

@ -34,8 +34,23 @@ extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
#endif /* !ASSEMBLY */ #endif /* !ASSEMBLY */
#define raw_smp_processor_id() (current_thread_info()->cpu) /*
* This is particularly ugly: it appears we can't actually get the definition
* of task_struct here, but we need access to the CPU this task is running on.
* Instead of using task_struct we're using TASK_CPU which is extracted from
* asm-offsets.h by kbuild to get the current processor ID.
*
* This also needs to be safeguarded when building asm-offsets.s because at
* that time TASK_CPU is not defined yet. It could have been guarded by
* TASK_CPU itself, but we want the build to fail if TASK_CPU is missing
* when building something else than asm-offsets.s
*/
#ifdef GENERATING_ASM_OFFSETS
#define raw_smp_processor_id() (0)
#else
#include <asm/asm-offsets.h>
#define raw_smp_processor_id() (*(unsigned int *)((void *)current + TASK_CPU))
#endif
#else /* CONFIG_SMP */ #else /* CONFIG_SMP */
static inline void smp_send_all_nop(void) { return; } static inline void smp_send_all_nop(void) { return; }

View File

@ -2,30 +2,21 @@
#ifndef _ASM_PARISC_THREAD_INFO_H #ifndef _ASM_PARISC_THREAD_INFO_H
#define _ASM_PARISC_THREAD_INFO_H #define _ASM_PARISC_THREAD_INFO_H
#ifdef __KERNEL__
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/special_insns.h> #include <asm/special_insns.h>
struct thread_info { struct thread_info {
struct task_struct *task; /* main task structure */
unsigned long flags; /* thread_info flags (see TIF_*) */ unsigned long flags; /* thread_info flags (see TIF_*) */
__u32 cpu; /* current CPU */
int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */ int preempt_count; /* 0=premptable, <0=BUG; will also serve as bh-counter */
}; };
#define INIT_THREAD_INFO(tsk) \ #define INIT_THREAD_INFO(tsk) \
{ \ { \
.task = &tsk, \
.flags = 0, \ .flags = 0, \
.cpu = 0, \
.preempt_count = INIT_PREEMPT_COUNT, \ .preempt_count = INIT_PREEMPT_COUNT, \
} }
/* how to get the thread information struct from C */
#define current_thread_info() ((struct thread_info *)mfctl(30))
#endif /* !__ASSEMBLY */ #endif /* !__ASSEMBLY */
/* thread information allocation */ /* thread information allocation */
@ -57,6 +48,7 @@ struct thread_info {
#define TIF_BLOCKSTEP 10 /* branch stepping? */ #define TIF_BLOCKSTEP 10 /* branch stepping? */
#define TIF_SECCOMP 11 /* secure computing */ #define TIF_SECCOMP 11 /* secure computing */
#define TIF_SYSCALL_TRACEPOINT 12 /* syscall tracepoint instrumentation */ #define TIF_SYSCALL_TRACEPOINT 12 /* syscall tracepoint instrumentation */
#define TIF_NONBLOCK_WARNING 13 /* warned about wrong O_NONBLOCK usage */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
@ -87,6 +79,4 @@ struct thread_info {
# define is_32bit_task() (1) # define is_32bit_task() (1)
#endif #endif
#endif /* __KERNEL__ */
#endif /* _ASM_PARISC_THREAD_INFO_H */ #endif /* _ASM_PARISC_THREAD_INFO_H */

View File

@ -14,6 +14,7 @@ void parisc_terminate(char *msg, struct pt_regs *regs,
void die_if_kernel(char *str, struct pt_regs *regs, long err); void die_if_kernel(char *str, struct pt_regs *regs, long err);
/* mm/fault.c */ /* mm/fault.c */
unsigned long parisc_acctyp(unsigned long code, unsigned int inst);
const char *trap_name(unsigned long code); const char *trap_name(unsigned long code);
void do_page_fault(struct pt_regs *regs, unsigned long code, void do_page_fault(struct pt_regs *regs, unsigned long code,
unsigned long address); unsigned long address);

View File

@ -4,10 +4,8 @@
#include <asm-generic/unaligned.h> #include <asm-generic/unaligned.h>
#ifdef __KERNEL__
struct pt_regs; struct pt_regs;
void handle_unaligned(struct pt_regs *regs); void handle_unaligned(struct pt_regs *regs);
int check_unaligned(struct pt_regs *regs); int check_unaligned(struct pt_regs *regs);
#endif
#endif /* _ASM_PARISC_UNALIGNED_H */ #endif /* _ASM_PARISC_UNALIGNED_H */

View File

@ -398,8 +398,10 @@ struct zeropage {
/* int (*vec_rendz)(void); */ /* int (*vec_rendz)(void); */
unsigned int vec_rendz; unsigned int vec_rendz;
int vec_pow_fail_flen; int vec_pow_fail_flen;
int vec_pad[10]; int vec_pad0[3];
unsigned int vec_toc_hi;
int vec_pad1[6];
/* [0x040] reserved processor dependent */ /* [0x040] reserved processor dependent */
int pad0[112]; int pad0[112];
@ -689,6 +691,28 @@ struct pdc_hpmc_pim_20 { /* PDC_PIM */
unsigned long long fr[32]; unsigned long long fr[32];
}; };
struct pdc_toc_pim_11 {
unsigned int gr[32];
unsigned int cr[32];
unsigned int sr[8];
unsigned int iasq_back;
unsigned int iaoq_back;
unsigned int check_type;
unsigned int hversion;
unsigned int cpu_state;
};
struct pdc_toc_pim_20 {
unsigned long long gr[32];
unsigned long long cr[32];
unsigned long long sr[8];
unsigned long long iasq_back;
unsigned long long iaoq_back;
unsigned int check_type;
unsigned int hversion;
unsigned int cpu_state;
};
#endif /* !defined(__ASSEMBLY__) */ #endif /* !defined(__ASSEMBLY__) */
#endif /* _UAPI_PARISC_PDC_H */ #endif /* _UAPI_PARISC_PDC_H */

View File

@ -39,3 +39,4 @@ obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_KEXEC_CORE) += kexec.o relocate_kernel.o obj-$(CONFIG_KEXEC_CORE) += kexec.o relocate_kernel.o
obj-$(CONFIG_KEXEC_FILE) += kexec_file.o obj-$(CONFIG_KEXEC_FILE) += kexec_file.o
obj-$(CONFIG_TOC) += toc.o toc_asm.o

View File

@ -14,6 +14,8 @@
* Copyright (C) 2003 James Bottomley <jejb at parisc-linux.org> * Copyright (C) 2003 James Bottomley <jejb at parisc-linux.org>
*/ */
#define GENERATING_ASM_OFFSETS /* asm/smp.h */
#include <linux/types.h> #include <linux/types.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/thread_info.h> #include <linux/thread_info.h>
@ -22,18 +24,12 @@
#include <linux/kbuild.h> #include <linux/kbuild.h>
#include <linux/pgtable.h> #include <linux/pgtable.h>
#include <asm/assembly.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/pdc.h> #include <asm/pdc.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#ifdef CONFIG_64BIT
#define FRAME_SIZE 128
#else
#define FRAME_SIZE 64
#endif
#define FRAME_ALIGN 64
/* Add FRAME_SIZE to the size x and align it to y. All definitions /* Add FRAME_SIZE to the size x and align it to y. All definitions
* that use align_frame will include space for a frame. * that use align_frame will include space for a frame.
*/ */
@ -41,13 +37,11 @@
int main(void) int main(void)
{ {
DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, stack)); DEFINE(TASK_TI_FLAGS, offsetof(struct task_struct, thread_info.flags));
DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags)); DEFINE(TASK_STACK, offsetof(struct task_struct, stack));
DEFINE(TASK_SIGPENDING, offsetof(struct task_struct, pending)); #ifdef CONFIG_SMP
DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace)); DEFINE(TASK_CPU, offsetof(struct task_struct, cpu));
DEFINE(TASK_MM, offsetof(struct task_struct, mm)); #endif
DEFINE(TASK_PERSONALITY, offsetof(struct task_struct, personality));
DEFINE(TASK_PID, offsetof(struct task_struct, pid));
BLANK(); BLANK();
DEFINE(TASK_REGS, offsetof(struct task_struct, thread.regs)); DEFINE(TASK_REGS, offsetof(struct task_struct, thread.regs));
DEFINE(TASK_PT_PSW, offsetof(struct task_struct, thread.regs.gr[ 0])); DEFINE(TASK_PT_PSW, offsetof(struct task_struct, thread.regs.gr[ 0]));
@ -135,10 +129,6 @@ int main(void)
DEFINE(TASK_PT_ISR, offsetof(struct task_struct, thread.regs.isr)); DEFINE(TASK_PT_ISR, offsetof(struct task_struct, thread.regs.isr));
DEFINE(TASK_PT_IOR, offsetof(struct task_struct, thread.regs.ior)); DEFINE(TASK_PT_IOR, offsetof(struct task_struct, thread.regs.ior));
BLANK(); BLANK();
DEFINE(TASK_SZ, sizeof(struct task_struct));
/* TASK_SZ_ALGN includes space for a stack frame. */
DEFINE(TASK_SZ_ALGN, align_frame(sizeof(struct task_struct), FRAME_ALIGN));
BLANK();
DEFINE(PT_PSW, offsetof(struct pt_regs, gr[ 0])); DEFINE(PT_PSW, offsetof(struct pt_regs, gr[ 0]));
DEFINE(PT_GR1, offsetof(struct pt_regs, gr[ 1])); DEFINE(PT_GR1, offsetof(struct pt_regs, gr[ 1]));
DEFINE(PT_GR2, offsetof(struct pt_regs, gr[ 2])); DEFINE(PT_GR2, offsetof(struct pt_regs, gr[ 2]));
@ -223,17 +213,11 @@ int main(void)
DEFINE(PT_IIR, offsetof(struct pt_regs, iir)); DEFINE(PT_IIR, offsetof(struct pt_regs, iir));
DEFINE(PT_ISR, offsetof(struct pt_regs, isr)); DEFINE(PT_ISR, offsetof(struct pt_regs, isr));
DEFINE(PT_IOR, offsetof(struct pt_regs, ior)); DEFINE(PT_IOR, offsetof(struct pt_regs, ior));
DEFINE(PT_SIZE, sizeof(struct pt_regs));
/* PT_SZ_ALGN includes space for a stack frame. */ /* PT_SZ_ALGN includes space for a stack frame. */
DEFINE(PT_SZ_ALGN, align_frame(sizeof(struct pt_regs), FRAME_ALIGN)); DEFINE(PT_SZ_ALGN, align_frame(sizeof(struct pt_regs), FRAME_ALIGN));
BLANK(); BLANK();
DEFINE(TI_TASK, offsetof(struct thread_info, task));
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); DEFINE(TI_PRE_COUNT, offsetof(struct task_struct, thread_info.preempt_count));
DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
DEFINE(THREAD_SZ, sizeof(struct thread_info));
/* THREAD_SZ_ALGN includes space for a stack frame. */
DEFINE(THREAD_SZ_ALGN, align_frame(sizeof(struct thread_info), FRAME_ALIGN));
BLANK(); BLANK();
DEFINE(ICACHE_BASE, offsetof(struct pdc_cache_info, ic_base)); DEFINE(ICACHE_BASE, offsetof(struct pdc_cache_info, ic_base));
DEFINE(ICACHE_STRIDE, offsetof(struct pdc_cache_info, ic_stride)); DEFINE(ICACHE_STRIDE, offsetof(struct pdc_cache_info, ic_stride));

View File

@ -543,10 +543,33 @@ static inline pte_t *get_ptep(pgd_t *pgd, unsigned long addr)
return ptep; return ptep;
} }
static void flush_cache_pages(struct vm_area_struct *vma, struct mm_struct *mm,
unsigned long start, unsigned long end)
{
unsigned long addr, pfn;
pte_t *ptep;
for (addr = start; addr < end; addr += PAGE_SIZE) {
ptep = get_ptep(mm->pgd, addr);
if (ptep) {
pfn = pte_pfn(*ptep);
flush_cache_page(vma, addr, pfn);
}
}
}
static void flush_user_cache_tlb(struct vm_area_struct *vma,
unsigned long start, unsigned long end)
{
flush_user_dcache_range_asm(start, end);
if (vma->vm_flags & VM_EXEC)
flush_user_icache_range_asm(start, end);
flush_tlb_range(vma, start, end);
}
void flush_cache_mm(struct mm_struct *mm) void flush_cache_mm(struct mm_struct *mm)
{ {
struct vm_area_struct *vma; struct vm_area_struct *vma;
pgd_t *pgd;
/* Flushing the whole cache on each cpu takes forever on /* Flushing the whole cache on each cpu takes forever on
rp3440, etc. So, avoid it if the mm isn't too big. */ rp3440, etc. So, avoid it if the mm isn't too big. */
@ -558,45 +581,22 @@ void flush_cache_mm(struct mm_struct *mm)
return; return;
} }
preempt_disable();
if (mm->context == mfsp(3)) { if (mm->context == mfsp(3)) {
for (vma = mm->mmap; vma; vma = vma->vm_next) { for (vma = mm->mmap; vma; vma = vma->vm_next)
flush_user_dcache_range_asm(vma->vm_start, vma->vm_end); flush_user_cache_tlb(vma, vma->vm_start, vma->vm_end);
if (vma->vm_flags & VM_EXEC) preempt_enable();
flush_user_icache_range_asm(vma->vm_start, vma->vm_end);
flush_tlb_range(vma, vma->vm_start, vma->vm_end);
}
return; return;
} }
pgd = mm->pgd; for (vma = mm->mmap; vma; vma = vma->vm_next)
for (vma = mm->mmap; vma; vma = vma->vm_next) { flush_cache_pages(vma, mm, vma->vm_start, vma->vm_end);
unsigned long addr; preempt_enable();
for (addr = vma->vm_start; addr < vma->vm_end;
addr += PAGE_SIZE) {
unsigned long pfn;
pte_t *ptep = get_ptep(pgd, addr);
if (!ptep)
continue;
pfn = pte_pfn(*ptep);
if (!pfn_valid(pfn))
continue;
if (unlikely(mm->context)) {
flush_tlb_page(vma, addr);
__flush_cache_page(vma, addr, PFN_PHYS(pfn));
} else {
__purge_cache_page(vma, addr, PFN_PHYS(pfn));
}
}
}
} }
void flush_cache_range(struct vm_area_struct *vma, void flush_cache_range(struct vm_area_struct *vma,
unsigned long start, unsigned long end) unsigned long start, unsigned long end)
{ {
pgd_t *pgd;
unsigned long addr;
if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) && if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
end - start >= parisc_cache_flush_threshold) { end - start >= parisc_cache_flush_threshold) {
if (vma->vm_mm->context) if (vma->vm_mm->context)
@ -605,30 +605,15 @@ void flush_cache_range(struct vm_area_struct *vma,
return; return;
} }
preempt_disable();
if (vma->vm_mm->context == mfsp(3)) { if (vma->vm_mm->context == mfsp(3)) {
flush_user_dcache_range_asm(start, end); flush_user_cache_tlb(vma, start, end);
if (vma->vm_flags & VM_EXEC) preempt_enable();
flush_user_icache_range_asm(start, end);
flush_tlb_range(vma, start, end);
return; return;
} }
pgd = vma->vm_mm->pgd; flush_cache_pages(vma, vma->vm_mm, vma->vm_start, vma->vm_end);
for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) { preempt_enable();
unsigned long pfn;
pte_t *ptep = get_ptep(pgd, addr);
if (!ptep)
continue;
pfn = pte_pfn(*ptep);
if (pfn_valid(pfn)) {
if (unlikely(vma->vm_mm->context)) {
flush_tlb_page(vma, addr);
__flush_cache_page(vma, addr, PFN_PHYS(pfn));
} else {
__purge_cache_page(vma, addr, PFN_PHYS(pfn));
}
}
}
} }
void void

View File

@ -51,30 +51,6 @@
extrd,u \spc,(64 - (SPACEID_SHIFT)),32,\prot extrd,u \spc,(64 - (SPACEID_SHIFT)),32,\prot
.endm .endm
#endif #endif
/* Switch to virtual mapping, trashing only %r1 */
.macro virt_map
/* pcxt_ssm_bug */
rsm PSW_SM_I, %r0 /* barrier for "Relied upon Translation */
mtsp %r0, %sr4
mtsp %r0, %sr5
mtsp %r0, %sr6
tovirt_r1 %r29
load32 KERNEL_PSW, %r1
rsm PSW_SM_QUIET,%r0 /* second "heavy weight" ctl op */
mtctl %r0, %cr17 /* Clear IIASQ tail */
mtctl %r0, %cr17 /* Clear IIASQ head */
mtctl %r1, %ipsw
load32 4f, %r1
mtctl %r1, %cr18 /* Set IIAOQ tail */
ldo 4(%r1), %r1
mtctl %r1, %cr18 /* Set IIAOQ head */
rfir
nop
4:
.endm
/* /*
* The "get_stack" macros are responsible for determining the * The "get_stack" macros are responsible for determining the
* kernel stack value. * kernel stack value.
@ -87,8 +63,8 @@
* Need to set up a kernel stack, so call the * Need to set up a kernel stack, so call the
* get_stack_use_cr30 macro to set up a pointer * get_stack_use_cr30 macro to set up a pointer
* to the pt_regs structure contained within the * to the pt_regs structure contained within the
* task pointer pointed to by cr30. Set the stack * task pointer pointed to by cr30. Load the stack
* pointer to point to the end of the task structure. * pointer from the task structure.
* *
* Note that we use shadowed registers for temps until * Note that we use shadowed registers for temps until
* we can save %r26 and %r29. %r26 is used to preserve * we can save %r26 and %r29. %r26 is used to preserve
@ -100,8 +76,6 @@
* or handle_interruption. %r29 is used to hold a pointer * or handle_interruption. %r29 is used to hold a pointer
* the register save area, and once again, it needs to * the register save area, and once again, it needs to
* be a non-shadowed register so that it survives the rfir. * be a non-shadowed register so that it survives the rfir.
*
* N.B. TASK_SZ_ALGN and PT_SZ_ALGN include space for a stack frame.
*/ */
.macro get_stack_use_cr30 .macro get_stack_use_cr30
@ -110,12 +84,11 @@
copy %r30, %r17 copy %r30, %r17
mfctl %cr30, %r1 mfctl %cr30, %r1
ldo THREAD_SZ_ALGN(%r1), %r30 tophys %r1,%r9 /* task_struct */
mtsp %r0,%sr7 LDREG TASK_STACK(%r9),%r30
ldo PT_SZ_ALGN(%r30),%r30
mtsp %r0,%sr7 /* clear sr7 after kernel stack was set! */
mtsp %r16,%sr3 mtsp %r16,%sr3
tophys %r1,%r9
LDREG TI_TASK(%r9), %r1 /* thread_info -> task_struct */
tophys %r1,%r9
ldo TASK_REGS(%r9),%r9 ldo TASK_REGS(%r9),%r9
STREG %r17,PT_GR30(%r9) STREG %r17,PT_GR30(%r9)
STREG %r29,PT_GR29(%r9) STREG %r29,PT_GR29(%r9)
@ -757,7 +730,7 @@ ENTRY(ret_from_kernel_thread)
BL schedule_tail, %r2 BL schedule_tail, %r2
nop nop
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 mfctl %cr30,%r1 /* task_struct */
LDREG TASK_PT_GR25(%r1), %r26 LDREG TASK_PT_GR25(%r1), %r26
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
LDREG TASK_PT_GR27(%r1), %r27 LDREG TASK_PT_GR27(%r1), %r27
@ -788,7 +761,6 @@ ENTRY_CFI(_switch_to)
STREG %r30, TASK_PT_KSP(%r26) STREG %r30, TASK_PT_KSP(%r26)
LDREG TASK_PT_KSP(%r25), %r30 LDREG TASK_PT_KSP(%r25), %r30
LDREG TASK_THREAD_INFO(%r25), %r25
bv %r0(%r2) bv %r0(%r2)
mtctl %r25,%cr30 mtctl %r25,%cr30
@ -819,17 +791,16 @@ ENDPROC_CFI(_switch_to)
.align PAGE_SIZE .align PAGE_SIZE
ENTRY_CFI(syscall_exit_rfi) ENTRY_CFI(syscall_exit_rfi)
mfctl %cr30,%r16 mfctl %cr30,%r16 /* task_struct */
LDREG TI_TASK(%r16), %r16 /* thread_info -> task_struct */
ldo TASK_REGS(%r16),%r16 ldo TASK_REGS(%r16),%r16
/* Force iaoq to userspace, as the user has had access to our current /* Force iaoq to userspace, as the user has had access to our current
* context via sigcontext. Also Filter the PSW for the same reason. * context via sigcontext. Also Filter the PSW for the same reason.
*/ */
LDREG PT_IAOQ0(%r16),%r19 LDREG PT_IAOQ0(%r16),%r19
depi 3,31,2,%r19 depi PRIV_USER,31,2,%r19
STREG %r19,PT_IAOQ0(%r16) STREG %r19,PT_IAOQ0(%r16)
LDREG PT_IAOQ1(%r16),%r19 LDREG PT_IAOQ1(%r16),%r19
depi 3,31,2,%r19 depi PRIV_USER,31,2,%r19
STREG %r19,PT_IAOQ1(%r16) STREG %r19,PT_IAOQ1(%r16)
LDREG PT_PSW(%r16),%r19 LDREG PT_PSW(%r16),%r19
load32 USER_PSW_MASK,%r1 load32 USER_PSW_MASK,%r1
@ -865,14 +836,14 @@ ENTRY_CFI(syscall_exit_rfi)
ENTRY(intr_return) ENTRY(intr_return)
/* check for reschedule */ /* check for reschedule */
mfctl %cr30,%r1 mfctl %cr30,%r1
LDREG TI_FLAGS(%r1),%r19 /* sched.h: TIF_NEED_RESCHED */ LDREG TASK_TI_FLAGS(%r1),%r19 /* sched.h: TIF_NEED_RESCHED */
bb,<,n %r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */ bb,<,n %r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */
.import do_notify_resume,code .import do_notify_resume,code
intr_check_sig: intr_check_sig:
/* As above */ /* As above */
mfctl %cr30,%r1 mfctl %cr30,%r1
LDREG TI_FLAGS(%r1),%r19 LDREG TASK_TI_FLAGS(%r1),%r19
ldi (_TIF_USER_WORK_MASK & ~_TIF_NEED_RESCHED), %r20 ldi (_TIF_USER_WORK_MASK & ~_TIF_NEED_RESCHED), %r20
and,COND(<>) %r19, %r20, %r0 and,COND(<>) %r19, %r20, %r0
b,n intr_restore /* skip past if we've nothing to do */ b,n intr_restore /* skip past if we've nothing to do */
@ -974,8 +945,8 @@ intr_do_preempt:
/* current_thread_info()->preempt_count */ /* current_thread_info()->preempt_count */
mfctl %cr30, %r1 mfctl %cr30, %r1
LDREG TI_PRE_COUNT(%r1), %r19 ldw TI_PRE_COUNT(%r1), %r19
cmpib,COND(<>) 0, %r19, intr_restore /* if preempt_count > 0 */ cmpib,<> 0, %r19, intr_restore /* if preempt_count > 0 */
nop /* prev insn branched backwards */ nop /* prev insn branched backwards */
/* check if we interrupted a critical path */ /* check if we interrupted a critical path */
@ -1716,7 +1687,7 @@ dtlb_fault:
.macro fork_like name .macro fork_like name
ENTRY_CFI(sys_\name\()_wrapper) ENTRY_CFI(sys_\name\()_wrapper)
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 mfctl %cr30,%r1
ldo TASK_REGS(%r1),%r1 ldo TASK_REGS(%r1),%r1
reg_save %r1 reg_save %r1
mfctl %cr27, %r28 mfctl %cr27, %r28
@ -1736,7 +1707,7 @@ ENTRY(child_return)
BL schedule_tail, %r2 BL schedule_tail, %r2
nop nop
finish_child_return: finish_child_return:
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30), %r1 mfctl %cr30,%r1
ldo TASK_REGS(%r1),%r1 /* get pt regs */ ldo TASK_REGS(%r1),%r1 /* get pt regs */
LDREG PT_CR27(%r1), %r3 LDREG PT_CR27(%r1), %r3
@ -1747,7 +1718,7 @@ finish_child_return:
END(child_return) END(child_return)
ENTRY_CFI(sys_rt_sigreturn_wrapper) ENTRY_CFI(sys_rt_sigreturn_wrapper)
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 mfctl %cr30,%r26
ldo TASK_REGS(%r26),%r26 /* get pt regs */ ldo TASK_REGS(%r26),%r26 /* get pt regs */
/* Don't save regs, we are going to restore them from sigcontext. */ /* Don't save regs, we are going to restore them from sigcontext. */
STREG %r2, -RP_OFFSET(%r30) STREG %r2, -RP_OFFSET(%r30)
@ -1764,7 +1735,7 @@ ENTRY_CFI(sys_rt_sigreturn_wrapper)
LDREG -RP_OFFSET(%r30), %r2 LDREG -RP_OFFSET(%r30), %r2
/* FIXME: I think we need to restore a few more things here. */ /* FIXME: I think we need to restore a few more things here. */
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 mfctl %cr30,%r1
ldo TASK_REGS(%r1),%r1 /* get pt regs */ ldo TASK_REGS(%r1),%r1 /* get pt regs */
reg_restore %r1 reg_restore %r1
@ -1783,9 +1754,7 @@ ENTRY(syscall_exit)
*/ */
/* save return value now */ /* save return value now */
mfctl %cr30, %r1 mfctl %cr30, %r1
LDREG TI_TASK(%r1),%r1
STREG %r28,TASK_PT_GR28(%r1) STREG %r28,TASK_PT_GR28(%r1)
/* Seems to me that dp could be wrong here, if the syscall involved /* Seems to me that dp could be wrong here, if the syscall involved
@ -1796,13 +1765,14 @@ ENTRY(syscall_exit)
syscall_check_resched: syscall_check_resched:
/* check for reschedule */ /* check for reschedule */
mfctl %cr30,%r19
LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19 /* long */ LDREG TASK_TI_FLAGS(%r19),%r19 /* long */
bb,<,n %r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */ bb,<,n %r19, 31-TIF_NEED_RESCHED, syscall_do_resched /* forward */
.import do_signal,code .import do_signal,code
syscall_check_sig: syscall_check_sig:
LDREG TI_FLAGS-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r19 mfctl %cr30,%r19
LDREG TASK_TI_FLAGS(%r19),%r19
ldi (_TIF_USER_WORK_MASK & ~_TIF_NEED_RESCHED), %r26 ldi (_TIF_USER_WORK_MASK & ~_TIF_NEED_RESCHED), %r26
and,COND(<>) %r19, %r26, %r0 and,COND(<>) %r19, %r26, %r0
b,n syscall_restore /* skip past if we've nothing to do */ b,n syscall_restore /* skip past if we've nothing to do */
@ -1813,7 +1783,7 @@ syscall_do_signal:
* consistent with all the relevant state of the process * consistent with all the relevant state of the process
* before the syscall. We need to verify this. * before the syscall. We need to verify this.
*/ */
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 mfctl %cr30,%r1
ldo TASK_REGS(%r1), %r26 /* struct pt_regs *regs */ ldo TASK_REGS(%r1), %r26 /* struct pt_regs *regs */
reg_save %r26 reg_save %r26
@ -1824,17 +1794,17 @@ syscall_do_signal:
BL do_notify_resume,%r2 BL do_notify_resume,%r2
ldi 1, %r25 /* long in_syscall = 1 */ ldi 1, %r25 /* long in_syscall = 1 */
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 mfctl %cr30,%r1
ldo TASK_REGS(%r1), %r20 /* reload pt_regs */ ldo TASK_REGS(%r1), %r20 /* reload pt_regs */
reg_restore %r20 reg_restore %r20
b,n syscall_check_sig b,n syscall_check_sig
syscall_restore: syscall_restore:
LDREG TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 mfctl %cr30,%r1
/* Are we being ptraced? */ /* Are we being ptraced? */
ldw TASK_FLAGS(%r1),%r19 LDREG TASK_TI_FLAGS(%r1),%r19
ldi _TIF_SYSCALL_TRACE_MASK,%r2 ldi _TIF_SYSCALL_TRACE_MASK,%r2
and,COND(=) %r19,%r2,%r0 and,COND(=) %r19,%r2,%r0
b,n syscall_restore_rfi b,n syscall_restore_rfi
@ -1873,7 +1843,7 @@ syscall_restore:
mtsp %r1,%sr5 /* Restore sr5 */ mtsp %r1,%sr5 /* Restore sr5 */
mtsp %r1,%sr6 /* Restore sr6 */ mtsp %r1,%sr6 /* Restore sr6 */
depi 3,31,2,%r31 /* ensure return to user mode. */ depi PRIV_USER,31,2,%r31 /* ensure return to user mode. */
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
/* decide whether to reset the wide mode bit /* decide whether to reset the wide mode bit
@ -1949,7 +1919,7 @@ syscall_restore_rfi:
STREG %r0,TASK_PT_SR2(%r1) STREG %r0,TASK_PT_SR2(%r1)
LDREG TASK_PT_GR31(%r1),%r2 LDREG TASK_PT_GR31(%r1),%r2
depi 3,31,2,%r2 /* ensure return to user mode. */ depi PRIV_USER,31,2,%r2 /* ensure return to user mode. */
STREG %r2,TASK_PT_IAOQ0(%r1) STREG %r2,TASK_PT_IAOQ0(%r1)
ldo 4(%r2),%r2 ldo 4(%r2),%r2
STREG %r2,TASK_PT_IAOQ1(%r1) STREG %r2,TASK_PT_IAOQ1(%r1)
@ -1958,10 +1928,10 @@ syscall_restore_rfi:
pt_regs_ok: pt_regs_ok:
LDREG TASK_PT_IAOQ0(%r1),%r2 LDREG TASK_PT_IAOQ0(%r1),%r2
depi 3,31,2,%r2 /* ensure return to user mode. */ depi PRIV_USER,31,2,%r2 /* ensure return to user mode. */
STREG %r2,TASK_PT_IAOQ0(%r1) STREG %r2,TASK_PT_IAOQ0(%r1)
LDREG TASK_PT_IAOQ1(%r1),%r2 LDREG TASK_PT_IAOQ1(%r1),%r2
depi 3,31,2,%r2 depi PRIV_USER,31,2,%r2
STREG %r2,TASK_PT_IAOQ1(%r1) STREG %r2,TASK_PT_IAOQ1(%r1)
b intr_restore b intr_restore
copy %r25,%r16 copy %r25,%r16

View File

@ -1061,6 +1061,38 @@ int pdc_mem_pdt_read_entries(struct pdc_mem_read_pdt *pret,
return retval; return retval;
} }
/**
* pdc_pim_toc11 - Fetch TOC PIM 1.1 data from firmware.
* @ret: pointer to return buffer
*/
int pdc_pim_toc11(struct pdc_toc_pim_11 *ret)
{
int retval;
unsigned long flags;
spin_lock_irqsave(&pdc_lock, flags);
retval = mem_pdc_call(PDC_PIM, PDC_PIM_TOC, __pa(pdc_result),
__pa(ret), sizeof(*ret));
spin_unlock_irqrestore(&pdc_lock, flags);
return retval;
}
/**
* pdc_pim_toc20 - Fetch TOC PIM 2.0 data from firmware.
* @ret: pointer to return buffer
*/
int pdc_pim_toc20(struct pdc_toc_pim_20 *ret)
{
int retval;
unsigned long flags;
spin_lock_irqsave(&pdc_lock, flags);
retval = mem_pdc_call(PDC_PIM, PDC_PIM_TOC, __pa(pdc_result),
__pa(ret), sizeof(*ret));
spin_unlock_irqrestore(&pdc_lock, flags);
return retval;
}
/** /**
* pdc_tod_set - Set the Time-Of-Day clock. * pdc_tod_set - Set the Time-Of-Day clock.
* @sec: The number of seconds since epoch. * @sec: The number of seconds since epoch.

View File

@ -15,6 +15,7 @@
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/kprobes.h> #include <linux/kprobes.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/jump_label.h>
#include <asm/assembly.h> #include <asm/assembly.h>
#include <asm/sections.h> #include <asm/sections.h>
@ -24,6 +25,8 @@
#define __hot __section(".text.hot") #define __hot __section(".text.hot")
#ifdef CONFIG_FUNCTION_GRAPH_TRACER #ifdef CONFIG_FUNCTION_GRAPH_TRACER
static DEFINE_STATIC_KEY_FALSE(ftrace_graph_enable);
/* /*
* Hook the return address and push it in the stack of return addrs * Hook the return address and push it in the stack of return addrs
* in current thread info. * in current thread info.
@ -48,25 +51,19 @@ static void __hot prepare_ftrace_return(unsigned long *parent,
} }
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
static ftrace_func_t ftrace_func;
void notrace __hot ftrace_function_trampoline(unsigned long parent, void notrace __hot ftrace_function_trampoline(unsigned long parent,
unsigned long self_addr, unsigned long self_addr,
unsigned long org_sp_gr3, unsigned long org_sp_gr3,
struct ftrace_regs *fregs) struct ftrace_regs *fregs)
{ {
#ifndef CONFIG_DYNAMIC_FTRACE
extern ftrace_func_t ftrace_trace_function;
#endif
extern struct ftrace_ops *function_trace_op; extern struct ftrace_ops *function_trace_op;
if (function_trace_op->flags & FTRACE_OPS_FL_ENABLED && ftrace_func(self_addr, parent, function_trace_op, fregs);
ftrace_trace_function != ftrace_stub)
ftrace_trace_function(self_addr, parent,
function_trace_op, fregs);
#ifdef CONFIG_FUNCTION_GRAPH_TRACER #ifdef CONFIG_FUNCTION_GRAPH_TRACER
if (dereference_function_descriptor(ftrace_graph_return) != if (static_branch_unlikely(&ftrace_graph_enable)) {
dereference_function_descriptor(ftrace_stub) ||
ftrace_graph_entry != ftrace_graph_entry_stub) {
unsigned long *parent_rp; unsigned long *parent_rp;
/* calculate pointer to %rp in stack */ /* calculate pointer to %rp in stack */
@ -84,11 +81,13 @@ void notrace __hot ftrace_function_trampoline(unsigned long parent,
#ifdef CONFIG_FUNCTION_GRAPH_TRACER #ifdef CONFIG_FUNCTION_GRAPH_TRACER
int ftrace_enable_ftrace_graph_caller(void) int ftrace_enable_ftrace_graph_caller(void)
{ {
static_key_enable(&ftrace_graph_enable.key);
return 0; return 0;
} }
int ftrace_disable_ftrace_graph_caller(void) int ftrace_disable_ftrace_graph_caller(void)
{ {
static_key_enable(&ftrace_graph_enable.key);
return 0; return 0;
} }
#endif #endif
@ -99,8 +98,10 @@ int __init ftrace_dyn_arch_init(void)
{ {
return 0; return 0;
} }
int ftrace_update_ftrace_func(ftrace_func_t func) int ftrace_update_ftrace_func(ftrace_func_t func)
{ {
ftrace_func = func;
return 0; return 0;
} }

View File

@ -35,7 +35,8 @@ END(boot_args)
__HEAD __HEAD
.align 4 .align 4
.import init_thread_union,data .import init_task,data
.import init_stack,data
.import fault_vector_20,code /* IVA parisc 2.0 32 bit */ .import fault_vector_20,code /* IVA parisc 2.0 32 bit */
#ifndef CONFIG_64BIT #ifndef CONFIG_64BIT
.import fault_vector_11,code /* IVA parisc 1.1 32 bit */ .import fault_vector_11,code /* IVA parisc 1.1 32 bit */
@ -123,12 +124,12 @@ $pgt_fill_loop:
load32 start_parisc,%r11 load32 start_parisc,%r11
/* And the initial task pointer */ /* And the initial task pointer */
load32 init_thread_union,%r6 load32 init_task,%r6
mtctl %r6,%cr30 mtctl %r6,%cr30
/* And the stack pointer too */ /* And the stack pointer too */
ldo THREAD_SZ_ALGN(%r6),%sp load32 init_stack,%sp
tophys_r1 %sp
#if defined(CONFIG_64BIT) && defined(CONFIG_FUNCTION_TRACER) #if defined(CONFIG_64BIT) && defined(CONFIG_FUNCTION_TRACER)
.import _mcount,data .import _mcount,data
/* initialize mcount FPTR */ /* initialize mcount FPTR */
@ -186,12 +187,11 @@ common_stext:
#endif /*CONFIG_SMP*/ #endif /*CONFIG_SMP*/
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
tophys_r1 %sp mfctl %cr30,%r6 /* PCX-W2 firmware bug */
tophys_r1 %r6
/* Save the rfi target address */ /* Save the rfi target address */
ldd TI_TASK-THREAD_SZ_ALGN(%sp), %r10 STREG %r11, TASK_PT_GR11(%r6)
tophys_r1 %r10
std %r11, TASK_PT_GR11(%r10)
/* Switch to wide mode Superdome doesn't support narrow PDC /* Switch to wide mode Superdome doesn't support narrow PDC
** calls. ** calls.
*/ */
@ -206,7 +206,6 @@ common_stext:
** Someday, palo might not do this for the Monarch either. ** Someday, palo might not do this for the Monarch either.
*/ */
2: 2:
mfctl %cr30,%r6 /* PCX-W2 firmware bug */
ldo PDC_PSW(%r0),%arg0 /* 21 */ ldo PDC_PSW(%r0),%arg0 /* 21 */
ldo PDC_PSW_SET_DEFAULTS(%r0),%arg1 /* 2 */ ldo PDC_PSW_SET_DEFAULTS(%r0),%arg1 /* 2 */
@ -216,13 +215,9 @@ common_stext:
copy %r0,%arg3 copy %r0,%arg3
stext_pdc_ret: stext_pdc_ret:
LDREG TASK_PT_GR11(%r6), %r11
tovirt_r1 %r6
mtctl %r6,%cr30 /* restore task thread info */ mtctl %r6,%cr30 /* restore task thread info */
/* restore rfi target address*/
ldd TI_TASK-THREAD_SZ_ALGN(%sp), %r10
tophys_r1 %r10
ldd TASK_PT_GR11(%r10), %r11
tovirt_r1 %sp
#endif #endif
/* PARANOID: clear user scratch/user space SR's */ /* PARANOID: clear user scratch/user space SR's */
@ -287,7 +282,9 @@ aligned_rfi:
load32 KERNEL_PSW,%r10 load32 KERNEL_PSW,%r10
mtctl %r10,%ipsw mtctl %r10,%ipsw
tovirt_r1 %sp
/* Jump through hyperspace to Virt Mode */ /* Jump through hyperspace to Virt Mode */
rfi rfi
nop nop
@ -343,12 +340,13 @@ smp_slave_stext:
#endif #endif
/* Initialize the SP - monarch sets up smp_init_current_idle_task */ /* Initialize the SP - monarch sets up smp_init_current_idle_task */
load32 PA(smp_init_current_idle_task),%sp load32 PA(smp_init_current_idle_task),%r6
LDREG 0(%sp),%sp /* load task address */ LDREG 0(%r6),%r6
mtctl %r6,%cr30
tophys_r1 %r6
LDREG TASK_STACK(%r6),%sp
tophys_r1 %sp tophys_r1 %sp
LDREG TASK_THREAD_INFO(%sp),%sp ldo FRAME_SIZE(%sp),%sp
mtctl %sp,%cr30 /* store in cr30 */
ldo THREAD_SZ_ALGN(%sp),%sp
/* point CPU to kernel page tables */ /* point CPU to kernel page tables */
load32 PA(swapper_pg_dir),%r4 load32 PA(swapper_pg_dir),%r4

View File

@ -15,6 +15,7 @@
#include <linux/kernel_stat.h> #include <linux/kernel_stat.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/sched/task_stack.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/softirq_stack.h> #include <asm/softirq_stack.h>
@ -399,8 +400,7 @@ static inline void stack_overflow_check(struct pt_regs *regs)
#ifdef CONFIG_DEBUG_STACKOVERFLOW #ifdef CONFIG_DEBUG_STACKOVERFLOW
#define STACK_MARGIN (256*6) #define STACK_MARGIN (256*6)
/* Our stack starts directly behind the thread_info struct. */ unsigned long stack_start = (unsigned long) task_stack_page(current);
unsigned long stack_start = (unsigned long) current_thread_info();
unsigned long sp = regs->gr[30]; unsigned long sp = regs->gr[30];
unsigned long stack_usage; unsigned long stack_usage;
unsigned int *last_usage; unsigned int *last_usage;
@ -476,7 +476,7 @@ static void execute_on_irq_stack(void *func, unsigned long param1)
union_ptr = &per_cpu(irq_stack_union, smp_processor_id()); union_ptr = &per_cpu(irq_stack_union, smp_processor_id());
irq_stack = (unsigned long) &union_ptr->stack; irq_stack = (unsigned long) &union_ptr->stack;
irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.slock), irq_stack = ALIGN(irq_stack + sizeof(irq_stack_union.slock),
64); /* align for stack frame usage */ FRAME_ALIGN); /* align for stack frame usage */
/* We may be called recursive. If we are already using the irq stack, /* We may be called recursive. If we are already using the irq stack,
* just continue to use it. Use spinlocks to serialize * just continue to use it. Use spinlocks to serialize

View File

@ -352,12 +352,10 @@ static int __init pdt_initcall(void)
if (pdt_type == PDT_NONE) if (pdt_type == PDT_NONE)
return -ENODEV; return -ENODEV;
kpdtd_task = kthread_create(pdt_mainloop, NULL, "kpdtd"); kpdtd_task = kthread_run(pdt_mainloop, NULL, "kpdtd");
if (IS_ERR(kpdtd_task)) if (IS_ERR(kpdtd_task))
return PTR_ERR(kpdtd_task); return PTR_ERR(kpdtd_task);
wake_up_process(kpdtd_task);
return 0; return 0;
} }

View File

@ -205,7 +205,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
/* Must exit via ret_from_kernel_thread in order /* Must exit via ret_from_kernel_thread in order
* to call schedule_tail() * to call schedule_tail()
*/ */
cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE; cregs->ksp = (unsigned long) stack + FRAME_SIZE + PT_SZ_ALGN;
cregs->kpc = (unsigned long) &ret_from_kernel_thread; cregs->kpc = (unsigned long) &ret_from_kernel_thread;
/* /*
* Copy function and argument to be called from * Copy function and argument to be called from
@ -228,7 +228,7 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
if (likely(usp)) if (likely(usp))
cregs->gr[30] = usp; cregs->gr[30] = usp;
} }
cregs->ksp = (unsigned long)stack + THREAD_SZ_ALGN + FRAME_SIZE; cregs->ksp = (unsigned long) stack + FRAME_SIZE;
cregs->kpc = (unsigned long) &child_return; cregs->kpc = (unsigned long) &child_return;
/* Setup thread TLS area */ /* Setup thread TLS area */

View File

@ -29,6 +29,7 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/ftrace.h> #include <linux/ftrace.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/kgdb.h>
#include <linux/atomic.h> #include <linux/atomic.h>
#include <asm/current.h> #include <asm/current.h>
@ -69,7 +70,10 @@ enum ipi_message_type {
IPI_CALL_FUNC, IPI_CALL_FUNC,
IPI_CPU_START, IPI_CPU_START,
IPI_CPU_STOP, IPI_CPU_STOP,
IPI_CPU_TEST IPI_CPU_TEST,
#ifdef CONFIG_KGDB
IPI_ENTER_KGDB,
#endif
}; };
@ -167,7 +171,12 @@ ipi_interrupt(int irq, void *dev_id)
case IPI_CPU_TEST: case IPI_CPU_TEST:
smp_debug(100, KERN_DEBUG "CPU%d is alive!\n", this_cpu); smp_debug(100, KERN_DEBUG "CPU%d is alive!\n", this_cpu);
break; break;
#ifdef CONFIG_KGDB
case IPI_ENTER_KGDB:
smp_debug(100, KERN_DEBUG "CPU%d ENTER_KGDB\n", this_cpu);
kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
break;
#endif
default: default:
printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n", printk(KERN_CRIT "Unknown IPI num on CPU%d: %lu\n",
this_cpu, which); this_cpu, which);
@ -219,13 +228,21 @@ static inline void
send_IPI_allbutself(enum ipi_message_type op) send_IPI_allbutself(enum ipi_message_type op)
{ {
int i; int i;
preempt_disable();
for_each_online_cpu(i) { for_each_online_cpu(i) {
if (i != smp_processor_id()) if (i != smp_processor_id())
send_IPI_single(i, op); send_IPI_single(i, op);
} }
preempt_enable();
} }
#ifdef CONFIG_KGDB
void kgdb_roundup_cpus(void)
{
send_IPI_allbutself(IPI_ENTER_KGDB);
}
#endif
inline void inline void
smp_send_stop(void) { send_IPI_allbutself(IPI_CPU_STOP); } smp_send_stop(void) { send_IPI_allbutself(IPI_CPU_STOP); }
@ -322,7 +339,7 @@ int smp_boot_one_cpu(int cpuid, struct task_struct *idle)
const struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpuid); const struct cpuinfo_parisc *p = &per_cpu(cpu_data, cpuid);
long timeout; long timeout;
task_thread_info(idle)->cpu = cpuid; idle->cpu = cpuid;
/* Let _start know what logical CPU we're booting /* Let _start know what logical CPU we're booting
** (offset into init_tasks[],cpu_data[]) ** (offset into init_tasks[],cpu_data[])

View File

@ -2,45 +2,41 @@
/* /*
* Stack trace management functions * Stack trace management functions
* *
* Copyright (C) 2009 Helge Deller <deller@gmx.de> * Copyright (C) 2009-2021 Helge Deller <deller@gmx.de>
* based on arch/x86/kernel/stacktrace.c by Ingo Molnar <mingo@redhat.com> * based on arch/x86/kernel/stacktrace.c by Ingo Molnar <mingo@redhat.com>
* and parisc unwind functions by Randolph Chung <tausq@debian.org> * and parisc unwind functions by Randolph Chung <tausq@debian.org>
* *
* TODO: Userspace stacktrace (CONFIG_USER_STACKTRACE_SUPPORT) * TODO: Userspace stacktrace (CONFIG_USER_STACKTRACE_SUPPORT)
*/ */
#include <linux/module.h>
#include <linux/stacktrace.h> #include <linux/stacktrace.h>
#include <asm/unwind.h> #include <asm/unwind.h>
static void dump_trace(struct task_struct *task, struct stack_trace *trace) static void notrace walk_stackframe(struct task_struct *task,
struct pt_regs *regs, bool (*fn)(void *, unsigned long), void *cookie)
{ {
struct unwind_frame_info info; struct unwind_frame_info info;
unwind_frame_init_task(&info, task, NULL); unwind_frame_init_task(&info, task, NULL);
while (1) {
/* unwind stack and save entries in stack_trace struct */
trace->nr_entries = 0;
while (trace->nr_entries < trace->max_entries) {
if (unwind_once(&info) < 0 || info.ip == 0) if (unwind_once(&info) < 0 || info.ip == 0)
break; break;
if (__kernel_text_address(info.ip)) if (__kernel_text_address(info.ip))
trace->entries[trace->nr_entries++] = info.ip; if (!fn(cookie, info.ip))
break;
} }
} }
/* void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie,
* Save stack-backtrace addresses into a stack_trace buffer. struct task_struct *task, struct pt_regs *regs)
*/
void save_stack_trace(struct stack_trace *trace)
{ {
dump_trace(current, trace); walk_stackframe(task, regs, consume_entry, cookie);
} }
EXPORT_SYMBOL_GPL(save_stack_trace);
void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) int arch_stack_walk_reliable(stack_trace_consume_fn consume_entry, void *cookie,
struct task_struct *task)
{ {
dump_trace(tsk, trace); walk_stackframe(task, NULL, consume_entry, cookie);
return 1;
} }
EXPORT_SYMBOL_GPL(save_stack_trace_tsk);

View File

@ -409,10 +409,12 @@ long parisc_personality(unsigned long personality)
static int FIX_O_NONBLOCK(int flags) static int FIX_O_NONBLOCK(int flags)
{ {
if (flags & O_NONBLOCK_MASK_OUT) { if ((flags & O_NONBLOCK_MASK_OUT) &&
struct task_struct *tsk = current; !test_thread_flag(TIF_NONBLOCK_WARNING)) {
pr_warn_once("%s(%d) uses a deprecated O_NONBLOCK value.\n", set_thread_flag(TIF_NONBLOCK_WARNING);
tsk->comm, tsk->pid); pr_warn("%s(%d) uses a deprecated O_NONBLOCK value."
" Please recompile with newer glibc.\n",
current->comm, current->pid);
} }
return flags & ~O_NONBLOCK_MASK_OUT; return flags & ~O_NONBLOCK_MASK_OUT;
} }

View File

@ -78,7 +78,7 @@ ENTRY(linux_gateway_page)
lws_entry: lws_entry:
gate lws_start, %r0 /* increase privilege */ gate lws_start, %r0 /* increase privilege */
depi 3, 31, 2, %r31 /* Ensure we return into user mode. */ depi PRIV_USER, 31, 2, %r31 /* Ensure we return into user mode. */
/* Fill from 0xb8 to 0xe0 */ /* Fill from 0xb8 to 0xe0 */
.rept 10 .rept 10
@ -89,7 +89,7 @@ lws_entry:
mechanism to work. DO NOT MOVE THIS CODE EVER! */ mechanism to work. DO NOT MOVE THIS CODE EVER! */
set_thread_pointer: set_thread_pointer:
gate .+8, %r0 /* increase privilege */ gate .+8, %r0 /* increase privilege */
depi 3, 31, 2, %r31 /* Ensure we return into user mode. */ depi PRIV_USER, 31, 2, %r31 /* Ensure we return into user mode. */
be 0(%sr7,%r31) /* return to user space */ be 0(%sr7,%r31) /* return to user space */
mtctl %r26, %cr27 /* move arg0 to the control register */ mtctl %r26, %cr27 /* move arg0 to the control register */
@ -139,9 +139,9 @@ linux_gateway_entry:
xor %r1,%r30,%r30 /* ye olde xor trick */ xor %r1,%r30,%r30 /* ye olde xor trick */
xor %r1,%r30,%r1 xor %r1,%r30,%r1
xor %r1,%r30,%r30 xor %r1,%r30,%r30
ldo THREAD_SZ_ALGN+FRAME_SIZE(%r30),%r30 /* set up kernel stack */
LDREG TASK_STACK(%r30),%r30 /* set up kernel stack */
ldo FRAME_SIZE(%r30),%r30
/* N.B.: It is critical that we don't set sr7 to 0 until r30 /* N.B.: It is critical that we don't set sr7 to 0 until r30
* contains a valid kernel stack pointer. It is also * contains a valid kernel stack pointer. It is also
* critical that we don't start using the kernel stack * critical that we don't start using the kernel stack
@ -152,7 +152,6 @@ linux_gateway_entry:
ssm PSW_SM_I, %r0 /* enable interrupts */ ssm PSW_SM_I, %r0 /* enable interrupts */
STREGM %r1,FRAME_SIZE(%r30) /* save r1 (usp) here for now */ STREGM %r1,FRAME_SIZE(%r30) /* save r1 (usp) here for now */
mfctl %cr30,%r1 /* get task ptr in %r1 */ mfctl %cr30,%r1 /* get task ptr in %r1 */
LDREG TI_TASK(%r1),%r1
/* Save some registers for sigcontext and potential task /* Save some registers for sigcontext and potential task
switch (see entry.S for the details of which ones are switch (see entry.S for the details of which ones are
@ -207,7 +206,7 @@ linux_gateway_entry:
/* Are we being ptraced? */ /* Are we being ptraced? */
mfctl %cr30, %r1 mfctl %cr30, %r1
LDREG TI_FLAGS(%r1),%r1 LDREG TASK_TI_FLAGS(%r1),%r1
ldi _TIF_SYSCALL_TRACE_MASK, %r19 ldi _TIF_SYSCALL_TRACE_MASK, %r19
and,COND(=) %r1, %r19, %r0 and,COND(=) %r1, %r19, %r0
b,n .Ltracesys b,n .Ltracesys
@ -272,8 +271,7 @@ tracesys:
* C bit set, a non-straced syscall entry results in C and D clear * C bit set, a non-straced syscall entry results in C and D clear
* in the saved PSW. * in the saved PSW.
*/ */
ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ mfctl %cr30,%r1 /* get task ptr */
LDREG TI_TASK(%r1), %r1
ssm 0,%r2 ssm 0,%r2
STREG %r2,TASK_PT_PSW(%r1) /* Lower 8 bits only!! */ STREG %r2,TASK_PT_PSW(%r1) /* Lower 8 bits only!! */
mfsp %sr0,%r2 mfsp %sr0,%r2
@ -327,8 +325,7 @@ tracesys_next:
*/ */
copy %ret0,%r20 copy %ret0,%r20
ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ mfctl %cr30,%r1 /* get task ptr */
LDREG TI_TASK(%r1), %r1
LDREG TASK_PT_GR28(%r1), %r28 /* Restore return value */ LDREG TASK_PT_GR28(%r1), %r28 /* Restore return value */
LDREG TASK_PT_GR26(%r1), %r26 /* Restore the users args */ LDREG TASK_PT_GR26(%r1), %r26 /* Restore the users args */
LDREG TASK_PT_GR25(%r1), %r25 LDREG TASK_PT_GR25(%r1), %r25
@ -385,16 +382,14 @@ tracesys_next:
makes a direct call to syscall_trace. */ makes a direct call to syscall_trace. */
tracesys_exit: tracesys_exit:
ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ mfctl %cr30,%r1 /* get task ptr */
LDREG TI_TASK(%r1), %r1
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */ ldo -16(%r30),%r29 /* Reference param save area */
#endif #endif
ldo TASK_REGS(%r1),%r26 ldo TASK_REGS(%r1),%r26
BL do_syscall_trace_exit,%r2 BL do_syscall_trace_exit,%r2
STREG %r28,TASK_PT_GR28(%r1) /* save return value now */ STREG %r28,TASK_PT_GR28(%r1) /* save return value now */
ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ mfctl %cr30,%r1 /* get task ptr */
LDREG TI_TASK(%r1), %r1
LDREG TASK_PT_GR28(%r1), %r28 /* Restore return val. */ LDREG TASK_PT_GR28(%r1), %r28 /* Restore return val. */
ldil L%syscall_exit,%r1 ldil L%syscall_exit,%r1
@ -407,8 +402,7 @@ tracesys_exit:
ldo R%tracesys_sigexit(%r2),%r2 ldo R%tracesys_sigexit(%r2),%r2
tracesys_sigexit: tracesys_sigexit:
ldo -THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1 /* get task ptr */ mfctl %cr30,%r1 /* get task ptr */
LDREG TI_TASK(%r1), %r1
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
ldo -16(%r30),%r29 /* Reference param save area */ ldo -16(%r30),%r29 /* Reference param save area */
#endif #endif

111
arch/parisc/kernel/toc.c Normal file
View File

@ -0,0 +1,111 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/kernel.h>
#include <linux/kgdb.h>
#include <linux/printk.h>
#include <linux/sched/debug.h>
#include <linux/delay.h>
#include <linux/reboot.h>
#include <asm/pdc.h>
#include <asm/pdc_chassis.h>
unsigned int __aligned(16) toc_lock = 1;
static void toc20_to_pt_regs(struct pt_regs *regs, struct pdc_toc_pim_20 *toc)
{
int i;
regs->gr[0] = (unsigned long)toc->cr[22];
for (i = 1; i < 32; i++)
regs->gr[i] = (unsigned long)toc->gr[i];
for (i = 0; i < 8; i++)
regs->sr[i] = (unsigned long)toc->sr[i];
regs->iasq[0] = (unsigned long)toc->cr[17];
regs->iasq[1] = (unsigned long)toc->iasq_back;
regs->iaoq[0] = (unsigned long)toc->cr[18];
regs->iaoq[1] = (unsigned long)toc->iaoq_back;
regs->sar = (unsigned long)toc->cr[11];
regs->iir = (unsigned long)toc->cr[19];
regs->isr = (unsigned long)toc->cr[20];
regs->ior = (unsigned long)toc->cr[21];
}
static void toc11_to_pt_regs(struct pt_regs *regs, struct pdc_toc_pim_11 *toc)
{
int i;
regs->gr[0] = toc->cr[22];
for (i = 1; i < 32; i++)
regs->gr[i] = toc->gr[i];
for (i = 0; i < 8; i++)
regs->sr[i] = toc->sr[i];
regs->iasq[0] = toc->cr[17];
regs->iasq[1] = toc->iasq_back;
regs->iaoq[0] = toc->cr[18];
regs->iaoq[1] = toc->iaoq_back;
regs->sar = toc->cr[11];
regs->iir = toc->cr[19];
regs->isr = toc->cr[20];
regs->ior = toc->cr[21];
}
void notrace __noreturn __cold toc_intr(struct pt_regs *regs)
{
struct pdc_toc_pim_20 pim_data20;
struct pdc_toc_pim_11 pim_data11;
nmi_enter();
if (boot_cpu_data.cpu_type >= pcxu) {
if (pdc_pim_toc20(&pim_data20))
panic("Failed to get PIM data");
toc20_to_pt_regs(regs, &pim_data20);
} else {
if (pdc_pim_toc11(&pim_data11))
panic("Failed to get PIM data");
toc11_to_pt_regs(regs, &pim_data11);
}
#ifdef CONFIG_KGDB
if (atomic_read(&kgdb_active) != -1)
kgdb_nmicallback(raw_smp_processor_id(), regs);
kgdb_handle_exception(9, SIGTRAP, 0, regs);
#endif
show_regs(regs);
/* give other CPUs time to show their backtrace */
mdelay(2000);
machine_restart("TOC");
/* should never reach this */
panic("TOC");
}
static __init int setup_toc(void)
{
unsigned int csum = 0;
unsigned long toc_code = (unsigned long)dereference_function_descriptor(toc_handler);
int i;
PAGE0->vec_toc = __pa(toc_code) & 0xffffffff;
#ifdef CONFIG_64BIT
PAGE0->vec_toc_hi = __pa(toc_code) >> 32;
#endif
PAGE0->vec_toclen = toc_handler_size;
for (i = 0; i < toc_handler_size/4; i++)
csum += ((u32 *)toc_code)[i];
toc_handler_csum = -csum;
pr_info("TOC handler registered\n");
return 0;
}
early_initcall(setup_toc);

View File

@ -0,0 +1,88 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* TOC (Transfer of Control) handler. */
.level 1.1
#include <asm/assembly.h>
#include <asm/psw.h>
#include <linux/threads.h>
#include <linux/linkage.h>
.text
.import toc_intr,code
.import toc_lock,data
.align 16
ENTRY_CFI(toc_handler)
/*
* synchronize CPUs and obtain offset
* for stack setup.
*/
load32 PA(toc_lock),%r1
0: ldcw,co 0(%r1),%r2
cmpib,= 0,%r2,0b
nop
addi 1,%r2,%r4
stw %r4,0(%r1)
addi -1,%r2,%r4
load32 PA(toc_stack),%sp
/*
* deposit CPU number into stack address,
* so every CPU will have its own stack.
*/
SHLREG %r4,14,%r4
add %r4,%sp,%sp
/*
* setup pt_regs on stack and save the
* floating point registers. PIM_TOC doesn't
* save fp registers, so we're doing it here.
*/
copy %sp,%arg0
ldo PT_SZ_ALGN(%sp), %sp
/* clear pt_regs */
copy %arg0,%r1
0: cmpb,<<,n %r1,%sp,0b
stw,ma %r0,4(%r1)
ldo PT_FR0(%arg0),%r25
save_fp %r25
/* go virtual */
load32 PA(swapper_pg_dir),%r4
mtctl %r4,%cr24
mtctl %r4,%cr25
/* Clear sr4-sr7 */
mtsp %r0, %sr4
mtsp %r0, %sr5
mtsp %r0, %sr6
mtsp %r0, %sr7
tovirt_r1 %sp
tovirt_r1 %arg0
virt_map
loadgp
#ifdef CONFIG_64BIT
ldo -16(%sp),%r29
#endif
load32 toc_intr,%r1
be 0(%sr7,%r1)
nop
ENDPROC_CFI(toc_handler)
/*
* keep this checksum here, as it is part of the toc_handler
* spanned by toc_handler_size (all words in toc_handler are
* added in PDC and the sum must equal to zero.
*/
SYM_DATA(toc_handler_csum, .long 0)
SYM_DATA(toc_handler_size, .long . - toc_handler)
__PAGE_ALIGNED_BSS
.align 64
SYM_DATA(toc_stack, .block 16384*NR_CPUS)

View File

@ -30,6 +30,7 @@
#include <linux/ratelimit.h> #include <linux/ratelimit.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/kdebug.h> #include <linux/kdebug.h>
#include <linux/kfence.h>
#include <asm/assembly.h> #include <asm/assembly.h>
#include <asm/io.h> #include <asm/io.h>
@ -143,7 +144,7 @@ void show_regs(struct pt_regs *regs)
printk("%s IIR: %08lx ISR: " RFMT " IOR: " RFMT "\n", printk("%s IIR: %08lx ISR: " RFMT " IOR: " RFMT "\n",
level, regs->iir, regs->isr, regs->ior); level, regs->iir, regs->isr, regs->ior);
printk("%s CPU: %8d CR30: " RFMT " CR31: " RFMT "\n", printk("%s CPU: %8d CR30: " RFMT " CR31: " RFMT "\n",
level, current_thread_info()->cpu, cr30, cr31); level, task_cpu(current), cr30, cr31);
printk("%s ORIG_R28: " RFMT "\n", level, regs->orig_r28); printk("%s ORIG_R28: " RFMT "\n", level, regs->orig_r28);
if (user) { if (user) {
@ -787,6 +788,10 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
/* Clean up and return if in exception table. */ /* Clean up and return if in exception table. */
if (fixup_exception(regs)) if (fixup_exception(regs))
return; return;
/* Clean up and return if handled by kfence. */
if (kfence_handle_page_fault(fault_address,
parisc_acctyp(code, regs->iir) == VM_WRITE, regs))
return;
pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC); pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
parisc_terminate("Kernel Fault", regs, code, fault_address); parisc_terminate("Kernel Fault", regs, code, fault_address);
} }

View File

@ -14,6 +14,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/sort.h> #include <linux/sort.h>
#include <linux/sched/task_stack.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/assembly.h> #include <asm/assembly.h>
@ -21,6 +22,8 @@
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/unwind.h> #include <asm/unwind.h>
#include <asm/switch_to.h>
#include <asm/sections.h>
/* #define DEBUG 1 */ /* #define DEBUG 1 */
#ifdef DEBUG #ifdef DEBUG
@ -203,6 +206,11 @@ int __init unwind_init(void)
return 0; return 0;
} }
static bool pc_is_kernel_fn(unsigned long pc, void *fn)
{
return (unsigned long)dereference_kernel_function_descriptor(fn) == pc;
}
static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int frame_size) static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int frame_size)
{ {
/* /*
@ -221,7 +229,7 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int
extern void * const _call_on_stack; extern void * const _call_on_stack;
#endif /* CONFIG_IRQSTACKS */ #endif /* CONFIG_IRQSTACKS */
if (pc == (unsigned long) &handle_interruption) { if (pc_is_kernel_fn(pc, handle_interruption)) {
struct pt_regs *regs = (struct pt_regs *)(info->sp - frame_size - PT_SZ_ALGN); struct pt_regs *regs = (struct pt_regs *)(info->sp - frame_size - PT_SZ_ALGN);
dbg("Unwinding through handle_interruption()\n"); dbg("Unwinding through handle_interruption()\n");
info->prev_sp = regs->gr[30]; info->prev_sp = regs->gr[30];
@ -229,13 +237,13 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int
return 1; return 1;
} }
if (pc == (unsigned long) &ret_from_kernel_thread || if (pc_is_kernel_fn(pc, ret_from_kernel_thread) ||
pc == (unsigned long) &syscall_exit) { pc_is_kernel_fn(pc, syscall_exit)) {
info->prev_sp = info->prev_ip = 0; info->prev_sp = info->prev_ip = 0;
return 1; return 1;
} }
if (pc == (unsigned long) &intr_return) { if (pc_is_kernel_fn(pc, intr_return)) {
struct pt_regs *regs; struct pt_regs *regs;
dbg("Found intr_return()\n"); dbg("Found intr_return()\n");
@ -246,20 +254,20 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int
return 1; return 1;
} }
if (pc == (unsigned long) &_switch_to_ret) { if (pc_is_kernel_fn(pc, _switch_to) ||
pc_is_kernel_fn(pc, _switch_to_ret)) {
info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE; info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE;
info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET); info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET);
return 1; return 1;
} }
#ifdef CONFIG_IRQSTACKS #ifdef CONFIG_IRQSTACKS
if (pc == (unsigned long) &_call_on_stack) { if (pc_is_kernel_fn(pc, _call_on_stack)) {
info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ); info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ);
info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET); info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET);
return 1; return 1;
} }
#endif #endif
return 0; return 0;
} }
@ -292,17 +300,15 @@ static void unwind_frame_regs(struct unwind_frame_info *info)
info->prev_sp = sp - 64; info->prev_sp = sp - 64;
info->prev_ip = 0; info->prev_ip = 0;
/* The stack is at the end inside the thread_union /* Check if stack is inside kernel stack area */
* struct. If we reach data, we have reached the if ((info->prev_sp - (unsigned long) task_stack_page(info->t))
* beginning of the stack and should stop unwinding. */ >= THREAD_SIZE) {
if (info->prev_sp >= (unsigned long) task_thread_info(info->t) &&
info->prev_sp < ((unsigned long) task_thread_info(info->t)
+ THREAD_SZ_ALGN)) {
info->prev_sp = 0; info->prev_sp = 0;
break; break;
} }
if (get_user(tmp, (unsigned long *)(info->prev_sp - RP_OFFSET))) if (copy_from_kernel_nofault(&tmp,
(void *)info->prev_sp - RP_OFFSET, sizeof(tmp)))
break; break;
info->prev_ip = tmp; info->prev_ip = tmp;
sp = info->prev_sp; sp = info->prev_sp;

View File

@ -18,7 +18,7 @@ arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned = {
#endif #endif
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
unsigned long __xchg64(unsigned long x, volatile unsigned long *ptr) unsigned long notrace __xchg64(unsigned long x, volatile unsigned long *ptr)
{ {
unsigned long temp, flags; unsigned long temp, flags;
@ -30,7 +30,7 @@ unsigned long __xchg64(unsigned long x, volatile unsigned long *ptr)
} }
#endif #endif
unsigned long __xchg32(int x, volatile int *ptr) unsigned long notrace __xchg32(int x, volatile int *ptr)
{ {
unsigned long flags; unsigned long flags;
long temp; long temp;
@ -43,7 +43,7 @@ unsigned long __xchg32(int x, volatile int *ptr)
} }
unsigned long __xchg8(char x, volatile char *ptr) unsigned long notrace __xchg8(char x, volatile char *ptr)
{ {
unsigned long flags; unsigned long flags;
long temp; long temp;
@ -56,7 +56,7 @@ unsigned long __xchg8(char x, volatile char *ptr)
} }
u64 __cmpxchg_u64(volatile u64 *ptr, u64 old, u64 new) u64 notrace __cmpxchg_u64(volatile u64 *ptr, u64 old, u64 new)
{ {
unsigned long flags; unsigned long flags;
u64 prev; u64 prev;
@ -68,7 +68,7 @@ u64 __cmpxchg_u64(volatile u64 *ptr, u64 old, u64 new)
return prev; return prev;
} }
unsigned long __cmpxchg_u32(volatile unsigned int *ptr, unsigned int old, unsigned int new) unsigned long notrace __cmpxchg_u32(volatile unsigned int *ptr, unsigned int old, unsigned int new)
{ {
unsigned long flags; unsigned long flags;
unsigned int prev; unsigned int prev;
@ -80,7 +80,7 @@ unsigned long __cmpxchg_u32(volatile unsigned int *ptr, unsigned int old, unsign
return (unsigned long)prev; return (unsigned long)prev;
} }
u8 __cmpxchg_u8(volatile u8 *ptr, u8 old, u8 new) u8 notrace __cmpxchg_u8(volatile u8 *ptr, u8 old, u8 new)
{ {
unsigned long flags; unsigned long flags;
u8 prev; u8 prev;

View File

@ -48,7 +48,7 @@ int show_unhandled_signals = 1;
* VM_WRITE if write operation * VM_WRITE if write operation
* VM_EXEC if execute operation * VM_EXEC if execute operation
*/ */
static unsigned long unsigned long
parisc_acctyp(unsigned long code, unsigned int inst) parisc_acctyp(unsigned long code, unsigned int inst)
{ {
if (code == 6 || code == 16) if (code == 6 || code == 16)

View File

@ -20,12 +20,9 @@ void notrace set_fixmap(enum fixed_addresses idx, phys_addr_t phys)
pte_t *pte; pte_t *pte;
if (pmd_none(*pmd)) if (pmd_none(*pmd))
pmd = pmd_alloc(NULL, pud, vaddr);
pte = pte_offset_kernel(pmd, vaddr);
if (pte_none(*pte))
pte = pte_alloc_kernel(pmd, vaddr); pte = pte_alloc_kernel(pmd, vaddr);
pte = pte_offset_kernel(pmd, vaddr);
set_pte_at(&init_mm, vaddr, pte, __mk_pte(phys, PAGE_KERNEL_RWX)); set_pte_at(&init_mm, vaddr, pte, __mk_pte(phys, PAGE_KERNEL_RWX));
flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE); flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE);
} }

View File

@ -127,16 +127,12 @@ static void __init setup_bootmem(void)
int j; int j;
for (j = i; j > 0; j--) { for (j = i; j > 0; j--) {
physmem_range_t tmp;
if (pmem_ranges[j-1].start_pfn < if (pmem_ranges[j-1].start_pfn <
pmem_ranges[j].start_pfn) { pmem_ranges[j].start_pfn) {
break; break;
} }
tmp = pmem_ranges[j-1]; swap(pmem_ranges[j-1], pmem_ranges[j]);
pmem_ranges[j-1] = pmem_ranges[j];
pmem_ranges[j] = tmp;
} }
} }
@ -842,9 +838,9 @@ void flush_tlb_all(void)
{ {
int do_recycle; int do_recycle;
__inc_irq_stat(irq_tlb_count);
do_recycle = 0; do_recycle = 0;
spin_lock(&sid_lock); spin_lock(&sid_lock);
__inc_irq_stat(irq_tlb_count);
if (dirty_space_ids > RECYCLE_THRESHOLD) { if (dirty_space_ids > RECYCLE_THRESHOLD) {
BUG_ON(recycle_inuse); /* FIXME: Use a semaphore/wait queue here */ BUG_ON(recycle_inuse); /* FIXME: Use a semaphore/wait queue here */
get_dirty_sids(&recycle_ndirty,recycle_dirty_array); get_dirty_sids(&recycle_ndirty,recycle_dirty_array);
@ -863,8 +859,8 @@ void flush_tlb_all(void)
#else #else
void flush_tlb_all(void) void flush_tlb_all(void)
{ {
__inc_irq_stat(irq_tlb_count);
spin_lock(&sid_lock); spin_lock(&sid_lock);
__inc_irq_stat(irq_tlb_count);
flush_tlb_all_local(NULL); flush_tlb_all_local(NULL);
recycle_sids(); recycle_sids();
spin_unlock(&sid_lock); spin_unlock(&sid_lock);

View File

@ -25,7 +25,11 @@ static inline void *task_stack_page(const struct task_struct *task)
static inline unsigned long *end_of_stack(const struct task_struct *task) static inline unsigned long *end_of_stack(const struct task_struct *task)
{ {
#ifdef CONFIG_STACK_GROWSUP
return (unsigned long *)((unsigned long)task->stack + THREAD_SIZE) - 1;
#else
return task->stack; return task->stack;
#endif
} }
#elif !defined(__HAVE_THREAD_FUNCTIONS) #elif !defined(__HAVE_THREAD_FUNCTIONS)