From patchwork Wed Jun 13 12:55:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 928870 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linaro.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="Ka3j0sG+"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 415RsL5zpYz9ry1 for ; Wed, 13 Jun 2018 23:08:54 +1000 (AEST) Received: from localhost ([::1]:34096 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fT5W8-00045O-Dk for incoming@patchwork.ozlabs.org; Wed, 13 Jun 2018 09:08:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52379) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fT5SD-0001Ui-3h for qemu-devel@nongnu.org; Wed, 13 Jun 2018 09:04:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fT5SB-0005Gj-HK for qemu-devel@nongnu.org; Wed, 13 Jun 2018 09:04:49 -0400 Received: from mail-wr0-x242.google.com ([2a00:1450:400c:c0c::242]:37688) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fT5SB-0005Dy-8f for qemu-devel@nongnu.org; Wed, 13 Jun 2018 09:04:47 -0400 Received: by mail-wr0-x242.google.com with SMTP id d8-v6so2693143wro.4 for ; Wed, 13 Jun 2018 06:04:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=7LijovdmKNV9kAq+uRPzeOm1CxkfeVzs8McFFxEKX1M=; b=Ka3j0sG+Rz47VAqe8RZ0IYI445ozvLKdXXWSX7cWjv4a+PgIosqzHjnPXanwSCRHhx xl+lWXFVcsS5KZMgZwA2Y4damwljuwy5FVoXD8q2PhGyS4WREL2bdhu7qBxa1Ae85J2h Z4mTprVmfZSx8f1D75MloOSm/piRMTSo5E4No= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=7LijovdmKNV9kAq+uRPzeOm1CxkfeVzs8McFFxEKX1M=; b=bZhQYdQCxNkIjScJw2zHuElZGph3aFO9Akj7+YhZsJF4zja7cGvXbcIyWCGEgtMB5T LoiLMZn1y5TuQMKalm6JWxmWCNFksjaSH678eFCAqvEswpCFZXXnnhzRcwV3eiuVMkfh wvOiC4GREGXtE9+Go1+qH2Q1yRf1FDVi/tOli7ZFbhLgkDswbqAMQnqg/TZmDCrJyNLA g83cYLwKImMrneMWIXMAVlXLiG5ypm0onclcA8P0jIxkJ4kb2wN+O3wYvegnbdgZExRl UqqNl16ibBFYqFUdKdyNpz2rOmD28dpQ9/kOVttmTn3f554xmuC0QUbqRHfeAJ4c2elx e+1w== X-Gm-Message-State: APt69E03vJJOvigsA+4RH70oKlovF938cWef4iGcZ1pLhw30PMXe3jki 1WTU+tMUGfwp8tUY4wuZHGBfFg== X-Google-Smtp-Source: ADUXVKKHXK60RbC+ocl20KlpUb5ZDhCnZPxPsLL+RpKL1ZPkTdC1DctqTXZ0KnGD436eiaY+kYWQ2Q== X-Received: by 2002:adf:a20a:: with SMTP id p10-v6mr4130343wra.196.1528895086103; Wed, 13 Jun 2018 06:04:46 -0700 (PDT) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id j4-v6sm2566981wrr.47.2018.06.13.06.04.45 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 13 Jun 2018 06:04:45 -0700 (PDT) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 24DA33E1305; Wed, 13 Jun 2018 13:56:02 +0100 (BST) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 13 Jun 2018 13:55:58 +0100 Message-Id: <20180613125601.14371-20-alex.bennee@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180613125601.14371-1-alex.bennee@linaro.org> References: <20180613125601.14371-1-alex.bennee@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::242 Subject: [Qemu-devel] [RISU PATCH v3 19/22] risu_reginfo_aarch64: add support for copying SVE register state X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?utf-8?q?Alex_Benn=C3=A9e?= , qemu-arm@nongnu.org, richard.henderson@linaro.org, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Add the ability to save SVE registers from the signal context. This is controlled with an optional flag --test-sve. The whole thing is conditionally compiled when SVE support is in the sigcontext headers. Signed-off-by: Alex Bennée Reviewed-by: Richard Henderson --- v2 - support EXTRA_MAGIC contexts v3 - handle conditional bits - include in reginfo.h - move from helper function to main init function - (void *) cast for memcpy - additional ifdef SVE_MAGIC stuff --- risu_reginfo_aarch64.c | 107 ++++++++++++++++++++++++++++++++++++----- risu_reginfo_aarch64.h | 16 ++++++ 2 files changed, 110 insertions(+), 13 deletions(-) diff --git a/risu_reginfo_aarch64.c b/risu_reginfo_aarch64.c index 3ccaf0e..79db5dd 100644 --- a/risu_reginfo_aarch64.c +++ b/risu_reginfo_aarch64.c @@ -16,13 +16,26 @@ #include /* for FPSIMD_MAGIC */ #include #include -#include +#include #include "risu.h" #include "risu_reginfo_aarch64.h" +#ifndef SVE_MAGIC const struct option * const arch_long_opts; const char * const arch_extra_help; +#else + +/* Should we test SVE register state */ +static int test_sve; +static const struct option extra_opts[] = { + {"test-sve", no_argument, &test_sve, 1}, + {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"; +#endif void process_arch_opt(int opt, const char *arg) { @@ -31,8 +44,12 @@ void process_arch_opt(int opt, const char *arg) const int reginfo_size(void) { - const int size = offsetof(struct reginfo, simd.end); - assert(sizeof(struct reginfo)==size); + int size = offsetof(struct reginfo, simd.end); +#ifdef SVE_MAGIC + if (test_sve) { + size = offsetof(struct reginfo, sve.end); + } +#endif return size; } @@ -40,8 +57,12 @@ const int reginfo_size(void) void reginfo_init(struct reginfo *ri, ucontext_t *uc) { int i; - struct _aarch64_ctx *ctx; - struct fpsimd_context *fp; + struct _aarch64_ctx *ctx, *extra = NULL; + struct fpsimd_context *fp = NULL; +#ifdef SVE_MAGIC + struct sve_context *sve = NULL; +#endif + /* necessary to be able to compare with memcmp later */ memset(ri, 0, sizeof(*ri)); @@ -57,21 +78,81 @@ void reginfo_init(struct reginfo *ri, ucontext_t *uc) ri->faulting_insn = *((uint32_t *) uc->uc_mcontext.pc); ctx = (struct _aarch64_ctx *) &uc->uc_mcontext.__reserved[0]; - - while (ctx->magic != FPSIMD_MAGIC && ctx->size != 0) { - ctx += (ctx->size + sizeof(*ctx) - 1) / sizeof(*ctx); + while (ctx) { + switch (ctx->magic) { + case FPSIMD_MAGIC: + fp = (void *)ctx; + break; +#ifdef SVE_MAGIC + case SVE_MAGIC: + sve = (void *)ctx; + break; + case EXTRA_MAGIC: + extra = (void *)((struct extra_context *)(ctx))->datap; + break; +#endif + case 0: + /* End of list. */ + ctx = extra; + extra = NULL; + continue; + default: + /* Unknown record -- skip it. */ + break; + } + ctx = (void *)ctx + ctx->size; } - if (ctx->magic != FPSIMD_MAGIC || ctx->size != sizeof(*fp)) { - fprintf(stderr, - "risu_reginfo_aarch64: failed to get FP/SIMD state\n"); + if (!fp || fp->head.size != sizeof(*fp)) { + fprintf(stderr, "risu_reginfo_aarch64: failed to get FP/SIMD state\n"); return; } - - fp = (struct fpsimd_context *) ctx; ri->fpsr = fp->fpsr; ri->fpcr = fp->fpcr; +#ifdef SVE_MAGIC + if (test_sve) { + int vq = sve_vq_from_vl(sve->vl); /* number of quads for whole vl */ + + if (sve == NULL) { + fprintf(stderr, "risu_reginfo_aarch64: failed to get SVE state\n"); + return; + } + + ri->sve.vl = sve->vl; + + if (sve->head.size < SVE_SIG_CONTEXT_SIZE(vq)) { + if (sve->head.size == sizeof(*sve)) { + /* SVE state is empty -- not an error. */ + } else { + fprintf(stderr, "risu_reginfo_aarch64: " + "failed to get complete SVE state\n"); + } + return; + } + + /* Copy ZREG's one at a time */ + for (i = 0; i < SVE_NUM_ZREGS; i++) { + memcpy(&ri->sve.zregs[i], + (void *)sve + SVE_SIG_ZREG_OFFSET(vq, i), + SVE_SIG_ZREG_SIZE(vq)); + } + + /* Copy PREG's one at a time */ + for (i = 0; i < SVE_NUM_PREGS; i++) { + memcpy(&ri->sve.pregs[i], + (void *)sve + SVE_SIG_PREG_OFFSET(vq, i), + SVE_SIG_PREG_SIZE(vq)); + } + + /* Finally the FFR */ + memcpy(&ri->sve.ffr,(void *)sve + SVE_SIG_FFR_OFFSET(vq), + SVE_SIG_FFR_SIZE(vq)); + + return; + } +#endif + for (i = 0; i < 32; i++) { ri->simd.vregs[i] = fp->vregs[i]; } diff --git a/risu_reginfo_aarch64.h b/risu_reginfo_aarch64.h index ef97622..b3701b3 100644 --- a/risu_reginfo_aarch64.h +++ b/risu_reginfo_aarch64.h @@ -13,11 +13,24 @@ #ifndef RISU_REGINFO_AARCH64_H #define RISU_REGINFO_AARCH64_H +#include /* for SVE_MAGIC */ + struct simd_reginfo { __uint128_t vregs[32]; char end[0]; }; +#ifdef SVE_MAGIC +struct sve_reginfo { + /* SVE */ + uint16_t vl; /* current VL */ + __uint128_t zregs[SVE_NUM_ZREGS][SVE_VQ_MAX]; + uint16_t pregs[SVE_NUM_PREGS][SVE_VQ_MAX]; + uint16_t ffr[SVE_VQ_MAX]; + char end[0]; +}; +#endif + struct reginfo { uint64_t fault_address; uint64_t regs[31]; @@ -32,6 +45,9 @@ struct reginfo { union { struct simd_reginfo simd; +#ifdef SVE_MAGIC + struct sve_reginfo sve; +#endif }; };