git: 75ad24775b68 - main - stand: Add blake3 support to boot loader

From: Warner Losh <imp_at_FreeBSD.org>
Date: Sat, 09 Jul 2022 05:03:33 UTC
The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=75ad24775b68c59e95bef0047fd6fc8a01271a03

commit 75ad24775b68c59e95bef0047fd6fc8a01271a03
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2022-07-08 23:35:06 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2022-07-09 04:57:59 +0000

    stand: Add blake3 support to boot loader
    
    Add the necessary glue to get blake3 building for the boot loaded as
    well as connected to the ZFS system so it is useful.
    
    On some platforms, we create references to blake3_sse2_impl and
    blake3_sse41_impl ops structs to utilize SIMD. These aren't present on
    x86 (since we dind't ask for them), but are on aarch64 with no
    implementation. Since we don't want SIMD in the boot loader, have these
    all return 'unsupported' always. This should be fixed upstream to allow
    more flexibility in this selection, but for now we use this hack to not
    modify the sys/contrib/openzfs with difficult to maintain hacks while
    an upstreamable solution is found.
    
    tsoome@ did the implementation bits in sys/cddl/boot, and I did the
    Makefile work and the aweful blake3_impl_hack.c.
    
    Co-author:              tsoome@freebsd.org
    Sponsored by:           Netflix
    Reviewed by:            kevans (earlier version)
    Differential Revision:  https://reviews.freebsd.org/D35750
---
 stand/libsa/zfs/Makefile.inc       |  8 ++++
 stand/libsa/zfs/blake3_impl_hack.c | 28 +++++++++++
 stand/libsa/zfs/zfsimpl.c          |  1 +
 sys/cddl/boot/zfs/blake3_zfs.c     | 97 ++++++++++++++++++++++++++++++++++++++
 sys/cddl/boot/zfs/zfsimpl.h        |  1 +
 sys/cddl/boot/zfs/zfssubr.c        |  7 ++-
 6 files changed, 141 insertions(+), 1 deletion(-)

diff --git a/stand/libsa/zfs/Makefile.inc b/stand/libsa/zfs/Makefile.inc
index 3f28c39c69da..314f74c903f1 100644
--- a/stand/libsa/zfs/Makefile.inc
+++ b/stand/libsa/zfs/Makefile.inc
@@ -7,8 +7,10 @@
 .PATH:		${OZFS}/module/zstd/lib/common
 .PATH:		${OZFS}/module/zstd/lib/compress
 .PATH:		${OZFS}/module/zstd/lib/decompress
+.PATH:		${OZFS}/module/icp/algs/blake3
 ZFS_SRC=	zfs.c nvlist.c skein.c skein_block.c list.c
 ZFS_SRC+=	zfs_zstd.c
+ZFS_SRC+=	blake3.c blake3_generic.c blake3_impl_hack.c
 ZSTD_SRC+=	entropy_common.c error_private.c
 ZSTD_SRC+=	fse_compress.c fse_decompress.c hist.c
 ZSTD_SRC+=	huf_compress.c huf_decompress.c pool.c xxhash.c
@@ -35,6 +37,9 @@ CFLAGS.$i+=	-include ${ZFSOSINC}/spl/sys/ccompile.h -Wformat -Wall -I${OZFS}/inc
 	-DNEED_SOLARIS_BOOLEAN
 .endfor
 
+CFLAGS_EARLY.blake3.c+= ${ZFS_EARLY}
+CFLAGS_EARLY.blake3_generic.c+= ${ZFS_EARLY}
+CFLAGS_EARLY.blake3_impl_hack.c+= ${ZFS_EARLY}
 CFLAGS_EARLY.list.c+= ${ZFS_EARLY}
 CFLAGS_EARLY.zfs_zstd.c+= ${ZFS_EARLY}
 
@@ -58,3 +63,6 @@ CFLAGS.zfs_zstd.c+= -DIN_BASE -DIN_LIBSA
 
 # Do not unroll skein loops, reduce code size
 CFLAGS.skein_block.c+=	-DSKEIN_LOOP=111
+
+# To puck up blake3_impl.c...
+CFLAGS.blake3_impl_hack.c+= -I${OZFS}/module/icp/algs/blake3
diff --git a/stand/libsa/zfs/blake3_impl_hack.c b/stand/libsa/zfs/blake3_impl_hack.c
new file mode 100644
index 000000000000..709ce510dad6
--- /dev/null
+++ b/stand/libsa/zfs/blake3_impl_hack.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2022, Netflix, Inc
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+/*
+ * Hack for aarch64... There's no way to tell it omit the SIMD
+ * versions, so we fake it here.
+ */
+#include "blake3_impl.c"
+
+static inline boolean_t blake3_is_not_supported(void)
+{
+	return (B_FALSE);
+}
+
+const blake3_impl_ops_t blake3_sse2_impl = {
+	.is_supported = blake3_is_not_supported,
+	.degree = 4,
+	.name = "fakesse2"
+};
+
+const blake3_impl_ops_t blake3_sse41_impl = {
+	.is_supported = blake3_is_not_supported,
+	.degree = 4,
+	.name = "fakesse41"
+};
diff --git a/stand/libsa/zfs/zfsimpl.c b/stand/libsa/zfs/zfsimpl.c
index 865294dafed4..6b961f3110ae 100644
--- a/stand/libsa/zfs/zfsimpl.c
+++ b/stand/libsa/zfs/zfsimpl.c
@@ -140,6 +140,7 @@ static const char *features_for_read[] = {
 	"org.freebsd:zstd_compress",
 	"com.delphix:bookmark_written",
 	"com.delphix:head_errlog",
+	"org.openzfs:blake3",
 	NULL
 };
 
diff --git a/sys/cddl/boot/zfs/blake3_zfs.c b/sys/cddl/boot/zfs/blake3_zfs.c
new file mode 100644
index 000000000000..0b2e1a014f62
--- /dev/null
+++ b/sys/cddl/boot/zfs/blake3_zfs.c
@@ -0,0 +1,97 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://opensource.org/licenses/CDDL-1.0.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2022 Tino Reichardt <milky-zfs@mcmilk.de>
+ */
+
+#include <sys/blake3.h>
+
+/*
+ * Computes a native 256-bit BLAKE3 MAC checksum. Please note that this
+ * function requires the presence of a ctx_template that should be allocated
+ * using zio_checksum_blake3_tmpl_init.
+ */
+static void
+zio_checksum_blake3_native(const void *buf, uint64_t size,
+    const void *ctx_template, zio_cksum_t *zcp)
+{
+	BLAKE3_CTX ctx;
+
+	ASSERT(ctx_template != 0);
+
+	memcpy(&ctx, ctx_template, sizeof(ctx));
+	Blake3_Update(&ctx, buf, size);
+	Blake3_Final(&ctx, (uint8_t *)zcp);
+
+	memset(&ctx, 0, sizeof (ctx));
+}
+
+/*
+ * Byteswapped version of zio_checksum_blake3_native. This just invokes
+ * the native checksum function and byteswaps the resulting checksum (since
+ * BLAKE3 is internally endian-insensitive).
+ */
+static void
+zio_checksum_blake3_byteswap(const void *buf, uint64_t size,
+    const void *ctx_template, zio_cksum_t *zcp)
+{
+	zio_cksum_t tmp;
+
+	ASSERT(ctx_template != 0);
+
+	zio_checksum_blake3_native(buf, size, ctx_template, &tmp);
+	zcp->zc_word[0] = BSWAP_64(tmp.zc_word[0]);
+	zcp->zc_word[1] = BSWAP_64(tmp.zc_word[1]);
+	zcp->zc_word[2] = BSWAP_64(tmp.zc_word[2]);
+	zcp->zc_word[3] = BSWAP_64(tmp.zc_word[3]);
+}
+
+/*
+ * Allocates a BLAKE3 MAC template suitable for using in BLAKE3 MAC checksum
+ * computations and returns a pointer to it.
+ */
+static void *
+zio_checksum_blake3_tmpl_init(const zio_cksum_salt_t *salt)
+{
+	BLAKE3_CTX *ctx;
+
+	ASSERT(sizeof (salt->zcs_bytes) == 32);
+
+	/* init reference object */
+	ctx = calloc(1, sizeof(*ctx));
+	Blake3_InitKeyed(ctx, salt->zcs_bytes);
+
+	return (ctx);
+}
+
+/*
+ * Frees a BLAKE3 context template previously allocated using
+ * zio_checksum_blake3_tmpl_init.
+ */
+static void
+zio_checksum_blake3_tmpl_free(void *ctx_template)
+{
+	BLAKE3_CTX *ctx = ctx_template;
+
+	memset(ctx, 0, sizeof(*ctx));
+	free(ctx);
+}
diff --git a/sys/cddl/boot/zfs/zfsimpl.h b/sys/cddl/boot/zfs/zfsimpl.h
index 9b09b3436c8e..d6e8900f6a97 100644
--- a/sys/cddl/boot/zfs/zfsimpl.h
+++ b/sys/cddl/boot/zfs/zfsimpl.h
@@ -602,6 +602,7 @@ enum zio_checksum {
 	ZIO_CHECKSUM_SHA512,
 	ZIO_CHECKSUM_SKEIN,
 	ZIO_CHECKSUM_EDONR,
+	ZIO_CHECKSUM_BLAKE3,
 	ZIO_CHECKSUM_FUNCTIONS
 };
 
diff --git a/sys/cddl/boot/zfs/zfssubr.c b/sys/cddl/boot/zfs/zfssubr.c
index 2e309fc10be4..c5ee4fda4579 100644
--- a/sys/cddl/boot/zfs/zfssubr.c
+++ b/sys/cddl/boot/zfs/zfssubr.c
@@ -102,6 +102,7 @@ typedef struct zio_checksum_info {
 #include "blkptr.c"
 
 #include "fletcher.c"
+#include "blake3_zfs.c"
 #include "sha256.c"
 #include "skein_zfs.c"
 
@@ -140,7 +141,11 @@ static zio_checksum_info_t zio_checksum_table[ZIO_CHECKSUM_FUNCTIONS] = {
 	    ZCHECKSUM_FLAG_SALTED | ZCHECKSUM_FLAG_NOPWRITE, "skein"},
 	/* no edonr for now */
 	{{NULL, NULL}, NULL, NULL, ZCHECKSUM_FLAG_METADATA |
-	    ZCHECKSUM_FLAG_SALTED | ZCHECKSUM_FLAG_NOPWRITE, "edonr"}
+	    ZCHECKSUM_FLAG_SALTED | ZCHECKSUM_FLAG_NOPWRITE, "edonr"},
+	{{zio_checksum_blake3_native,	zio_checksum_blake3_byteswap},
+	    zio_checksum_blake3_tmpl_init, zio_checksum_blake3_tmpl_free,
+	    ZCHECKSUM_FLAG_METADATA | ZCHECKSUM_FLAG_DEDUP |
+	    ZCHECKSUM_FLAG_SALTED | ZCHECKSUM_FLAG_NOPWRITE, "blake3"}
 };
 
 /*