From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 150525051705839.465950915646204; Tue, 12 Sep 2017 14:08:37 -0700 (PDT) Received: from localhost ([::1]:38613 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsQ7-0005mU-QL for importer@patchew.org; Tue, 12 Sep 2017 17:08:35 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52935) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsNb-0004Dt-TY for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:06:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drsNX-0008Ty-OX for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:05:59 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:48722) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsNX-0008Td-Ca for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:05:55 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CL5pek021525; Tue, 12 Sep 2017 23:05:51 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 640362EB; Tue, 12 Sep 2017 23:05:46 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 00:05:45 +0300 Message-Id: <150525034497.15988.15470574509428976971.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CL5pek021525 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 01/22] instrument: Add documentation 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: "Emilio G. Cota" , Markus Armbruster , Stefan Hajnoczi , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- MAINTAINERS | 6 ++ docs/instrument.txt | 173 +++++++++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 179 insertions(+) create mode 100644 docs/instrument.txt diff --git a/MAINTAINERS b/MAINTAINERS index 36eeb42d19..fb0eaee06a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1486,6 +1486,12 @@ F: scripts/tracetool/ F: docs/tracing.txt T: git git://github.com/stefanha/qemu.git tracing =20 +Event instrumentation +M: Llu=C3=ADs Vilanova +M: Stefan Hajnoczi +S: Maintained +F: docs/instrument.txt + TPM S: Orphan F: tpm.c diff --git a/docs/instrument.txt b/docs/instrument.txt new file mode 100644 index 0000000000..24a0d21fc7 --- /dev/null +++ b/docs/instrument.txt @@ -0,0 +1,173 @@ +=3D Event instrumentation =3D + +=3D=3D Introduction =3D=3D + +Event instrumentation allows users to execute their own host-native code o= n a +set of pre-defined events provided by QEMU. QEMU also exposes other +functionality to peek/poke at the guest state (e.g., memory or registers),= as +well as interacting with tracing events. For those familiar with the term,= this +provides dynamic binary instrumentation, works on all QEMU-supported +architectures, as well as works in both 'user' (standalone application) and +'system' (full-system emulation) modes. + +Look at the headers installed by QEMU on the "qemu-instr" directory for fu= rther +information beyond this document. + + +=3D=3D Loading an instrumentation library =3D=3D + +Instrumentation code can be bundled into a dynamic library, which can be l= ater +loaded into QEMU: + +* Using the command-line "-instr" argument. + +* Using the "instr-load" and "instr-unload" commands in the HMP and QMP + interfaces. + + +=3D=3D Example =3D=3D + +1. Configure QEMU with event instrumentation: + + # instrument guest_cpu_enter and guest_mem_before + mkdir -p /path/to/qemu-build + cd /path/to/qemu-build + /path/to/qemu-source/configure \ + --enable-instrument \ + --prefix=3D/path/to/qemu-install + +2. Build and install QEMU: + + make install + +3. Create the "Makefile" to build the instrumentation library: + + mkdir -p /tmp/my-instrument + =20 + cat > /tmp/my-instrument/Makefile < /tmp/my-instrument/instrument.c < + #include + =20 + #include /* manipulate events */ + #include /* manipulate tracing */ + =20 + /* the address for the memory access is not known at translation time = */ + void guest_mem_before_trans(QICPU vcpu_trans, QITCGv_cpu vcpu_exec, + QITCGv vaddr, QIMemInfo info) + { + printf("%s: %p %p %p %d %d %d %d\n", __func__, vcpu_trans, vcpu_ex= ec, vaddr, + 1 << info.size_shift, info.sign_extend, info.endianness, in= fo.store); + if (info.store) { + /* generate at execution time only for memory writes */ + qi_event_gen_guest_mem_before_exec(vcpu_exec, vaddr, info); + } + } + =20 + /* called when QEMU executes a memory access */ + void guest_mem_before_exec(QICPU vcpu, uint64_t vaddr, QIMemInfo info) + { + if (info.store) { + /* if called by TCG code, we'll only get writes (see above) */ + printf("%s: %p %lx %d %d %d %d\n", __func__, vcpu, vaddr, + 1 << info.size_shift, info.sign_extend, info.endianness= , info.store); + } + } + =20 + /* called every time QEMU hotplugs a CPU */ + void guest_cpu_enter(QICPU vcpu) + { + printf("%s: %p\n", __func__, vcpu); + =20 + /* disable instrumentation and tracing after the first call */ + static bool found =3D false; + if (found) { + qi_event_set_guest_cpu_enter(NULL); + QITraceEvent *ev =3D qi_trace_event_name("guest_cpu_enter"); + assert(ev); + qi_trace_event_set_state_dynamic(ev, true); + } else { + found =3D true; + } + } + =20 + static void fini(void *data) + { + /* diable all tracing events */ + QITraceEventIter iter; + qi_trace_event_iter_init(&iter, NULL); + QITraceEvent *ev; + while ((ev =3D qi_trace_event_iter_next(&iter)) !=3D NULL) { + if (qi_trace_event_get_state_static(ev)) { + qi_trace_event_set_state_dynamic(ev, false); + } + } + =20 + /* instrumentation callbacks are automatically reset by QEMU */ + } + =20 + /* mandatory initialization function */ + int main(int argc, const char **argv) + { + int i; + printf("init!\n"); + printf(" argc :: %d\n", argc); + for (i =3D 0; i < argc; i++) { + printf(" -> %s\n", argv[i]); + } + =20 + qi_set_fini(fini, NULL); + =20 + /* instrument and trace events */ + QITraceEvent *ev; + =20 + qi_event_set_guest_cpu_enter(guest_cpu_enter); + ev =3D qi_trace_event_name("guest_cpu_enter"); + assert(ev); + qi_trace_event_set_state_dynamic(ev, true); + =20 + qi_event_set_guest_mem_before_trans(guest_mem_before_trans); + ev =3D qi_trace_event_name("guest_mem_before_trans"); + assert(ev); + qi_trace_event_set_state_dynamic(ev, true); + =20 + qi_event_set_guest_mem_before_exec(guest_mem_before_exec); + ev =3D qi_trace_event_name("guest_mem_before_exec"); + assert(ev); + qi_trace_event_set_state_dynamic(ev, true); + =20 + return 0; + } + EOF + +5. Compile the instrumentation library: + + make -C /tmp/my-instrument + +6. Start QEMU with the instrumentation library: + + /tmp/qemu-install/bin/qemu-system-x86_64 \ + -instr file=3D/tmp/my-dinstrument/.libs/libtrace-instrument.so, \ + arg=3Dfoo,arg=3Dbar From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505250654810190.07898240401585; Tue, 12 Sep 2017 14:10:54 -0700 (PDT) Received: from localhost ([::1]:38627 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsSL-00077q-Rh for importer@patchew.org; Tue, 12 Sep 2017 17:10:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55140) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsRX-0006ck-3t for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:10:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drsRS-0002WP-7v for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:10:03 -0400 Received: from roura.ac.upc.edu ([147.83.33.10]:34756 helo=roura.ac.upc.es) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsRR-0002Vl-TK for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:09:58 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CL9rUe021638; Tue, 12 Sep 2017 23:09:53 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 6D2702EB; Tue, 12 Sep 2017 23:09:48 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 00:09:47 +0300 Message-Id: <150525058710.15988.551646038781937708.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CL9rUe021638 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 02/22] instrument: Add configure-time flag 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: "Emilio G. Cota" , Markus Armbruster , Stefan Hajnoczi Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- configure | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/configure b/configure index fd7e3a5e81..a21d1bceb9 100755 --- a/configure +++ b/configure @@ -356,6 +356,7 @@ pie=3D"" qom_cast_debug=3D"yes" trace_backends=3D"log" trace_file=3D"trace" +instrument=3D"no" spice=3D"" rbd=3D"" smartcard=3D"" @@ -886,6 +887,8 @@ for opt do ;; --with-trace-file=3D*) trace_file=3D"$optarg" ;; + --enable-instrument) instrument=3D"yes" + ;; --enable-gprof) gprof=3D"yes" ;; --enable-gcov) gcov=3D"yes" @@ -1436,6 +1439,7 @@ Advanced options (experts only): Available backends: $trace_backend_list --with-trace-file=3DNAME Full PATH,NAME of file to store traces Default:trace- + --enable-instrument enable event instrumentation --disable-slirp disable SLIRP userspace network connectivity --enable-tcg-interpreter enable TCG with bytecode interpreter (TCI) --oss-lib path to OSS library @@ -5366,6 +5370,7 @@ echo "Trace backends $trace_backends" if have_backend "simple"; then echo "Trace output file $trace_file-" fi +echo "instrumentation $instrument" echo "spice support $spice $(echo_version $spice $spice_protocol_versi= on/$spice_server_version)" echo "rbd support $rbd" echo "xfsctl support $xfs" @@ -6019,6 +6024,10 @@ if have_backend "syslog"; then fi echo "CONFIG_TRACE_FILE=3D$trace_file" >> $config_host_mak =20 +if test "$instrument" =3D "yes"; then + echo "CONFIG_INSTRUMENT=3Dy" >> $config_host_mak +fi + if test "$rdma" =3D "yes" ; then echo "CONFIG_RDMA=3Dy" >> $config_host_mak fi From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 150525094160029.246234625369993; Tue, 12 Sep 2017 14:15:41 -0700 (PDT) Received: from localhost ([::1]:38648 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsWy-0002bc-DD for importer@patchew.org; Tue, 12 Sep 2017 17:15:40 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57939) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsVP-0001RX-KM for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:14:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drsVM-0005HW-HO for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:14:03 -0400 Received: from roura.ac.upc.edu ([147.83.33.10]:57255 helo=roura.ac.upc.es) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsVL-0005GQ-UA for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:14:00 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CLDuQA021763; Tue, 12 Sep 2017 23:13:56 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 85264201; Tue, 12 Sep 2017 23:13:50 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 00:13:49 +0300 Message-Id: <150525082913.15988.6500475428955069862.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CLDuQA021763 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 03/22] instrument: Add generic library loader 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: Markus Armbruster , "Emilio G. Cota" , Stefan Hajnoczi , Paolo Bonzini , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- MAINTAINERS | 1=20 Makefile.objs | 4 + configure | 3 + instrument/Makefile.objs | 4 + instrument/cmdline.c | 128 +++++++++++++++++++++++++++++++++++ instrument/cmdline.h | 51 ++++++++++++++ instrument/load.c | 166 ++++++++++++++++++++++++++++++++++++++++++= ++++ instrument/load.h | 88 ++++++++++++++++++++++++ stubs/Makefile.objs | 1=20 stubs/instrument.c | 18 +++++ 10 files changed, 464 insertions(+) create mode 100644 instrument/Makefile.objs create mode 100644 instrument/cmdline.c create mode 100644 instrument/cmdline.h create mode 100644 instrument/load.c create mode 100644 instrument/load.h create mode 100644 stubs/instrument.c diff --git a/MAINTAINERS b/MAINTAINERS index fb0eaee06a..6c0b12a69a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1491,6 +1491,7 @@ M: Llu=C3=ADs Vilanova M: Stefan Hajnoczi S: Maintained F: docs/instrument.txt +F: instrument/ =20 TPM S: Orphan diff --git a/Makefile.objs b/Makefile.objs index 24a4ea08b8..81a9218e14 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -97,6 +97,10 @@ version-obj-$(CONFIG_WIN32) +=3D $(BUILD_DIR)/version.o util-obj-y +=3D trace/ target-obj-y +=3D trace/ =20 +###################################################################### +# instrument +target-obj-y +=3D instrument/ + ###################################################################### # guest agent =20 diff --git a/configure b/configure index a21d1bceb9..5175151317 100755 --- a/configure +++ b/configure @@ -6025,6 +6025,9 @@ fi echo "CONFIG_TRACE_FILE=3D$trace_file" >> $config_host_mak =20 if test "$instrument" =3D "yes"; then + LDFLAGS=3D"-rdynamic $LDFLAGS" # limit symbols available to cli= ents + QEMU_CFLAGS=3D"-fvisibility=3Dhidden $QEMU_CFLAGS" + LIBS=3D"-ldl $LIBS" echo "CONFIG_INSTRUMENT=3Dy" >> $config_host_mak fi =20 diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs new file mode 100644 index 0000000000..71994a4c85 --- /dev/null +++ b/instrument/Makefile.objs @@ -0,0 +1,4 @@ +# -*- mode: makefile -*- + +target-obj-$(CONFIG_INSTRUMENT) +=3D cmdline.o +target-obj-$(CONFIG_INSTRUMENT) +=3D load.o diff --git a/instrument/cmdline.c b/instrument/cmdline.c new file mode 100644 index 0000000000..da7a7cbceb --- /dev/null +++ b/instrument/cmdline.c @@ -0,0 +1,128 @@ +/* + * Control instrumentation during program (de)initialization. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include +#include "instrument/cmdline.h" +#include "instrument/load.h" +#include "qemu/config-file.h" +#include "qemu/error-report.h" + + +QemuOptsList qemu_instr_opts =3D { + .name =3D "instrument", + .implied_opt_name =3D "file", + .merge_lists =3D true, + .head =3D QTAILQ_HEAD_INITIALIZER(qemu_instr_opts.head), + .desc =3D { + { + .name =3D "file", + .type =3D QEMU_OPT_STRING, + },{ + .name =3D "arg", + .type =3D QEMU_OPT_STRING, + }, + { /* end of list */ } + }, +}; + +void instr_opt_parse(const char *optarg, char **path, + int *argc, const char ***argv) +{ + const char *arg; + QemuOptsIter iter; + QemuOpts *opts =3D qemu_opts_parse_noisily(qemu_find_opts("instrument"= ), + optarg, true); + if (!opts) { + exit(1); + } else { +#if !defined(CONFIG_INSTRUMENT) + error_report("instrumentation not enabled on this build"); + exit(1); +#endif + } + + + arg =3D qemu_opt_get(opts, "file"); + if (arg !=3D NULL) { + g_free(*path); + *path =3D g_strdup(arg); + } + + qemu_opt_iter_init(&iter, opts, "arg"); + while ((arg =3D qemu_opt_iter_next(&iter)) !=3D NULL) { + *argv =3D realloc(*argv, sizeof(**argv) * (*argc + 1)); + (*argv)[*argc] =3D g_strdup(arg); + (*argc)++; + } + + qemu_opts_del(opts); +} + +void instr_init(const char *path, int argc, const char **argv) +{ +#if defined(CONFIG_INSTRUMENT) + InstrLoadError err; + + if (path =3D=3D NULL) { + return; + } + + if (atexit(instr_fini) !=3D 0) { + fprintf(stderr, "error: atexit: %s\n", strerror(errno)); + abort(); + } + + const char *id =3D "cmdline"; + err =3D instr_load(path, argc, argv, &id); + switch (err) { + case INSTR_LOAD_OK: + error_report("instrument: loaded library with ID '%s'", id); + return; + case INSTR_LOAD_TOO_MANY: + error_report("instrument: tried to load too many libraries"); + break; + case INSTR_LOAD_ID_EXISTS: + g_assert_not_reached(); + break; + case INSTR_LOAD_ERROR: + error_report("instrument: library initialization returned non-zero= "); + break; + case INSTR_LOAD_DLERROR: + error_report("instrument: error loading library: %s", dlerror()); + break; + } +#else + error_report("instrument: not available"); +#endif + + exit(1); +} + +void instr_fini(void) +{ +#if defined(CONFIG_INSTRUMENT) + InstrUnloadError err =3D instr_unload_all(); + + switch (err) { + case INSTR_UNLOAD_OK: + return; + case INSTR_UNLOAD_INVALID: + /* the user might have already unloaded it */ + return; + case INSTR_UNLOAD_DLERROR: + error_report("instrument: error unloading library: %s", dlerror()); + break; + } +#else + error_report("instrument: not available"); +#endif + + exit(1); +} diff --git a/instrument/cmdline.h b/instrument/cmdline.h new file mode 100644 index 0000000000..3734f5f438 --- /dev/null +++ b/instrument/cmdline.h @@ -0,0 +1,51 @@ +/* + * Control instrumentation during program (de)initialization. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef INSTRUMENT__CMDLINE_H +#define INSTRUMENT__CMDLINE_H + +#include "qemu/typedefs.h" + + +/** + * Definition of QEMU options describing instrumentation subsystem + * configuration. + */ +extern QemuOptsList qemu_instr_opts; + +/** + * instr_opt_parse: + * @optarg: A string argument of --instrument command line argument + * + * Initialize instrument subsystem. + */ +void instr_opt_parse(const char *optarg, char **path, + int *argc, const char ***argv); + +/** + * instr_init: + * @path: Path to dynamic trace instrumentation library. + * @argc: Number of arguments to the library's #qi_init routine. + * @argv: Arguments to the library's #qi_init routine. + * + * Load and initialize the given instrumentation library. Calls exit() if = the + * library's initialization function returns a non-zero value. + * + * Installs instr_fini() as an atexit() callback. + */ +void instr_init(const char *path, int argc, const char **argv); + +/** + * instr_fini: + * + * Deinitialize and unload all instrumentation libraries. + */ +void instr_fini(void); + +#endif /* INSTRUMENT__CMDLINE_H */ diff --git a/instrument/load.c b/instrument/load.c new file mode 100644 index 0000000000..af98f4ce38 --- /dev/null +++ b/instrument/load.c @@ -0,0 +1,166 @@ +/* + * Interface for (un)loading instrumentation libraries. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" + +#include +#include "instrument/load.h" +#include "qemu/config-file.h" +#include "qemu/error-report.h" + + +typedef struct InstrHandle { + char *id; + void *dlhandle; + QLIST_ENTRY(InstrHandle) list; +} InstrHandle; + + +static unsigned int handle_auto_id; +static QLIST_HEAD(, InstrHandle) handles =3D QLIST_HEAD_INITIALIZER(handle= s); +static QemuMutex instr_lock; + + +static InstrHandle *handle_new(const char **id) +{ + /* instr_lock is locked */ + InstrHandle *res =3D g_malloc0(sizeof(InstrHandle)); + if (!*id) { + *id =3D g_strdup_printf("lib%d", handle_auto_id); + handle_auto_id++; + } + res->id =3D g_strdup(*id); + QLIST_INSERT_HEAD(&handles, res, list); + return res; +} + +static void handle_destroy(InstrHandle *handle) +{ + /* instr_lock is locked */ + QLIST_REMOVE(handle, list); + g_free(handle->id); + g_free(handle); +} + +static InstrHandle *handle_find(const char *id) +{ + /* instr_lock is locked */ + InstrHandle *handle; + QLIST_FOREACH(handle, &handles, list) { + if (strcmp(handle->id, id) =3D=3D 0) { + return handle; + } + } + return NULL; +} + +InstrLoadError instr_load(const char *path, int argc, const char **argv, + const char **id) +{ + InstrLoadError res; + InstrHandle *handle; + int (*main_cb)(int, const char **); + int main_res; + + qemu_rec_mutex_lock(&instr_lock); + + if (*id && handle_find(*id)) { + res =3D INSTR_LOAD_ID_EXISTS; + goto out; + } + + if (!QLIST_EMPTY(&handles) > 0) { + /* XXX: This is in fact a hard-coded limit, but there's no reason = why a + * real multi-library implementation should fail. + */ + res =3D INSTR_LOAD_TOO_MANY; + goto out; + } + + handle =3D handle_new(id); + handle->dlhandle =3D dlopen(path, RTLD_NOW); + if (handle->dlhandle =3D=3D NULL) { + res =3D INSTR_LOAD_DLERROR; + goto err; + } + + main_cb =3D dlsym(handle->dlhandle, "main"); + if (main_cb =3D=3D NULL) { + res =3D INSTR_LOAD_DLERROR; + goto err; + } + + main_res =3D main_cb(argc, argv); + + if (main_res !=3D 0) { + res =3D INSTR_LOAD_ERROR; + goto err; + } + + res =3D INSTR_LOAD_OK; + goto out; + +err: + handle_destroy(handle); +out: + qemu_rec_mutex_unlock(&instr_lock); + return res; +} + +InstrUnloadError instr_unload(const char *id) +{ + InstrUnloadError res; + + qemu_rec_mutex_lock(&instr_lock); + + InstrHandle *handle =3D handle_find(id); + if (handle =3D=3D NULL) { + res =3D INSTR_UNLOAD_INVALID; + goto out; + } + + /* this should never fail */ + if (dlclose(handle->dlhandle) < 0) { + res =3D INSTR_UNLOAD_DLERROR; + } else { + res =3D INSTR_UNLOAD_OK; + } + handle_destroy(handle); + +out: + qemu_rec_mutex_unlock(&instr_lock); + return res; +} + +InstrUnloadError instr_unload_all(void) +{ + InstrUnloadError res =3D INSTR_UNLOAD_OK; + + qemu_rec_mutex_lock(&instr_lock); + while (true) { + InstrHandle *handle =3D QLIST_FIRST(&handles); + if (handle =3D=3D NULL) { + break; + } else { + res =3D instr_unload(handle->id); + if (res !=3D INSTR_UNLOAD_OK) { + break; + } + } + } + qemu_rec_mutex_unlock(&instr_lock); + + return res; +} + +static void __attribute__((constructor)) instr_lock_init(void) +{ + qemu_rec_mutex_init(&instr_lock); +} diff --git a/instrument/load.h b/instrument/load.h new file mode 100644 index 0000000000..162e09f9c9 --- /dev/null +++ b/instrument/load.h @@ -0,0 +1,88 @@ +/* + * Interface for (un)loading instrumentation libraries. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + + +#ifndef INSTRUMENT_LOAD_H +#define INSTRUMENT_LOAD_H + +#include "qemu/osdep.h" + +#include "qapi-types.h" +#include "qemu/queue.h" +#include "qemu/thread.h" + + +/** + * InstrLoadError: + * @INSTR_LOAD_OK: Correctly loaded. + * @INSTR_LOAD_ID_EXISTS: Tried to load an instrumentation libraries with = an + * existing ID. + * @INSTR_LOAD_TOO_MANY: Tried to load too many instrumentation libraries. + * @INSTR_LOAD_ERROR: The library's main() function returned a non-zero va= lue. + * @INSTR_LOAD_DLERROR: Error with libdl (see dlerror). + * + * Error codes for instr_load(). + */ +typedef enum { + INSTR_LOAD_OK, + INSTR_LOAD_ID_EXISTS, + INSTR_LOAD_TOO_MANY, + INSTR_LOAD_ERROR, + INSTR_LOAD_DLERROR, +} InstrLoadError; + +/** + * InstrUnloadError: + * @INSTR_UNLOAD_OK: Correctly unloaded. + * @INSTR_UNLOAD_INVALID: Invalid handle. + * @INSTR_UNLOAD_DLERROR: Error with libdl (see dlerror). + * + * Error codes for instr_unload(). + */ +typedef enum { + INSTR_UNLOAD_OK, + INSTR_UNLOAD_INVALID, + INSTR_UNLOAD_DLERROR, +} InstrUnloadError; + +/** + * instr_load: + * @path: Path to the shared library to load. + * @argc: Number of arguments passed to the initialization function of the + * library. + * @argv: Arguments passed to the initialization function of the library. + * @id: Instrumentation library id. + * + * Load a dynamic trace instrumentation library. + * + * Returns: Whether the library could be loaded. + */ +InstrLoadError instr_load(const char *path, int argc, const char **argv, + const char **id); + +/** + * instr_unload: + * @id: Instrumentation library id passed to instr_load(). + * + * Unload the given instrumentation library. + * + * Returns: Whether the library could be unloaded. + */ +InstrUnloadError instr_unload(const char *id); + +/** + * instr_unload_all: + * + * Unload all instrumentation libraries. + * + * Returns: Whether any library could not be unloaded. + */ +InstrUnloadError instr_unload_all(void); + +#endif /* INSTRUMENT_LOAD_H */ diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index 4a33495911..4bf342cb96 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -13,6 +13,7 @@ stub-obj-y +=3D error-printf.o stub-obj-y +=3D fdset.o stub-obj-y +=3D gdbstub.o stub-obj-y +=3D get-vm-name.o +stub-obj-y +=3D instrument.o stub-obj-y +=3D iothread.o stub-obj-y +=3D iothread-lock.o stub-obj-y +=3D is-daemonized.o diff --git a/stubs/instrument.c b/stubs/instrument.c new file mode 100644 index 0000000000..7d66f75454 --- /dev/null +++ b/stubs/instrument.c @@ -0,0 +1,18 @@ +/* + * Instrumentation placeholders. + * + * Copyright (C) 2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "instrument/cmdline.h" + + +void instr_init(const char *path, int argc, const char **argv) +{ +} +void instr_fini(void) +{ +} From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505251155024774.8902066038977; Tue, 12 Sep 2017 14:19:15 -0700 (PDT) Received: from localhost ([::1]:38662 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsaQ-0004to-90 for importer@patchew.org; Tue, 12 Sep 2017 17:19:14 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60197) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsZS-0004Qe-2V for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:18:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drsZP-0000hx-9r for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:18:14 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:49895) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsZO-0000h6-VH for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:18:11 -0400 Received: from correu-2.ac.upc.es (correu-2.ac.upc.es [147.83.30.92]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CLHwr9021876; Tue, 12 Sep 2017 23:17:58 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id D8E9A259; Tue, 12 Sep 2017 23:17:52 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 00:17:51 +0300 Message-Id: <150525107140.15988.6826863421661463025.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CLHwr9021876 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 04/22] instrument: [linux-user] Add command line library loader 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: Riku Voipio , Markus Armbruster , Laurent Vivier , "Emilio G. Cota" , Stefan Hajnoczi Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- linux-user/main.c | 21 +++++++++++++++++++++ linux-user/syscall.c | 4 ++++ 2 files changed, 25 insertions(+) diff --git a/linux-user/main.c b/linux-user/main.c index 03666ef657..ac5c30c1fb 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -36,6 +36,7 @@ #include "exec/log.h" #include "trace/control.h" #include "glib-compat.h" +#include "instrument/cmdline.h" =20 char *exec_path; =20 @@ -4017,6 +4018,17 @@ static void handle_arg_trace(const char *arg) trace_file =3D trace_opt_parse(arg); } =20 +static char *instrument_path; +static int instrument_argc; +static const char **instrument_argv; +#if defined(CONFIG_INSTRUMENT) +static void handle_arg_instrument(const char *arg) +{ + instr_opt_parse(arg, &instrument_path, + &instrument_argc, &instrument_argv); +} +#endif + struct qemu_argument { const char *argv; const char *env; @@ -4066,6 +4078,10 @@ static const struct qemu_argument arg_table[] =3D { "", "Seed for pseudo-random number generator"}, {"trace", "QEMU_TRACE", true, handle_arg_trace, "", "[[enable=3D]][,events=3D][,file=3D]"}, +#if defined(CONFIG_INSTRUMENT) + {"instr", "QEMU_INSTR", true, handle_arg_instrument, + "", "[file=3D][,arg=3D]"}, +#endif {"version", "QEMU_VERSION", false, handle_arg_version, "", "display version information and exit"}, {NULL, NULL, false, NULL, NULL, NULL} @@ -4257,6 +4273,9 @@ int main(int argc, char **argv, char **envp) srand(time(NULL)); =20 qemu_add_opts(&qemu_trace_opts); +#if defined(CONFIG_INSTRUMENT) + qemu_add_opts(&qemu_instr_opts); +#endif =20 optind =3D parse_args(argc, argv); =20 @@ -4265,6 +4284,8 @@ int main(int argc, char **argv, char **envp) } trace_init_file(trace_file); =20 + instr_init(instrument_path, instrument_argc, instrument_argv); + /* Zero out regs */ memset(regs, 0, sizeof(struct target_pt_regs)); =20 diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 9b6364a266..e73a07fa6f 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -115,6 +115,8 @@ int __clone2(int (*fn)(void *), void *child_stack_base, #include "uname.h" =20 #include "qemu.h" +#include "instrument/cmdline.h" + =20 #ifndef CLONE_IO #define CLONE_IO 0x80000000 /* Clone io context */ @@ -7765,6 +7767,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long = arg1, _mcleanup(); #endif gdb_exit(cpu_env, arg1); + instr_fini(); _exit(arg1); ret =3D 0; /* avoid warning */ break; @@ -9821,6 +9824,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long = arg1, _mcleanup(); #endif gdb_exit(cpu_env, arg1); + instr_fini(); ret =3D get_errno(exit_group(arg1)); break; #endif From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 150525137779938.191494644720365; Tue, 12 Sep 2017 14:22:57 -0700 (PDT) Received: from localhost ([::1]:38672 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drse0-0006KV-Uo for importer@patchew.org; Tue, 12 Sep 2017 17:22:56 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34267) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsdC-00060D-Ff for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:22:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drsd9-0003du-Ng for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:22:06 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:50042) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsd9-0003dM-Cq for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:22:03 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CLM0FO022220; Tue, 12 Sep 2017 23:22:00 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 0C3821C7; Tue, 12 Sep 2017 23:21:54 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 00:21:53 +0300 Message-Id: <150525131357.15988.12385200396782957884.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CLM0FO022220 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 05/22] instrument: [bsd-user] Add command line library loader 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: "Emilio G. Cota" , Markus Armbruster , Stefan Hajnoczi Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- bsd-user/main.c | 17 +++++++++++++++++ bsd-user/syscall.c | 5 +++++ 2 files changed, 22 insertions(+) diff --git a/bsd-user/main.c b/bsd-user/main.c index 8a6706a1c8..104844edfc 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -33,6 +33,7 @@ #include "exec/log.h" #include "trace/control.h" #include "glib-compat.h" +#include "instrument/cmdline.h" =20 int singlestep; unsigned long mmap_min_addr; @@ -667,6 +668,11 @@ static void usage(void) "-B address set guest_base address to address\n" "-bsd type select emulated BSD type FreeBSD/NetBSD/Open= BSD (default)\n" "\n" +#if defined(CONFIG_INSTRUMENT) + "-instr [file=3D][,arg=3D]\n" + " load an instrumentation library\n" + "\n" +#endif "Debug options:\n" "-d item1[,...] enable logging of specified items\n" " (use '-d help' for a list of log items)\n" @@ -738,6 +744,9 @@ int main(int argc, char **argv) envlist_t *envlist =3D NULL; char *trace_file =3D NULL; bsd_type =3D target_openbsd; + char *instrument_path =3D NULL; + int instrument_argc =3D 0; + const char **instrument_argv =3D NULL; =20 if (argc <=3D 1) usage(); @@ -756,6 +765,9 @@ int main(int argc, char **argv) cpu_model =3D NULL; =20 qemu_add_opts(&qemu_trace_opts); +#if defined(CONFIG_INSTRUMENT) + qemu_add_opts(&qemu_instr_opts); +#endif =20 optind =3D 1; for (;;) { @@ -843,6 +855,9 @@ int main(int argc, char **argv) } else if (!strcmp(r, "trace")) { g_free(trace_file); trace_file =3D trace_opt_parse(optarg); + } else if (!strcmp(r, "instr")) { + instr_opt_parse(optarg, &instrument_path, + &instrument_argc, &instrument_argv); } else { usage(); } @@ -872,6 +887,8 @@ int main(int argc, char **argv) } trace_init_file(trace_file); =20 + instr_init(instrument_path, instrument_argc, instrument_argv); + /* Zero out regs */ memset(regs, 0, sizeof(struct target_pt_regs)); =20 diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c index 66492aaf5d..3230f722f3 100644 --- a/bsd-user/syscall.c +++ b/bsd-user/syscall.c @@ -26,6 +26,8 @@ =20 #include "qemu.h" #include "qemu-common.h" +#include "instrument/cmdline.h" + =20 //#define DEBUG =20 @@ -332,6 +334,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi= _long arg1, _mcleanup(); #endif gdb_exit(cpu_env, arg1); + instr_fini(); /* XXX: should free thread stack and CPU env */ _exit(arg1); ret =3D 0; /* avoid warning */ @@ -430,6 +433,7 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_= long arg1, _mcleanup(); #endif gdb_exit(cpu_env, arg1); + instr_fini(); /* XXX: should free thread stack and CPU env */ _exit(arg1); ret =3D 0; /* avoid warning */ @@ -505,6 +509,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, abi= _long arg1, _mcleanup(); #endif gdb_exit(cpu_env, arg1); + instr_fini(); /* XXX: should free thread stack and CPU env */ _exit(arg1); ret =3D 0; /* avoid warning */ From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505251649668354.7899572844059; Tue, 12 Sep 2017 14:27:29 -0700 (PDT) Received: from localhost ([::1]:38686 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsiO-0007nY-Op for importer@patchew.org; Tue, 12 Sep 2017 17:27:28 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36198) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drshA-00073A-3s for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:26:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drsh5-0007Eh-OR for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:26:12 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:47898) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsh5-0007Dn-CD for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:26:07 -0400 Received: from correu-2.ac.upc.es (correu-2.ac.upc.es [147.83.30.92]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CLQ3ER022266; Tue, 12 Sep 2017 23:26:03 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id 554C425B; Tue, 12 Sep 2017 23:25:57 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 00:25:56 +0300 Message-Id: <150525155585.15988.1048249945691112897.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CLQ3ER022266 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 06/22] instrument: [softmmu] Add command line library loader 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: Paolo Bonzini , "Emilio G. Cota" , Markus Armbruster , Stefan Hajnoczi Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- qemu-options.hx | 19 +++++++++++++++++++ vl.c | 15 +++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/qemu-options.hx b/qemu-options.hx index 9f6e2adfff..6947388aab 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4077,6 +4077,25 @@ HXCOMM HX does not support conditional compilation o= f text. @findex -trace @include qemu-option-trace.texi ETEXI +#if defined(CONFIG_INSTRUMENT) +DEF("instr", HAS_ARG, QEMU_OPTION_instr, + "-instr [file=3D][,arg=3D]\n" + " load an instrumentation library\n", + QEMU_ARCH_ALL) +#endif +STEXI +@item -instr file=3D@var{file}[,arg=3D@var{string}] +@findex -instr + +Load a dynamic trace instrumentation library. + +@table @option +@item file=3D@var{file} +Load the given dynamic trace instrumentation library. +@item arg=3D@var{string} +String argument passed as to the library's @code{qi_init} routine (can be = given multiple times). +@end table +ETEXI =20 HXCOMM Internal use DEF("qtest", HAS_ARG, QEMU_OPTION_qtest, "", QEMU_ARCH_ALL) diff --git a/vl.c b/vl.c index fb1f05b937..aea05ed4cc 100644 --- a/vl.c +++ b/vl.c @@ -118,6 +118,7 @@ int main(int argc, char **argv) =20 #include "trace-root.h" #include "trace/control.h" +#include "instrument/cmdline.h" #include "qemu/queue.h" #include "sysemu/arch_init.h" =20 @@ -3037,6 +3038,9 @@ int main(int argc, char **argv, char **envp) } BlockdevOptions_queue; QSIMPLEQ_HEAD(, BlockdevOptions_queue) bdo_queue =3D QSIMPLEQ_HEAD_INITIALIZER(bdo_queue); + char *instrument_path =3D NULL; + int instrument_argc =3D 0; + const char **instrument_argv =3D NULL; =20 module_call_init(MODULE_INIT_TRACE); =20 @@ -3064,6 +3068,9 @@ int main(int argc, char **argv, char **envp) qemu_add_opts(&qemu_global_opts); qemu_add_opts(&qemu_mon_opts); qemu_add_opts(&qemu_trace_opts); +#if defined(CONFIG_INSTRUMENT) + qemu_add_opts(&qemu_instr_opts); +#endif qemu_add_opts(&qemu_option_rom_opts); qemu_add_opts(&qemu_machine_opts); qemu_add_opts(&qemu_accel_opts); @@ -4009,6 +4016,12 @@ int main(int argc, char **argv, char **envp) g_free(trace_file); trace_file =3D trace_opt_parse(optarg); break; +#if defined(CONFIG_INSTRUMENT) + case QEMU_OPTION_instr: + instr_opt_parse(optarg, &instrument_path, + &instrument_argc, &instrument_argv); + break; +#endif case QEMU_OPTION_readconfig: { int ret =3D qemu_read_config_file(optarg); @@ -4196,6 +4209,8 @@ int main(int argc, char **argv, char **envp) } trace_init_file(trace_file); =20 + instr_init(instrument_path, instrument_argc, instrument_argv); + /* Open the logfile at this point and set the log mask if necessary. */ if (log_file) { From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505251880007350.09424813864314; Tue, 12 Sep 2017 14:31:20 -0700 (PDT) Received: from localhost ([::1]:38699 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsm7-0001RJ-4b for importer@patchew.org; Tue, 12 Sep 2017 17:31:19 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38211) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsl3-0000vB-Kn for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:30:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drskz-0002XW-Am for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:30:13 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:42121) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsky-0002WC-SB for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:30:09 -0400 Received: from correu-2.ac.upc.es (correu-2.ac.upc.es [147.83.30.92]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CLU5ug022360; Tue, 12 Sep 2017 23:30:05 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id 20DBF25B; Tue, 12 Sep 2017 23:29:59 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 00:29:58 +0300 Message-Id: <150525179869.15988.10803736017266867796.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CLU5ug022360 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 07/22] instrument: [qapi] Add library loader 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: "Dr. David Alan Gilbert" , Markus Armbruster , "Emilio G. Cota" , Stefan Hajnoczi , Paolo Bonzini , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- MAINTAINERS | 1 + Makefile | 1 + instrument/Makefile.objs | 1 + instrument/qmp.c | 82 ++++++++++++++++++++++++++++++++++++++++++= ++++ monitor.c | 4 ++ qapi-schema.json | 3 ++ qapi/instrument.json | 49 +++++++++++++++++++++++++++ stubs/instrument.c | 26 +++++++++++++++ 8 files changed, 167 insertions(+) create mode 100644 instrument/qmp.c create mode 100644 qapi/instrument.json diff --git a/MAINTAINERS b/MAINTAINERS index 6c0b12a69a..edddab0502 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1492,6 +1492,7 @@ M: Stefan Hajnoczi S: Maintained F: docs/instrument.txt F: instrument/ +F: qapi/instrument.json =20 TPM S: Orphan diff --git a/Makefile b/Makefile index 337a1f6f9b..3861b3f49c 100644 --- a/Makefile +++ b/Makefile @@ -412,6 +412,7 @@ qapi-modules =3D $(SRC_PATH)/qapi-schema.json $(SRC_PAT= H)/qapi/common.json \ $(SRC_PATH)/qapi/block.json $(SRC_PATH)/qapi/block-core.jso= n \ $(SRC_PATH)/qapi/char.json \ $(SRC_PATH)/qapi/crypto.json \ + $(SRC_PATH)/qapi/instrument.json \ $(SRC_PATH)/qapi/introspect.json \ $(SRC_PATH)/qapi/migration.json \ $(SRC_PATH)/qapi/net.json \ diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs index 71994a4c85..7bf4e27e3c 100644 --- a/instrument/Makefile.objs +++ b/instrument/Makefile.objs @@ -2,3 +2,4 @@ =20 target-obj-$(CONFIG_INSTRUMENT) +=3D cmdline.o target-obj-$(CONFIG_INSTRUMENT) +=3D load.o +target-obj-$(CONFIG_INSTRUMENT) +=3D qmp.o diff --git a/instrument/qmp.c b/instrument/qmp.c new file mode 100644 index 0000000000..e4464aa5eb --- /dev/null +++ b/instrument/qmp.c @@ -0,0 +1,82 @@ +/* + * QMP interface for instrumentation control commands. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include + +#include "instrument/load.h" +#include "qemu-common.h" +#include "qapi/qmp/qerror.h" +#include "qmp-commands.h" + + +InstrLoadResult *qmp_instr_load(const char *path, + bool has_id, const char *id, + bool have_args, strList *args, + Error **errp) +{ + InstrLoadResult *res =3D g_malloc0(sizeof(*res)); + int argc =3D 0; + const char **argv =3D NULL; + InstrLoadError code; + + if (!has_id) { + id =3D NULL; + } + + strList *entry =3D have_args ? args : NULL; + while (entry !=3D NULL) { + argv =3D realloc(argv, sizeof(*argv) * (argc + 1)); + argv[argc] =3D entry->value; + argc++; + entry =3D entry->next; + } + + code =3D instr_load(path, argc, argv, &id); + switch (code) { + case INSTR_LOAD_OK: + res->id =3D g_strdup(id); + break; + case INSTR_LOAD_ID_EXISTS: + error_setg(errp, "Library ID exists"); + break; + case INSTR_LOAD_TOO_MANY: + error_setg(errp, "Tried to load too many libraries"); + break; + case INSTR_LOAD_ERROR: + error_setg(errp, "Library initialization returned non-zero"); + break; + case INSTR_LOAD_DLERROR: + error_setg(errp, "Error loading library: %s", + dlerror()); + break; + } + + if (*errp) { + g_free(res); + res =3D NULL; + } + + return res; +} + +void qmp_instr_unload(const char *id, Error **errp) +{ + InstrUnloadError code =3D instr_unload(id); + switch (code) { + case INSTR_UNLOAD_OK: + break; + case INSTR_UNLOAD_INVALID: + error_setg(errp, "Unknown library ID"); + break; + case INSTR_UNLOAD_DLERROR: + error_setg(errp, "Error unloading library: %s", dlerror()); + break; + } +} diff --git a/monitor.c b/monitor.c index 9239f7adde..e031aa2687 100644 --- a/monitor.c +++ b/monitor.c @@ -978,6 +978,10 @@ static void qmp_unregister_commands_hack(void) qmp_unregister_command(&qmp_commands, "query-xen-replication-status"); qmp_unregister_command(&qmp_commands, "xen-colo-do-checkpoint"); #endif +#ifndef CONFIG_INSTRUMENT + qmp_unregister_command(&qmp_commands, "instr-load"); + qmp_unregister_command(&qmp_commands, "instr-unload"); +#endif #ifndef TARGET_I386 qmp_unregister_command(&qmp_commands, "rtc-reset-reinjection"); #endif diff --git a/qapi-schema.json b/qapi-schema.json index f3af2cb851..706c64659f 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -93,6 +93,9 @@ { 'include': 'qapi/trace.json' } { 'include': 'qapi/introspect.json' } =20 +# Instrumentation commands +{ 'include': 'qapi/instrument.json' } + ## # =3D Miscellanea ## diff --git a/qapi/instrument.json b/qapi/instrument.json new file mode 100644 index 0000000000..c59bee74cb --- /dev/null +++ b/qapi/instrument.json @@ -0,0 +1,49 @@ +# *-*- Mode: Python -*-* +# +# Copyright (C) 2012-2017 Llu=C3=ADs Vilanova +# +# This work is licensed under the terms of the GNU GPL, version 2 or later. +# See the COPYING file in the top-level directory. + +## +# QAPI instrumentation control commands. +## + +## +# @InstrLoadResult: +# +# Result of an 'instr-load' command. +# +# @id: instrumentation library ID +# +# Since: 2.11 +## +{ 'struct': 'InstrLoadResult', + 'data': { 'id': 'str' } } + +## +# @instr-load: +# +# Load an instrumentation library. +# +# @path: path to the dynamic instrumentation library +# @id: unique ID for the loaded library +# @args: arguments to the dynamic instrumentation library +# +# Since: 2.11 +## +{ 'command': 'instr-load', + 'data': { 'path': 'str', '*id': 'str', '*args': ['str'] }, + 'returns': 'InstrLoadResult' } + +## +# @instr-unload: +# +# Unload an instrumentation library. +# +# @id: unique ID passed to instr-load(). +# +# Since: 2.11 +## +{ 'command': 'instr-unload', + 'data': { 'id': 'str' } } diff --git a/stubs/instrument.c b/stubs/instrument.c index 7d66f75454..79cd0fd2d1 100644 --- a/stubs/instrument.c +++ b/stubs/instrument.c @@ -7,7 +7,15 @@ * See the COPYING file in the top-level directory. */ =20 +#include "qemu/osdep.h" + #include "instrument/cmdline.h" +#include "qapi/error.h" +#include "qapi/qmp/qerror.h" + + +/* Declare missing types */ +typedef struct strList strList; =20 =20 void instr_init(const char *path, int argc, const char **argv) @@ -16,3 +24,21 @@ void instr_init(const char *path, int argc, const char *= *argv) void instr_fini(void) { } + +InstrLoadResult *qmp_instr_load(const char *path, + bool has_id, const char *id, + bool have_args, strList *args, + Error **errp); +InstrLoadResult *qmp_instr_load(const char *path, + bool has_id, const char *id, + bool have_args, strList *args, + Error **errp) +{ + error_setg(errp, QERR_UNSUPPORTED); + return NULL; +} +void qmp_instr_unload(const char *id, Error **errp); +void qmp_instr_unload(const char *id, Error **errp) +{ + error_setg(errp, QERR_UNSUPPORTED); +} From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505252188524248.97450429485866; Tue, 12 Sep 2017 14:36:28 -0700 (PDT) Received: from localhost ([::1]:38732 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsr5-0005iV-Nx for importer@patchew.org; Tue, 12 Sep 2017 17:36:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39930) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsp2-0004HB-Vy for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:34:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drsoy-0004pt-NR for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:34:21 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:51449) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsoy-0004pU-CK for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:34:16 -0400 Received: from correu-2.ac.upc.es (correu-2.ac.upc.es [147.83.30.92]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CLY7lj022446; Tue, 12 Sep 2017 23:34:07 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id 30C1D259; Tue, 12 Sep 2017 23:34:02 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 00:34:01 +0300 Message-Id: <150525204093.15988.8421573656094243079.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CLY7lj022446 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 08/22] instrument: [hmp] Add library loader 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: "Emilio G. Cota" , Markus Armbruster , Stefan Hajnoczi , "Dr. David Alan Gilbert" Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- hmp-commands.hx | 32 ++++++++++++++++++++++++++++++++ monitor.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index 1941e19932..2e8ebe8422 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1858,6 +1858,38 @@ ETEXI .sub_table =3D info_cmds, }, =20 +#ifdef CONFIG_INSTRUMENT + { + .name =3D "instr-load", + .args_type =3D "path:F,id:s?,arg:s?", + .params =3D "path [id] [arg]", + .help =3D "load an instrumentation library", + .cmd =3D hmp_instr_load, + }, +#endif + +STEXI +@item instr-load @var{path} [@var{id}] [@var{arg}] +@findex instr-load +Load an instrumentation library. +ETEXI + +#ifdef CONFIG_INSTRUMENT + { + .name =3D "instr-unload", + .args_type =3D "id:s", + .params =3D "id", + .help =3D "unload an instrumentation library", + .cmd =3D hmp_instr_unload, + }, +#endif + +STEXI +@item instr-unload +@findex instr-unload +Unload an instrumentation library. +ETEXI + STEXI @end table ETEXI diff --git a/monitor.c b/monitor.c index e031aa2687..7b80d5351f 100644 --- a/monitor.c +++ b/monitor.c @@ -2323,6 +2323,45 @@ int monitor_fd_param(Monitor *mon, const char *fdnam= e, Error **errp) return fd; } =20 +#ifdef CONFIG_INSTRUMENT +static void hmp_instr_load(Monitor *mon, const QDict *qdict) +{ + Error *err =3D NULL; + const char *path =3D qdict_get_str(qdict, "path"); + const char *id =3D qdict_get_try_str(qdict, "id"); + const char *str =3D qdict_get_try_str(qdict, "arg"); + strList args; + + args.value =3D (char *)str; + args.next =3D NULL; + + InstrLoadResult *res =3D qmp_instr_load(path, + id !=3D NULL, id, + args.value !=3D NULL, &args, + &err); + if (err) { + error_report_err(err); + } else { + monitor_printf(mon, "Handle: %s\n", res->id); + monitor_printf(mon, "OK\n"); + } + qapi_free_InstrLoadResult(res); +} + +static void hmp_instr_unload(Monitor *mon, const QDict *qdict) +{ + Error *err =3D NULL; + const char *id =3D qdict_get_str(qdict, "id"); + + qmp_instr_unload(id, &err); + if (err) { + error_report_err(err); + } else { + monitor_printf(mon, "OK\n"); + } +} +#endif + /* Please update hmp-commands.hx when adding or changing commands */ static mon_cmd_t info_cmds[] =3D { #include "hmp-commands-info.h" From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505252373127250.26415378855722; Tue, 12 Sep 2017 14:39:33 -0700 (PDT) Received: from localhost ([::1]:38747 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsu4-0000bp-DA for importer@patchew.org; Tue, 12 Sep 2017 17:39:32 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41602) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsst-00080W-3w for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:38:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drssn-0000QA-S7 for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:38:19 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:54629) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drssn-0000OP-CA for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:38:13 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CLcAHq022600; Tue, 12 Sep 2017 23:38:10 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 6CA4B2EB; Tue, 12 Sep 2017 23:38:04 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 00:38:03 +0300 Message-Id: <150525228289.15988.9844115871305476442.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CLcAHq022600 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 09/22] instrument: Add basic control interface 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: Markus Armbruster , "Emilio G. Cota" , Stefan Hajnoczi , Paolo Bonzini , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- Makefile | 4 +++ configure | 1 + include/qemu/compiler.h | 19 ++++++++++++++++ instrument/Makefile.objs | 1 + instrument/control.c | 28 ++++++++++++++++++++++++ instrument/control.h | 44 +++++++++++++++++++++++++++++++++++= ++ instrument/control.inc.h | 25 +++++++++++++++++++++ instrument/error.h | 28 ++++++++++++++++++++++++ instrument/events.h | 37 +++++++++++++++++++++++++++++++ instrument/events.inc.h | 11 +++++++++ instrument/load.c | 13 +++++++++++ instrument/qemu-instr/control.h | 46 +++++++++++++++++++++++++++++++++++= ++++ stubs/instrument.c | 4 +++ 13 files changed, 261 insertions(+) create mode 100644 instrument/control.c create mode 100644 instrument/control.h create mode 100644 instrument/control.inc.h create mode 100644 instrument/error.h create mode 100644 instrument/events.h create mode 100644 instrument/events.inc.h create mode 100644 instrument/qemu-instr/control.h diff --git a/Makefile b/Makefile index 3861b3f49c..c3d9a4bcd9 100644 --- a/Makefile +++ b/Makefile @@ -599,6 +599,10 @@ ifdef CONFIG_VIRTFS $(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1" $(INSTALL_DATA) fsdev/virtfs-proxy-helper.1 "$(DESTDIR)$(mandir)/man1" endif +ifdef CONFIG_INSTRUMENT + $(INSTALL_DIR) "$(DESTDIR)$(includedir)/qemu-instr/" + $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/control.h "$(DESTDIR)$(= includedir)/qemu-instr/" +endif =20 install-datadir: $(INSTALL_DIR) "$(DESTDIR)$(qemu_datadir)" diff --git a/configure b/configure index 5175151317..18810eae84 100755 --- a/configure +++ b/configure @@ -6030,6 +6030,7 @@ if test "$instrument" =3D "yes"; then LIBS=3D"-ldl $LIBS" echo "CONFIG_INSTRUMENT=3Dy" >> $config_host_mak fi +QEMU_INCLUDES=3D"-I\$(SRC_PATH)/instrument $QEMU_INCLUDES" =20 if test "$rdma" =3D "yes" ; then echo "CONFIG_RDMA=3Dy" >> $config_host_mak diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index 340e5fdc09..e86bd34e2c 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h @@ -111,4 +111,23 @@ #define GCC_FMT_ATTR(n, m) #endif =20 +/* + * Export symbol to dlopen()'ed libraries'. + * + * This code is taken from http://gcc.gnu.org/wiki/Visibility. + */ +#if defined _WIN32 || defined __CYGWIN__ + #ifdef __GNUC__ + #define SYM_PUBLIC __attribute__ ((dllimport)) + #else + #define SYM_PUBLIC __declspec(dllimport) + #endif +#else + #if __GNUC__ >=3D 4 + #define SYM_PUBLIC __attribute__ ((visibility("default"))) + #else + #define SYM_PUBLIC + #endif +#endif + #endif /* COMPILER_H */ diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs index 7bf4e27e3c..ec76b2080b 100644 --- a/instrument/Makefile.objs +++ b/instrument/Makefile.objs @@ -3,3 +3,4 @@ target-obj-$(CONFIG_INSTRUMENT) +=3D cmdline.o target-obj-$(CONFIG_INSTRUMENT) +=3D load.o target-obj-$(CONFIG_INSTRUMENT) +=3D qmp.o +target-obj-$(CONFIG_INSTRUMENT) +=3D control.o diff --git a/instrument/control.c b/instrument/control.c new file mode 100644 index 0000000000..3630d6b3be --- /dev/null +++ b/instrument/control.c @@ -0,0 +1,28 @@ +/* + * Control instrumentation during program (de)initialization. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "instrument/control.h" +#include "instrument/error.h" +#include "instrument/events.h" +#include "instrument/load.h" +#include "instrument/qemu-instr/control.h" +#include "qemu/compiler.h" + +__thread InstrState instr_cur_state; + + +qi_fini_fn instr_event__fini_fn; +void *instr_event__fini_data; + +SYM_PUBLIC void qi_set_fini(qi_fini_fn fn, void *data) +{ + ERROR_IF(!instr_get_state(), "called outside instrumentation"); + instr_set_event(fini_fn, fn); + instr_set_event(fini_data, data); +} diff --git a/instrument/control.h b/instrument/control.h new file mode 100644 index 0000000000..f2b085f69b --- /dev/null +++ b/instrument/control.h @@ -0,0 +1,44 @@ +/* + * Control instrumentation during program (de)initialization. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef INSTRUMENT__CONTROL_H +#define INSTRUMENT__CONTROL_H + + +/** + * InstrState: + * @INSTR_STATE_DISABLE: Intrumentation API not available. + * @INSTR_STATE_ENABLE: Intrumentation API available. + * + * Instrumentation state of current host thread. Used to ensure instrument= ation + * clients use QEMU's API only in expected points. + */ +typedef enum { + INSTR_STATE_DISABLE, + INSTR_STATE_ENABLE, +} InstrState; + +/** + * instr_set_state: + * + * Set the instrumentation state of the current host thread. + */ +static inline void instr_set_state(InstrState state); + +/** + * instr_get_state: + * + * Get the instrumentation state of the current host thread. + */ +static inline InstrState instr_get_state(void); + + +#include "instrument/control.inc.h" + +#endif /* INSTRUMENT__CONTROL_H */ diff --git a/instrument/control.inc.h b/instrument/control.inc.h new file mode 100644 index 0000000000..0f649f4caa --- /dev/null +++ b/instrument/control.inc.h @@ -0,0 +1,25 @@ +/* + * Control instrumentation during program (de)initialization. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/atomic.h" +#include "qemu/compiler.h" +#include + + +extern __thread InstrState instr_cur_state; + +static inline void instr_set_state(InstrState state) +{ + atomic_store_release(&instr_cur_state, state); +} + +static inline InstrState instr_get_state(void) +{ + return atomic_load_acquire(&instr_cur_state); +} diff --git a/instrument/error.h b/instrument/error.h new file mode 100644 index 0000000000..f8d1dd4b16 --- /dev/null +++ b/instrument/error.h @@ -0,0 +1,28 @@ +/* + * Helpers for controlling errors in instrumentation libraries. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef INSTRUMENT_ERROR_H +#define INSTRUMENT_ERROR_H + +#include "qemu/osdep.h" +#include "qemu/error-report.h" + + +#define _ERROR(msg, args...) \ + do { \ + error_report("%s:" msg, __func__, ##args); \ + } while (0) + +#define ERROR_IF(cond, msg, args...) \ + if (unlikely(cond)) { \ + _ERROR(msg, ##args); \ + return; \ + } + +#endif /* INSTRUMENT_ERROR_H */ diff --git a/instrument/events.h b/instrument/events.h new file mode 100644 index 0000000000..82ad0bd827 --- /dev/null +++ b/instrument/events.h @@ -0,0 +1,37 @@ +/* + * Internal API for triggering instrumentation events. + * + * Copyright (C) 2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef INSTRUMENT__EVENTS_H +#define INSTRUMENT__EVENTS_H + +#include "instrument/qemu-instr/control.h" + +/** + * instr_get_event: + * + * Get value set by instrumentation library. + */ +#define instr_get_event(name) \ + atomic_load_acquire(&instr_event__ ## name) + +/** + * instr_get_event: + * + * Set value from instrumentation library. + */ +#define instr_set_event(name, fn) \ + atomic_store_release(&instr_event__ ## name, fn) + + +extern qi_fini_fn instr_event__fini_fn; +extern void *instr_event__fini_data; + +#include "instrument/events.inc.h" + +#endif /* INSTRUMENT__EVENTS_H */ diff --git a/instrument/events.inc.h b/instrument/events.inc.h new file mode 100644 index 0000000000..8b1ce7fcb2 --- /dev/null +++ b/instrument/events.inc.h @@ -0,0 +1,11 @@ +/* + * Internal API for triggering instrumentation events. + * + * Copyright (C) 2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + + + diff --git a/instrument/load.c b/instrument/load.c index af98f4ce38..a01d66a4d4 100644 --- a/instrument/load.c +++ b/instrument/load.c @@ -11,6 +11,8 @@ #include "qemu-common.h" =20 #include +#include "instrument/control.h" +#include "instrument/events.h" #include "instrument/load.h" #include "qemu/config-file.h" #include "qemu/error-report.h" @@ -96,8 +98,11 @@ InstrLoadError instr_load(const char *path, int argc, co= nst char **argv, res =3D INSTR_LOAD_DLERROR; goto err; } + instr_set_event(fini_fn, NULL); =20 + instr_set_state(INSTR_STATE_ENABLE); main_res =3D main_cb(argc, argv); + instr_set_state(INSTR_STATE_DISABLE); =20 if (main_res !=3D 0) { res =3D INSTR_LOAD_ERROR; @@ -126,6 +131,14 @@ InstrUnloadError instr_unload(const char *id) goto out; } =20 + qi_fini_fn fini_fn =3D instr_get_event(fini_fn); + if (fini_fn) { + void *fini_data =3D instr_get_event(fini_data); + fini_fn(fini_data); + } + + instr_set_event(fini_fn, NULL); + /* this should never fail */ if (dlclose(handle->dlhandle) < 0) { res =3D INSTR_UNLOAD_DLERROR; diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/contro= l.h new file mode 100644 index 0000000000..b841afaa31 --- /dev/null +++ b/instrument/qemu-instr/control.h @@ -0,0 +1,46 @@ +/* + * Main instrumentation interface for QEMU. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef QI__CONTROL_H +#define QI__CONTROL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + + +/** + * SECTION:control + * @section_id: qi-control + * @title: Event control API for QEMU event instrumentation + */ + +typedef void (*qi_fini_fn)(void *arg); + +/** + * qi_set_fini: + * @fn: Finalization function. + * @data: Argument to pass to the finalization function. + * + * Set the function to call when finalizing (unloading) the instrumentation + * library. + * + * NOTE: Calls to printf() might not be shown if the library is unloaded w= hen + * QEMU terminates. + */ +void qi_set_fini(qi_fini_fn fn, void *data); + +#ifdef __cplusplus +} +#endif + +#endif /* QI__CONTROL_H */ diff --git a/stubs/instrument.c b/stubs/instrument.c index 79cd0fd2d1..9498fcdfe5 100644 --- a/stubs/instrument.c +++ b/stubs/instrument.c @@ -10,6 +10,7 @@ #include "qemu/osdep.h" =20 #include "instrument/cmdline.h" +#include "instrument/control.h" #include "qapi/error.h" #include "qapi/qmp/qerror.h" =20 @@ -42,3 +43,6 @@ void qmp_instr_unload(const char *id, Error **errp) { error_setg(errp, QERR_UNSUPPORTED); } + + +__thread InstrState instr_cur_state; From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505252589300366.9437531109468; Tue, 12 Sep 2017 14:43:09 -0700 (PDT) Received: from localhost ([::1]:38771 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drsxY-0002lB-8K for importer@patchew.org; Tue, 12 Sep 2017 17:43:08 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44301) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drswl-0002LM-IV for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:42:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drswi-00056N-2s for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:42:19 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:54644) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drswh-00055P-JN for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:42:16 -0400 Received: from correu-2.ac.upc.es (correu-2.ac.upc.es [147.83.30.92]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CLgCk6022680; Tue, 12 Sep 2017 23:42:12 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id C705C25B; Tue, 12 Sep 2017 23:42:06 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 00:42:05 +0300 Message-Id: <150525252530.15988.15700689004917162150.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CLgCk6022680 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 10/22] instrument: Add support for tracing events 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: "Emilio G. Cota" , Markus Armbruster , Stefan Hajnoczi , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- .gitignore | 1=20 Makefile | 3 + instrument/Makefile.objs | 1=20 instrument/error.h | 6 ++ instrument/qemu-instr/types.h | 51 +++++++++++++++ instrument/qemu-instr/types.inc.h | 15 ++++ instrument/trace.c | 125 +++++++++++++++++++++++++++++++++= ++++ trace/control.h | 1=20 8 files changed, 203 insertions(+) create mode 100644 instrument/qemu-instr/types.h create mode 100644 instrument/qemu-instr/types.inc.h create mode 100644 instrument/trace.c diff --git a/.gitignore b/.gitignore index cf65316863..5ffcb9a091 100644 --- a/.gitignore +++ b/.gitignore @@ -134,3 +134,4 @@ trace-dtrace-root.h trace-dtrace-root.dtrace trace-ust-all.h trace-ust-all.c +!/instrument/* diff --git a/Makefile b/Makefile index c3d9a4bcd9..646fe2f327 100644 --- a/Makefile +++ b/Makefile @@ -602,6 +602,9 @@ endif ifdef CONFIG_INSTRUMENT $(INSTALL_DIR) "$(DESTDIR)$(includedir)/qemu-instr/" $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/control.h "$(DESTDIR)$(= includedir)/qemu-instr/" + $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/trace.h "$(DESTDIR)$(in= cludedir)/qemu-instr/" + $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/types.h "$(DESTDIR)$(in= cludedir)/qemu-instr/" + $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/types.inc.h "$(DESTDIR)= $(includedir)/qemu-instr/" endif =20 install-datadir: diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs index ec76b2080b..d7e6c760c3 100644 --- a/instrument/Makefile.objs +++ b/instrument/Makefile.objs @@ -4,3 +4,4 @@ target-obj-$(CONFIG_INSTRUMENT) +=3D cmdline.o target-obj-$(CONFIG_INSTRUMENT) +=3D load.o target-obj-$(CONFIG_INSTRUMENT) +=3D qmp.o target-obj-$(CONFIG_INSTRUMENT) +=3D control.o +target-obj-$(CONFIG_INSTRUMENT) +=3D trace.o diff --git a/instrument/error.h b/instrument/error.h index f8d1dd4b16..7a51d62fdb 100644 --- a/instrument/error.h +++ b/instrument/error.h @@ -25,4 +25,10 @@ return; \ } =20 +#define ERROR_IF_RET(cond, ret, msg, args...) \ + if (unlikely(cond)) { \ + _ERROR(msg, ##args); \ + return ret; \ + } \ + #endif /* INSTRUMENT_ERROR_H */ diff --git a/instrument/qemu-instr/types.h b/instrument/qemu-instr/types.h new file mode 100644 index 0000000000..ea3a032b4f --- /dev/null +++ b/instrument/qemu-instr/types.h @@ -0,0 +1,51 @@ +/* + * QEMU-specific types for instrumentation clients. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef QI__TYPES_H +#define QI__TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * SECTION: types + * @section_id: qi-types + * @title: Common types + */ + +/** + * QITraceEvent: + * + * Opaque structure defining a tracing event. + */ +typedef struct QITraceEvent QITraceEvent; + +/** + * QITraceEventIter: + * + * Opaque structure defining a tracing event iterator. + */ +typedef struct QITraceEventIter QITraceEventIter; + +/** + * QICPU: + * + * Opaque guest CPU pointer. + */ +typedef struct QICPU_d *QICPU; + + +#include + +#ifdef __cplusplus +} +#endif + +#endif /* QI__TYPES_H */ diff --git a/instrument/qemu-instr/types.inc.h b/instrument/qemu-instr/type= s.inc.h new file mode 100644 index 0000000000..0d99ea59a2 --- /dev/null +++ b/instrument/qemu-instr/types.inc.h @@ -0,0 +1,15 @@ +/* + * QEMU-specific types for instrumentation clients. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include + + +struct QITraceEventIter { + char buffer[(sizeof(size_t) * 2) + sizeof(char *)]; +}; diff --git a/instrument/trace.c b/instrument/trace.c new file mode 100644 index 0000000000..6a437039b4 --- /dev/null +++ b/instrument/trace.c @@ -0,0 +1,125 @@ +/* + * API for QEMU's tracing events. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "instrument/error.h" +#include "qemu/compiler.h" +#include "qemu-instr/trace.h" +#include "trace/control.h" + + +SYM_PUBLIC +QITraceEvent *qi_trace_event_name(const char *name) +{ + ERROR_IF_RET(!name, NULL, "must provide a name"); + return (QITraceEvent *)trace_event_name(name); +} + +SYM_PUBLIC +void qi_trace_event_iter_init(QITraceEventIter *iter, const char *pattern) +{ + TraceEventIter *iter_ =3D (TraceEventIter *)iter; + ERROR_IF(!iter_, "must provide an iterator"); + trace_event_iter_init(iter_, pattern); +} + +SYM_PUBLIC +QITraceEvent *qi_trace_event_iter_next(QITraceEventIter *iter) +{ + TraceEventIter *iter_ =3D (TraceEventIter *)iter; + ERROR_IF_RET(!iter_, NULL, "must provide an iterator"); + return (QITraceEvent *)trace_event_iter_next(iter_); +} + + +SYM_PUBLIC +bool qi_trace_event_is_vcpu(QITraceEvent *ev) +{ + TraceEvent *ev_ =3D (TraceEvent *)ev; + ERROR_IF_RET(!ev_, false, "must provide an event"); + return trace_event_is_vcpu(ev_); +} + +SYM_PUBLIC +const char *qi_trace_event_get_name(QITraceEvent *ev) +{ + TraceEvent *ev_ =3D (TraceEvent *)ev; + ERROR_IF_RET(!ev_, false, "must provide an event"); + return trace_event_get_name(ev_); +} + + +SYM_PUBLIC +bool qi_trace_event_get_state(QITraceEvent *ev) +{ + TraceEvent *ev_ =3D (TraceEvent *)ev; + ERROR_IF_RET(!ev_, false, "must provide an event"); + return trace_event_get_state_static(ev_) && + trace_event_get_state_dynamic(ev_); +} + +SYM_PUBLIC +bool qi_trace_event_get_vcpu_state(QICPU *vcpu, QITraceEvent *ev) +{ + CPUState *vcpu_ =3D (CPUState *)vcpu; + TraceEvent *ev_ =3D (TraceEvent *)ev; + ERROR_IF_RET(!vcpu_, false, "must provide a vCPU"); + ERROR_IF_RET(!ev_, false, "must provide an event"); + return trace_event_get_state_static(ev_) && + trace_event_get_vcpu_state_dynamic(vcpu_, ev_); +} + +SYM_PUBLIC +bool qi_trace_event_get_state_static(QITraceEvent *ev) +{ + TraceEvent *ev_ =3D (TraceEvent *)ev; + ERROR_IF_RET(!ev_, false, "must provide an event"); + return trace_event_get_state_static(ev_); +} + +SYM_PUBLIC +bool qi_trace_event_get_state_dynamic(QITraceEvent *ev) +{ + TraceEvent *ev_ =3D (TraceEvent *)ev; + ERROR_IF_RET(!ev_, false, "must provide an event"); + return trace_event_get_state_dynamic(ev_); +} + +SYM_PUBLIC +bool qi_trace_event_get_vcpu_state_dynamic(QICPU *vcpu, QITraceEvent *ev) +{ + CPUState *vcpu_ =3D (CPUState *)vcpu; + TraceEvent *ev_ =3D (TraceEvent *)ev; + ERROR_IF_RET(!vcpu_, false, "must provide a vCPU"); + ERROR_IF_RET(!ev_, false, "must provide an event"); + return trace_event_get_vcpu_state_dynamic(vcpu_, ev_); +} + +SYM_PUBLIC +void qi_trace_event_set_state_dynamic(QITraceEvent *ev, bool state) +{ + TraceEvent *ev_ =3D (TraceEvent *)ev; + ERROR_IF(!ev_, "must provide an event"); + ERROR_IF(!trace_event_get_state_static(ev_), + "event must be statically enabled"); + trace_event_set_state_dynamic(ev_, state); +} + +SYM_PUBLIC +void qi_trace_event_set_vcpu_state_dynamic(QICPU *vcpu, + QITraceEvent *ev, bool state) +{ + CPUState *vcpu_ =3D (CPUState *)vcpu; + TraceEvent *ev_ =3D (TraceEvent *)ev; + ERROR_IF(!vcpu_, "must provide a vCPU"); + ERROR_IF(!ev_, "must provide an event"); + ERROR_IF(!trace_event_get_state_static(ev_), + "event must be statically enabled"); + trace_event_set_vcpu_state_dynamic(vcpu_, ev_, state); +} diff --git a/trace/control.h b/trace/control.h index 1903e22975..3e6da24c98 100644 --- a/trace/control.h +++ b/trace/control.h @@ -13,6 +13,7 @@ #include "qemu-common.h" #include "event-internal.h" =20 +/* NOTE: Keep in sync with size of QITraceEventIter */ typedef struct TraceEventIter { size_t event; size_t group; From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505252839098492.0818976871868; Tue, 12 Sep 2017 14:47:19 -0700 (PDT) Received: from localhost ([::1]:38809 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drt1Z-0005Fg-Hz for importer@patchew.org; Tue, 12 Sep 2017 17:47:17 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50071) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drt0g-0004RF-31 for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:46:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drt0c-0002qr-ML for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:46:22 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:35374) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drt0c-0002pi-BK for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:46:18 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CLkEAD022739; Tue, 12 Sep 2017 23:46:14 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 20393201; Tue, 12 Sep 2017 23:46:08 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 00:46:07 +0300 Message-Id: <150525276755.15988.10713051972672554822.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CLkEAD022739 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 11/22] instrument: Track vCPUs 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: "Emilio G. Cota" , Markus Armbruster , Stefan Hajnoczi , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Keep a translation between instrumentation's QICPU and CPUState objects to = avoid exposing QEMU's internals to instrumentation clients. Signed-off-by: Llu=C3=ADs Vilanova --- cpus-common.c | 9 +++++++++ instrument/control.c | 23 +++++++++++++++++++++++ instrument/control.h | 36 ++++++++++++++++++++++++++++++++++++ instrument/control.inc.h | 23 +++++++++++++++++++++++ 4 files changed, 91 insertions(+) diff --git a/cpus-common.c b/cpus-common.c index 59f751ecf9..ec5f46cc3d 100644 --- a/cpus-common.c +++ b/cpus-common.c @@ -22,6 +22,9 @@ #include "exec/cpu-common.h" #include "qom/cpu.h" #include "sysemu/cpus.h" +#if defined(CONFIG_INSTRUMENT) +#include "instrument/control.h" +#endif =20 static QemuMutex qemu_cpu_list_lock; static QemuCond exclusive_cond; @@ -84,6 +87,9 @@ void cpu_list_add(CPUState *cpu) } else { assert(!cpu_index_auto_assigned); } +#if defined(CONFIG_INSTRUMENT) + instr_cpu_add(cpu); +#endif QTAILQ_INSERT_TAIL(&cpus, cpu, node); qemu_mutex_unlock(&qemu_cpu_list_lock); =20 @@ -102,6 +108,9 @@ void cpu_list_remove(CPUState *cpu) assert(!(cpu_index_auto_assigned && cpu !=3D QTAILQ_LAST(&cpus, CPUTai= lQ))); =20 QTAILQ_REMOVE(&cpus, cpu, node); +#if defined(CONFIG_INSTRUMENT) + instr_cpu_remove(cpu); +#endif cpu->cpu_index =3D UNASSIGNED_CPU_INDEX; qemu_mutex_unlock(&qemu_cpu_list_lock); } diff --git a/instrument/control.c b/instrument/control.c index 3630d6b3be..8cf2b4f967 100644 --- a/instrument/control.c +++ b/instrument/control.c @@ -13,10 +13,33 @@ #include "instrument/load.h" #include "instrument/qemu-instr/control.h" #include "qemu/compiler.h" +#include "qom/cpu.h" + =20 __thread InstrState instr_cur_state; =20 =20 +unsigned int instr_cpus_count; +CPUState **instr_cpus; + +void instr_cpu_add(CPUState *vcpu) +{ + unsigned int idx =3D vcpu->cpu_index; + if (idx >=3D instr_cpus_count) { + instr_cpus_count =3D idx + 1; + instr_cpus =3D realloc(instr_cpus, + sizeof(*instr_cpus) * instr_cpus_count); + } + instr_cpus[idx] =3D vcpu; +} + +void instr_cpu_remove(CPUState *vcpu) +{ + unsigned int idx =3D vcpu->cpu_index; + instr_cpus[idx] =3D NULL; +} + + qi_fini_fn instr_event__fini_fn; void *instr_event__fini_data; =20 diff --git a/instrument/control.h b/instrument/control.h index f2b085f69b..57cea07fa7 100644 --- a/instrument/control.h +++ b/instrument/control.h @@ -10,6 +10,42 @@ #ifndef INSTRUMENT__CONTROL_H #define INSTRUMENT__CONTROL_H =20 +#include "qemu/typedefs.h" +#include "instrument/qemu-instr/types.h" + + +/** + * instr_cpu_add: + * + * Make @vcpu available to instrumentation clients. + * + * Precondition: cpu_list_lock(). + */ +void instr_cpu_add(CPUState *vcpu); + +/** + * instr_cpu_remove: + * + * Make @vcpu unavailable to instrumentation clients. + * + * Precondition: cpu_list_lock(). + */ +void instr_cpu_remove(CPUState *vcpu); + +/** + * instr_cpu_to_qicpu: + * + * Get the #QICPU corresponding to the given #CPUState. + */ +static inline QICPU instr_cpu_to_qicpu(CPUState *vcpu); + +/** + * instr_cpu_from_qicpu: + * + * Get the #CPUState corresponding to the given #QICPU. + */ +static inline CPUState *instr_cpu_from_qicpu(QICPU vcpu); + =20 /** * InstrState: diff --git a/instrument/control.inc.h b/instrument/control.inc.h index 0f649f4caa..45daae7d1d 100644 --- a/instrument/control.inc.h +++ b/instrument/control.inc.h @@ -7,9 +7,32 @@ * See the COPYING file in the top-level directory. */ =20 +#include "qemu/osdep.h" #include "qemu/atomic.h" #include "qemu/compiler.h" +#include "qom/cpu.h" #include +#include + + +extern unsigned int instr_cpus_count; +extern CPUState **instr_cpus; + +static inline QICPU instr_cpu_to_qicpu(CPUState *vcpu) +{ + uintptr_t idx =3D vcpu->cpu_index; + return (QICPU)idx; +} + +static inline CPUState *instr_cpu_from_qicpu(QICPU vcpu) +{ + unsigned int idx =3D (uintptr_t)vcpu; + if (idx >=3D instr_cpus_count) { + return NULL; + } else { + return instr_cpus[idx]; + } +} =20 =20 extern __thread InstrState instr_cur_state; From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505253100556831.9208894514853; Tue, 12 Sep 2017 14:51:40 -0700 (PDT) Received: from localhost ([::1]:38820 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drt5n-00074o-Kq for importer@patchew.org; Tue, 12 Sep 2017 17:51:39 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51821) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drt4a-0006Z5-Fn for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:50:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drt4X-0007dB-2E for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:50:24 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:38353) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drt4W-0007cJ-Iu for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:50:20 -0400 Received: from correu-2.ac.upc.es (correu-2.ac.upc.es [147.83.30.92]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CLoH8V022816; Tue, 12 Sep 2017 23:50:17 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id 6FB88259; Tue, 12 Sep 2017 23:50:11 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 00:50:10 +0300 Message-Id: <150525300993.15988.4392688345407178657.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CLoH8V022816 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 12/22] instrument: Add event 'guest_cpu_enter' 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: Markus Armbruster , "Emilio G. Cota" , Stefan Hajnoczi , Paolo Bonzini , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- instrument/control.c | 9 ++++++++ instrument/events.h | 5 ++++ instrument/events.inc.h | 11 +++++++++ instrument/load.c | 9 ++++++++ instrument/qemu-instr/control.h | 46 +++++++++++++++++++++++++++++++++++= ++++ stubs/instrument.c | 1 + trace/control-target.c | 2 ++ 7 files changed, 83 insertions(+) diff --git a/instrument/control.c b/instrument/control.c index 8cf2b4f967..c4b3ca0440 100644 --- a/instrument/control.c +++ b/instrument/control.c @@ -49,3 +49,12 @@ SYM_PUBLIC void qi_set_fini(qi_fini_fn fn, void *data) instr_set_event(fini_fn, fn); instr_set_event(fini_data, data); } + + +void (*instr_event__guest_cpu_enter)(QICPU vcpu); + +SYM_PUBLIC void qi_event_set_guest_cpu_enter(void (*fn)(QICPU vcpu)) +{ + ERROR_IF(!instr_get_state(), "called outside instrumentation"); + instr_set_event(guest_cpu_enter, fn); +} diff --git a/instrument/events.h b/instrument/events.h index 82ad0bd827..947f120aa9 100644 --- a/instrument/events.h +++ b/instrument/events.h @@ -11,6 +11,7 @@ #define INSTRUMENT__EVENTS_H =20 #include "instrument/qemu-instr/control.h" +#include "instrument/qemu-instr/types.h" =20 /** * instr_get_event: @@ -32,6 +33,10 @@ extern qi_fini_fn instr_event__fini_fn; extern void *instr_event__fini_data; =20 +extern void (*instr_event__guest_cpu_enter)(QICPU vcpu); +static inline void instr_guest_cpu_enter(CPUState *vcpu); + + #include "instrument/events.inc.h" =20 #endif /* INSTRUMENT__EVENTS_H */ diff --git a/instrument/events.inc.h b/instrument/events.inc.h index 8b1ce7fcb2..e3f8024716 100644 --- a/instrument/events.inc.h +++ b/instrument/events.inc.h @@ -7,5 +7,16 @@ * See the COPYING file in the top-level directory. */ =20 +#include "instrument/control.h" =20 =20 +static inline void instr_guest_cpu_enter(CPUState *vcpu) +{ + void (*cb)(QICPU vcpu) =3D instr_get_event(guest_cpu_enter); + if (cb) { + QICPU vcpu_ =3D instr_cpu_to_qicpu(vcpu); + instr_set_state(INSTR_STATE_ENABLE); + (*cb)(vcpu_); + instr_set_state(INSTR_STATE_DISABLE); + } +} diff --git a/instrument/load.c b/instrument/load.c index a01d66a4d4..218bca74b2 100644 --- a/instrument/load.c +++ b/instrument/load.c @@ -11,6 +11,7 @@ #include "qemu-common.h" =20 #include +#include "exec/cpu-common.h" #include "instrument/control.h" #include "instrument/events.h" #include "instrument/load.h" @@ -109,6 +110,13 @@ InstrLoadError instr_load(const char *path, int argc, = const char **argv, goto err; } =20 + cpu_list_lock(); + CPUState *cpu; + CPU_FOREACH(cpu) { + instr_guest_cpu_enter(cpu); + } + cpu_list_unlock(); + res =3D INSTR_LOAD_OK; goto out; =20 @@ -138,6 +146,7 @@ InstrUnloadError instr_unload(const char *id) } =20 instr_set_event(fini_fn, NULL); + instr_set_event(guest_cpu_enter, NULL); =20 /* this should never fail */ if (dlclose(handle->dlhandle) < 0) { diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/contro= l.h index b841afaa31..f61e7a2b6e 100644 --- a/instrument/qemu-instr/control.h +++ b/instrument/qemu-instr/control.h @@ -16,6 +16,7 @@ extern "C" { =20 #include #include +#include =20 =20 /** @@ -39,6 +40,51 @@ typedef void (*qi_fini_fn)(void *arg); */ void qi_set_fini(qi_fini_fn fn, void *data); =20 + +/* + * Set callbacks for available events. Each event has a short description = and + * various indicators of when it can be triggered: + * + * - Mode :: user + * Triggered in QEMU user application emulation (e.g., linux-user). + * + * - Mode :: softmmy + * Triggered in QEMU full-system emulation. + * + * + * - Targets :: all + * Triggered on all targets, both using TCG or native hardware virtualiz= ation + * (e.g., KVM). + * + * - Targets :: TCG() + * Triggered on the given guest target architectures when executing with= TCG + * (no native hardware virtualization). + * + * + * - Time :: exec + * Triggered when the guest executes the described operation. + * + * - Time :: trans + * Triggered when QEMU translates a guest operation. This is only availa= ble + * when executing with TCG. Guest instructions are decompiled and transl= ated + * into the intermediate TCG language (when "Time: trans" events are + * triggered). Then, the TCG compiler translates TCG code into the nativ= e host + * code that QEMU will execute to emulate the guest (when "Time: exec" e= vents + * are triggered). As QEMU uses a cache of translated code, the same + * instruction might be translated more than once (when the cache overfl= ows). + */ + +/* + * Hot-plug a new virtual (guest) CPU. + * + * Also triggered on each CPU when an instrumentation library is loaded. + * + * Mode: user, softmmu + * Targets: all + * Time: exec + */ +void qi_event_set_guest_cpu_enter(void (*fn)(QICPU vcpu)); + #ifdef __cplusplus } #endif diff --git a/stubs/instrument.c b/stubs/instrument.c index 9498fcdfe5..6b59ba9a7a 100644 --- a/stubs/instrument.c +++ b/stubs/instrument.c @@ -46,3 +46,4 @@ void qmp_instr_unload(const char *id, Error **errp) =20 =20 __thread InstrState instr_cur_state; +void (*instr_event__guest_cpu_enter)(QICPU *vcpu); diff --git a/trace/control-target.c b/trace/control-target.c index 706b2cee9d..f22688bcd5 100644 --- a/trace/control-target.c +++ b/trace/control-target.c @@ -9,6 +9,7 @@ =20 #include "qemu/osdep.h" #include "cpu.h" +#include "instrument/events.h" #include "trace-root.h" #include "trace/control.h" #include "translate-all.h" @@ -146,5 +147,6 @@ void trace_init_vcpu(CPUState *vcpu) } } } + instr_guest_cpu_enter(vcpu); trace_guest_cpu_enter(vcpu); } From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505253316292696.2771966460406; Tue, 12 Sep 2017 14:55:16 -0700 (PDT) Received: from localhost ([::1]:38828 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drt9H-0000Zz-FR for importer@patchew.org; Tue, 12 Sep 2017 17:55:15 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53775) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drt8U-0000CL-N6 for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:54:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drt8R-0003Px-9n for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:54:26 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:39968) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drt8Q-0003Pl-Tj for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:54:23 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CLsJVn022898; Tue, 12 Sep 2017 23:54:19 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 94F592EB; Tue, 12 Sep 2017 23:54:13 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 00:54:12 +0300 Message-Id: <150525325219.15988.2418594999948440514.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CLsJVn022898 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 13/22] instrument: Support synchronous modification of vCPU 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: "Emilio G. Cota" , Markus Armbruster , Stefan Hajnoczi , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Stops all vCPUs to allow performing management operations like TB invalidations. These are later necessary to ensure translated code does not reference unloaded instrumentation libraries. Signed-off-by: Llu=C3=ADs Vilanova --- instrument/control.c | 66 ++++++++++++++++++++++++++++++++++++++++++= ++++ instrument/control.h | 26 ++++++++++++++++++ instrument/control.inc.h | 11 ++++++++ 3 files changed, 103 insertions(+) diff --git a/instrument/control.c b/instrument/control.c index c4b3ca0440..20ddffdc28 100644 --- a/instrument/control.c +++ b/instrument/control.c @@ -13,6 +13,7 @@ #include "instrument/load.h" #include "instrument/qemu-instr/control.h" #include "qemu/compiler.h" +#include "qemu/main-loop.h" #include "qom/cpu.h" =20 =20 @@ -40,6 +41,71 @@ void instr_cpu_remove(CPUState *vcpu) } =20 =20 +static void instr_cpu_stop_all__cb(CPUState *cpu, run_on_cpu_data data) +{ + InstrCPUStop *info =3D data.host_ptr; + /* run posted function */ + if (info->fun) { + info->fun(cpu, info->data); + } +#if !defined(CONFIG_USER_ONLY) + /* signal we're out of the main vCPU loop */ + unsigned int count =3D atomic_load_acquire(&info->count); + atomic_store_release(&info->count, count + 1); + atomic_store_release(&info->stopped, true); + /* wait until we're good to go again */ + qemu_cond_wait(&info->cond, &info->mutex); + count =3D atomic_load_acquire(&info->count); + atomic_store_release(&info->count, count - 1); + qemu_mutex_unlock(&info->mutex); +#endif +} + +void instr_cpu_stop_all_begin(InstrCPUStop *info, + instr_cpu_stop_fun fun, void *data) +{ + CPUState *cpu; + + info->fun =3D fun; + info->data =3D data; + +#if !defined(CONFIG_USER_ONLY) + info->count =3D 0; + qemu_cond_init(&info->cond); + qemu_mutex_init(&info->mutex); + + /* main dispatch loop and run_on_cpu() lock the BQL */ + qemu_mutex_unlock_iothread(); +#endif + + CPU_FOREACH(cpu) { +#if !defined(CONFIG_USER_ONLY) + atomic_store_release(&info->stopped, false); + qemu_mutex_lock(&info->mutex); + async_run_on_cpu(cpu, instr_cpu_stop_all__cb, RUN_ON_CPU_HOST_PTR(= info)); + while (!atomic_load_acquire(&info->stopped)) { + /* wait for vCPU to signal it's stopped */ + } +#else + instr_cpu_stop_all__cb(cpu, RUN_ON_CPU_HOST_PTR(info)); +#endif + } +} + +void instr_cpu_stop_all_end(InstrCPUStop *info) +{ +#if !defined(CONFIG_USER_ONLY) + qemu_cond_broadcast(&info->cond); + while (atomic_load_acquire(&info->count)) { + /* wait for all vCPUs to continue before we can destroy info */ + } + qemu_cond_destroy(&info->cond); + qemu_mutex_destroy(&info->mutex); + qemu_mutex_lock_iothread(); +#endif +} + + qi_fini_fn instr_event__fini_fn; void *instr_event__fini_data; =20 diff --git a/instrument/control.h b/instrument/control.h index 57cea07fa7..03e87b2b8f 100644 --- a/instrument/control.h +++ b/instrument/control.h @@ -46,6 +46,32 @@ static inline QICPU instr_cpu_to_qicpu(CPUState *vcpu); */ static inline CPUState *instr_cpu_from_qicpu(QICPU vcpu); =20 +typedef struct InstrCPUStop InstrCPUStop; +typedef void (*instr_cpu_stop_fun)(CPUState *cpu, void *data); + +/** + * instr_cpu_stop_all_begin: + * @info: Opaque structure describing the operation. + * @fun: Function to run on the context of each vCPU once stopped. + * @data: Pointer to pass to @fun. + * + * Ensure all vCPUs stop executing guest code, and execute @fun on their c= ontext + * in turn. Returns with all vCPUs still stopped. + * + * Assumes cpu_list_lock() and that the QBL is locked before calling. + */ +void instr_cpu_stop_all_begin(InstrCPUStop *info, + instr_cpu_stop_fun fun, void *data); + +/** + * instr_cpu_stop_all_end: + * @info: Opaque structure passed to a previous instr_cpu_stop_all_begin() + * call. + * + * Resume execution on all vCPUs stopped by instr_cpu_stop_all_begin(). + */ +void instr_cpu_stop_all_end(InstrCPUStop *info); + =20 /** * InstrState: diff --git a/instrument/control.inc.h b/instrument/control.inc.h index 45daae7d1d..6d65b23ead 100644 --- a/instrument/control.inc.h +++ b/instrument/control.inc.h @@ -15,6 +15,17 @@ #include =20 =20 +struct InstrCPUStop { + instr_cpu_stop_fun fun; + void *data; +#if !defined(CONFIG_USER_ONLY) + bool stopped; + unsigned int count; + QemuCond cond; + QemuMutex mutex; +#endif +}; + extern unsigned int instr_cpus_count; extern CPUState **instr_cpus; =20 From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505253557724901.0322481326948; Tue, 12 Sep 2017 14:59:17 -0700 (PDT) Received: from localhost ([::1]:38842 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtDA-0002Y3-OT for importer@patchew.org; Tue, 12 Sep 2017 17:59:16 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55881) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtCO-00020A-IZ for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:58:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drtCL-0005pl-Rv for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:58:28 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:42590) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtCL-0005pB-Gf for qemu-devel@nongnu.org; Tue, 12 Sep 2017 17:58:25 -0400 Received: from correu-2.ac.upc.es (correu-2.ac.upc.es [147.83.30.92]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CLwLPF022977; Tue, 12 Sep 2017 23:58:21 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id AC45D25B; Tue, 12 Sep 2017 23:58:15 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 00:58:14 +0300 Message-Id: <150525349438.15988.10881535098471062952.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CLwLPF022977 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 14/22] exec: Add function to synchronously flush TB on a stopped vCPU 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: Peter Crosthwaite , Markus Armbruster , "Emilio G. Cota" , Stefan Hajnoczi , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- accel/stubs/tcg-stub.c | 3 +++ accel/tcg/translate-all.c | 7 +++++++ include/exec/exec-all.h | 1 + 3 files changed, 11 insertions(+) diff --git a/accel/stubs/tcg-stub.c b/accel/stubs/tcg-stub.c index 5dd480b1a2..5226c4a8a4 100644 --- a/accel/stubs/tcg-stub.c +++ b/accel/stubs/tcg-stub.c @@ -20,3 +20,6 @@ void tb_flush(CPUState *cpu) { } +void tb_flush_sync(CPUState *cpu) +{ +} diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 2d1ed06065..a334ac4ccb 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -929,6 +929,13 @@ done: tb_unlock(); } =20 +void tb_flush_sync(CPUState *cpu) +{ + unsigned tb_flush_count =3D atomic_mb_read(&tcg_ctx.tb_ctx.tb_flush_co= unt); + assert(cpu =3D=3D current_cpu); + do_tb_flush(cpu, RUN_ON_CPU_HOST_INT(tb_flush_count)); +} + void tb_flush(CPUState *cpu) { if (tcg_enabled()) { diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 673fc066d0..3f38186a5e 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -358,6 +358,7 @@ struct TranslationBlock { =20 void tb_free(TranslationBlock *tb); void tb_flush(CPUState *cpu); +void tb_flush_sync(CPUState *cpu); void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr); TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc, target_ulong cs_base, uint32_t flags); From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505253801631415.85020479022546; Tue, 12 Sep 2017 15:03:21 -0700 (PDT) Received: from localhost ([::1]:38875 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtH7-0005Yp-05 for importer@patchew.org; Tue, 12 Sep 2017 18:03:21 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58949) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtGI-00055S-VY for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:02:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drtGG-0000Iu-6H for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:02:31 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:43378) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtGF-0000I2-NR for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:02:28 -0400 Received: from correu-2.ac.upc.es (correu-2.ac.upc.es [147.83.30.92]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CM2NdL023099; Wed, 13 Sep 2017 00:02:23 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id F051E840; Wed, 13 Sep 2017 00:02:17 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 01:02:16 +0300 Message-Id: <150525373641.15988.12142967916976724761.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CM2NdL023099 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 15/22] instrument: Add event 'guest_cpu_exit' 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: Markus Armbruster , "Emilio G. Cota" , Stefan Hajnoczi , Paolo Bonzini , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- instrument/control.c | 9 +++++++++ instrument/events.h | 3 +++ instrument/events.inc.h | 11 +++++++++++ instrument/load.c | 17 +++++++++++++++++ instrument/qemu-instr/control.h | 11 +++++++++++ stubs/instrument.c | 1 + trace/control.c | 4 +++- 7 files changed, 55 insertions(+), 1 deletion(-) diff --git a/instrument/control.c b/instrument/control.c index 20ddffdc28..0be8065409 100644 --- a/instrument/control.c +++ b/instrument/control.c @@ -124,3 +124,12 @@ SYM_PUBLIC void qi_event_set_guest_cpu_enter(void (*fn= )(QICPU vcpu)) ERROR_IF(!instr_get_state(), "called outside instrumentation"); instr_set_event(guest_cpu_enter, fn); } + + +void (*instr_event__guest_cpu_exit)(QICPU vcpu); + +SYM_PUBLIC void qi_event_set_guest_cpu_exit(void (*fn)(QICPU vcpu)) +{ + ERROR_IF(!instr_get_state(), "called outside instrumentation"); + instr_set_event(guest_cpu_exit, fn); +} diff --git a/instrument/events.h b/instrument/events.h index 947f120aa9..c743cb8180 100644 --- a/instrument/events.h +++ b/instrument/events.h @@ -36,6 +36,9 @@ extern void *instr_event__fini_data; extern void (*instr_event__guest_cpu_enter)(QICPU vcpu); static inline void instr_guest_cpu_enter(CPUState *vcpu); =20 +extern void (*instr_event__guest_cpu_exit)(QICPU vcpu); +static inline void instr_guest_cpu_exit(CPUState *vcpu); + =20 #include "instrument/events.inc.h" =20 diff --git a/instrument/events.inc.h b/instrument/events.inc.h index e3f8024716..c88df7e42f 100644 --- a/instrument/events.inc.h +++ b/instrument/events.inc.h @@ -20,3 +20,14 @@ static inline void instr_guest_cpu_enter(CPUState *vcpu) instr_set_state(INSTR_STATE_DISABLE); } } + +static inline void instr_guest_cpu_exit(CPUState *vcpu) +{ + void (*cb)(QICPU vcpu) =3D instr_get_event(guest_cpu_exit); + if (cb) { + QICPU vcpu_ =3D instr_cpu_to_qicpu(vcpu); + instr_set_state(INSTR_STATE_ENABLE); + (*cb)(vcpu_); + instr_set_state(INSTR_STATE_DISABLE); + } +} diff --git a/instrument/load.c b/instrument/load.c index 218bca74b2..6808d361b5 100644 --- a/instrument/load.c +++ b/instrument/load.c @@ -11,7 +11,9 @@ #include "qemu-common.h" =20 #include +#include "cpu.h" #include "exec/cpu-common.h" +#include "exec/exec-all.h" #include "instrument/control.h" #include "instrument/events.h" #include "instrument/load.h" @@ -127,6 +129,13 @@ out: return res; } =20 + +static void instr_unload__cb(CPUState *cpu, void *data) +{ + tb_flush_sync(cpu); + instr_guest_cpu_exit(cpu); +} + InstrUnloadError instr_unload(const char *id) { InstrUnloadError res; @@ -139,6 +148,10 @@ InstrUnloadError instr_unload(const char *id) goto out; } =20 + InstrCPUStop info; + cpu_list_lock(); + instr_cpu_stop_all_begin(&info, instr_unload__cb, NULL); + qi_fini_fn fini_fn =3D instr_get_event(fini_fn); if (fini_fn) { void *fini_data =3D instr_get_event(fini_data); @@ -147,6 +160,10 @@ InstrUnloadError instr_unload(const char *id) =20 instr_set_event(fini_fn, NULL); instr_set_event(guest_cpu_enter, NULL); + instr_set_event(guest_cpu_exit, NULL); + + instr_cpu_stop_all_end(&info); + cpu_list_unlock(); =20 /* this should never fail */ if (dlclose(handle->dlhandle) < 0) { diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/contro= l.h index f61e7a2b6e..107ee8afe0 100644 --- a/instrument/qemu-instr/control.h +++ b/instrument/qemu-instr/control.h @@ -85,6 +85,17 @@ void qi_set_fini(qi_fini_fn fn, void *data); */ void qi_event_set_guest_cpu_enter(void (*fn)(QICPU vcpu)); =20 +/* + * Hot-unplug a virtual (guest) CPU. + * + * Also triggered on each CPU when an instrumentation library is unloaded. + * + * Mode: user, softmmu + * Targets: all + * Time: exec + */ +void qi_event_set_guest_cpu_exit(void (*fn)(QICPU vcpu)); + #ifdef __cplusplus } #endif diff --git a/stubs/instrument.c b/stubs/instrument.c index 6b59ba9a7a..c4b1c791d9 100644 --- a/stubs/instrument.c +++ b/stubs/instrument.c @@ -47,3 +47,4 @@ void qmp_instr_unload(const char *id, Error **errp) =20 __thread InstrState instr_cur_state; void (*instr_event__guest_cpu_enter)(QICPU *vcpu); +void (*instr_event__guest_cpu_exit)(QICPU *vcpu); diff --git a/trace/control.c b/trace/control.c index 82d8989c4d..946a0af818 100644 --- a/trace/control.c +++ b/trace/control.c @@ -1,13 +1,14 @@ /* * Interface for configuring and controlling the state of tracing events. * - * Copyright (C) 2011-2016 Llu=C3=ADs Vilanova + * Copyright (C) 2011-2017 Llu=C3=ADs Vilanova * * This work is licensed under the terms of the GNU GPL, version 2 or late= r. * See the COPYING file in the top-level directory. */ =20 #include "qemu/osdep.h" +#include "instrument/events.h" #include "trace/control.h" #include "qemu/help_option.h" #ifdef CONFIG_TRACE_SIMPLE @@ -272,6 +273,7 @@ void trace_fini_vcpu(CPUState *vcpu) TraceEventIter iter; TraceEvent *ev; =20 + instr_guest_cpu_exit(vcpu); trace_guest_cpu_exit(vcpu); =20 trace_event_iter_init(&iter, NULL); From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505254086400988.0976953379932; Tue, 12 Sep 2017 15:08:06 -0700 (PDT) Received: from localhost ([::1]:38894 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtLh-0007m4-5m for importer@patchew.org; Tue, 12 Sep 2017 18:08:05 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:32968) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtKC-0006n2-IU for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:06:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drtK9-0004cX-MY for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:06:32 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:43396) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtK9-0004bm-Bp for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:06:29 -0400 Received: from correu-2.ac.upc.es (correu-2.ac.upc.es [147.83.30.92]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CM6PWe023215; Wed, 13 Sep 2017 00:06:25 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id 2E2A544C; Wed, 13 Sep 2017 00:06:20 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 01:06:18 +0300 Message-Id: <150525397866.15988.17518293933244872138.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CM6PWe023215 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 16/22] instrument: Add event 'guest_cpu_reset' 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: Markus Armbruster , "Emilio G. Cota" , Stefan Hajnoczi , Paolo Bonzini , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- instrument/control.c | 9 +++++++++ instrument/events.h | 3 +++ instrument/events.inc.h | 11 +++++++++++ instrument/load.c | 1 + instrument/qemu-instr/control.h | 9 +++++++++ qom/cpu.c | 2 ++ stubs/instrument.c | 1 + 7 files changed, 36 insertions(+) diff --git a/instrument/control.c b/instrument/control.c index 0be8065409..401189db2e 100644 --- a/instrument/control.c +++ b/instrument/control.c @@ -133,3 +133,12 @@ SYM_PUBLIC void qi_event_set_guest_cpu_exit(void (*fn)= (QICPU vcpu)) ERROR_IF(!instr_get_state(), "called outside instrumentation"); instr_set_event(guest_cpu_exit, fn); } + + +void (*instr_event__guest_cpu_reset)(QICPU vcpu); + +SYM_PUBLIC void qi_event_set_guest_cpu_reset(void (*fn)(QICPU vcpu)) +{ + ERROR_IF(!instr_get_state(), "called outside instrumentation"); + instr_set_event(guest_cpu_reset, fn); +} diff --git a/instrument/events.h b/instrument/events.h index c743cb8180..4a0560490a 100644 --- a/instrument/events.h +++ b/instrument/events.h @@ -39,6 +39,9 @@ static inline void instr_guest_cpu_enter(CPUState *vcpu); extern void (*instr_event__guest_cpu_exit)(QICPU vcpu); static inline void instr_guest_cpu_exit(CPUState *vcpu); =20 +extern void (*instr_event__guest_cpu_reset)(QICPU vcpu); +static inline void instr_guest_cpu_reset(CPUState *vcpu); + =20 #include "instrument/events.inc.h" =20 diff --git a/instrument/events.inc.h b/instrument/events.inc.h index c88df7e42f..a126ba5ae6 100644 --- a/instrument/events.inc.h +++ b/instrument/events.inc.h @@ -31,3 +31,14 @@ static inline void instr_guest_cpu_exit(CPUState *vcpu) instr_set_state(INSTR_STATE_DISABLE); } } + +static inline void instr_guest_cpu_reset(CPUState *vcpu) +{ + void (*cb)(QICPU vcpu) =3D instr_get_event(guest_cpu_reset); + if (cb) { + QICPU vcpu_ =3D instr_cpu_to_qicpu(vcpu); + instr_set_state(INSTR_STATE_ENABLE); + (*cb)(vcpu_); + instr_set_state(INSTR_STATE_DISABLE); + } +} diff --git a/instrument/load.c b/instrument/load.c index 6808d361b5..8c15a73a8c 100644 --- a/instrument/load.c +++ b/instrument/load.c @@ -161,6 +161,7 @@ InstrUnloadError instr_unload(const char *id) instr_set_event(fini_fn, NULL); instr_set_event(guest_cpu_enter, NULL); instr_set_event(guest_cpu_exit, NULL); + instr_set_event(guest_cpu_reset, NULL); =20 instr_cpu_stop_all_end(&info); cpu_list_unlock(); diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/contro= l.h index 107ee8afe0..322009100d 100644 --- a/instrument/qemu-instr/control.h +++ b/instrument/qemu-instr/control.h @@ -96,6 +96,15 @@ void qi_event_set_guest_cpu_enter(void (*fn)(QICPU vcpu)= ); */ void qi_event_set_guest_cpu_exit(void (*fn)(QICPU vcpu)); =20 +/* + * Reset the state of a virtual (guest) CPU. + * + * Mode: user, softmmu + * Targets: all + * Time: exec + */ +void qi_event_set_guest_cpu_reset(void (*fn)(QICPU vcpu)); + #ifdef __cplusplus } #endif diff --git a/qom/cpu.c b/qom/cpu.c index dc5392dbeb..6336d63f66 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -19,6 +19,7 @@ */ =20 #include "qemu/osdep.h" +#include "instrument/events.h" #include "qapi/error.h" #include "qemu-common.h" #include "qom/cpu.h" @@ -275,6 +276,7 @@ void cpu_reset(CPUState *cpu) (*klass->reset)(cpu); } =20 + instr_guest_cpu_reset(cpu); trace_guest_cpu_reset(cpu); } =20 diff --git a/stubs/instrument.c b/stubs/instrument.c index c4b1c791d9..dda2ae88c5 100644 --- a/stubs/instrument.c +++ b/stubs/instrument.c @@ -48,3 +48,4 @@ void qmp_instr_unload(const char *id, Error **errp) __thread InstrState instr_cur_state; void (*instr_event__guest_cpu_enter)(QICPU *vcpu); void (*instr_event__guest_cpu_exit)(QICPU *vcpu); +void (*instr_event__guest_cpu_reset)(QICPU *vcpu); From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505254289560549.6768970020609; Tue, 12 Sep 2017 15:11:29 -0700 (PDT) Received: from localhost ([::1]:38913 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtOx-0000sU-KH for importer@patchew.org; Tue, 12 Sep 2017 18:11:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35586) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtO9-0000Yy-FL for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:10:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drtO4-0000xE-Um for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:10:37 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:59075) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtO4-0000vx-E1 for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:10:32 -0400 Received: from correu-2.ac.upc.es (correu-2.ac.upc.es [147.83.30.92]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CMARoI023282; Wed, 13 Sep 2017 00:10:27 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id 510F9840; Wed, 13 Sep 2017 00:10:22 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 01:10:21 +0300 Message-Id: <150525422092.15988.17756255976389655875.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CMARoI023282 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 17/22] trace: Introduce a proper structure to describe memory accesses 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: Peter Crosthwaite , Markus Armbruster , "Emilio G. Cota" , Stefan Hajnoczi , Paolo Bonzini , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- include/exec/cpu_ldst_template.h | 15 ++++++-------- include/exec/cpu_ldst_useronly_template.h | 15 ++++++-------- tcg/tcg-op.c | 22 +++++++++++++-------- trace/mem-internal.h | 22 ++++++++++++--------- trace/mem.h | 31 +++++++++++++++++++++++++= ---- 5 files changed, 66 insertions(+), 39 deletions(-) diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_templ= ate.h index 4db2302962..debbabcfb2 100644 --- a/include/exec/cpu_ldst_template.h +++ b/include/exec/cpu_ldst_template.h @@ -88,9 +88,8 @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArch= State *env, TCGMemOpIdx oi; =20 #if !defined(SOFTMMU_CODE_ACCESS) - trace_guest_mem_before_exec( - ENV_GET_CPU(env), ptr, - trace_mem_build_info(SHIFT, false, MO_TE, false)); + TraceMemInfo meminfo =3D trace_mem_build_info(SHIFT, false, MO_TE, fal= se); + trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw); #endif =20 addr =3D ptr; @@ -126,9 +125,8 @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUAr= chState *env, TCGMemOpIdx oi; =20 #if !defined(SOFTMMU_CODE_ACCESS) - trace_guest_mem_before_exec( - ENV_GET_CPU(env), ptr, - trace_mem_build_info(SHIFT, true, MO_TE, false)); + TraceMemInfo meminfo =3D trace_mem_build_info(SHIFT, true, MO_TE, fals= e); + trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw); #endif =20 addr =3D ptr; @@ -168,9 +166,8 @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArc= hState *env, TCGMemOpIdx oi; =20 #if !defined(SOFTMMU_CODE_ACCESS) - trace_guest_mem_before_exec( - ENV_GET_CPU(env), ptr, - trace_mem_build_info(SHIFT, false, MO_TE, true)); + TraceMemInfo meminfo =3D trace_mem_build_info(SHIFT, false, MO_TE, tru= e); + trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw); #endif =20 addr =3D ptr; diff --git a/include/exec/cpu_ldst_useronly_template.h b/include/exec/cpu_l= dst_useronly_template.h index 7b8c7c506e..b0b3fc1b8d 100644 --- a/include/exec/cpu_ldst_useronly_template.h +++ b/include/exec/cpu_ldst_useronly_template.h @@ -61,9 +61,8 @@ static inline RES_TYPE glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) { #if !defined(CODE_ACCESS) - trace_guest_mem_before_exec( - ENV_GET_CPU(env), ptr, - trace_mem_build_info(DATA_SIZE, false, MO_TE, false)); + TraceMemInfo meminfo =3D trace_mem_build_info(DATA_SIZE, false, MO_TE,= false); + trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw); #endif return glue(glue(ld, USUFFIX), _p)(g2h(ptr)); } @@ -81,9 +80,8 @@ static inline int glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) { #if !defined(CODE_ACCESS) - trace_guest_mem_before_exec( - ENV_GET_CPU(env), ptr, - trace_mem_build_info(DATA_SIZE, true, MO_TE, false)); + TraceMemInfo meminfo =3D trace_mem_build_info(DATA_SIZE, true, MO_TE, = false); + trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw); #endif return glue(glue(lds, SUFFIX), _p)(g2h(ptr)); } @@ -103,9 +101,8 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env= , target_ulong ptr, RES_TYPE v) { #if !defined(CODE_ACCESS) - trace_guest_mem_before_exec( - ENV_GET_CPU(env), ptr, - trace_mem_build_info(DATA_SIZE, false, MO_TE, true)); + TraceMemInfo meminfo =3D trace_mem_build_info(DATA_SIZE, false, MO_TE,= true); + trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw); #endif glue(glue(st, SUFFIX), _p)(g2h(ptr), v); } diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c index 688d91755b..6edf70bdfc 100644 --- a/tcg/tcg-op.c +++ b/tcg/tcg-op.c @@ -2676,24 +2676,28 @@ static void tcg_gen_req_mo(TCGBar type) =20 void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp mem= op) { + TraceMemInfo meminfo; tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD); memop =3D tcg_canonicalize_memop(memop, 0, 0); - trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, - addr, trace_mem_get_info(memop, 0)); + meminfo =3D trace_mem_get_info(memop, 0); + trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, addr, meminfo= .raw); gen_ldst_i32(INDEX_op_qemu_ld_i32, val, addr, memop, idx); } =20 void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp mem= op) { + TraceMemInfo meminfo; tcg_gen_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST); memop =3D tcg_canonicalize_memop(memop, 0, 1); - trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, - addr, trace_mem_get_info(memop, 1)); + meminfo =3D trace_mem_get_info(memop, 1); + trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, addr, meminfo= .raw); gen_ldst_i32(INDEX_op_qemu_st_i32, val, addr, memop, idx); } =20 void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp mem= op) { + TraceMemInfo meminfo; + tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD); if (TCG_TARGET_REG_BITS =3D=3D 32 && (memop & MO_SIZE) < MO_64) { tcg_gen_qemu_ld_i32(TCGV_LOW(val), addr, idx, memop); @@ -2706,13 +2710,15 @@ void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, T= CGArg idx, TCGMemOp memop) } =20 memop =3D tcg_canonicalize_memop(memop, 1, 0); - trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, - addr, trace_mem_get_info(memop, 0)); + meminfo =3D trace_mem_get_info(memop, 0); + trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, addr, meminfo= .raw); gen_ldst_i64(INDEX_op_qemu_ld_i64, val, addr, memop, idx); } =20 void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp mem= op) { + TraceMemInfo meminfo; + tcg_gen_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST); if (TCG_TARGET_REG_BITS =3D=3D 32 && (memop & MO_SIZE) < MO_64) { tcg_gen_qemu_st_i32(TCGV_LOW(val), addr, idx, memop); @@ -2720,8 +2726,8 @@ void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCG= Arg idx, TCGMemOp memop) } =20 memop =3D tcg_canonicalize_memop(memop, 1, 1); - trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, - addr, trace_mem_get_info(memop, 1)); + meminfo =3D trace_mem_get_info(memop, 1); + trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, addr, meminfo= .raw); gen_ldst_i64(INDEX_op_qemu_st_i64, val, addr, memop, idx); } =20 diff --git a/trace/mem-internal.h b/trace/mem-internal.h index ddda934253..b77079527f 100644 --- a/trace/mem-internal.h +++ b/trace/mem-internal.h @@ -1,7 +1,7 @@ /* * Helper functions for guest memory tracing * - * Copyright (C) 2016 Llu=C3=ADs Vilanova + * Copyright (C) 2016-2017 Llu=C3=ADs Vilanova * * This work is licensed under the terms of the GNU GPL, version 2 or late= r. * See the COPYING file in the top-level directory. @@ -10,8 +10,9 @@ #ifndef TRACE__MEM_INTERNAL_H #define TRACE__MEM_INTERNAL_H =20 -static inline uint8_t trace_mem_get_info(TCGMemOp op, bool store) +static inline TraceMemInfo trace_mem_get_info(TCGMemOp op, bool store) { + TraceMemInfo res_; uint8_t res =3D op; bool be =3D (op & MO_BSWAP) =3D=3D MO_BE; =20 @@ -27,19 +28,22 @@ static inline uint8_t trace_mem_get_info(TCGMemOp op, b= ool store) res |=3D 1ULL << 4; } =20 - return res; + res_.raw =3D res; + return res_; } =20 -static inline uint8_t trace_mem_build_info( +static inline TraceMemInfo trace_mem_build_info( TCGMemOp size, bool sign_extend, TCGMemOp endianness, bool store) { - uint8_t res =3D 0; - res |=3D size; - res |=3D (sign_extend << 2); + TraceMemInfo res; + res.size_shift =3D size; + res.sign_extend =3D sign_extend; if (endianness =3D=3D MO_BE) { - res |=3D (1ULL << 3); + res.endianness =3D 1; + } else { + res.endianness =3D 0; } - res |=3D (store << 4); + res.store =3D store; return res; } =20 diff --git a/trace/mem.h b/trace/mem.h index 9c88bcb4e6..9866b41401 100644 --- a/trace/mem.h +++ b/trace/mem.h @@ -1,7 +1,7 @@ /* * Helper functions for guest memory tracing * - * Copyright (C) 2016 Llu=C3=ADs Vilanova + * Copyright (C) 2016-2017 Llu=C3=ADs Vilanova * * This work is licensed under the terms of the GNU GPL, version 2 or late= r. * See the COPYING file in the top-level directory. @@ -12,21 +12,44 @@ =20 #include "tcg/tcg.h" =20 +/** + * TraceMemInfo: + * @size_shift: Memoy access size, interpreted as "1 << size_shift" bytes. + * @sign_extend: Whether the access is sign-extended. + * @endianness: Endinness type (0: little, 1: big). + * @store: Whether it's a store operation. + * + * Memory access information. + * + * NOTE: Keep in sync with QIMemInfo. + */ +typedef struct TraceMemInfo { + union { + struct { + uint8_t size_shift : 2; + bool sign_extend: 1; + uint8_t endianness : 1; + bool store : 1; + }; + uint8_t raw; + }; +} TraceMemInfo; + =20 /** * trace_mem_get_info: * * Return a value for the 'info' argument in guest memory access traces. */ -static uint8_t trace_mem_get_info(TCGMemOp op, bool store); +static TraceMemInfo trace_mem_get_info(TCGMemOp op, bool store); =20 /** * trace_mem_build_info: * * Return a value for the 'info' argument in guest memory access traces. */ -static uint8_t trace_mem_build_info(TCGMemOp size, bool sign_extend, - TCGMemOp endianness, bool store); +static TraceMemInfo trace_mem_build_info(TCGMemOp size, bool sign_extend, + TCGMemOp endianness, bool store); =20 =20 #include "trace/mem-internal.h" From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505254590788983.2346159951235; Tue, 12 Sep 2017 15:16:30 -0700 (PDT) Received: from localhost ([::1]:38940 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtTo-0004Gh-OI for importer@patchew.org; Tue, 12 Sep 2017 18:16:28 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41623) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtS6-0002oA-0C for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:14:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drtRz-0005TV-LM for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:14:41 -0400 Received: from roura.ac.upc.edu ([147.83.33.10]:42609 helo=roura.ac.upc.es) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtRy-0005Qf-VM for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:14:35 -0400 Received: from correu-2.ac.upc.es (correu-2.ac.upc.es [147.83.30.92]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CMEUJ1023389; Wed, 13 Sep 2017 00:14:30 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id AB8CE2F0; Wed, 13 Sep 2017 00:14:24 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 01:14:23 +0300 Message-Id: <150525446311.15988.14180809542310825210.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CMEUJ1023389 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 18/22] instrument: Add event 'guest_mem_before_trans' 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: Markus Armbruster , "Emilio G. Cota" , Stefan Hajnoczi , Paolo Bonzini , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- Makefile.target | 1 + instrument/control.c | 15 +++++++++ instrument/control.h | 36 +++++++++++++++++++++- instrument/control.inc.h | 16 +++++++--- instrument/events.h | 21 +++++++++++++ instrument/events.inc.h | 20 ++++++++++++ instrument/load.c | 1 + instrument/qemu-instr/control.h | 16 ++++++++++ instrument/qemu-instr/types.h | 64 +++++++++++++++++++++++++++++++++++= ++++ stubs/instrument.c | 4 ++ tcg/tcg-op.c | 5 +++ trace/control.h | 23 ++++++++++++++ trace/mem.h | 23 -------------- 13 files changed, 214 insertions(+), 31 deletions(-) diff --git a/Makefile.target b/Makefile.target index 7f42c45db8..6997b921c9 100644 --- a/Makefile.target +++ b/Makefile.target @@ -196,6 +196,7 @@ $(QEMU_PROG_BUILD): config-devices.mak COMMON_LDADDS =3D ../libqemuutil.a ../libqemustub.a =20 # build either PROG or PROGW +$(QEMU_PROG_BUILD): CFLAGS +=3D -DQEMU_TARGET_BUILD=3D1 $(QEMU_PROG_BUILD): $(all-obj-y) $(COMMON_LDADDS) $(call LINK, $(filter-out %.mak, $^)) ifdef CONFIG_DARWIN diff --git a/instrument/control.c b/instrument/control.c index 401189db2e..0424dd57ab 100644 --- a/instrument/control.c +++ b/instrument/control.c @@ -17,7 +17,7 @@ #include "qom/cpu.h" =20 =20 -__thread InstrState instr_cur_state; +__thread InstrInfo instr_cur_info; =20 =20 unsigned int instr_cpus_count; @@ -142,3 +142,16 @@ SYM_PUBLIC void qi_event_set_guest_cpu_reset(void (*fn= )(QICPU vcpu)) ERROR_IF(!instr_get_state(), "called outside instrumentation"); instr_set_event(guest_cpu_reset, fn); } + + +void (*instr_event__guest_mem_before_trans)( + QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMemInfo info); + +SYM_PUBLIC void qi_event_set_guest_mem_before_trans( + void (*fn)(QICPU vcpu_trans, QITCGv_cpu vcpu_exec, + QITCGv vaddr, QIMemInfo info)) +{ + ERROR_IF(!instr_get_state(), "called outside instrumentation"); + ERROR_IF(!tcg_enabled(), "called without TCG"); + instr_set_event(guest_mem_before_trans, fn); +} diff --git a/instrument/control.h b/instrument/control.h index 03e87b2b8f..3e44702f75 100644 --- a/instrument/control.h +++ b/instrument/control.h @@ -86,12 +86,21 @@ typedef enum { INSTR_STATE_ENABLE, } InstrState; =20 +#define INSTR_MAX_TCG_REGS 16 + +typedef struct InstrInfo { + InstrState state; + unsigned int max; + void *tcg_regs[INSTR_MAX_TCG_REGS]; +} InstrInfo; + /** * instr_set_state: * - * Set the instrumentation state of the current host thread. + * Set the instrumentation state of the current host thread, and return its + * #InstrInfo. */ -static inline void instr_set_state(InstrState state); +static inline InstrInfo *instr_set_state(InstrState state); =20 /** * instr_get_state: @@ -100,6 +109,29 @@ static inline void instr_set_state(InstrState state); */ static inline InstrState instr_get_state(void); =20 +/** + * instr_tcg_to_qitcg: + * @info: Pointer to #InstrInfo. + * @num: Number of TCG register used by instrumentation. + * @arg: TCG register. + * + * Get a suitable QITCGv* from a TCGv* value. + */ +#define instr_tcg_to_qitcg(info, num, arg) \ + ({ \ + info->tcg_regs[num] =3D arg; \ + (void *)num; \ + }) + +/** + * instr_tcg_count: + * @info: Pointer to #InstrInfo. + * @count: Number of TCG registers used by instrumentation. + * + * Set the number of TCG registers used by instrumentation. + */ +static inline void instr_tcg_count(InstrInfo *info, unsigned int count); + =20 #include "instrument/control.inc.h" =20 diff --git a/instrument/control.inc.h b/instrument/control.inc.h index 6d65b23ead..3eba9b7c85 100644 --- a/instrument/control.inc.h +++ b/instrument/control.inc.h @@ -46,14 +46,22 @@ static inline CPUState *instr_cpu_from_qicpu(QICPU vcpu) } =20 =20 -extern __thread InstrState instr_cur_state; +extern __thread InstrInfo instr_cur_info; =20 -static inline void instr_set_state(InstrState state) +static inline InstrInfo *instr_set_state(InstrState state) { - atomic_store_release(&instr_cur_state, state); + InstrInfo *info =3D &instr_cur_info; + atomic_store_release(&info->state, state); + return info; } =20 static inline InstrState instr_get_state(void) { - return atomic_load_acquire(&instr_cur_state); + return atomic_load_acquire(&instr_cur_info.state); +} + + +static inline void instr_tcg_count(InstrInfo *info, unsigned int count) +{ + info->max =3D count; } diff --git a/instrument/events.h b/instrument/events.h index 4a0560490a..1cc4dbb052 100644 --- a/instrument/events.h +++ b/instrument/events.h @@ -12,6 +12,8 @@ =20 #include "instrument/qemu-instr/control.h" #include "instrument/qemu-instr/types.h" +#include "trace/control.h" + =20 /** * instr_get_event: @@ -30,6 +32,20 @@ atomic_store_release(&instr_event__ ## name, fn) =20 =20 +/* + * Re-define types used by some instrumentation events. We need some arbit= rary + * definition for non-target objects. + */ +#if defined(QEMU_TARGET_BUILD) +#include "tcg/tcg.h" +#else +typedef struct TCGv_d *TCGv; +typedef struct TCGv_env_d *TCGv_env; +typedef struct TCGv_i32_d *TCGv_i32; +typedef struct TCGv_i64_d *TCGv_i64; +#endif + + extern qi_fini_fn instr_event__fini_fn; extern void *instr_event__fini_data; =20 @@ -42,6 +58,11 @@ static inline void instr_guest_cpu_exit(CPUState *vcpu); extern void (*instr_event__guest_cpu_reset)(QICPU vcpu); static inline void instr_guest_cpu_reset(CPUState *vcpu); =20 +extern void (*instr_event__guest_mem_before_trans)( + QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMemInfo info); +static inline void instr_guest_mem_before_trans( + CPUState *vcpu_trans, TCGv_env vcpu_exec, TCGv vaddr, TraceMemInfo inf= o); + =20 #include "instrument/events.inc.h" =20 diff --git a/instrument/events.inc.h b/instrument/events.inc.h index a126ba5ae6..365c715db4 100644 --- a/instrument/events.inc.h +++ b/instrument/events.inc.h @@ -8,6 +8,7 @@ */ =20 #include "instrument/control.h" +#include "trace/control.h" =20 =20 static inline void instr_guest_cpu_enter(CPUState *vcpu) @@ -42,3 +43,22 @@ static inline void instr_guest_cpu_reset(CPUState *vcpu) instr_set_state(INSTR_STATE_DISABLE); } } + +static inline void instr_guest_mem_before_trans( + CPUState *vcpu_trans, TCGv_env vcpu_exec, TCGv vaddr, TraceMemInfo inf= o) +{ + void (*cb)(QICPU vcpu_trans, QITCGv_cpu vcpu_exec, + QITCGv vaddr, QIMemInfo info) + =3D instr_get_event(guest_mem_before_trans); + if (cb) { + InstrInfo *iinfo =3D instr_set_state(INSTR_STATE_ENABLE); + QICPU vcpu_trans_ =3D instr_cpu_to_qicpu(vcpu_trans); + QITCGv_cpu vcpu_exec_ =3D instr_tcg_to_qitcg(iinfo, 0, vcpu_exec); + QITCGv vaddr_ =3D instr_tcg_to_qitcg(iinfo, 1, vaddr); + QIMemInfo info_; + info_.raw =3D info.raw; + instr_tcg_count(iinfo, 2); + (*cb)(vcpu_trans_, vcpu_exec_, vaddr_, info_); + instr_set_state(INSTR_STATE_DISABLE); + } +} diff --git a/instrument/load.c b/instrument/load.c index 8c15a73a8c..e8f869201b 100644 --- a/instrument/load.c +++ b/instrument/load.c @@ -162,6 +162,7 @@ InstrUnloadError instr_unload(const char *id) instr_set_event(guest_cpu_enter, NULL); instr_set_event(guest_cpu_exit, NULL); instr_set_event(guest_cpu_reset, NULL); + instr_set_event(guest_mem_before_trans, NULL); =20 instr_cpu_stop_all_end(&info); cpu_list_unlock(); diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/contro= l.h index 322009100d..c3c8c3988d 100644 --- a/instrument/qemu-instr/control.h +++ b/instrument/qemu-instr/control.h @@ -105,6 +105,22 @@ void qi_event_set_guest_cpu_exit(void (*fn)(QICPU vcpu= )); */ void qi_event_set_guest_cpu_reset(void (*fn)(QICPU vcpu)); =20 +/* + * Start virtual memory access (before any potential access violation). + * + * @vaddr: Access' virtual address. + * @info : Access' information. + * + * Does not include memory accesses performed by devices. + * + * Mode: user, softmmu + * Targets: TCG(all) + * Time: trans + */ +void qi_event_set_guest_mem_before_trans( + void (*fn)(QICPU vcpu_trans, QITCGv_cpu vcpu_exec, + QITCGv vaddr, QIMemInfo info)); + #ifdef __cplusplus } #endif diff --git a/instrument/qemu-instr/types.h b/instrument/qemu-instr/types.h index ea3a032b4f..11cbe1ccaa 100644 --- a/instrument/qemu-instr/types.h +++ b/instrument/qemu-instr/types.h @@ -14,10 +14,18 @@ extern "C" { #endif =20 +#include +#include + + /** * SECTION: types * @section_id: qi-types * @title: Common types + * + * Data of architecture-specific length is always passed as an #int64_t to + * provide binary compatibility between the instrumentation library and QE= MU, + * regardless of the guest architecture being instrumented. */ =20 /** @@ -41,6 +49,62 @@ typedef struct QITraceEventIter QITraceEventIter; */ typedef struct QICPU_d *QICPU; =20 +/** + * QIMemInfo: + * @size_shift: Memoy access size, interpreted as "1 << size_shift" bytes. + * @sign_extend: Whether the access is sign-extended. + * @endianness: Endianness type (0: little, 1: big). + * @store: Whether it's a store operation. + * + * Memory access information. + */ +typedef struct QIMemInfo { + union { + struct { + uint8_t size_shift : 2; + bool sign_extend: 1; + uint8_t endianness : 1; + bool store : 1; + }; + uint8_t raw; + }; +} QIMemInfo; + +/** + * QITCGv_cpu: + * + * TCG register with QICPU. + */ +typedef struct QITCGv_cpu_d *QITCGv_cpu; + +/** + * QITCGv: + * + * TCG register with data of architecture-specific length. + */ +typedef struct QITCGv_d *QITCGv; + +/** + * QITCGv_i32: + * + * TCG register with 32-bit data. + */ +typedef struct QITCGv_i32_d *QITCGv_i32; + +/** + * QITCGv_i64: + * + * TCG register with 64-bit data. + */ +typedef struct QITCGv_i64_d *QITCGv_i64; + +/* + * QITCGv_ptr: + * + * TCG register with pointer of architecture-specific length. + */ +typedef struct QITCGv_ptr_d *QITCGv_ptr; + =20 #include =20 diff --git a/stubs/instrument.c b/stubs/instrument.c index dda2ae88c5..2387b61840 100644 --- a/stubs/instrument.c +++ b/stubs/instrument.c @@ -45,7 +45,9 @@ void qmp_instr_unload(const char *id, Error **errp) } =20 =20 -__thread InstrState instr_cur_state; +__thread InstrInfo instr_cur_info; void (*instr_event__guest_cpu_enter)(QICPU *vcpu); void (*instr_event__guest_cpu_exit)(QICPU *vcpu); void (*instr_event__guest_cpu_reset)(QICPU *vcpu); +void (*instr_event__guest_mem_before_trans)( + QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMemInfo info); diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c index 6edf70bdfc..295c0c5a4a 100644 --- a/tcg/tcg-op.c +++ b/tcg/tcg-op.c @@ -26,6 +26,7 @@ #include "qemu-common.h" #include "cpu.h" #include "exec/exec-all.h" +#include "instrument/events.h" #include "tcg.h" #include "tcg-op.h" #include "tcg-mo.h" @@ -2680,6 +2681,7 @@ void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCG= Arg idx, TCGMemOp memop) tcg_gen_req_mo(TCG_MO_LD_LD | TCG_MO_ST_LD); memop =3D tcg_canonicalize_memop(memop, 0, 0); meminfo =3D trace_mem_get_info(memop, 0); + instr_guest_mem_before_trans(tcg_ctx.cpu, tcg_ctx.tcg_env, addr, memin= fo); trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, addr, meminfo= .raw); gen_ldst_i32(INDEX_op_qemu_ld_i32, val, addr, memop, idx); } @@ -2690,6 +2692,7 @@ void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCG= Arg idx, TCGMemOp memop) tcg_gen_req_mo(TCG_MO_LD_ST | TCG_MO_ST_ST); memop =3D tcg_canonicalize_memop(memop, 0, 1); meminfo =3D trace_mem_get_info(memop, 1); + instr_guest_mem_before_trans(tcg_ctx.cpu, tcg_ctx.tcg_env, addr, memin= fo); trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, addr, meminfo= .raw); gen_ldst_i32(INDEX_op_qemu_st_i32, val, addr, memop, idx); } @@ -2711,6 +2714,7 @@ void tcg_gen_qemu_ld_i64(TCGv_i64 val, TCGv addr, TCG= Arg idx, TCGMemOp memop) =20 memop =3D tcg_canonicalize_memop(memop, 1, 0); meminfo =3D trace_mem_get_info(memop, 0); + instr_guest_mem_before_trans(tcg_ctx.cpu, tcg_ctx.tcg_env, addr, memin= fo); trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, addr, meminfo= .raw); gen_ldst_i64(INDEX_op_qemu_ld_i64, val, addr, memop, idx); } @@ -2727,6 +2731,7 @@ void tcg_gen_qemu_st_i64(TCGv_i64 val, TCGv addr, TCG= Arg idx, TCGMemOp memop) =20 memop =3D tcg_canonicalize_memop(memop, 1, 1); meminfo =3D trace_mem_get_info(memop, 1); + instr_guest_mem_before_trans(tcg_ctx.cpu, tcg_ctx.tcg_env, addr, memin= fo); trace_guest_mem_before_tcg(tcg_ctx.cpu, tcg_ctx.tcg_env, addr, meminfo= .raw); gen_ldst_i64(INDEX_op_qemu_st_i64, val, addr, memop, idx); } diff --git a/trace/control.h b/trace/control.h index 3e6da24c98..6b3fe9a28f 100644 --- a/trace/control.h +++ b/trace/control.h @@ -20,6 +20,29 @@ typedef struct TraceEventIter { const char *pattern; } TraceEventIter; =20 +/** + * TraceMemInfo: + * @size_shift: Memoy access size, interpreted as "1 << size_shift" bytes. + * @sign_extend: Whether the access is sign-extended. + * @endianness: Endinness type (0: little, 1: big). + * @store: Whether it's a store operation. + * + * Memory access information. + * + * NOTE: Keep in sync with QIMemInfo. + */ +typedef struct TraceMemInfo { + union { + struct { + uint8_t size_shift : 2; + bool sign_extend: 1; + uint8_t endianness : 1; + bool store : 1; + }; + uint8_t raw; + }; +} TraceMemInfo; + =20 /** * trace_event_iter_init: diff --git a/trace/mem.h b/trace/mem.h index 9866b41401..bc89673272 100644 --- a/trace/mem.h +++ b/trace/mem.h @@ -12,29 +12,6 @@ =20 #include "tcg/tcg.h" =20 -/** - * TraceMemInfo: - * @size_shift: Memoy access size, interpreted as "1 << size_shift" bytes. - * @sign_extend: Whether the access is sign-extended. - * @endianness: Endinness type (0: little, 1: big). - * @store: Whether it's a store operation. - * - * Memory access information. - * - * NOTE: Keep in sync with QIMemInfo. - */ -typedef struct TraceMemInfo { - union { - struct { - uint8_t size_shift : 2; - bool sign_extend: 1; - uint8_t endianness : 1; - bool store : 1; - }; - uint8_t raw; - }; -} TraceMemInfo; - =20 /** * trace_mem_get_info: From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505254787277904.4946560897216; Tue, 12 Sep 2017 15:19:47 -0700 (PDT) Received: from localhost ([::1]:38950 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtX0-0006ZD-E9 for importer@patchew.org; Tue, 12 Sep 2017 18:19:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47819) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtVy-0005xd-GB for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:18:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drtVu-0001PV-0C for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:18:42 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:47828) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtVt-0001OP-DD for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:18:37 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CMIWVT023474; Wed, 13 Sep 2017 00:18:32 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 250FB201; Wed, 13 Sep 2017 00:18:27 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 01:18:25 +0300 Message-Id: <150525470558.15988.1401941433009738705.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CMIWVT023474 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 19/22] instrument: Add event 'guest_mem_before_exec' 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: Peter Crosthwaite , Markus Armbruster , "Emilio G. Cota" , Stefan Hajnoczi , Paolo Bonzini , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- include/exec/cpu_ldst_template.h | 4 +++ include/exec/cpu_ldst_useronly_template.h | 4 +++ include/exec/helper-gen.h | 1 + include/exec/helper-proto.h | 1 + include/exec/helper-tcg.h | 1 + instrument/control.c | 37 +++++++++++++++++++++++++= ++++ instrument/control.h | 15 ++++++++++++ instrument/events.h | 5 ++++ instrument/events.inc.h | 18 +++++++++++++- instrument/helpers.h | 2 ++ instrument/load.c | 1 + instrument/qemu-instr/control.h | 21 ++++++++++++++++ stubs/instrument.c | 19 ++++++++++++++- 13 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 instrument/helpers.h diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_templ= ate.h index debbabcfb2..8018e8b16a 100644 --- a/include/exec/cpu_ldst_template.h +++ b/include/exec/cpu_ldst_template.h @@ -28,6 +28,7 @@ #include "trace-root.h" #endif =20 +#include "instrument/events.h" #include "trace/mem.h" =20 #if DATA_SIZE =3D=3D 8 @@ -89,6 +90,7 @@ glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArch= State *env, =20 #if !defined(SOFTMMU_CODE_ACCESS) TraceMemInfo meminfo =3D trace_mem_build_info(SHIFT, false, MO_TE, fal= se); + instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo); trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw); #endif =20 @@ -126,6 +128,7 @@ glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUAr= chState *env, =20 #if !defined(SOFTMMU_CODE_ACCESS) TraceMemInfo meminfo =3D trace_mem_build_info(SHIFT, true, MO_TE, fals= e); + instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo); trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw); #endif =20 @@ -167,6 +170,7 @@ glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArc= hState *env, =20 #if !defined(SOFTMMU_CODE_ACCESS) TraceMemInfo meminfo =3D trace_mem_build_info(SHIFT, false, MO_TE, tru= e); + instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo); trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw); #endif =20 diff --git a/include/exec/cpu_ldst_useronly_template.h b/include/exec/cpu_l= dst_useronly_template.h index b0b3fc1b8d..c36c50ae41 100644 --- a/include/exec/cpu_ldst_useronly_template.h +++ b/include/exec/cpu_ldst_useronly_template.h @@ -27,6 +27,7 @@ #include "trace-root.h" #endif =20 +#include "instrument/events.h" #include "trace/mem.h" =20 #if DATA_SIZE =3D=3D 8 @@ -62,6 +63,7 @@ glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env,= target_ulong ptr) { #if !defined(CODE_ACCESS) TraceMemInfo meminfo =3D trace_mem_build_info(DATA_SIZE, false, MO_TE,= false); + instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo); trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw); #endif return glue(glue(ld, USUFFIX), _p)(g2h(ptr)); @@ -81,6 +83,7 @@ glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env,= target_ulong ptr) { #if !defined(CODE_ACCESS) TraceMemInfo meminfo =3D trace_mem_build_info(DATA_SIZE, true, MO_TE, = false); + instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo); trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw); #endif return glue(glue(lds, SUFFIX), _p)(g2h(ptr)); @@ -102,6 +105,7 @@ glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env= , target_ulong ptr, { #if !defined(CODE_ACCESS) TraceMemInfo meminfo =3D trace_mem_build_info(DATA_SIZE, false, MO_TE,= true); + instr_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo); trace_guest_mem_before_exec(ENV_GET_CPU(env), ptr, meminfo.raw); #endif glue(glue(st, SUFFIX), _p)(g2h(ptr), v); diff --git a/include/exec/helper-gen.h b/include/exec/helper-gen.h index 8239ffc77c..f351c3d050 100644 --- a/include/exec/helper-gen.h +++ b/include/exec/helper-gen.h @@ -57,6 +57,7 @@ static inline void glue(gen_helper_, name)(dh_retvar_decl= (ret) \ } =20 #include "helper.h" +#include "instrument/helpers.h" #include "trace/generated-helpers.h" #include "trace/generated-helpers-wrappers.h" #include "tcg-runtime.h" diff --git a/include/exec/helper-proto.h b/include/exec/helper-proto.h index 954bef85ce..8fdd02c132 100644 --- a/include/exec/helper-proto.h +++ b/include/exec/helper-proto.h @@ -27,6 +27,7 @@ dh_ctype(ret) HELPER(name) (dh_ctype(t1), dh_ctype(t2), d= h_ctype(t3), \ dh_ctype(t4), dh_ctype(t5)); =20 #include "helper.h" +#include "instrument/helpers.h" #include "trace/generated-helpers.h" #include "tcg-runtime.h" =20 diff --git a/include/exec/helper-tcg.h b/include/exec/helper-tcg.h index b0c5bafa99..255e73c3e6 100644 --- a/include/exec/helper-tcg.h +++ b/include/exec/helper-tcg.h @@ -40,6 +40,7 @@ | dh_sizemask(t5, 5) }, =20 #include "helper.h" +#include "instrument/helpers.h" #include "trace/generated-helpers.h" #include "tcg-runtime.h" =20 diff --git a/instrument/control.c b/instrument/control.c index 0424dd57ab..4181e030f6 100644 --- a/instrument/control.c +++ b/instrument/control.c @@ -15,6 +15,8 @@ #include "qemu/compiler.h" #include "qemu/main-loop.h" #include "qom/cpu.h" +#include "exec/helper-proto.h" +#include "exec/helper-gen.h" =20 =20 __thread InstrInfo instr_cur_info; @@ -155,3 +157,38 @@ SYM_PUBLIC void qi_event_set_guest_mem_before_trans( ERROR_IF(!tcg_enabled(), "called without TCG"); instr_set_event(guest_mem_before_trans, fn); } + + +SYM_PUBLIC void qi_event_gen_guest_mem_before_exec( + QITCGv_cpu vcpu, QITCGv vaddr, QIMemInfo info) +{ + ERROR_IF(instr_get_state() !=3D INSTR_STATE_ENABLE_TCG, + "called outside instrumentation"); + ERROR_IF(!tcg_enabled(), "called without TCG"); + InstrInfo *iinfo =3D &instr_cur_info; + TCGv_env vcpu_ =3D instr_tcg_from_qitcg(iinfo, vcpu); + TCGv vaddr_ =3D instr_tcg_from_qitcg(iinfo, vaddr); + TCGv_i32 info_ =3D tcg_const_i32(info.raw); + gen_helper_instr_guest_mem_before_exec(vcpu_, vaddr_, info_); + tcg_temp_free_i32(info_); +} + +void helper_instr_guest_mem_before_exec( + CPUArchState *vcpu, target_ulong vaddr, uint32_t info) +{ + TraceMemInfo info_; + info_.raw =3D info; + instr_guest_mem_before_exec(ENV_GET_CPU(vcpu), vaddr, info_); +} + + +void (*instr_event__guest_mem_before_exec)( + QICPU vcpu, uint64_t vaddr, QIMemInfo info); + +SYM_PUBLIC void qi_event_set_guest_mem_before_exec( + void (*fn)(QICPU vcpu, uint64_t vaddr, QIMemInfo info)) +{ + ERROR_IF(!instr_get_state(), "called outside instrumentation"); + ERROR_IF(!tcg_enabled(), "called without TCG"); + instr_set_event(guest_mem_before_exec, fn); +} diff --git a/instrument/control.h b/instrument/control.h index 3e44702f75..3b1d5c5344 100644 --- a/instrument/control.h +++ b/instrument/control.h @@ -84,6 +84,7 @@ void instr_cpu_stop_all_end(InstrCPUStop *info); typedef enum { INSTR_STATE_DISABLE, INSTR_STATE_ENABLE, + INSTR_STATE_ENABLE_TCG, } InstrState; =20 #define INSTR_MAX_TCG_REGS 16 @@ -123,6 +124,20 @@ static inline InstrState instr_get_state(void); (void *)num; \ }) =20 +/** + * instr_tcg_from_qitcg: + * @info: Pointer to #InstrInfo. + * @arg: QITCG register. + * + * Get a suitable TCGv* from a QITCGv* value. + */ +#define instr_tcg_from_qitcg(info, arg) \ + ({ \ + unsigned int idx =3D (uintptr_t)arg; \ + ERROR_IF(info->max <=3D idx, "invalid QITCGv register"); \ + info->tcg_regs[idx]; \ + }) + /** * instr_tcg_count: * @info: Pointer to #InstrInfo. diff --git a/instrument/events.h b/instrument/events.h index 1cc4dbb052..6507b26867 100644 --- a/instrument/events.h +++ b/instrument/events.h @@ -63,6 +63,11 @@ extern void (*instr_event__guest_mem_before_trans)( static inline void instr_guest_mem_before_trans( CPUState *vcpu_trans, TCGv_env vcpu_exec, TCGv vaddr, TraceMemInfo inf= o); =20 +extern void (*instr_event__guest_mem_before_exec)( + QICPU vcpu, uint64_t vaddr, QIMemInfo info); +static inline void instr_guest_mem_before_exec( + CPUState *vcpu, uint64_t vaddr, TraceMemInfo info); + =20 #include "instrument/events.inc.h" =20 diff --git a/instrument/events.inc.h b/instrument/events.inc.h index 365c715db4..ebc8020715 100644 --- a/instrument/events.inc.h +++ b/instrument/events.inc.h @@ -51,7 +51,7 @@ static inline void instr_guest_mem_before_trans( QITCGv vaddr, QIMemInfo info) =3D instr_get_event(guest_mem_before_trans); if (cb) { - InstrInfo *iinfo =3D instr_set_state(INSTR_STATE_ENABLE); + InstrInfo *iinfo =3D instr_set_state(INSTR_STATE_ENABLE_TCG); QICPU vcpu_trans_ =3D instr_cpu_to_qicpu(vcpu_trans); QITCGv_cpu vcpu_exec_ =3D instr_tcg_to_qitcg(iinfo, 0, vcpu_exec); QITCGv vaddr_ =3D instr_tcg_to_qitcg(iinfo, 1, vaddr); @@ -62,3 +62,19 @@ static inline void instr_guest_mem_before_trans( instr_set_state(INSTR_STATE_DISABLE); } } + +static inline void instr_guest_mem_before_exec( + CPUState *vcpu, uint64_t vaddr, TraceMemInfo info) +{ + void (*cb)(QICPU vcpu, uint64_t vaddr, QIMemInfo info) + =3D instr_get_event(guest_mem_before_exec); + if (cb) { + InstrInfo *iinfo =3D instr_set_state(INSTR_STATE_ENABLE); + QICPU vcpu_ =3D instr_cpu_to_qicpu(vcpu); + QIMemInfo info_; + info_.raw =3D info.raw; + instr_tcg_count(iinfo, 2); + (*cb)(vcpu_, vaddr, info_); + instr_set_state(INSTR_STATE_DISABLE); + } +} diff --git a/instrument/helpers.h b/instrument/helpers.h new file mode 100644 index 0000000000..199f781b89 --- /dev/null +++ b/instrument/helpers.h @@ -0,0 +1,2 @@ +DEF_HELPER_FLAGS_3(instr_guest_mem_before_exec, TCG_CALL_NO_RWG, + void, env, tl, i32) diff --git a/instrument/load.c b/instrument/load.c index e8f869201b..f1d769b92d 100644 --- a/instrument/load.c +++ b/instrument/load.c @@ -163,6 +163,7 @@ InstrUnloadError instr_unload(const char *id) instr_set_event(guest_cpu_exit, NULL); instr_set_event(guest_cpu_reset, NULL); instr_set_event(guest_mem_before_trans, NULL); + instr_set_event(guest_mem_before_exec, NULL); =20 instr_cpu_stop_all_end(&info); cpu_list_unlock(); diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/contro= l.h index c3c8c3988d..acd4b10f03 100644 --- a/instrument/qemu-instr/control.h +++ b/instrument/qemu-instr/control.h @@ -121,6 +121,27 @@ void qi_event_set_guest_mem_before_trans( void (*fn)(QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMemInfo info)); =20 +/* + * Generate code to trigger a 'guest_mem_before_exec' from + * 'guest_mem_before_trans'. + * + * Mode: user, softmmu + * Targets: TCG(all) + * Time: trans + */ +void qi_event_gen_guest_mem_before_exec( + QITCGv_cpu vcpu, QITCGv vaddr, QIMemInfo info); + +/* + * Execution-time equivalent of 'guest_mem_before_trans'. + * + * Mode: user, softmmu + * Targets: TCG(all) + * Time: exec + */ +void qi_event_set_guest_mem_before_exec( + void (*fn)(QICPU vcpu, uint64_t vaddr, QIMemInfo info)); + #ifdef __cplusplus } #endif diff --git a/stubs/instrument.c b/stubs/instrument.c index 2387b61840..045d31fd78 100644 --- a/stubs/instrument.c +++ b/stubs/instrument.c @@ -7,6 +7,9 @@ * See the COPYING file in the top-level directory. */ =20 +/* Unpoison missing types */ +#define HW_POISON_H + #include "qemu/osdep.h" =20 #include "instrument/cmdline.h" @@ -17,6 +20,9 @@ =20 /* Declare missing types */ typedef struct strList strList; +typedef struct CPUArchState CPUArchState; +typedef int target_ulong; + =20 =20 void instr_init(const char *path, int argc, const char **argv) @@ -50,4 +56,15 @@ void (*instr_event__guest_cpu_enter)(QICPU *vcpu); void (*instr_event__guest_cpu_exit)(QICPU *vcpu); void (*instr_event__guest_cpu_reset)(QICPU *vcpu); void (*instr_event__guest_mem_before_trans)( - QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMemInfo info); + QICPU vcpu_trans, QITCGv_cpu vcpu_exec, + QITCGv vaddr, QIMemInfo info); +void helper_instr_guest_mem_before_exec( + CPUArchState *vcpu, target_ulong vaddr, uint32_t info); +void helper_instr_guest_mem_before_exec( + CPUArchState *vcpu, target_ulong vaddr, uint32_t info) +{ + assert(false); +} +void (*instr_event__guest_mem_before_exec)( + QICPU vcpu_trans, QITCGv_cpu vcpu_exec, + QITCGv vaddr, QIMemInfo info); From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505255034513853.5630960019096; Tue, 12 Sep 2017 15:23:54 -0700 (PDT) Received: from localhost ([::1]:38974 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtaz-0002Hr-NL for importer@patchew.org; Tue, 12 Sep 2017 18:23:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50424) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drta1-0001Xn-K7 for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:22:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drtZx-0003zr-6G for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:22:53 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:55984) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtZw-0003ye-Mm for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:22:49 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CMMZdu023686; Wed, 13 Sep 2017 00:22:35 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id B3BE877C; Wed, 13 Sep 2017 00:22:29 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 01:22:28 +0300 Message-Id: <150525494801.15988.8042196515265137270.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CMMZdu023686 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 20/22] instrument: Add event 'guest_user_syscall' 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: Riku Voipio , Markus Armbruster , Laurent Vivier , "Emilio G. Cota" , Stefan Hajnoczi , Paolo Bonzini , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- bsd-user/syscall.c | 6 ++++++ instrument/control.c | 18 ++++++++++++++++++ instrument/events.h | 7 +++++++ instrument/events.inc.h | 16 ++++++++++++++++ instrument/load.c | 1 + instrument/qemu-instr/control.h | 15 +++++++++++++++ linux-user/syscall.c | 2 ++ stubs/instrument.c | 3 +++ 8 files changed, 68 insertions(+) diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c index 3230f722f3..0d92eaf8c4 100644 --- a/bsd-user/syscall.c +++ b/bsd-user/syscall.c @@ -324,6 +324,8 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi= _long arg1, #ifdef DEBUG gemu_log("freebsd syscall %d\n", num); #endif + instr_guest_user_syscall(cpu, num, + arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg= 8); trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6,= arg7, arg8); if(do_strace) print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); @@ -423,6 +425,8 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_= long arg1, #ifdef DEBUG gemu_log("netbsd syscall %d\n", num); #endif + instr_guest_user_syscall(cpu, num, + arg1, arg2, arg3, arg4, arg5, arg6, 0, 0); trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6,= 0, 0); if(do_strace) print_netbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); @@ -499,6 +503,8 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, abi= _long arg1, #ifdef DEBUG gemu_log("openbsd syscall %d\n", num); #endif + instr_guest_user_syscall(cpu, num, + arg1, arg2, arg3, arg4, arg5, arg6, 0, 0); trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6,= 0, 0); if(do_strace) print_openbsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); diff --git a/instrument/control.c b/instrument/control.c index 4181e030f6..b3ef03798e 100644 --- a/instrument/control.c +++ b/instrument/control.c @@ -192,3 +192,21 @@ SYM_PUBLIC void qi_event_set_guest_mem_before_exec( ERROR_IF(!tcg_enabled(), "called without TCG"); instr_set_event(guest_mem_before_exec, fn); } + + +void (*instr_event__guest_user_syscall)( + QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3, + uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t a= rg8); + +SYM_PUBLIC void qi_event_set_guest_user_syscall( + void (*fn)(QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, + uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6, + uint64_t arg7, uint64_t arg8)) +{ + ERROR_IF(!instr_get_state(), "called outside instrumentation"); + ERROR_IF(!tcg_enabled(), "called without TCG"); +#if !defined(CONFIG_USER_ONLY) + ERROR_IF(true, "called in full-system mode"); +#endif + instr_set_event(guest_user_syscall, fn); +} diff --git a/instrument/events.h b/instrument/events.h index 6507b26867..8c944e1f91 100644 --- a/instrument/events.h +++ b/instrument/events.h @@ -68,6 +68,13 @@ extern void (*instr_event__guest_mem_before_exec)( static inline void instr_guest_mem_before_exec( CPUState *vcpu, uint64_t vaddr, TraceMemInfo info); =20 +extern void (*instr_event__guest_user_syscall)( + QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3, + uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t a= rg8); +static inline void instr_guest_user_syscall( + CPUState *vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t a= rg3, + uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t a= rg8); + =20 #include "instrument/events.inc.h" =20 diff --git a/instrument/events.inc.h b/instrument/events.inc.h index ebc8020715..e2f4315fb0 100644 --- a/instrument/events.inc.h +++ b/instrument/events.inc.h @@ -78,3 +78,19 @@ static inline void instr_guest_mem_before_exec( instr_set_state(INSTR_STATE_DISABLE); } } + +static inline void instr_guest_user_syscall( + CPUState *vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t a= rg3, + uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t a= rg8) +{ + void (*cb)(QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, + uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6, + uint64_t arg7, uint64_t arg8) + =3D instr_get_event(guest_user_syscall); + if (cb) { + instr_set_state(INSTR_STATE_ENABLE); + QICPU vcpu_ =3D instr_cpu_to_qicpu(vcpu); + (*cb)(vcpu_, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); + instr_set_state(INSTR_STATE_DISABLE); + } +} diff --git a/instrument/load.c b/instrument/load.c index f1d769b92d..a76f76e1d1 100644 --- a/instrument/load.c +++ b/instrument/load.c @@ -164,6 +164,7 @@ InstrUnloadError instr_unload(const char *id) instr_set_event(guest_cpu_reset, NULL); instr_set_event(guest_mem_before_trans, NULL); instr_set_event(guest_mem_before_exec, NULL); + instr_set_event(guest_user_syscall, NULL); =20 instr_cpu_stop_all_end(&info); cpu_list_unlock(); diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/contro= l.h index acd4b10f03..136058af4f 100644 --- a/instrument/qemu-instr/control.h +++ b/instrument/qemu-instr/control.h @@ -142,6 +142,21 @@ void qi_event_gen_guest_mem_before_exec( void qi_event_set_guest_mem_before_exec( void (*fn)(QICPU vcpu, uint64_t vaddr, QIMemInfo info)); =20 +/* + * Start executing a guest system call in syscall emulation mode. + * + * @num: System call number. + * @arg*: System call argument value. + * + * Mode: user + * Targets: TCG(all) + * Time: exec + */ +void qi_event_set_guest_user_syscall( + void (*fn)(QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, + uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6, + uint64_t arg7, uint64_t arg8)); + #ifdef __cplusplus } #endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index e73a07fa6f..c9f0b9fa56 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7723,6 +7723,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long = arg1, #ifdef DEBUG gemu_log("syscall %d", num); #endif + instr_guest_user_syscall(cpu, num, + arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg= 8); trace_guest_user_syscall(cpu, num, arg1, arg2, arg3, arg4, arg5, arg6,= arg7, arg8); if(do_strace) print_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); diff --git a/stubs/instrument.c b/stubs/instrument.c index 045d31fd78..77c9861b71 100644 --- a/stubs/instrument.c +++ b/stubs/instrument.c @@ -68,3 +68,6 @@ void helper_instr_guest_mem_before_exec( void (*instr_event__guest_mem_before_exec)( QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMemInfo info); +void (*instr_event__guest_user_syscall)( + QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3, + uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t a= rg8); From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505255352401445.4416200477766; Tue, 12 Sep 2017 15:29:12 -0700 (PDT) Received: from localhost ([::1]:38999 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtg5-0005eZ-Pb for importer@patchew.org; Tue, 12 Sep 2017 18:29:09 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53138) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtdt-0004W9-N3 for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:26:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drtdq-0006r1-3o for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:26:53 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:56010) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtdp-0006qb-PD for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:26:50 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CMQdxS023789; Wed, 13 Sep 2017 00:26:39 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 3A7832EB; Wed, 13 Sep 2017 00:26:33 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 01:26:30 +0300 Message-Id: <150525519047.15988.7515219035767609489.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CMQdxS023789 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 21/22] instrument: Add event 'guest_user_syscall_ret' 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: Riku Voipio , Markus Armbruster , Laurent Vivier , "Emilio G. Cota" , Stefan Hajnoczi , Paolo Bonzini , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- bsd-user/syscall.c | 3 +++ instrument/control.c | 15 +++++++++++++++ instrument/events.h | 5 +++++ instrument/events.inc.h | 13 +++++++++++++ instrument/load.c | 1 + instrument/qemu-instr/control.h | 13 +++++++++++++ linux-user/syscall.c | 1 + stubs/instrument.c | 2 ++ 8 files changed, 53 insertions(+) diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c index 0d92eaf8c4..fb468c0574 100644 --- a/bsd-user/syscall.c +++ b/bsd-user/syscall.c @@ -407,6 +407,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi= _long arg1, #endif if (do_strace) print_freebsd_syscall_ret(num, ret); + instr_guest_user_syscall_ret(cpu, num, ret); trace_guest_user_syscall_ret(cpu, num, ret); return ret; efault: @@ -485,6 +486,7 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_= long arg1, #endif if (do_strace) print_netbsd_syscall_ret(num, ret); + instr_guest_user_syscall_ret(cpu, num, ret); trace_guest_user_syscall_ret(cpu, num, ret); return ret; efault: @@ -563,6 +565,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, abi= _long arg1, #endif if (do_strace) print_openbsd_syscall_ret(num, ret); + instr_guest_user_syscall_ret(cpu, num, ret); trace_guest_user_syscall_ret(cpu, num, ret); return ret; efault: diff --git a/instrument/control.c b/instrument/control.c index b3ef03798e..b5b1e0503d 100644 --- a/instrument/control.c +++ b/instrument/control.c @@ -210,3 +210,18 @@ SYM_PUBLIC void qi_event_set_guest_user_syscall( #endif instr_set_event(guest_user_syscall, fn); } + + +void (*instr_event__guest_user_syscall_ret)( + QICPU vcpu, uint64_t num, uint64_t ret); + +SYM_PUBLIC void qi_event_set_guest_user_syscall_ret( + void (*fn)(QICPU vcpu, uint64_t num, uint64_t ret)) +{ + ERROR_IF(!instr_get_state(), "called outside instrumentation"); + ERROR_IF(!tcg_enabled(), "called without TCG"); +#if !defined(CONFIG_USER_ONLY) + ERROR_IF(true, "called in full-system mode"); +#endif + instr_set_event(guest_user_syscall_ret, fn); +} diff --git a/instrument/events.h b/instrument/events.h index 8c944e1f91..6197ece466 100644 --- a/instrument/events.h +++ b/instrument/events.h @@ -75,6 +75,11 @@ static inline void instr_guest_user_syscall( CPUState *vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t a= rg3, uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t a= rg8); =20 +extern void (*instr_event__guest_user_syscall_ret)( + QICPU vcpu, uint64_t num, uint64_t ret); +static inline void instr_guest_user_syscall_ret( + CPUState *vcpu, uint64_t num, uint64_t ret); + =20 #include "instrument/events.inc.h" =20 diff --git a/instrument/events.inc.h b/instrument/events.inc.h index e2f4315fb0..d31dec54b8 100644 --- a/instrument/events.inc.h +++ b/instrument/events.inc.h @@ -94,3 +94,16 @@ static inline void instr_guest_user_syscall( instr_set_state(INSTR_STATE_DISABLE); } } + +static inline void instr_guest_user_syscall_ret( + CPUState *vcpu, uint64_t num, uint64_t ret) +{ + void (*cb)(QICPU vcpu, uint64_t num, uint64_t ret) + =3D instr_get_event(guest_user_syscall_ret); + if (cb) { + instr_set_state(INSTR_STATE_ENABLE); + QICPU vcpu_ =3D instr_cpu_to_qicpu(vcpu); + (*cb)(vcpu_, num, ret); + instr_set_state(INSTR_STATE_DISABLE); + } +} diff --git a/instrument/load.c b/instrument/load.c index a76f76e1d1..be13a90286 100644 --- a/instrument/load.c +++ b/instrument/load.c @@ -165,6 +165,7 @@ InstrUnloadError instr_unload(const char *id) instr_set_event(guest_mem_before_trans, NULL); instr_set_event(guest_mem_before_exec, NULL); instr_set_event(guest_user_syscall, NULL); + instr_set_event(guest_user_syscall_ret, NULL); =20 instr_cpu_stop_all_end(&info); cpu_list_unlock(); diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/contro= l.h index 136058af4f..bc4e49bef1 100644 --- a/instrument/qemu-instr/control.h +++ b/instrument/qemu-instr/control.h @@ -157,6 +157,19 @@ void qi_event_set_guest_user_syscall( uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t arg8)); =20 +/* + * Finish executing a guest system call in syscall emulation mode. + * + * @num: System call number. + * @ret: System call result value. + * + * Mode: user + * Targets: TCG(all) + * Time: exec + */ +void qi_event_set_guest_user_syscall_ret( + void (*fn)(QICPU vcpu, uint64_t num, uint64_t ret)); + #ifdef __cplusplus } #endif diff --git a/linux-user/syscall.c b/linux-user/syscall.c index c9f0b9fa56..44b91e3c52 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -12398,6 +12398,7 @@ fail: #endif if(do_strace) print_syscall_ret(num, ret); + instr_guest_user_syscall_ret(cpu, num, ret); trace_guest_user_syscall_ret(cpu, num, ret); return ret; efault: diff --git a/stubs/instrument.c b/stubs/instrument.c index 77c9861b71..5c56c1a322 100644 --- a/stubs/instrument.c +++ b/stubs/instrument.c @@ -71,3 +71,5 @@ void (*instr_event__guest_mem_before_exec)( void (*instr_event__guest_user_syscall)( QICPU vcpu, uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5, uint64_t arg6, uint64_t arg7, uint64_t a= rg8); +void (*instr_event__guest_user_syscall_ret)( + QICPU vcpu, uint64_t num, uint64_t ret); From nobody Fri May 3 09:15:22 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1505255552019729.3069088994537; Tue, 12 Sep 2017 15:32:32 -0700 (PDT) Received: from localhost ([::1]:39010 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drtjL-00074O-6Q for importer@patchew.org; Tue, 12 Sep 2017 18:32:31 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55050) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drthj-0006De-8M for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:30:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1drthf-0000K8-MB for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:30:51 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:48475) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1drthe-0000Jf-Uz for qemu-devel@nongnu.org; Tue, 12 Sep 2017 18:30:47 -0400 Received: from correu-2.ac.upc.es (correu-2.ac.upc.es [147.83.30.92]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v8CMUhDL023867; Wed, 13 Sep 2017 00:30:43 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id 1AEEB44C; Wed, 13 Sep 2017 00:30:37 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 13 Sep 2017 01:30:36 +0300 Message-Id: <150525543616.15988.18238686972036900217.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150525010239.15988.8172586618197849619.stgit@frigg.lan> References: <150525010239.15988.8172586618197849619.stgit@frigg.lan> User-Agent: StGit/0.18 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v8CMUhDL023867 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH v5 22/22] instrument: Add API to manipulate guest memory 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: "Emilio G. Cota" , Markus Armbruster , Stefan Hajnoczi , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 It includes access to the guest's memory and vCPU registers. Signed-off-by: Llu=C3=ADs Vilanova --- instrument/Makefile.objs | 1=20 instrument/qemu-instr/state.h | 104 +++++++++++++++++++++++++++++++++++++= ++++ instrument/state.c | 73 +++++++++++++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 instrument/qemu-instr/state.h create mode 100644 instrument/state.c diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs index d7e6c760c3..ee482bdb45 100644 --- a/instrument/Makefile.objs +++ b/instrument/Makefile.objs @@ -5,3 +5,4 @@ target-obj-$(CONFIG_INSTRUMENT) +=3D load.o target-obj-$(CONFIG_INSTRUMENT) +=3D qmp.o target-obj-$(CONFIG_INSTRUMENT) +=3D control.o target-obj-$(CONFIG_INSTRUMENT) +=3D trace.o +target-obj-$(CONFIG_INSTRUMENT) +=3D state.o diff --git a/instrument/qemu-instr/state.h b/instrument/qemu-instr/state.h new file mode 100644 index 0000000000..0ae6255fe5 --- /dev/null +++ b/instrument/qemu-instr/state.h @@ -0,0 +1,104 @@ +/* + * Interface for accessing guest state. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef QI__STATE_H +#define QI__STATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +/** + * qi_mem_read_virt: + * @vcpu: CPU to use for address translation. + * @vaddr: Starting virtual address to read from. + * @size: Number of bytes to read. + * @buf: Buffer to write into. + * + * Read contents from virtual memory. + * + * Returns: Whether the range of virtual addresses to read could be transl= ated. + * + * Warning: Even on error, some of the destination buffer might have been + * modified. + * + * Precondition: The output buffer has at least "size" bytes. + */ +bool qi_mem_read_virt(QICPU vcpu, uint64_t vaddr, size_t size, void *buf); + +/** + * qi_mem_write_virt: + * @vcpu: CPU to use for address translation. + * @vaddr: Starting virtual address to write into. + * @size: Number of bytes to write. + * @buf: Buffer with the contents to write from. + * + * Write contents into virtual memory. + * + * Returns: Whether the range of virtual addresses to write could be trans= lated. + * + * Warning: Even on error, some of the destination memory might have been + * modified. + * Precondition: The input buffer has at least "size" bytes. + */ +bool qi_mem_write_virt(QICPU vcpu, uint64_t vaddr, size_t size, void *buf); + +/** + * qi_mem_virt_to_phys: + * @vcpu: CPU to use for address translation. + * @vaddr: Virtual address to translate. + * @paddr: Pointer to output physical address. + * + * Translate a virtual address into a physical address. + * + * Returns: Whether the address could be translated. + */ +bool qi_mem_virt_to_phys(QICPU vcpu, uint64_t vaddr, uint64_t *paddr); + +/** + * qi_mem_read_phys: + * @paddr: Starting physical address to read from. + * @size: Number of bytes to read. + * @buf: Buffer to write into. + * + * Read contents from physical memory. + * + * Returns: Whether the range of physical addresses is valid. + * + * Warning: Even on error, some of the destination buffer might have been + * modified. + * Precondition: The output buffer has at least "size" bytes. + */ +bool qi_mem_read_phys(uint64_t paddr, size_t size, void *buf); + +/** + * qi_mem_write_phys: + * @paddr: Starting physical address to write into. + * @size: Number of bytes to write. + * @buf: Buffer with the contents to write from. + * + * Write contents into virtual memory. + * + * Returns: Whether the range of physical addresses is valid. + * + * Warning: Even on error, some of the destination memory might have been + * modified. + * + * Precondition: The input buffer has at least "size" bytes. + */ +bool qi_mem_write_phys(uint64_t paddr, size_t size, void *buf); + +#ifdef __cplusplus +} +#endif + +#endif /* QI__STATE_H */ diff --git a/instrument/state.c b/instrument/state.c new file mode 100644 index 0000000000..e76fd5fbcd --- /dev/null +++ b/instrument/state.c @@ -0,0 +1,73 @@ +/* + * Interface for accessing guest state. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" + +#include "qemu/compiler.h" +#include "cpu.h" +#include "exec/cpu-all.h" +#include "instrument/control.h" +#include "instrument/error.h" +#include "instrument/qemu-instr/state.h" + + +SYM_PUBLIC bool qi_mem_read_virt(QICPU vcpu, uint64_t vaddr, + size_t size, void *buf) +{ + CPUState *vcpu_ =3D instr_cpu_from_qicpu(vcpu); + ERROR_IF_RET(!instr_get_state(), false, "called outside instrumentatio= n"); + ERROR_IF_RET(!vcpu_, false, "invalid QICPU"); + return cpu_memory_rw_debug(vcpu_, vaddr, buf, size, 0) =3D=3D 0; +} + +SYM_PUBLIC bool qi_mem_write_virt(QICPU vcpu, uint64_t vaddr, + size_t size, void *buf) +{ + CPUState *vcpu_ =3D instr_cpu_from_qicpu(vcpu); + ERROR_IF_RET(!instr_get_state(), false, "called outside instrumentatio= n"); + ERROR_IF_RET(!vcpu_, false, "invalid QICPU"); + return cpu_memory_rw_debug(vcpu_, vaddr, buf, size, 1) =3D=3D 0; +} + +SYM_PUBLIC bool qi_mem_virt_to_phys(QICPU vcpu, uint64_t vaddr, uint64_t *= paddr) +{ + CPUState *vcpu_ =3D instr_cpu_from_qicpu(vcpu); + ERROR_IF_RET(!instr_get_state(), false, "called outside instrumentatio= n"); + ERROR_IF_RET(!vcpu_, false, "invalid QICPU"); + +#if defined(CONFIG_USER_ONLY) + *paddr =3D vaddr; + return true; +#else + *paddr =3D cpu_get_phys_page_debug(vcpu_, vaddr); + return *paddr !=3D -1; +#endif +} + +SYM_PUBLIC bool qi_mem_read_phys(uint64_t paddr, size_t size, void *buf) +{ + ERROR_IF_RET(!instr_get_state(), false, "called outside instrumentatio= n"); +#if defined(CONFIG_USER_ONLY) + return cpu_memory_rw_debug(NULL, paddr, buf, size, 0) =3D=3D 0; +#else + cpu_physical_memory_read(paddr, buf, size); + return true; +#endif +} + +SYM_PUBLIC bool qi_mem_write_phys(uint64_t paddr, size_t size, void *buf) +{ + ERROR_IF_RET(!instr_get_state(), false, "called outside instrumentatio= n"); +#if defined(CONFIG_USER_ONLY) + return cpu_memory_rw_debug(NULL, paddr, buf, size, 1) =3D=3D 0; +#else + cpu_physical_memory_write(paddr, buf, size); + return true; +#endif +}