Skip to content

Fix randomx_get_flags not reporting hardware AES on RISC-V - #370

Open
thomasbuilds wants to merge 1 commit into
tevador:masterfrom
thomasbuilds:fix-riscv-get-flags-aes
Open

thomasbuilds wants to merge 1 commit into
tevador:masterfrom
thomasbuilds:fix-riscv-get-flags-aes

Conversation

@thomasbuilds

@thomasbuilds thomasbuilds commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

randomx_get_flags() reports RANDOMX_FLAG_HARD_AES only if HAVE_AES is 1, which it never was on RISC-V: rx_aesenc_vec_i128/rx_aesdec_vec_i128 had no RISC-V implementation. So callers that take their flags from it, such as Monero and randomx-benchmark --auto, used software AES even where hardware AES is detected.

This implements both functions with Zvkned in aes_hash_rv64_zvkned.cpp, the file already compiled with Zvkned, and sets HAVE_AES to 1 on RISC-V. They are only called from RANDOMX_FLAG_HARD_AES VMs, which VmBase::allocate() rejects unless cpu.hasAes(). In those VMs, the interpreter's v2 AES mix now uses them instead of software AES. platformError only exists when HAVE_AES is 0, so allocate() now uses the string directly. The "Hardware AES not supported" test keeps running on RISC-V.

@hyc hyc left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If the CPU has hardware AES but HAVE_AES is not being defined, then the right thing to do is to fix that, not muck around here.

@SChernykh

Copy link
Copy Markdown
Collaborator

Yes, HAVE_AES should be 1 on RISC-V because there are AES instruction extensions there.

@thomasbuilds
thomasbuilds force-pushed the fix-riscv-get-flags-aes branch 2 times, most recently from 614502d to 6788dd3 Compare October 31, 2026 09:27
@thomasbuilds
thomasbuilds requested a review from hyc October 31, 2026 11:05
Comment thread src/tests/tests.cpp
#else
constexpr bool hardAesCheckedAtRuntime = !HAVE_AES;
#endif
runTest("Hardware AES not supported", hardAesCheckedAtRuntime && !randomx::cpu.hasAes(), []() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This change seems completely unnecessary. Why single out RISC-V?

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.

With HAVE_AES now 1 on RISC-V, the old condition would skip this test on every RISC-V build, including the riscv64 CI job, where it runs today (QEMU's CPU has VLEN 128 so cpu.hasAes() is false). RISC-V is singled out because it's the only platform where allocate() checks cpu.hasAes(). Elsewhere, with HAVE_AES 1, allocate() executes an AES instruction so with a plain !cpu.hasAes() the test would fail in the ppc64le and Win32 CI jobs, where cpu.hasAes() is never set but the CPU has AES.

Comment thread src/virtual_machine.cpp
#ifdef __riscv
if (!softAes && !cpu.hasAes())
throw std::runtime_error(platformError);
throw std::runtime_error("Platform doesn't support hardware AES");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Completely unrelated and unnecessary change.

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.

platformError is only declared inside the #ifndef HAVE_AES block of intrin_portable.h so with HAVE_AES now defined on RISC-V the original line fails to compile ('platformError' was not declared in this scope). The message text is unchanged.

Comment thread src/vm_interpreted.cpp Outdated
freg[0] = aesenc<softAes>(freg[0], ekey[i]);
freg[1] = aesdec<softAes>(freg[1], ekey[i]);
freg[2] = aesenc<softAes>(freg[2], ekey[i]);
freg[3] = aesdec<softAes>(freg[3], ekey[i]);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why remove it? If HAVE_AES is 0 and softAes is false, this will compile to a code that will throw an exception in intrin_portable.h

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.

Will restore

@thomasbuilds
thomasbuilds force-pushed the fix-riscv-get-flags-aes branch 2 times, most recently from b63be62 to d21bbd8 Compare October 31, 2026 14:56
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.

3 participants