powerpc/atomic: Fix atomic_testand_*_long on powerpc64
After b5d227b0
FreeBSD was panicking on boot with "Duplicate free" in
UMA. Analyzing the asm, the '1' mask was treated as an integer, rather
than a long, causing 'slw' (shift left word) to be used for the shifting
instruction, not 'sld' (shift left double). This means the upper bits
of the bitfield were not getting used, resulting in corruption of the
bitfield.
While fixing this, the 'and' check of the mask does not need to be
recorded, so don't record (drop the '.').
This commit is contained in:
parent
3b248a2113
commit
aa4736459e
@ -997,13 +997,13 @@ atomic_swap_64(volatile u_long *p, u_long v)
|
||||
static __inline int
|
||||
atomic_testandset_int(volatile u_int *p, u_int v)
|
||||
{
|
||||
u_int m = (1 << (v & 0x1f));
|
||||
u_int m = (1u << (v & 0x1f));
|
||||
u_int res;
|
||||
u_int tmp;
|
||||
|
||||
__asm __volatile(
|
||||
"1: lwarx %0,0,%3\n"
|
||||
" and. %1,%0,%4\n"
|
||||
" and %1,%0,%4\n"
|
||||
" or %0,%0,%4\n"
|
||||
" stwcx. %0,0,%3\n"
|
||||
" bne- 1b\n"
|
||||
@ -1017,13 +1017,13 @@ atomic_testandset_int(volatile u_int *p, u_int v)
|
||||
static __inline int
|
||||
atomic_testandclear_int(volatile u_int *p, u_int v)
|
||||
{
|
||||
u_int m = (1 << (v & 0x1f));
|
||||
u_int m = (1u << (v & 0x1f));
|
||||
u_int res;
|
||||
u_int tmp;
|
||||
|
||||
__asm __volatile(
|
||||
"1: lwarx %0,0,%3\n"
|
||||
" and. %1,%0,%4\n"
|
||||
" and %1,%0,%4\n"
|
||||
" andc %0,%0,%4\n"
|
||||
" stwcx. %0,0,%3\n"
|
||||
" bne- 1b\n"
|
||||
@ -1038,13 +1038,13 @@ atomic_testandclear_int(volatile u_int *p, u_int v)
|
||||
static __inline int
|
||||
atomic_testandset_long(volatile u_long *p, u_int v)
|
||||
{
|
||||
u_long m = (1 << (v & 0x3f));
|
||||
u_long m = (1ul << (v & 0x3f));
|
||||
u_long res;
|
||||
u_long tmp;
|
||||
|
||||
__asm __volatile(
|
||||
"1: ldarx %0,0,%3\n"
|
||||
" and. %1,%0,%4\n"
|
||||
" and %1,%0,%4\n"
|
||||
" or %0,%0,%4\n"
|
||||
" stdcx. %0,0,%3\n"
|
||||
" bne- 1b\n"
|
||||
@ -1058,13 +1058,13 @@ atomic_testandset_long(volatile u_long *p, u_int v)
|
||||
static __inline int
|
||||
atomic_testandclear_long(volatile u_long *p, u_int v)
|
||||
{
|
||||
u_long m = (1 << (v & 0x3f));
|
||||
u_long m = (1ul << (v & 0x3f));
|
||||
u_long res;
|
||||
u_long tmp;
|
||||
|
||||
__asm __volatile(
|
||||
"1: ldarx %0,0,%3\n"
|
||||
" and. %1,%0,%4\n"
|
||||
" and %1,%0,%4\n"
|
||||
" andc %0,%0,%4\n"
|
||||
" stdcx. %0,0,%3\n"
|
||||
" bne- 1b\n"
|
||||
|
Loading…
Reference in New Issue
Block a user