Details
-
Bug
-
Status: Stalled (View Workflow)
-
Major
-
Resolution: Unresolved
-
None
-
None
-
Clang version: 17
Target architecture: RISC-V
Description
Problem Description
When executing the mariadbd binary compiled for the RISC-V architecture using Clang 17, a SIGILL error occurs. The compilation process itself completes without errors. I believe this runtime error may be related to the use of __builtin_readcyclecounter in the my_timer_cycles function (in include/my_rdtsc.h), which seems to generate an rdcycle instruction that is illegal to execute in user mode on RISC-V.
Steps to Reproduce
Compile MariaDB/server for RISC-V architecture using Clang 17
execute ./sql/mariadb
The compilation process triggers a SIGILL error
Analysis
In include/my_rdtsc.h, the my_timer_cycles function uses __builtin_readcyclecounter
A simple test program was written to verify the behavior of __builtin_readcyclecounter
Using objdump to analyze the compiled binary confirms the generation of the rdcycle instruction
In RISC-V architecture, rdcycle is a privileged instruction, execution in user mode triggers a SIGILL error
Relevant Code
// Test code
|
int main() { |
unsigned long cycles; |
cycles = __builtin_readcyclecounter();
|
printf("Cycle count: %lu\n", cycles); |
return 0; |
}
|
 |
// objdump
|
0000000000000668 <main>:
|
...
|
672: fca43c23 sd a0,-40(s0)
|
676: fea42623 sw a0,-20(s0)
|
67a: c0002573 rdcycle a0
|
67e: fea43023 sd a0,-32(s0)
|
...
|
69c: 8082 ret
|
If this issue is confirmed, one possible solution might be to modify the condition in include/my_rdtsc.h to explicitly use the RISC-V specific implementation:
# if __has_builtin(__builtin_readcyclecounter) && !defined(__aarch64__) && !defined(__riscv) |
static inline ulonglong my_timer_cycles(void) |
{
|
# if __has_builtin(__builtin_readcyclecounter) && !defined (__aarch64__)
|
#define MY_TIMER_ROUTINE_CYCLES MY_TIMER_ROUTINE_AARCH64
|
return __builtin_readcyclecounter(); |
...
|
#elif defined(__riscv)
|
#define MY_TIMER_ROUTINE_CYCLES MY_TIMER_ROUTINE_RISCV
|
/* Use RDTIME (and RDTIMEH on riscv32) */ |
{
|
# if __riscv_xlen == 32
|
ulong result_lo, result_hi0, result_hi1;
|
/* Implemented in assembly because Clang insisted on branching. */ |
__asm __volatile__(
|
"rdtimeh %0\n" |
"rdtime %1\n" |
"rdtimeh %2\n" |
"sub %0, %0, %2\n" |
"seqz %0, %0\n" |
"sub %0, zero, %0\n" |
"and %1, %1, %0\n" |
: "=r"(result_hi0), "=r"(result_lo), "=r"(result_hi1)); |
return (static_cast<ulonglong>(result_hi1) << 32) | result_lo; |
# else
|
ulonglong result;
|
__asm __volatile__("rdtime %0" : "=r"(result)); |
return result; |
}
|
# endif
|
#elif defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
|
#define MY_TIMER_ROUTINE_CYCLES MY_TIMER_ROUTINE_GETHRTIME
|
/* gethrtime may appear as either cycle or nanosecond counter */ |
return (ulonglong) gethrtime(); |
#else
|
#define MY_TIMER_ROUTINE_CYCLES 0
|
return 0; |
#endif
|
}
|
Attachments
Issue Links
- duplicates
-
MDEV-33435 RISC-V RDCYCLE cannot be accessed from userland
- Closed