All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
To: iommu@lists.linux-foundation.org, kvm@vger.kernel.org,
	virtualization@lists.linux-foundation.org,
	virtio-dev@lists.oasis-open.org
Cc: cdall@linaro.org, will.deacon@arm.com, robin.murphy@arm.com,
	lorenzo.pieralisi@arm.com, joro@8bytes.org, mst@redhat.com,
	jasowang@redhat.com, alex.williamson@redhat.com,
	marc.zyngier@arm.com
Subject: [RFC PATCH kvmtool 08/15] virtio: add vIOMMU instance for virtio devices
Date: Fri,  7 Apr 2017 20:24:48 +0100	[thread overview]
Message-ID: <20170407192455.26814-9-jean-philippe.brucker@arm.com> (raw)
In-Reply-To: <20170407192455.26814-1-jean-philippe.brucker@arm.com>

Virtio devices can now opt-in to use an IOMMU, by setting the use_iommu
field. None of this will work in the current state, since virtio devices
still access memory linearly. A subsequent patch implements sg accesses.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
---
 include/kvm/virtio-mmio.h |  1 +
 include/kvm/virtio-pci.h  |  1 +
 include/kvm/virtio.h      | 13 ++++++++++++
 virtio/core.c             | 52 +++++++++++++++++++++++++++++++++++++++++++++++
 virtio/mmio.c             | 27 ++++++++++++++++++++++++
 virtio/pci.c              | 26 ++++++++++++++++++++++++
 6 files changed, 120 insertions(+)

diff --git a/include/kvm/virtio-mmio.h b/include/kvm/virtio-mmio.h
index 835f421b..c25a4fd7 100644
--- a/include/kvm/virtio-mmio.h
+++ b/include/kvm/virtio-mmio.h
@@ -44,6 +44,7 @@ struct virtio_mmio_hdr {
 struct virtio_mmio {
 	u32			addr;
 	void			*dev;
+	struct virtio_device	*vdev;
 	struct kvm		*kvm;
 	u8			irq;
 	struct virtio_mmio_hdr	hdr;
diff --git a/include/kvm/virtio-pci.h b/include/kvm/virtio-pci.h
index b70cadd8..26772f74 100644
--- a/include/kvm/virtio-pci.h
+++ b/include/kvm/virtio-pci.h
@@ -22,6 +22,7 @@ struct virtio_pci {
 	struct pci_device_header pci_hdr;
 	struct device_header	dev_hdr;
 	void			*dev;
+	struct virtio_device	*vdev;
 	struct kvm		*kvm;
 
 	u16			port_addr;
diff --git a/include/kvm/virtio.h b/include/kvm/virtio.h
index 24c0c487..9f2ff237 100644
--- a/include/kvm/virtio.h
+++ b/include/kvm/virtio.h
@@ -9,6 +9,7 @@
 #include <linux/types.h>
 #include <sys/uio.h>
 
+#include "kvm/iommu.h"
 #include "kvm/kvm.h"
 
 #define VIRTIO_IRQ_LOW		0
@@ -137,10 +138,12 @@ enum virtio_trans {
 };
 
 struct virtio_device {
+	bool			use_iommu;
 	bool			use_vhost;
 	void			*virtio;
 	struct virtio_ops	*ops;
 	u16			endian;
+	void			*iotlb;
 };
 
 struct virtio_ops {
@@ -182,4 +185,14 @@ static inline void virtio_init_device_vq(struct kvm *kvm,
 	vring_init(&vq->vring, nr_descs, p, align);
 }
 
+/*
+ * These are callbacks for IOMMU operations on virtio devices. They are not
+ * operations on the virtio-iommu device. Confusing, I know.
+ */
+const struct iommu_properties *
+virtio__iommu_get_properties(struct device_header *dev);
+
+int virtio__iommu_attach(void *, struct virtio_device *vdev, int flags);
+int virtio__iommu_detach(void *, struct virtio_device *vdev);
+
 #endif /* KVM__VIRTIO_H */
diff --git a/virtio/core.c b/virtio/core.c
index d6ac289d..32bd4ebc 100644
--- a/virtio/core.c
+++ b/virtio/core.c
@@ -6,11 +6,16 @@
 #include "kvm/guest_compat.h"
 #include "kvm/barrier.h"
 #include "kvm/virtio.h"
+#include "kvm/virtio-iommu.h"
 #include "kvm/virtio-pci.h"
 #include "kvm/virtio-mmio.h"
 #include "kvm/util.h"
 #include "kvm/kvm.h"
 
+static void *iommu = NULL;
+static struct iommu_properties iommu_props = {
+	.name		= "viommu-virtio",
+};
 
 const char* virtio_trans_name(enum virtio_trans trans)
 {
@@ -198,6 +203,41 @@ bool virtio_queue__should_signal(struct virt_queue *vq)
 	return false;
 }
 
+const struct iommu_properties *
+virtio__iommu_get_properties(struct device_header *dev)
+{
+	return &iommu_props;
+}
+
+int virtio__iommu_attach(void *priv, struct virtio_device *vdev, int flags)
+{
+	struct virtio_tlb *iotlb = priv;
+
+	if (!iotlb)
+		return -ENOMEM;
+
+	if (vdev->iotlb) {
+		pr_err("device already attached");
+		return -EINVAL;
+	}
+
+	vdev->iotlb = iotlb;
+
+	return 0;
+}
+
+int virtio__iommu_detach(void *priv, struct virtio_device *vdev)
+{
+	if (vdev->iotlb != priv) {
+		pr_err("wrong iotlb"); /* bug */
+		return -EINVAL;
+	}
+
+	vdev->iotlb = NULL;
+
+	return 0;
+}
+
 int virtio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
 		struct virtio_ops *ops, enum virtio_trans trans,
 		int device_id, int subsys_id, int class)
@@ -233,6 +273,18 @@ int virtio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
 		return -1;
 	};
 
+	if (!iommu && vdev->use_iommu) {
+		iommu_props.pgsize_mask = ~(PAGE_SIZE - 1);
+		/*
+		 * With legacy MMIO, we only have 32-bit to hold the vring PFN.
+		 * This limits the IOVA size to (32 + 12) = 44 bits, when using
+		 * 4k pages.
+		 */
+		iommu_props.input_addr_size = 44;
+		iommu = viommu_register(kvm, &iommu_props);
+	}
+
+
 	return 0;
 }
 
diff --git a/virtio/mmio.c b/virtio/mmio.c
index 16b44fbb..24a14a71 100644
--- a/virtio/mmio.c
+++ b/virtio/mmio.c
@@ -1,4 +1,5 @@
 #include "kvm/devices.h"
+#include "kvm/virtio-iommu.h"
 #include "kvm/virtio-mmio.h"
 #include "kvm/ioeventfd.h"
 #include "kvm/iommu.h"
@@ -286,6 +287,30 @@ void virtio_mmio_assign_irq(struct device_header *dev_hdr)
 	vmmio->irq = irq__alloc_line();
 }
 
+#define mmio_dev_to_virtio(dev_hdr)					\
+	container_of(dev_hdr, struct virtio_mmio, dev_hdr)->vdev
+
+static int virtio_mmio_iommu_attach(void *priv, struct device_header *dev_hdr,
+				    int flags)
+{
+	return virtio__iommu_attach(priv, mmio_dev_to_virtio(dev_hdr), flags);
+}
+
+static int virtio_mmio_iommu_detach(void *priv, struct device_header *dev_hdr)
+{
+	return virtio__iommu_detach(priv, mmio_dev_to_virtio(dev_hdr));
+}
+
+static struct iommu_ops virtio_mmio_iommu_ops = {
+	.get_properties		= virtio__iommu_get_properties,
+	.alloc_address_space	= iommu_alloc_address_space,
+	.free_address_space	= iommu_free_address_space,
+	.attach			= virtio_mmio_iommu_attach,
+	.detach			= virtio_mmio_iommu_detach,
+	.map			= iommu_map,
+	.unmap			= iommu_unmap,
+};
+
 int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
 		     int device_id, int subsys_id, int class)
 {
@@ -294,6 +319,7 @@ int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
 	vmmio->addr	= virtio_mmio_get_io_space_block(VIRTIO_MMIO_IO_SIZE);
 	vmmio->kvm	= kvm;
 	vmmio->dev	= dev;
+	vmmio->vdev	= vdev;
 
 	kvm__register_mmio(kvm, vmmio->addr, VIRTIO_MMIO_IO_SIZE,
 			   false, virtio_mmio_mmio_callback, vdev);
@@ -309,6 +335,7 @@ int virtio_mmio_init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
 	vmmio->dev_hdr = (struct device_header) {
 		.bus_type	= DEVICE_BUS_MMIO,
 		.data		= generate_virtio_mmio_fdt_node,
+		.iommu_ops	= vdev->use_iommu ? &virtio_mmio_iommu_ops : NULL,
 	};
 
 	device__register(&vmmio->dev_hdr);
diff --git a/virtio/pci.c b/virtio/pci.c
index b6ef389e..674d5143 100644
--- a/virtio/pci.c
+++ b/virtio/pci.c
@@ -408,6 +408,30 @@ static void virtio_pci__io_mmio_callback(struct kvm_cpu *vcpu,
 	kvm__emulate_io(vcpu, port, data, direction, len, 1);
 }
 
+#define pci_dev_to_virtio(dev_hdr)				\
+	(container_of(dev_hdr, struct virtio_pci, dev_hdr)->vdev)
+
+static int virtio_pci_iommu_attach(void *priv, struct device_header *dev_hdr,
+				   int flags)
+{
+	return virtio__iommu_attach(priv, pci_dev_to_virtio(dev_hdr), flags);
+}
+
+static int virtio_pci_iommu_detach(void *priv, struct device_header *dev_hdr)
+{
+	return virtio__iommu_detach(priv, pci_dev_to_virtio(dev_hdr));
+}
+
+static struct iommu_ops virtio_pci_iommu_ops = {
+	.get_properties		= virtio__iommu_get_properties,
+	.alloc_address_space	= iommu_alloc_address_space,
+	.free_address_space	= iommu_free_address_space,
+	.attach			= virtio_pci_iommu_attach,
+	.detach			= virtio_pci_iommu_detach,
+	.map			= iommu_map,
+	.unmap			= iommu_unmap,
+};
+
 int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
 		     int device_id, int subsys_id, int class)
 {
@@ -416,6 +440,7 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
 
 	vpci->kvm = kvm;
 	vpci->dev = dev;
+	vpci->vdev = vdev;
 
 	r = ioport__register(kvm, IOPORT_EMPTY, &virtio_pci__io_ops, IOPORT_SIZE, vdev);
 	if (r < 0)
@@ -461,6 +486,7 @@ int virtio_pci__init(struct kvm *kvm, void *dev, struct virtio_device *vdev,
 	vpci->dev_hdr = (struct device_header) {
 		.bus_type		= DEVICE_BUS_PCI,
 		.data			= &vpci->pci_hdr,
+		.iommu_ops		= vdev->use_iommu ? &virtio_pci_iommu_ops : NULL,
 	};
 
 	vpci->pci_hdr.msix.cap = PCI_CAP_ID_MSIX;
-- 
2.12.1

  parent reply	other threads:[~2017-04-07 19:24 UTC|newest]

Thread overview: 99+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-07 19:17 [RFC 0/3] virtio-iommu: a paravirtualized IOMMU Jean-Philippe Brucker
2017-04-07 19:17 ` [RFC 1/3] virtio-iommu: firmware description of the virtual topology Jean-Philippe Brucker
2017-04-07 19:17 ` [RFC 2/3] virtio-iommu: device probing and operations Jean-Philippe Brucker
2017-04-18 10:26   ` Tian, Kevin
2017-04-18 18:45     ` Jean-Philippe Brucker
2017-04-18 18:45     ` Jean-Philippe Brucker
2017-04-21  9:02       ` Tian, Kevin
2017-04-24 15:05         ` Jean-Philippe Brucker
     [not found]         ` <AADFC41AFE54684AB9EE6CBC0274A5D190CB262D-0J0gbvR4kThpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2017-04-24 15:05           ` Jean-Philippe Brucker
2017-08-21  7:59             ` Tian, Kevin
2017-08-21 12:00               ` Jean-Philippe Brucker
2017-08-21 12:00               ` Jean-Philippe Brucker
2017-08-21 12:00                 ` [virtio-dev] " Jean-Philippe Brucker
     [not found]                 ` <454095c4-cae5-ad52-a459-5c9e2cce4047-5wv7dgnIgG8@public.gmane.org>
2017-08-22  6:24                   ` Tian, Kevin
2017-08-22 14:19                     ` Jean-Philippe Brucker
2017-08-22 14:19                     ` Jean-Philippe Brucker
2017-08-22 14:19                       ` [virtio-dev] " Jean-Philippe Brucker
2017-08-23  2:23                       ` Tian, Kevin
2017-08-23  2:23                       ` Tian, Kevin
2017-08-23  2:23                         ` [virtio-dev] " Tian, Kevin
2017-08-22  6:24                 ` Tian, Kevin
2017-04-18 10:26   ` Tian, Kevin
2017-04-07 19:17 ` Jean-Philippe Brucker
2017-04-07 19:17 ` [RFC 3/3] virtio-iommu: future work Jean-Philippe Brucker
2017-04-21  8:31   ` Tian, Kevin
     [not found]   ` <20170407191747.26618-4-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2017-04-21  8:31     ` Tian, Kevin
2017-04-24 15:05       ` Jean-Philippe Brucker
2017-04-24 15:05       ` Jean-Philippe Brucker
2017-04-26 16:24     ` Michael S. Tsirkin
2017-04-26 16:24   ` Michael S. Tsirkin
2017-04-07 19:17 ` Jean-Philippe Brucker
2017-04-07 19:23 ` [RFC PATCH linux] iommu: Add virtio-iommu driver Jean-Philippe Brucker
2017-06-16  8:48   ` [virtio-dev] " Bharat Bhushan
2017-06-16 11:36     ` Jean-Philippe Brucker
2017-06-16 11:36     ` Jean-Philippe Brucker
2017-06-16  8:48   ` Bharat Bhushan
2017-04-07 19:24 ` [RFC PATCH kvmtool 00/15] Add virtio-iommu Jean-Philippe Brucker
2017-04-07 19:24   ` [RFC PATCH kvmtool 01/15] virtio: synchronize virtio-iommu headers with Linux Jean-Philippe Brucker
2017-04-07 19:24   ` Jean-Philippe Brucker
2017-04-07 19:24   ` [RFC PATCH kvmtool 02/15] FDT: (re)introduce a dynamic phandle allocator Jean-Philippe Brucker
2017-04-07 19:24   ` Jean-Philippe Brucker
2017-04-07 19:24   ` [RFC PATCH kvmtool 03/15] virtio: add virtio-iommu Jean-Philippe Brucker
2017-04-07 19:24   ` Jean-Philippe Brucker
2017-04-07 19:24   ` [RFC PATCH kvmtool 04/15] Add a simple IOMMU Jean-Philippe Brucker
2017-04-07 19:24   ` Jean-Philippe Brucker
2017-04-07 19:24   ` [RFC PATCH kvmtool 05/15] iommu: describe IOMMU topology in device-trees Jean-Philippe Brucker
2017-04-07 19:24   ` Jean-Philippe Brucker
2017-04-07 19:24   ` [RFC PATCH kvmtool 06/15] irq: register MSI doorbell addresses Jean-Philippe Brucker
2017-04-07 19:24   ` Jean-Philippe Brucker
2017-04-07 19:24   ` [RFC PATCH kvmtool 07/15] virtio: factor virtqueue initialization Jean-Philippe Brucker
2017-04-07 19:24   ` Jean-Philippe Brucker
2017-04-07 19:24   ` Jean-Philippe Brucker [this message]
2017-04-07 19:24   ` [RFC PATCH kvmtool 08/15] virtio: add vIOMMU instance for virtio devices Jean-Philippe Brucker
2017-04-07 19:24   ` [RFC PATCH kvmtool 09/15] virtio: access vring and buffers through IOMMU mappings Jean-Philippe Brucker
2017-04-07 19:24   ` Jean-Philippe Brucker
2017-04-07 19:24   ` [RFC PATCH kvmtool 10/15] virtio-pci: translate MSIs with the virtual IOMMU Jean-Philippe Brucker
2017-04-07 19:24   ` Jean-Philippe Brucker
2017-04-07 19:24   ` [RFC PATCH kvmtool 11/15] virtio: set VIRTIO_F_IOMMU_PLATFORM when necessary Jean-Philippe Brucker
2017-04-07 19:24   ` Jean-Philippe Brucker
2017-04-07 19:24   ` [RFC PATCH kvmtool 12/15] vfio: add support for virtual IOMMU Jean-Philippe Brucker
2017-04-07 19:24   ` Jean-Philippe Brucker
2017-04-07 19:24   ` [RFC PATCH kvmtool 13/15] virtio-iommu: debug via IPC Jean-Philippe Brucker
2017-04-07 19:24   ` Jean-Philippe Brucker
2017-04-07 19:24   ` [RFC PATCH kvmtool 14/15] virtio-iommu: implement basic debug commands Jean-Philippe Brucker
2017-04-07 19:24   ` Jean-Philippe Brucker
2017-04-07 19:24   ` [RFC PATCH kvmtool 15/15] virtio: use virtio-iommu when available Jean-Philippe Brucker
2017-04-07 19:24   ` Jean-Philippe Brucker
2017-05-22  8:26   ` [RFC PATCH kvmtool 00/15] Add virtio-iommu Bharat Bhushan
     [not found]   ` <20170407192455.26814-1-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2017-05-22  8:26     ` Bharat Bhushan
2017-05-22 14:01       ` Jean-Philippe Brucker
     [not found]       ` <AM5PR0401MB2545FADDF2A7649DF0DB68309AF80-oQ3wXcTHOqrg6d/1FbYcvI3W/0Ik+aLCnBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2017-05-22 14:01         ` Jean-Philippe Brucker
2017-04-07 21:19 ` [RFC 0/3] virtio-iommu: a paravirtualized IOMMU Michael S. Tsirkin
2017-04-07 21:19 ` Michael S. Tsirkin
2017-04-10 18:39   ` [virtio-dev] " Jean-Philippe Brucker
2017-04-10 18:39   ` Jean-Philippe Brucker
2017-04-10 20:04     ` [virtio-dev] " Michael S. Tsirkin
2017-04-10 20:04     ` Michael S. Tsirkin
2017-04-10  2:30 ` Need information on type 2 IOMMU valmiki
2017-04-12  9:06 ` [RFC 0/3] virtio-iommu: a paravirtualized IOMMU Jason Wang
2017-04-13  8:16   ` Tian, Kevin
     [not found]   ` <a0920e37-a11e-784c-7d90-be6617ea7686-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2017-04-13  8:16     ` Tian, Kevin
     [not found]       ` <AADFC41AFE54684AB9EE6CBC0274A5D190CA990E-0J0gbvR4kThpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2017-04-13 13:12         ` Jean-Philippe Brucker
2017-04-13 13:12       ` Jean-Philippe Brucker
2017-04-12  9:06 ` Jason Wang
2017-04-13  8:41 ` Tian, Kevin
     [not found] ` <20170407191747.26618-1-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2017-04-07 19:17   ` [RFC 1/3] virtio-iommu: firmware description of the virtual topology Jean-Philippe Brucker
     [not found]     ` <20170407191747.26618-2-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2017-04-18  9:51       ` Tian, Kevin
2017-04-18 18:41         ` Jean-Philippe Brucker
2017-04-21  8:43           ` Tian, Kevin
     [not found]             ` <AADFC41AFE54684AB9EE6CBC0274A5D190CB2570-0J0gbvR4kThpB2pF5aRoyrfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2017-04-24 15:05               ` Jean-Philippe Brucker
2017-04-24 15:05             ` Jean-Philippe Brucker
2017-04-18 18:41         ` Jean-Philippe Brucker
2017-04-18  9:51     ` Tian, Kevin
2017-04-10  2:30   ` Need information on type 2 IOMMU valmiki
     [not found]     ` <1b48daab-c9e1-84d1-78a9-84d3e2001f32-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2017-04-10  4:19       ` Alex Williamson
2017-04-10  4:19     ` Alex Williamson
2017-04-13  8:41   ` [RFC 0/3] virtio-iommu: a paravirtualized IOMMU Tian, Kevin
2017-04-13 13:12     ` Jean-Philippe Brucker
2017-04-13 13:12     ` Jean-Philippe Brucker

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=20170407192455.26814-9-jean-philippe.brucker@arm.com \
    --to=jean-philippe.brucker@arm.com \
    --cc=alex.williamson@redhat.com \
    --cc=cdall@linaro.org \
    --cc=iommu@lists.linux-foundation.org \
    --cc=jasowang@redhat.com \
    --cc=joro@8bytes.org \
    --cc=kvm@vger.kernel.org \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=marc.zyngier@arm.com \
    --cc=mst@redhat.com \
    --cc=robin.murphy@arm.com \
    --cc=virtio-dev@lists.oasis-open.org \
    --cc=virtualization@lists.linux-foundation.org \
    --cc=will.deacon@arm.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.