Commit 681857ef authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'parisc-4.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux

Pull parisc updates from Helge Deller:

 - fix panic when halting system via "shutdown -h now"

 - drop own coding in favour of generic CONFIG_COMPAT_BINFMT_ELF
   implementation

 - add FPE_CONDTRAP constant: last outstanding parisc-specific cleanup
   for Eric Biedermans siginfo patches

 - move some functions to .init and some to .text.hot linker sections

* 'parisc-4.17-2' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux:
  parisc: Prevent panic at system halt
  parisc: Switch to generic COMPAT_BINFMT_ELF
  parisc: Move cache flush functions into .text.hot section
  parisc/signal: Add FPE_CONDTRAP for conditional trap handling
parents 80aa76bc 67698287
...@@ -338,6 +338,7 @@ source "mm/Kconfig" ...@@ -338,6 +338,7 @@ source "mm/Kconfig"
config COMPAT config COMPAT
def_bool y def_bool y
depends on 64BIT depends on 64BIT
select COMPAT_BINFMT_ELF if BINFMT_ELF
config SYSVIPC_COMPAT config SYSVIPC_COMPAT
def_bool y def_bool y
......
...@@ -192,6 +192,12 @@ struct compat_shmid64_ds { ...@@ -192,6 +192,12 @@ struct compat_shmid64_ds {
compat_ulong_t __unused6; compat_ulong_t __unused6;
}; };
/*
* The type of struct elf_prstatus.pr_reg in compatible core dumps.
*/
#define COMPAT_ELF_NGREG 80
typedef compat_ulong_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
/* /*
* A pointer passed in from user mode. This should not * A pointer passed in from user mode. This should not
* be used for syscall parameters, just declare them * be used for syscall parameters, just declare them
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* ELF register definitions.. * ELF register definitions..
*/ */
#include <asm/ptrace.h> #include <linux/types.h>
#define EM_PARISC 15 #define EM_PARISC 15
...@@ -169,16 +169,12 @@ typedef struct elf64_fdesc { ...@@ -169,16 +169,12 @@ typedef struct elf64_fdesc {
__u64 gp; __u64 gp;
} Elf64_Fdesc; } Elf64_Fdesc;
#ifdef __KERNEL__
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
#define Elf_Fdesc Elf64_Fdesc #define Elf_Fdesc Elf64_Fdesc
#else #else
#define Elf_Fdesc Elf32_Fdesc #define Elf_Fdesc Elf32_Fdesc
#endif /*CONFIG_64BIT*/ #endif /*CONFIG_64BIT*/
#endif /*__KERNEL__*/
/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ /* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */
#define PT_HP_TLS (PT_LOOS + 0x0) #define PT_HP_TLS (PT_LOOS + 0x0)
...@@ -212,45 +208,45 @@ typedef struct elf64_fdesc { ...@@ -212,45 +208,45 @@ typedef struct elf64_fdesc {
#define PF_HP_LAZYSWAP 0x04000000 #define PF_HP_LAZYSWAP 0x04000000
#define PF_HP_SBP 0x08000000 #define PF_HP_SBP 0x08000000
/*
* This yields a string that ld.so will use to load implementation
* specific libraries for optimization. This is more specific in
* intent than poking at uname or /proc/cpuinfo.
*/
#define ELF_PLATFORM ("PARISC")
/* /*
* The following definitions are those for 32-bit ELF binaries on a 32-bit * The following definitions are those for 32-bit ELF binaries on a 32-bit
* kernel and for 64-bit binaries on a 64-bit kernel. To run 32-bit binaries * kernel and for 64-bit binaries on a 64-bit kernel. To run 32-bit binaries
* on a 64-bit kernel, arch/parisc/kernel/binfmt_elf32.c defines these * on a 64-bit kernel, fs/compat_binfmt_elf.c defines ELF_CLASS and then
* macros appropriately and then #includes binfmt_elf.c, which then includes * #includes binfmt_elf.c, which then includes this file.
* this file.
*/ */
#ifndef ELF_CLASS #ifndef ELF_CLASS
/*
* This is used to ensure we don't load something for the wrong architecture.
*
* Note that this header file is used by default in fs/binfmt_elf.c. So
* the following macros are for the default case. However, for the 64
* bit kernel we also support 32 bit parisc binaries. To do that
* arch/parisc/kernel/binfmt_elf32.c defines its own set of these
* macros, and then it includes fs/binfmt_elf.c to provide an alternate
* elf binary handler for 32 bit binaries (on the 64 bit kernel).
*/
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
#define ELF_CLASS ELFCLASS64 #define ELF_CLASS ELFCLASS64
#else #else
#define ELF_CLASS ELFCLASS32 #define ELF_CLASS ELFCLASS32
#endif #endif
typedef unsigned long elf_greg_t; typedef unsigned long elf_greg_t;
/*
* This yields a string that ld.so will use to load implementation
* specific libraries for optimization. This is more specific in
* intent than poking at uname or /proc/cpuinfo.
*/
#define ELF_PLATFORM ("PARISC\0")
#define SET_PERSONALITY(ex) \ #define SET_PERSONALITY(ex) \
({ \
set_personality((current->personality & ~PER_MASK) | PER_LINUX); \ set_personality((current->personality & ~PER_MASK) | PER_LINUX); \
current->thread.map_base = DEFAULT_MAP_BASE; \ current->thread.map_base = DEFAULT_MAP_BASE; \
current->thread.task_size = DEFAULT_TASK_SIZE \ current->thread.task_size = DEFAULT_TASK_SIZE; \
})
#endif /* ! ELF_CLASS */
#define COMPAT_SET_PERSONALITY(ex) \
({ \
set_thread_flag(TIF_32BIT); \
current->thread.map_base = DEFAULT_MAP_BASE32; \
current->thread.task_size = DEFAULT_TASK_SIZE32; \
})
/* /*
* Fill in general registers in a core dump. This saves pretty * Fill in general registers in a core dump. This saves pretty
...@@ -277,10 +273,12 @@ typedef unsigned long elf_greg_t; ...@@ -277,10 +273,12 @@ typedef unsigned long elf_greg_t;
#define ELF_CORE_COPY_REGS(dst, pt) \ #define ELF_CORE_COPY_REGS(dst, pt) \
memset(dst, 0, sizeof(dst)); /* don't leak any "random" bits */ \ memset(dst, 0, sizeof(dst)); /* don't leak any "random" bits */ \
memcpy(dst + 0, pt->gr, 32 * sizeof(elf_greg_t)); \ { int i; \
memcpy(dst + 32, pt->sr, 8 * sizeof(elf_greg_t)); \ for (i = 0; i < 32; i++) dst[i] = pt->gr[i]; \
memcpy(dst + 40, pt->iaoq, 2 * sizeof(elf_greg_t)); \ for (i = 0; i < 8; i++) dst[32 + i] = pt->sr[i]; \
memcpy(dst + 42, pt->iasq, 2 * sizeof(elf_greg_t)); \ } \
dst[40] = pt->iaoq[0]; dst[41] = pt->iaoq[1]; \
dst[42] = pt->iasq[0]; dst[43] = pt->iasq[1]; \
dst[44] = pt->sar; dst[45] = pt->iir; \ dst[44] = pt->sar; dst[45] = pt->iir; \
dst[46] = pt->isr; dst[47] = pt->ior; \ dst[46] = pt->isr; dst[47] = pt->ior; \
dst[48] = mfctl(22); dst[49] = mfctl(0); \ dst[48] = mfctl(22); dst[49] = mfctl(0); \
...@@ -292,7 +290,7 @@ typedef unsigned long elf_greg_t; ...@@ -292,7 +290,7 @@ typedef unsigned long elf_greg_t;
dst[60] = mfctl(12); dst[61] = mfctl(13); \ dst[60] = mfctl(12); dst[61] = mfctl(13); \
dst[62] = mfctl(10); dst[63] = mfctl(15); dst[62] = mfctl(10); dst[63] = mfctl(15);
#endif /* ! ELF_CLASS */ #define CORE_DUMP_USE_REGSET
#define ELF_NGREG 80 /* We only need 64 at present, but leave space #define ELF_NGREG 80 /* We only need 64 at present, but leave space
for expansion. */ for expansion. */
...@@ -310,7 +308,10 @@ extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *); ...@@ -310,7 +308,10 @@ extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
struct pt_regs; /* forward declaration... */ struct pt_regs; /* forward declaration... */
#define elf_check_arch(x) ((x)->e_machine == EM_PARISC && (x)->e_ident[EI_CLASS] == ELF_CLASS) #define elf_check_arch(x) \
((x)->e_machine == EM_PARISC && (x)->e_ident[EI_CLASS] == ELF_CLASS)
#define compat_elf_check_arch(x) \
((x)->e_machine == EM_PARISC && (x)->e_ident[EI_CLASS] == ELFCLASS32)
/* /*
* These are used to set parameters in the core dumps. * These are used to set parameters in the core dumps.
......
...@@ -8,11 +8,4 @@ ...@@ -8,11 +8,4 @@
#include <asm-generic/siginfo.h> #include <asm-generic/siginfo.h>
/*
* SIGFPE si_codes
*/
#ifdef __KERNEL__
#define FPE_FIXME 0 /* Broken dup of SI_USER */
#endif /* __KERNEL__ */
#endif #endif
// SPDX-License-Identifier: GPL-2.0
/*
* Support for 32-bit Linux/Parisc ELF binaries on 64 bit kernels
*
* Copyright (C) 2000 John Marvin
* Copyright (C) 2000 Hewlett Packard Co.
*
* Heavily inspired from various other efforts to do the same thing
* (ia64,sparc64/mips64)
*/
/* Make sure include/asm-parisc/elf.h does the right thing */
#define ELF_CLASS ELFCLASS32
#define ELF_CORE_COPY_REGS(dst, pt) \
memset(dst, 0, sizeof(dst)); /* don't leak any "random" bits */ \
{ int i; \
for (i = 0; i < 32; i++) dst[i] = (elf_greg_t) pt->gr[i]; \
for (i = 0; i < 8; i++) dst[32 + i] = (elf_greg_t) pt->sr[i]; \
} \
dst[40] = (elf_greg_t) pt->iaoq[0]; dst[41] = (elf_greg_t) pt->iaoq[1]; \
dst[42] = (elf_greg_t) pt->iasq[0]; dst[43] = (elf_greg_t) pt->iasq[1]; \
dst[44] = (elf_greg_t) pt->sar; dst[45] = (elf_greg_t) pt->iir; \
dst[46] = (elf_greg_t) pt->isr; dst[47] = (elf_greg_t) pt->ior; \
dst[48] = (elf_greg_t) mfctl(22); dst[49] = (elf_greg_t) mfctl(0); \
dst[50] = (elf_greg_t) mfctl(24); dst[51] = (elf_greg_t) mfctl(25); \
dst[52] = (elf_greg_t) mfctl(26); dst[53] = (elf_greg_t) mfctl(27); \
dst[54] = (elf_greg_t) mfctl(28); dst[55] = (elf_greg_t) mfctl(29); \
dst[56] = (elf_greg_t) mfctl(30); dst[57] = (elf_greg_t) mfctl(31); \
dst[58] = (elf_greg_t) mfctl( 8); dst[59] = (elf_greg_t) mfctl( 9); \
dst[60] = (elf_greg_t) mfctl(12); dst[61] = (elf_greg_t) mfctl(13); \
dst[62] = (elf_greg_t) mfctl(10); dst[63] = (elf_greg_t) mfctl(15);
typedef unsigned int elf_greg_t;
#include <linux/spinlock.h>
#include <asm/processor.h>
#include <linux/module.h>
#include <linux/elfcore.h>
#include <linux/compat.h> /* struct compat_timeval */
#define elf_prstatus elf_prstatus32
struct elf_prstatus32
{
struct elf_siginfo pr_info; /* Info associated with signal */
short pr_cursig; /* Current signal */
unsigned int pr_sigpend; /* Set of pending signals */
unsigned int pr_sighold; /* Set of held signals */
pid_t pr_pid;
pid_t pr_ppid;
pid_t pr_pgrp;
pid_t pr_sid;
struct compat_timeval pr_utime; /* User time */
struct compat_timeval pr_stime; /* System time */
struct compat_timeval pr_cutime; /* Cumulative user time */
struct compat_timeval pr_cstime; /* Cumulative system time */
elf_gregset_t pr_reg; /* GP registers */
int pr_fpvalid; /* True if math co-processor being used. */
};
#define elf_prpsinfo elf_prpsinfo32
struct elf_prpsinfo32
{
char pr_state; /* numeric process state */
char pr_sname; /* char for pr_state */
char pr_zomb; /* zombie */
char pr_nice; /* nice val */
unsigned int pr_flag; /* flags */
u16 pr_uid;
u16 pr_gid;
pid_t pr_pid, pr_ppid, pr_pgrp, pr_sid;
/* Lots missing */
char pr_fname[16]; /* filename of executable */
char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
};
#define init_elf_binfmt init_elf32_binfmt
#define ELF_PLATFORM ("PARISC32\0")
/*
* We should probably use this macro to set a flag somewhere to indicate
* this is a 32 on 64 process. We could use PER_LINUX_32BIT, or we
* could set a processor dependent flag in the thread_struct.
*/
#undef SET_PERSONALITY
#define SET_PERSONALITY(ex) \
set_thread_flag(TIF_32BIT); \
current->thread.map_base = DEFAULT_MAP_BASE32; \
current->thread.task_size = DEFAULT_TASK_SIZE32 \
#undef ns_to_timeval
#define ns_to_timeval ns_to_compat_timeval
#include "../../../fs/binfmt_elf.c"
...@@ -254,7 +254,7 @@ parisc_cache_init(void) ...@@ -254,7 +254,7 @@ parisc_cache_init(void)
} }
} }
void disable_sr_hashing(void) void __init disable_sr_hashing(void)
{ {
int srhash_type, retval; int srhash_type, retval;
unsigned long space_bits; unsigned long space_bits;
......
...@@ -38,9 +38,10 @@ ...@@ -38,9 +38,10 @@
#include <asm/cache.h> #include <asm/cache.h>
#include <asm/ldcw.h> #include <asm/ldcw.h>
#include <linux/linkage.h> #include <linux/linkage.h>
#include <linux/init.h>
.text .section .text.hot
.align 128 .align 16
ENTRY_CFI(flush_tlb_all_local) ENTRY_CFI(flush_tlb_all_local)
.proc .proc
...@@ -328,8 +329,6 @@ fdsync: ...@@ -328,8 +329,6 @@ fdsync:
.procend .procend
ENDPROC_CFI(flush_data_cache_local) ENDPROC_CFI(flush_data_cache_local)
.align 16
/* Macros to serialize TLB purge operations on SMP. */ /* Macros to serialize TLB purge operations on SMP. */
.macro tlb_lock la,flags,tmp .macro tlb_lock la,flags,tmp
...@@ -1216,6 +1215,8 @@ ENTRY_CFI(flush_kernel_icache_range_asm) ...@@ -1216,6 +1215,8 @@ ENTRY_CFI(flush_kernel_icache_range_asm)
.procend .procend
ENDPROC_CFI(flush_kernel_icache_range_asm) ENDPROC_CFI(flush_kernel_icache_range_asm)
__INIT
/* align should cover use of rfi in disable_sr_hashing_asm and /* align should cover use of rfi in disable_sr_hashing_asm and
* srdis_done. * srdis_done.
*/ */
......
...@@ -112,14 +112,6 @@ void machine_restart(char *cmd) ...@@ -112,14 +112,6 @@ void machine_restart(char *cmd)
} }
void machine_halt(void)
{
/*
** The LED/ChassisCodes are updated by the led_halt()
** function, called by the reboot notifier chain.
*/
}
void (*chassis_power_off)(void); void (*chassis_power_off)(void);
/* /*
...@@ -158,6 +150,11 @@ void machine_power_off(void) ...@@ -158,6 +150,11 @@ void machine_power_off(void)
void (*pm_power_off)(void); void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off); EXPORT_SYMBOL(pm_power_off);
void machine_halt(void)
{
machine_power_off();
}
void flush_thread(void) void flush_thread(void)
{ {
/* Only needs to handle fpu stuff or perf monitors. /* Only needs to handle fpu stuff or perf monitors.
......
...@@ -627,9 +627,10 @@ void notrace handle_interruption(int code, struct pt_regs *regs) ...@@ -627,9 +627,10 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
on condition */ on condition */
if(user_mode(regs)){ if(user_mode(regs)){
si.si_signo = SIGFPE; si.si_signo = SIGFPE;
/* Set to zero, and let the userspace app figure it out from /* Let userspace app figure it out from the insn pointed
the insn pointed to by si_addr */ * to by si_addr.
si.si_code = FPE_FIXME; */
si.si_code = FPE_CONDTRAP;
si.si_addr = (void __user *) regs->iaoq[0]; si.si_addr = (void __user *) regs->iaoq[0];
force_sig_info(SIGFPE, &si, current); force_sig_info(SIGFPE, &si, current);
return; return;
......
...@@ -26,7 +26,7 @@ static inline void signal_compat_build_tests(void) ...@@ -26,7 +26,7 @@ static inline void signal_compat_build_tests(void)
* new fields are handled in copy_siginfo_to_user32()! * new fields are handled in copy_siginfo_to_user32()!
*/ */
BUILD_BUG_ON(NSIGILL != 11); BUILD_BUG_ON(NSIGILL != 11);
BUILD_BUG_ON(NSIGFPE != 14); BUILD_BUG_ON(NSIGFPE != 15);
BUILD_BUG_ON(NSIGSEGV != 7); BUILD_BUG_ON(NSIGSEGV != 7);
BUILD_BUG_ON(NSIGBUS != 5); BUILD_BUG_ON(NSIGBUS != 5);
BUILD_BUG_ON(NSIGTRAP != 4); BUILD_BUG_ON(NSIGTRAP != 4);
......
...@@ -211,7 +211,8 @@ typedef struct siginfo { ...@@ -211,7 +211,8 @@ typedef struct siginfo {
#define __FPE_INVASC 12 /* invalid ASCII digit */ #define __FPE_INVASC 12 /* invalid ASCII digit */
#define __FPE_INVDEC 13 /* invalid decimal digit */ #define __FPE_INVDEC 13 /* invalid decimal digit */
#define FPE_FLTUNK 14 /* undiagnosed floating-point exception */ #define FPE_FLTUNK 14 /* undiagnosed floating-point exception */
#define NSIGFPE 14 #define FPE_CONDTRAP 15 /* trap on condition */
#define NSIGFPE 15
/* /*
* SIGSEGV si_codes * SIGSEGV si_codes
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment