[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 |