All of lore.kernel.org
 help / color / mirror / Atom feed
From: rmk+kernel@armlinux.org.uk (Russell King)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 2/4] ARM: kuser: split out kuser code
Date: Thu, 09 Feb 2017 12:18:40 +0000	[thread overview]
Message-ID: <E1cbngO-000262-21@rmk-PC.armlinux.org.uk> (raw)
In-Reply-To: <20170209121756.GC27312@n2100.armlinux.org.uk>

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/kernel/Makefile     |   2 +
 arch/arm/kernel/entry-armv.S | 198 -------------------------------------------
 arch/arm/kernel/kuser.S      | 197 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 199 insertions(+), 198 deletions(-)
 create mode 100644 arch/arm/kernel/kuser.S

diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index f7751cb71fb1..a7c21ce534e3 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -30,6 +30,8 @@ else
 obj-y		+= entry-armv.o
 endif
 
+obj-$(CONFIG_KUSER_HELPERS)	+= kuser.o
+
 obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 obj-$(CONFIG_ISA_DMA_API)	+= dma.o
 obj-$(CONFIG_FIQ)		+= fiq.o
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 9f157e7c51e7..3acc6e6b948c 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -819,204 +819,6 @@ ENTRY(__switch_to)
  UNWIND(.fnend		)
 ENDPROC(__switch_to)
 
-	__INIT
-
-/*
- * User helpers.
- *
- * Each segment is 32-byte aligned and will be moved to the top of the high
- * vector page.  New segments (if ever needed) must be added in front of
- * existing ones.  This mechanism should be used only for things that are
- * really small and justified, and not be abused freely.
- *
- * See Documentation/arm/kernel_user_helpers.txt for formal definitions.
- */
- THUMB(	.arm	)
-
-	.macro	usr_ret, reg
-#ifdef CONFIG_ARM_THUMB
-	bx	\reg
-#else
-	ret	\reg
-#endif
-	.endm
-
-	.macro	kuser_pad, sym, size
-	.if	(. - \sym) & 3
-	.rept	4 - (. - \sym) & 3
-	.byte	0
-	.endr
-	.endif
-	.rept	(\size - (. - \sym)) / 4
-	.word	0xe7fddef1
-	.endr
-	.endm
-
-#ifdef CONFIG_KUSER_HELPERS
-	.align	5
-	.globl	__kuser_helper_start
-__kuser_helper_start:
-
-/*
- * Due to the length of some sequences, __kuser_cmpxchg64 spans 2 regular
- * kuser "slots", therefore 0xffff0f80 is not used as a valid entry point.
- */
-
-__kuser_cmpxchg64:				@ 0xffff0f60
-
-#if defined(CONFIG_CPU_32v6K)
-
-	stmfd	sp!, {r4, r5, r6, r7}
-	ldrd	r4, r5, [r0]			@ load old val
-	ldrd	r6, r7, [r1]			@ load new val
-	smp_dmb	arm
-1:	ldrexd	r0, r1, [r2]			@ load current val
-	eors	r3, r0, r4			@ compare with oldval (1)
-	eoreqs	r3, r1, r5			@ compare with oldval (2)
-	strexdeq r3, r6, r7, [r2]		@ store newval if eq
-	teqeq	r3, #1				@ success?
-	beq	1b				@ if no then retry
-	smp_dmb	arm
-	rsbs	r0, r3, #0			@ set returned val and C flag
-	ldmfd	sp!, {r4, r5, r6, r7}
-	usr_ret	lr
-
-#elif !defined(CONFIG_SMP)
-
-#ifdef CONFIG_MMU
-
-	/*
-	 * The only thing that can break atomicity in this cmpxchg64
-	 * implementation is either an IRQ or a data abort exception
-	 * causing another process/thread to be scheduled in the middle of
-	 * the critical sequence.  The same strategy as for cmpxchg is used.
-	 */
-	stmfd	sp!, {r4, r5, r6, lr}
-	ldmia	r0, {r4, r5}			@ load old val
-	ldmia	r1, {r6, lr}			@ load new val
-1:	ldmia	r2, {r0, r1}			@ load current val
-	eors	r3, r0, r4			@ compare with oldval (1)
-	eoreqs	r3, r1, r5			@ compare with oldval (2)
-2:	stmeqia	r2, {r6, lr}			@ store newval if eq
-	rsbs	r0, r3, #0			@ set return val and C flag
-	ldmfd	sp!, {r4, r5, r6, pc}
-
-	.text
-kuser_cmpxchg64_fixup:
-	@ Called from kuser_cmpxchg_fixup.
-	@ r4 = address of interrupted insn (must be preserved).
-	@ sp = saved regs. r7 and r8 are clobbered.
-	@ 1b = first critical insn, 2b = last critical insn.
-	@ If r4 >= 1b and r4 <= 2b then saved pc_usr is set to 1b.
-	mov	r7, #0xffff0fff
-	sub	r7, r7, #(0xffff0fff - (0xffff0f60 + (1b - __kuser_cmpxchg64)))
-	subs	r8, r4, r7
-	rsbcss	r8, r8, #(2b - 1b)
-	strcs	r7, [sp, #S_PC]
-#if __LINUX_ARM_ARCH__ < 6
-	bcc	kuser_cmpxchg32_fixup
-#endif
-	ret	lr
-	.previous
-
-#else
-#warning "NPTL on non MMU needs fixing"
-	mov	r0, #-1
-	adds	r0, r0, #0
-	usr_ret	lr
-#endif
-
-#else
-#error "incoherent kernel configuration"
-#endif
-
-	kuser_pad __kuser_cmpxchg64, 64
-
-__kuser_memory_barrier:				@ 0xffff0fa0
-	smp_dmb	arm
-	usr_ret	lr
-
-	kuser_pad __kuser_memory_barrier, 32
-
-__kuser_cmpxchg:				@ 0xffff0fc0
-
-#if __LINUX_ARM_ARCH__ < 6
-
-#ifdef CONFIG_MMU
-
-	/*
-	 * The only thing that can break atomicity in this cmpxchg
-	 * implementation is either an IRQ or a data abort exception
-	 * causing another process/thread to be scheduled in the middle
-	 * of the critical sequence.  To prevent this, code is added to
-	 * the IRQ and data abort exception handlers to set the pc back
-	 * to the beginning of the critical section if it is found to be
-	 * within that critical section (see kuser_cmpxchg_fixup).
-	 */
-1:	ldr	r3, [r2]			@ load current val
-	subs	r3, r3, r0			@ compare with oldval
-2:	streq	r1, [r2]			@ store newval if eq
-	rsbs	r0, r3, #0			@ set return val and C flag
-	usr_ret	lr
-
-	.text
-kuser_cmpxchg32_fixup:
-	@ Called from kuser_cmpxchg_check macro.
-	@ r4 = address of interrupted insn (must be preserved).
-	@ sp = saved regs. r7 and r8 are clobbered.
-	@ 1b = first critical insn, 2b = last critical insn.
-	@ If r4 >= 1b and r4 <= 2b then saved pc_usr is set to 1b.
-	mov	r7, #0xffff0fff
-	sub	r7, r7, #(0xffff0fff - (0xffff0fc0 + (1b - __kuser_cmpxchg)))
-	subs	r8, r4, r7
-	rsbcss	r8, r8, #(2b - 1b)
-	strcs	r7, [sp, #S_PC]
-	ret	lr
-	.previous
-
-#else
-#warning "NPTL on non MMU needs fixing"
-	mov	r0, #-1
-	adds	r0, r0, #0
-	usr_ret	lr
-#endif
-
-#else
-
-	smp_dmb	arm
-1:	ldrex	r3, [r2]
-	subs	r3, r3, r0
-	strexeq	r3, r1, [r2]
-	teqeq	r3, #1
-	beq	1b
-	rsbs	r0, r3, #0
-	/* beware -- each __kuser slot must be 8 instructions max */
-	ALT_SMP(b	__kuser_memory_barrier)
-	ALT_UP(usr_ret	lr)
-
-#endif
-
-	kuser_pad __kuser_cmpxchg, 32
-
-__kuser_get_tls:				@ 0xffff0fe0
-	ldr	r0, [pc, #(16 - 8)]	@ read TLS, set in kuser_get_tls_init
-	usr_ret	lr
-	mrc	p15, 0, r0, c13, c0, 3	@ 0xffff0fe8 hardware TLS code
-	kuser_pad __kuser_get_tls, 16
-	.rep	3
-	.word	0			@ 0xffff0ff0 software TLS value, then
-	.endr				@ pad up to __kuser_helper_version
-
-__kuser_helper_version:				@ 0xffff0ffc
-	.word	((__kuser_helper_end - __kuser_helper_start) >> 5)
-
-	.globl	__kuser_helper_end
-__kuser_helper_end:
-
-#endif
-
- THUMB(	.thumb	)
-
 /*
  * Vector stubs.
  *
diff --git a/arch/arm/kernel/kuser.S b/arch/arm/kernel/kuser.S
new file mode 100644
index 000000000000..5d2a2784ed09
--- /dev/null
+++ b/arch/arm/kernel/kuser.S
@@ -0,0 +1,197 @@
+#include <linux/init.h>
+
+#include <asm/assembler.h>
+
+	__INIT
+
+/*
+ * User helpers.
+ *
+ * Each segment is 32-byte aligned and will be moved to the top of the high
+ * vector page.  New segments (if ever needed) must be added in front of
+ * existing ones.  This mechanism should be used only for things that are
+ * really small and justified, and not be abused freely.
+ *
+ * See Documentation/arm/kernel_user_helpers.txt for formal definitions.
+ */
+ THUMB(	.arm	)
+
+	.macro	usr_ret, reg
+#ifdef CONFIG_ARM_THUMB
+	bx	\reg
+#else
+	ret	\reg
+#endif
+	.endm
+
+	.macro	kuser_pad, sym, size
+	.if	(. - \sym) & 3
+	.rept	4 - (. - \sym) & 3
+	.byte	0
+	.endr
+	.endif
+	.rept	(\size - (. - \sym)) / 4
+	.word	0xe7fddef1
+	.endr
+	.endm
+
+	.align	5
+	.globl	__kuser_helper_start
+__kuser_helper_start:
+
+/*
+ * Due to the length of some sequences, __kuser_cmpxchg64 spans 2 regular
+ * kuser "slots", therefore 0xffff0f80 is not used as a valid entry point.
+ */
+
+__kuser_cmpxchg64:				@ 0xffff0f60
+
+#if defined(CONFIG_CPU_32v6K)
+
+	stmfd	sp!, {r4, r5, r6, r7}
+	ldrd	r4, r5, [r0]			@ load old val
+	ldrd	r6, r7, [r1]			@ load new val
+	smp_dmb	arm
+1:	ldrexd	r0, r1, [r2]			@ load current val
+	eors	r3, r0, r4			@ compare with oldval (1)
+	eoreqs	r3, r1, r5			@ compare with oldval (2)
+	strexdeq r3, r6, r7, [r2]		@ store newval if eq
+	teqeq	r3, #1				@ success?
+	beq	1b				@ if no then retry
+	smp_dmb	arm
+	rsbs	r0, r3, #0			@ set returned val and C flag
+	ldmfd	sp!, {r4, r5, r6, r7}
+	usr_ret	lr
+
+#elif !defined(CONFIG_SMP)
+
+#ifdef CONFIG_MMU
+
+	/*
+	 * The only thing that can break atomicity in this cmpxchg64
+	 * implementation is either an IRQ or a data abort exception
+	 * causing another process/thread to be scheduled in the middle of
+	 * the critical sequence.  The same strategy as for cmpxchg is used.
+	 */
+	stmfd	sp!, {r4, r5, r6, lr}
+	ldmia	r0, {r4, r5}			@ load old val
+	ldmia	r1, {r6, lr}			@ load new val
+1:	ldmia	r2, {r0, r1}			@ load current val
+	eors	r3, r0, r4			@ compare with oldval (1)
+	eoreqs	r3, r1, r5			@ compare with oldval (2)
+2:	stmeqia	r2, {r6, lr}			@ store newval if eq
+	rsbs	r0, r3, #0			@ set return val and C flag
+	ldmfd	sp!, {r4, r5, r6, pc}
+
+	.text
+	.globl kuser_cmpxchg64_fixup
+kuser_cmpxchg64_fixup:
+	@ Called from kuser_cmpxchg_check macro.
+	@ r4 = address of interrupted insn (must be preserved).
+	@ sp = saved regs. r7 and r8 are clobbered.
+	@ 1b = first critical insn, 2b = last critical insn.
+	@ If r4 >= 1b and r4 <= 2b then saved pc_usr is set to 1b.
+	mov	r7, #0xffff0fff
+	sub	r7, r7, #(0xffff0fff - (0xffff0f60 + (1b - __kuser_cmpxchg64)))
+	subs	r8, r4, r7
+	rsbcss	r8, r8, #(2b - 1b)
+	strcs	r7, [sp, #S_PC]
+#if __LINUX_ARM_ARCH__ < 6
+	bcc	kuser_cmpxchg32_fixup
+#endif
+	ret	lr
+	.previous
+
+#else
+#warning "NPTL on non MMU needs fixing"
+	mov	r0, #-1
+	adds	r0, r0, #0
+	usr_ret	lr
+#endif
+
+#else
+#error "incoherent kernel configuration"
+#endif
+
+	kuser_pad __kuser_cmpxchg64, 64
+
+__kuser_memory_barrier:				@ 0xffff0fa0
+	smp_dmb	arm
+	usr_ret	lr
+
+	kuser_pad __kuser_memory_barrier, 32
+
+__kuser_cmpxchg:				@ 0xffff0fc0
+
+#if __LINUX_ARM_ARCH__ < 6
+
+#ifdef CONFIG_MMU
+
+	/*
+	 * The only thing that can break atomicity in this cmpxchg
+	 * implementation is either an IRQ or a data abort exception
+	 * causing another process/thread to be scheduled in the middle
+	 * of the critical sequence.  To prevent this, code is added to
+	 * the IRQ and data abort exception handlers to set the pc back
+	 * to the beginning of the critical section if it is found to be
+	 * within that critical section (see kuser_cmpxchg_check).
+	 */
+1:	ldr	r3, [r2]			@ load current val
+	subs	r3, r3, r0			@ compare with oldval
+2:	streq	r1, [r2]			@ store newval if eq
+	rsbs	r0, r3, #0			@ set return val and C flag
+	usr_ret	lr
+
+	.text
+kuser_cmpxchg32_fixup:
+	@ Called from kuser_cmpxchg64_fixup above via kuser_cmpxchg_check macro.
+	@ r4 = address of interrupted insn (must be preserved).
+	@ sp = saved regs. r7 and r8 are clobbered.
+	@ 1b = first critical insn, 2b = last critical insn.
+	@ If r4 >= 1b and r4 <= 2b then saved pc_usr is set to 1b.
+	mov	r7, #0xffff0fff
+	sub	r7, r7, #(0xffff0fff - (0xffff0fc0 + (1b - __kuser_cmpxchg)))
+	subs	r8, r4, r7
+	rsbcss	r8, r8, #(2b - 1b)
+	strcs	r7, [sp, #S_PC]
+	ret	lr
+	.previous
+
+#else
+#warning "NPTL on non MMU needs fixing"
+	mov	r0, #-1
+	adds	r0, r0, #0
+	usr_ret	lr
+#endif
+
+#else
+
+	smp_dmb	arm
+1:	ldrex	r3, [r2]
+	subs	r3, r3, r0
+	strexeq	r3, r1, [r2]
+	teqeq	r3, #1
+	beq	1b
+	rsbs	r0, r3, #0
+	/* beware -- each __kuser slot must be 8 instructions max */
+	ALT_SMP(b	__kuser_memory_barrier)
+	ALT_UP(usr_ret	lr)
+
+#endif
+
+	kuser_pad __kuser_cmpxchg, 32
+
+__kuser_get_tls:				@ 0xffff0fe0
+	ldr	r0, [pc, #(16 - 8)]	@ read TLS, set in kuser_get_tls_init
+	usr_ret	lr
+	mrc	p15, 0, r0, c13, c0, 3	@ 0xffff0fe8 hardware TLS code
+	kuser_pad __kuser_get_tls, 16
+	.rep	3
+	.word	0			@ 0xffff0ff0 software TLS value, then
+	.endr				@ pad up to __kuser_helper_version
+
+__kuser_helper_version:				@ 0xffff0ffc
+	.word	((__kuser_helper_end - __kuser_helper_start) >> 5)
+
+	.globl	__kuser_helper_end
+__kuser_helper_end:
-- 
2.7.4

  parent reply	other threads:[~2017-02-09 12:18 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-09 12:17 [PATCH 0/4] kuser updates for ARM-only vs Thumb Russell King - ARM Linux
2017-02-09 12:18 ` [PATCH 1/4] ARM: add CPU_THUMB_CAPABLE to indicate possible Thumb support Russell King
2017-02-10 17:29   ` Stephen Boyd
2017-02-09 12:18 ` Russell King [this message]
2017-02-09 12:18 ` [PATCH 3/4] ARM: kuser: simplify kuser_cmpxchg* preprocessor conditionals Russell King
2017-02-09 12:18 ` [PATCH 4/4] ARM: kuser: split the kuser support for Thumb-capable and ARM-only Russell King
2017-02-09 19:25   ` Nicolas Pitre
2017-02-20 17:06 ` [PATCH 0/4] kuser updates for ARM-only vs Thumb Martin Kaiser
2017-02-20 17:24   ` Russell King - ARM Linux

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E1cbngO-000262-21@rmk-PC.armlinux.org.uk \
    --to=rmk+kernel@armlinux.org.uk \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.