From nobody Thu May 2 05:58:20 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 1504718886337860.4608128959785; Wed, 6 Sep 2017 10:28:06 -0700 (PDT) Received: from localhost ([::1]:37260 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpe7Q-000179-KV for importer@patchew.org; Wed, 06 Sep 2017 13:28:04 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36678) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpe6P-0000fa-8l for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:27:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpe6I-00031S-Rj for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:27:01 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:55283) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpe6I-00030f-EH for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:26:54 -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 v86HQpdg003765; Wed, 6 Sep 2017 19:26:51 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id B435D7FD; Wed, 6 Sep 2017 19:26:45 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 20:26:43 +0300 Message-Id: <150471880362.24907.17816085971167173217.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86HQpdg003765 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 v4 01/20] 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" , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= , 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 --- MAINTAINERS | 6 ++ docs/instrument.txt | 174 +++++++++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 180 insertions(+) create mode 100644 docs/instrument.txt diff --git a/MAINTAINERS b/MAINTAINERS index ccee28b12d..edb313c632 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1480,6 +1480,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 + Checkpatch S: Odd Fixes F: scripts/checkpatch.pl diff --git a/docs/instrument.txt b/docs/instrument.txt new file mode 100644 index 0000000000..c43ca9c6d0 --- /dev/null +++ b/docs/instrument.txt @@ -0,0 +1,174 @@ +=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 */ + #include /* symbol visibility */ + =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 */ + QI_VPUBLIC 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 Thu May 2 05:58:20 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 1504719112088201.37840186477; Wed, 6 Sep 2017 10:31:52 -0700 (PDT) Received: from localhost ([::1]:37275 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeB5-0002Ca-38 for importer@patchew.org; Wed, 06 Sep 2017 13:31:51 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37428) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeAG-0001si-V9 for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:31:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpeAD-0004ON-0e for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:31:00 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:36872) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeAC-0004Nr-M9 for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:30:56 -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 v86HUrcC003860; Wed, 6 Sep 2017 19:30:53 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id C2AF8355; Wed, 6 Sep 2017 19:30:47 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 20:30:46 +0300 Message-Id: <150471904580.24907.15196045749813468308.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86HUrcC003860 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 v4 02/20] 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" , 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 dd73cce62f..80dcc91c98 100755 --- a/configure +++ b/configure @@ -352,6 +352,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"" @@ -891,6 +892,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" @@ -1441,6 +1444,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 @@ -5371,6 +5375,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" @@ -6028,6 +6033,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 Thu May 2 05:58:20 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 15047193572961.2346266672246884; Wed, 6 Sep 2017 10:35:57 -0700 (PDT) Received: from localhost ([::1]:37289 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeF1-0003iU-Fx for importer@patchew.org; Wed, 06 Sep 2017 13:35:55 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38410) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeEB-0003Ox-IR for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:35:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpeE8-0006YW-Ch for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:35:03 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:40325) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeE7-0006Y2-OF for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:35: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 v86HYteU003993; Wed, 6 Sep 2017 19:34:55 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id D7E7D8AF; Wed, 6 Sep 2017 19:34:49 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 20:34:48 +0300 Message-Id: <150471928780.24907.14047559834166839201.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86HYteU003993 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 v4 03/20] 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: "Emilio G. Cota" , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= , 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 --- MAINTAINERS | 1=20 Makefile.objs | 4 + configure | 2 + instrument/Makefile.objs | 4 + instrument/cmdline.c | 124 ++++++++++++++++++++++++++++++++ instrument/cmdline.h | 49 +++++++++++++ instrument/load.c | 176 ++++++++++++++++++++++++++++++++++++++++++= ++++ instrument/load.h | 83 ++++++++++++++++++++++ 8 files changed, 443 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 diff --git a/MAINTAINERS b/MAINTAINERS index edb313c632..edd2c49078 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1485,6 +1485,7 @@ M: Llu=C3=ADs Vilanova M: Stefan Hajnoczi S: Maintained F: docs/instrument.txt +F: instrument/ =20 Checkpatch S: Odd Fixes 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 80dcc91c98..05bd7b1950 100755 --- a/configure +++ b/configure @@ -6034,6 +6034,8 @@ 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 + 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..5ea5c77245 --- /dev/null +++ b/instrument/Makefile.objs @@ -0,0 +1,4 @@ +# -*- mode: makefile -*- + +target-obj-y +=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..ec87f96c72 --- /dev/null +++ b/instrument/cmdline.c @@ -0,0 +1,124 @@ +/* + * 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; + int64_t handle; + + if (path =3D=3D NULL) { + return; + } + + if (atexit(instr_fini) !=3D 0) { + fprintf(stderr, "error: atexit: %s\n", strerror(errno)); + abort(); + } + + err =3D instr_load(path, argc, argv, &handle); + switch (err) { + case INSTR_LOAD_OK: + return; + case INSTR_LOAD_TOO_MANY: + error_report("instrument: tried to load too many libraries"); + 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..e6ea08c3e3 --- /dev/null +++ b/instrument/cmdline.h @@ -0,0 +1,49 @@ +/* + * 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 + + +/** + * 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..a57401102a --- /dev/null +++ b/instrument/load.c @@ -0,0 +1,176 @@ +/* + * 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 int64_t InstrHandleID; + +typedef struct InstrHandle +{ + InstrHandleID id; + void *dlhandle; + QSLIST_ENTRY(InstrHandle) list; +} InstrHandle; + + +static InstrHandleID handle_last_id; +static QSLIST_HEAD(, InstrHandle) handles =3D QSLIST_HEAD_INITIALIZER(hand= les); +static QemuMutex instr_lock; + + +static InstrHandle *handle_get(void) +{ + InstrHandle *res =3D g_malloc0(sizeof(InstrHandle)); + res->id =3D handle_last_id++; + QSLIST_INSERT_HEAD(&handles, res, list); + return res; +} + +static bool handle_put(InstrHandleID id) +{ + InstrHandle *prev =3D NULL; + InstrHandle *handle; + QSLIST_FOREACH(handle, &handles, list) { + if (handle->id =3D=3D id) { + break; + } + prev =3D handle; + } + if (handle =3D=3D NULL) { + return false; + } else { + if (prev =3D=3D NULL) { + QSLIST_REMOVE_HEAD(&handles, list); + } else { + QSLIST_REMOVE_AFTER(prev, list); + } + g_free(handle); + return true; + } +} + +static InstrHandle *handle_find(InstrHandleID id) +{ + InstrHandle *handle; + QSLIST_FOREACH(handle, &handles, list) { + if (handle->id =3D=3D id) { + return handle; + } + } + return NULL; +} + +InstrLoadError instr_load(const char * path, int argc, const char ** argv, + int64_t *handle_id) +{ + InstrLoadError res; + InstrHandle * handle; + int (*main_cb)(int, const char **); + int main_res; + + qemu_rec_mutex_lock(&instr_lock); + + *handle_id =3D -1; + + if (!QSLIST_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_get(); + 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; + } + + *handle_id =3D handle->id; + res =3D INSTR_LOAD_OK; + goto out; + +err: + handle_put(handle->id); +out: + qemu_rec_mutex_unlock(&instr_lock); + return res; +} + +InstrUnloadError instr_unload(int64_t handle_id) +{ + InstrLoadError res; + + qemu_rec_mutex_lock(&instr_lock); + + InstrHandle *handle =3D handle_find(handle_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_put(handle->id); + +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 QSLIST_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..2ddb2c6c19 --- /dev/null +++ b/instrument/load.h @@ -0,0 +1,83 @@ +/* + * 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 "qemu/queue.h" +#include "qemu/thread.h" + + +/** + * InstrLoadError: + * @INSTR_LOAD_OK: Correctly loaded. + * @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_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. + * @handle: Instrumentation library handle (undefined in case of error). + * + * Load a dynamic trace instrumentation library. + * + * Returns: Whether the library could be loaded. + */ +InstrLoadError instr_load(const char * path, int argc, const char ** argv, + int64_t *handle); + +/** + * instr_unload: + * @handle: Instrumentation library handle returned by instr_load(). + * + * Unload the given instrumentation library. + * + * Returns: Whether the library could be unloaded. + */ +InstrUnloadError instr_unload(int64_t handle); + +/** + * instr_unload_all: + * + * Unload all instrumentation libraries. + * + * Returns: Whether any library could not be unloaded. + */ +InstrUnloadError instr_unload_all(void); + +#endif /* INSTRUMENT_LOAD_H */ From nobody Thu May 2 05:58:20 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 1504719635338646.2005442713955; Wed, 6 Sep 2017 10:40:35 -0700 (PDT) Received: from localhost ([::1]:37300 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeJV-0005MI-86 for importer@patchew.org; Wed, 06 Sep 2017 13:40:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39232) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeIJ-0004lT-8q for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:39:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpeIG-00007L-5M for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:39:19 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:57729) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeIF-00006u-RO for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:39: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 v86HcwFk004086; Wed, 6 Sep 2017 19:38:58 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id B8BF1126C; Wed, 6 Sep 2017 19:38:52 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 20:38:50 +0300 Message-Id: <150471953040.24907.10182874912246869287.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86HcwFk004086 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 v4 04/20] 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 , "Emilio G. Cota" , Laurent Vivier , 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 | 19 +++++++++++++++++++ linux-user/syscall.c | 4 ++++ 2 files changed, 23 insertions(+) diff --git a/linux-user/main.c b/linux-user/main.c index 03666ef657..25253bc28a 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,7 @@ int main(int argc, char **argv, char **envp) srand(time(NULL)); =20 qemu_add_opts(&qemu_trace_opts); + qemu_add_opts(&qemu_instr_opts); =20 optind =3D parse_args(argc, argv); =20 @@ -4265,6 +4282,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 Thu May 2 05:58:20 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 150471983925837.25232333193844; Wed, 6 Sep 2017 10:43:59 -0700 (PDT) Received: from localhost ([::1]:37311 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeMo-0006a9-5S for importer@patchew.org; Wed, 06 Sep 2017 13:43:58 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40119) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeLz-0006Gg-KB for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:43:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpeLw-0001X8-IW for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:43:07 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:58762) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeLw-0001Wh-7E for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:43:04 -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 v86Hh0s5004203; Wed, 6 Sep 2017 19:43:00 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id C0B02323; Wed, 6 Sep 2017 19:42:54 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 20:42:53 +0300 Message-Id: <150471977282.24907.9071837694091118220.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86Hh0s5004203 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 v4 05/20] 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" , 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 | 15 +++++++++++++++ bsd-user/syscall.c | 5 +++++ 2 files changed, 20 insertions(+) diff --git a/bsd-user/main.c b/bsd-user/main.c index 8a6706a1c8..2cf75290cd 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,7 @@ int main(int argc, char **argv) cpu_model =3D NULL; =20 qemu_add_opts(&qemu_trace_opts); + qemu_add_opts(&qemu_instr_opts); =20 optind =3D 1; for (;;) { @@ -843,6 +853,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 +885,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 Thu May 2 05:58:20 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 1504720081696207.11014886005773; Wed, 6 Sep 2017 10:48:01 -0700 (PDT) Received: from localhost ([::1]:37319 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeQi-0008BT-7t for importer@patchew.org; Wed, 06 Sep 2017 13:48:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41046) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpePu-0007kw-8B for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:47:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpePr-0003hv-6o for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:47:10 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:58780) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpePq-0003hh-RU for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:47:07 -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 v86Hl2td004294; Wed, 6 Sep 2017 19:47:02 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id D00DD7FD; Wed, 6 Sep 2017 19:46:56 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 20:46:55 +0300 Message-Id: <150472001548.24907.17836290049474089908.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86Hl2td004294 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 v4 06/20] 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" , 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 8e247cc2a2..10dfea3ec7 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 @@ -3035,6 +3036,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 @@ -3062,6 +3066,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); @@ -4003,6 +4010,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); @@ -4190,6 +4203,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 Thu May 2 05:58:20 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 15047203354911016.5959458492405; Wed, 6 Sep 2017 10:52:15 -0700 (PDT) Received: from localhost ([::1]:37328 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeUo-0000sC-4c for importer@patchew.org; Wed, 06 Sep 2017 13:52:14 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41657) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeTp-0000EX-VC for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:51:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpeTl-0005pB-2i for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:51:14 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:41489) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeTk-0005oB-Id for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:51:08 -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 v86Hp4r2004372; Wed, 6 Sep 2017 19:51:04 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 36F8E11D; Wed, 6 Sep 2017 19:50:59 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 20:50:57 +0300 Message-Id: <150472025751.24907.6133235993130047929.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86Hp4r2004372 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 v4 07/20] 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: "Emilio G. Cota" , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= , Stefan Hajnoczi , Markus Armbruster 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/Makefile.objs | 1=20 instrument/load.h | 4 ++ instrument/qmp.c | 88 ++++++++++++++++++++++++++++++++++++++++++ qapi-schema.json | 3 + qapi/instrument.json | 96 ++++++++++++++++++++++++++++++++++++++++++= ++++ 5 files changed, 192 insertions(+) create mode 100644 instrument/qmp.c create mode 100644 qapi/instrument.json diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs index 5ea5c77245..13a8f60431 100644 --- a/instrument/Makefile.objs +++ b/instrument/Makefile.objs @@ -2,3 +2,4 @@ =20 target-obj-y +=3D cmdline.o target-obj-$(CONFIG_INSTRUMENT) +=3D load.o +target-obj-y +=3D qmp.o diff --git a/instrument/load.h b/instrument/load.h index 2ddb2c6c19..f8a02e6849 100644 --- a/instrument/load.h +++ b/instrument/load.h @@ -25,6 +25,8 @@ * @INSTR_LOAD_DLERROR: Error with libdl (see dlerror). * * Error codes for instr_load(). + * + * NOTE: Keep in sync with QAPI's #InstrLoadCode. */ typedef enum { INSTR_LOAD_OK, @@ -40,6 +42,8 @@ typedef enum { * @INSTR_UNLOAD_DLERROR: Error with libdl (see dlerror). * * Error codes for instr_unload(). + * + * NOTE: Keep in sync with QAPI's #InstrUnloadCode. */ typedef enum { INSTR_UNLOAD_OK, diff --git a/instrument/qmp.c b/instrument/qmp.c new file mode 100644 index 0000000000..c36960c12f --- /dev/null +++ b/instrument/qmp.c @@ -0,0 +1,88 @@ +/* + * 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 "qemu-common.h" +#include "qapi/qmp/qerror.h" +#include "qmp-commands.h" + +#include + +#include "instrument/load.h" + + + +InstrLoadResult *qmp_instr_load(const char * path, + bool have_args, strList * args, + Error **errp) +{ + InstrLoadResult *res =3D g_malloc0(sizeof(*res)); + +#if defined(CONFIG_INSTRUMENT) + int argc =3D 0; + const char **argv =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; + } + + InstrLoadError code =3D instr_load(path, argc, argv, &res->handle); + switch (code) { + case INSTR_LOAD_OK: + res->code =3D INSTR_LOAD_CODE_OK; + res->has_handle =3D true; + break; + case INSTR_LOAD_TOO_MANY: + res->code =3D INSTR_LOAD_CODE_TOO_MANY; + break; + case INSTR_LOAD_ERROR: + res->code =3D INSTR_LOAD_CODE_ERROR; + break; + case INSTR_LOAD_DLERROR: + res->has_msg =3D true; + res->msg =3D dlerror(); + res->code =3D INSTR_LOAD_CODE_DLERROR; + break; + } +#else + res->code =3D INSTR_LOAD_CODE_UNAVAILABLE; +#endif + + return res; +} + +InstrUnloadResult *qmp_instr_unload(int64_t handle, Error **errp) +{ + InstrUnloadResult *res =3D g_malloc0(sizeof(*res)); + +#if defined(CONFIG_INSTRUMENT) + InstrUnloadError code =3D instr_unload(handle); + switch (code) { + case INSTR_UNLOAD_OK: + res->code =3D INSTR_UNLOAD_CODE_OK; + break; + case INSTR_UNLOAD_INVALID: + res->code =3D INSTR_UNLOAD_CODE_INVALID; + break; + case INSTR_UNLOAD_DLERROR: + res->has_msg =3D true; + res->msg =3D dlerror(); + break; + res->code =3D INSTR_UNLOAD_CODE_DLERROR; + } +#else + res->code =3D INSTR_UNLOAD_CODE_UNAVAILABLE; +#endif + + return res; +} diff --git a/qapi-schema.json b/qapi-schema.json index 802ea53d00..5e343be9ff 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -90,6 +90,9 @@ # QAPI introspection { 'include': 'qapi/introspect.json' } =20 +# Instrumentation commands +{ 'include': 'qapi/instrument.json' } + ## # =3D QMP commands ## diff --git a/qapi/instrument.json b/qapi/instrument.json new file mode 100644 index 0000000000..ea63fae309 --- /dev/null +++ b/qapi/instrument.json @@ -0,0 +1,96 @@ +# *-*- Mode: Python -*-* +# +# QAPI 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 later. +# See the COPYING file in the top-level directory. + +## +# @InstrLoadCode: +# +# Result code of an 'instr-load' command. +# +# @ok: Correctly loaded. +# @too-many: Tried to load too many instrumentation libraries. +# @error: The library's main() function returned a non-zero value. +# @dlerror: Error with libdl (see 'msg'). +# @unavailable: Service not available. +# +# Since: 2.11 +## +{ 'enum': 'InstrLoadCode', + 'data': [ 'ok', 'too-many', 'error', 'dlerror', 'unavailable' ] } + +## +# @InstrLoadResult: +# +# Result of an 'instr-load' command. +# +# @code: Result code. +# @msg: Additional error message (for human consumption only; present only= in +# case of error). +# @handle: Instrumentation library identifier (present only if successful). +# +# Since: 2.11 +## +{ 'struct': 'InstrLoadResult', + 'data': { 'code': 'InstrLoadCode', '*msg': 'str', '*handle': 'int' } } + +## +# @instr-load: +# +# Load an instrumentation library. +# +# @path: path to the dynamic instrumentation library +# @args: arguments to the dynamic instrumentation library +# +# Since: 2.11 +## +{ 'command': 'instr-load', + 'data': { 'path': 'str', '*args': ['str'] }, + 'returns': 'InstrLoadResult' } + + +## +# @InstrUnloadCode: +# +# Result code of an 'instr-unload' command. +# +# @ok: Correctly unloaded. +# @invalid: Invalid handle. +# @dlerror: Error with libdl (see 'msg'). +# @unavailable: Service not available. +# +# Since: 2.11 +## +{ 'enum': 'InstrUnloadCode', + 'data': [ 'ok', 'invalid', 'dlerror', 'unavailable' ] } + +## +# @InstrUnloadResult: +# +# Result of an 'instr-unload' command. +# +# @code: Result code. +# @msg: Additional error message (for human consumption only; present only= in +# case of error). +# +# Since: 2.11 +## +{ 'struct': 'InstrUnloadResult', + 'data': { 'code': 'InstrUnloadCode', '*msg': 'str' } } + +## +# @instr-unload: +# +# Unload an instrumentation library. +# +# @handle: Instrumentation library identifier (see #InstrLoadResult). +# +# Since: 2.11 +## +{ 'command': 'instr-unload', + 'data': { 'handle': 'int' }, + 'returns': 'InstrUnloadResult' } From nobody Thu May 2 05:58:20 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 1504720596730492.86777211101196; Wed, 6 Sep 2017 10:56:36 -0700 (PDT) Received: from localhost ([::1]:37338 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeZ1-0002BC-Ho for importer@patchew.org; Wed, 06 Sep 2017 13:56:35 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42605) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeXj-0001Ya-RL for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:55:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpeXe-0002ZU-W2 for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:55:15 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:47217) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeXe-0002Yv-Ju for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:55:10 -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 v86Ht7rv004480; Wed, 6 Sep 2017 19:55:07 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id 68D2633A; Wed, 6 Sep 2017 19:55:01 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 20:55:00 +0300 Message-Id: <150472050004.24907.4613952373869620144.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86Ht7rv004480 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 v4 08/20] 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" , "Dr. David Alan Gilbert" , Stefan Hajnoczi , Markus Armbruster 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 | 28 ++++++++++++++++++++++++++ monitor.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 88 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index 1941e19932..703d7262f5 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1858,6 +1858,34 @@ ETEXI .sub_table =3D info_cmds, }, =20 + { + .name =3D "instr-load", + .args_type =3D "path:F,args:s?", + .params =3D "path [arg]", + .help =3D "load an instrumentation library", + .cmd =3D hmp_instr_load, + }, + +STEXI +@item instr-load @var{path} [args=3Dvalue[,...]] +@findex instr-load +Load an instrumentation library. +ETEXI + + { + .name =3D "instr-unload", + .args_type =3D "handle:i", + .params =3D "handle", + .help =3D "unload an instrumentation library", + .cmd =3D hmp_instr_unload, + }, + +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 e0f880107f..8a7684f860 100644 --- a/monitor.c +++ b/monitor.c @@ -2319,6 +2319,66 @@ int monitor_fd_param(Monitor *mon, const char *fdnam= e, Error **errp) return fd; } =20 +static void hmp_instr_load(Monitor *mon, const QDict *qdict) +{ + const char *path =3D qdict_get_str(qdict, "path"); + const char *str =3D qdict_get_try_str(qdict, "args"); + strList args; + args.value =3D (str =3D=3D NULL) ? NULL : (char *)str; + args.next =3D NULL; + InstrLoadResult *res =3D qmp_instr_load(path, args.value !=3D NULL, + args.value !=3D NULL ? &args : N= ULL, + NULL); + switch (res->code) { + case INSTR_LOAD_CODE_OK: + monitor_printf(mon, "Handle: %"PRId64"\n", res->handle); + monitor_printf(mon, "OK\n"); + break; + case INSTR_LOAD_CODE_TOO_MANY: + monitor_printf(mon, "Too many instrumentation libraries already lo= aded\n"); + break; + case INSTR_LOAD_CODE_ERROR: + monitor_printf(mon, "Instrumentation library returned a non-zero v= alue during initialization"); + break; + case INSTR_LOAD_CODE_DLERROR: + monitor_printf(mon, "Error loading library: %s\n", res->msg); + break; + case INSTR_LOAD_CODE_UNAVAILABLE: + monitor_printf(mon, "Service not available\n"); + break; + default: + fprintf(stderr, "Unknown instrumentation load code: %d", res->code= ); + exit(1); + break; + } + qapi_free_InstrLoadResult(res); +} + +static void hmp_instr_unload(Monitor *mon, const QDict *qdict) +{ + int64_t handle =3D qdict_get_int(qdict, "handle"); + InstrUnloadResult *res =3D qmp_instr_unload(handle, NULL); + switch (res->code) { + case INSTR_UNLOAD_CODE_OK: + monitor_printf(mon, "OK\n"); + break; + case INSTR_UNLOAD_CODE_INVALID: + monitor_printf(mon, "Invalid handle\n"); + break; + case INSTR_UNLOAD_CODE_DLERROR: + monitor_printf(mon, "Error unloading library: %s\n", res->msg); + break; + case INSTR_UNLOAD_CODE_UNAVAILABLE: + monitor_printf(mon, "Service not available\n"); + break; + default: + fprintf(stderr, "Unknown instrumentation unload code: %d", res->co= de); + exit(1); + break; + } + qapi_free_InstrUnloadResult(res); +} + /* Please update hmp-commands.hx when adding or changing commands */ static mon_cmd_t info_cmds[] =3D { #include "hmp-commands-info.h" From nobody Thu May 2 05:58:20 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 1504720834399619.7644149289906; Wed, 6 Sep 2017 11:00:34 -0700 (PDT) Received: from localhost ([::1]:37352 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpecr-00044V-Fm for importer@patchew.org; Wed, 06 Sep 2017 14:00:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44471) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpebf-0003RH-96 for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:59:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpebZ-0007p4-KB for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:59:19 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:38567) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpebZ-0007no-0L for qemu-devel@nongnu.org; Wed, 06 Sep 2017 13:59:13 -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 v86Hx9Jr004576; Wed, 6 Sep 2017 19:59:09 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id ACAA5323; Wed, 6 Sep 2017 19:59:03 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 20:59:02 +0300 Message-Id: <150472074219.24907.5510718414753398145.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86Hx9Jr004576 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 v4 09/20] 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: Paolo Bonzini , "Emilio G. Cota" , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= , 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 --- Makefile | 5 +++ configure | 1 + instrument/Makefile.objs | 2 + 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 | 43 +++++++++++++++++++++++++++ instrument/qemu-instr/visibility.h | 58 ++++++++++++++++++++++++++++++++= ++++ stubs/Makefile.objs | 1 + stubs/instrument.c | 13 ++++++++ 14 files changed, 309 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 create mode 100644 instrument/qemu-instr/visibility.h create mode 100644 stubs/instrument.c diff --git a/Makefile b/Makefile index 81447b1f08..6171661458 100644 --- a/Makefile +++ b/Makefile @@ -589,6 +589,11 @@ 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/" + $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/visibility.h "$(DESTDIR= )$(includedir)/qemu-instr/" +endif =20 install-datadir: $(INSTALL_DIR) "$(DESTDIR)$(qemu_datadir)" diff --git a/configure b/configure index 05bd7b1950..3673fc9058 100755 --- a/configure +++ b/configure @@ -6038,6 +6038,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/instrument/Makefile.objs b/instrument/Makefile.objs index 13a8f60431..9b7e1c03aa 100644 --- a/instrument/Makefile.objs +++ b/instrument/Makefile.objs @@ -3,3 +3,5 @@ target-obj-y +=3D cmdline.o target-obj-$(CONFIG_INSTRUMENT) +=3D load.o target-obj-y +=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..2c2781beeb --- /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 "instrument/qemu-instr/visibility.h" + +__thread InstrState instr_cur_state; + + +qi_fini_fn instr_event__fini_fn; +void *instr_event__fini_data; + +QI_VPUBLIC 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 a57401102a..e180f03429 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" @@ -105,8 +107,11 @@ InstrLoadError instr_load(const char * path, int argc,= const 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; @@ -136,6 +141,14 @@ InstrUnloadError instr_unload(int64_t handle_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..f6e289daa0 --- /dev/null +++ b/instrument/qemu-instr/control.h @@ -0,0 +1,43 @@ +/* + * 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. + */ +void qi_set_fini(qi_fini_fn fn, void *data); + +#ifdef __cplusplus +} +#endif + +#endif /* QI__CONTROL_H */ diff --git a/instrument/qemu-instr/visibility.h b/instrument/qemu-instr/vis= ibility.h new file mode 100644 index 0000000000..305dddf7d8 --- /dev/null +++ b/instrument/qemu-instr/visibility.h @@ -0,0 +1,58 @@ +/* + * Macros for symbol visibility. + * + * 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 of QEMU. + */ + +#ifndef QI__VISIBILITY_H +#define QI__VISIBILITY_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * SECTION:visibility + * @section_id: qi-visibility + * @title: Symbol visibility + * + * This code is taken from http://gcc.gnu.org/wiki/Visibility. + */ + +/** + * QI_VPUBLIC: + * + * Make an element public to user's instrumentation code. + */ + +/** + * QI_VLOCAL: + * + * Make an element not visible to user's instrumentation code. + */ + +#if defined _WIN32 || defined __CYGWIN__ + #ifdef __GNUC__ + #define QI_VPUBLIC __attribute__ ((dllimport)) + #else + #define QI_VPUBLIC __declspec(dllimport) + #endif + #define QI_VLOCAL +#else + #if __GNUC__ >=3D 4 + #define QI_VPUBLIC __attribute__ ((visibility ("default"))) + #define QI_VLOCAL __attribute__ ((visibility ("hidden"))) + #else + #define QI_VPUBLIC + #define QI_VLOCAL + #endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* QI__VISIBILITY_H */ diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index e69c217aff..3aaec2d9dd 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..6731710fd5 --- /dev/null +++ b/stubs/instrument.c @@ -0,0 +1,13 @@ +/* + * 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/control.h" + + +__thread InstrState instr_cur_state; From nobody Thu May 2 05:58:20 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 1504721074573593.2046495864652; Wed, 6 Sep 2017 11:04:34 -0700 (PDT) Received: from localhost ([::1]:37360 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpegj-0005Hd-1J for importer@patchew.org; Wed, 06 Sep 2017 14:04:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45593) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpefZ-0004mF-4P for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:03:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpefT-0003yd-Ur for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:03:21 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:56110) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpefT-0003xz-E4 for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:03:15 -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 v86I3BWA004672; Wed, 6 Sep 2017 20:03:11 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id 0FED51DF; Wed, 6 Sep 2017 20:03:05 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 21:03:04 +0300 Message-Id: <150472098452.24907.17299050957814650497.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86I3BWA004672 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 v4 10/20] 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" , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= , 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 --- .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 6171661458..6f4de75f79 100644 --- a/Makefile +++ b/Makefile @@ -592,6 +592,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/" $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/visibility.h "$(DESTDIR= )$(includedir)/qemu-instr/" endif =20 diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs index 9b7e1c03aa..8258dbfa79 100644 --- a/instrument/Makefile.objs +++ b/instrument/Makefile.objs @@ -5,3 +5,4 @@ target-obj-$(CONFIG_INSTRUMENT) +=3D load.o target-obj-y +=3D qmp.o =20 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..a73fcdf50a --- /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-instr/trace.h" +#include "qemu-instr/visibility.h" +#include "trace/control.h" + + +QI_VPUBLIC +QITraceEvent *qi_trace_event_name(const char *name) +{ + ERROR_IF_RET(!name, NULL, "must provide a name"); + return (QITraceEvent *)trace_event_name(name); +} + +QI_VPUBLIC +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); +} + +QI_VPUBLIC +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_); +} + + +QI_VPUBLIC +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_); +} + +QI_VPUBLIC +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_); +} + + +QI_VPUBLIC +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_); +} + +QI_VPUBLIC +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_); +} + +QI_VPUBLIC +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_); +} + +QI_VPUBLIC +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_); +} + +QI_VPUBLIC +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_); +} + +QI_VPUBLIC +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); +} + +QI_VPUBLIC +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 Thu May 2 05:58:20 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 1504721347652676.6818326844108; Wed, 6 Sep 2017 11:09:07 -0700 (PDT) Received: from localhost ([::1]:37374 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpel8-0007o9-MS for importer@patchew.org; Wed, 06 Sep 2017 14:09:06 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46714) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpejT-0006gd-OV for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:07:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpejP-0008Sg-Fb for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:07:23 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:56132) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpejP-0008PE-4n for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:07:19 -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 v86I7Dur004766; Wed, 6 Sep 2017 20:07:13 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 2F70A8AF; Wed, 6 Sep 2017 20:07:08 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 21:07:06 +0300 Message-Id: <150472122675.24907.11597641982841030964.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86I7Dur004766 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 v4 11/20] 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" , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= , Stefan Hajnoczi 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 | 22 ++++++++++++++++++++++ instrument/control.h | 32 ++++++++++++++++++++++++++++++++ instrument/control.inc.h | 23 +++++++++++++++++++++++ 4 files changed, 86 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 2c2781beeb..83453ea561 100644 --- a/instrument/control.c +++ b/instrument/control.c @@ -13,10 +13,32 @@ #include "instrument/load.h" #include "instrument/qemu-instr/control.h" #include "instrument/qemu-instr/visibility.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_cpu= s_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..0c37692465 100644 --- a/instrument/control.h +++ b/instrument/control.h @@ -10,6 +10,38 @@ #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. + */ +void instr_cpu_add(CPUState *vcpu); + +/** + * instr_cpu_remove: + * + * Make @vcpu unavailable to instrumentation clients. + */ +void instr_cpu_remove(CPUState *vcpu); + +/** + * instr_cpu_get: + * + * Get the #CPUState corresponding to the given #QICPU. + */ +static inline CPUState *instr_cpu_get(QICPU vcpu); + +/** + * instr_cpu_set: + * + * Get the #QICPU corresponding to the given #CPUState. + */ +static inline QICPU instr_cpu_set(CPUState *vcpu); + =20 /** * InstrState: diff --git a/instrument/control.inc.h b/instrument/control.inc.h index 0f649f4caa..18ae6a34cc 100644 --- a/instrument/control.inc.h +++ b/instrument/control.inc.h @@ -7,9 +7,12 @@ * 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 =20 =20 extern __thread InstrState instr_cur_state; @@ -23,3 +26,23 @@ static inline InstrState instr_get_state(void) { return atomic_load_acquire(&instr_cur_state); } + + +extern unsigned int instr_cpus_count; +extern CPUState **instr_cpus; + +static inline CPUState *instr_cpu_get(QICPU vcpu) +{ + unsigned int idx =3D (uintptr_t)vcpu; + if (idx >=3D instr_cpus_count) { + return NULL; + } else { + return instr_cpus[idx]; + } +} + +static inline QICPU instr_cpu_set(CPUState *vcpu) +{ + uintptr_t idx =3D vcpu->cpu_index; + return (QICPU )idx; +} From nobody Thu May 2 05:58:20 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 1504721555290458.44531065034187; Wed, 6 Sep 2017 11:12:35 -0700 (PDT) Received: from localhost ([::1]:37385 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpeoT-00012D-Jk for importer@patchew.org; Wed, 06 Sep 2017 14:12:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47442) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpenK-00008f-Ti for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:11:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpenG-0002iC-TL for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:11:22 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:33722) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpenG-0002hn-EG for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:11: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 v86IBFXr004859; Wed, 6 Sep 2017 20:11:15 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 7BDFF7FD; Wed, 6 Sep 2017 20:11:10 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 21:11:09 +0300 Message-Id: <150472146893.24907.1040882648962239022.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86IBFXr004859 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 v4 12/20] 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: Paolo Bonzini , "Emilio G. Cota" , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= , 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 --- instrument/control.c | 9 ++++++++ instrument/events.h | 5 ++++ instrument/events.inc.h | 11 ++++++++++ instrument/load.c | 1 + instrument/qemu-instr/control.h | 44 +++++++++++++++++++++++++++++++++++= ++++ stubs/instrument.c | 1 + trace/control-target.c | 2 ++ 7 files changed, 73 insertions(+) diff --git a/instrument/control.c b/instrument/control.c index 83453ea561..ed0d537b88 100644 --- a/instrument/control.c +++ b/instrument/control.c @@ -48,3 +48,12 @@ QI_VPUBLIC 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); + +QI_VPUBLIC 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..238cce9855 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_set(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 e180f03429..0fe878afa8 100644 --- a/instrument/load.c +++ b/instrument/load.c @@ -148,6 +148,7 @@ InstrUnloadError instr_unload(int64_t handle_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 f6e289daa0..26d8aa976d 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 /** @@ -36,6 +37,49 @@ 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. + * + * 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 6731710fd5..658a872e1c 100644 --- a/stubs/instrument.c +++ b/stubs/instrument.c @@ -11,3 +11,4 @@ =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 0056da6a46..e47361cef8 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" @@ -147,5 +148,6 @@ void trace_init_vcpu(CPUState *vcpu) } } } + instr_guest_cpu_enter(vcpu); trace_guest_cpu_enter(vcpu); } From nobody Thu May 2 05:58:20 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 1504721774179351.15959503371005; Wed, 6 Sep 2017 11:16:14 -0700 (PDT) Received: from localhost ([::1]:37400 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpes0-0002RC-V7 for importer@patchew.org; Wed, 06 Sep 2017 14:16:12 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48849) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dperG-000295-WC for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:15:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dperC-0004Jk-T2 for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:15:26 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:47387) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dperC-0004JX-Hc for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:15:22 -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 v86IFIB6004929; Wed, 6 Sep 2017 20:15:18 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 5A4067FD; Wed, 6 Sep 2017 20:15:13 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 21:15:11 +0300 Message-Id: <150472171121.24907.12569584037182483614.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86IFIB6004929 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 v4 13/20] 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: Paolo Bonzini , "Emilio G. Cota" , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= , 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 --- instrument/control.c | 9 +++++++++ instrument/events.h | 3 +++ instrument/events.inc.h | 11 +++++++++++ instrument/load.c | 1 + instrument/qemu-instr/control.h | 9 +++++++++ stubs/instrument.c | 1 + trace/control.c | 4 +++- 7 files changed, 37 insertions(+), 1 deletion(-) diff --git a/instrument/control.c b/instrument/control.c index ed0d537b88..09ba682483 100644 --- a/instrument/control.c +++ b/instrument/control.c @@ -57,3 +57,12 @@ QI_VPUBLIC 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); + +QI_VPUBLIC 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 238cce9855..bcbf0cb32a 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_set(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 0fe878afa8..63b7d564ec 100644 --- a/instrument/load.c +++ b/instrument/load.c @@ -149,6 +149,7 @@ InstrUnloadError instr_unload(int64_t handle_id) =20 instr_set_event(fini_fn, NULL); instr_set_event(guest_cpu_enter, NULL); + instr_set_event(guest_cpu_exit, 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 26d8aa976d..c37a380ab0 100644 --- a/instrument/qemu-instr/control.h +++ b/instrument/qemu-instr/control.h @@ -80,6 +80,15 @@ 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. + * + * 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 658a872e1c..ea8df6d467 100644 --- a/stubs/instrument.c +++ b/stubs/instrument.c @@ -12,3 +12,4 @@ =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 Thu May 2 05:58:20 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 1504722029633801.1481539101665; Wed, 6 Sep 2017 11:20:29 -0700 (PDT) Received: from localhost ([::1]:37408 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpew8-00043r-FS for importer@patchew.org; Wed, 06 Sep 2017 14:20:28 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49769) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpevA-0003i3-Tx for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:19:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpev6-0005w3-Sr for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:19:28 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:39560) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpev6-0005vr-Hn for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:19:24 -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 v86IJLWp005042; Wed, 6 Sep 2017 20:19:21 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id A8DFF1DF; Wed, 6 Sep 2017 20:19:15 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 21:19:14 +0300 Message-Id: <150472195416.24907.15859962605541218107.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86IJLWp005042 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 v4 14/20] 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: Paolo Bonzini , "Emilio G. Cota" , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= , 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 --- 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 09ba682483..3cec1028e5 100644 --- a/instrument/control.c +++ b/instrument/control.c @@ -66,3 +66,12 @@ QI_VPUBLIC void qi_event_set_guest_cpu_exit(void (*fn)(Q= ICPU vcpu)) ERROR_IF(!instr_get_state(), "called outside instrumentation"); instr_set_event(guest_cpu_exit, fn); } + + +void (*instr_event__guest_cpu_reset)(QICPU vcpu); + +QI_VPUBLIC 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 bcbf0cb32a..2f2cd324aa 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_set(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 63b7d564ec..d9310d1979 100644 --- a/instrument/load.c +++ b/instrument/load.c @@ -150,6 +150,7 @@ InstrUnloadError instr_unload(int64_t handle_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 /* 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 c37a380ab0..238ea63301 100644 --- a/instrument/qemu-instr/control.h +++ b/instrument/qemu-instr/control.h @@ -89,6 +89,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 4f38db0dac..d09cf583eb 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" @@ -271,6 +272,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 ea8df6d467..74935975da 100644 --- a/stubs/instrument.c +++ b/stubs/instrument.c @@ -13,3 +13,4 @@ __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 Thu May 2 05:58:20 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 1504722265307258.37248367585835; Wed, 6 Sep 2017 11:24:25 -0700 (PDT) Received: from localhost ([::1]:37423 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpezw-0006cZ-1j for importer@patchew.org; Wed, 06 Sep 2017 14:24:24 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51709) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpezA-0006Ix-6k for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:23:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpez4-000806-ST for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:23:36 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:50999) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpez4-0007zk-D6 for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:23:30 -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 v86INNiT005145; Wed, 6 Sep 2017 20:23:23 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id DC520355; Wed, 6 Sep 2017 20:23:17 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 21:23:16 +0300 Message-Id: <150472219643.24907.18130899263866950639.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86INNiT005145 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 v4 15/20] 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 , "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 87f673ef49..234e300ede 100644 --- a/tcg/tcg-op.c +++ b/tcg/tcg-op.c @@ -2664,22 +2664,26 @@ static void gen_ldst_i64(TCGOpcode opc, TCGv_i64 va= l, TCGv addr, =20 void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp mem= op) { + TraceMemInfo meminfo; 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; 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; + if (TCG_TARGET_REG_BITS =3D=3D 32 && (memop & MO_SIZE) < MO_64) { tcg_gen_qemu_ld_i32(TCGV_LOW(val), addr, idx, memop); if (memop & MO_SIGN) { @@ -2691,21 +2695,23 @@ 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; + if (TCG_TARGET_REG_BITS =3D=3D 32 && (memop & MO_SIZE) < MO_64) { tcg_gen_qemu_st_i32(TCGV_LOW(val), addr, idx, memop); return; } =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 Thu May 2 05:58:20 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 1504722526687873.1966069808263; Wed, 6 Sep 2017 11:28:46 -0700 (PDT) Received: from localhost ([::1]:37439 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpf49-0007w1-M6 for importer@patchew.org; Wed, 06 Sep 2017 14:28:45 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53388) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpf31-0007QH-SB for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:27:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpf2w-000108-8C for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:27:35 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:51016) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpf2v-0000zq-Lt for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:27:30 -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 v86IRPi1005211; Wed, 6 Sep 2017 20:27:25 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 416F57FD; Wed, 6 Sep 2017 20:27:20 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 21:27:18 +0300 Message-Id: <150472243868.24907.11184861173318139147.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86IRPi1005211 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 v4 16/20] 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: "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 | 13 +++++++- instrument/control.h | 36 +++++++++++++++++++++- instrument/control.inc.h | 16 +++++++--- instrument/events.h | 21 +++++++++++++ instrument/events.inc.h | 19 ++++++++++++ instrument/load.c | 1 + instrument/qemu-instr/control.h | 15 +++++++++ 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, 210 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 3cec1028e5..3c3875dc99 100644 --- a/instrument/control.c +++ b/instrument/control.c @@ -16,7 +16,7 @@ #include "qom/cpu.h" =20 =20 -__thread InstrState instr_cur_state; +__thread InstrInfo instr_cur_info; =20 =20 unsigned int instr_cpus_count; @@ -75,3 +75,14 @@ QI_VPUBLIC 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); + +QI_VPUBLIC void qi_event_set_guest_mem_before_trans( + void (*fn)(QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMem= Info info)) +{ + ERROR_IF(!instr_get_state(), "called outside instrumentation"); + instr_set_event(guest_mem_before_trans, fn); +} diff --git a/instrument/control.h b/instrument/control.h index 0c37692465..d9e3dd3da6 100644 --- a/instrument/control.h +++ b/instrument/control.h @@ -56,12 +56,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: @@ -70,6 +79,29 @@ static inline void instr_set_state(InstrState state); */ static inline InstrState instr_get_state(void); =20 +/** + * instr_tcg_set: + * @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_set(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 18ae6a34cc..e8224319e0 100644 --- a/instrument/control.inc.h +++ b/instrument/control.inc.h @@ -15,16 +15,18 @@ #include =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); } =20 =20 @@ -46,3 +48,9 @@ static inline QICPU instr_cpu_set(CPUState *vcpu) uintptr_t idx =3D vcpu->cpu_index; return (QICPU )idx; } + + +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 2f2cd324aa..2cb17049f7 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,21 @@ 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, QIMem= Info 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_set(vcpu_trans); + QITCGv_cpu vcpu_exec_ =3D instr_tcg_set(iinfo, 0, vcpu_exec); + QITCGv vaddr_ =3D instr_tcg_set(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 d9310d1979..d5612af452 100644 --- a/instrument/load.c +++ b/instrument/load.c @@ -151,6 +151,7 @@ InstrUnloadError instr_unload(int64_t handle_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 /* 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 238ea63301..af4fda138e 100644 --- a/instrument/qemu-instr/control.h +++ b/instrument/qemu-instr/control.h @@ -98,6 +98,21 @@ 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, QIMem= Info 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 74935975da..5e0d5150b5 100644 --- a/stubs/instrument.c +++ b/stubs/instrument.c @@ -10,7 +10,9 @@ #include "instrument/control.h" =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 234e300ede..40de61872e 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 "trace-tcg.h" @@ -2667,6 +2668,7 @@ void tcg_gen_qemu_ld_i32(TCGv_i32 val, TCGv addr, TCG= Arg idx, TCGMemOp memop) TraceMemInfo meminfo; 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); } @@ -2676,6 +2678,7 @@ void tcg_gen_qemu_st_i32(TCGv_i32 val, TCGv addr, TCG= Arg idx, TCGMemOp memop) TraceMemInfo meminfo; 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); } @@ -2696,6 +2699,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); } @@ -2711,6 +2715,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 Thu May 2 05:58:20 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 1504722750961407.8167113542887; Wed, 6 Sep 2017 11:32:30 -0700 (PDT) Received: from localhost ([::1]:37450 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpf7l-0000TM-OB for importer@patchew.org; Wed, 06 Sep 2017 14:32:29 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54587) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpf6y-0008RG-QY for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:31:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpf6t-0002li-UB for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:31:40 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:43208) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpf6t-0002lS-BE for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:31:35 -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 v86IVSQt005348; Wed, 6 Sep 2017 20:31:28 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id BC1D4355; Wed, 6 Sep 2017 20:31:22 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 21:31:21 +0300 Message-Id: <150472268114.24907.6651243060428816063.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86IVSQt005348 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 v4 17/20] 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 , "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 | 35 +++++++++++++++++++++++++= ++++ instrument/control.h | 15 ++++++++++++ instrument/events.h | 5 ++++ instrument/events.inc.h | 18 ++++++++++++++- instrument/helpers.h | 1 + instrument/load.c | 1 + instrument/qemu-instr/control.h | 21 +++++++++++++++++ stubs/instrument.c | 2 ++ 13 files changed, 108 insertions(+), 1 deletion(-) 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 3c3875dc99..f39e81d7c7 100644 --- a/instrument/control.c +++ b/instrument/control.c @@ -14,6 +14,8 @@ #include "instrument/qemu-instr/control.h" #include "instrument/qemu-instr/visibility.h" #include "qom/cpu.h" +#include "exec/helper-proto.h" +#include "exec/helper-gen.h" =20 =20 __thread InstrInfo instr_cur_info; @@ -86,3 +88,36 @@ QI_VPUBLIC void qi_event_set_guest_mem_before_trans( ERROR_IF(!instr_get_state(), "called outside instrumentation"); instr_set_event(guest_mem_before_trans, fn); } + + +QI_VPUBLIC 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"); + InstrInfo *iinfo =3D &instr_cur_info; + TCGv_env vcpu_ =3D instr_tcg_get(iinfo, vcpu); + TCGv vaddr_ =3D instr_tcg_get(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); + +QI_VPUBLIC 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"); + instr_set_event(guest_mem_before_exec, fn); +} diff --git a/instrument/control.h b/instrument/control.h index d9e3dd3da6..19c9c9fb98 100644 --- a/instrument/control.h +++ b/instrument/control.h @@ -54,6 +54,7 @@ static inline QICPU instr_cpu_set(CPUState *vcpu); typedef enum { INSTR_STATE_DISABLE, INSTR_STATE_ENABLE, + INSTR_STATE_ENABLE_TCG, } InstrState; =20 #define INSTR_MAX_TCG_REGS 16 @@ -102,6 +103,20 @@ static inline InstrState instr_get_state(void); */ static inline void instr_tcg_count(InstrInfo *info, unsigned int count); =20 +/** + * instr_tcg_get: + * @info: Pointer to #InstrInfo. + * @arg: QITCG register. + * + * Get a suitable TCGv* from a QITCGv* value. + */ +#define instr_tcg_get(info, arg) \ + ({ \ + unsigned int idx =3D (uintptr_t)arg; \ + ERROR_IF(info->max <=3D idx, "invalid QITCGv register"); \ + info->tcg_regs[idx]; \ + }) + =20 #include "instrument/control.inc.h" =20 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 2cb17049f7..d7a3065ac1 100644 --- a/instrument/events.inc.h +++ b/instrument/events.inc.h @@ -50,7 +50,7 @@ static inline void instr_guest_mem_before_trans( void (*cb)(QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMem= Info 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_set(vcpu_trans); QITCGv_cpu vcpu_exec_ =3D instr_tcg_set(iinfo, 0, vcpu_exec); QITCGv vaddr_ =3D instr_tcg_set(iinfo, 1, vaddr); @@ -61,3 +61,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_set(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..957cdc0993 --- /dev/null +++ b/instrument/helpers.h @@ -0,0 +1 @@ +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 d5612af452..1df660d5d1 100644 --- a/instrument/load.c +++ b/instrument/load.c @@ -152,6 +152,7 @@ InstrUnloadError instr_unload(int64_t handle_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 /* 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 af4fda138e..4fa99a968d 100644 --- a/instrument/qemu-instr/control.h +++ b/instrument/qemu-instr/control.h @@ -113,6 +113,27 @@ void qi_event_set_guest_cpu_reset(void (*fn)(QICPU vcp= u)); void qi_event_set_guest_mem_before_trans( void (*fn)(QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMem= Info 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 5e0d5150b5..c6c279c85e 100644 --- a/stubs/instrument.c +++ b/stubs/instrument.c @@ -16,3 +16,5 @@ 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); +void (*instr_event__guest_mem_before_exec)( + QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMemInfo info); From nobody Thu May 2 05:58:20 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 1504723006384313.76512063007624; Wed, 6 Sep 2017 11:36:46 -0700 (PDT) Received: from localhost ([::1]:37458 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpfBr-0001VH-SB for importer@patchew.org; Wed, 06 Sep 2017 14:36:43 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55692) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpfAy-0001Br-Jc for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:35:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpfAt-0004dx-Ah for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:35:48 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:33047) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpfAs-0004dY-UW for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:35:43 -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 v86IZUrY005405; Wed, 6 Sep 2017 20:35:30 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id EC3658AF; Wed, 6 Sep 2017 20:35:24 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 21:35:23 +0300 Message-Id: <150472292357.24907.8416317535071720615.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86IZUrY005405 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 v4 18/20] 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 , 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 | 14 ++++++++++++++ instrument/events.h | 7 +++++++ instrument/events.inc.h | 16 ++++++++++++++++ instrument/load.c | 1 + instrument/qemu-instr/control.h | 15 +++++++++++++++ linux-user/syscall.c | 1 + stubs/instrument.c | 3 +++ 8 files changed, 60 insertions(+) diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c index 3230f722f3..43f8887529 100644 --- a/bsd-user/syscall.c +++ b/bsd-user/syscall.c @@ -324,6 +324,7 @@ 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, arg8); 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 +424,7 @@ 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 +501,7 @@ 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 f39e81d7c7..7e84dadf24 100644 --- a/instrument/control.c +++ b/instrument/control.c @@ -121,3 +121,17 @@ QI_VPUBLIC void qi_event_set_guest_mem_before_exec( ERROR_IF(!instr_get_state(), "called outside instrumentation"); 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); + +QI_VPUBLIC 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"); + 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 d7a3065ac1..9c64497533 100644 --- a/instrument/events.inc.h +++ b/instrument/events.inc.h @@ -77,3 +77,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_set(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 1df660d5d1..d977049082 100644 --- a/instrument/load.c +++ b/instrument/load.c @@ -153,6 +153,7 @@ InstrUnloadError instr_unload(int64_t handle_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 /* 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 4fa99a968d..cba8ade54e 100644 --- a/instrument/qemu-instr/control.h +++ b/instrument/qemu-instr/control.h @@ -134,6 +134,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..c0c33d4a75 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -7723,6 +7723,7 @@ 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, arg8); 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 c6c279c85e..dbd8b1438d 100644 --- a/stubs/instrument.c +++ b/stubs/instrument.c @@ -18,3 +18,6 @@ void (*instr_event__guest_mem_before_trans)( QICPU vcpu_trans, QITCGv_cpu vcpu_exec, QITCGv vaddr, QIMemInfo info); 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 Thu May 2 05:58:20 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 1504723244698927.3792267513346; Wed, 6 Sep 2017 11:40:44 -0700 (PDT) Received: from localhost ([::1]:37462 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpfFj-0002XQ-FJ for importer@patchew.org; Wed, 06 Sep 2017 14:40:43 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57111) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpfEu-0002Dv-Im for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:39:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpfEp-0008CP-PR for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:39:52 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:52334) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpfEp-0008Be-Dh for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:39:47 -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 v86IdWX6005516; Wed, 6 Sep 2017 20:39:32 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 158868AF; Wed, 6 Sep 2017 20:39:26 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 21:39:25 +0300 Message-Id: <150472316564.24907.15448502877571730252.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86IdWX6005516 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 v4 19/20] 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 , 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 | 11 +++++++++++ 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, 49 insertions(+) diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c index 43f8887529..dcfb31f436 100644 --- a/bsd-user/syscall.c +++ b/bsd-user/syscall.c @@ -406,6 +406,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: @@ -483,6 +484,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: @@ -560,6 +562,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 7e84dadf24..f8f368efb0 100644 --- a/instrument/control.c +++ b/instrument/control.c @@ -135,3 +135,14 @@ QI_VPUBLIC void qi_event_set_guest_user_syscall( ERROR_IF(!instr_get_state(), "called outside instrumentation"); instr_set_event(guest_user_syscall, fn); } + + +void (*instr_event__guest_user_syscall_ret)( + QICPU vcpu, uint64_t num, uint64_t ret); + +QI_VPUBLIC 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"); + 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 9c64497533..ca1d789cea 100644 --- a/instrument/events.inc.h +++ b/instrument/events.inc.h @@ -93,3 +93,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_set(vcpu); + (*cb)(vcpu_, num, ret); + instr_set_state(INSTR_STATE_DISABLE); + } +} diff --git a/instrument/load.c b/instrument/load.c index d977049082..decd357105 100644 --- a/instrument/load.c +++ b/instrument/load.c @@ -154,6 +154,7 @@ InstrUnloadError instr_unload(int64_t handle_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 /* 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 cba8ade54e..fd83c86c2b 100644 --- a/instrument/qemu-instr/control.h +++ b/instrument/qemu-instr/control.h @@ -149,6 +149,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 c0c33d4a75..0f86b6935d 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -12397,6 +12397,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 dbd8b1438d..7c171dcee0 100644 --- a/stubs/instrument.c +++ b/stubs/instrument.c @@ -21,3 +21,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 Thu May 2 05:58:20 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 1504723697906753.6016211441637; Wed, 6 Sep 2017 11:48:17 -0700 (PDT) Received: from localhost ([::1]:37490 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpfN2-0008W4-Oy for importer@patchew.org; Wed, 06 Sep 2017 14:48:16 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58367) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpfIc-0004wP-93 for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:43:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dpfIZ-0002lS-4K for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:43:42 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:53873) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dpfIY-0002l8-LU for qemu-devel@nongnu.org; Wed, 06 Sep 2017 14:43:39 -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 v86IhYgD005630; Wed, 6 Sep 2017 20:43:34 +0200 Received: from localhost (unknown [31.210.187.58]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id 3389D126C; Wed, 6 Sep 2017 20:43:29 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Wed, 6 Sep 2017 21:43:28 +0300 Message-Id: <150472340780.24907.7057286910324120181.stgit@frigg.lan> X-Mailer: git-send-email 2.14.1 In-Reply-To: <150471856141.24907.274176769201097378.stgit@frigg.lan> References: <150471856141.24907.274176769201097378.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty 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 v86IhYgD005630 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 v4 20/20] 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" , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= , Stefan Hajnoczi 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 | 72 ++++++++++++++++++++++++++++ 3 files changed, 177 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 8258dbfa79..c9bc4e75f4 100644 --- a/instrument/Makefile.objs +++ b/instrument/Makefile.objs @@ -6,3 +6,4 @@ target-obj-y +=3D qmp.o =20 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..4bf99b4882 --- /dev/null +++ b/instrument/state.c @@ -0,0 +1,72 @@ +/* + * 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 "cpu.h" +#include "exec/cpu-all.h" +#include "instrument/control.h" +#include "instrument/error.h" +#include "instrument/qemu-instr/state.h" +#include "instrument/qemu-instr/visibility.h" + + +QI_VPUBLIC bool qi_mem_read_virt(QICPU vcpu, uint64_t vaddr, + size_t size, void *buf) +{ + CPUState *vcpu_ =3D instr_cpu_get(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; +} + +QI_VPUBLIC bool qi_mem_write_virt(QICPU vcpu, uint64_t vaddr, + size_t size, void *buf) +{ + CPUState *vcpu_ =3D instr_cpu_get(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; +} + +QI_VPUBLIC bool qi_mem_virt_to_phys(QICPU vcpu, uint64_t vaddr, uint64_t *= paddr) +{ + CPUState *vcpu_ =3D instr_cpu_get(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 +} + +QI_VPUBLIC 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 +} + +QI_VPUBLIC 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 +}