Skip to content

Commit

Permalink
m68k: Fix xchg/cmpxchg to fail to link if given an inappropriate pointer
Browse files Browse the repository at this point in the history
Fix the m68k versions of xchg() and cmpxchg() to fail to link if given an
inappropriately sized pointer rather than BUG()'ing at runtime.

Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Greg Ungerer <gerg@uclinux.org>
cc: linux-m68k@lists.linux-m68k.org
  • Loading branch information
David Howells committed Mar 28, 2012
1 parent c9034c3 commit 2501cf7
Showing 1 changed file with 16 additions and 4 deletions.
20 changes: 16 additions & 4 deletions arch/m68k/include/asm/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ asmlinkage void resume(void);
struct __xchg_dummy { unsigned long a[100]; };
#define __xg(x) ((volatile struct __xchg_dummy *)(x))

extern unsigned long __invalid_xchg_size(unsigned long, volatile void *, int);

#ifndef CONFIG_RMW_INSNS
static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
{
Expand All @@ -92,7 +94,8 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
x = tmp;
break;
default:
BUG();
tmp = __invalid_xchg_size(x, ptr, size);
break;
}

local_irq_restore(flags);
Expand All @@ -102,30 +105,33 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
{
switch (size) {
case 1:
case 1:
__asm__ __volatile__
("moveb %2,%0\n\t"
"1:\n\t"
"casb %0,%1,%2\n\t"
"jne 1b"
: "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory");
break;
case 2:
case 2:
__asm__ __volatile__
("movew %2,%0\n\t"
"1:\n\t"
"casw %0,%1,%2\n\t"
"jne 1b"
: "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory");
break;
case 4:
case 4:
__asm__ __volatile__
("movel %2,%0\n\t"
"1:\n\t"
"casl %0,%1,%2\n\t"
"jne 1b"
: "=&d" (x) : "d" (x), "m" (*__xg(ptr)) : "memory");
break;
default:
x = __invalid_xchg_size(x, ptr, size);
break;
}
return x;
}
Expand All @@ -135,6 +141,9 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz

#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))

extern unsigned long __invalid_cmpxchg_size(volatile void *,
unsigned long, unsigned long, int);

/*
* Atomic compare and exchange. Compare OLD with MEM, if identical,
* store NEW in MEM. Return the initial value in MEM. Success is
Expand Down Expand Up @@ -162,6 +171,9 @@ static inline unsigned long __cmpxchg(volatile void *p, unsigned long old,
: "=d" (old), "=m" (*(int *)p)
: "d" (new), "0" (old), "m" (*(int *)p));
break;
default:
old = __invalid_cmpxchg_size(p, old, new, size);
break;
}
return old;
}
Expand Down

0 comments on commit 2501cf7

Please sign in to comment.