Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/815322/?format=api
{ "id": 815322, "url": "http://patchwork.ozlabs.org/api/patches/815322/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/1505807208-9063-4-git-send-email-eric.auger@redhat.com/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<1505807208-9063-4-git-send-email-eric.auger@redhat.com>", "list_archive_url": null, "date": "2017-09-19T07:46:35", "name": "[RFC,v4,03/16] virtio-iommu: add skeleton", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "182553556f1892c46b7a6ec599b079ab822e632c", "submitter": { "id": 69187, "url": "http://patchwork.ozlabs.org/api/people/69187/?format=api", "name": "Eric Auger", "email": "eric.auger@redhat.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/1505807208-9063-4-git-send-email-eric.auger@redhat.com/mbox/", "series": [ { "id": 3796, "url": "http://patchwork.ozlabs.org/api/series/3796/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=3796", "date": "2017-09-19T07:46:32", "name": "VIRTIO-IOMMU device", "version": 4, "mbox": "http://patchwork.ozlabs.org/series/3796/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/815322/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/815322/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org", "Authentication-Results": [ "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=nongnu.org\n\t(client-ip=2001:4830:134:3::11; helo=lists.gnu.org;\n\tenvelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n\treceiver=<UNKNOWN>)", "ext-mx09.extmail.prod.ext.phx2.redhat.com;\n\tdmarc=none (p=none dis=none) header.from=redhat.com", "ext-mx09.extmail.prod.ext.phx2.redhat.com;\n\tspf=fail smtp.mailfrom=eric.auger@redhat.com" ], "Received": [ "from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11])\n\t(using TLSv1 with cipher AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xxFT93pg3z9s82\n\tfor <incoming@patchwork.ozlabs.org>;\n\tTue, 19 Sep 2017 17:52:13 +1000 (AEST)", "from localhost ([::1]:40611 helo=lists.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.71) (envelope-from\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>)\n\tid 1duDKF-0002WS-Io\n\tfor incoming@patchwork.ozlabs.org; Tue, 19 Sep 2017 03:52:11 -0400", "from eggs.gnu.org ([2001:4830:134:3::10]:47170)\n\tby lists.gnu.org with esmtp (Exim 4.71)\n\t(envelope-from <eric.auger@redhat.com>) id 1duDFz-0007xx-TN\n\tfor qemu-devel@nongnu.org; Tue, 19 Sep 2017 03:47:52 -0400", "from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)\n\t(envelope-from <eric.auger@redhat.com>) id 1duDFx-0000di-Ta\n\tfor qemu-devel@nongnu.org; Tue, 19 Sep 2017 03:47:47 -0400", "from mx1.redhat.com ([209.132.183.28]:45088)\n\tby eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32)\n\t(Exim 4.71) (envelope-from <eric.auger@redhat.com>)\n\tid 1duDFt-0000bD-Lb; Tue, 19 Sep 2017 03:47:41 -0400", "from smtp.corp.redhat.com\n\t(int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby mx1.redhat.com (Postfix) with ESMTPS id 765784A702;\n\tTue, 19 Sep 2017 07:47:40 +0000 (UTC)", "from localhost.localdomain.com (ovpn-116-197.ams2.redhat.com\n\t[10.36.116.197])\n\tby smtp.corp.redhat.com (Postfix) with ESMTP id 77C0161342;\n\tTue, 19 Sep 2017 07:47:34 +0000 (UTC)" ], "DMARC-Filter": "OpenDMARC Filter v1.3.2 mx1.redhat.com 765784A702", "From": "Eric Auger <eric.auger@redhat.com>", "To": "eric.auger.pro@gmail.com, eric.auger@redhat.com, peter.maydell@linaro.org,\n\talex.williamson@redhat.com, mst@redhat.com, qemu-arm@nongnu.org,\n\tqemu-devel@nongnu.org, jean-philippe.brucker@arm.com", "Date": "Tue, 19 Sep 2017 09:46:35 +0200", "Message-Id": "<1505807208-9063-4-git-send-email-eric.auger@redhat.com>", "In-Reply-To": "<1505807208-9063-1-git-send-email-eric.auger@redhat.com>", "References": "<1505807208-9063-1-git-send-email-eric.auger@redhat.com>", "X-Scanned-By": "MIMEDefang 2.79 on 10.5.11.11", "X-Greylist": "Sender IP whitelisted, not delayed by milter-greylist-4.5.16\n\t(mx1.redhat.com [10.5.110.38]);\n\tTue, 19 Sep 2017 07:47:40 +0000 (UTC)", "X-detected-operating-system": "by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]\n\t[fuzzy]", "X-Received-From": "209.132.183.28", "Subject": "[Qemu-devel] [RFC v4 03/16] virtio-iommu: add skeleton", "X-BeenThere": "qemu-devel@nongnu.org", "X-Mailman-Version": "2.1.21", "Precedence": "list", "List-Id": "<qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<http://lists.nongnu.org/archive/html/qemu-devel/>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Cc": "wei@redhat.com, kevin.tian@intel.com, marc.zyngier@arm.com,\n\ttn@semihalf.com, \n\twill.deacon@arm.com, drjones@redhat.com, peterx@redhat.com,\n\tlinuc.decode@gmail.com, bharat.bhushan@nxp.com,\n\tchristoffer.dall@linaro.org", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "\"Qemu-devel\"\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>" }, "content": "This patchs adds the skeleton for the virtio-iommu device.\n\nSigned-off-by: Eric Auger <eric.auger@redhat.com>\n\n---\n\nv3 -> v4:\n- use page_size_mask instead of page_sizes\n- added set_features()\n- added some traces (reset, set_status, set_features)\n- empty virtio_iommu_set_config() as the driver MUST NOT\n write to device configuration fields\n- add get_config trace\n\nv2 -> v3:\n- rebase on 2.10-rc0, ie. use IOMMUMemoryRegion and remove\n iommu_ops.\n- advertise VIRTIO_IOMMU_F_MAP_UNMAP feature\n- page_sizes set to TARGET_PAGE_SIZE\n---\n hw/virtio/Makefile.objs | 1 +\n hw/virtio/trace-events | 7 ++\n hw/virtio/virtio-iommu.c | 255 +++++++++++++++++++++++++++++++++++++++\n include/hw/virtio/virtio-iommu.h | 59 +++++++++\n 4 files changed, 322 insertions(+)\n create mode 100644 hw/virtio/virtio-iommu.c\n create mode 100644 include/hw/virtio/virtio-iommu.h", "diff": "diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs\nindex 765d363..8967a4a 100644\n--- a/hw/virtio/Makefile.objs\n+++ b/hw/virtio/Makefile.objs\n@@ -6,6 +6,7 @@ common-obj-y += virtio-mmio.o\n \n obj-y += virtio.o virtio-balloon.o \n obj-$(CONFIG_LINUX) += vhost.o vhost-backend.o vhost-user.o\n+obj-$(CONFIG_LINUX) += virtio-iommu.o\n obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock.o\n obj-y += virtio-crypto.o\n obj-$(CONFIG_VIRTIO_PCI) += virtio-crypto-pci.o\ndiff --git a/hw/virtio/trace-events b/hw/virtio/trace-events\nindex 775461a..98cf9a1 100644\n--- a/hw/virtio/trace-events\n+++ b/hw/virtio/trace-events\n@@ -25,3 +25,10 @@ virtio_balloon_handle_output(const char *name, uint64_t gpa) \"section name: %s g\n virtio_balloon_get_config(uint32_t num_pages, uint32_t actual) \"num_pages: %d actual: %d\"\n virtio_balloon_set_config(uint32_t actual, uint32_t oldactual) \"actual: %d oldactual: %d\"\n virtio_balloon_to_target(uint64_t target, uint32_t num_pages) \"balloon target: 0x%\"PRIx64\" num_pages: %d\"\n+\n+# hw/virtio/virtio-iommu.c\n+#\n+virtio_iommu_set_features(uint64_t features) \"features accepted by the driver =0x%\"PRIx64\n+virtio_iommu_device_reset(void) \"reset!\"\n+virtio_iommu_device_status(uint8_t status) \"driver status = %d\"\n+virtio_iommu_get_config(uint64_t page_size_mask, uint64_t start, uint64_t end, uint8_t ioasid_bits, uint32_t probe_size) \"page_size_mask=0x%\"PRIx64\" start=0x%\"PRIx64\" end=0x%\"PRIx64\" ioasid_bits=%d probe_size=0x%x\"\ndiff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c\nnew file mode 100644\nindex 0000000..36e5b5f\n--- /dev/null\n+++ b/hw/virtio/virtio-iommu.c\n@@ -0,0 +1,255 @@\n+/*\n+ * virtio-iommu device\n+ *\n+ * Copyright (c) 2017 Red Hat, Inc.\n+ *\n+ * This program is free software; you can redistribute it and/or modify it\n+ * under the terms and conditions of the GNU General Public License,\n+ * version 2 or later, as published by the Free Software Foundation.\n+ *\n+ * This program is distributed in the hope it will be useful, but WITHOUT\n+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n+ * more details.\n+ *\n+ * You should have received a copy of the GNU General Public License along with\n+ * this program. If not, see <http://www.gnu.org/licenses/>.\n+ *\n+ */\n+\n+#include \"qemu/osdep.h\"\n+#include \"qemu/iov.h\"\n+#include \"qemu-common.h\"\n+#include \"hw/virtio/virtio.h\"\n+#include \"sysemu/kvm.h\"\n+#include \"qapi-event.h\"\n+#include \"trace.h\"\n+\n+#include \"standard-headers/linux/virtio_ids.h\"\n+#include <linux/virtio_iommu.h>\n+\n+#include \"hw/virtio/virtio-bus.h\"\n+#include \"hw/virtio/virtio-access.h\"\n+#include \"hw/virtio/virtio-iommu.h\"\n+\n+/* Max size */\n+#define VIOMMU_DEFAULT_QUEUE_SIZE 256\n+\n+static int virtio_iommu_handle_attach(VirtIOIOMMU *s,\n+ struct iovec *iov,\n+ unsigned int iov_cnt)\n+{\n+ return -ENOENT;\n+}\n+static int virtio_iommu_handle_detach(VirtIOIOMMU *s,\n+ struct iovec *iov,\n+ unsigned int iov_cnt)\n+{\n+ return -ENOENT;\n+}\n+static int virtio_iommu_handle_map(VirtIOIOMMU *s,\n+ struct iovec *iov,\n+ unsigned int iov_cnt)\n+{\n+ return -ENOENT;\n+}\n+static int virtio_iommu_handle_unmap(VirtIOIOMMU *s,\n+ struct iovec *iov,\n+ unsigned int iov_cnt)\n+{\n+ return -ENOENT;\n+}\n+\n+static void virtio_iommu_handle_command(VirtIODevice *vdev, VirtQueue *vq)\n+{\n+ VirtIOIOMMU *s = VIRTIO_IOMMU(vdev);\n+ VirtQueueElement *elem;\n+ struct virtio_iommu_req_head head;\n+ struct virtio_iommu_req_tail tail;\n+ unsigned int iov_cnt;\n+ struct iovec *iov;\n+ size_t sz;\n+\n+ for (;;) {\n+ elem = virtqueue_pop(vq, sizeof(VirtQueueElement));\n+ if (!elem) {\n+ return;\n+ }\n+\n+ if (iov_size(elem->in_sg, elem->in_num) < sizeof(tail) ||\n+ iov_size(elem->out_sg, elem->out_num) < sizeof(head)) {\n+ virtio_error(vdev, \"virtio-iommu erroneous head or tail\");\n+ virtqueue_detach_element(vq, elem, 0);\n+ g_free(elem);\n+ break;\n+ }\n+\n+ iov_cnt = elem->out_num;\n+ iov = g_memdup(elem->out_sg, sizeof(struct iovec) * elem->out_num);\n+ sz = iov_to_buf(iov, iov_cnt, 0, &head, sizeof(head));\n+ if (sz != sizeof(head)) {\n+ tail.status = VIRTIO_IOMMU_S_UNSUPP;\n+ }\n+ qemu_mutex_lock(&s->mutex);\n+ switch (head.type) {\n+ case VIRTIO_IOMMU_T_ATTACH:\n+ tail.status = virtio_iommu_handle_attach(s, iov, iov_cnt);\n+ break;\n+ case VIRTIO_IOMMU_T_DETACH:\n+ tail.status = virtio_iommu_handle_detach(s, iov, iov_cnt);\n+ break;\n+ case VIRTIO_IOMMU_T_MAP:\n+ tail.status = virtio_iommu_handle_map(s, iov, iov_cnt);\n+ break;\n+ case VIRTIO_IOMMU_T_UNMAP:\n+ tail.status = virtio_iommu_handle_unmap(s, iov, iov_cnt);\n+ break;\n+ default:\n+ tail.status = VIRTIO_IOMMU_S_UNSUPP;\n+ }\n+ qemu_mutex_unlock(&s->mutex);\n+\n+ sz = iov_from_buf(elem->in_sg, elem->in_num, 0,\n+ &tail, sizeof(tail));\n+ assert(sz == sizeof(tail));\n+\n+ virtqueue_push(vq, elem, sizeof(tail));\n+ virtio_notify(vdev, vq);\n+ g_free(elem);\n+ }\n+}\n+\n+static void virtio_iommu_get_config(VirtIODevice *vdev, uint8_t *config_data)\n+{\n+ VirtIOIOMMU *dev = VIRTIO_IOMMU(vdev);\n+ struct virtio_iommu_config *config = &dev->config;\n+\n+ trace_virtio_iommu_get_config(config->page_size_mask,\n+ config->input_range.start,\n+ config->input_range.end,\n+ config->ioasid_bits,\n+ config->probe_size);\n+ memcpy(config_data, &dev->config, sizeof(struct virtio_iommu_config));\n+}\n+\n+static void virtio_iommu_set_config(VirtIODevice *vdev,\n+ const uint8_t *config_data)\n+{\n+}\n+\n+static uint64_t virtio_iommu_get_features(VirtIODevice *vdev, uint64_t f,\n+ Error **errp)\n+{\n+ VirtIOIOMMU *dev = VIRTIO_IOMMU(vdev);\n+ f |= dev->host_features;\n+ virtio_add_feature(&f, VIRTIO_RING_F_EVENT_IDX);\n+ virtio_add_feature(&f, VIRTIO_RING_F_INDIRECT_DESC);\n+ virtio_add_feature(&f, VIRTIO_IOMMU_F_INPUT_RANGE);\n+ virtio_add_feature(&f, VIRTIO_IOMMU_F_MAP_UNMAP);\n+ return f;\n+}\n+\n+static void virtio_iommu_set_features(VirtIODevice *vdev, uint64_t val)\n+{\n+ trace_virtio_iommu_set_features(val);\n+}\n+\n+static int virtio_iommu_post_load_device(void *opaque, int version_id)\n+{\n+ return 0;\n+}\n+\n+static const VMStateDescription vmstate_virtio_iommu_device = {\n+ .name = \"virtio-iommu-device\",\n+ .version_id = 1,\n+ .minimum_version_id = 1,\n+ .post_load = virtio_iommu_post_load_device,\n+ .fields = (VMStateField[]) {\n+ VMSTATE_END_OF_LIST()\n+ },\n+};\n+\n+static void virtio_iommu_device_realize(DeviceState *dev, Error **errp)\n+{\n+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);\n+ VirtIOIOMMU *s = VIRTIO_IOMMU(dev);\n+\n+ virtio_init(vdev, \"virtio-iommu\", VIRTIO_ID_IOMMU,\n+ sizeof(struct virtio_iommu_config));\n+\n+ s->vq = virtio_add_queue(vdev, VIOMMU_DEFAULT_QUEUE_SIZE,\n+ virtio_iommu_handle_command);\n+\n+ s->config.page_size_mask = TARGET_PAGE_MASK;\n+ s->config.input_range.end = -1UL;\n+}\n+\n+static void virtio_iommu_device_unrealize(DeviceState *dev, Error **errp)\n+{\n+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);\n+\n+ virtio_cleanup(vdev);\n+}\n+\n+static void virtio_iommu_device_reset(VirtIODevice *vdev)\n+{\n+ trace_virtio_iommu_device_reset();\n+}\n+\n+static void virtio_iommu_set_status(VirtIODevice *vdev, uint8_t status)\n+{\n+ trace_virtio_iommu_device_status(status);\n+}\n+\n+static void virtio_iommu_instance_init(Object *obj)\n+{\n+}\n+\n+static const VMStateDescription vmstate_virtio_iommu = {\n+ .name = \"virtio-iommu\",\n+ .minimum_version_id = 1,\n+ .version_id = 1,\n+ .fields = (VMStateField[]) {\n+ VMSTATE_VIRTIO_DEVICE,\n+ VMSTATE_END_OF_LIST()\n+ },\n+};\n+\n+static Property virtio_iommu_properties[] = {\n+ DEFINE_PROP_END_OF_LIST(),\n+};\n+\n+static void virtio_iommu_class_init(ObjectClass *klass, void *data)\n+{\n+ DeviceClass *dc = DEVICE_CLASS(klass);\n+ VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);\n+\n+ dc->props = virtio_iommu_properties;\n+ dc->vmsd = &vmstate_virtio_iommu;\n+\n+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);\n+ vdc->realize = virtio_iommu_device_realize;\n+ vdc->unrealize = virtio_iommu_device_unrealize;\n+ vdc->reset = virtio_iommu_device_reset;\n+ vdc->get_config = virtio_iommu_get_config;\n+ vdc->set_config = virtio_iommu_set_config;\n+ vdc->get_features = virtio_iommu_get_features;\n+ vdc->set_features = virtio_iommu_set_features;\n+ vdc->set_status = virtio_iommu_set_status;\n+ vdc->vmsd = &vmstate_virtio_iommu_device;\n+}\n+\n+static const TypeInfo virtio_iommu_info = {\n+ .name = TYPE_VIRTIO_IOMMU,\n+ .parent = TYPE_VIRTIO_DEVICE,\n+ .instance_size = sizeof(VirtIOIOMMU),\n+ .instance_init = virtio_iommu_instance_init,\n+ .class_init = virtio_iommu_class_init,\n+};\n+\n+static void virtio_register_types(void)\n+{\n+ type_register_static(&virtio_iommu_info);\n+}\n+\n+type_init(virtio_register_types)\ndiff --git a/include/hw/virtio/virtio-iommu.h b/include/hw/virtio/virtio-iommu.h\nnew file mode 100644\nindex 0000000..6716cdb\n--- /dev/null\n+++ b/include/hw/virtio/virtio-iommu.h\n@@ -0,0 +1,59 @@\n+/*\n+ * virtio-iommu device\n+ *\n+ * Copyright (c) 2017 Red Hat, Inc.\n+ *\n+ * This program is free software; you can redistribute it and/or modify it\n+ * under the terms and conditions of the GNU General Public License,\n+ * version 2 or later, as published by the Free Software Foundation.\n+ *\n+ * This program is distributed in the hope it will be useful, but WITHOUT\n+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n+ * more details.\n+ *\n+ * You should have received a copy of the GNU General Public License along with\n+ * this program. If not, see <http://www.gnu.org/licenses/>.\n+ *\n+ */\n+\n+#ifndef QEMU_VIRTIO_IOMMU_H\n+#define QEMU_VIRTIO_IOMMU_H\n+\n+#include \"standard-headers/linux/virtio_iommu.h\"\n+#include \"hw/virtio/virtio.h\"\n+#include \"hw/pci/pci.h\"\n+\n+#define TYPE_VIRTIO_IOMMU \"virtio-iommu-device\"\n+#define VIRTIO_IOMMU(obj) \\\n+ OBJECT_CHECK(VirtIOIOMMU, (obj), TYPE_VIRTIO_IOMMU)\n+\n+#define IOMMU_PCI_BUS_MAX 256\n+#define IOMMU_PCI_DEVFN_MAX 256\n+\n+typedef struct IOMMUDevice {\n+ void *viommu;\n+ PCIBus *bus;\n+ int devfn;\n+ IOMMUMemoryRegion iommu_mr;\n+ AddressSpace as;\n+} IOMMUDevice;\n+\n+typedef struct IOMMUPciBus {\n+ PCIBus *bus;\n+ IOMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */\n+} IOMMUPciBus;\n+\n+typedef struct VirtIOIOMMU {\n+ VirtIODevice parent_obj;\n+ VirtQueue *vq;\n+ struct virtio_iommu_config config;\n+ uint32_t host_features;\n+ GHashTable *as_by_busptr;\n+ IOMMUPciBus *as_by_bus_num[IOMMU_PCI_BUS_MAX];\n+ GTree *address_spaces;\n+ QemuMutex mutex;\n+ GTree *devices;\n+} VirtIOIOMMU;\n+\n+#endif\n", "prefixes": [ "RFC", "v4", "03/16" ] }