Skip to content

zfs(openzfs): enable OpenZFS on aarch64 (follow-on to #1423) - #1459

Open
gburd wants to merge 4 commits into
cloudius-systems:masterfrom
gburd:pr/openzfs-aarch64
Open

zfs(openzfs): enable OpenZFS on aarch64 (follow-on to #1423)#1459
gburd wants to merge 4 commits into
cloudius-systems:masterfrom
gburd:pr/openzfs-aarch64

Conversation

@gburd

@gburd gburd commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Enables the vendored OpenZFS 2.4.3 port (added in #1423) to build on aarch64, with x86_64 left byte-for-byte unchanged.

Depends on: #1423

This is the aarch64 follow-on to #1423 ("zfs: selectable in-kernel ZFS (BSD or OpenZFS 2.4.2) via upstream submodule + patch series"). It is cut directly on top of that PR's tip and must land after it — the two commits here only make sense against the modules/open_zfs/ submodule + patch-series layout introduced by #1423.

What this does

Two small, self-contained changes — the aarch64-enablement nugget re-authored against the current modules/open_zfs/ layout:

  1. modules/open_zfs/patches/0031-*.patch — SPL sha512 stub / SIMD fallback.
    The OSv SPL layer (patch 0001) only recognized x86_64: isa_defs.h #errored on any other ISA, and simd.h's non-x86 feature-detection stub block was missing zfs_sha512_available(). On x86_64 SHA-512 availability comes from the sha512-x86_64.S asm path so the stub was never needed; aarch64 has no such asm hook wired into the SPL, so icp/algs/sha2 calls zfs_sha512_available() and fails without the fallback. Patch 0031 adds an __aarch64__ ISA branch to isa_defs.h and the missing zfs_sha512_available() B_FALSE stub to simd.h. The submodule stays pinned to the pristine upstream zfs-2.4.3 tag — this is a new entry in the patch series, not a submodule re-pin.

  2. modules/open_zfs/open_zfs_sources.mk — arch-conditional ICP asm object lists.
    The x86_64 ICP crypto asm objects (aes_amd64.S, aes_aesni.S, aeskey.c) have no top-level __x86_64__ guard and emit raw x86 instructions, so an aarch64 build's assembler chokes on them. (The raidz vdev_raidz_math_* objects already coexist across arches via per-file #ifdef guards; the ICP asm objects do not.) The object selection is now gated on $(arch): x64 gets aeskey.o + the four x86_64 asm objects exactly as before; aarch64 gets the #if defined(__aarch64__)-guarded ARMv8 sha256/sha512 asm and the native ARMv8 blake3 asm (all present in the upstream zfs-2.4.3 submodule). No Makefile change is needed — open_zfs_sources.mk is already included after arch is set.

x86_64 is unaffected (arch-gated)

With arch=x64 the emitted openzfs-icp / openzfs-icp-asm object lists are byte-identical to #1423 (verified by expanding both branches of the makefile). Patch 0031's hunks are all guarded by __aarch64__ or the existing non-x86 #else, so x86_64 preprocessor output is unchanged.

Not included

  • No submodule re-pin (2.4.3 preserved).
  • No libsolaris.so / userspace-CLI compile-flag changes. The old aarch64 branch bundled an -isystem-I libspl include-ordering tweak with unrelated io_uring syscall aliases; that swap is not arch-gated, only manifests during an aarch64 userspace build, and risks perturbing the x86 userspace build if applied blind. It's deferred until it can be validated on real aarch64 hardware.

⚠️ BUILD-UNVERIFIED on aarch64 — needs an aarch64 metal build+boot to validate before un-drafting.

This was re-authored from the older aarch64 work by inspection against the current layout; it has not been compiled or booted on aarch64 (no aarch64 toolchain/hardware available at authoring time). The x86_64 no-op property is verified by makefile expansion, but the aarch64 build+boot path must be exercised on aarch64 hardware before this leaves draft.

@gburd
gburd force-pushed the pr/openzfs-aarch64 branch 2 times, most recently from 37ea518 to 53dec06 Compare July 31, 2026 13:12
@gburd

gburd commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

Same status as #1423: this branch's base predates several merged tests and it needs the full forward-port + ZFS module restructure, not just a Makefile fixup. I will convert its ZFS test entries to standalone tests += lines (per #1469) as part of that forward-port. Holding until then.

@gburd
gburd force-pushed the pr/openzfs-aarch64 branch from 53dec06 to e7155a9 Compare August 18, 2026 08:39
@gburd

gburd commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

#1423 merged, so this is rebased onto master. Most of the earlier ZFS content is now on master via the squash-merge, so this reduces to just the aarch64-specific enablement:

  • aarch64: raise the ARM generic-timer frequency ceiling to 2GHz
  • libc: gate the aarch64 atomic.h kernel-only includes so the ZFS userspace builds
  • zfs(openzfs): make the ICP asm object lists arch-conditional for aarch64
  • zfs(openzfs): enable aarch64 SPL isa_defs and the sha512 SIMD B_FALSE fallback

The post-restructure layout carries the OSv SPL platform files as parent-tracked source under modules/open_zfs/osv/ rather than as submodule patches, so the SPL isa_defs/simd change is applied there directly. The vnode_pager_setsize NULL-vnode guard from the old series is already on master, so it is dropped here.

x64 verify: conf_zfs=openzfs fs=zfs compiles and links clean (loader.elf, libsolaris.so, libzfs.so, zpool.so), no regression from the aarch64 SPL/simd edits.

aarch64 build-verify pending: the aarch64 cross-build compiles all of the changed SPL/ICP/atomic/timer objects clean, but the full openzfs image build is currently blocked on an unrelated pre-existing gap - the aarch64 userspace libzfs cannot find zlib.h in the cross toolchain include path. Leaving this draft until the aarch64 openzfs image is verified end to end.

gburd added 4 commits August 18, 2026 06:19
The generic-timer frequency sanity check rejected anything above 1GHz.
Current server ARM cores report generic-timer frequencies above 1GHz, which
tripped the old ceiling and aborted the boot. Raise the ceiling to 2GHz to
cover current server ARM cores with headroom while still rejecting a garbage
read.
libc/arch/aarch64/atomic.h pulls in OSv kernel-only headers (the
FreeBSD-derived machine/atomic.h and the bsd/cddl opensolaris sys/types.h),
which are only on the include path for kernel/bsd objects. Userspace
translation units that resolve <atomic.h> to this file (the OpenZFS
libspl/libzfs sources on aarch64) do not have them and do not need them.
Gate those includes on the kernel build and use the compiler atomic builtin
in the userspace path. The x86_64 variant has no such includes, so this is
aarch64-only and leaves x86_64 byte-identical.
open_zfs_sources.mk unconditionally listed the x86_64 ICP crypto asm objects
(aes_amd64.o, aes_aesni.o, sha256/sha512-x86_64.o) plus aeskey.o. The
aes_amd64.S / aes_aesni.S / aeskey.c sources carry no top-level __x86_64__
guard and emit raw x86 instructions, so on an aarch64 build the assembler
chokes. (The raidz vdev_raidz_math_* objects already coexist across arches
because each is #ifdef-guarded to compile-to-empty on the wrong ISA; the ICP
asm objects are not.)

Gate the object selection on $(arch) (open_zfs_sources.mk is already included
after arch is set, so no Makefile change is needed):

  - x64: aeskey.o + the four x86_64 ICP asm objects, exactly as before.
  - aarch64: the ARMv8 sha256/sha512 asm (both #if defined(__aarch64__)
    guarded) and the native ARMv8 blake3 asm, all present in the upstream
    zfs-2.4.3 submodule; no x86 objects, no aeskey.o.

x86_64 is unaffected: with arch=x64 the emitted openzfs-icp / openzfs-icp-asm
lists are byte-identical to before (verified by expanding both branches).

BUILD-UNVERIFIED on aarch64 - needs an aarch64 metal build+boot to
validate before un-drafting.

Signed-off-by: Greg Burd <greg@burd.me>
The OSv SPL platform layer only recognized x86_64: isa_defs.h #errored out
on any other ISA, and simd.h's non-x86 feature-detection stub block was
missing zfs_sha512_available(). On x86_64 OpenZFS pulls SHA-512 availability
from the sha512-x86_64.S asm path, so the stub was never needed; aarch64 has
no such asm hook wired into the SPL, so icp/algs/sha2 calls
zfs_sha512_available() and fails to compile without the fallback.

Teach the SPL layer about aarch64:

  - isa_defs.h: add an __aarch64__ ISA branch (LP64, _SUNOS_VTOC_16), matching
    the existing x86_64 branch. Endianness is still derived from __BYTE_ORDER
    below, so no arch-specific endian define is needed.
  - simd.h: add zfs_sha512_available() to the non-x86 B_FALSE stub block so
    the SHA-512 impl selector resolves to the generic C path on aarch64.

x86_64 is unaffected: both hunks add new code guarded by __aarch64__ / the
existing non-x86 #else block, leaving the x86_64 preprocessor paths byte for
byte identical. Applied as direct edits to the parent-tracked OSv platform
source under modules/open_zfs/osv/ (the module now carries these files as
real source rather than as a submodule patch).
@gburd
gburd force-pushed the pr/openzfs-aarch64 branch from e7155a9 to 03b5735 Compare August 18, 2026 10:22
@gburd
gburd marked this pull request as ready for review August 18, 2026 10:22
@gburd

gburd commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

aarch64 conf_zfs=openzfs builds clean (rc=0) on a native arm64 host: loader.elf, libsolaris.so, libzfs.so, libzfs_core.so, zpool.so, and zfs.so all compile and link with zero errors (301 OpenZFS objects), and the resulting aarch64 loader boots (banner + network up). The arch-conditional ICP asm selection resolves correctly: aarch64 pulls the ARMv8 sha256/sha512 and blake3 asm and none of the x86 objects, x86_64 is byte-identical to before.

The image build was verified on a native arm64 toolchain (gcc 13.3.1, binutils 2.40), matching the toolchain used to qualify the x86_64 OpenZFS image in #1423. Building natively sidesteps the earlier blocker: the aarch64 userspace libzfs could not find zlib.h in a cross toolchain. That was a cross-build include-path gap in the toolchain, not in this change; a native build finds the platform zlib headers and compiles cleanly, so no source change was needed for it.

One cleanup in this revision: the arm-clock.cc generic-timer comment is now fully vendor- and core-neutral (it explains only that current server ARM cores report frequencies above 1GHz, which the old 1GHz ceiling rejected; the ceiling is raised to 2GHz). The code is otherwise identical to the previous revision. The functional OpenZFS content is unchanged from #1423 (same submodule pin, same platform sources); this PR only adds the aarch64-specific SPL isa_defs, the SHA-512 SIMD C fallback, the userspace atomic.h gating, and the arch-conditional ICP asm lists. Ready for review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant