diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4 index d33f1885922..c1b873ed0ab 100644 --- a/make/autoconf/flags-cflags.m4 +++ b/make/autoconf/flags-cflags.m4 @@ -830,6 +830,22 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_CPU_DEP], FLAGS_SETUP_BRANCH_PROTECTION + if test "x$FLAGS_CPU" = xriscv64; then + AC_MSG_CHECKING([if RVV/vector sigcontext supported]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ], + [ + return (int)sizeof(struct __riscv_v_ext_state); + ])], + [ + AC_MSG_RESULT([yes]) + ], + [ + $1_DEFINES_CPU_JVM="${$1_DEFINES_CPU_JVM} -DNO_RVV_SIGCONTEXT" + AC_MSG_RESULT([no]) + ] + ) + fi + # EXPORT to API CFLAGS_JVM_COMMON="$ALWAYS_CFLAGS_JVM $ALWAYS_DEFINES_JVM \ $TOOLCHAIN_CFLAGS_JVM ${$1_TOOLCHAIN_CFLAGS_JVM} \ diff --git a/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp index a00659f37cb..0b6a1469d06 100644 --- a/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp +++ b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp @@ -56,8 +56,9 @@ // put OS-includes here # include -# include # include +# include +# include # include # include # include @@ -350,6 +351,72 @@ void os::print_context(outputStream *st, const void *context) { st->print_cr("%-*.*s=" INTPTR_FORMAT, 8, 8, reg_abi_names[r], (uintptr_t)uc->uc_mcontext.__gregs[r]); } st->cr(); + const struct __riscv_mc_d_ext_state * const f_ext_state = &(uc->uc_mcontext.__fpregs.__d); + st->print_cr("Floating point state:"); + st->print_cr("fcsr=" UINT32_FORMAT, f_ext_state->__fcsr); + st->print_cr("Floating point registers:"); + for (int r = 0; r < 32; r++) { + st->print_cr("f%d=" INTPTR_FORMAT, r, (intptr_t)f_ext_state->__f[r]); + } + st->cr(); + +#ifdef NO_RVV_SIGCONTEXT + st->print_cr("Vector state: JVM compiled without vector sigcontext support"); +#else // ifndef NO_RVV_SIGCONTEXT +// This magic number is not in any user-space header. +// No other choice but to define it (arch/riscv/include/uapi/asm/sigcontext.h). +#ifndef RISCV_V_MAGIC +#define RISCV_V_MAGIC 0x53465457 +#endif + + // Find the vector context + struct __riscv_extra_ext_header *ext = (struct __riscv_extra_ext_header *)(&uc->uc_mcontext.__fpregs); + if (ext->hdr.magic != RISCV_V_MAGIC) { + st->print_cr("Vector state: not found"); + return; + } + + // The size passed to user-space is calculated accordingly: + // size = sizeof(struct __riscv_ctx_hdr) + sizeof(struct __riscv_v_ext_state) + riscv_v_vsize; + uint32_t ext_size = ext->hdr.size; + + if (ext_size < (sizeof(struct __riscv_ctx_hdr) + sizeof(struct __riscv_v_ext_state))) { + st->print_cr("Vector state: not found, invalid size"); + return; + } + + struct __riscv_v_ext_state *v_ext_state = (struct __riscv_v_ext_state *)((char *)(ext) + sizeof(struct __riscv_extra_ext_header)); + + st->print_cr("Vector state:"); + st->print_cr("vstart=" INTPTR_FORMAT, v_ext_state->vstart); + st->print_cr("vl =" INTPTR_FORMAT, v_ext_state->vl); + st->print_cr("vtype =" INTPTR_FORMAT, v_ext_state->vtype); + st->print_cr("vcsr =" INTPTR_FORMAT, v_ext_state->vcsr); + st->print_cr("vlenb =" INTPTR_FORMAT, v_ext_state->vlenb); + st->print_cr("Vector registers:"); + + uint64_t vr_size = v_ext_state->vlenb; + + // Registers are after the v extensions header. + ext_size -= (sizeof(struct __riscv_ctx_hdr) + sizeof(struct __riscv_v_ext_state)); + + if (ext_size != (32 * vr_size)) { + st->print_cr("Vector registers: not found, invalid size"); + return; + } + + // datap format is undocumented, but is generated by kernel function riscv_v_vstate_save(). + uint8_t *regp = (uint8_t *)v_ext_state->datap; + for (int r = 0; r < 32; r++) { + st->print("v%d=0x", r); + for (int i = vr_size; i > 0; i--) { + st->print("%02" PRIx8, regp[i-1]); + } + st->print_cr(""); + regp += vr_size; + } + st->cr(); +#endif // #ifndef NO_RVV_SIGCONTEXT } void os::print_register_info(outputStream *st, const void *context, int& continuation) {