Skip to content

Commit

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

* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus:
  [MIPS] User stack pointer randomisation
  [MIPS] Remove unused include/asm-mips/gfx.h
  [MIPS] Remove unused include/asm-mips/ds1216.h
  [MIPS] Workaround for RM7000 WAIT instruction aka erratum 38
  [MIPS] Make support for weakly ordered LL/SC a config option.
  [MIPS] Disable UserLocal runtime detection on platforms which never have it.
  [MIPS] Disable MT runtime detection on platforms which never support MT.
  • Loading branch information
Linus Torvalds committed Jul 20, 2007
2 parents 0b1937a + 9410910 commit 02d6112
Show file tree
Hide file tree
Showing 20 changed files with 125 additions and 134 deletions.
11 changes: 11 additions & 0 deletions arch/mips/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1190,8 +1190,19 @@ config SYS_HAS_CPU_RM9000
config SYS_HAS_CPU_SB1
bool

#
# CPU may reorder R->R, R->W, W->R, W->W
# Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC
#
config WEAK_ORDERING
bool

#
# CPU may reorder reads and writes beyond LL/SC
# CPU may reorder R->LL, R->LL, W->LL, W->LL, R->SC, R->SC, W->SC, W->SC
#
config WEAK_REORDERING_BEYOND_LLSC
bool
endmenu

#
Expand Down
26 changes: 25 additions & 1 deletion arch/mips/kernel/cpu-probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,27 @@ static void r4k_wait_irqoff(void)
local_irq_enable();
}

/*
* The RM7000 variant has to handle erratum 38. The workaround is to not
* have any pending stores when the WAIT instruction is executed.
*/
static void rm7k_wait_irqoff(void)
{
local_irq_disable();
if (!need_resched())
__asm__(
" .set push \n"
" .set mips3 \n"
" .set noat \n"
" mfc0 $1, $12 \n"
" sync \n"
" mtc0 $1, $12 # stalls until W stage \n"
" wait \n"
" mtc0 $1, $12 # stalls until W stage \n"
" .set pop \n");
local_irq_enable();
}

/* The Au1xxx wait is available only if using 32khz counter or
* external timer source, but specifically not CP0 Counter. */
int allow_au1k_wait;
Expand Down Expand Up @@ -132,7 +153,6 @@ static inline void check_wait(void)
case CPU_R4700:
case CPU_R5000:
case CPU_NEVADA:
case CPU_RM7000:
case CPU_4KC:
case CPU_4KEC:
case CPU_4KSC:
Expand All @@ -142,6 +162,10 @@ static inline void check_wait(void)
cpu_wait = r4k_wait;
break;

case CPU_RM7000:
cpu_wait = rm7k_wait_irqoff;
break;

case CPU_24K:
case CPU_34K:
cpu_wait = r4k_wait;
Expand Down
14 changes: 14 additions & 0 deletions arch/mips/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
#include <linux/init.h>
#include <linux/completion.h>
#include <linux/kallsyms.h>
#include <linux/random.h>

#include <asm/asm.h>
#include <asm/bootinfo.h>
#include <asm/cpu.h>
#include <asm/dsp.h>
Expand Down Expand Up @@ -460,3 +462,15 @@ unsigned long get_wchan(struct task_struct *task)
out:
return pc;
}

/*
* Don't forget that the stack pointer must be aligned on a 8 bytes
* boundary for 32-bits ABI and 16 bytes for 64-bits ABI.
*/
unsigned long arch_align_stack(unsigned long sp)
{
if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
sp -= get_random_int() & ~PAGE_MASK;

return sp & ALMASK;
}
33 changes: 17 additions & 16 deletions include/asm-mips/atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
{
unsigned long result;

smp_mb();
smp_llsc_mb();

if (cpu_has_llsc && R10000_LLSC_WAR) {
unsigned long temp;
Expand Down Expand Up @@ -181,7 +181,7 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
raw_local_irq_restore(flags);
}

smp_mb();
smp_llsc_mb();

return result;
}
Expand All @@ -190,7 +190,7 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
{
unsigned long result;

smp_mb();
smp_llsc_mb();

if (cpu_has_llsc && R10000_LLSC_WAR) {
unsigned long temp;
Expand Down Expand Up @@ -233,7 +233,7 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
raw_local_irq_restore(flags);
}

smp_mb();
smp_llsc_mb();

return result;
}
Expand All @@ -250,7 +250,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
{
unsigned long result;

smp_mb();
smp_llsc_mb();

if (cpu_has_llsc && R10000_LLSC_WAR) {
unsigned long temp;
Expand Down Expand Up @@ -302,7 +302,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
raw_local_irq_restore(flags);
}

smp_mb();
smp_llsc_mb();

return result;
}
Expand Down Expand Up @@ -519,7 +519,7 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
{
unsigned long result;

smp_mb();
smp_llsc_mb();

if (cpu_has_llsc && R10000_LLSC_WAR) {
unsigned long temp;
Expand Down Expand Up @@ -562,7 +562,7 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
raw_local_irq_restore(flags);
}

smp_mb();
smp_llsc_mb();

return result;
}
Expand All @@ -571,7 +571,7 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
{
unsigned long result;

smp_mb();
smp_llsc_mb();

if (cpu_has_llsc && R10000_LLSC_WAR) {
unsigned long temp;
Expand Down Expand Up @@ -614,7 +614,7 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
raw_local_irq_restore(flags);
}

smp_mb();
smp_llsc_mb();

return result;
}
Expand All @@ -631,7 +631,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
{
unsigned long result;

smp_mb();
smp_llsc_mb();

if (cpu_has_llsc && R10000_LLSC_WAR) {
unsigned long temp;
Expand Down Expand Up @@ -683,7 +683,7 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
raw_local_irq_restore(flags);
}

smp_mb();
smp_llsc_mb();

return result;
}
Expand Down Expand Up @@ -791,10 +791,11 @@ static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
* atomic*_return operations are serializing but not the non-*_return
* versions.
*/
#define smp_mb__before_atomic_dec() smp_mb()
#define smp_mb__after_atomic_dec() smp_mb()
#define smp_mb__before_atomic_inc() smp_mb()
#define smp_mb__after_atomic_inc() smp_mb()
#define smp_mb__before_atomic_dec() smp_llsc_mb()
#define smp_mb__after_atomic_dec() smp_llsc_mb()
#define smp_mb__before_atomic_inc() smp_llsc_mb()
#define smp_mb__after_atomic_inc() smp_llsc_mb()

#include <asm-generic/atomic.h>

#endif /* _ASM_ATOMIC_H */
9 changes: 9 additions & 0 deletions include/asm-mips/barrier.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,11 @@
#else
#define __WEAK_ORDERING_MB " \n"
#endif
#if defined(CONFIG_WEAK_REORDERING_BEYOND_LLSC) && defined(CONFIG_SMP)
#define __WEAK_LLSC_MB " sync \n"
#else
#define __WEAK_LLSC_MB " \n"
#endif

#define smp_mb() __asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory")
#define smp_rmb() __asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory")
Expand All @@ -129,4 +134,8 @@
#define set_mb(var, value) \
do { var = value; smp_mb(); } while (0)

#define smp_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
#define smp_llsc_rmb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
#define smp_llsc_wmb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")

#endif /* __ASM_BARRIER_H */
10 changes: 5 additions & 5 deletions include/asm-mips/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
/*
* clear_bit() doesn't provide any barrier for the compiler.
*/
#define smp_mb__before_clear_bit() smp_mb()
#define smp_mb__after_clear_bit() smp_mb()
#define smp_mb__before_clear_bit() smp_llsc_mb()
#define smp_mb__after_clear_bit() smp_llsc_mb()

/*
* set_bit - Atomically set a bit in memory
Expand Down Expand Up @@ -289,7 +289,7 @@ static inline int test_and_set_bit(unsigned long nr,
raw_local_irq_restore(flags);
}

smp_mb();
smp_llsc_mb();

return res != 0;
}
Expand Down Expand Up @@ -377,7 +377,7 @@ static inline int test_and_clear_bit(unsigned long nr,
raw_local_irq_restore(flags);
}

smp_mb();
smp_llsc_mb();

return res != 0;
}
Expand Down Expand Up @@ -445,7 +445,7 @@ static inline int test_and_change_bit(unsigned long nr,
raw_local_irq_restore(flags);
}

smp_mb();
smp_llsc_mb();

return res != 0;
}
Expand Down
31 changes: 0 additions & 31 deletions include/asm-mips/ds1216.h

This file was deleted.

8 changes: 4 additions & 4 deletions include/asm-mips/futex.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
" .set mips3 \n" \
"2: sc $1, %2 \n" \
" beqzl $1, 1b \n" \
__WEAK_ORDERING_MB \
__WEAK_LLSC_MB \
"3: \n" \
" .set pop \n" \
" .set mips0 \n" \
Expand All @@ -55,7 +55,7 @@
" .set mips3 \n" \
"2: sc $1, %2 \n" \
" beqz $1, 1b \n" \
__WEAK_ORDERING_MB \
__WEAK_LLSC_MB \
"3: \n" \
" .set pop \n" \
" .set mips0 \n" \
Expand Down Expand Up @@ -152,7 +152,7 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
" .set mips3 \n"
"2: sc $1, %1 \n"
" beqzl $1, 1b \n"
__WEAK_ORDERING_MB
__WEAK_LLSC_MB
"3: \n"
" .set pop \n"
" .section .fixup,\"ax\" \n"
Expand All @@ -179,7 +179,7 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
" .set mips3 \n"
"2: sc $1, %1 \n"
" beqz $1, 1b \n"
__WEAK_ORDERING_MB
__WEAK_LLSC_MB
"3: \n"
" .set pop \n"
" .section .fixup,\"ax\" \n"
Expand Down
55 changes: 0 additions & 55 deletions include/asm-mips/gfx.h

This file was deleted.

Loading

0 comments on commit 02d6112

Please sign in to comment.