From patchwork Fri Dec 9 11:48:24 2016 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: 87455 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp268660qgi; Fri, 9 Dec 2016 04:05:53 -0800 (PST) X-Received: by 10.237.45.38 with SMTP id h35mr80550931qtd.9.1481285152974; Fri, 09 Dec 2016 04:05:52 -0800 (PST) Return-Path: Received: from lists.gnu.org (lists.gnu.org. [208.118.235.17]) by mx.google.com with ESMTPS id p4si19838657qtc.291.2016.12.09.04.05.52 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 09 Dec 2016 04:05:52 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:46115 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cFJw0-0002Y4-K4 for patch@linaro.org; Fri, 09 Dec 2016 07:05:52 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41852) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cFJgV-0007Uh-4B for qemu-devel@nongnu.org; Fri, 09 Dec 2016 06:49:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cFJgO-0007rG-UF for qemu-devel@nongnu.org; Fri, 09 Dec 2016 06:49:51 -0500 Received: from mail-wm0-f42.google.com ([74.125.82.42]:38673) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cFJgO-0007qJ-MG for qemu-devel@nongnu.org; Fri, 09 Dec 2016 06:49:44 -0500 Received: by mail-wm0-f42.google.com with SMTP id f82so23298571wmf.1 for ; Fri, 09 Dec 2016 03:49:44 -0800 (PST) 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=eaTKe7kI9O2b8+bx2x8EpogtHn1BQWpvYbDQ8v3lKNk=; b=LTsp7Mbf2Hf7sHkzxxnolj1F1uq0ZaZQxHjoptVjcusOkAihIoMb1oPHT4t3DKH4oZ sjW0x9Vp8IgDzyUeGO8xDVnosyT6vrtbn69eAXF+JiIx6Vl0SYEsOjDwqsDGrpbhWWZG L6ZCfBNSR81gTUNfaAtCwPNJnZxVSfTAfWUIk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eaTKe7kI9O2b8+bx2x8EpogtHn1BQWpvYbDQ8v3lKNk=; b=ThGRmA7o04BE7Ze0YTsKIPCZCQEpWBvlQvqiqdP7Y/lcis3sdB0BSpCcwAQEvlJ77Z B3zA+5VpuqETOtcRLoUIdtJFVZeYKqo9q5lr/WmMx0uwWcIRb22dglS3wXs7ptbQLkHB MkohMR7LebUdRjJXBcHfXc49Ooagrxo+UqKky6eam7wyMWps3b0nTJVpT9+yfM5G2GqC X2m+vnq+MIUQxCwpJokGYUAt0QG8dfc62utEuHxiLTILvakPudnR3tEXtPrs1Foc5bxu ZdNglQFrqtkSgn2izBqtgb3Q5hBn0Nz8QMAh47hTL+baz2B0sOk4KL0AfCMWsAs6iLWK K9HA== X-Gm-Message-State: AKaTC013PgvQlfub3Z9Eb7bAKY0H8G/o1M80KzLK4uEgJp6ib7GtBSLtfHT+WTZ7I2meourC X-Received: by 10.28.128.211 with SMTP id b202mr6806480wmd.7.1481284123456; Fri, 09 Dec 2016 03:48:43 -0800 (PST) Received: from zen.linaro.local ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id v2sm41937505wja.41.2016.12.09.03.48.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 09 Dec 2016 03:48:42 -0800 (PST) Received: from zen.linaroharston (localhost [127.0.0.1]) by zen.linaro.local (Postfix) with ESMTP id B397D3E06EF; Fri, 9 Dec 2016 11:48:34 +0000 (GMT) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: peter.maydell@linaro.org Date: Fri, 9 Dec 2016 11:48:24 +0000 Message-Id: <20161209114830.9158-5-alex.bennee@linaro.org> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20161209114830.9158-1-alex.bennee@linaro.org> References: <20161209114830.9158-1-alex.bennee@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 74.125.82.42 Subject: [Qemu-devel] [RISU PATCH v3 04/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=20Benn=C3=A9e?= , joserz@linux.vnet.ibm.com, 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 --- v2 - moved read/write functions into main risu.c - cleaned up formatting - report more in apprentice --trace mode v3 - fix options parsing - re-factored so no need for copy & paste --- risu.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++---------- risu_aarch64.c | 5 ++- risu_arm.c | 4 +-- 3 files changed, 93 insertions(+), 24 deletions(-) -- 2.11.0 diff --git a/risu.c b/risu.c index 22571cd..173dd3c 100644 --- a/risu.c +++ b/risu.c @@ -31,6 +31,7 @@ void *memblock = 0; int apprentice_socket, master_socket; +int trace_file = 0; sigjmp_buf jmpbuf; @@ -40,10 +41,12 @@ int test_fp_exc = 0; long executed_tests = 0; void report_test_status(void *pc) { - executed_tests += 1; - if (executed_tests % 100 == 0) { - fprintf(stderr,"Executed %ld test instructions (pc=%p)\r", - executed_tests, pc); + if (ismaster || trace_file) { + executed_tests += 1; + if (executed_tests % 100 == 0) { + fprintf(stderr,"Executed %ld test instructions (pc=%p)\r", + executed_tests, pc); + } } } @@ -54,6 +57,12 @@ int read_sock(void *ptr, size_t bytes) return recv_data_pkt(master_socket, ptr, bytes); } +int write_trace(void *ptr, size_t bytes) +{ + size_t res = write(trace_file, ptr, bytes); + return (res == bytes) ? 0 : 1; +} + void respond_sock(int r) { send_response_byte(master_socket, r); @@ -66,26 +75,62 @@ int write_sock(void *ptr, size_t bytes) return send_data_pkt(apprentice_socket, ptr, bytes); } +int read_trace(void *ptr, size_t bytes) +{ + size_t res = read(trace_file, 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: + fprintf(stderr,"%s: got response of %d\n", __func__, r); + break; + } +} + void master_sigill(int sig, siginfo_t *si, void *uc) { - switch (recv_and_compare_register_info(read_sock, respond_sock, uc)) + int r; + + if (trace_file) { + 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 */ + /* All OK */ advance_pc(uc); return; default: /* mismatch, or end of test */ siglongjmp(jmpbuf, 1); + /* never */ + return; } } void apprentice_sigill(int sig, siginfo_t *si, void *uc) { - switch (send_register_info(write_sock, uc)) + int r; + + if (trace_file) { + 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 */ + /* All OK */ advance_pc(uc); return; case 1: @@ -94,6 +139,9 @@ void apprentice_sigill(int sig, siginfo_t *si, void *uc) exit(0); default: /* mismatch */ + if (trace_file) { + report_match_status(); + } exit(1); } } @@ -155,7 +203,13 @@ int master(int sock) { if (sigsetjmp(jmpbuf, 1)) { - return report_match_status(); + if (trace_file) { + close(trace_file); + fprintf(stderr,"\nDone...\n"); + return 0; + } else { + return report_match_status(); + } } master_socket = sock; set_sigill_handler(&master_sigill); @@ -184,6 +238,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"); fprintf(stderr, " -p, --port=PORT Specify the port to connect to/listen on (default 9191)\n"); } @@ -194,6 +249,7 @@ int main(int argc, char **argv) uint16_t port = 9191; char *hostname = "localhost"; char *imgfile; + char *trace_fn = NULL; int sock; // TODO clean this up later @@ -204,13 +260,14 @@ int main(int argc, char **argv) { { "help", no_argument, 0, '?'}, { "master", no_argument, &ismaster, 1 }, + { "trace", required_argument, 0, 't' }, { "host", required_argument, 0, 'h' }, { "port", required_argument, 0, 'p' }, { "test-fp-exc", no_argument, &test_fp_exc, 1 }, { 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; @@ -223,6 +280,11 @@ int main(int argc, char **argv) /* flag set by getopt_long, do nothing */ break; } + case 't': + { + trace_fn = optarg; + break; + } case 'h': { hostname = optarg; @@ -253,18 +315,28 @@ 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_fn) + { + trace_file = open(trace_fn, O_WRONLY|O_CREAT, S_IRWXU); + } else { + fprintf(stderr, "master port %d\n", port); + sock = master_connect(port); + } + return master(sock); } else - { - fprintf(stderr, "apprentice host %s port %d\n", hostname, port); - sock = apprentice_connect(hostname, port); - return apprentice(sock); + { + if (trace_fn) + { + trace_file = open(trace_fn, O_RDONLY); + } else { + fprintf(stderr, "apprentice host %s port %d\n", hostname, port); + sock = apprentice_connect(hostname, port); + } + return apprentice(sock); } } diff --git a/risu_aarch64.c b/risu_aarch64.c index c4c0d4d..7f9f612 100644 --- a/risu_aarch64.c +++ b/risu_aarch64.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "risu.h" #include "risu_reginfo_aarch64.h" @@ -28,9 +29,7 @@ void advance_pc(void *vuc) { ucontext_t *uc = vuc; uc->uc_mcontext.pc += 4; - if (ismaster) { - report_test_status((void *) uc->uc_mcontext.pc); - } + report_test_status((void *) uc->uc_mcontext.pc); } static void set_x0(void *vuc, uint64_t x0) diff --git a/risu_arm.c b/risu_arm.c index 474729c..77bdcac 100644 --- a/risu_arm.c +++ b/risu_arm.c @@ -50,9 +50,7 @@ void advance_pc(void *vuc) { ucontext_t *uc = vuc; uc->uc_mcontext.arm_pc += insnsize(uc); - if (ismaster) { - report_test_status((void *) uc->uc_mcontext.arm_pc); - } + report_test_status((void *) uc->uc_mcontext.arm_pc); } static void set_r0(void *vuc, uint32_t r0)