diff options
author | Alex Bennée <alex.bennee@linaro.org> | 2018-06-22 15:12:05 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-07-02 13:08:21 +0100 |
commit | 13eea5418eaf682284bda6944626298a5a78cc00 (patch) | |
tree | f87670680bf0d9e6704865aa1bdc1ae58ed03b92 | |
parent | 3e7398eb1e0c7d5b8c1c45f5ac15ca2fd8a8661a (diff) |
risu_reginfo_aarch64: handle variable VQ
This involves parsing the command line parameter and calling the
kernel to set the VQ limit. We also add dumping of the register state
in the main register dump.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180622141205.16306-23-alex.bennee@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | risu_reginfo_aarch64.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/risu_reginfo_aarch64.c b/risu_reginfo_aarch64.c index bf98ba1..00d1c8b 100644 --- a/risu_reginfo_aarch64.c +++ b/risu_reginfo_aarch64.c @@ -18,6 +18,8 @@ #include <stddef.h> #include <stdbool.h> #include <inttypes.h> +#include <assert.h> +#include <sys/prctl.h> #include "risu.h" #include "risu_reginfo_aarch64.h" @@ -30,17 +32,41 @@ const char * const arch_extra_help; /* Should we test SVE register state */ static int test_sve; static const struct option extra_opts[] = { - {"test-sve", no_argument, &test_sve, 1}, + {"test-sve", required_argument, NULL, FIRST_ARCH_OPT }, {0, 0, 0, 0} }; const struct option * const arch_long_opts = &extra_opts[0]; -const char * const arch_extra_help = " --test-sve Compare SVE registers\n"; +const char * const arch_extra_help + = " --test-sve=<vq> Compare SVE registers with VQ\n"; #endif void process_arch_opt(int opt, const char *arg) { +#ifdef SVE_MAGIC + long want, got; + + assert(opt == FIRST_ARCH_OPT); + test_sve = strtol(arg, 0, 10); + + if (test_sve <= 0 || test_sve > SVE_VQ_MAX) { + fprintf(stderr, "Invalid value for VQ (1-%d)\n", SVE_VQ_MAX); + exit(1); + } + want = sve_vl_from_vq(test_sve); + got = prctl(PR_SVE_SET_VL, want); + if (want != got) { + if (got < 0) { + perror("prctl PR_SVE_SET_VL"); + } else { + fprintf(stderr, "Unsupported value for VQ (%d != %d)\n", + test_sve, (int)sve_vq_from_vl(got)); + } + exit(1); + } +#else abort(); +#endif } const int reginfo_size(void) @@ -113,12 +139,18 @@ void reginfo_init(struct reginfo *ri, ucontext_t *uc) #ifdef SVE_MAGIC if (test_sve) { - int vq = sve_vq_from_vl(sve->vl); /* number of quads for whole vl */ + int vq = test_sve; if (sve == NULL) { fprintf(stderr, "risu_reginfo_aarch64: failed to get SVE state\n"); return; } + if (sve->vl != sve_vl_from_vq(vq)) { + fprintf(stderr, "risu_reginfo_aarch64: " + "unexpected SVE state: %d != %d\n", + sve->vl, sve_vl_from_vq(vq)); + return; + } ri->sve.vl = sve->vl; |