Skip to content

Commit

Permalink
i#3544 RV64: Implements proc_has_feature() for vector extension (Dyna…
Browse files Browse the repository at this point in the history
…moRIO#6836)

Detects RISC-V vector extension support using SIGILL in
signal_arch_init(). Manually tested on real hardware.

Issue: DynamoRIO#3544
  • Loading branch information
ksco authored Jun 4, 2024
1 parent 8419c47 commit 51e439f
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 13 deletions.
14 changes: 7 additions & 7 deletions core/arch/proc_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,14 +195,12 @@ typedef struct {

#endif
#ifdef RISCV64
/* FIXME i#3544: Not implemented */
/**
* For RISC-V64 there are no features readable from userspace. Hence only a
* dummy flag is there. May be replaced by actual feature flags in the future.
* Used by proc_get_all_feature_bits().
* For RISC-V64 there are no features readable from userspace, so we mimic this ourselves,
* see signal_arch_init(). Used by proc_get_all_feature_bits().
*/
typedef struct {
uint64 dummy; /**< Dummy member to keep size non-0. */
uint64 isa_features[1];
} features_t;
#endif

Expand Down Expand Up @@ -410,13 +408,15 @@ typedef enum {
#endif

#ifdef RISCV64
/* FIXME i#3544: Not implemented */
/**
* Feature bits passed to proc_has_feature() to determine whether the underlying
* processor has the feature.
* XXX: The enum definitions here and the bitmask of hwprobe in the kernel are kept
* consistent to facilitate possible switching in the future, refer to
* https://github.com/torvalds/linux/blob/v6.9/arch/riscv/include/uapi/asm/hwprobe.h.
*/
typedef enum {
FEATURE_DUMMY = 0, /**< Dummy, non-existent feature. */
FEATURE_VECTOR = 2, /**< Vector extension. */
} feature_bit_t;
#endif

Expand Down
3 changes: 1 addition & 2 deletions core/arch/proc_shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,7 @@ cpu_info_t cpu_info = {
CACHE_SIZE_UNKNOWN,
CACHE_SIZE_UNKNOWN,
CACHE_SIZE_UNKNOWN,
/* FIXME i#3544: (RISCV64) Not implemented */
#ifdef AARCHXX
#if defined(AARCHXX) || defined(RISCV64)
{},
#else
{ 0 },
Expand Down
8 changes: 5 additions & 3 deletions core/arch/riscv64/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,13 @@ proc_init_arch(void)
}

bool
proc_has_feature(feature_bit_t f)
proc_has_feature(feature_bit_t feature_bit)
{
/* FIXME i#3544: Not implemented */
ASSERT_NOT_IMPLEMENTED(false);
#ifdef DR_HOST_NOT_TARGET
return false;
#else
return *cpu_info.features.isa_features & (1 << feature_bit);
#endif
}

void
Expand Down
54 changes: 53 additions & 1 deletion core/unix/signal_linux_riscv64.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@

#include "arch.h"

static int sigill_caught = 0;
static dr_jmp_buf_t jmpbuf;

extern cpu_info_t cpu_info;

void
save_fpstate(dcontext_t *dcontext, sigframe_rt_t *frame)
{
Expand Down Expand Up @@ -121,8 +126,55 @@ signal_frame_extra_size(bool include_alignment)
return 0;
}

static void
catch_sigill(int signo, kernel_siginfo_t *si, void *data)
{
(void)signo;
(void)si;
(void)data;

sigill_caught = 1;
dr_longjmp(&jmpbuf, 1);
}

static int
sigill_detected(void *func)
{
sigill_caught = 0;

kernel_sigaction_t act = { 0 };
kernel_sigaction_t old_act;

set_handler_sigact(&act, SIGILL, (handler_t)catch_sigill);
sigaction_syscall(SIGILL, &act, &old_act);

if (dr_setjmp(&jmpbuf) == 0) {
((void (*)(void))func)();
}

sigaction_syscall(SIGILL, &old_act, NULL);

return sigill_caught;
}

static void
func_v(void)
{
/* csrr zero, vcsr */
asm volatile(".align 2\n.word 0xf02073");
}

void
signal_arch_init(void)
{
/* Nothing. */
/* Detects RISC-V extensions support using SIGILL.
* We could also use the riscv_hwprobe syscall (since kernel 6.4) or /proc/cpuinfo to
* detect extension support, but as of year 2024, using SIGILL is still the most
* reliable way for various devices and kernel versions.
*
* Only supports the V extension detection for now.
*/
if (!sigill_detected((void *)func_v)) {
*cpu_info.features.isa_features |= 1 << FEATURE_VECTOR;
}
}

0 comments on commit 51e439f

Please sign in to comment.