Repository navigation
fix(vex): decode arm64 MRS of all EL0-visible ID registers - #59
not-matthias merged 2 commits into
Conversation
Linux emulates EL0 reads of the ID registers in Op0=3, Op1=0, CRn=0, CRm=2..7 and returns 0 for registers it does not track, so these reads never trap natively. VEX decoded only some of them and raised SIGILL for the rest, e.g. ID_AA64FPFR0_EL1, which NumKong reads at import time. Return 0 for every encoding in that range that no specific case handles, reporting the features as absent. Also relabel the case for 0xD5380440, which decodes ID_AA64PFR2_EL1, not ID_AA64ZFR0_EL1. Closes #58
[Medium impact] The PR appears safe to merge; no actionable issues were found. SummaryExtends ARM64 register reads so programs can check additional CPU features without hitting
No actionable issues found. Runtime tests were not run during this review. Reviews (1) · Last reviewed commit: "fix(vex): decode arm64 MRS of TPIDRRO_EL..." · Reviewed by Greptile |
Merging this PR will not alter performance
Comparing Footnotes
|
GuillaumeLagrange
left a comment
There was a problem hiding this comment.
olgtm, quite niche but always good to fix
EL0 may read TPIDRRO_EL0, and Linux zeroes it for AArch64 tasks, so the read succeeds natively. VEX had no case for it and raised SIGILL. Return 0, matching the kernel.
a205ba0 to
8a69791
Compare
Decode arm64
MRSof every ID register Linux emulates for EL0, and ofTPIDRRO_EL0, instead of raising SIGILL.Linux traps and emulates EL0 reads of
Op0=3, Op1=0, CRn=0, CRm=2..7, returning the sanitized value or 0 for untracked registers (is_emulated()/emulate_sys_reg()inarch/arm64/kernel/cpufeature.c). VEX decoded only part of that range, so reads such asID_AA64FPFR0_EL1worked natively but crashed under Valgrind. NumKong reads it unconditionally in a load-time constructor, soimport numkong(andimport usearch>= 2.25) died with exit 132 and no traceback.Changes:
S3_0_C0_C<2..7>_<op2>. This reports the features as absent, consistent with the SVE-free PFR0 and zero PFR1 Valgrind already reports and with the HWCAPs it hides. An exhaustive check over all 128CRm/op2encodings inCRn=0shows the decoder now accepts exactly the set the kernel emulates (CRm=1and unknownCRm=0encodings still SIGILL, as natively).ID_AA64ZFR0_EL1actually decodes0xD5380440=ID_AA64PFR2_EL1; relabelled.MRS TPIDRRO_EL0returns 0: EL0 may read it (Arm ARM), and Linux zeroes it for AArch64 tasks (tls_thread_switch()).MSRto it stays undefined, as on hardware.none/tests/arm64/mrs_id_regsregression test.Verification (x86_64 host, aarch64 cross-build run under
qemu-aarch64 -cpu max; not yet run on real arm64 hardware, and CI does not run arm64 tests):mrs_id_regsimport numkong(7.6.0, CPython 3.12)ID_AA64FPFR0_EL1read, exit 132serial, neonEncodings cross-checked against Linux
arch/arm64/tools/sysregand the LLVM disassembler. Upstream has the same gap (KDE bug 487413).Closes #58