Question and scenario
Your team must ship one Linux application to several RISC-V 64-bit application processors. Explain how RVA23 provides a common hardware baseline, which extensions are guaranteed, and how compiler and runtime decisions handle optional capabilities.
What the interviewer is testing
- Separating the base ISA, a profile, extensions, and vendor-specific capabilities.
- Mapping profile constraints to the ABI,
-march/-mabi, and a release matrix. - Distinguishing compiling for a profile from enabling optional extensions at runtime.
Clarifying questions before answering
Clarify whether the target is RVA23U64 or another profile, the OS and libc, static or dynamic linking, and whether older RVA22/RV64 platforms need a fallback. Ask whether the application uses vector or hypervisor features and whether the target is one chip or a compatible processor set.
30-second answer framework
RVA23 is a standardized profile for 64-bit application processors. It creates a dependable binary baseline from mandatory extensions while leaving a small set of discoverable coarse-grain options. I would compile a baseline against the lowest profile and stable ABI, build optional variants, and dispatch only after checking CPU capabilities, OS state preservation, and toolchain support. A release must test real hardware, emulators, and fallback paths.
Step-by-step deep answer
- Read the target profile version and baseline, recording mandatory and optional extensions, privilege environment, and vector-state requirements. RISC-V is not one fixed ISA.
- Choose
-marchand-mabiso baseline code depends only on the release profile. Put aggressive optimizations in separate variants so older CPUs cannot execute unknown instructions. - At startup or a capability layer, detect optional extensions and whether the OS/kernel preserves their context. Map the result to function multiversioning, plugins, or an interpreted path.
- For vectors, separate architectural support from VLEN/ELEN parameters. Algorithms need scalar fallbacks; implementations do not share one vector width.
- In CI, run profile compliance checks, cross-compilation, an emulator, and at least one real chip. Test illegal instructions, the dynamic linker, signal handling, and thread migration.
- Record CPU, profile, compiler, and libc versions in release metadata. On incompatibility, fall back to the baseline build instead of allowing a random runtime crash.
riscv64-linux-gnu-gcc -march=rv64gcv_zba_zbb_zbs -mabi=lp64d app.c -o app
readelf -A appHigh-quality sample answer
RVA23 combines common extensions for 64-bit application processors into a dependable profile, so software ecosystems do not guess at each chip’s ISA. I would ship a baseline built for the minimum profile and stable ABI, then separate optional vector or other optimized variants and dispatch only after checking CPU capability, OS context preservation, and toolchain support. CI would include profile checks, an emulator, and real hardware, while recording -march/-mabi, libc, and kernel versions. This keeps vendor extensions or wider VLEN out of the portable binary without giving up optimized paths.
Common errors
- Treating RISC-V as one fixed instruction set and ignoring profiles and extension sets.
- Specifying
-marchwithout considering-mabi, libc, or the dynamic linker. - Assuming vector support implies the same VLEN/ELEN everywhere.
- Shipping without scalar fallback or illegal-instruction monitoring.
- Testing only an emulator and missing real-chip, OS-state, or thread-migration behavior.
Follow-up questions and responses
What is the relationship between a profile and an extension?
An extension is one ISA capability. A profile is a versioned combination that defines mandatory capabilities and discoverable options. Software should depend on the profile contract, not a vendor string.
Why not compile only for the fastest CPU with -march?
The result may contain instructions absent on other targets and trap with an illegal instruction. Keep optimized variants separate and select them through capability detection.
What must vector testing cover?
Test VLEN/ELEN differences, OS vector-state preservation, signals, thread migration, and scalar fallback. Architectural support does not make every vector width available.
How do you handle a profile upgrade?
Record the profile version in build and release metadata, expand the CI and hardware matrix, and raise the baseline gradually. Keep older artifacts for older platforms instead of introducing silent binary incompatibility.