[xen stable-4.12] xen/arm32: bitops: Rewrite bitop helpers in C

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[xen stable-4.12] xen/arm32: bitops: Rewrite bitop helpers in C

patchbot
commit a18450caab64aae2ede668b5ec2d5027fc75174c
Author:     Julien Grall <[hidden email]>
AuthorDate: Mon Apr 29 15:05:19 2019 +0100
Commit:     Julien Grall <[hidden email]>
CommitDate: Fri Jun 14 14:32:19 2019 +0100

    xen/arm32: bitops: Rewrite bitop helpers in C
   
    This is part of XSA-295.
   
    Signed-off-by: Julien Grall <[hidden email]>
    Reviewed-by: Stefano Stabellini <[hidden email]>
    Signed-off-by: Stefano Stabellini <[hidden email]>
---
 xen/arch/arm/README.LinuxPrimitives    |  14 +----
 xen/arch/arm/arm32/lib/Makefile        |   5 +-
 xen/arch/arm/arm32/lib/bitops.c        |  98 +++++++++++++++++++++++++++++++
 xen/arch/arm/arm32/lib/bitops.h        | 104 ---------------------------------
 xen/arch/arm/arm32/lib/changebit.S     |  14 -----
 xen/arch/arm/arm32/lib/clearbit.S      |  14 -----
 xen/arch/arm/arm32/lib/setbit.S        |  15 -----
 xen/arch/arm/arm32/lib/testchangebit.S |  15 -----
 xen/arch/arm/arm32/lib/testclearbit.S  |  15 -----
 xen/arch/arm/arm32/lib/testsetbit.S    |  15 -----
 xen/include/asm-arm/arm32/bitops.h     |  19 ++----
 11 files changed, 108 insertions(+), 220 deletions(-)

diff --git a/xen/arch/arm/README.LinuxPrimitives b/xen/arch/arm/README.LinuxPrimitives
index 891667a5da..664a9f89ed 100644
--- a/xen/arch/arm/README.LinuxPrimitives
+++ b/xen/arch/arm/README.LinuxPrimitives
@@ -68,19 +68,9 @@ arm32
 
 bitops: last sync @ v3.16-rc6 (last commit: c32ffce0f66e)
 
-linux/arch/arm/lib/bitops.h             xen/arch/arm/arm32/lib/bitops.h
-linux/arch/arm/lib/changebit.S          xen/arch/arm/arm32/lib/changebit.S
-linux/arch/arm/lib/clearbit.S           xen/arch/arm/arm32/lib/clearbit.S
 linux/arch/arm/lib/findbit.S            xen/arch/arm/arm32/lib/findbit.S
-linux/arch/arm/lib/setbit.S             xen/arch/arm/arm32/lib/setbit.S
-linux/arch/arm/lib/testchangebit.S      xen/arch/arm/arm32/lib/testchangebit.S
-linux/arch/arm/lib/testclearbit.S       xen/arch/arm/arm32/lib/testclearbit.S
-linux/arch/arm/lib/testsetbit.S         xen/arch/arm/arm32/lib/testsetbit.S
-
-for i in bitops.h changebit.S clearbit.S findbit.S setbit.S testchangebit.S \
-         testclearbit.S testsetbit.S; do
-    diff -u ../linux/arch/arm/lib/$i xen/arch/arm/arm32/lib/$i;
-done
+
+diff -u ../linux/arch/arm/lib/findbit.S xen/arch/arm/arm32/lib/findbit.S
 
 ---------------------------------------------------------------------
 
diff --git a/xen/arch/arm/arm32/lib/Makefile b/xen/arch/arm/arm32/lib/Makefile
index e9fbc595b9..b1457c89dc 100644
--- a/xen/arch/arm/arm32/lib/Makefile
+++ b/xen/arch/arm/arm32/lib/Makefile
@@ -1,6 +1,5 @@
 obj-y += memcpy.o memmove.o memset.o memchr.o memzero.o
-obj-y += findbit.o setbit.o
-obj-y += setbit.o clearbit.o changebit.o
-obj-y += testsetbit.o testclearbit.o testchangebit.o
+obj-y += findbit.o
+obj-y += bitops.o
 obj-y += strchr.o strrchr.o
 obj-y += lib1funcs.o lshrdi3.o div64.o
diff --git a/xen/arch/arm/arm32/lib/bitops.c b/xen/arch/arm/arm32/lib/bitops.c
new file mode 100644
index 0000000000..c69bb53037
--- /dev/null
+++ b/xen/arch/arm/arm32/lib/bitops.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2018 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <xen/bitops.h>
+#include <xen/prefetch.h>
+#include <asm/system.h>
+
+/*
+ * The atomic bit operations pass the number of bit in a signed number
+ * (not sure why). This has the drawback to increase the complexity of
+ * the resulting assembly.
+ *
+ * To generate simpler code, the number of bit (nr) will be cast to
+ * unsigned int.
+ *
+ * XXX: Rework the interface to use unsigned int.
+ */
+
+#define bitop(name, instr)                                                  \
+void name(int nr, volatile void *p)                                         \
+{                                                                           \
+    volatile uint32_t *ptr = (uint32_t *)p + BIT_WORD((unsigned int)nr);    \
+    const uint32_t mask = BIT_MASK((unsigned int)nr);                       \
+    unsigned long res, tmp;                                                 \
+                                                                            \
+    ASSERT(((vaddr_t)p & 0x3) == 0);                                        \
+    prefetchw((const void *)ptr);                                           \
+                                                                            \
+    do                                                                      \
+    {                                                                       \
+        asm volatile ("// " __stringify(name) "\n"                          \
+        "   ldrex   %2, %1\n"                                               \
+        "   " __stringify(instr) "     %2, %2, %3\n"                        \
+        "   strex   %0, %2, %1\n"                                           \
+        : "=&r" (res), "+Qo" (*ptr), "=&r" (tmp)                            \
+        : "r" (mask));                                                      \
+    } while ( res );                                                        \
+}
+
+#define testop(name, instr)                                                 \
+int name(int nr, volatile void *p)                                          \
+{                                                                           \
+    volatile uint32_t *ptr = (uint32_t *)p + BIT_WORD((unsigned int)nr);    \
+    unsigned int bit = (unsigned int)nr % BITS_PER_WORD;                    \
+    const uint32_t mask = BIT_MASK(bit);                                    \
+    unsigned long res, tmp;                                                 \
+    int oldbit;                                                             \
+                                                                            \
+    ASSERT(((vaddr_t)p & 0x3) == 0);                                        \
+    smp_mb();                                                               \
+                                                                            \
+    prefetchw((const void *)ptr);                                           \
+                                                                            \
+    do                                                                      \
+    {                                                                       \
+        asm volatile ("// " __stringify(name) "\n"                          \
+        "   ldrex   %3, %2\n"                                               \
+        "   lsr     %1, %3, %5 // Save old value of bit\n"                  \
+        "   " __stringify(instr) "  %3, %3, %4 // Toggle bit\n"             \
+        "   strex  %0, %3, %2\n"                                            \
+        : "=&r" (res), "=&r" (oldbit), "+Qo" (*ptr), "=&r" (tmp)            \
+        : "r" (mask), "r" (bit));                                           \
+    } while ( res );                                                        \
+                                                                            \
+    smp_mb();                                                               \
+                                                                            \
+    return oldbit & 1;                                                      \
+}                                                                           \
+
+bitop(change_bit, eor)
+bitop(clear_bit, bic)
+bitop(set_bit, orr)
+
+testop(test_and_change_bit, eor)
+testop(test_and_clear_bit, bic)
+testop(test_and_set_bit, orr)
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/arm32/lib/bitops.h b/xen/arch/arm/arm32/lib/bitops.h
deleted file mode 100644
index d5e13476f4..0000000000
--- a/xen/arch/arm/arm32/lib/bitops.h
+++ /dev/null
@@ -1,104 +0,0 @@
-
-#if __LINUX_ARM_ARCH__ >= 6
- .macro bitop, name, instr
-ENTRY( \name )
-UNWIND( .fnstart )
- ands ip, r1, #3
- strneb r1, [ip] @ assert word-aligned
- mov r2, #1
- and r3, r0, #31 @ Get bit offset
- mov r0, r0, lsr #5
- add r1, r1, r0, lsl #2 @ Get word offset
-#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
- .arch_extension mp
- ALT_SMP(W(pldw) [r1])
- ALT_UP(W(nop))
-#endif
- mov r3, r2, lsl r3
-1: ldrex r2, [r1]
- \instr r2, r2, r3
- strex r0, r2, [r1]
- cmp r0, #0
- bne 1b
- bx lr
-UNWIND( .fnend )
-ENDPROC(\name )
- .endm
-
- .macro testop, name, instr, store
-ENTRY( \name )
-UNWIND( .fnstart )
- ands ip, r1, #3
- strneb r1, [ip] @ assert word-aligned
- mov r2, #1
- and r3, r0, #31 @ Get bit offset
- mov r0, r0, lsr #5
- add r1, r1, r0, lsl #2 @ Get word offset
- mov r3, r2, lsl r3 @ create mask
- smp_dmb
-#if __LINUX_ARM_ARCH__ >= 7 && defined(CONFIG_SMP)
- .arch_extension mp
- ALT_SMP(W(pldw) [r1])
- ALT_UP(W(nop))
-#endif
-1: ldrex r2, [r1]
- ands r0, r2, r3 @ save old value of bit
- \instr r2, r2, r3 @ toggle bit
- strex ip, r2, [r1]
- cmp ip, #0
- bne 1b
- smp_dmb
- cmp r0, #0
- movne r0, #1
-2: bx lr
-UNWIND( .fnend )
-ENDPROC(\name )
- .endm
-#else
- .macro bitop, name, instr
-ENTRY( \name )
-UNWIND( .fnstart )
- ands ip, r1, #3
- strneb r1, [ip] @ assert word-aligned
- and r2, r0, #31
- mov r0, r0, lsr #5
- mov r3, #1
- mov r3, r3, lsl r2
- save_and_disable_irqs ip
- ldr r2, [r1, r0, lsl #2]
- \instr r2, r2, r3
- str r2, [r1, r0, lsl #2]
- restore_irqs ip
- mov pc, lr
-UNWIND( .fnend )
-ENDPROC(\name )
- .endm
-
-/**
- * testop - implement a test_and_xxx_bit operation.
- * @instr: operational instruction
- * @store: store instruction
- *
- * Note: we can trivially conditionalise the store instruction
- * to avoid dirtying the data cache.
- */
- .macro testop, name, instr, store
-ENTRY( \name )
-UNWIND( .fnstart )
- ands ip, r1, #3
- strneb r1, [ip] @ assert word-aligned
- and r3, r0, #31
- mov r0, r0, lsr #5
- save_and_disable_irqs ip
- ldr r2, [r1, r0, lsl #2]!
- mov r0, #1
- tst r2, r0, lsl r3
- \instr r2, r2, r0, lsl r3
- \store r2, [r1]
- moveq r0, #0
- restore_irqs ip
- mov pc, lr
-UNWIND( .fnend )
-ENDPROC(\name )
- .endm
-#endif
diff --git a/xen/arch/arm/arm32/lib/changebit.S b/xen/arch/arm/arm32/lib/changebit.S
deleted file mode 100644
index 6e4ae7594a..0000000000
--- a/xen/arch/arm/arm32/lib/changebit.S
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- *  linux/arch/arm/lib/changebit.S
- *
- *  Copyright (C) 1995-1996 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include "assembler.h"
-#include "bitops.h"
-                .text
-
-bitop _change_bit, eor
diff --git a/xen/arch/arm/arm32/lib/clearbit.S b/xen/arch/arm/arm32/lib/clearbit.S
deleted file mode 100644
index fda553f246..0000000000
--- a/xen/arch/arm/arm32/lib/clearbit.S
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- *  linux/arch/arm/lib/clearbit.S
- *
- *  Copyright (C) 1995-1996 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include "assembler.h"
-#include "bitops.h"
-                .text
-
-bitop _clear_bit, bic
diff --git a/xen/arch/arm/arm32/lib/setbit.S b/xen/arch/arm/arm32/lib/setbit.S
deleted file mode 100644
index d52f0ab65c..0000000000
--- a/xen/arch/arm/arm32/lib/setbit.S
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- *  linux/arch/arm/lib/setbit.S
- *
- *  Copyright (C) 1995-1996 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include "assembler.h"
-#include "bitops.h"
- .text
-
-bitop _set_bit, orr
diff --git a/xen/arch/arm/arm32/lib/testchangebit.S b/xen/arch/arm/arm32/lib/testchangebit.S
deleted file mode 100644
index d83b04c057..0000000000
--- a/xen/arch/arm/arm32/lib/testchangebit.S
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- *  linux/arch/arm/lib/testchangebit.S
- *
- *  Copyright (C) 1995-1996 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include "assembler.h"
-#include "bitops.h"
-                .text
-
-testop _test_and_change_bit, eor, str
diff --git a/xen/arch/arm/arm32/lib/testclearbit.S b/xen/arch/arm/arm32/lib/testclearbit.S
deleted file mode 100644
index 6f5b7b92d1..0000000000
--- a/xen/arch/arm/arm32/lib/testclearbit.S
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- *  linux/arch/arm/lib/testclearbit.S
- *
- *  Copyright (C) 1995-1996 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include "assembler.h"
-#include "bitops.h"
-                .text
-
-testop _test_and_clear_bit, bicne, strne
diff --git a/xen/arch/arm/arm32/lib/testsetbit.S b/xen/arch/arm/arm32/lib/testsetbit.S
deleted file mode 100644
index 30425a842a..0000000000
--- a/xen/arch/arm/arm32/lib/testsetbit.S
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- *  linux/arch/arm/lib/testsetbit.S
- *
- *  Copyright (C) 1995-1996 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include "assembler.h"
-#include "bitops.h"
-                .text
-
-testop _test_and_set_bit, orreq, streq
diff --git a/xen/include/asm-arm/arm32/bitops.h b/xen/include/asm-arm/arm32/bitops.h
index 8be3564540..67c4c3f55c 100644
--- a/xen/include/asm-arm/arm32/bitops.h
+++ b/xen/include/asm-arm/arm32/bitops.h
@@ -1,19 +1,12 @@
 #ifndef _ARM_ARM32_BITOPS_H
 #define _ARM_ARM32_BITOPS_H
 
-extern void _set_bit(int nr, volatile void * p);
-extern void _clear_bit(int nr, volatile void * p);
-extern void _change_bit(int nr, volatile void * p);
-extern int _test_and_set_bit(int nr, volatile void * p);
-extern int _test_and_clear_bit(int nr, volatile void * p);
-extern int _test_and_change_bit(int nr, volatile void * p);
-
-#define set_bit(n,p)              _set_bit(n,p)
-#define clear_bit(n,p)            _clear_bit(n,p)
-#define change_bit(n,p)           _change_bit(n,p)
-#define test_and_set_bit(n,p)     _test_and_set_bit(n,p)
-#define test_and_clear_bit(n,p)   _test_and_clear_bit(n,p)
-#define test_and_change_bit(n,p)  _test_and_change_bit(n,p)
+extern void set_bit(int nr, volatile void * p);
+extern void clear_bit(int nr, volatile void * p);
+extern void change_bit(int nr, volatile void * p);
+extern int test_and_set_bit(int nr, volatile void * p);
+extern int test_and_clear_bit(int nr, volatile void * p);
+extern int test_and_change_bit(int nr, volatile void * p);
 
 #define flsl fls
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.12

_______________________________________________
Xen-changelog mailing list
[hidden email]
https://lists.xenproject.org/xen-changelog