RISC-V: detect virtual address space at runtime using hwprobe#1296
RISC-V: detect virtual address space at runtime using hwprobe#1296aurel32 wants to merge 1 commit into
Conversation
|
@microsoft-github-policy-service agree |
The virtual address space on RISC-V is currently detected at build time by parsing /proc/cpuinfo. This works when the binary runs on the same hardware it was built, however running such a binary on a system with a larger address space just causes a segmentation fault. Replace the build time check with a runtime detection using the hwprobe interface (available since Linux 6.11, commit c9b8cd139c1d "riscv: hwprobe export highest virtual userspace address"), with a fallback to parsing /proc/cpuinfo on older kernels.
|
Closing this pull request and as I have opened #1299 against the correct dev3 branch. |
| #else | ||
| #include <sys/mman.h> | ||
| #endif | ||
| #if defined(__riscv) || defined(_M_RISCV) |
There was a problem hiding this comment.
We cannot use extensions like __has_include generally as it requires C23 (and mimalloc assumes C11). I think we should use the cmake CHECK_INCLUDE_FILES and pass an extra define MI_HAS_ASM_HWPROBE_H such we can test in the sources for it.
(mmm, but maybe riscV is so recent that we can assume that all C compilers on riscV support __has_include ? ... maybe we can make an exception in that case as __has_include is quite clean?)
There was a problem hiding this comment.
I have seen it used in an other place so I assumed it was fine, but I realized now that it was guarded by defined(__APPLE__). I'll fix that as you suggested
| #endif | ||
|
|
||
| // Fallback to checking /proc/cpuinfo for older kernels | ||
| int fd = mi_prim_open("/proc/cpuinfo", O_RDONLY); |
| // Fallback to checking /proc/cpuinfo for older kernels | ||
| int fd = mi_prim_open("/proc/cpuinfo", O_RDONLY); | ||
| if (fd >= 0) { | ||
| char buf[4096]; |
There was a problem hiding this comment.
That is a large buffer on the stack; maybe 1024 bytes is enough to find if svXX is there?
There was a problem hiding this comment.
That works fine for now on a recent CPU, but that might be tight if more extensions are added. Here is for instance the first 1024 bytes on a SpacemiT K3:
processor : 0
hart : 0
isa : rv64imafdcvh_zicbom_zicbop_zicboz_ziccrse_zicntr_zicond_zicsr_zifencei_zihintntl_zihintpause_zihpm_zimop_zaamo_zalrsc_zawrs_zfa_zfbfmin_zfh_zfhmin_zca_zcb_zcd_zcmop_zba_zbb_zbc_zbs_zkt_zvbb_zvbc_zve32f_zve32x_zve64d_zve64f_zve64x_zvfbfmin_zvfbfwma_zvfh_zvfhmin_zvkb_zvkg_zvkned_zvknha_zvknhb_zvksed_zvksh_zvkt_smaia_smstateen_ssaia_sscofpmf_ssnpm_sstc_svade_svinval_svnapot_svpbmt
mmu : sv39
uarch : spacemit,x100
mvendorid : 0x710
marchid : 0x8000000058000002
mimpid : 0x33d8a600
hart isa : rv64imafdcvh_zicbom_zicbop_zicboz_ziccrse_zicntr_zicond_zicsr_zifencei_zihintntl_zihintpause_zihpm_zimop_zaamo_zalrsc_zawrs_zfa_zfbfmin_zfh_zfhmin_zca_zcb_zcd_zcmop_zba_zbb_zbc_zbs_zkt_zvbb_zvbc_zve32f_zve32x_zve64d_zve64f_zve64x_zvfbfmin_zvfbfwma_zvfh_zvfhmin_zvkb_zvkg_zvkned_zvknha_zvknhb_zvksed_zvksh_zvkt_smaia_smstateen_ssaia_sscofpmf_ssnpm_sstc_svade_svinval_svnapot_svpbmt
processor : 1
hart : 1
Would that be acceptable to go down to 2048 bytes instead?
| ssize_t nread = mi_prim_read(fd, &buf, sizeof(buf)); | ||
| mi_prim_close(fd); | ||
| if (nread >= 1) { | ||
| if (_mi_strnstr(buf, nread, "sv39")) { |
There was a problem hiding this comment.
Maybe we should also test if nread <= sizeof(buf) just in case.
|
Thanks @aurel32 ! I really like the riscV ISA so it would be great to support it well. I left some comments -- let me know if you think we can somewhat assume that all C compilers on riscV will have Also, can you rebase on the Thanks again. |
It seems I failed to do so, doing it now. |
The virtual address space on RISC-V is currently detected at build time by parsing /proc/cpuinfo. This works when the binary runs on the same hardware it was built, however running such a binary on a system with a larger address space just causes a segmentation fault.
Replace the build time check with a runtime detection using the hwprobe interface (available since Linux 6.11, commit c9b8cd139c1d "riscv: hwprobe export highest virtual userspace address"). For older kernels, fallback to the default 48 bits. This is suboptimal on SV39 MMUs but still works.