Commit dbf3b7dd authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus

Pull MIPS fixes from Ralf Baechle:
 "The pending MIPS fixes for 3.19.  All across the field and nothing
  particularly severe or dramatic"

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (23 commits)
  IRQCHIP: mips-gic: Avoid rerouting timer IRQs for smp-cmp
  MIPS: Fix syscall_get_nr for the syscall exit tracing.
  MIPS: elf2ecoff: Ignore PT_MIPS_ABIFLAGS program headers.
  MIPS: elf2ecoff: Rewrite main processing loop to switch.
  MIPS: fork: Fix MSA/FPU/DSP context duplication race
  MIPS: Fix C0_Pagegrain[IEC] support.
  MIPS: traps: Fix inline asm ctc1 missing .set hardfloat
  MIPS: mipsregs.h: Add write_32bit_cp1_register()
  MIPS: Fix kernel lockup or crash after CPU offline/online
  MIPS: OCTEON: fix kernel crash when offlining a CPU
  MIPS: ARC: Fix build error.
  MIPS: IRQ: Fix disable_irq on CPU IRQs
  MIPS: smp-mt,smp-cmp: Enable all HW IRQs on secondary CPUs
  MIPS: Fix restart of indirect syscalls
  MIPS: ELF: fix loading o32 binaries on 64-bit kernels
  MIPS: mips-cm: Fix sparse warnings
  MIPS: Kconfig: Fix recursive dependency.
  MIPS: Compat: Fix build error if CONFIG_MIPS32_COMPAT but no compat ABI.
  MIPS: JZ4740: Fixup #include's (sparse)
  MIPS: Wire up execveat(2).
  ...
parents 9d82f5eb 1b6af71a
...@@ -2656,27 +2656,21 @@ config TRAD_SIGNALS ...@@ -2656,27 +2656,21 @@ config TRAD_SIGNALS
bool bool
config MIPS32_COMPAT config MIPS32_COMPAT
bool "Kernel support for Linux/MIPS 32-bit binary compatibility" bool
depends on 64BIT
help
Select this option if you want Linux/MIPS 32-bit binary
compatibility. Since all software available for Linux/MIPS is
currently 32-bit you should say Y here.
config COMPAT config COMPAT
bool bool
depends on MIPS32_COMPAT
select ARCH_WANT_OLD_COMPAT_IPC
default y
config SYSVIPC_COMPAT config SYSVIPC_COMPAT
bool bool
depends on COMPAT && SYSVIPC
default y
config MIPS32_O32 config MIPS32_O32
bool "Kernel support for o32 binaries" bool "Kernel support for o32 binaries"
depends on MIPS32_COMPAT depends on 64BIT
select ARCH_WANT_OLD_COMPAT_IPC
select COMPAT
select MIPS32_COMPAT
select SYSVIPC_COMPAT if SYSVIPC
help help
Select this option if you want to run o32 binaries. These are pure Select this option if you want to run o32 binaries. These are pure
32-bit binaries as used by the 32-bit Linux/MIPS port. Most of 32-bit binaries as used by the 32-bit Linux/MIPS port. Most of
...@@ -2686,7 +2680,10 @@ config MIPS32_O32 ...@@ -2686,7 +2680,10 @@ config MIPS32_O32
config MIPS32_N32 config MIPS32_N32
bool "Kernel support for n32 binaries" bool "Kernel support for n32 binaries"
depends on MIPS32_COMPAT depends on 64BIT
select COMPAT
select MIPS32_COMPAT
select SYSVIPC_COMPAT if SYSVIPC
help help
Select this option if you want to run n32 binaries. These are Select this option if you want to run n32 binaries. These are
64-bit binaries using 32-bit quantities for addressing and certain 64-bit binaries using 32-bit quantities for addressing and certain
......
...@@ -49,7 +49,8 @@ ...@@ -49,7 +49,8 @@
/* /*
* Some extra ELF definitions * Some extra ELF definitions
*/ */
#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ #define PT_MIPS_REGINFO 0x70000000 /* Register usage information */
#define PT_MIPS_ABIFLAGS 0x70000003 /* Records ABI related flags */
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
...@@ -349,39 +350,46 @@ int main(int argc, char *argv[]) ...@@ -349,39 +350,46 @@ int main(int argc, char *argv[])
for (i = 0; i < ex.e_phnum; i++) { for (i = 0; i < ex.e_phnum; i++) {
/* Section types we can ignore... */ /* Section types we can ignore... */
if (ph[i].p_type == PT_NULL || ph[i].p_type == PT_NOTE || switch (ph[i].p_type) {
ph[i].p_type == PT_PHDR case PT_NULL:
|| ph[i].p_type == PT_MIPS_REGINFO) case PT_NOTE:
case PT_PHDR:
case PT_MIPS_REGINFO:
case PT_MIPS_ABIFLAGS:
continue; continue;
/* Section types we can't handle... */
else if (ph[i].p_type != PT_LOAD) {
fprintf(stderr,
"Program header %d type %d can't be converted.\n",
ex.e_phnum, ph[i].p_type);
exit(1);
}
/* Writable (data) segment? */
if (ph[i].p_flags & PF_W) {
struct sect ndata, nbss;
ndata.vaddr = ph[i].p_vaddr; case PT_LOAD:
ndata.len = ph[i].p_filesz; /* Writable (data) segment? */
nbss.vaddr = ph[i].p_vaddr + ph[i].p_filesz; if (ph[i].p_flags & PF_W) {
nbss.len = ph[i].p_memsz - ph[i].p_filesz; struct sect ndata, nbss;
ndata.vaddr = ph[i].p_vaddr;
ndata.len = ph[i].p_filesz;
nbss.vaddr = ph[i].p_vaddr + ph[i].p_filesz;
nbss.len = ph[i].p_memsz - ph[i].p_filesz;
combine(&data, &ndata, 0); combine(&data, &ndata, 0);
combine(&bss, &nbss, 1); combine(&bss, &nbss, 1);
} else { } else {
struct sect ntxt; struct sect ntxt;
ntxt.vaddr = ph[i].p_vaddr; ntxt.vaddr = ph[i].p_vaddr;
ntxt.len = ph[i].p_filesz; ntxt.len = ph[i].p_filesz;
combine(&text, &ntxt, 0); combine(&text, &ntxt, 0);
}
/* Remember the lowest segment start address. */
if (ph[i].p_vaddr < cur_vma)
cur_vma = ph[i].p_vaddr;
break;
default:
/* Section types we can't handle... */
fprintf(stderr,
"Program header %d type %d can't be converted.\n",
ex.e_phnum, ph[i].p_type);
exit(1);
} }
/* Remember the lowest segment start address. */
if (ph[i].p_vaddr < cur_vma)
cur_vma = ph[i].p_vaddr;
} }
/* Sections must be in order to be converted... */ /* Sections must be in order to be converted... */
......
...@@ -240,9 +240,7 @@ static int octeon_cpu_disable(void) ...@@ -240,9 +240,7 @@ static int octeon_cpu_disable(void)
set_cpu_online(cpu, false); set_cpu_online(cpu, false);
cpu_clear(cpu, cpu_callin_map); cpu_clear(cpu, cpu_callin_map);
local_irq_disable();
octeon_fixup_irqs(); octeon_fixup_irqs();
local_irq_enable();
flush_cache_all(); flush_cache_all();
local_flush_tlb_all(); local_flush_tlb_all();
......
...@@ -132,7 +132,6 @@ CONFIG_IP_NF_MATCH_ECN=m ...@@ -132,7 +132,6 @@ CONFIG_IP_NF_MATCH_ECN=m
CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_MATCH_TTL=m
CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_FILTER=m
CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_REJECT=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_MANGLE=m
CONFIG_IP_NF_TARGET_CLUSTERIP=m CONFIG_IP_NF_TARGET_CLUSTERIP=m
CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_ECN=m
...@@ -175,7 +174,6 @@ CONFIG_BRIDGE_EBT_MARK_T=m ...@@ -175,7 +174,6 @@ CONFIG_BRIDGE_EBT_MARK_T=m
CONFIG_BRIDGE_EBT_REDIRECT=m CONFIG_BRIDGE_EBT_REDIRECT=m
CONFIG_BRIDGE_EBT_SNAT=m CONFIG_BRIDGE_EBT_SNAT=m
CONFIG_BRIDGE_EBT_LOG=m CONFIG_BRIDGE_EBT_LOG=m
CONFIG_BRIDGE_EBT_ULOG=m
CONFIG_BRIDGE_EBT_NFLOG=m CONFIG_BRIDGE_EBT_NFLOG=m
CONFIG_IP_SCTP=m CONFIG_IP_SCTP=m
CONFIG_BRIDGE=m CONFIG_BRIDGE=m
...@@ -220,8 +218,6 @@ CONFIG_NET_ACT_SKBEDIT=m ...@@ -220,8 +218,6 @@ CONFIG_NET_ACT_SKBEDIT=m
CONFIG_NET_CLS_IND=y CONFIG_NET_CLS_IND=y
CONFIG_CFG80211=m CONFIG_CFG80211=m
CONFIG_MAC80211=m CONFIG_MAC80211=m
CONFIG_MAC80211_RC_PID=y
CONFIG_MAC80211_RC_DEFAULT_PID=y
CONFIG_MAC80211_MESH=y CONFIG_MAC80211_MESH=y
CONFIG_RFKILL=m CONFIG_RFKILL=m
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
...@@ -248,19 +244,13 @@ CONFIG_ATA_OVER_ETH=m ...@@ -248,19 +244,13 @@ CONFIG_ATA_OVER_ETH=m
CONFIG_IDE=y CONFIG_IDE=y
CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_IDECD=y
CONFIG_IDE_GENERIC=y CONFIG_IDE_GENERIC=y
CONFIG_BLK_DEV_GENERIC=y
CONFIG_BLK_DEV_PIIX=y
CONFIG_BLK_DEV_IT8213=m
CONFIG_BLK_DEV_TC86C001=m
CONFIG_RAID_ATTRS=m CONFIG_RAID_ATTRS=m
CONFIG_SCSI=m CONFIG_BLK_DEV_SD=y
CONFIG_BLK_DEV_SD=m
CONFIG_CHR_DEV_ST=m CONFIG_CHR_DEV_ST=m
CONFIG_CHR_DEV_OSST=m CONFIG_CHR_DEV_OSST=m
CONFIG_BLK_DEV_SR=m CONFIG_BLK_DEV_SR=m
CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=m CONFIG_CHR_DEV_SG=m
CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y CONFIG_SCSI_SCAN_ASYNC=y
...@@ -273,6 +263,8 @@ CONFIG_SCSI_AACRAID=m ...@@ -273,6 +263,8 @@ CONFIG_SCSI_AACRAID=m
CONFIG_SCSI_AIC7XXX=m CONFIG_SCSI_AIC7XXX=m
CONFIG_AIC7XXX_RESET_DELAY_MS=15000 CONFIG_AIC7XXX_RESET_DELAY_MS=15000
# CONFIG_AIC7XXX_DEBUG_ENABLE is not set # CONFIG_AIC7XXX_DEBUG_ENABLE is not set
CONFIG_ATA=y
CONFIG_ATA_PIIX=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
...@@ -340,6 +332,7 @@ CONFIG_UIO=m ...@@ -340,6 +332,7 @@ CONFIG_UIO=m
CONFIG_UIO_CIF=m CONFIG_UIO_CIF=m
CONFIG_EXT2_FS=y CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y CONFIG_EXT3_FS=y
CONFIG_EXT4_FS=y
CONFIG_REISERFS_FS=m CONFIG_REISERFS_FS=m
CONFIG_REISERFS_PROC_INFO=y CONFIG_REISERFS_PROC_INFO=y
CONFIG_REISERFS_FS_XATTR=y CONFIG_REISERFS_FS_XATTR=y
...@@ -441,4 +434,3 @@ CONFIG_CRYPTO_SERPENT=m ...@@ -441,4 +434,3 @@ CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_TWOFISH=m
# CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRC16=m
...@@ -64,7 +64,7 @@ static inline int __enable_fpu(enum fpu_mode mode) ...@@ -64,7 +64,7 @@ static inline int __enable_fpu(enum fpu_mode mode)
return SIGFPE; return SIGFPE;
/* set FRE */ /* set FRE */
write_c0_config5(read_c0_config5() | MIPS_CONF5_FRE); set_c0_config5(MIPS_CONF5_FRE);
goto fr_common; goto fr_common;
case FPU_64BIT: case FPU_64BIT:
...@@ -74,8 +74,10 @@ static inline int __enable_fpu(enum fpu_mode mode) ...@@ -74,8 +74,10 @@ static inline int __enable_fpu(enum fpu_mode mode)
#endif #endif
/* fall through */ /* fall through */
case FPU_32BIT: case FPU_32BIT:
/* clear FRE */ if (cpu_has_fre) {
write_c0_config5(read_c0_config5() & ~MIPS_CONF5_FRE); /* clear FRE */
clear_c0_config5(MIPS_CONF5_FRE);
}
fr_common: fr_common:
/* set CU1 & change FR appropriately */ /* set CU1 & change FR appropriately */
fr = (int)mode & FPU_FR_MASK; fr = (int)mode & FPU_FR_MASK;
...@@ -182,25 +184,32 @@ static inline int init_fpu(void) ...@@ -182,25 +184,32 @@ static inline int init_fpu(void)
int ret = 0; int ret = 0;
if (cpu_has_fpu) { if (cpu_has_fpu) {
unsigned int config5;
ret = __own_fpu(); ret = __own_fpu();
if (!ret) { if (ret)
unsigned int config5 = read_c0_config5(); return ret;
/*
* Ensure FRE is clear whilst running _init_fpu, since
* single precision FP instructions are used. If FRE
* was set then we'll just end up initialising all 32
* 64b registers.
*/
write_c0_config5(config5 & ~MIPS_CONF5_FRE);
enable_fpu_hazard();
if (!cpu_has_fre) {
_init_fpu(); _init_fpu();
/* Restore FRE */ return 0;
write_c0_config5(config5);
enable_fpu_hazard();
} }
/*
* Ensure FRE is clear whilst running _init_fpu, since
* single precision FP instructions are used. If FRE
* was set then we'll just end up initialising all 32
* 64b registers.
*/
config5 = clear_c0_config5(MIPS_CONF5_FRE);
enable_fpu_hazard();
_init_fpu();
/* Restore FRE */
write_c0_config5(config5);
enable_fpu_hazard();
} else } else
fpu_emulator_init_fpu(); fpu_emulator_init_fpu();
......
...@@ -119,7 +119,7 @@ union key_u { ...@@ -119,7 +119,7 @@ union key_u {
#define SGI_ARCS_REV 10 /* rev .10, 3/04/92 */ #define SGI_ARCS_REV 10 /* rev .10, 3/04/92 */
#endif #endif
typedef struct component { typedef struct {
CONFIGCLASS Class; CONFIGCLASS Class;
CONFIGTYPE Type; CONFIGTYPE Type;
IDENTIFIERFLAG Flags; IDENTIFIERFLAG Flags;
...@@ -140,7 +140,7 @@ struct cfgdata { ...@@ -140,7 +140,7 @@ struct cfgdata {
}; };
/* System ID */ /* System ID */
typedef struct systemid { typedef struct {
CHAR VendorId[8]; CHAR VendorId[8];
CHAR ProductId[8]; CHAR ProductId[8];
} SYSTEMID; } SYSTEMID;
...@@ -166,7 +166,7 @@ typedef enum memorytype { ...@@ -166,7 +166,7 @@ typedef enum memorytype {
#endif /* _NT_PROM */ #endif /* _NT_PROM */
} MEMORYTYPE; } MEMORYTYPE;
typedef struct memorydescriptor { typedef struct {
MEMORYTYPE Type; MEMORYTYPE Type;
LONG BasePage; LONG BasePage;
LONG PageCount; LONG PageCount;
......
...@@ -89,9 +89,9 @@ static inline bool mips_cm_has_l2sync(void) ...@@ -89,9 +89,9 @@ static inline bool mips_cm_has_l2sync(void)
/* Macros to ease the creation of register access functions */ /* Macros to ease the creation of register access functions */
#define BUILD_CM_R_(name, off) \ #define BUILD_CM_R_(name, off) \
static inline u32 *addr_gcr_##name(void) \ static inline u32 __iomem *addr_gcr_##name(void) \
{ \ { \
return (u32 *)(mips_cm_base + (off)); \ return (u32 __iomem *)(mips_cm_base + (off)); \
} \ } \
\ \
static inline u32 read_gcr_##name(void) \ static inline u32 read_gcr_##name(void) \
......
...@@ -1386,12 +1386,27 @@ do { \ ...@@ -1386,12 +1386,27 @@ do { \
__res; \ __res; \
}) })
#define _write_32bit_cp1_register(dest, val, gas_hardfloat) \
do { \
__asm__ __volatile__( \
" .set push \n" \
" .set reorder \n" \
" "STR(gas_hardfloat)" \n" \
" ctc1 %0,"STR(dest)" \n" \
" .set pop \n" \
: : "r" (val)); \
} while (0)
#ifdef GAS_HAS_SET_HARDFLOAT #ifdef GAS_HAS_SET_HARDFLOAT
#define read_32bit_cp1_register(source) \ #define read_32bit_cp1_register(source) \
_read_32bit_cp1_register(source, .set hardfloat) _read_32bit_cp1_register(source, .set hardfloat)
#define write_32bit_cp1_register(dest, val) \
_write_32bit_cp1_register(dest, val, .set hardfloat)
#else #else
#define read_32bit_cp1_register(source) \ #define read_32bit_cp1_register(source) \
_read_32bit_cp1_register(source, ) _read_32bit_cp1_register(source, )
#define write_32bit_cp1_register(dest, val) \
_write_32bit_cp1_register(dest, val, )
#endif #endif
#ifdef HAVE_AS_DSP #ifdef HAVE_AS_DSP
......
...@@ -29,13 +29,7 @@ ...@@ -29,13 +29,7 @@
static inline long syscall_get_nr(struct task_struct *task, static inline long syscall_get_nr(struct task_struct *task,
struct pt_regs *regs) struct pt_regs *regs)
{ {
/* O32 ABI syscall() - Either 64-bit with O32 or 32-bit */ return current_thread_info()->syscall;
if ((config_enabled(CONFIG_32BIT) ||
test_tsk_thread_flag(task, TIF_32BIT_REGS)) &&
(regs->regs[2] == __NR_syscall))
return regs->regs[4];
else
return regs->regs[2];
} }
static inline unsigned long mips_get_syscall_arg(unsigned long *arg, static inline unsigned long mips_get_syscall_arg(unsigned long *arg,
......
...@@ -36,6 +36,7 @@ struct thread_info { ...@@ -36,6 +36,7 @@ struct thread_info {
*/ */
struct restart_block restart_block; struct restart_block restart_block;
struct pt_regs *regs; struct pt_regs *regs;
long syscall; /* syscall number */
}; };
/* /*
......
...@@ -376,16 +376,17 @@ ...@@ -376,16 +376,17 @@
#define __NR_getrandom (__NR_Linux + 353) #define __NR_getrandom (__NR_Linux + 353)
#define __NR_memfd_create (__NR_Linux + 354) #define __NR_memfd_create (__NR_Linux + 354)
#define __NR_bpf (__NR_Linux + 355) #define __NR_bpf (__NR_Linux + 355)
#define __NR_execveat (__NR_Linux + 356)
/* /*
* Offset of the last Linux o32 flavoured syscall * Offset of the last Linux o32 flavoured syscall
*/ */
#define __NR_Linux_syscalls 355 #define __NR_Linux_syscalls 356
#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
#define __NR_O32_Linux 4000 #define __NR_O32_Linux 4000
#define __NR_O32_Linux_syscalls 355 #define __NR_O32_Linux_syscalls 356
#if _MIPS_SIM == _MIPS_SIM_ABI64 #if _MIPS_SIM == _MIPS_SIM_ABI64
...@@ -709,16 +710,17 @@ ...@@ -709,16 +710,17 @@
#define __NR_getrandom (__NR_Linux + 313) #define __NR_getrandom (__NR_Linux + 313)
#define __NR_memfd_create (__NR_Linux + 314) #define __NR_memfd_create (__NR_Linux + 314)
#define __NR_bpf (__NR_Linux + 315) #define __NR_bpf (__NR_Linux + 315)
#define __NR_execveat (__NR_Linux + 316)
/* /*
* Offset of the last Linux 64-bit flavoured syscall * Offset of the last Linux 64-bit flavoured syscall
*/ */
#define __NR_Linux_syscalls 315 #define __NR_Linux_syscalls 316
#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
#define __NR_64_Linux 5000 #define __NR_64_Linux 5000
#define __NR_64_Linux_syscalls 315 #define __NR_64_Linux_syscalls 316
#if _MIPS_SIM == _MIPS_SIM_NABI32 #if _MIPS_SIM == _MIPS_SIM_NABI32
...@@ -1046,15 +1048,16 @@ ...@@ -1046,15 +1048,16 @@
#define __NR_getrandom (__NR_Linux + 317) #define __NR_getrandom (__NR_Linux + 317)
#define __NR_memfd_create (__NR_Linux + 318) #define __NR_memfd_create (__NR_Linux + 318)
#define __NR_bpf (__NR_Linux + 319) #define __NR_bpf (__NR_Linux + 319)
#define __NR_execveat (__NR_Linux + 320)
/* /*
* Offset of the last N32 flavoured syscall * Offset of the last N32 flavoured syscall
*/ */
#define __NR_Linux_syscalls 319 #define __NR_Linux_syscalls 320
#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
#define __NR_N32_Linux 6000 #define __NR_N32_Linux 6000
#define __NR_N32_Linux_syscalls 319 #define __NR_N32_Linux_syscalls 320
#endif /* _UAPI_ASM_UNISTD_H */ #endif /* _UAPI_ASM_UNISTD_H */
...@@ -30,6 +30,9 @@ ...@@ -30,6 +30,9 @@
#include <asm/irq_cpu.h> #include <asm/irq_cpu.h>
#include <asm/mach-jz4740/base.h> #include <asm/mach-jz4740/base.h>
#include <asm/mach-jz4740/irq.h>
#include "irq.h"
static void __iomem *jz_intc_base; static void __iomem *jz_intc_base;
......
...@@ -19,8 +19,8 @@ enum { ...@@ -19,8 +19,8 @@ enum {
int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf, int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
bool is_interp, struct arch_elf_state *state) bool is_interp, struct arch_elf_state *state)
{ {
struct elfhdr *ehdr = _ehdr; struct elf32_hdr *ehdr = _ehdr;
struct elf_phdr *phdr = _phdr; struct elf32_phdr *phdr = _phdr;
struct mips_elf_abiflags_v0 abiflags; struct mips_elf_abiflags_v0 abiflags;
int ret; int ret;
...@@ -48,7 +48,7 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf, ...@@ -48,7 +48,7 @@ int arch_elf_pt_proc(void *_ehdr, void *_phdr, struct file *elf,
return 0; return 0;
} }
static inline unsigned get_fp_abi(struct elfhdr *ehdr, int in_abi) static inline unsigned get_fp_abi(struct elf32_hdr *ehdr, int in_abi)
{ {
/* If the ABI requirement is provided, simply return that */ /* If the ABI requirement is provided, simply return that */
if (in_abi != -1) if (in_abi != -1)
...@@ -65,7 +65,7 @@ static inline unsigned get_fp_abi(struct elfhdr *ehdr, int in_abi) ...@@ -65,7 +65,7 @@ static inline unsigned get_fp_abi(struct elfhdr *ehdr, int in_abi)
int arch_check_elf(void *_ehdr, bool has_interpreter, int arch_check_elf(void *_ehdr, bool has_interpreter,
struct arch_elf_state *state) struct arch_elf_state *state)
{ {
struct elfhdr *ehdr = _ehdr; struct elf32_hdr *ehdr = _ehdr;
unsigned fp_abi, interp_fp_abi, abi0, abi1; unsigned fp_abi, interp_fp_abi, abi0, abi1;
/* Ignore non-O32 binaries */ /* Ignore non-O32 binaries */
......
...@@ -57,6 +57,8 @@ static struct irq_chip mips_cpu_irq_controller = { ...@@ -57,6 +57,8 @@ static struct irq_chip mips_cpu_irq_controller = {
.irq_mask_ack = mask_mips_irq, .irq_mask_ack = mask_mips_irq,
.irq_unmask = unmask_mips_irq, .irq_unmask = unmask_mips_irq,
.irq_eoi = unmask_mips_irq, .irq_eoi = unmask_mips_irq,
.irq_disable = mask_mips_irq,
.irq_enable = unmask_mips_irq,
}; };
/* /*
...@@ -93,6 +95,8 @@ static struct irq_chip mips_mt_cpu_irq_controller = { ...@@ -93,6 +95,8 @@ static struct irq_chip mips_mt_cpu_irq_controller = {
.irq_mask_ack = mips_mt_cpu_irq_ack, .irq_mask_ack = mips_mt_cpu_irq_ack,
.irq_unmask = unmask_mips_irq, .irq_unmask = unmask_mips_irq,
.irq_eoi = unmask_mips_irq, .irq_eoi = unmask_mips_irq,
.irq_disable = mask_mips_irq,
.irq_enable = unmask_mips_irq,
}; };
asmlinkage void __weak plat_irq_dispatch(void) asmlinkage void __weak plat_irq_dispatch(void)
......
...@@ -82,6 +82,30 @@ void flush_thread(void) ...@@ -82,6 +82,30 @@ void flush_thread(void)
{ {
} }
int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
{
/*
* Save any process state which is live in hardware registers to the
* parent context prior to duplication. This prevents the new child
* state becoming stale if the parent is preempted before copy_thread()
* gets a chance to save the parent's live hardware registers to the
* child context.
*/
preempt_disable();
if (is_msa_enabled())
save_msa(current);
else if (is_fpu_owner())
_save_fp(current);
save_dsp(current);
preempt_enable();
*dst = *src;
return 0;
}
int copy_thread(unsigned long clone_flags, unsigned long usp, int copy_thread(unsigned long clone_flags, unsigned long usp,
unsigned long arg, struct task_struct *p) unsigned long arg, struct task_struct *p)
{ {
...@@ -92,18 +116,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, ...@@ -92,18 +116,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32; childksp = (unsigned long)task_stack_page(p) + THREAD_SIZE - 32;
preempt_disable();
if (is_msa_enabled())
save_msa(p);
else if (is_fpu_owner())
save_fp(p);
if (cpu_has_dsp)
save_dsp(p);
preempt_enable();
/* set up new TSS. */ /* set up new TSS. */
childregs = (struct pt_regs *) childksp - 1; childregs = (struct pt_regs *) childksp - 1;
/* Put the stack after the struct pt_regs. */ /* Put the stack after the struct pt_regs. */
......
...@@ -770,6 +770,8 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall) ...@@ -770,6 +770,8 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
long ret = 0; long ret = 0;
user_exit(); user_exit();
current_thread_info()->syscall = syscall;
if (secure_computing() == -1) if (secure_computing() == -1)
return -1; return -1;
......
...@@ -181,6 +181,7 @@ illegal_syscall: ...@@ -181,6 +181,7 @@ illegal_syscall:
sll t1, t0, 2 sll t1, t0, 2
beqz v0, einval beqz v0, einval
lw t2, sys_call_table(t1) # syscall routine lw t2, sys_call_table(t1) # syscall routine
sw a0, PT_R2(sp) # call routine directly on restart
/* Some syscalls like execve get their arguments from struct pt_regs /* Some syscalls like execve get their arguments from struct pt_regs
and claim zero arguments in the syscall table. Thus we have to and claim zero arguments in the syscall table. Thus we have to
...@@ -580,3 +581,4 @@ EXPORT(sys_call_table) ...@@ -580,3 +581,4 @@ EXPORT(sys_call_table)
PTR sys_getrandom PTR sys_getrandom
PTR sys_memfd_create PTR sys_memfd_create
PTR sys_bpf /* 4355 */ PTR sys_bpf /* 4355 */
PTR sys_execveat
...@@ -435,4 +435,5 @@ EXPORT(sys_call_table) ...@@ -435,4 +435,5 @@ EXPORT(sys_call_table)
PTR sys_getrandom PTR sys_getrandom
PTR sys_memfd_create PTR sys_memfd_create
PTR sys_bpf /* 5315 */ PTR sys_bpf /* 5315 */
PTR sys_execveat
.size sys_call_table,.-sys_call_table .size sys_call_table,.-sys_call_table
...@@ -428,4 +428,5 @@ EXPORT(sysn32_call_table) ...@@ -428,4 +428,5 @@ EXPORT(sysn32_call_table)
PTR sys_getrandom PTR sys_getrandom
PTR sys_memfd_create PTR sys_memfd_create
PTR sys_bpf PTR sys_bpf
PTR compat_sys_execveat /* 6320 */
.size sysn32_call_table,.-sysn32_call_table .size sysn32_call_table,.-sysn32_call_table
...@@ -186,6 +186,7 @@ LEAF(sys32_syscall) ...@@ -186,6 +186,7 @@ LEAF(sys32_syscall)
dsll t1, t0, 3 dsll t1, t0, 3
beqz v0, einval beqz v0, einval
ld t2, sys32_call_table(t1) # syscall routine ld t2, sys32_call_table(t1) # syscall routine
sd a0, PT_R2(sp) # call routine directly on restart
move a0, a1 # shift argument registers move a0, a1 # shift argument registers
move a1, a2 move a1, a2
...@@ -565,4 +566,5 @@ EXPORT(sys32_call_table) ...@@ -565,4 +566,5 @@ EXPORT(sys32_call_table)
PTR sys_getrandom PTR sys_getrandom
PTR sys_memfd_create PTR sys_memfd_create
PTR sys_bpf /* 4355 */ PTR sys_bpf /* 4355 */
PTR compat_sys_execveat
.size sys32_call_table,.-sys32_call_table .size sys32_call_table,.-sys32_call_table
...@@ -44,8 +44,8 @@ static void cmp_init_secondary(void) ...@@ -44,8 +44,8 @@ static void cmp_init_secondary(void)
struct cpuinfo_mips *c __maybe_unused = &current_cpu_data; struct cpuinfo_mips *c __maybe_unused = &current_cpu_data;
/* Assume GIC is present */ /* Assume GIC is present */
change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP6 | change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 |
STATUSF_IP7); STATUSF_IP5 | STATUSF_IP6 | STATUSF_IP7);
/* Enable per-cpu interrupts: platform specific */ /* Enable per-cpu interrupts: platform specific */
......
...@@ -161,7 +161,8 @@ static void vsmp_init_secondary(void) ...@@ -161,7 +161,8 @@ static void vsmp_init_secondary(void)
#ifdef CONFIG_MIPS_GIC #ifdef CONFIG_MIPS_GIC
/* This is Malta specific: IPI,performance and timer interrupts */ /* This is Malta specific: IPI,performance and timer interrupts */
if (gic_present) if (gic_present)
change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | change_c0_status(ST0_IM, STATUSF_IP2 | STATUSF_IP3 |
STATUSF_IP4 | STATUSF_IP5 |
STATUSF_IP6 | STATUSF_IP7); STATUSF_IP6 | STATUSF_IP7);
else else
#endif #endif
......
...@@ -123,10 +123,10 @@ asmlinkage void start_secondary(void) ...@@ -123,10 +123,10 @@ asmlinkage void start_secondary(void)
unsigned int cpu; unsigned int cpu;
cpu_probe(); cpu_probe();
cpu_report();
per_cpu_trap_init(false); per_cpu_trap_init(false);
mips_clockevent_init(); mips_clockevent_init();
mp_ops->init_secondary(); mp_ops->init_secondary();
cpu_report();
/* /*
* XXX parity protection should be folded in here when it's converted * XXX parity protection should be folded in here when it's converted
......
...@@ -1231,7 +1231,8 @@ static int enable_restore_fp_context(int msa) ...@@ -1231,7 +1231,8 @@ static int enable_restore_fp_context(int msa)
/* Restore the scalar FP control & status register */ /* Restore the scalar FP control & status register */
if (!was_fpu_owner) if (!was_fpu_owner)
asm volatile("ctc1 %0, $31" : : "r"(current->thread.fpu.fcr31)); write_32bit_cp1_register(CP1_STATUS,
current->thread.fpu.fcr31);
} }
out: out:
......
...@@ -489,6 +489,8 @@ static void r4k_tlb_configure(void) ...@@ -489,6 +489,8 @@ static void r4k_tlb_configure(void)
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
pg |= PG_ELPA; pg |= PG_ELPA;
#endif #endif
if (cpu_has_rixiex)
pg |= PG_IEC;
write_c0_pagegrain(pg); write_c0_pagegrain(pg);
} }
......
...@@ -37,6 +37,7 @@ static struct irq_domain *gic_irq_domain; ...@@ -37,6 +37,7 @@ static struct irq_domain *gic_irq_domain;
static int gic_shared_intrs; static int gic_shared_intrs;
static int gic_vpes; static int gic_vpes;
static unsigned int gic_cpu_pin; static unsigned int gic_cpu_pin;
static unsigned int timer_cpu_pin;
static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller; static struct irq_chip gic_level_irq_controller, gic_edge_irq_controller;
static void __gic_irq_dispatch(void); static void __gic_irq_dispatch(void);
...@@ -616,6 +617,8 @@ static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq, ...@@ -616,6 +617,8 @@ static int gic_local_irq_domain_map(struct irq_domain *d, unsigned int virq,
gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_MAP), val); gic_write(GIC_REG(VPE_OTHER, GIC_VPE_COMPARE_MAP), val);
break; break;
case GIC_LOCAL_INT_TIMER: case GIC_LOCAL_INT_TIMER:
/* CONFIG_MIPS_CMP workaround (see __gic_init) */
val = GIC_MAP_TO_PIN_MSK | timer_cpu_pin;
gic_write(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP), val); gic_write(GIC_REG(VPE_OTHER, GIC_VPE_TIMER_MAP), val);
break; break;
case GIC_LOCAL_INT_PERFCTR: case GIC_LOCAL_INT_PERFCTR:
...@@ -713,12 +716,36 @@ static void __init __gic_init(unsigned long gic_base_addr, ...@@ -713,12 +716,36 @@ static void __init __gic_init(unsigned long gic_base_addr,
if (cpu_has_veic) { if (cpu_has_veic) {
/* Always use vector 1 in EIC mode */ /* Always use vector 1 in EIC mode */
gic_cpu_pin = 0; gic_cpu_pin = 0;
timer_cpu_pin = gic_cpu_pin;
set_vi_handler(gic_cpu_pin + GIC_PIN_TO_VEC_OFFSET, set_vi_handler(gic_cpu_pin + GIC_PIN_TO_VEC_OFFSET,
__gic_irq_dispatch); __gic_irq_dispatch);
} else { } else {
gic_cpu_pin = cpu_vec - GIC_CPU_PIN_OFFSET; gic_cpu_pin = cpu_vec - GIC_CPU_PIN_OFFSET;
irq_set_chained_handler(MIPS_CPU_IRQ_BASE + cpu_vec, irq_set_chained_handler(MIPS_CPU_IRQ_BASE + cpu_vec,
gic_irq_dispatch); gic_irq_dispatch);
/*
* With the CMP implementation of SMP (deprecated), other CPUs
* are started by the bootloader and put into a timer based
* waiting poll loop. We must not re-route those CPU's local
* timer interrupts as the wait instruction will never finish,
* so just handle whatever CPU interrupt it is routed to by
* default.
*
* This workaround should be removed when CMP support is
* dropped.
*/
if (IS_ENABLED(CONFIG_MIPS_CMP) &&
gic_local_irq_is_routable(GIC_LOCAL_INT_TIMER)) {
timer_cpu_pin = gic_read(GIC_REG(VPE_LOCAL,
GIC_VPE_TIMER_MAP)) &
GIC_MAP_MSK;
irq_set_chained_handler(MIPS_CPU_IRQ_BASE +
GIC_CPU_PIN_OFFSET +
timer_cpu_pin,
gic_irq_dispatch);
} else {
timer_cpu_pin = gic_cpu_pin;
}
} }
gic_irq_domain = irq_domain_add_simple(node, GIC_NUM_LOCAL_INTRS + gic_irq_domain = irq_domain_add_simple(node, GIC_NUM_LOCAL_INTRS +
......
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