Commit ab57a611 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:
 "Here's the first round of MIPS fixes after the merge window:

   - Detect Octeon III's PCI correctly.
   - Fix return value of the MT7620 probing function.
   - Wire up the copy_file_range syscall.
   - Fix 64k page support on 32 bit kernels.
   - Fix the early Coherency Manager probe.
   - Allow only hardware-supported page sizes to be selected for R6000.
   - Fix corner cases for the RDHWR nstruction emulation on old hardware.
   - Fix FPU handling corner cases.
   - Remove stale entry for BCM33xx from the MAINTAINERS file.
   - 32 and 64 bit ELF headers are different, handle them correctly"

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus:
  mips: Differentiate between 32 and 64 bit ELF header
  MIPS: Octeon: Update OCTEON_FEATURE_PCIE for Octeon III
  MIPS: pci-mt7620: Fix return value check in mt7620_pci_probe()
  MIPS: Fix early CM probing
  MIPS: Wire up copy_file_range syscall.
  MIPS: Fix 64k page support for 32 bit kernels.
  MIPS: R6000: Don't allow 64k pages for R6000.
  MIPS: traps.c: Correct microMIPS RDHWR emulation
  MIPS: traps.c: Don't emulate RDHWR in the CpU #0 exception handler
  MAINTAINERS: Remove stale entry for BCM33xx chips
  MIPS: Fix FPU disable with preemption
  MIPS: Properly disable FPU in start_thread()
  MIPS: Fix buffer overflow in syscall_get_arguments()
parents be3f4e0f f4d3d504
...@@ -2362,14 +2362,6 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rpi/linux-rpi.git ...@@ -2362,14 +2362,6 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rpi/linux-rpi.git
S: Maintained S: Maintained
N: bcm2835 N: bcm2835
BROADCOM BCM33XX MIPS ARCHITECTURE
M: Kevin Cernekee <cernekee@gmail.com>
L: linux-mips@linux-mips.org
S: Maintained
F: arch/mips/bcm3384/*
F: arch/mips/include/asm/mach-bcm3384/*
F: arch/mips/kernel/*bmips*
BROADCOM BCM47XX MIPS ARCHITECTURE BROADCOM BCM47XX MIPS ARCHITECTURE
M: Hauke Mehrtens <hauke@hauke-m.de> M: Hauke Mehrtens <hauke@hauke-m.de>
M: Rafał Miłecki <zajec5@gmail.com> M: Rafał Miłecki <zajec5@gmail.com>
......
...@@ -2085,7 +2085,7 @@ config PAGE_SIZE_32KB ...@@ -2085,7 +2085,7 @@ config PAGE_SIZE_32KB
config PAGE_SIZE_64KB config PAGE_SIZE_64KB
bool "64kB" bool "64kB"
depends on !CPU_R3000 && !CPU_TX39XX depends on !CPU_R3000 && !CPU_TX39XX && !CPU_R6000
help help
Using 64kB page size will result in higher performance kernel at Using 64kB page size will result in higher performance kernel at
the price of higher memory consumption. This option is available on the price of higher memory consumption. This option is available on
......
...@@ -227,7 +227,7 @@ struct mips_elf_abiflags_v0 { ...@@ -227,7 +227,7 @@ struct mips_elf_abiflags_v0 {
int __res = 1; \ int __res = 1; \
struct elfhdr *__h = (hdr); \ struct elfhdr *__h = (hdr); \
\ \
if (__h->e_machine != EM_MIPS) \ if (!mips_elf_check_machine(__h)) \
__res = 0; \ __res = 0; \
if (__h->e_ident[EI_CLASS] != ELFCLASS32) \ if (__h->e_ident[EI_CLASS] != ELFCLASS32) \
__res = 0; \ __res = 0; \
...@@ -258,7 +258,7 @@ struct mips_elf_abiflags_v0 { ...@@ -258,7 +258,7 @@ struct mips_elf_abiflags_v0 {
int __res = 1; \ int __res = 1; \
struct elfhdr *__h = (hdr); \ struct elfhdr *__h = (hdr); \
\ \
if (__h->e_machine != EM_MIPS) \ if (!mips_elf_check_machine(__h)) \
__res = 0; \ __res = 0; \
if (__h->e_ident[EI_CLASS] != ELFCLASS64) \ if (__h->e_ident[EI_CLASS] != ELFCLASS64) \
__res = 0; \ __res = 0; \
...@@ -285,6 +285,11 @@ struct mips_elf_abiflags_v0 { ...@@ -285,6 +285,11 @@ struct mips_elf_abiflags_v0 {
#endif /* !defined(ELF_ARCH) */ #endif /* !defined(ELF_ARCH) */
#define mips_elf_check_machine(x) ((x)->e_machine == EM_MIPS)
#define vmcore_elf32_check_arch mips_elf_check_machine
#define vmcore_elf64_check_arch mips_elf_check_machine
struct mips_abi; struct mips_abi;
extern struct mips_abi mips_abi; extern struct mips_abi mips_abi;
......
...@@ -179,6 +179,10 @@ static inline void lose_fpu_inatomic(int save, struct task_struct *tsk) ...@@ -179,6 +179,10 @@ static inline void lose_fpu_inatomic(int save, struct task_struct *tsk)
if (save) if (save)
_save_fp(tsk); _save_fp(tsk);
__disable_fpu(); __disable_fpu();
} else {
/* FPU should not have been left enabled with no owner */
WARN(read_c0_status() & ST0_CU1,
"Orphaned FPU left enabled");
} }
KSTK_STATUS(tsk) &= ~ST0_CU1; KSTK_STATUS(tsk) &= ~ST0_CU1;
clear_tsk_thread_flag(tsk, TIF_USEDFPU); clear_tsk_thread_flag(tsk, TIF_USEDFPU);
......
...@@ -128,7 +128,8 @@ static inline int octeon_has_feature(enum octeon_feature feature) ...@@ -128,7 +128,8 @@ static inline int octeon_has_feature(enum octeon_feature feature)
case OCTEON_FEATURE_PCIE: case OCTEON_FEATURE_PCIE:
return OCTEON_IS_MODEL(OCTEON_CN56XX) return OCTEON_IS_MODEL(OCTEON_CN56XX)
|| OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)
|| OCTEON_IS_MODEL(OCTEON_CN6XXX); || OCTEON_IS_MODEL(OCTEON_CN6XXX)
|| OCTEON_IS_MODEL(OCTEON_CN7XXX);
case OCTEON_FEATURE_SRIO: case OCTEON_FEATURE_SRIO:
return OCTEON_IS_MODEL(OCTEON_CN63XX) return OCTEON_IS_MODEL(OCTEON_CN63XX)
......
...@@ -45,7 +45,7 @@ extern unsigned int vced_count, vcei_count; ...@@ -45,7 +45,7 @@ extern unsigned int vced_count, vcei_count;
* User space process size: 2GB. This is hardcoded into a few places, * User space process size: 2GB. This is hardcoded into a few places,
* so don't change it unless you know what you are doing. * so don't change it unless you know what you are doing.
*/ */
#define TASK_SIZE 0x7fff8000UL #define TASK_SIZE 0x80000000UL
#endif #endif
#define STACK_TOP_MAX TASK_SIZE #define STACK_TOP_MAX TASK_SIZE
......
...@@ -289,7 +289,7 @@ ...@@ -289,7 +289,7 @@
.set reorder .set reorder
.set noat .set noat
mfc0 a0, CP0_STATUS mfc0 a0, CP0_STATUS
li v1, 0xff00 li v1, ST0_CU1 | ST0_IM
ori a0, STATMASK ori a0, STATMASK
xori a0, STATMASK xori a0, STATMASK
mtc0 a0, CP0_STATUS mtc0 a0, CP0_STATUS
...@@ -330,7 +330,7 @@ ...@@ -330,7 +330,7 @@
ori a0, STATMASK ori a0, STATMASK
xori a0, STATMASK xori a0, STATMASK
mtc0 a0, CP0_STATUS mtc0 a0, CP0_STATUS
li v1, 0xff00 li v1, ST0_CU1 | ST0_FR | ST0_IM
and a0, v1 and a0, v1
LONG_L v0, PT_STATUS(sp) LONG_L v0, PT_STATUS(sp)
nor v1, $0, v1 nor v1, $0, v1
......
...@@ -101,10 +101,8 @@ static inline void syscall_get_arguments(struct task_struct *task, ...@@ -101,10 +101,8 @@ static inline void syscall_get_arguments(struct task_struct *task,
/* O32 ABI syscall() - Either 64-bit with O32 or 32-bit */ /* O32 ABI syscall() - Either 64-bit with O32 or 32-bit */
if ((config_enabled(CONFIG_32BIT) || if ((config_enabled(CONFIG_32BIT) ||
test_tsk_thread_flag(task, TIF_32BIT_REGS)) && test_tsk_thread_flag(task, TIF_32BIT_REGS)) &&
(regs->regs[2] == __NR_syscall)) { (regs->regs[2] == __NR_syscall))
i++; i++;
n++;
}
while (n--) while (n--)
ret |= mips_get_syscall_arg(args++, task, regs, i++); ret |= mips_get_syscall_arg(args++, task, regs, i++);
......
...@@ -380,16 +380,17 @@ ...@@ -380,16 +380,17 @@
#define __NR_userfaultfd (__NR_Linux + 357) #define __NR_userfaultfd (__NR_Linux + 357)
#define __NR_membarrier (__NR_Linux + 358) #define __NR_membarrier (__NR_Linux + 358)
#define __NR_mlock2 (__NR_Linux + 359) #define __NR_mlock2 (__NR_Linux + 359)
#define __NR_copy_file_range (__NR_Linux + 360)
/* /*
* Offset of the last Linux o32 flavoured syscall * Offset of the last Linux o32 flavoured syscall
*/ */
#define __NR_Linux_syscalls 359 #define __NR_Linux_syscalls 360
#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 359 #define __NR_O32_Linux_syscalls 360
#if _MIPS_SIM == _MIPS_SIM_ABI64 #if _MIPS_SIM == _MIPS_SIM_ABI64
...@@ -717,16 +718,17 @@ ...@@ -717,16 +718,17 @@
#define __NR_userfaultfd (__NR_Linux + 317) #define __NR_userfaultfd (__NR_Linux + 317)
#define __NR_membarrier (__NR_Linux + 318) #define __NR_membarrier (__NR_Linux + 318)
#define __NR_mlock2 (__NR_Linux + 319) #define __NR_mlock2 (__NR_Linux + 319)
#define __NR_copy_file_range (__NR_Linux + 320)
/* /*
* Offset of the last Linux 64-bit flavoured syscall * Offset of the last Linux 64-bit flavoured syscall
*/ */
#define __NR_Linux_syscalls 319 #define __NR_Linux_syscalls 320
#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 319 #define __NR_64_Linux_syscalls 320
#if _MIPS_SIM == _MIPS_SIM_NABI32 #if _MIPS_SIM == _MIPS_SIM_NABI32
...@@ -1058,15 +1060,16 @@ ...@@ -1058,15 +1060,16 @@
#define __NR_userfaultfd (__NR_Linux + 321) #define __NR_userfaultfd (__NR_Linux + 321)
#define __NR_membarrier (__NR_Linux + 322) #define __NR_membarrier (__NR_Linux + 322)
#define __NR_mlock2 (__NR_Linux + 323) #define __NR_mlock2 (__NR_Linux + 323)
#define __NR_copy_file_range (__NR_Linux + 324)
/* /*
* Offset of the last N32 flavoured syscall * Offset of the last N32 flavoured syscall
*/ */
#define __NR_Linux_syscalls 323 #define __NR_Linux_syscalls 324
#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 323 #define __NR_N32_Linux_syscalls 324
#endif /* _UAPI_ASM_UNISTD_H */ #endif /* _UAPI_ASM_UNISTD_H */
...@@ -35,7 +35,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; ...@@ -35,7 +35,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
int __res = 1; \ int __res = 1; \
struct elfhdr *__h = (hdr); \ struct elfhdr *__h = (hdr); \
\ \
if (__h->e_machine != EM_MIPS) \ if (!mips_elf_check_machine(__h)) \
__res = 0; \ __res = 0; \
if (__h->e_ident[EI_CLASS] != ELFCLASS32) \ if (__h->e_ident[EI_CLASS] != ELFCLASS32) \
__res = 0; \ __res = 0; \
......
...@@ -47,7 +47,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; ...@@ -47,7 +47,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
int __res = 1; \ int __res = 1; \
struct elfhdr *__h = (hdr); \ struct elfhdr *__h = (hdr); \
\ \
if (__h->e_machine != EM_MIPS) \ if (!mips_elf_check_machine(__h)) \
__res = 0; \ __res = 0; \
if (__h->e_ident[EI_CLASS] != ELFCLASS32) \ if (__h->e_ident[EI_CLASS] != ELFCLASS32) \
__res = 0; \ __res = 0; \
......
...@@ -65,12 +65,10 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) ...@@ -65,12 +65,10 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
status = regs->cp0_status & ~(ST0_CU0|ST0_CU1|ST0_FR|KU_MASK); status = regs->cp0_status & ~(ST0_CU0|ST0_CU1|ST0_FR|KU_MASK);
status |= KU_USER; status |= KU_USER;
regs->cp0_status = status; regs->cp0_status = status;
lose_fpu(0);
clear_thread_flag(TIF_MSA_CTX_LIVE);
clear_used_math(); clear_used_math();
clear_fpu_owner();
init_dsp(); init_dsp();
clear_thread_flag(TIF_USEDMSA);
clear_thread_flag(TIF_MSA_CTX_LIVE);
disable_msa();
regs->cp0_epc = pc; regs->cp0_epc = pc;
regs->regs[29] = sp; regs->regs[29] = sp;
} }
......
...@@ -595,3 +595,4 @@ EXPORT(sys_call_table) ...@@ -595,3 +595,4 @@ EXPORT(sys_call_table)
PTR sys_userfaultfd PTR sys_userfaultfd
PTR sys_membarrier PTR sys_membarrier
PTR sys_mlock2 PTR sys_mlock2
PTR sys_copy_file_range /* 4360 */
...@@ -433,4 +433,5 @@ EXPORT(sys_call_table) ...@@ -433,4 +433,5 @@ EXPORT(sys_call_table)
PTR sys_userfaultfd PTR sys_userfaultfd
PTR sys_membarrier PTR sys_membarrier
PTR sys_mlock2 PTR sys_mlock2
PTR sys_copy_file_range /* 5320 */
.size sys_call_table,.-sys_call_table .size sys_call_table,.-sys_call_table
...@@ -423,4 +423,5 @@ EXPORT(sysn32_call_table) ...@@ -423,4 +423,5 @@ EXPORT(sysn32_call_table)
PTR sys_userfaultfd PTR sys_userfaultfd
PTR sys_membarrier PTR sys_membarrier
PTR sys_mlock2 PTR sys_mlock2
PTR sys_copy_file_range
.size sysn32_call_table,.-sysn32_call_table .size sysn32_call_table,.-sysn32_call_table
...@@ -578,4 +578,5 @@ EXPORT(sys32_call_table) ...@@ -578,4 +578,5 @@ EXPORT(sys32_call_table)
PTR sys_userfaultfd PTR sys_userfaultfd
PTR sys_membarrier PTR sys_membarrier
PTR sys_mlock2 PTR sys_mlock2
PTR sys_copy_file_range /* 4360 */
.size sys32_call_table,.-sys32_call_table .size sys32_call_table,.-sys32_call_table
...@@ -782,6 +782,7 @@ static inline void prefill_possible_map(void) {} ...@@ -782,6 +782,7 @@ static inline void prefill_possible_map(void) {}
void __init setup_arch(char **cmdline_p) void __init setup_arch(char **cmdline_p)
{ {
cpu_probe(); cpu_probe();
mips_cm_probe();
prom_init(); prom_init();
setup_early_fdc_console(); setup_early_fdc_console();
......
...@@ -663,7 +663,7 @@ static int simulate_rdhwr_normal(struct pt_regs *regs, unsigned int opcode) ...@@ -663,7 +663,7 @@ static int simulate_rdhwr_normal(struct pt_regs *regs, unsigned int opcode)
return -1; return -1;
} }
static int simulate_rdhwr_mm(struct pt_regs *regs, unsigned short opcode) static int simulate_rdhwr_mm(struct pt_regs *regs, unsigned int opcode)
{ {
if ((opcode & MM_POOL32A_FUNC) == MM_RDHWR) { if ((opcode & MM_POOL32A_FUNC) == MM_RDHWR) {
int rd = (opcode & MM_RS) >> 16; int rd = (opcode & MM_RS) >> 16;
...@@ -1119,11 +1119,12 @@ asmlinkage void do_ri(struct pt_regs *regs) ...@@ -1119,11 +1119,12 @@ asmlinkage void do_ri(struct pt_regs *regs)
if (get_isa16_mode(regs->cp0_epc)) { if (get_isa16_mode(regs->cp0_epc)) {
unsigned short mmop[2] = { 0 }; unsigned short mmop[2] = { 0 };
if (unlikely(get_user(mmop[0], epc) < 0)) if (unlikely(get_user(mmop[0], (u16 __user *)epc + 0) < 0))
status = SIGSEGV; status = SIGSEGV;
if (unlikely(get_user(mmop[1], epc) < 0)) if (unlikely(get_user(mmop[1], (u16 __user *)epc + 1) < 0))
status = SIGSEGV; status = SIGSEGV;
opcode = (mmop[0] << 16) | mmop[1]; opcode = mmop[0];
opcode = (opcode << 16) | mmop[1];
if (status < 0) if (status < 0)
status = simulate_rdhwr_mm(regs, opcode); status = simulate_rdhwr_mm(regs, opcode);
...@@ -1369,26 +1370,12 @@ asmlinkage void do_cpu(struct pt_regs *regs) ...@@ -1369,26 +1370,12 @@ asmlinkage void do_cpu(struct pt_regs *regs)
if (unlikely(compute_return_epc(regs) < 0)) if (unlikely(compute_return_epc(regs) < 0))
break; break;
if (get_isa16_mode(regs->cp0_epc)) { if (!get_isa16_mode(regs->cp0_epc)) {
unsigned short mmop[2] = { 0 };
if (unlikely(get_user(mmop[0], epc) < 0))
status = SIGSEGV;
if (unlikely(get_user(mmop[1], epc) < 0))
status = SIGSEGV;
opcode = (mmop[0] << 16) | mmop[1];
if (status < 0)
status = simulate_rdhwr_mm(regs, opcode);
} else {
if (unlikely(get_user(opcode, epc) < 0)) if (unlikely(get_user(opcode, epc) < 0))
status = SIGSEGV; status = SIGSEGV;
if (!cpu_has_llsc && status < 0) if (!cpu_has_llsc && status < 0)
status = simulate_llsc(regs, opcode); status = simulate_llsc(regs, opcode);
if (status < 0)
status = simulate_rdhwr_normal(regs, opcode);
} }
if (status < 0) if (status < 0)
......
...@@ -181,10 +181,6 @@ static int __init mips_sc_probe_cm3(void) ...@@ -181,10 +181,6 @@ static int __init mips_sc_probe_cm3(void)
return 1; return 1;
} }
void __weak platform_early_l2_init(void)
{
}
static inline int __init mips_sc_probe(void) static inline int __init mips_sc_probe(void)
{ {
struct cpuinfo_mips *c = &current_cpu_data; struct cpuinfo_mips *c = &current_cpu_data;
...@@ -194,12 +190,6 @@ static inline int __init mips_sc_probe(void) ...@@ -194,12 +190,6 @@ static inline int __init mips_sc_probe(void)
/* Mark as not present until probe completed */ /* Mark as not present until probe completed */
c->scache.flags |= MIPS_CACHE_NOT_PRESENT; c->scache.flags |= MIPS_CACHE_NOT_PRESENT;
/*
* Do we need some platform specific probing before
* we configure L2?
*/
platform_early_l2_init();
if (mips_cm_revision() >= CM_REV_CM3) if (mips_cm_revision() >= CM_REV_CM3)
return mips_sc_probe_cm3(); return mips_sc_probe_cm3();
......
...@@ -293,7 +293,6 @@ void __init prom_init(void) ...@@ -293,7 +293,6 @@ void __init prom_init(void)
console_config(); console_config();
#endif #endif
/* Early detection of CMP support */ /* Early detection of CMP support */
mips_cm_probe();
mips_cpc_probe(); mips_cpc_probe();
if (!register_cps_smp_ops()) if (!register_cps_smp_ops())
...@@ -304,10 +303,3 @@ void __init prom_init(void) ...@@ -304,10 +303,3 @@ void __init prom_init(void)
return; return;
register_up_smp_ops(); register_up_smp_ops();
} }
void platform_early_l2_init(void)
{
/* L2 configuration lives in the CM3 */
if (mips_cm_revision() >= CM_REV_CM3)
mips_cm_probe();
}
...@@ -297,12 +297,12 @@ static int mt7620_pci_probe(struct platform_device *pdev) ...@@ -297,12 +297,12 @@ static int mt7620_pci_probe(struct platform_device *pdev)
return PTR_ERR(rstpcie0); return PTR_ERR(rstpcie0);
bridge_base = devm_ioremap_resource(&pdev->dev, bridge_res); bridge_base = devm_ioremap_resource(&pdev->dev, bridge_res);
if (!bridge_base) if (IS_ERR(bridge_base))
return -ENOMEM; return PTR_ERR(bridge_base);
pcie_base = devm_ioremap_resource(&pdev->dev, pcie_res); pcie_base = devm_ioremap_resource(&pdev->dev, pcie_res);
if (!pcie_base) if (IS_ERR(pcie_base))
return -ENOMEM; return PTR_ERR(pcie_base);
iomem_resource.start = 0; iomem_resource.start = 0;
iomem_resource.end = ~0; iomem_resource.end = ~0;
......
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