From patchwork Wed Jun 21 15:42:40 2017 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: 106104 Delivered-To: patch@linaro.org Received: by 10.140.91.2 with SMTP id y2csp1995541qgd; Wed, 21 Jun 2017 08:45:12 -0700 (PDT) X-Received: by 10.237.46.166 with SMTP id k35mr42109349qtd.115.1498059912831; Wed, 21 Jun 2017 08:45:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1498059912; cv=none; d=google.com; s=arc-20160816; b=WsLtBcjVSCV1RgEftVJZgqOrMpDLLm1J2WVwy4DztSe3J6O+3rGZ/GQ/Qky99O7ylJ 3Ln6Z8id+QcN+uPQjAT08Cnu6cd5EcnS57qCv8y/8pMFuHU1l59s4sixTygexH7iUoej TRuDfhN7SK0Jo2MewvuCsbj+tnBQaz+kCIouNOLGrzfuIDV4C0DX2joPq1n2ayiHzlV9 bz/4xuYXDku2i8ZedsUpd3g7C7LGFd2cfuE7aEiH9JsYqZEedFYUwDWdk0fEmMWIdi09 fb2xP8a+g6N2o8THIDtEcl1hM9MghsSSGjMjVeYH1NRk+To15waBe73GdDTnNt5zc8D5 Jb/w== 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:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:arc-authentication-results; bh=LXdGdlUX1cBxxHXOsPXGf1VgqdcmxZFRDkJk/YNCJt8=; b=hjoac+SosSBlC73S1wBzoQNWEKr7BNcADrGLdr7clcOjdSHQXWjYHX8FqlroXrQwtG hwku2Uw7yEW0AC+FsMy1BU8sAoC4pzpTJyl1FBwRUSqObdftEgcRN1irECRl48aDL4MF ZPFG5o9RKUmM2mm+A1yu/rFdF0bhmfGX3KcXDDBXV3R8WHj0mcYiONFTFJERX5I3ALye 5sD2y5PKlMJEMJkKvN/QClY0Q2eZikwh0oSSLGlFNVThxl0lonmgBKB056rcS8Q1kcS6 tCG9D9nXjn1fDGVUFI2Mso+CKsud3oLgEIDT9HihM8cC2XUZ5Sef+fId0883YTTnT7h6 OVxw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.b=V4JPoZVQ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id v5si14482356qtd.336.2017.06.21.08.45.12 for (version=TLS1 cipher=AES128-SHA bits=128/128); Wed, 21 Jun 2017 08:45:12 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.b=V4JPoZVQ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:54752 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dNhoc-0008Sn-5Y for patch@linaro.org; Wed, 21 Jun 2017 11:45:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52482) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dNhlo-0006EY-D1 for qemu-devel@nongnu.org; Wed, 21 Jun 2017 11:42:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dNhln-0002rC-5o for qemu-devel@nongnu.org; Wed, 21 Jun 2017 11:42:16 -0400 Received: from mail-wr0-x232.google.com ([2a00:1450:400c:c0c::232]:36651) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dNhlm-0002qd-SU for qemu-devel@nongnu.org; Wed, 21 Jun 2017 11:42:15 -0400 Received: by mail-wr0-x232.google.com with SMTP id c11so84695943wrc.3 for ; Wed, 21 Jun 2017 08:42:14 -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=LXdGdlUX1cBxxHXOsPXGf1VgqdcmxZFRDkJk/YNCJt8=; b=V4JPoZVQLNb8sUNqntgA/ke86ZRGnW9K1arFE2ZSfku8KOtVH6j/Y4I/9eG0Oyh0PE nIm/2Wb8YyxElnJpd2+EXB+A3UU4jcfQv7Qu6qX3EX5esU6aNe2aDAN7p5QQlSLBxFiC 0EUYYmdIaX6cZCyETp1nV/h47bR14wuQ9yfTo= 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=LXdGdlUX1cBxxHXOsPXGf1VgqdcmxZFRDkJk/YNCJt8=; b=N+hWNCx6uPRQp1Dflv+ZSjGRe0p3Ke1ZkIRz7kkT5oAJYlsG9dUMnd89UPWEvV9T15 14PWP/pupjPQcm+XRWsZLmxbB+HFqPcJOSRLg9TZ96IQfFjirr7rAVc0A9bpHFu3IKbM CMaPtvgrtKegmfChB4TIoXOTnNO0Puey3Fy68q2GQEK4VPnsnkv6Pq9Gp57CxjsJaRbp W60w2KGjpwQOZWlS9spIK9fgtkhYBKYNfokB2gaPc9BVJxIjI5KOeVw2L2batg9Ey9av KOrpbs/RDI10dI1HroNdpXGGkLbil42ImmxgXG6AVhMYC0+930QHltfIUQ0jtFsKKSzU DbYQ== X-Gm-Message-State: AKS2vOwdxMApzyb1N93N9dZpxBBqgDcvgOtGRi7GJMXWspWOgvoEOBxP e+OYt2qqClKFLuGI X-Received: by 10.28.131.142 with SMTP id f136mr3068246wmd.101.1498059733690; Wed, 21 Jun 2017 08:42:13 -0700 (PDT) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id u4sm14117767wmf.7.2017.06.21.08.42.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Jun 2017 08:42:12 -0700 (PDT) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 68DE33E0F87; Wed, 21 Jun 2017 16:42:51 +0100 (BST) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Wed, 21 Jun 2017 16:42:40 +0100 Message-Id: <20170621154244.28309-7-alex.bennee@linaro.org> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170621154244.28309-1-alex.bennee@linaro.org> References: <20170621154244.28309-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::232 Subject: [Qemu-devel] [RISU PATCH v6 06/10] risu: add simple trace and replay support 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-devel@nongnu.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" This adds a very dumb and easily breakable trace and replay support. In --master mode the various risu ops trigger a write of register/memory state into a binary file which can be played back to an apprentice. Currently there is no validation of the image source so feeding the wrong image will fail straight away. The trace files will get very big for any appreciable sized test file and this will be addressed in later patches. Signed-off-by: Alex Bennée Reviewed-by: Peter Maydell --- v5 - re-base without formatting fixes - unify socket/file descriptors - count number of signals/checkpoint - all output from sigjmp (not in signhandlers) v4 - fix formatting mess - abort() instead of reporting de-sync - don't fake return for compiler v3 - fix options parsing - re-factored so no need for copy & paste v2 - moved read/write functions into main risu.c - cleaned up formatting - report more in apprentice --trace mode --- risu.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 93 insertions(+), 19 deletions(-) -- 2.13.0 diff --git a/risu.c b/risu.c index 88e586c..93c274b 100644 --- a/risu.c +++ b/risu.c @@ -30,7 +30,9 @@ void *memblock; -int apprentice_socket, master_socket; +int apprentice_fd, master_fd; +int trace; +size_t signal_count; sigjmp_buf jmpbuf; @@ -41,24 +43,60 @@ int test_fp_exc; int read_sock(void *ptr, size_t bytes) { - return recv_data_pkt(master_socket, ptr, bytes); + return recv_data_pkt(master_fd, ptr, bytes); +} + +int write_trace(void *ptr, size_t bytes) +{ + size_t res = write(master_fd, ptr, bytes); + return (res == bytes) ? 0 : 1; } void respond_sock(int r) { - send_response_byte(master_socket, r); + send_response_byte(master_fd, r); } /* Apprentice function */ int write_sock(void *ptr, size_t bytes) { - return send_data_pkt(apprentice_socket, ptr, bytes); + return send_data_pkt(apprentice_fd, ptr, bytes); +} + +int read_trace(void *ptr, size_t bytes) +{ + size_t res = read(apprentice_fd, ptr, bytes); + return (res == bytes) ? 0 : 1; +} + +void respond_trace(int r) +{ + switch (r) { + case 0: /* test ok */ + case 1: /* end of test */ + break; + default: + /* mismatch - if tracing we need to report, otherwise barf */ + if (!trace) { + abort(); + } + break; + } } void master_sigill(int sig, siginfo_t *si, void *uc) { - switch (recv_and_compare_register_info(read_sock, respond_sock, uc)) { + int r; + signal_count++; + + if (trace) { + r = send_register_info(write_trace, uc); + } else { + r = recv_and_compare_register_info(read_sock, respond_sock, uc); + } + + switch (r) { case 0: /* match OK */ advance_pc(uc); @@ -71,7 +109,16 @@ void master_sigill(int sig, siginfo_t *si, void *uc) void apprentice_sigill(int sig, siginfo_t *si, void *uc) { - switch (send_register_info(write_sock, uc)) { + int r; + signal_count++; + + if (trace) { + r = recv_and_compare_register_info(read_trace, respond_trace, uc); + } else { + r = send_register_info(write_sock, uc); + } + + switch (r) { case 0: /* match OK */ advance_pc(uc); @@ -81,6 +128,9 @@ void apprentice_sigill(int sig, siginfo_t *si, void *uc) exit(0); default: /* mismatch */ + if (trace) { + siglongjmp(jmpbuf, 1); + } exit(1); } } @@ -136,12 +186,17 @@ void load_image(const char *imgfile) image_start_address = (uintptr_t) addr; } -int master(int sock) +int master(void) { if (sigsetjmp(jmpbuf, 1)) { - return report_match_status(); + close(master_fd); + if (trace) { + fprintf(stderr, "trace complete after %zd checkpoints\n", signal_count); + return 0; + } else { + return report_match_status(); + } } - master_socket = sock; set_sigill_handler(&master_sigill); fprintf(stderr, "starting master image at 0x%"PRIxPTR"\n", image_start_address); @@ -151,9 +206,13 @@ int master(int sock) exit(1); } -int apprentice(int sock) +int apprentice(void) { - apprentice_socket = sock; + if (sigsetjmp(jmpbuf, 1)) { + close(apprentice_fd); + fprintf(stderr, "finished early after %zd checkpoints\n", signal_count); + return report_match_status(); + } set_sigill_handler(&apprentice_sigill); fprintf(stderr, "starting apprentice image at 0x%"PRIxPTR"\n", image_start_address); @@ -175,6 +234,7 @@ void usage(void) fprintf(stderr, "between master and apprentice risu processes.\n\n"); fprintf(stderr, "Options:\n"); fprintf(stderr, " --master Be the master (server)\n"); + fprintf(stderr, " -t, --trace=FILE Record/playback trace file\n"); fprintf(stderr, " -h, --host=HOST Specify master host machine (apprentice only)" "\n"); @@ -189,7 +249,7 @@ int main(int argc, char **argv) uint16_t port = 9191; char *hostname = "localhost"; char *imgfile; - int sock; + char *trace_fn = NULL; /* TODO clean this up later */ @@ -203,7 +263,7 @@ int main(int argc, char **argv) {0, 0, 0, 0} }; int optidx = 0; - int c = getopt_long(argc, argv, "h:p:", longopts, &optidx); + int c = getopt_long(argc, argv, "h:p:t:", longopts, &optidx); if (c == -1) { break; } @@ -214,6 +274,12 @@ int main(int argc, char **argv) /* flag set by getopt_long, do nothing */ break; } + case 't': + { + trace_fn = optarg; + trace = 1; + break; + } case 'h': { hostname = optarg; @@ -245,12 +311,20 @@ int main(int argc, char **argv) load_image(imgfile); if (ismaster) { - fprintf(stderr, "master port %d\n", port); - sock = master_connect(port); - return master(sock); + if (trace) { + master_fd = open(trace_fn, O_WRONLY|O_CREAT, S_IRWXU); + } else { + fprintf(stderr, "master port %d\n", port); + master_fd = master_connect(port); + } + return master(); } else { - fprintf(stderr, "apprentice host %s port %d\n", hostname, port); - sock = apprentice_connect(hostname, port); - return apprentice(sock); + if (trace) { + apprentice_fd = open(trace_fn, O_RDONLY); + } else { + fprintf(stderr, "apprentice host %s port %d\n", hostname, port); + apprentice_fd = apprentice_connect(hostname, port); + } + return apprentice(); } }