From patchwork Fri May 22 02:34:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 187115 Delivered-To: patch@linaro.org Received: by 2002:a92:5b0a:0:0:0:0:0 with SMTP id p10csp2102546ilb; Thu, 21 May 2020 19:35:44 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzDeugxhDJCoNXN1dTNVc0dLa3wPtBsx7CiPXTGX7WCbHE8ezvnJLaHJdkJHrT+vtUVEeWr X-Received: by 2002:a25:845:: with SMTP id 66mr19658444ybi.7.1590114944200; Thu, 21 May 2020 19:35:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1590114944; cv=none; d=google.com; s=arc-20160816; b=Ls2s4uGBbGGidIhn+gLahxocnxGnOfo78RR/yKQSfGbaiTRcL9d6BrUi3M9/pf9pFb Amzw6m1whQRwtUcnt28Oc+lYngk3vNvIT5IcMVC+dz7hUVNTz9MNCFhytsF0gMOYRZDy lNnMj79Bs9/JdKYJQMv1tt9Ggi2FrwH/pG1EZaChu7Aeys+5Mw6F1aWO/7kBGlWzM42M P8Nl2qe2Jryhhoye3tFBsbO084NwoTMgumsn6ftEl4mNfXNPg7IWJxOj7GghyyuZbQTH LtheHV4euh2JAKLuciB32HQL1vupQpcLNrNmAH/7YltH/cAcDspQeLOmeGk2lqrqowQe 3ikg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=TXAASNAhxxCZnrmhR/019xFA1WSxX4Hf5mCh0xMRPmU=; b=zQxk2QavBLHdify8FdfB6wIE9cvRqFslz8jNFrWcrnm3/GSykOcPMC7q6c/V1DJkor MImEqKeZ6nCgnlivUOIR4vC1AsJAvknlkiAX2T6cDYGbODD2MPDypdqXSvKOull4MeHd KS/AOYnrtqQoAZo2dj1GCEE/iGLry2h7XRCZB6qXjLyolYeg3sKpMnllMA5sUsQrR3U1 xVAJWtoQtk+REYPcOq8ljFLtnbb17uLeI7PpYwjV0yJeEJw+nSzS7OR2g/s4/71r3451 kjnbVwf4T0m9Q8mTmdyloIewOhougZhSm6Hs5hl24k2nv7hdXGfUo+QjtY7AsB9vapCi tl2g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=AUtufOGf; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id q7si6516728ybk.391.2020.05.21.19.35.44 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Thu, 21 May 2020 19:35:44 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=AUtufOGf; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:44418 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jbxXD-0002kz-LF for patch@linaro.org; Thu, 21 May 2020 22:35:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48248) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jbxWZ-0002el-Sl for qemu-devel@nongnu.org; Thu, 21 May 2020 22:35:03 -0400 Received: from mail-pg1-x541.google.com ([2607:f8b0:4864:20::541]:40785) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jbxWX-00057X-Dg for qemu-devel@nongnu.org; Thu, 21 May 2020 22:35:02 -0400 Received: by mail-pg1-x541.google.com with SMTP id j21so4275588pgb.7 for ; Thu, 21 May 2020 19:35:00 -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=TXAASNAhxxCZnrmhR/019xFA1WSxX4Hf5mCh0xMRPmU=; b=AUtufOGfzGkjlfkqqxb794wZpat78KRsybJft61LmYhClncza5WibhmGMSUo0t5KF2 0fk1SW80/fxljjgayPa757/OA0kpTohm2lcfsuZrVEI3EtCGHkuLU41Z06jX1ITQDEfj Ir05GmGj7sdNcFzLu006gwS9tVN/Oa7fHj4sfiM1yVQW9CO0zSt8jxgMC0Is8sxfmjPw iVYt+Hjo/rwmUwf5IRXTjEsrYrUfiEQnxgjP2V+Ip7quBTke6gVPsuC4RNNVRcX1bTz3 w/cEQnHAaWd+D0UYvoPET5wzT/XvNiJ48HdEvGeqTqDQl9DEDnTB/DKLjYzidLa3qF0/ leRw== 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=TXAASNAhxxCZnrmhR/019xFA1WSxX4Hf5mCh0xMRPmU=; b=keaUoLu6tJ7zK+eUKekKqvyzHVzBrXBIPCYoZCskn3C5+qtWYo1j/ergASjjDeolY+ fpw2NnMLLrj82H3It9+Nx4BXbIWZbTjE7ZQ1Xdqjl0pJdrKpbIGGB7xv4GHZzhGheKq1 muiwbxaQU61eni/TU57aS+lg0nRwu0Pb+qoLdznHD80NCaEPhRvGnnl/QeQngHmzzEjU MaqlgJ/7iwXFuhCxtS9dC94MUz0IyAbRTra31jjpgRB/m284GOKq6fQwF6FmAqQ0kr60 i+9+YctJ78k3Je7aBChq5lhxWRRThHQ+LZq71P3HRJ7DIKoRKL4AS9RLdMrtNYxwmt37 7SRw== X-Gm-Message-State: AOAM533JxcRkMCqnlXRHIxV2OtCnxWcC4lhkVvU72pEwf4ArraOjCZIV lzYkW5/22LVtowwdVvh0BtIYFvYLnxk= X-Received: by 2002:a63:6e8a:: with SMTP id j132mr10248319pgc.301.1590114899535; Thu, 21 May 2020 19:34:59 -0700 (PDT) Received: from localhost.localdomain (174-21-143-238.tukw.qwest.net. [174.21.143.238]) by smtp.gmail.com with ESMTPSA id gt10sm5443755pjb.30.2020.05.21.19.34.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 May 2020 19:34:58 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH v3 14/25] Merge reginfo.c into risu.c Date: Thu, 21 May 2020 19:34:29 -0700 Message-Id: <20200522023440.26261-15-richard.henderson@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200522023440.26261-1-richard.henderson@linaro.org> References: <20200522023440.26261-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::541; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x541.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" The distinction between the two is artificial. Following patches will rearrange the functions involved to make it easier for dumping of the trace file. Signed-off-by: Richard Henderson Reviewed-by: Alex Bennée --- Makefile | 2 +- risu.h | 28 +--------- reginfo.c | 151 ------------------------------------------------------ risu.c | 129 ++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 126 insertions(+), 184 deletions(-) delete mode 100644 reginfo.c -- 2.20.1 diff --git a/Makefile b/Makefile index 6ab014a..ad7f879 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ CFLAGS ?= -g ALL_CFLAGS = -Wall -D_GNU_SOURCE -DARCH=$(ARCH) -U$(ARCH) $(BUILD_INC) $(CFLAGS) $(EXTRA_CFLAGS) PROG=risu -SRCS=risu.c comms.c reginfo.c risu_$(ARCH).c risu_reginfo_$(ARCH).c +SRCS=risu.c comms.c risu_$(ARCH).c risu_reginfo_$(ARCH).c HDRS=risu.h risu_reginfo_$(ARCH).h BINS=test_$(ARCH).bin diff --git a/risu.h b/risu.h index 77d6128..dd9fda5 100644 --- a/risu.h +++ b/risu.h @@ -35,7 +35,6 @@ void process_arch_opt(int opt, const char *arg); #include REGINFO_HEADER(ARCH) extern uintptr_t image_start_address; -extern void *memblock; /* Ops code under test can request from risu: */ typedef enum { @@ -83,34 +82,9 @@ void send_response_byte(int sock, int resp); /* Functions operating on reginfo */ -/* Function prototypes for read/write helper functions. */ -RisuResult write_buffer(void *ptr, size_t bytes); -RisuResult read_buffer(void *ptr, size_t bytes); -void respond(RisuResult response); - -/* - * Send the register information from the struct ucontext down the socket. - * NB: called from a signal handler. - */ -RisuResult send_register_info(void *uc); - -/* - * Read register info from the socket and compare it with that from the - * ucontext. - * NB: called from a signal handler. - */ -RisuResult recv_and_compare_register_info(void *uc); - -/* - * Print a useful report on the status of the last reg comparison - * done in recv_and_compare_register_info(). - */ -void report_mismatch_reg(void); - /* Interface provided by CPU-specific code: */ -/* Move the PC past this faulting insn by adjusting ucontext - */ +/* Move the PC past this faulting insn by adjusting ucontext. */ void advance_pc(void *uc); /* Set the parameter register in a ucontext_t to the specified value. diff --git a/reginfo.c b/reginfo.c deleted file mode 100644 index a007f16..0000000 --- a/reginfo.c +++ /dev/null @@ -1,151 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2017 Linaro Limited - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Peter Maydell (Linaro) - initial implementation - *****************************************************************************/ - -#include -#include -#include -#include "risu.h" - -static struct reginfo master_ri, apprentice_ri; -static uint8_t master_memblock[MEMBLOCKLEN]; - -RisuResult send_register_info(void *uc) -{ - struct reginfo ri; - trace_header_t header; - RisuResult res; - RisuOp op; - - reginfo_init(&ri, uc); - op = get_risuop(&ri); - - /* Write a header with PC/op to keep in sync */ - header.pc = get_pc(&ri); - header.risu_op = op; - res = write_buffer(&header, sizeof(header)); - if (res != RES_OK) { - return res; - } - - switch (op) { - case OP_COMPARE: - case OP_TESTEND: - case OP_SIGILL: - /* - * Do a simple register compare on (a) explicit request - * (b) end of test (c) a non-risuop UNDEF - */ - res = write_buffer(&ri, reginfo_size()); - /* For OP_TEST_END, force exit. */ - if (res == RES_OK && op == OP_TESTEND) { - res = RES_END; - } - break; - case OP_SETMEMBLOCK: - memblock = (void *)(uintptr_t)get_reginfo_paramreg(&ri); - break; - case OP_GETMEMBLOCK: - set_ucontext_paramreg(uc, - get_reginfo_paramreg(&ri) + (uintptr_t)memblock); - break; - case OP_COMPAREMEM: - return write_buffer(memblock, MEMBLOCKLEN); - default: - abort(); - } - return res; -} - -/* Read register info from the socket and compare it with that from the - * ucontext. Return 0 for match, 1 for end-of-test, 2 for mismatch. - * NB: called from a signal handler. - * - * We don't have any kind of identifying info in the incoming data - * that says whether it is register or memory data, so if the two - * sides get out of sync then we will fail obscurely. - */ -RisuResult recv_and_compare_register_info(void *uc) -{ - RisuResult res; - trace_header_t header; - RisuOp op; - - reginfo_init(&apprentice_ri, uc); - op = get_risuop(&apprentice_ri); - - res = read_buffer(&header, sizeof(header)); - if (res != RES_OK) { - return res; - } - - if (header.risu_op != op) { - /* We are out of sync. Tell master to exit. */ - respond(RES_END); - return RES_BAD_IO; - } - - /* send OK for the header */ - respond(RES_OK); - - switch (op) { - case OP_COMPARE: - case OP_TESTEND: - case OP_SIGILL: - /* Do a simple register compare on (a) explicit request - * (b) end of test (c) a non-risuop UNDEF - */ - res = read_buffer(&master_ri, reginfo_size()); - if (res != RES_OK) { - /* fail */ - } else if (!reginfo_is_eq(&master_ri, &apprentice_ri)) { - /* register mismatch */ - res = RES_MISMATCH_REG; - } else if (op == OP_TESTEND) { - res = RES_END; - } - respond(res == RES_OK ? RES_OK : RES_END); - break; - case OP_SETMEMBLOCK: - memblock = (void *)(uintptr_t)get_reginfo_paramreg(&apprentice_ri); - break; - case OP_GETMEMBLOCK: - set_ucontext_paramreg(uc, get_reginfo_paramreg(&apprentice_ri) + - (uintptr_t)memblock); - break; - case OP_COMPAREMEM: - res = read_buffer(master_memblock, MEMBLOCKLEN); - if (res != RES_OK) { - /* fail */ - } else if (memcmp(memblock, master_memblock, MEMBLOCKLEN) != 0) { - /* memory mismatch */ - res = RES_MISMATCH_MEM; - } - respond(res == RES_OK ? RES_OK : RES_END); - break; - default: - abort(); - } - - return res; -} - -/* - * Print a useful report on the status of the last reg comparison - * done in recv_and_compare_register_info(). - */ -void report_mismatch_reg(void) -{ - fprintf(stderr, "master reginfo:\n"); - reginfo_dump(&master_ri, stderr); - fprintf(stderr, "apprentice reginfo:\n"); - reginfo_dump(&apprentice_ri, stderr); - reginfo_dump_mismatch(&master_ri, &apprentice_ri, stderr); -} diff --git a/risu.c b/risu.c index d6c2deb..a0e20d5 100644 --- a/risu.c +++ b/risu.c @@ -28,7 +28,10 @@ #include "config.h" #include "risu.h" -void *memblock; +static void *memblock; +static struct reginfo master_ri, apprentice_ri; +static uint8_t master_memblock[MEMBLOCKLEN]; + static int comm_fd; static bool trace; @@ -48,7 +51,7 @@ static sigjmp_buf jmpbuf; /* I/O functions */ -RisuResult read_buffer(void *ptr, size_t bytes) +static RisuResult read_buffer(void *ptr, size_t bytes) { size_t res; @@ -69,7 +72,7 @@ RisuResult read_buffer(void *ptr, size_t bytes) return res == bytes ? RES_OK : RES_BAD_IO; } -RisuResult write_buffer(void *ptr, size_t bytes) +static RisuResult write_buffer(void *ptr, size_t bytes) { size_t res; @@ -90,13 +93,60 @@ RisuResult write_buffer(void *ptr, size_t bytes) return res == bytes ? RES_OK : RES_BAD_IO; } -void respond(RisuResult r) +static void respond(RisuResult r) { if (!trace) { send_response_byte(comm_fd, r); } } +static RisuResult send_register_info(void *uc) +{ + struct reginfo ri; + trace_header_t header; + RisuResult res; + RisuOp op; + + reginfo_init(&ri, uc); + op = get_risuop(&ri); + + /* Write a header with PC/op to keep in sync */ + header.pc = get_pc(&ri); + header.risu_op = op; + res = write_buffer(&header, sizeof(header)); + if (res != RES_OK) { + return res; + } + + switch (op) { + case OP_COMPARE: + case OP_TESTEND: + case OP_SIGILL: + /* + * Do a simple register compare on (a) explicit request + * (b) end of test (c) a non-risuop UNDEF + */ + res = write_buffer(&ri, reginfo_size()); + /* For OP_TEST_END, force exit. */ + if (res == RES_OK && op == OP_TESTEND) { + res = RES_END; + } + break; + case OP_SETMEMBLOCK: + memblock = (void *)(uintptr_t)get_reginfo_paramreg(&ri); + break; + case OP_GETMEMBLOCK: + set_ucontext_paramreg(uc, + get_reginfo_paramreg(&ri) + (uintptr_t)memblock); + break; + case OP_COMPAREMEM: + return write_buffer(memblock, MEMBLOCKLEN); + default: + abort(); + } + return res; +} + static void master_sigill(int sig, siginfo_t *si, void *uc) { RisuResult r; @@ -110,6 +160,71 @@ static void master_sigill(int sig, siginfo_t *si, void *uc) } } +static RisuResult recv_and_compare_register_info(void *uc) +{ + RisuResult res; + trace_header_t header; + RisuOp op; + + reginfo_init(&apprentice_ri, uc); + op = get_risuop(&apprentice_ri); + + res = read_buffer(&header, sizeof(header)); + if (res != RES_OK) { + return res; + } + + if (header.risu_op != op) { + /* We are out of sync. Tell master to exit. */ + respond(RES_END); + return RES_BAD_IO; + } + + /* send OK for the header */ + respond(RES_OK); + + switch (op) { + case OP_COMPARE: + case OP_TESTEND: + case OP_SIGILL: + /* Do a simple register compare on (a) explicit request + * (b) end of test (c) a non-risuop UNDEF + */ + res = read_buffer(&master_ri, reginfo_size()); + if (res != RES_OK) { + /* fail */ + } else if (!reginfo_is_eq(&master_ri, &apprentice_ri)) { + /* register mismatch */ + res = RES_MISMATCH_REG; + } else if (op == OP_TESTEND) { + res = RES_END; + } + respond(res == RES_OK ? RES_OK : RES_END); + break; + case OP_SETMEMBLOCK: + memblock = (void *)(uintptr_t)get_reginfo_paramreg(&apprentice_ri); + break; + case OP_GETMEMBLOCK: + set_ucontext_paramreg(uc, get_reginfo_paramreg(&apprentice_ri) + + (uintptr_t)memblock); + break; + case OP_COMPAREMEM: + res = read_buffer(master_memblock, MEMBLOCKLEN); + if (res != RES_OK) { + /* fail */ + } else if (memcmp(memblock, master_memblock, MEMBLOCKLEN) != 0) { + /* memory mismatch */ + res = RES_MISMATCH_MEM; + } + respond(res == RES_OK ? RES_OK : RES_END); + break; + default: + abort(); + } + + return res; +} + static void apprentice_sigill(int sig, siginfo_t *si, void *uc) { RisuResult r; @@ -226,7 +341,11 @@ static int apprentice(void) case RES_MISMATCH_REG: fprintf(stderr, "mismatch reg after %zd checkpoints\n", signal_count); - report_mismatch_reg(); + fprintf(stderr, "master reginfo:\n"); + reginfo_dump(&master_ri, stderr); + fprintf(stderr, "apprentice reginfo:\n"); + reginfo_dump(&apprentice_ri, stderr); + reginfo_dump_mismatch(&master_ri, &apprentice_ri, stderr); return EXIT_FAILURE; case RES_MISMATCH_MEM: