Skip to content

Commit

Permalink
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upst…
Browse files Browse the repository at this point in the history
…ream-linus

Pull MIPS fixes from Ralf Baechle:
 "Lantiq:
    - Fix adding xbar resoures causing a panic

  Loongson3:
    - Some Loongson 3A don't identify themselves as having an FTLB so
      hardwire that knowledge into CPU probing.
    - Handle Loongson 3 TLB peculiarities in the fast path of the RDHWR
      emulation.
    - Fix invalid FTLB entries with huge page on VTLB+FTLB platforms
    - Add missing calculation of S-cache and V-cache cache-way size

  Ralink:
    - Fix typos in rt3883 pinctrl data

  Generic:
    - Force o32 fp64 support on 32bit MIPS64r6 kernels
    - Yet another build fix after the linux/sched.h changes
    - Wire up statx system call
    - Fix stack unwinding after introduction of IRQ stack
    - Fix spinlock code to build even for microMIPS with recent binutils

  SMP-CPS:
    - Fix retrieval of VPE mask on big endian CPUs"

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus:
  MIPS: IRQ Stack: Unwind IRQ stack onto task stack
  MIPS: c-r4k: Fix Loongson-3's vcache/scache waysize calculation
  MIPS: Flush wrong invalid FTLB entry for huge page
  MIPS: Check TLB before handle_ri_rdhwr() for Loongson-3
  MIPS: Add MIPS_CPU_FTLB for Loongson-3A R2
  MIPS: Lantiq: fix missing xbar kernel panic
  MIPS: smp-cps: Fix retrieval of VPE mask on big endian CPUs
  MIPS: Wire up statx system call
  MIPS: Include asm/ptrace.h now linux/sched.h doesn't
  MIPS: ralink: Fix typos in rt3883 pinctrl
  MIPS: End spinlocks with .insn
  MIPS: Force o32 fp64 support on 32bit MIPS64r6 kernels
  • Loading branch information
torvalds committed Apr 6, 2017
2 parents 4691f4a + db8466c commit 977674c
Show file tree
Hide file tree
Showing 19 changed files with 122 additions and 46 deletions.
2 changes: 1 addition & 1 deletion arch/mips/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1531,7 +1531,7 @@ config CPU_MIPS64_R6
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_MSA
select GENERIC_CSUM
select MIPS_O32_FP64_SUPPORT if MIPS32_O32
select MIPS_O32_FP64_SUPPORT if 32BIT || MIPS32_O32
select HAVE_KVM
help
Choose this option to build a kernel for release 6 or later of the
Expand Down
1 change: 1 addition & 0 deletions arch/mips/include/asm/fpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <asm/cpu-features.h>
#include <asm/fpu_emulator.h>
#include <asm/hazards.h>
#include <asm/ptrace.h>
#include <asm/processor.h>
#include <asm/current.h>
#include <asm/msa.h>
Expand Down
15 changes: 15 additions & 0 deletions arch/mips/include/asm/irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,24 @@
#include <irq.h>

#define IRQ_STACK_SIZE THREAD_SIZE
#define IRQ_STACK_START (IRQ_STACK_SIZE - sizeof(unsigned long))

extern void *irq_stack[NR_CPUS];

/*
* The highest address on the IRQ stack contains a dummy frame put down in
* genex.S (handle_int & except_vec_vi_handler) which is structured as follows:
*
* top ------------
* | task sp | <- irq_stack[cpu] + IRQ_STACK_START
* ------------
* | | <- First frame of IRQ context
* ------------
*
* task sp holds a copy of the task stack pointer where the struct pt_regs
* from exception entry can be found.
*/

static inline bool on_irq_stack(int cpu, unsigned long sp)
{
unsigned long low = (unsigned long)irq_stack[cpu];
Expand Down
8 changes: 4 additions & 4 deletions arch/mips/include/asm/spinlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ static inline void arch_spin_lock(arch_spinlock_t *lock)
" andi %[ticket], %[ticket], 0xffff \n"
" bne %[ticket], %[my_ticket], 4f \n"
" subu %[ticket], %[my_ticket], %[ticket] \n"
"2: \n"
"2: .insn \n"
" .subsection 2 \n"
"4: andi %[ticket], %[ticket], 0xffff \n"
" sll %[ticket], 5 \n"
Expand Down Expand Up @@ -202,7 +202,7 @@ static inline unsigned int arch_spin_trylock(arch_spinlock_t *lock)
" sc %[ticket], %[ticket_ptr] \n"
" beqz %[ticket], 1b \n"
" li %[ticket], 1 \n"
"2: \n"
"2: .insn \n"
" .subsection 2 \n"
"3: b 2b \n"
" li %[ticket], 0 \n"
Expand Down Expand Up @@ -382,7 +382,7 @@ static inline int arch_read_trylock(arch_rwlock_t *rw)
" .set reorder \n"
__WEAK_LLSC_MB
" li %2, 1 \n"
"2: \n"
"2: .insn \n"
: "=" GCC_OFF_SMALL_ASM() (rw->lock), "=&r" (tmp), "=&r" (ret)
: GCC_OFF_SMALL_ASM() (rw->lock)
: "memory");
Expand Down Expand Up @@ -422,7 +422,7 @@ static inline int arch_write_trylock(arch_rwlock_t *rw)
" lui %1, 0x8000 \n"
" sc %1, %0 \n"
" li %2, 1 \n"
"2: \n"
"2: .insn \n"
: "=" GCC_OFF_SMALL_ASM() (rw->lock), "=&r" (tmp),
"=&r" (ret)
: GCC_OFF_SMALL_ASM() (rw->lock)
Expand Down
15 changes: 9 additions & 6 deletions arch/mips/include/uapi/asm/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -386,17 +386,18 @@
#define __NR_pkey_mprotect (__NR_Linux + 363)
#define __NR_pkey_alloc (__NR_Linux + 364)
#define __NR_pkey_free (__NR_Linux + 365)
#define __NR_statx (__NR_Linux + 366)


/*
* Offset of the last Linux o32 flavoured syscall
*/
#define __NR_Linux_syscalls 365
#define __NR_Linux_syscalls 366

#endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */

#define __NR_O32_Linux 4000
#define __NR_O32_Linux_syscalls 365
#define __NR_O32_Linux_syscalls 366

#if _MIPS_SIM == _MIPS_SIM_ABI64

Expand Down Expand Up @@ -730,16 +731,17 @@
#define __NR_pkey_mprotect (__NR_Linux + 323)
#define __NR_pkey_alloc (__NR_Linux + 324)
#define __NR_pkey_free (__NR_Linux + 325)
#define __NR_statx (__NR_Linux + 326)

/*
* Offset of the last Linux 64-bit flavoured syscall
*/
#define __NR_Linux_syscalls 325
#define __NR_Linux_syscalls 326

#endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */

#define __NR_64_Linux 5000
#define __NR_64_Linux_syscalls 325
#define __NR_64_Linux_syscalls 326

#if _MIPS_SIM == _MIPS_SIM_NABI32

Expand Down Expand Up @@ -1077,15 +1079,16 @@
#define __NR_pkey_mprotect (__NR_Linux + 327)
#define __NR_pkey_alloc (__NR_Linux + 328)
#define __NR_pkey_free (__NR_Linux + 329)
#define __NR_statx (__NR_Linux + 330)

/*
* Offset of the last N32 flavoured syscall
*/
#define __NR_Linux_syscalls 329
#define __NR_Linux_syscalls 330

#endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */

#define __NR_N32_Linux 6000
#define __NR_N32_Linux_syscalls 329
#define __NR_N32_Linux_syscalls 330

#endif /* _UAPI_ASM_UNISTD_H */
1 change: 1 addition & 0 deletions arch/mips/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ void output_thread_info_defines(void)
DEFINE(_THREAD_SIZE, THREAD_SIZE);
DEFINE(_THREAD_MASK, THREAD_MASK);
DEFINE(_IRQ_STACK_SIZE, IRQ_STACK_SIZE);
DEFINE(_IRQ_STACK_START, IRQ_STACK_START);
BLANK();
}

Expand Down
2 changes: 1 addition & 1 deletion arch/mips/kernel/cps-vec.S
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ LEAF(mips_cps_get_bootcfg)
END(mips_cps_get_bootcfg)

LEAF(mips_cps_boot_vpes)
PTR_L ta2, COREBOOTCFG_VPEMASK(a0)
lw ta2, COREBOOTCFG_VPEMASK(a0)
PTR_L ta3, COREBOOTCFG_VPECONFIG(a0)

#if defined(CONFIG_CPU_MIPSR6)
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/kernel/cpu-probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -1824,7 +1824,7 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
}

decode_configs(c);
c->options |= MIPS_CPU_TLBINV | MIPS_CPU_LDPTE;
c->options |= MIPS_CPU_FTLB | MIPS_CPU_TLBINV | MIPS_CPU_LDPTE;
c->writecombine = _CACHE_UNCACHED_ACCELERATED;
break;
default:
Expand Down
12 changes: 8 additions & 4 deletions arch/mips/kernel/genex.S
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,11 @@ NESTED(handle_int, PT_SIZE, sp)
beq t0, t1, 2f

/* Switch to IRQ stack */
li t1, _IRQ_STACK_SIZE
li t1, _IRQ_STACK_START
PTR_ADD sp, t0, t1

/* Save task's sp on IRQ stack so that unwinding can follow it */
LONG_S s1, 0(sp)
2:
jal plat_irq_dispatch

Expand Down Expand Up @@ -325,9 +327,11 @@ NESTED(except_vec_vi_handler, 0, sp)
beq t0, t1, 2f

/* Switch to IRQ stack */
li t1, _IRQ_STACK_SIZE
li t1, _IRQ_STACK_START
PTR_ADD sp, t0, t1

/* Save task's sp on IRQ stack so that unwinding can follow it */
LONG_S s1, 0(sp)
2:
jalr v0

Expand Down Expand Up @@ -519,7 +523,7 @@ NESTED(nmi_handler, PT_SIZE, sp)
BUILD_HANDLER reserved reserved sti verbose /* others */

.align 5
LEAF(handle_ri_rdhwr_vivt)
LEAF(handle_ri_rdhwr_tlbp)
.set push
.set noat
.set noreorder
Expand All @@ -538,7 +542,7 @@ NESTED(nmi_handler, PT_SIZE, sp)
.set pop
bltz k1, handle_ri /* slow path */
/* fall thru */
END(handle_ri_rdhwr_vivt)
END(handle_ri_rdhwr_tlbp)

LEAF(handle_ri_rdhwr)
.set push
Expand Down
56 changes: 38 additions & 18 deletions arch/mips/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,31 +488,52 @@ unsigned long notrace unwind_stack_by_address(unsigned long stack_page,
unsigned long pc,
unsigned long *ra)
{
unsigned long low, high, irq_stack_high;
struct mips_frame_info info;
unsigned long size, ofs;
struct pt_regs *regs;
int leaf;
extern void ret_from_irq(void);
extern void ret_from_exception(void);

if (!stack_page)
return 0;

/*
* If we reached the bottom of interrupt context,
* return saved pc in pt_regs.
* IRQ stacks start at IRQ_STACK_START
* task stacks at THREAD_SIZE - 32
*/
if (pc == (unsigned long)ret_from_irq ||
pc == (unsigned long)ret_from_exception) {
struct pt_regs *regs;
if (*sp >= stack_page &&
*sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) {
regs = (struct pt_regs *)*sp;
pc = regs->cp0_epc;
if (!user_mode(regs) && __kernel_text_address(pc)) {
*sp = regs->regs[29];
*ra = regs->regs[31];
return pc;
}
low = stack_page;
if (!preemptible() && on_irq_stack(raw_smp_processor_id(), *sp)) {
high = stack_page + IRQ_STACK_START;
irq_stack_high = high;
} else {
high = stack_page + THREAD_SIZE - 32;
irq_stack_high = 0;
}

/*
* If we reached the top of the interrupt stack, start unwinding
* the interrupted task stack.
*/
if (unlikely(*sp == irq_stack_high)) {
unsigned long task_sp = *(unsigned long *)*sp;

/*
* Check that the pointer saved in the IRQ stack head points to
* something within the stack of the current task
*/
if (!object_is_on_stack((void *)task_sp))
return 0;

/*
* Follow pointer to tasks kernel stack frame where interrupted
* state was saved.
*/
regs = (struct pt_regs *)task_sp;
pc = regs->cp0_epc;
if (!user_mode(regs) && __kernel_text_address(pc)) {
*sp = regs->regs[29];
*ra = regs->regs[31];
return pc;
}
return 0;
}
Expand All @@ -533,8 +554,7 @@ unsigned long notrace unwind_stack_by_address(unsigned long stack_page,
if (leaf < 0)
return 0;

if (*sp < stack_page ||
*sp + info.frame_size > stack_page + THREAD_SIZE - 32)
if (*sp < low || *sp + info.frame_size > high)
return 0;

if (leaf)
Expand Down
1 change: 1 addition & 0 deletions arch/mips/kernel/scall32-o32.S
Original file line number Diff line number Diff line change
Expand Up @@ -600,3 +600,4 @@ EXPORT(sys_call_table)
PTR sys_pkey_mprotect
PTR sys_pkey_alloc
PTR sys_pkey_free /* 4365 */
PTR sys_statx
1 change: 1 addition & 0 deletions arch/mips/kernel/scall64-64.S
Original file line number Diff line number Diff line change
Expand Up @@ -438,4 +438,5 @@ EXPORT(sys_call_table)
PTR sys_pkey_mprotect
PTR sys_pkey_alloc
PTR sys_pkey_free /* 5325 */
PTR sys_statx
.size sys_call_table,.-sys_call_table
1 change: 1 addition & 0 deletions arch/mips/kernel/scall64-n32.S
Original file line number Diff line number Diff line change
Expand Up @@ -433,4 +433,5 @@ EXPORT(sysn32_call_table)
PTR sys_pkey_mprotect
PTR sys_pkey_alloc
PTR sys_pkey_free
PTR sys_statx /* 6330 */
.size sysn32_call_table,.-sysn32_call_table
1 change: 1 addition & 0 deletions arch/mips/kernel/scall64-o32.S
Original file line number Diff line number Diff line change
Expand Up @@ -588,4 +588,5 @@ EXPORT(sys32_call_table)
PTR sys_pkey_mprotect
PTR sys_pkey_alloc
PTR sys_pkey_free /* 4365 */
PTR sys_statx
.size sys32_call_table,.-sys32_call_table
17 changes: 13 additions & 4 deletions arch/mips/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ extern asmlinkage void handle_dbe(void);
extern asmlinkage void handle_sys(void);
extern asmlinkage void handle_bp(void);
extern asmlinkage void handle_ri(void);
extern asmlinkage void handle_ri_rdhwr_vivt(void);
extern asmlinkage void handle_ri_rdhwr_tlbp(void);
extern asmlinkage void handle_ri_rdhwr(void);
extern asmlinkage void handle_cpu(void);
extern asmlinkage void handle_ov(void);
Expand Down Expand Up @@ -2408,9 +2408,18 @@ void __init trap_init(void)

set_except_vector(EXCCODE_SYS, handle_sys);
set_except_vector(EXCCODE_BP, handle_bp);
set_except_vector(EXCCODE_RI, rdhwr_noopt ? handle_ri :
(cpu_has_vtag_icache ?
handle_ri_rdhwr_vivt : handle_ri_rdhwr));

if (rdhwr_noopt)
set_except_vector(EXCCODE_RI, handle_ri);
else {
if (cpu_has_vtag_icache)
set_except_vector(EXCCODE_RI, handle_ri_rdhwr_tlbp);
else if (current_cpu_type() == CPU_LOONGSON3)
set_except_vector(EXCCODE_RI, handle_ri_rdhwr_tlbp);
else
set_except_vector(EXCCODE_RI, handle_ri_rdhwr);
}

set_except_vector(EXCCODE_CPU, handle_cpu);
set_except_vector(EXCCODE_OV, handle_ov);
set_except_vector(EXCCODE_TR, handle_tr);
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/lantiq/xway/sysctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ void __init ltq_soc_init(void)

if (!np_xbar)
panic("Failed to load xbar nodes from devicetree");
if (of_address_to_resource(np_pmu, 0, &res_xbar))
if (of_address_to_resource(np_xbar, 0, &res_xbar))
panic("Failed to get xbar resources");
if (!request_mem_region(res_xbar.start, resource_size(&res_xbar),
res_xbar.name))
Expand Down
2 changes: 2 additions & 0 deletions arch/mips/mm/c-r4k.c
Original file line number Diff line number Diff line change
Expand Up @@ -1562,6 +1562,7 @@ static void probe_vcache(void)
vcache_size = c->vcache.sets * c->vcache.ways * c->vcache.linesz;

c->vcache.waybit = 0;
c->vcache.waysize = vcache_size / c->vcache.ways;

pr_info("Unified victim cache %ldkB %s, linesize %d bytes.\n",
vcache_size >> 10, way_string[c->vcache.ways], c->vcache.linesz);
Expand Down Expand Up @@ -1664,6 +1665,7 @@ static void __init loongson3_sc_init(void)
/* Loongson-3 has 4 cores, 1MB scache for each. scaches are shared */
scache_size *= 4;
c->scache.waybit = 0;
c->scache.waysize = scache_size / c->scache.ways;
pr_info("Unified secondary cache %ldkB %s, linesize %d bytes.\n",
scache_size >> 10, way_string[c->scache.ways], c->scache.linesz);
if (scache_size)
Expand Down
Loading

0 comments on commit 977674c

Please sign in to comment.