From patchwork Mon Jun 19 10:46:51 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: 105827 Delivered-To: patch@linaro.org Received: by 10.140.91.2 with SMTP id y2csp812065qgd; Mon, 19 Jun 2017 03:56:10 -0700 (PDT) X-Received: by 10.31.190.145 with SMTP id o139mr11045823vkf.35.1497869770377; Mon, 19 Jun 2017 03:56:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1497869770; cv=none; d=google.com; s=arc-20160816; b=Oe/uN6ghBGpTay1umh4NEboqO72LjAeSJr5xjZWlwpU9HuCz224/z0qvnyzPmmkEQV gAfB7di8vYELxAMMVHu6wn6gD1fdneMf05WWSq4BhLuBLsBXxGryvSfs1zgeutbWrHtG wDlaASB/UaBUxg8EYTK68FB4ybH4WbvhAqh50pSI6XyH9YyFwgCi9RVJqoX/SgDVsp7o m2QkoBhx/E0i7xDLM2RPZIg8SqnDTiU1fTuwHfC3lDL1h6+vKlqsMsATK404Ki8vWhoA cfPl+FF2MbxNV4UlakEFiPvrzYepPlpU+vGzm8QGTJEGCX6MS0V+mklAbqPR7ZS1bEJv 5x0g== 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=DN2lth0mZkE3XcXUeN/mzEOFF3RlDTUzep1rbK4HGDA=; b=exF6hVblcUK7L1IZQbD2Cue3S3hHF0i73KgQ/mwNM2NyZRtFmfgBP/RWaR1E88ZCVe /qGwiO0uDlvxXnzgZOMEWCq9Y8ynUUPjYfZAFhyJgN+/0fBLShFcrMV5RHOUW9viP65I aXlOb7UBhVsmkTKbNEI6NN4GiSrGbD+hlQLfVo5tbTMjo/P1vOYT4i24PkzWaRIrDHy/ nE8tQlJbJJYc+LZ1KkogvApzWed6bNEKczAPpHCLXrIirGpMpgMjAj2r9Zo4o4zFXslE 3uFlfiLNmcNRMMPzdVnyQk/7bjbvAyStB5V/Ny+KbRxElgJKwixGCnZBxrtqWl0oAldW f3Qg== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.b=eToI4tm7; 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 e33si5061547uah.276.2017.06.19.03.56.10 for (version=TLS1 cipher=AES128-SHA bits=128/128); Mon, 19 Jun 2017 03:56:10 -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=eToI4tm7; 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]:41690 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dMuLp-0007G5-Su for patch@linaro.org; Mon, 19 Jun 2017 06:56:09 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40768) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dMuCW-0007Pb-RB for qemu-devel@nongnu.org; Mon, 19 Jun 2017 06:46:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dMuCV-0004wS-I6 for qemu-devel@nongnu.org; Mon, 19 Jun 2017 06:46:32 -0400 Received: from mail-wm0-x236.google.com ([2a00:1450:400c:c09::236]:35191) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dMuCV-0004vk-9F for qemu-devel@nongnu.org; Mon, 19 Jun 2017 06:46:31 -0400 Received: by mail-wm0-x236.google.com with SMTP id x70so75453819wme.0 for ; Mon, 19 Jun 2017 03:46:31 -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=DN2lth0mZkE3XcXUeN/mzEOFF3RlDTUzep1rbK4HGDA=; b=eToI4tm7bih3MEtg5qoiVz4hKrkYaRkrvTvebILv9R1JC4gIRU6rBYIlNGUMw1N22R D3HGs01dgcLs4+kNG/uo0U2IETiv1cB0Eyw2+avxDGFGoLvJvw/+u+VWZf7ufzhKn1ji uaGK0w9vtPm14U5wN3o4Xu/6snsr1avSKi/0g= 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=DN2lth0mZkE3XcXUeN/mzEOFF3RlDTUzep1rbK4HGDA=; b=qoBhXWyMLZ5wb6iwuAw1uGypIumxig0CEM8eo48qnVfmR2k9lEjZBaqV9n3vXcNpxy OlkeahVfj6zcMT7jQywWrzFB57b87I7Bua6qK4vBWS6nOyHzz+QL6l5em4x764bJVO7+ jiCXzuaROtlnLz7+SO8ondxUJ3bfMgepBzX2teB6dAxPIbGyY/3Wzb6IAjpzbQ1Q6tbK Gf4/+UHZR90x7+6saipfMyUD9Vp/shiWcYlwm/LosGmz0FpEg6x52Bot5TRhesqQ487w RVaKxppHjHNORF8JfHc86ODc2vUE+2QTJEP29Tu+v1yfFCo4g0NYVFrrCLWnK2oZ11hX 58Gg== X-Gm-Message-State: AKS2vOz4GtfFql5XdwGhgcHz6Q4DWV9SXkcCLi+qosWMHQiGIisaOwzx EeUJUil3dgxzgchy X-Received: by 10.28.230.153 with SMTP id e25mr13888679wmi.41.1497869190033; Mon, 19 Jun 2017 03:46:30 -0700 (PDT) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id m63sm6976749wma.18.2017.06.19.03.46.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 19 Jun 2017 03:46:23 -0700 (PDT) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id 72A333E0BE6; Mon, 19 Jun 2017 11:47:00 +0100 (BST) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Mon, 19 Jun 2017 11:46:51 +0100 Message-Id: <20170619104655.31104-10-alex.bennee@linaro.org> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170619104655.31104-1-alex.bennee@linaro.org> References: <20170619104655.31104-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:c09::236 Subject: [Qemu-devel] [RISU PATCH v5 09/13] 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 --- 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 Reviewed-by: Peter Maydell 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(); } }