git: aa4736459ee2 - main - powerpc/atomic: Fix atomic_testand_*_long on powerpc64
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 03 Feb 2022 23:25:49 UTC
The branch main has been updated by jhibbits: URL: https://cgit.FreeBSD.org/src/commit/?id=aa4736459ee2d314dc90ae9cbb4ad9c1cf48d796 commit aa4736459ee2d314dc90ae9cbb4ad9c1cf48d796 Author: Justin Hibbits <jhibbits@FreeBSD.org> AuthorDate: 2022-02-03 23:20:36 +0000 Commit: Justin Hibbits <jhibbits@FreeBSD.org> CommitDate: 2022-02-03 23:25:39 +0000 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 '.'). --- sys/powerpc/include/atomic.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sys/powerpc/include/atomic.h b/sys/powerpc/include/atomic.h index deb53173418f..43bb239719ae 100644 --- a/sys/powerpc/include/atomic.h +++ b/sys/powerpc/include/atomic.h @@ -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"