Skip to content

Add Neoverse-V3 (Graviton5) detection and dispatch - #3374

Merged
nebeid merged 7 commits into
aws:mainfrom
nebeid:graviton5-neoverse-v3-dispatch
Aug 1, 2026
Merged

nebeid merged 7 commits into
aws:mainfrom
nebeid:graviton5-neoverse-v3-dispatch

Conversation

@nebeid

@nebeid nebeid commented Jul 24, 2026 •

Copy link
Copy Markdown
Contributor

Issues

N/A

Description of Changes

Add runtime and static detection of the Neoverse-V3 microarchitecture (Graviton5, MIDR part 0xD84) and group it with Neoverse-V1/V2 for selecting AWS-LC's fastest AArch64 implementations.

Why

AWS-LC gates several of its fastest AArch64 code paths on a microarchitecture allowlist (Neoverse-V1/V2, Apple-M). Neoverse-V3 was not on that list, so on Graviton5 the library silently fell through to
slower fallbacks. Measured on a c9g (Neoverse-V3) instance, with every dispatch path trap-verified at the object-code level:

Workload Before (fallback) After (V-core path) Delta
AES-128-GCM, 16 KB 6135 MB/s (4x kernel) 8854 MB/s (8x-EOR3) +44%
RSA-2048 sign 1227 ops/s (s2n-bignum) 2025 ops/s (generic) +65%
RSA-2048 verify 49986 ops/s 77819 ops/s +56%
SHAKE256-x4, 16 KB Neon-SHA3 keccak2 (413 MB/s) V-core alt2 (448 MB/s) +8%

Changes

  • arm_arch.h: add ARMV8_NEOVERSE_V3 (bit 1<<18) and ARM_CPU_PART_V3 (0xD84); update the CPU-indicator-bit mask comments (0x7080โ†’0x47080, 0x78fcโ†’0x478fc).
  • cpu_aarch64_linux.c: detect the V3 MIDR at runtime; set the V3 bit and the N1-subset bit (matching the existing V1/V2 pattern).
  • cpucap.c: static-armcap support via OPENSSL_STATIC_ARMCAP_NEOVERSE_V3 / __ARM_FEATURE_NEOVERSE_V3.
  • internal.h: add V3 to the AES-GCM-8x and wide-multiplier gates; add CRYPTO_is_Neoverse_V3(); exclude V3 from CRYPTO_is_Neoverse_N1() (since detection also sets the N1-subset bit, V3 must be excluded here or it would be mis-classified as N1 and mis-route Keccak).
  • keccak1600.c: group V3 with V1/V2 at both dispatch sites.
  • all_tests.json: update the CPU-indicator armcap masks used by the "dispatch without CPU indicator bits" tests to include the V3 bit.
  • CI: add a linux-graviton5-c9g-2xlarge CodeBuild fleet and agraviton5 job in linux_arm_omnibus.yml (mirrors the graviton4 job).

Testing

  • Built and ran crypto_test on a Neoverse-V3 (c9g) instance; all tests pass and the FIPS module links cleanly.
  • Each dispatch decision (GCM 8x, generic Montgomery, Keccak alt2) was trap-verified on hardware to confirm the intended kernel executes.
  • Benchmarks above collected on c9g with warmup + averaged repeated runs.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.

AWS-LC gates its fastest AArch64 implementations (AES-GCM 8x-EOR3,
wide-multiplier Montgomery, batched Keccak) on a microarchitecture
allowlist of Neoverse-V1/V2 and Apple-M. Neoverse-V3 (Graviton5,
MIDR part 0xD84) was not detected, so on Graviton5 the library fell
through to slower fallbacks:
  * AES-128-GCM 16KB:  6135 -> 8854 MB/s   (+44%, 4x -> 8x-EOR3)
  * RSA-2048 sign:     1227 -> 2025 ops/s  (+65%, s2n-bignum -> generic)
  * RSA-2048 verify:  49986 -> 77819 ops/s (+56%)
  * Batched Keccak (SHAKE256-x4): now uses the V-core alt2 kernel
Measured on c9g (Neoverse-V3), all dispatch paths trap-verified.

Changes:
  * arm_arch.h: ARMV8_NEOVERSE_V3 bit (1<<18), ARM_CPU_PART_V3 (0xD84);
    update CPU-indicator-bit masks 0x7080->0x47080, 0x78fc->0x478fc.
  * cpu_aarch64_linux.c: detect V3 MIDR (sets V3 + N1-subset bit).
  * cpucap.c: static-armcap support for V3.
  * internal.h: add V3 to GCM_8x/wide_multiplier gates + CRYPTO_is_Neoverse_V3();
    exclude V3 from is_Neoverse_N1() (V3 is not N1).
  * keccak1600.c: group V3 with V1/V2 in both dispatch sites.
  * all_tests.json: update CPU-indicator armcap masks to include the V3 bit.
  * CI: add linux-graviton5-c9g-2xlarge fleet + graviton5 job.
@github-actions

Copy link
Copy Markdown
Contributor

๐Ÿ”’ Security Review โ€” View Report

Please review before merging.

@codecov-commenter

codecov-commenter commented Jul 24, 2026 •

Copy link
Copy Markdown

Codecov Report

โœ… All modified and coverable lines are covered by tests.
โœ… Project coverage is 78.19%. Comparing base (b822cec) to head (b6866c3).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3374      +/-   ##
==========================================
- Coverage   78.40%   78.19%   -0.22%     
==========================================
  Files         695      695              
  Lines      124222   124220       -2     
  Branches    17265    17261       -4     
==========================================
- Hits        97400    97136     -264     
- Misses      25899    26162     +263     
+ Partials      923      922       -1     

โ˜” View full report in Codecov by Harness.
๐Ÿ“ข Have feedback on the report? Share it here.

๐Ÿš€ New features to boost your workflow:
  • โ„๏ธ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.


#if defined(MY_ASSEMBLER_SUPPORTS_NEON_SHA3_EXTENSION)
if (CRYPTO_is_Neoverse_V1() || CRYPTO_is_Neoverse_V2()) {
if (CRYPTO_is_Neoverse_V1() || CRYPTO_is_Neoverse_V2() || CRYPTO_is_Neoverse_V3()) {

@hanno-becker hanno-becker Jul 26, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am surprised that we see a speedup here. V3 has SHA3 instruction support on all Neon units, and should use the path L450ff (like Apple silicon CPUs)-- or so I thought.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We investigated and benchmarked V3 on both paths: the SHA3-extension path you're pointing at (L450ff, sha3_keccak2_f1600 run twice) and the V1/V2 grouping (sha3_keccak4_f1600_alt2). Both were trap-verified at the object-code level to confirm the intended kernel actually executed, warmup + 7 reps, SHAKE256-x4 Absorb @ 16 KB:

core alt2 (V1/V2 path) keccak2 (SHA3-ext path, L450ff) delta
V2 (Graviton4) 264.9 MB/s 120.8 MB/s alt2 +119%
V3 (Graviton5) 447.8 MB/s 413.5 MB/s alt2 +8.3%

You're right that V3 closes the gap dramatically โ€” this is exactly the effect of the improved SHA3 units you describe: the keccak2 SHA3-extension path jumps 120.8 โ†’ 413.5 MB/s (3.4ร—) from V2 to V3, so it nearly catches alt2. But alt2 still wins on V3 by ~8%, so grouping V3 with V1/V2 is the (narrowly) faster choice here rather than routing it to the Apple-silicon path. The margin is small enough that if a future V-core flips the ordering we'd want to revisit, but on measured Graviton5 the V-grouping is correct.

(Numbers are on stock c9g / r8g; V3 ~3.29 GHz vs V2 ~2.79 GHz.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On another note, while looking into your point, I also checked the single-buffer (x1) path on V3, since the same "V3 has full-width SHA3" reasoning could apply there too. To rule out measurement drift on a shared instance, I ran both paths interleaved (A/B/A/B per rep, pinned core, prebuilt trap-verified binaries, 40 reps):

x1 kernel V3 (MB/s)
sha3_keccak_f1600 (scalar lazy-rot, what V3 gets) 914
sha3_keccak_f1600_alt (SHA3-extension) 832

Scalar won 40/40 interleaved reps (+9.9% mean).

The x4 comparison in this thread held up the same way โ€” alt2 won 40/40 reps (+8.4%) over the SHA3-ext path. So V3 stays grouped with N1/V1/V2 at both x1 and x4.

This doesn't contradict the wider SHA3 units โ€” the scalar lazy-rotation kernel is just very good on V3's scalar/barrel-shift path โ€” so I've kept the "SHA3 on 1/4 Neon units" comment scoped to V1/V2.

Comment on lines +91 to +92
// CPU capabilities of N1 are a subset of CPU capabilities of V3
OPENSSL_armcap_P |= ARMV8_NEOVERSE_N1;

@hanno-becker hanno-becker Jul 26, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pre-existing: I think it is confusing to set the NEOVERSE_N1 capability on a CPU that is not an N1. ISTM that one should set at most a one CPU-specific capability (none if the CPU is not detected). If NEOVERSE_N1 is used as an indicator of certain architectural capabilities that all Neoverse cores offer, that deserves a separate helper.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We resorted to that solution to be able to test N1-specific code paths on a Vx machine in FIPS ACVP testing as detailed in #2815. ACVP testing relies on setting the OPENSSL_armcap environment variable to test the various code paths included in the module.

@hanno-becker hanno-becker Jul 28, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @nebeid!

Rationale: we can think of the N1 capabilities as a subset of those of V1 and V2, so enabling its bit is semantically valid

I can see the motivation, thank you. However, is overloading the CPU capability for N1 the right solution? Now, ARMV8_NEOVERSE_N1 stands both for a specific CPU and for an unspecified set of architecture capabilities. It is also not the case that we are building hierarchical capabilities -- e.g. V2 does not set the V1 capability.

Have you considered introducing a separate capability capturing which aspects of N1 you care about here?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding is that the V2 and V1 code paths overlap, thus there is (currently) no need for setting the additional flag โ€” and the same applies to V3.
On the other hand, I am also wondering about the value of setting the V1/V2 flag on V3, in case a new code path is introduced for V3 โ€” a V3 machine wouldn't otherwise be able to reach and test the V1/V2 code paths. It could be done later when/if needed, but it also could be missed, as it is not obvious that it is needed for the tests. Perhaps we could add a note.

@nebeid nebeid left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your review, Hanno.


#if defined(MY_ASSEMBLER_SUPPORTS_NEON_SHA3_EXTENSION)
if (CRYPTO_is_Neoverse_V1() || CRYPTO_is_Neoverse_V2()) {
if (CRYPTO_is_Neoverse_V1() || CRYPTO_is_Neoverse_V2() || CRYPTO_is_Neoverse_V3()) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We investigated and benchmarked V3 on both paths: the SHA3-extension path you're pointing at (L450ff, sha3_keccak2_f1600 run twice) and the V1/V2 grouping (sha3_keccak4_f1600_alt2). Both were trap-verified at the object-code level to confirm the intended kernel actually executed, warmup + 7 reps, SHAKE256-x4 Absorb @ 16 KB:

core alt2 (V1/V2 path) keccak2 (SHA3-ext path, L450ff) delta
V2 (Graviton4) 264.9 MB/s 120.8 MB/s alt2 +119%
V3 (Graviton5) 447.8 MB/s 413.5 MB/s alt2 +8.3%

You're right that V3 closes the gap dramatically โ€” this is exactly the effect of the improved SHA3 units you describe: the keccak2 SHA3-extension path jumps 120.8 โ†’ 413.5 MB/s (3.4ร—) from V2 to V3, so it nearly catches alt2. But alt2 still wins on V3 by ~8%, so grouping V3 with V1/V2 is the (narrowly) faster choice here rather than routing it to the Apple-silicon path. The margin is small enough that if a future V-core flips the ordering we'd want to revisit, but on measured Graviton5 the V-grouping is correct.

(Numbers are on stock c9g / r8g; V3 ~3.29 GHz vs V2 ~2.79 GHz.

Comment on lines +91 to +92
// CPU capabilities of N1 are a subset of CPU capabilities of V3
OPENSSL_armcap_P |= ARMV8_NEOVERSE_N1;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We resorted to that solution to be able to test N1-specific code paths on a Vx machine in FIPS ACVP testing as detailed in #2815. ACVP testing relies on setting the OPENSSL_armcap environment variable to test the various code paths included in the module.

Group V3 with N1/V1/V2 (x1 scalar) and V1/V2 (x4 SIMD) in the
dispatch-logic comments, matching the code. Note that V3's SHA3-extension
x4 path is much faster than on V1/V2 but the SIMD path still wins, so V3
stays grouped there. The 'SHA3 on 1/4 Neon units' note is left as V1/V2
only -- V3 has full-width SHA3, and the scalar x1 kernel wins for a
different reason (very good on V3's wide scalar/barrel-shift units).

Benchmarks (Neoverse-V3, trap-verified, 7 reps):
  x1 SHA3-256 @16k: scalar 914 vs SHA3-ext 832 MB/s (+9.8%)
  x4 SHAKE256 @16k: SIMD alt2 448 vs SHA3-ext keccak2 414 MB/s (+8.3%)
@hanno-becker

Copy link
Copy Markdown
Contributor

@nebeid Thank you for digging into this. I missed that V3 has faster Barrel shifter than Apple M cores.

It is interesting to note that if scalar ~= Neon, than 2x scalar + 1x Neon (hybrid) ~= 2x Neon (non-hybrid), with the LHS's apparently winning slightly in each case.

Note that leave quite a bit of performance on the table here: In 2x scalar + 1x Neon, the Neon unit is busy only half of the time because the scalar is the bottleneck. An optimal hybrid would use 1x scalar + 1x Neon, but that would be a 3x-batch, which we have no APIs for. The amortized cost of 1x scalar + 1x Neon would be 1/3 (because it's a x3 batch), whereas the amortized cost of 2x scalar + 1x Neon is 1/2 because it's a x4 batch (one unit being the Scalar/Neon cost in each case).

We may want evaluate whether it's worth allowing an x3-native version for Keccak in mlx-native.

@nebeid
nebeid marked this pull request as ready for review July 29, 2026 16:57
@nebeid
nebeid requested a review from a team as a code owner July 29, 2026 16:57
@nebeid
nebeid enabled auto-merge (squash) July 30, 2026 22:34
@nebeid
nebeid merged commit 8480499 into aws:main Aug 1, 2026
522 of 528 checks passed
justsmth pushed a commit that referenced this pull request Aug 6, 2026
### Description of Changes

Remove the `linux-graviton5-c9g-2xlarge` CodeBuild fleet and the
`graviton5` job added in #3374. Targeted revert of that PR's CI portions
only โ€” the Neoverse-V3 dispatch code stays in place.

#### Why

The c9g fleet fails to deploy. CodeBuild reserved-capacity fleets do not
currently support the c9g (Graviton5) instance family:

- The CodeBuild docs' "Supported instance families" list for reserved
fleets tops out at `c8g` for compute-optimized (`c6g | c7g | c8g`); no
`c9g`. See
https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-compute-types.html
- A `create_fleet` call with `c9g.2xlarge` returns "The specified
instance type is not supported", while the same request with a supported
family (`c8g.2xlarge`) succeeds.

Graviton5 CI can be re-added once CodeBuild supports a Graviton5 fleet
instance family.

By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 license and the ISC license.

Co-authored-by: Prasanth Dendukuri <prasden@amazon.com>
social4hyq pushed a commit to social4hyq/homebrew-core that referenced this pull request Sep 20, 2026
aws-lc 5.5.0

Created-by: HarmonybrewBot
Commit-by: HarmonybrewBot
Merged-by: HarmonybrewBot
Description: Created by `brew bump`

---

Created with `brew bump-formula-pr`.<details>
  <summary>release notes</summary>
  <pre>## What's Changed
* Restore ADX/AVX2 code paths under OPENSSL_SMALL via new MY_ASSEMBLER_IS_TOO_OLD_FOR_ADX_AVX2 flag by @justsmth in aws/aws-lc#3368
* Include <openssl/cipher.h> from <openssl/hmac.h> for OpenSSL compat by @justsmth in aws/aws-lc#3371
* ci: harden security-review.yml against script injection by @nebeid in aws/aws-lc#3365
* Fix flaky s_client cipher tests by using better ciphers by @justsmth in aws/aws-lc#3373
* chore: simplify the api docs workflow by @dougch in aws/aws-lc#3186
* Add tests for RSASSA-PSS with SHA-3 digest and MGF1 by @WillChilds-Klein in aws/aws-lc#3377
* Link header documentation from README by @WillChilds-Klein in aws/aws-lc#3378
* Rename autofix reasoning role to AwsLcGitHubActionsBedrockRole by @tianyiy-tim in aws/aws-lc#3376
* ci: pin openssh required job by @dougch in aws/aws-lc#3387
* delocate: Drop redundant `-dI` flag by @hanno-becker in aws/aws-lc#3384
* Add Neoverse-V3 (Graviton5) detection and dispatch by @nebeid in aws/aws-lc#3374
* Bump ring from 0.17.8 to 0.17.14 in /tests/ci/lambda by @dependabot[bot] in aws/aws-lc#3375
* Fix docker image dependencies and update octocrab initialization by @prasden in aws/aws-lc#3388
* Update FIPS.md by @justsmth in aws/aws-lc#3382
* Bump urllib3 from 2.6.3 to 2.7.0 in /tests/ci by @dependabot[bot] in aws/aws-lc#3372
* Add MinGW shared-library Windows CI coverage by @justsmth in aws/aws-lc#3398
* Update concurrency in `security-review` by @nhatnghiho in aws/aws-lc#3403
* Enable linker garbage collection for non-FIPS static builds by @justsmth in aws/aws-lc#3397
* Prepare 5.5.0 by @justsmth in aws/aws-lc#3401

## New Contributors
* @tianyiy-tim made their first contribution in aws/aws-lc#3376

**Full Changelog**: https://github.com/aws/aws-lc/compare/v5.4.0...v5.5.0</pre>
  <p>View the full release notes at <a href="https://github.com/aws/aws-lc/releases/tag/v5.5.0">https://github.com/aws/aws-lc/releases/tag/v5.5.0</a>.</p>
</details>
<hr>

See merge request: Harmonybrew/homebrew-core!15934

This branch was previously deployed

1 inactive deployment
auto-approve โ€” b6866c34 Deployed Aug 1, 2026 by nebeid via execute #564
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.

5 participants