Skip to contentSkip to conversation

arm64 crypto roundup

PATCH New Ard Biesheuvel 2 participants 17 messages May 14, 2014 – May 16, 2014

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

v2 cover arm64 crypto roundup

This is another repost of the arm64 crypto patches, this time I have only included the ones that go under arch/arm64/crypto.

Changes wrt previous version:
- updated the voluntary preemption patches to test for CRYPTO_TFM_REQ_MAY_SLEEP instead of !in_interrupt()
- added Herbert's ack

All patches operate correctly under their respective 'tcrypt.ko mode=xx' tests.

Ard Biesheuvel (11):
arm64/crypto: SHA-1 using ARMv8 Crypto Extensions arm64/crypto: SHA-224/SHA-256 using ARMv8 Crypto Extensions arm64/crypto: GHASH secure hash using ARMv8 Crypto Extensions arm64/crypto: AES using ARMv8 Crypto Extensions arm64/crypto: AES in CCM mode using ARMv8 Crypto Extensions
arm64: pull in <asm/simd.h> from asm-generic arm64/crypto: AES-ECB/CBC/CTR/XTS using ARMv8 NEON and Crypto
Extensions
arm64/crypto: add shared macro to test for NEED_RESCHED arm64/crypto: add voluntary preemption to Crypto Extensions SHA1 arm64/crypto: add voluntary preemption to Crypto Extensions SHA2 arm64/crypto: add voluntary preemption to Crypto Extensions GHASH

 arch/arm64/Kconfig                  |   3 +
 arch/arm64/Makefile                 |   1 +
 arch/arm64/crypto/Kconfig           |  53 ++++
 arch/arm64/crypto/Makefile          |  38 +++
 arch/arm64/crypto/aes-ce-ccm-core.S | 222 +++++++++++++++
 arch/arm64/crypto/aes-ce-ccm-glue.c | 297 ++++++++++++++++++++
 arch/arm64/crypto/aes-ce-cipher.c   | 155 +++++++++++
 arch/arm64/crypto/aes-ce.S          | 133 +++++++++
 arch/arm64/crypto/aes-glue.c        | 446 ++++++++++++++++++++++++++++++
 arch/arm64/crypto/aes-modes.S       | 532 ++++++++++++++++++++++++++++++++++++
 arch/arm64/crypto/aes-neon.S        | 382 ++++++++++++++++++++++++++
 arch/arm64/crypto/ghash-ce-core.S   |  97 +++++++
 arch/arm64/crypto/ghash-ce-glue.c   | 173 ++++++++++++
 arch/arm64/crypto/sha1-ce-core.S    | 154 +++++++++++
 arch/arm64/crypto/sha1-ce-glue.c    | 190 +++++++++++++
 arch/arm64/crypto/sha2-ce-core.S    | 159 +++++++++++
 arch/arm64/crypto/sha2-ce-glue.c    | 270 ++++++++++++++++++
 arch/arm64/include/asm/Kbuild       |   1 +
 arch/arm64/include/asm/assembler.h  |  21 ++
 19 files changed, 3327 insertions(+)
 create mode 100644 arch/arm64/crypto/Kconfig
 create mode 100644 arch/arm64/crypto/Makefile
 create mode 100644 arch/arm64/crypto/aes-ce-ccm-core.S
 create mode 100644 arch/arm64/crypto/aes-ce-ccm-glue.c
 create mode 100644 arch/arm64/crypto/aes-ce-cipher.c
 create mode 100644 arch/arm64/crypto/aes-ce.S
 create mode 100644 arch/arm64/crypto/aes-glue.c
 create mode 100644 arch/arm64/crypto/aes-modes.S
 create mode 100644 arch/arm64/crypto/aes-neon.S
 create mode 100644 arch/arm64/crypto/ghash-ce-core.S
 create mode 100644 arch/arm64/crypto/ghash-ce-glue.c
 create mode 100644 arch/arm64/crypto/sha1-ce-core.S
 create mode 100644 arch/arm64/crypto/sha1-ce-glue.c
 create mode 100644 arch/arm64/crypto/sha2-ce-core.S
 create mode 100644 arch/arm64/crypto/sha2-ce-glue.c
Signature · 1 line
1.8.3.2
#1 lore raw

PATCH v2 1/11 arm64/crypto: SHA-1 using ARMv8 Crypto Extensions

This patch adds support for the SHA-1 Secure Hash Algorithm for CPUs that have support for the SHA-1 part of the ARM v8 Crypto Extensions.

---
 arch/arm64/Kconfig               |   3 +
 arch/arm64/Makefile              |   1 +
 arch/arm64/crypto/Kconfig        |  16 ++++
 arch/arm64/crypto/Makefile       |  12 +++
 arch/arm64/crypto/sha1-ce-core.S | 153 ++++++++++++++++++++++++++++++++++
 arch/arm64/crypto/sha1-ce-glue.c | 174 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 359 insertions(+)
 create mode 100644 arch/arm64/crypto/Kconfig
 create mode 100644 arch/arm64/crypto/Makefile
 create mode 100644 arch/arm64/crypto/sha1-ce-core.S
 create mode 100644 arch/arm64/crypto/sha1-ce-glue.c
arch/arm64/Kconfig +3 -0
index e6e4d3749a6e..1cefc6fe969a 100644
@@ -342,5 +342,8 @@ source "arch/arm64/Kconfig.debug"
 source "security/Kconfig"
 
 source "crypto/Kconfig"
+if CRYPTO
+source "arch/arm64/crypto/Kconfig"
+endif
 
 source "lib/Kconfig"
arch/arm64/Makefile +1 -0
index 2fceb71ac3b7..8185a913c5ed 100644
@@ -45,6 +45,7 @@ export	TEXT_OFFSET GZFLAGS
 core-y		+= arch/arm64/kernel/ arch/arm64/mm/
 core-$(CONFIG_KVM) += arch/arm64/kvm/
 core-$(CONFIG_XEN) += arch/arm64/xen/
+core-$(CONFIG_CRYPTO) += arch/arm64/crypto/
 libs-y		:= arch/arm64/lib/ $(libs-y)
 libs-y		+= $(LIBGCC)
 
arch/arm64/crypto/Kconfig new file +16 -0
new file mode 100644
index 000000000000..7956881b5986
@@ -0,0 +1,16 @@
+
+menuconfig ARM64_CRYPTO
+	bool "ARM64 Accelerated Cryptographic Algorithms"
+	depends on ARM64
+	help
+	  Say Y here to choose from a selection of cryptographic algorithms
+	  implemented using ARM64 specific CPU features or instructions.
+
+if ARM64_CRYPTO
+
+config CRYPTO_SHA1_ARM64_CE
+	tristate "SHA-1 digest algorithm (ARMv8 Crypto Extensions)"
+	depends on ARM64 && KERNEL_MODE_NEON
+	select CRYPTO_HASH
+
+endif
arch/arm64/crypto/Makefile new file +12 -0
new file mode 100644
index 000000000000..0ed3caaec81b
@@ -0,0 +1,12 @@
+#
+# linux/arch/arm64/crypto/Makefile
+#
+# Copyright (C) 2014 Linaro Ltd <[email protected]>
+#
+# 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.
+#
+
+obj-$(CONFIG_CRYPTO_SHA1_ARM64_CE) += sha1-ce.o
+sha1-ce-y := sha1-ce-glue.o sha1-ce-core.o
arch/arm64/crypto/sha1-ce-core.S new file +153 -0

153 lines not on this page · raw message

arch/arm64/crypto/sha1-ce-glue.c new file +174 -0

174 lines not on this page · raw message

Signature · 1 line
1.8.3.2
#2 lore raw

PATCH v2 2/11 arm64/crypto: SHA-224/SHA-256 using ARMv8 Crypto Extensions

In reply to Ard Biesheuvel

This patch adds support for the SHA-224 and SHA-256 Secure Hash Algorithms for CPUs that have support for the SHA-2 part of the ARM v8 Crypto Extensions.

---
 arch/arm64/crypto/Kconfig        |   5 +
 arch/arm64/crypto/Makefile       |   3 +
 arch/arm64/crypto/sha2-ce-core.S | 156 ++++++++++++++++++++++++
 arch/arm64/crypto/sha2-ce-glue.c | 255 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 419 insertions(+)
 create mode 100644 arch/arm64/crypto/sha2-ce-core.S
 create mode 100644 arch/arm64/crypto/sha2-ce-glue.c
arch/arm64/crypto/Kconfig +5 -0
index 7956881b5986..eb1e99770c21 100644
@@ -13,4 +13,9 @@ config CRYPTO_SHA1_ARM64_CE
 	depends on ARM64 && KERNEL_MODE_NEON
 	select CRYPTO_HASH
 
+config CRYPTO_SHA2_ARM64_CE
+	tristate "SHA-224/SHA-256 digest algorithm (ARMv8 Crypto Extensions)"
+	depends on ARM64 && KERNEL_MODE_NEON
+	select CRYPTO_HASH
+
 endif
arch/arm64/crypto/Makefile +3 -0
index 0ed3caaec81b..0b3885a60d43 100644
@@ -10,3 +10,6 @@
 
 obj-$(CONFIG_CRYPTO_SHA1_ARM64_CE) += sha1-ce.o
 sha1-ce-y := sha1-ce-glue.o sha1-ce-core.o
+
+obj-$(CONFIG_CRYPTO_SHA2_ARM64_CE) += sha2-ce.o
+sha2-ce-y := sha2-ce-glue.o sha2-ce-core.o
arch/arm64/crypto/sha2-ce-core.S new file +156 -0

156 lines not on this page · raw message

arch/arm64/crypto/sha2-ce-glue.c new file +255 -0

255 lines not on this page · raw message

Signature · 1 line
1.8.3.2
#3 lore raw

PATCH v2 3/11 arm64/crypto: GHASH secure hash using ARMv8 Crypto Extensions

In reply to Ard Biesheuvel

This is a port to ARMv8 (Crypto Extensions) of the Intel implementation of the GHASH Secure Hash (used in the Galois/Counter chaining mode). It relies on the optional PMULL/PMULL2 instruction (polynomial multiply long, what Intel call carry-less multiply).

---
 arch/arm64/crypto/Kconfig         |   6 ++
 arch/arm64/crypto/Makefile        |   3 +
 arch/arm64/crypto/ghash-ce-core.S |  95 +++++++++++++++++++++++
 arch/arm64/crypto/ghash-ce-glue.c | 155 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 259 insertions(+)
 create mode 100644 arch/arm64/crypto/ghash-ce-core.S
 create mode 100644 arch/arm64/crypto/ghash-ce-glue.c
arch/arm64/crypto/Kconfig +6 -0
index eb1e99770c21..0c50859ee7b9 100644
@@ -18,4 +18,10 @@ config CRYPTO_SHA2_ARM64_CE
 	depends on ARM64 && KERNEL_MODE_NEON
 	select CRYPTO_HASH
 
+
+config CRYPTO_GHASH_ARM64_CE
+	tristate "GHASH (for GCM chaining mode) using ARMv8 Crypto Extensions"
+	depends on ARM64 && KERNEL_MODE_NEON
+	select CRYPTO_HASH
+
 endif
arch/arm64/crypto/Makefile +3 -0
index 0b3885a60d43..e8c81a068868 100644
@@ -13,3 +13,6 @@ sha1-ce-y := sha1-ce-glue.o sha1-ce-core.o
 
 obj-$(CONFIG_CRYPTO_SHA2_ARM64_CE) += sha2-ce.o
 sha2-ce-y := sha2-ce-glue.o sha2-ce-core.o
+
+obj-$(CONFIG_CRYPTO_GHASH_ARM64_CE) += ghash-ce.o
+ghash-ce-y := ghash-ce-glue.o ghash-ce-core.o
arch/arm64/crypto/ghash-ce-core.S new file +95 -0

95 lines not on this page · raw message

arch/arm64/crypto/ghash-ce-glue.c new file +155 -0

155 lines not on this page · raw message

Signature · 1 line
1.8.3.2
#4 lore raw

PATCH v2 4/11 arm64/crypto: AES using ARMv8 Crypto Extensions

In reply to Ard Biesheuvel

This patch adds support for the AES symmetric encryption algorithm for CPUs that have support for the AES part of the ARM v8 Crypto Extensions.

---
 arch/arm64/crypto/Kconfig         |   7 +-
 arch/arm64/crypto/Makefile        |   3 +
 arch/arm64/crypto/aes-ce-cipher.c | 155 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 164 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm64/crypto/aes-ce-cipher.c
arch/arm64/crypto/Kconfig +6 -1
index 0c50859ee7b9..9ba32c0da871 100644
@@ -18,10 +18,15 @@ config CRYPTO_SHA2_ARM64_CE
 	depends on ARM64 && KERNEL_MODE_NEON
 	select CRYPTO_HASH
 
-
 config CRYPTO_GHASH_ARM64_CE
 	tristate "GHASH (for GCM chaining mode) using ARMv8 Crypto Extensions"
 	depends on ARM64 && KERNEL_MODE_NEON
 	select CRYPTO_HASH
 
+config CRYPTO_AES_ARM64_CE
+	tristate "AES core cipher using ARMv8 Crypto Extensions"
+	depends on ARM64 && KERNEL_MODE_NEON
+	select CRYPTO_ALGAPI
+	select CRYPTO_AES
+
 endif
arch/arm64/crypto/Makefile +3 -0
index e8c81a068868..908abd9242b1 100644
@@ -16,3 +16,6 @@ sha2-ce-y := sha2-ce-glue.o sha2-ce-core.o
 
 obj-$(CONFIG_CRYPTO_GHASH_ARM64_CE) += ghash-ce.o
 ghash-ce-y := ghash-ce-glue.o ghash-ce-core.o
+
+obj-$(CONFIG_CRYPTO_AES_ARM64_CE) += aes-ce-cipher.o
+CFLAGS_aes-ce-cipher.o += -march=armv8-a+crypto
arch/arm64/crypto/aes-ce-cipher.c new file +155 -0

155 lines not on this page · raw message

Signature · 1 line
1.8.3.2
#5 lore raw

PATCH v2 5/11 arm64/crypto: AES in CCM mode using ARMv8 Crypto Extensions

In reply to Ard Biesheuvel

This patch adds support for the AES-CCM encryption algorithm for CPUs that have support for the AES part of the ARM v8 Crypto Extensions.

---
 arch/arm64/crypto/Kconfig           |   7 +
 arch/arm64/crypto/Makefile          |   3 +
 arch/arm64/crypto/aes-ce-ccm-core.S | 222 +++++++++++++++++++++++++++
 arch/arm64/crypto/aes-ce-ccm-glue.c | 297 ++++++++++++++++++++++++++++++++++++
 4 files changed, 529 insertions(+)
 create mode 100644 arch/arm64/crypto/aes-ce-ccm-core.S
 create mode 100644 arch/arm64/crypto/aes-ce-ccm-glue.c
arch/arm64/crypto/Kconfig +7 -0
index 9ba32c0da871..8fffd5af65ef 100644
@@ -29,4 +29,11 @@ config CRYPTO_AES_ARM64_CE
 	select CRYPTO_ALGAPI
 	select CRYPTO_AES
 
+config CRYPTO_AES_ARM64_CE_CCM
+	tristate "AES in CCM mode using ARMv8 Crypto Extensions"
+	depends on ARM64 && KERNEL_MODE_NEON
+	select CRYPTO_ALGAPI
+	select CRYPTO_AES
+	select CRYPTO_AEAD
+
 endif
arch/arm64/crypto/Makefile +3 -0
index 908abd9242b1..311287d68078 100644
@@ -19,3 +19,6 @@ ghash-ce-y := ghash-ce-glue.o ghash-ce-core.o
 
 obj-$(CONFIG_CRYPTO_AES_ARM64_CE) += aes-ce-cipher.o
 CFLAGS_aes-ce-cipher.o += -march=armv8-a+crypto
+
+obj-$(CONFIG_CRYPTO_AES_ARM64_CE_CCM) += aes-ce-ccm.o
+aes-ce-ccm-y := aes-ce-ccm-glue.o aes-ce-ccm-core.o
arch/arm64/crypto/aes-ce-ccm-core.S new file +222 -0

222 lines not on this page · raw message

arch/arm64/crypto/aes-ce-ccm-glue.c new file +297 -0

297 lines not on this page · raw message

Signature · 1 line
1.8.3.2
#6 lore raw

PATCH v2 6/11 arm64: pull in <asm/simd.h> from asm-generic

In reply to Ard Biesheuvel
---
 arch/arm64/include/asm/Kbuild | 1 +
 1 file changed, 1 insertion(+)
arch/arm64/include/asm/Kbuild +1 -0
index 83f71b3004a8..42c7eecd2bb6 100644
@@ -40,6 +40,7 @@ generic-y += segment.h
 generic-y += sembuf.h
 generic-y += serial.h
 generic-y += shmbuf.h
+generic-y += simd.h
 generic-y += sizes.h
 generic-y += socket.h
 generic-y += sockios.h
Signature · 1 line
1.8.3.2
#7 lore raw

PATCH v2 7/11 arm64/crypto: AES-ECB/CBC/CTR/XTS using ARMv8 NEON and Crypto Extensions

In reply to Ard Biesheuvel

This adds ARMv8 implementations of AES in ECB, CBC, CTR and XTS modes, both for ARMv8 with Crypto Extensions and for plain ARMv8 NEON.

The Crypto Extensions version can only run on ARMv8 implementations that have support for these optional extensions.

The plain NEON version is a table based yet time invariant implementation. All S-box substitutions are performed in parallel, leveraging the wide range of ARMv8's tbl/tbx instructions, and the huge NEON register file, which can comfortably hold the entire S-box and still have room to spare for doing the actual computations.

The key expansion routines were borrowed from aes_generic.

---
 arch/arm64/crypto/Kconfig     |  14 ++
 arch/arm64/crypto/Makefile    |  14 ++
 arch/arm64/crypto/aes-ce.S    | 133 +++++++++++
 arch/arm64/crypto/aes-glue.c  | 446 +++++++++++++++++++++++++++++++++++
 arch/arm64/crypto/aes-modes.S | 532 ++++++++++++++++++++++++++++++++++++++++++
 arch/arm64/crypto/aes-neon.S  | 382 ++++++++++++++++++++++++++++++
 6 files changed, 1521 insertions(+)
 create mode 100644 arch/arm64/crypto/aes-ce.S
 create mode 100644 arch/arm64/crypto/aes-glue.c
 create mode 100644 arch/arm64/crypto/aes-modes.S
 create mode 100644 arch/arm64/crypto/aes-neon.S
arch/arm64/crypto/Kconfig +14 -0
index 8fffd5af65ef..5562652c5316 100644
@@ -36,4 +36,18 @@ config CRYPTO_AES_ARM64_CE_CCM
 	select CRYPTO_AES
 	select CRYPTO_AEAD
 
+config CRYPTO_AES_ARM64_CE_BLK
+	tristate "AES in ECB/CBC/CTR/XTS modes using ARMv8 Crypto Extensions"
+	depends on ARM64 && KERNEL_MODE_NEON
+	select CRYPTO_BLKCIPHER
+	select CRYPTO_AES
+	select CRYPTO_ABLK_HELPER
+
+config CRYPTO_AES_ARM64_NEON_BLK
+	tristate "AES in ECB/CBC/CTR/XTS modes using NEON instructions"
+	depends on ARM64 && KERNEL_MODE_NEON
+	select CRYPTO_BLKCIPHER
+	select CRYPTO_AES
+	select CRYPTO_ABLK_HELPER
+
 endif
arch/arm64/crypto/Makefile +14 -0
index 311287d68078..2070a56ecc46 100644
@@ -22,3 +22,17 @@ CFLAGS_aes-ce-cipher.o += -march=armv8-a+crypto
 
 obj-$(CONFIG_CRYPTO_AES_ARM64_CE_CCM) += aes-ce-ccm.o
 aes-ce-ccm-y := aes-ce-ccm-glue.o aes-ce-ccm-core.o
+
+obj-$(CONFIG_CRYPTO_AES_ARM64_CE_BLK) += aes-ce-blk.o
+aes-ce-blk-y := aes-glue-ce.o aes-ce.o
+
+obj-$(CONFIG_CRYPTO_AES_ARM64_NEON_BLK) += aes-neon-blk.o
+aes-neon-blk-y := aes-glue-neon.o aes-neon.o
+
+AFLAGS_aes-ce.o		:= -DINTERLEAVE=2 -DINTERLEAVE_INLINE
+AFLAGS_aes-neon.o	:= -DINTERLEAVE=4
+
+CFLAGS_aes-glue-ce.o	:= -DUSE_V8_CRYPTO_EXTENSIONS
+
+$(obj)/aes-glue-%.o: $(src)/aes-glue.c FORCE
+	$(call if_changed_dep,cc_o_c)
arch/arm64/crypto/aes-ce.S new file +133 -0

133 lines not on this page · raw message

arch/arm64/crypto/aes-glue.c new file +446 -0

446 lines not on this page · raw message

arch/arm64/crypto/aes-modes.S new file +532 -0

532 lines not on this page · raw message

arch/arm64/crypto/aes-neon.S new file +382 -0

382 lines not on this page · raw message

Signature · 1 line
1.8.3.2
#8 lore raw

PATCH v2 8/11 arm64/crypto: add shared macro to test for NEED_RESCHED

In reply to Ard Biesheuvel

This adds the asm macro definition 'b_if_no_resched' that performs a conditional branch depending on the preempt need_resched state.

---
 arch/arm64/include/asm/assembler.h | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
arch/arm64/include/asm/assembler.h +21 -0
index fd3e3924041b..296105fd3021 100644
@@ -22,6 +22,11 @@
 
 #include <asm/ptrace.h>
 
+#if defined(CONFIG_PREEMPT) || defined(CONFIG_PREEMPT_VOLUNTARY)
+#include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
+#endif
+
 /*
  * Stack pushing/popping (register pairs only). Equivalent to store decrement
  * before, load increment after.
@@ -146,3 +151,19 @@ lr	.req	x30		// link register
 #endif
 	orr	\rd, \lbits, \hbits, lsl #32
 	.endm
+
+/*
+ * Branch to 'lb' but only if we have not been tagged for preemption.
+ *
+ * Expects current->thread_info in ti, or NULL if running in interrupt
+ * context. reg is a scratch x register.
+ */
+	.macro		b_if_no_resched, ti, reg, lb
+#if defined(CONFIG_PREEMPT) || defined(CONFIG_PREEMPT_VOLUNTARY)
+	cbz		\ti, \lb			/* have thread_info? */
+	ldr		\reg, [\ti, #TI_FLAGS]		/* get flags */
+	tbz		\reg, #TIF_NEED_RESCHED, \lb	/* need rescheduling? */
+#else
+	b		\lb
+#endif
+	.endm
Signature · 1 line
1.8.3.2
#9 lore raw

PATCH v2 9/11 arm64/crypto: add voluntary preemption to Crypto Extensions SHA1

In reply to Ard Biesheuvel

The Crypto Extensions based SHA1 implementation uses the NEON register file, and hence runs with preemption disabled. This patch adds a TIF_NEED_RESCHED check to its inner loop so we at least give up the CPU voluntarily when we are running in process context and have been tagged for preemption by the scheduler.

---
 arch/arm64/crypto/sha1-ce-core.S | 19 ++++++++-------
 arch/arm64/crypto/sha1-ce-glue.c | 52 ++++++++++++++++++++++++++--------------
 2 files changed, 44 insertions(+), 27 deletions(-)
arch/arm64/crypto/sha1-ce-core.S +10 -9
index 09d57d98609c..0cb9b8f4906b 100644
@@ -66,8 +66,8 @@
 	.word		0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6
 
 	/*
-	 * void sha1_ce_transform(int blocks, u8 const *src, u32 *state,
-	 * 			  u8 *head, long bytes)
+	 * int sha1_ce_transform(int blocks, u8 const *src, u32 *state,
+	 * 			 u8 *head, long bytes, struct thread_info *ti)
 	 */
 ENTRY(sha1_ce_transform)
 	/* load round constants */
@@ -127,7 +127,13 @@ CPU_LE(	rev32		v11.16b, v11.16b	)
 	add		dgbv.2s, dgbv.2s, dg1v.2s
 	add		dgav.4s, dgav.4s, dg0v.4s
 
-	cbnz		w0, 0b
+	cbz		w0, 4f
+	b_if_no_resched	x5, x8, 0b
+
+	/* store new state */
+3:	str		dga, [x2]
+	str		dgb, [x2, #16]
+	ret
 
 	/*
 	 * Final block: add padding and total bit count.
@@ -135,7 +141,7 @@ CPU_LE(	rev32		v11.16b, v11.16b	)
 	 * size was not a round multiple of the block size, and the padding is
 	 * handled by the C code.
 	 */
-	cbz		x4, 3f
+4:	cbz		x4, 3b
 	movi		v9.2d, #0
 	mov		x8, #0x80000000
 	movi		v10.2d, #0
@@ -145,9 +151,4 @@ CPU_LE(	rev32		v11.16b, v11.16b	)
 	mov		v11.d[0], xzr
 	mov		v11.d[1], x7
 	b		2b
-
-	/* store new state */
-3:	str		dga, [x2]
-	str		dgb, [x2, #16]
-	ret
 ENDPROC(sha1_ce_transform)
arch/arm64/crypto/sha1-ce-glue.c +34 -18

89 lines not on this page · raw message

Signature · 1 line
1.8.3.2
maintainer
#10 lore raw

PATCH v2 9/11 arm64/crypto: add voluntary preemption to Crypto Extensions SHA1

Quoted 5 lines · Ard Biesheuvel

The Crypto Extensions based SHA1 implementation uses the NEON register file, and hence runs with preemption disabled. This patch adds a TIF_NEED_RESCHED check to its inner loop so we at least give up the CPU voluntarily when we are running in process context and have been tagged for preemption by the scheduler.

Sorry, I haven't got to the bottom of your series earlier and I now realised that the last patches are not just new crypto algorithms.

Quoted 17 lines
arch/arm64/crypto/sha1-ce-glue.c +17 -0
+static u8 const *sha1_do_update(struct shash_desc *desc, const u8 *data,
+				int blocks, u8 *head, unsigned int len)
+{
+	struct sha1_state *sctx = shash_desc_ctx(desc);
+	struct thread_info *ti = NULL;
+
+	/*
+	 * Pass current's thread info pointer to sha1_ce_transform()
+	 * below if we want it to play nice under preemption.
+	 */
+	if ((IS_ENABLED(CONFIG_PREEMPT_VOLUNTARY) || IS_ENABLED(CONFIG_PREEMPT))
+	    && (desc->flags & CRYPTO_TFM_REQ_MAY_SLEEP))
+		ti = current_thread_info();
+
+	do {
+		int rem;
+

arch/arm64/crypto/sha1-ce-glue.c static int sha1_init(struct shash_desc *desc) · line 62

Quoted 10 lines
arch/arm64/crypto/sha1-ce-glue.c +10 -0
+		kernel_neon_begin_partial(16);
+		rem = sha1_ce_transform(blocks, data, sctx->state, head, 0, ti);
+		kernel_neon_end();
+
+		data += (blocks - rem) * SHA1_BLOCK_SIZE;
+		blocks = rem;
+		head = NULL;
+	} while (unlikely(ti && blocks > 0));
+	return data;
+}

What latencies are we talking about? Would it make sense to always call cond_resched() even if preemption is disabled?

With PREEMPT_VOLUNTARY I don't think the above code does any voluntary preemption. The preempt_enable() in kernel_neon_end() only reschedules if PREEMPT.

But I think we should have this loop always rescheduling if CRYPTO_TFM_REQ_MAY_SLEEP. I can see there is a crypto_yield() function that conditionally reschedules. What's the overhead of calling sha1_ce_transform() in a loop vs a single call for the entire data?

Signature · 1 line
Catalin
#11 lore raw

PATCH v2 9/11 arm64/crypto: add voluntary preemption to Crypto Extensions SHA1

Quoted 32 lines · Catalin Marinas
Quoted 5 lines · Ard Biesheuvel

The Crypto Extensions based SHA1 implementation uses the NEON register file, and hence runs with preemption disabled. This patch adds a TIF_NEED_RESCHED check to its inner loop so we at least give up the CPU voluntarily when we are running in process context and have been tagged for preemption by the scheduler.

Sorry, I haven't got to the bottom of your series earlier and I now realised that the last patches are not just new crypto algorithms.

Quoted 22 lines
arch/arm64/crypto/sha1-ce-glue.c +22 -0
+static u8 const *sha1_do_update(struct shash_desc *desc, const u8 *data,
+                             int blocks, u8 *head, unsigned int len)
+{
+     struct sha1_state *sctx = shash_desc_ctx(desc);
+     struct thread_info *ti = NULL;
+
+     /*
+      * Pass current's thread info pointer to sha1_ce_transform()
+      * below if we want it to play nice under preemption.
+      */
+     if ((IS_ENABLED(CONFIG_PREEMPT_VOLUNTARY) || IS_ENABLED(CONFIG_PREEMPT))
+         && (desc->flags & CRYPTO_TFM_REQ_MAY_SLEEP))
+             ti = current_thread_info();
+
+     do {
+             int rem;
+
+             kernel_neon_begin_partial(16);
+             rem = sha1_ce_transform(blocks, data, sctx->state, head, 0, ti);
+             kernel_neon_end();
+
+             data += (blocks - rem) * SHA1_BLOCK_SIZE;
Quoted 9 lines

arch/arm64/crypto/sha1-ce-glue.c static int sha1_init(struct shash_desc *desc) · line 62

Quoted 5 lines
arch/arm64/crypto/sha1-ce-glue.c +5 -0
+             blocks = rem;
+             head = NULL;
+     } while (unlikely(ti && blocks > 0));
+     return data;
+}

What latencies are we talking about? Would it make sense to always call cond_resched() even if preemption is disabled?

Calculating the SHA256 (which is the most striking example) hash of a 4k buffer takes ~10 microseconds, so perhaps this is all a bit moot as I don't think there will generally be many in-kernel users hashing substantially larger quantities of data at a time.

Quoted 4 lines

With PREEMPT_VOLUNTARY I don't think the above code does any voluntary preemption. The preempt_enable() in kernel_neon_end() only reschedules if PREEMPT.

Right, my mistake.

Quoted 5 lines

But I think we should have this loop always rescheduling if CRYPTO_TFM_REQ_MAY_SLEEP. I can see there is a crypto_yield() function that conditionally reschedules. What's the overhead of calling sha1_ce_transform() in a loop vs a single call for the entire data?

For SHA256 we lose at least 10% if we call into the core function for each 64 byte block rather than letting it chew away at all the data itself. (This is due to the fact that it needs to load 64 32-bit round keys) But perhaps (considering the above) it is better to just shelve the last 4 patches in this series until it becomes a problem for anyone.

Signature · 1 line
Ard.
maintainer
#12 lore raw

PATCH v2 9/11 arm64/crypto: add voluntary preemption to Crypto Extensions SHA1

Quoted 33 lines · Ard Biesheuvel
Quoted 23 lines · Catalin Marinas
Quoted 22 lines · Ard Biesheuvel
arch/arm64/crypto/sha1-ce-glue.c +22 -0
+static u8 const *sha1_do_update(struct shash_desc *desc, const u8 *data,
+                             int blocks, u8 *head, unsigned int len)
+{
+     struct sha1_state *sctx = shash_desc_ctx(desc);
+     struct thread_info *ti = NULL;
+
+     /*
+      * Pass current's thread info pointer to sha1_ce_transform()
+      * below if we want it to play nice under preemption.
+      */
+     if ((IS_ENABLED(CONFIG_PREEMPT_VOLUNTARY) || IS_ENABLED(CONFIG_PREEMPT))
+         && (desc->flags & CRYPTO_TFM_REQ_MAY_SLEEP))
+             ti = current_thread_info();
+
+     do {
+             int rem;
+
+             kernel_neon_begin_partial(16);
+             rem = sha1_ce_transform(blocks, data, sctx->state, head, 0, ti);
+             kernel_neon_end();
+
+             data += (blocks - rem) * SHA1_BLOCK_SIZE;
Quoted 8 lines

arch/arm64/crypto/sha1-ce-glue.c static int sha1_init(struct shash_desc *desc) · line 62

Quoted 5 lines
arch/arm64/crypto/sha1-ce-glue.c +5 -0
+             blocks = rem;
+             head = NULL;
+     } while (unlikely(ti && blocks > 0));
+     return data;
+}

What latencies are we talking about? Would it make sense to always call cond_resched() even if preemption is disabled?

Quoted 4 lines

Calculating the SHA256 (which is the most striking example) hash of a 4k buffer takes ~10 microseconds, so perhaps this is all a bit moot as I don't think there will generally be many in-kernel users hashing substantially larger quantities of data at a time.

And what?s the maximum size? Could we do it in blocks of 4K?

Quoted 8 lines
Quoted 4 lines

But I think we should have this loop always rescheduling if CRYPTO_TFM_REQ_MAY_SLEEP. I can see there is a crypto_yield() function that conditionally reschedules. What's the overhead of calling sha1_ce_transform() in a loop vs a single call for the entire data?

For SHA256 we lose at least 10% if we call into the core function for each 64 byte block rather than letting it chew away at all the data itself.

I was thinking more like calling it for bigger buffers (e.g. page) at once and a crypto_yield() in between.

Quoted 4 lines

(This is due to the fact that it needs to load 64 32-bit round keys) But perhaps (considering the above) it is better to just shelve the last 4 patches in this series until it becomes a problem for anyone.

For the time being I would drop the last 4 patches. We can revisit them for the next kernel version.

Catalin

#13 lore raw

PATCH v2 9/11 arm64/crypto: add voluntary preemption to Crypto Extensions SHA1

Quoted 34 lines · Catalin Marinas
Quoted 33 lines · Ard Biesheuvel
Quoted 31 lines · Catalin Marinas
Quoted 17 lines · Ard Biesheuvel
arch/arm64/crypto/sha1-ce-glue.c +17 -0
+static u8 const *sha1_do_update(struct shash_desc *desc, const u8 *data,
+                             int blocks, u8 *head, unsigned int len)
+{
+     struct sha1_state *sctx = shash_desc_ctx(desc);
+     struct thread_info *ti = NULL;
+
+     /*
+      * Pass current's thread info pointer to sha1_ce_transform()
+      * below if we want it to play nice under preemption.
+      */
+     if ((IS_ENABLED(CONFIG_PREEMPT_VOLUNTARY) || IS_ENABLED(CONFIG_PREEMPT))
+         && (desc->flags & CRYPTO_TFM_REQ_MAY_SLEEP))
+             ti = current_thread_info();
+
+     do {
+             int rem;
+

arch/arm64/crypto/sha1-ce-glue.c static int sha1_init(struct shash_desc *desc) · line 62

Quoted 10 lines
arch/arm64/crypto/sha1-ce-glue.c +10 -0
+             kernel_neon_begin_partial(16);
+             rem = sha1_ce_transform(blocks, data, sctx->state, head, 0, ti);
+             kernel_neon_end();
+
+             data += (blocks - rem) * SHA1_BLOCK_SIZE;
+             blocks = rem;
+             head = NULL;
+     } while (unlikely(ti && blocks > 0));
+     return data;
+}

What latencies are we talking about? Would it make sense to always call cond_resched() even if preemption is disabled?

Quoted 7 lines
Quoted 4 lines

Calculating the SHA256 (which is the most striking example) hash of a 4k buffer takes ~10 microseconds, so perhaps this is all a bit moot as I don't think there will generally be many in-kernel users hashing substantially larger quantities of data at a time.

And what?s the maximum size? Could we do it in blocks of 4K?

Yes, that should be doable as well. Once we feel we actually need this feature, that is probably a better approach.

Quoted 12 lines
Quoted 8 lines
Quoted 4 lines

But I think we should have this loop always rescheduling if CRYPTO_TFM_REQ_MAY_SLEEP. I can see there is a crypto_yield() function that conditionally reschedules. What's the overhead of calling sha1_ce_transform() in a loop vs a single call for the entire data?

For SHA256 we lose at least 10% if we call into the core function for each 64 byte block rather than letting it chew away at all the data itself.

I was thinking more like calling it for bigger buffers (e.g. page) at once and a crypto_yield() in between.

Quoted 8 lines
Quoted 4 lines

(This is due to the fact that it needs to load 64 32-bit round keys) But perhaps (considering the above) it is better to just shelve the last 4 patches in this series until it becomes a problem for anyone.

For the time being I would drop the last 4 patches. We can revisit them for the next kernel version.

Agreed.

Should I send an updated pull request?

Signature · 1 line
Ard.
maintainer
#14 lore raw

PATCH v2 9/11 arm64/crypto: add voluntary preemption to Crypto Extensions SHA1

Quoted 7 lines · Ard Biesheuvel
Quoted 2 lines · Catalin Marinas

For the time being I would drop the last 4 patches. We can revisit them for the next kernel version.

Agreed.

Should I send an updated pull request?

As it's not a signed tag anyway, I can merge up to the relevant commit.

Signature · 1 line
Catalin
#15 lore raw

PATCH v2 10/11 arm64/crypto: add voluntary preemption to Crypto Extensions SHA2

In reply to Ard Biesheuvel

The Crypto Extensions based SHA2 implementation uses the NEON register file, and hence runs with preemption disabled. This patch adds a TIF_NEED_RESCHED check to its inner loop so we at least give up the CPU voluntarily when we are running in process context and have been tagged for preemption by the scheduler.

---
 arch/arm64/crypto/sha2-ce-core.S | 19 ++++++++-------
 arch/arm64/crypto/sha2-ce-glue.c | 51 ++++++++++++++++++++++++++--------------
 2 files changed, 44 insertions(+), 26 deletions(-)
arch/arm64/crypto/sha2-ce-core.S +11 -8
index 7f29fc031ea8..71c617cd57ca 100644
@@ -73,8 +73,8 @@
 	.word		0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
 
 	/*
-	 * void sha2_ce_transform(int blocks, u8 const *src, u32 *state,
-	 *                        u8 *head, long bytes)
+	 * int sha2_ce_transform(int blocks, u8 const *src, u32 *state,
+	 *                       u8 *head, long bytes, struct thread_info *ti)
 	 */
 ENTRY(sha2_ce_transform)
 	/* load round constants */
@@ -131,7 +131,14 @@ CPU_LE(	rev32		v19.16b, v19.16b	)
 	add		dgbv.4s, dgbv.4s, dg1v.4s
 
 	/* handled all input blocks? */
-	cbnz		w0, 0b
+	cbz		w0, 4f
+
+	/* should we exit early? */
+	b_if_no_resched	x5, x8, 0b
+
+	/* store new state */
+3:	stp		dga, dgb, [x2]
+	ret
 
 	/*
 	 * Final block: add padding and total bit count.
@@ -139,7 +146,7 @@ CPU_LE(	rev32		v19.16b, v19.16b	)
 	 * size was not a round multiple of the block size, and the padding is
 	 * handled by the C code.
 	 */
-	cbz		x4, 3f
+4:	cbz		x4, 3b
 	movi		v17.2d, #0
 	mov		x8, #0x80000000
 	movi		v18.2d, #0
@@ -149,8 +156,4 @@ CPU_LE(	rev32		v19.16b, v19.16b	)
 	mov		v19.d[0], xzr
 	mov		v19.d[1], x7
 	b		2b
-
-	/* store new state */
-3:	stp		dga, dgb, [x2]
-	ret
 ENDPROC(sha2_ce_transform)
arch/arm64/crypto/sha2-ce-glue.c +33 -18

88 lines not on this page · raw message

Signature · 1 line
1.8.3.2
#16 lore raw

PATCH v2 11/11 arm64/crypto: add voluntary preemption to Crypto Extensions GHASH

In reply to Ard Biesheuvel

The Crypto Extensions based GHASH implementation uses the NEON register file, and hence runs with preemption disabled. This patch adds a TIF_NEED_RESCHED check to its inner loop so we at least give up the CPU voluntarily when we are running in process context and have been tagged for preemption by the scheduler.

---
 arch/arm64/crypto/ghash-ce-core.S | 10 ++++++----
 arch/arm64/crypto/ghash-ce-glue.c | 34 ++++++++++++++++++++++++++--------
 2 files changed, 32 insertions(+), 12 deletions(-)
arch/arm64/crypto/ghash-ce-core.S +6 -4
index b9e6eaf41c9b..523432f24ed2 100644
@@ -31,8 +31,9 @@
 	.arch		armv8-a+crypto
 
 	/*
-	 * void pmull_ghash_update(int blocks, u64 dg[], const char *src,
-	 *			   struct ghash_key const *k, const char *head)
+	 * int pmull_ghash_update(int blocks, u64 dg[], const char *src,
+	 *			  struct ghash_key const *k, const char *head,
+	 * 			  struct thread_info *ti)
 	 */
 ENTRY(pmull_ghash_update)
 	ld1		{DATA.16b}, [x1]
@@ -88,8 +89,9 @@ CPU_LE(	rev64		IN1.16b, IN1.16b	)
 	eor		T1.16b, T1.16b, T2.16b
 	eor		DATA.16b, DATA.16b, T1.16b
 
-	cbnz		w0, 0b
+	cbz		w0, 2f
+	b_if_no_resched	x5, x7, 0b
 
-	st1		{DATA.16b}, [x1]
+2:	st1		{DATA.16b}, [x1]
 	ret
 ENDPROC(pmull_ghash_update)
arch/arm64/crypto/ghash-ce-glue.c +26 -8
index b92baf3f68c7..b8f58f9bcf00 100644
@@ -33,8 +33,9 @@ struct ghash_desc_ctx {
 	u32 count;
 };
 
-asmlinkage void pmull_ghash_update(int blocks, u64 dg[], const char *src,
-				   struct ghash_key const *k, const char *head);
+asmlinkage int pmull_ghash_update(int blocks, u64 dg[], const char *src,
+				  struct ghash_key const *k, const char *head,
+				  struct thread_info *ti);
 
 static int ghash_init(struct shash_desc *desc)
 {
@@ -54,6 +55,7 @@ static int ghash_update(struct shash_desc *desc, const u8 *src,
 
 	if ((partial + len) >= GHASH_BLOCK_SIZE) {
 		struct ghash_key *key = crypto_shash_ctx(desc->tfm);
+		struct thread_info *ti = NULL;
 		int blocks;
 
 		if (partial) {
@@ -64,14 +66,30 @@ static int ghash_update(struct shash_desc *desc, const u8 *src,
 			len -= p;
 		}
 
+		/*
+		 * Pass current's thread info pointer to pmull_ghash_update()
+		 * below if we want it to play nice under preemption.
+		 */
+		if ((IS_ENABLED(CONFIG_PREEMPT_VOLUNTARY) ||
+		     IS_ENABLED(CONFIG_PREEMPT))
+		    && (desc->flags & CRYPTO_TFM_REQ_MAY_SLEEP))
+			ti = current_thread_info();
+
 		blocks = len / GHASH_BLOCK_SIZE;
 		len %= GHASH_BLOCK_SIZE;
 
-		kernel_neon_begin_partial(6);
-		pmull_ghash_update(blocks, ctx->digest, src, key,
-				   partial ? ctx->buf : NULL);
-		kernel_neon_end();
-		src += blocks * GHASH_BLOCK_SIZE;
+		do {
+			int rem;
+
+			kernel_neon_begin_partial(6);
+			rem = pmull_ghash_update(blocks, ctx->digest, src, key,
+						 partial ? ctx->buf : NULL, ti);
+			kernel_neon_end();
+
+			src += (blocks - rem) * GHASH_BLOCK_SIZE;
+			blocks = rem;
+			partial = 0;
+		} while (unlikely(ti && blocks > 0));
 	}
 	if (len)
 		memcpy(ctx->buf + partial, src, len);
@@ -89,7 +107,7 @@ static int ghash_final(struct shash_desc *desc, u8 *dst)
 		memset(ctx->buf + partial, 0, GHASH_BLOCK_SIZE - partial);
 
 		kernel_neon_begin_partial(6);
-		pmull_ghash_update(1, ctx->digest, ctx->buf, key, NULL);
+		pmull_ghash_update(1, ctx->digest, ctx->buf, key, NULL, NULL);
 		kernel_neon_end();
 	}
 	put_unaligned_be64(ctx->digest[1], dst);
Signature · 1 line
1.8.3.2