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). ...
This commit is contained in:
commit
dbf3b7ddba
|
@ -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
|
||||||
|
|
||||||
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 @@
|
||||||
/*
|
/*
|
||||||
* 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[])
|
||||||
|
|
||||||
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) {
|
case PT_LOAD:
|
||||||
|
/* Writable (data) segment? */
|
||||||
|
if (ph[i].p_flags & PF_W) {
|
||||||
|
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(&bss, &nbss, 1);
|
||||||
|
} else {
|
||||||
|
struct sect ntxt;
|
||||||
|
|
||||||
|
ntxt.vaddr = ph[i].p_vaddr;
|
||||||
|
ntxt.len = ph[i].p_filesz;
|
||||||
|
|
||||||
|
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,
|
fprintf(stderr,
|
||||||
"Program header %d type %d can't be converted.\n",
|
"Program header %d type %d can't be converted.\n",
|
||||||
ex.e_phnum, ph[i].p_type);
|
ex.e_phnum, ph[i].p_type);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
/* Writable (data) segment? */
|
|
||||||
if (ph[i].p_flags & PF_W) {
|
|
||||||
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(&bss, &nbss, 1);
|
|
||||||
} else {
|
|
||||||
struct sect ntxt;
|
|
||||||
|
|
||||||
ntxt.vaddr = ph[i].p_vaddr;
|
|
||||||
ntxt.len = ph[i].p_filesz;
|
|
||||||
|
|
||||||
combine(&text, &ntxt, 0);
|
|
||||||
}
|
|
||||||
/* 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)
|
||||||
|
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
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
|
||||||
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)
|
||||||
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)
|
||||||
#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)
|
||||||
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 {
|
||||||
#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 {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 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 {
|
||||||
#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)
|
||||||
|
|
||||||
/* 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 { \
|
||||||
__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 @@
|
||||||
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 {
|
||||||
*/
|
*/
|
||||||
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 @@
|
||||||
#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 @@
|
||||||
#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 @@
|
||||||
#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 @@
|
||||||
#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 {
|
||||||
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,
|
||||||
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)
|
||||||
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 = {
|
||||||
.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 = {
|
||||||
.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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
|
||||||
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)
|
||||||
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:
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
struct cpuinfo_mips *c __maybe_unused = ¤t_cpu_data;
|
struct cpuinfo_mips *c __maybe_unused = ¤t_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)
|
||||||
#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)
|
||||||
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)
|
||||||
|
|
||||||
/* 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)
|
||||||
#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;
|
||||||
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,
|
||||||
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,
|
||||||
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 +
|
||||||
|
|
Loading…
Reference in New Issue