|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen stable-4.9] xen/arm32: bitops: Rewrite bitop helpers in C
commit 67530e7f96bedcb18a53fb5989dc326b8349583b
Author: Julien Grall <julien.grall@xxxxxxx>
AuthorDate: Mon Apr 29 15:05:19 2019 +0100
Commit: Julien Grall <julien.grall@xxxxxxx>
CommitDate: Fri Jun 14 14:49:19 2019 +0100
xen/arm32: bitops: Rewrite bitop helpers in C
This is part of XSA-295.
Signed-off-by: Julien Grall <julien.grall@xxxxxxx>
Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
Signed-off-by: Stefano Stabellini <stefanos@xxxxxxxxxx>
---
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.9
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |