All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Lluís Vilanova" <vilanova@ac.upc.edu>
To: qemu-devel@nongnu.org
Cc: Stefan Hajnoczi <stefanha@redhat.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	Marcel Apfelbaum <marcel@redhat.com>
Subject: [Qemu-devel] [PATCH 4/6] hypertrace: [softmmu] Add QEMU-side proxy to "guest_hypertrace" event
Date: Fri,  5 Aug 2016 18:59:45 +0200	[thread overview]
Message-ID: <147041638509.2523.4424218032825618871.stgit@fimbulvetr.bsc.es> (raw)
In-Reply-To: <147041636348.2523.2954972609232949598.stgit@fimbulvetr.bsc.es>

Uses a virtual device to trigger the hypertrace channel event.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 hypertrace/Makefile.objs |    5 +
 hypertrace/softmmu.c     |  243 ++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/pci/pci.h     |    2 
 3 files changed, 249 insertions(+), 1 deletion(-)
 create mode 100644 hypertrace/softmmu.c

diff --git a/hypertrace/Makefile.objs b/hypertrace/Makefile.objs
index 6eb5acf..2a120b4 100644
--- a/hypertrace/Makefile.objs
+++ b/hypertrace/Makefile.objs
@@ -1,8 +1,11 @@
 # -*- mode: makefile -*-
 
 target-obj-$(CONFIG_USER_ONLY) += user.o
+ifdef CONFIG_PCI
+target-obj-$(CONFIG_SOFTMMU) += softmmu.o
+endif
 
-$(obj)/user.o: $(obj)/emit.c
+$(obj)/user.o $(obj)/softmmu.o: $(obj)/emit.c
 
 $(obj)/emit.c: $(obj)/emit.c-timestamp $(BUILD_DIR)/config-host.mak
 	@cmp $< $@ >/dev/null 2>&1 || cp $< $@
diff --git a/hypertrace/softmmu.c b/hypertrace/softmmu.c
new file mode 100644
index 0000000..4927197
--- /dev/null
+++ b/hypertrace/softmmu.c
@@ -0,0 +1,243 @@
+/*
+ * QEMU-side management of hypertrace in softmmu emulation.
+ *
+ * Copyright (C) 2016 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+/*
+ * Implementation details
+ * ======================
+ *
+ * Both channels are provided as a virtual device with two BARs that can be used
+ * through MMIO.
+ *
+ * Data channel
+ * ------------
+ *
+ * The guest must mmap BAR 1 of the hypertrace virtual device, which will act as
+ * regular writable device memory.
+ *
+ * Regular memory accesses pass data through the data channel.
+ *
+ * Control channel
+ * ---------------
+ *
+ * The guest must mmap BAR 0 of the hypertrace virtual device.
+ *
+ * Guest reads from that memory are intercepted by QEMU in order to return the
+ * size of the data channel.
+ *
+ * Guest writes into that memory are intercepted by QEMU in order to raise the
+ * "guest_hypertrace" tracing event.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "exec/ram_addr.h"
+#include "hw/pci/pci.h"
+#include "migration/migration.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "trace.h"
+
+
+#define PAGE_SIZE TARGET_PAGE_SIZE
+
+
+typedef struct HypertraceState
+{
+    PCIDevice dev;
+
+    uint8_t pages;
+    uint64_t size;
+
+    union
+    {
+        uint64_t v;
+        char     a[8];
+    } c_max_offset;
+    union
+    {
+        uint64_t v;
+        char     a[8];
+    } c_cmd;
+
+    void *data_ptr;
+    MemoryRegion data;
+    MemoryRegion control;
+
+    Error *migration_blocker;
+} HypertraceState;
+
+
+static uint64_t hypertrace_control_io_read(void *opaque, hwaddr addr,
+                                           unsigned size)
+{
+    HypertraceState *s = opaque;
+    char *mem = &s->c_max_offset.a[addr % sizeof(uint64_t)];
+
+    if (addr + size > sizeof(uint64_t)) {
+        error_report("error: hypertrace: Unexpected read to address %lu\n", addr);
+        return 0;
+    }
+
+    /* control values already have target endianess */
+
+    switch (size) {
+    case 1:
+    {
+        uint8_t *res = (uint8_t*)mem;
+        return *res;
+    }
+    case 2:
+    {
+        uint16_t *res = (uint16_t*)mem;
+        return *res;
+    }
+    case 4:
+    {
+        uint32_t *res = (uint32_t*)mem;
+        return *res;
+    }
+    case 8:
+    {
+        uint64_t *res = (uint64_t*)mem;
+        return *res;
+    }
+    default:
+        error_report("error: hypertrace: Unexpected read of size %d\n", size);
+        return 0;
+    }
+}
+
+#include "hypertrace/emit.c"
+
+static void hypertrace_control_io_write(void *opaque, hwaddr addr,
+                                        uint64_t data, unsigned size)
+{
+    HypertraceState *s = opaque;
+    char *mem = &s->c_cmd.a[addr % sizeof(uint64_t)];
+
+    if (addr < sizeof(uint64_t) || addr + size > sizeof(uint64_t) * 2) {
+        error_report("error: hypertrace: Unexpected write to address %lu\n", addr);
+        return;
+    }
+
+    /* c_cmd will have target endianess (left up to the user) */
+
+    switch (size) {
+    case 1:
+    {
+        uint8_t *res = (uint8_t*)mem;
+        *res = (uint8_t)data;
+        break;
+    }
+    case 2:
+    {
+        uint16_t *res = (uint16_t*)mem;
+        *res = (uint16_t)data;
+        break;
+    }
+    case 4:
+    {
+        uint32_t *res = (uint32_t*)mem;
+        *res = (uint32_t)data;
+        break;
+    }
+    case 8:
+    {
+        uint64_t *res = (uint64_t*)mem;
+        *res = (uint64_t)data;
+        break;
+    }
+    default:
+        error_report("error: hypertrace: Unexpected write of size %d\n", size);
+    }
+
+    if ((addr + size) % sizeof(s->c_cmd.v) == 0) {
+        uint64_t vcontrol = s->c_cmd.v;
+        uint64_t *data_ptr = (uint64_t*)s->data_ptr;
+        data_ptr = &data_ptr[vcontrol * CONFIG_HYPERTRACE_ARGS * sizeof(uint64_t)];
+        hypertrace_emit(current_cpu, data_ptr);
+    }
+}
+
+static const MemoryRegionOps hypertrace_control_ops = {
+    .read = &hypertrace_control_io_read,
+    .write = &hypertrace_control_io_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 8,
+    },
+};
+
+
+static void hypertrace_realize(PCIDevice *dev, Error **errp)
+{
+    HypertraceState *s = DO_UPCAST(HypertraceState, dev, dev);
+    Error *err = NULL;
+    size_t size = s->pages * TARGET_PAGE_SIZE;
+
+    if (s->pages < 1) {
+        error_setg(errp, "hypertrace: the data channel must have one or more pages\n");
+        return;
+    }
+    s->c_max_offset.v = tswap64(s->size / (CONFIG_HYPERTRACE_ARGS * sizeof(uint64_t)));
+
+    error_setg(&s->migration_blocker, "The 'hypertrace' device cannot be migrated");
+    migrate_add_blocker(s->migration_blocker);
+
+    pci_set_word(s->dev.config + PCI_COMMAND,
+                 PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+
+    /* control channel */
+    memory_region_init_io(&s->control, OBJECT(s), &hypertrace_control_ops, s,
+                          "hypertrace.control", PAGE_SIZE);
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->control);
+
+    /* data channel */
+    memory_region_init_ram(&s->data, OBJECT(s), "hypertrace.data", size, &err);
+    if (err) {
+        error_propagate(errp, err);
+        return;
+    }
+    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->data);
+    s->data_ptr = qemu_map_ram_ptr(s->data.ram_block, 0);
+}
+
+
+static Property hypertrace_properties[] = {
+    DEFINE_PROP_UINT8("pages", HypertraceState, pages, 1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void hypertrace_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->realize = hypertrace_realize;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    k->device_id = PCI_DEVICE_ID_HYPERTRACE;
+    k->class_id = PCI_CLASS_MEMORY_RAM;
+    dc->desc  = "Hypertrace communication channel",
+    dc->props = hypertrace_properties;
+}
+
+static TypeInfo hypertrace_info = {
+    .name          = "hypertrace",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(HypertraceState),
+    .class_init    = hypertrace_class_init,
+};
+
+static void hypertrace_register_types(void)
+{
+    type_register_static(&hypertrace_info);
+}
+
+type_init(hypertrace_register_types)
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 9ed1624..af0772f 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -80,6 +80,8 @@
 #define PCI_DEVICE_ID_VIRTIO_RNG         0x1005
 #define PCI_DEVICE_ID_VIRTIO_9P          0x1009
 
+#define PCI_DEVICE_ID_HYPERTRACE         0x10f0
+
 #define PCI_VENDOR_ID_REDHAT             0x1b36
 #define PCI_DEVICE_ID_REDHAT_BRIDGE      0x0001
 #define PCI_DEVICE_ID_REDHAT_SERIAL      0x0002

  parent reply	other threads:[~2016-08-05 16:59 UTC|newest]

Thread overview: 68+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-05 16:59 [Qemu-devel] [PATCH 0/6] hypertrace: Lightweight guest-to-QEMU trace channel Lluís Vilanova
2016-08-05 16:59 ` [Qemu-devel] [PATCH 1/6] hypertrace: Add documentation Lluís Vilanova
2016-08-05 17:17   ` Eric Blake
2016-08-08 13:02     ` Lluís Vilanova
2016-08-05 16:59 ` [Qemu-devel] [PATCH 2/6] hypertrace: Add tracing event "guest_hypertrace" Lluís Vilanova
2016-08-18  9:59   ` Stefan Hajnoczi
2016-08-18 10:32     ` Lluís Vilanova
2016-08-05 16:59 ` [Qemu-devel] [PATCH 3/6] hypertrace: [*-user] Add QEMU-side proxy to "guest_hypertrace" event Lluís Vilanova
2016-08-05 17:23   ` Eric Blake
2016-08-08 13:08     ` Lluís Vilanova
2016-08-18 10:17   ` Stefan Hajnoczi
2016-08-21 12:15     ` Lluís Vilanova
2016-08-23 15:52       ` Stefan Hajnoczi
2016-08-05 16:59 ` Lluís Vilanova [this message]
2016-08-05 16:59 ` [Qemu-devel] [PATCH 5/6] hypertrace: Add guest-side user-level library Lluís Vilanova
2016-08-05 16:59 ` [Qemu-devel] [PATCH 6/6] hypertrace: Add guest-side Linux module Lluís Vilanova
2016-08-18  9:47 ` [Qemu-devel] [PATCH 0/6] hypertrace: Lightweight guest-to-QEMU trace channel Stefan Hajnoczi
2016-08-18  9:47   ` Stefan Hajnoczi
2016-08-18 10:22   ` [Qemu-devel] " Lluís Vilanova
2016-08-18 13:53     ` Stefan Hajnoczi
2016-08-18 14:21       ` Luiz Capitulino
2016-08-21 12:17         ` Lluís Vilanova
2016-08-21 12:17         ` Lluís Vilanova
2016-08-18 14:21       ` Luiz Capitulino
2016-08-18 13:53     ` Stefan Hajnoczi
2016-08-18 10:22   ` Lluís Vilanova
2016-08-18 10:54 ` Stefan Hajnoczi
2016-08-18 10:54   ` Stefan Hajnoczi
2016-08-18 13:37   ` [Qemu-devel] " Luiz Capitulino
2016-08-19  4:45     ` Masami Hiramatsu
2016-08-19  4:45       ` Masami Hiramatsu
2016-08-18 13:37   ` [Qemu-devel] " Luiz Capitulino
2016-08-18 16:19   ` Steven Rostedt
2016-08-19 10:02     ` Stefan Hajnoczi
2016-08-19 13:30       ` Steven Rostedt
2016-08-19 13:30       ` Steven Rostedt
2016-08-19 10:02     ` Stefan Hajnoczi
2016-08-18 16:19   ` Steven Rostedt
2016-08-21 12:32   ` Lluís Vilanova
2016-08-23 15:54     ` Stefan Hajnoczi
2016-08-23 15:54     ` Stefan Hajnoczi
2016-08-24 10:25       ` Lluís Vilanova
2016-08-29 13:45         ` Stefan Hajnoczi
2016-08-29 13:45           ` Stefan Hajnoczi
2016-08-29 18:46           ` [Qemu-devel] " Lluís Vilanova
2016-08-29 18:46           ` Lluís Vilanova
2016-08-31 16:35             ` Stefan Hajnoczi
2016-08-31 16:35             ` Stefan Hajnoczi
2016-09-05 14:37               ` Lluís Vilanova
2016-09-05 14:37               ` Lluís Vilanova
2016-09-05 19:20                 ` Masami Hiramatsu
2016-09-05 19:20                   ` Masami Hiramatsu
2016-09-06 12:59                   ` [Qemu-devel] " Lluís Vilanova
2016-09-06 12:59                   ` Lluís Vilanova
2016-09-13 13:52                 ` Stefan Hajnoczi
2016-09-13 13:52                   ` Stefan Hajnoczi
2016-09-13 16:50                   ` [Qemu-devel] " Lluís Vilanova
2016-09-13 16:50                   ` Lluís Vilanova
2016-09-05 14:59             ` Daniel P. Berrange
2016-09-05 14:59               ` Daniel P. Berrange
2016-09-05 18:29               ` [Qemu-devel] " Lluís Vilanova
2016-09-05 18:59                 ` Daniel P. Berrange
2016-09-06  8:54                   ` Lluís Vilanova
2016-09-06  8:54                   ` Lluís Vilanova
2016-09-05 18:59                 ` Daniel P. Berrange
2016-09-05 18:29               ` Lluís Vilanova
2016-08-24 10:25       ` Lluís Vilanova
2016-08-21 12:32   ` Lluís Vilanova

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=147041638509.2523.4424218032825618871.stgit@fimbulvetr.bsc.es \
    --to=vilanova@ac.upc.edu \
    --cc=marcel@redhat.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.