qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v2 4/5] backdoor: [softmmu] Add QEMU-side proxy


From: Anthony Liguori
Subject: Re: [Qemu-devel] [PATCH v2 4/5] backdoor: [softmmu] Add QEMU-side proxy to "libbackdoor.a"
Date: Tue, 06 Dec 2011 13:55:47 -0600
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.21) Gecko/20110831 Lightning/1.0b2 Thunderbird/3.1.13

I really worry about us introducing so many of these one-off paravirtual 
devices.

I would much prefer that you look at doing this as an extension to the ivshmem device as it already has this sort of scope. You should be able to do this by just extending the size of bar 1 and using a well known guest id.

Regards,

Anthony Liguori

On 12/05/2011 04:23 PM, Lluís Vilanova wrote:
Uses a virtual device to proxy uses of the backdoor communication channel to the
user-provided code.

Signed-off-by: Lluís Vilanova<address@hidden>
---
  Makefile.objs           |    1
  backdoor/qemu/softmmu.c |  186 +++++++++++++++++++++++++++++++++++++++++++++++
  hw/pci.h                |    1
  3 files changed, 188 insertions(+), 0 deletions(-)
  create mode 100644 backdoor/qemu/softmmu.c

diff --git a/Makefile.objs b/Makefile.objs
index 9784441..a45ff56 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -401,6 +401,7 @@ $(trace-obj-y): $(GENERATED_HEADERS)
  # backdoor

  backdoor-nested-$(CONFIG_USER_ONLY) += user.o
+backdoor-nested-$(CONFIG_SOFTMMU) += softmmu.o

  backdoor-obj-y += $(addprefix backdoor/qemu/, $(backdoor-nested-y))

diff --git a/backdoor/qemu/softmmu.c b/backdoor/qemu/softmmu.c
new file mode 100644
index 0000000..9cde59f
--- /dev/null
+++ b/backdoor/qemu/softmmu.c
@@ -0,0 +1,186 @@
+/*
+ * QEMU-side management of backdoor channels in softmmu emulation.
+ *
+ * Copyright (C) 2011 Lluís Vilanova<address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "hw/pci.h"
+#include "backdoor/qemu/qemu-backdoor.h"
+
+
+#define PAGE_SIZE TARGET_PAGE_SIZE
+
+
+typedef struct BackdoorState
+{
+    PCIDevice dev;
+
+    uint8_t pages;
+    uint64_t size;
+
+    union
+    {
+        uint64_t v;
+        char     a[8];
+    } c_size;
+    union
+    {
+        uint64_t v;
+        uint8_t  a[8];
+    } c_cmd;
+
+    void *data_ptr;
+    MemoryRegion data;
+    MemoryRegion control;
+} BackdoorState;
+
+
+static uint64_t backdoor_control_io_read(void *opaque, target_phys_addr_t 
addr, unsigned size)
+{
+    BackdoorState *s = opaque;
+
+    /* c_size already has target endianess */
+
+    switch (size) {
+    case 1:
+    {
+        uint8_t *res = (uint8_t*)&s->c_size.a[addr % sizeof(uint64_t)];
+        return *res;
+    }
+    case 2:
+    {
+        uint16_t *res = (uint16_t*)&s->c_size.a[addr % sizeof(uint64_t)];
+        return *res;
+    }
+    case 4:
+    {
+        uint32_t *res = (uint32_t*)&s->c_size.a[addr % sizeof(uint64_t)];
+        return *res;
+    }
+    case 8:
+    {
+        uint64_t *res = (uint64_t*)&s->c_size.a[addr % sizeof(uint64_t)];
+        return *res;
+    }
+    default:
+        fprintf(stderr, "error: backdoor: Unexpected read of size %d\n", size);
+        abort();
+    }
+}
+
+static void backdoor_control_io_write(void *opaque, target_phys_addr_t addr, 
uint64_t data, unsigned size)
+{
+    BackdoorState *s = opaque;
+
+    /* c_cmd will have target endianess (left up to the user) */
+
+    switch (size) {
+    case 1:
+    {
+        uint8_t *res = (uint8_t*)&s->c_cmd.a[addr % sizeof(uint64_t)];
+        *res = (uint8_t)data;
+        break;
+    }
+    case 2:
+    {
+        uint16_t *res = (uint16_t*)&s->c_cmd.a[addr % sizeof(uint64_t)];
+        *res = (uint16_t)data;
+        break;
+    }
+    case 4:
+    {
+        uint32_t *res = (uint32_t*)&s->c_cmd.a[addr % sizeof(uint64_t)];
+        *res = (uint32_t)data;
+        break;
+    }
+    case 8:
+    {
+        uint64_t *res = (uint64_t*)&s->c_cmd.a[addr % sizeof(uint64_t)];
+        *res = (uint64_t)data;
+        break;
+    }
+    default:
+        fprintf(stderr, "error: backdoor: Unexpected write of size %d\n", 
size);
+        abort();
+    }
+
+    if ((addr + size) % sizeof(s->c_cmd.v) == 0) {
+        qemu_backdoor(s->c_cmd.v, s->data_ptr);
+    }
+}
+
+static const MemoryRegionOps backdoor_control_ops = {
+    .read = backdoor_control_io_read,
+    .write = backdoor_control_io_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 8,
+    },
+};
+
+
+static int backdoor_init(PCIDevice *dev)
+{
+    BackdoorState *s = DO_UPCAST(BackdoorState, dev, dev);
+
+    if (s->pages<  1) {
+        fprintf(stderr, "error: backdoor: "
+                "the data channel must have one or more pages\n");
+        return -1;
+    }
+    s->size = s->pages * PAGE_SIZE;
+    s->c_size.v = tswap64(s->size);
+
+    pci_set_word(s->dev.config + PCI_COMMAND,
+                 PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
+
+    memory_region_init_io(&s->control,&backdoor_control_ops, s,
+                          "backdoor.control", PAGE_SIZE);
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY,&s->control);
+
+    memory_region_init_ram(&s->data,&s->dev.qdev,
+                           "backdoor.data", s->c_size.v);
+    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY,&s->data);
+    s->data_ptr = qemu_get_ram_ptr(s->data.ram_addr);
+
+    qemu_backdoor_init(s->c_size.v);
+
+    return 0;
+}
+
+static int backdoor_fini(PCIDevice *dev)
+{
+    BackdoorState *s = DO_UPCAST(BackdoorState, dev, dev);
+
+    memory_region_destroy(&s->data);
+    memory_region_destroy(&s->control);
+
+    return 0;
+}
+
+
+static PCIDeviceInfo backdoor_info = {
+    .qdev.name  = "backdoor",
+    .qdev.desc  = "Backdoor communication channel",
+    .qdev.size  = sizeof(BackdoorState),
+    .init       = backdoor_init,
+    .exit       = backdoor_fini,
+    .vendor_id  = PCI_VENDOR_ID_REDHAT_QUMRANET,
+    .device_id  = PCI_DEVICE_ID_BACKDOOR,
+    .class_id   = PCI_CLASS_MEMORY_RAM,
+    .qdev.props = (Property[]) {
+        DEFINE_PROP_UINT8("pages", BackdoorState, pages, 1),
+        DEFINE_PROP_END_OF_LIST(),
+    }
+};
+
+static void backdoor_register_device(void)
+{
+    pci_qdev_register(&backdoor_info);
+}
+
+device_init(backdoor_register_device)
diff --git a/hw/pci.h b/hw/pci.h
index 625e717..e7dc3cb 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -75,6 +75,7 @@
  #define PCI_DEVICE_ID_VIRTIO_BLOCK       0x1001
  #define PCI_DEVICE_ID_VIRTIO_BALLOON     0x1002
  #define PCI_DEVICE_ID_VIRTIO_CONSOLE     0x1003
+#define PCI_DEVICE_ID_BACKDOOR           0x1004

  #define FMT_PCIBUS                      PRIx64







reply via email to

[Prev in Thread] Current Thread [Next in Thread]