Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1257707 > unrolled thread
| Started by | Andy Lutomirski <luto@kernel.org> |
|---|---|
| First post | 2015-10-28 07:40 +0100 |
| Last post | 2015-10-28 15:10 +0100 |
| Articles | 20 on this page of 26 — 7 participants |
Back to article view | Back to linux.kernel
[PATCH v3 0/3] virtio DMA API core stuff Andy Lutomirski <luto@kernel.org> - 2015-10-28 07:40 +0100
[PATCH v3 2/3] virtio_ring: Support DMA APIs Andy Lutomirski <luto@kernel.org> - 2015-10-28 07:50 +0100
[PATCH v3 3/3] virtio_pci: Use the DMA API Andy Lutomirski <luto@kernel.org> - 2015-10-28 07:50 +0100
[PATCH v3 1/3] virtio_net: Stop doing DMA from the stack Andy Lutomirski <luto@kernel.org> - 2015-10-28 07:50 +0100
Re: [PATCH v3 1/3] virtio_net: Stop doing DMA from the stack "Michael S. Tsirkin" <mst@redhat.com> - 2015-10-28 08:10 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff David Woodhouse <dwmw2@infradead.org> - 2015-10-28 08:00 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff Andy Lutomirski <luto@amacapital.net> - 2015-10-28 08:20 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff "Michael S. Tsirkin" <mst@redhat.com> - 2015-10-28 08:20 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff Christian Borntraeger <borntraeger@de.ibm.com> - 2015-10-28 08:50 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff David Woodhouse <dwmw2@infradead.org> - 2015-10-28 09:20 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff "Michael S. Tsirkin" <mst@redhat.com> - 2015-10-28 12:40 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff David Woodhouse <dwmw2@infradead.org> - 2015-10-28 14:40 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff "Michael S. Tsirkin" <mst@redhat.com> - 2015-10-28 15:10 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff David Woodhouse <dwmw2@infradead.org> - 2015-10-28 15:20 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff "Michael S. Tsirkin" <mst@redhat.com> - 2015-10-28 15:30 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff David Woodhouse <dwmw2@infradead.org> - 2015-10-28 15:40 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff "Michael S. Tsirkin" <mst@redhat.com> - 2015-10-28 17:20 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff Andy Lutomirski <luto@amacapital.net> - 2015-10-29 00:00 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff "Michael S. Tsirkin" <mst@redhat.com> - 2015-10-29 10:10 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff David Woodhouse <dwmw2@infradead.org> - 2015-10-29 17:20 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff Joerg Roedel <jroedel@suse.de> - 2015-10-30 16:20 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff David Woodhouse <dwmw2@infradead.org> - 2015-10-30 18:00 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff Benjamin Herrenschmidt <benh@kernel.crashing.org> - 2015-10-28 09:40 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff "Michael S. Tsirkin" <mst@redhat.com> - 2015-10-28 12:30 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff David Woodhouse <dwmw2@infradead.org> - 2015-10-28 14:40 +0100
Re: [PATCH v3 0/3] virtio DMA API core stuff "Michael S. Tsirkin" <mst@redhat.com> - 2015-10-28 15:10 +0100
Page 1 of 2 [1] 2 Next page →
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2015-10-28 07:40 +0100 |
| Subject | [PATCH v3 0/3] virtio DMA API core stuff |
| Message-ID | <qosyS-7ut-7@gated-at.bofh.it> |
This switches virtio to use the DMA API unconditionally. I'm sure it breaks things, but it seems to work on x86 using virtio-pci, with and without Xen, and using both the modern 1.0 variant and the legacy variant. Changes from v2: - Fix really embarrassing bug. This version actually works. Changes from v1: - Fix an endian conversion error causing a BUG to hit. - Fix a DMA ordering issue (swiotlb=force works now). - Minor cleanups. Andy Lutomirski (3): virtio_net: Stop doing DMA from the stack virtio_ring: Support DMA APIs virtio_pci: Use the DMA API drivers/net/virtio_net.c | 53 +++++++---- drivers/virtio/Kconfig | 2 +- drivers/virtio/virtio_pci_common.h | 3 +- drivers/virtio/virtio_pci_legacy.c | 19 +++- drivers/virtio/virtio_pci_modern.c | 34 +++++-- drivers/virtio/virtio_ring.c | 187 ++++++++++++++++++++++++++++++------- tools/virtio/linux/dma-mapping.h | 17 ++++ 7 files changed, 246 insertions(+), 69 deletions(-) create mode 100644 tools/virtio/linux/dma-mapping.h -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [next] | [standalone]
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2015-10-28 07:50 +0100 |
| Subject | [PATCH v3 2/3] virtio_ring: Support DMA APIs |
| Message-ID | <qosIx-7ys-11@gated-at.bofh.it> |
| In reply to | #1257707 |
virtio_ring currently sends the device (usually a hypervisor)
physical addresses of its I/O buffers. This is okay when DMA
addresses and physical addresses are the same thing, but this isn't
always the case. For example, this never works on Xen guests, and
it is likely to fail if a physical "virtio" device ever ends up
behind an IOMMU or swiotlb.
The immediate use case for me is to enable virtio on Xen guests.
For that to work, we need vring to support DMA address translation
as well as a corresponding change to virtio_pci or to another
driver.
With this patch, if enabled, virtfs survives kmemleak and
CONFIG_DMA_API_DEBUG.
Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
drivers/virtio/Kconfig | 2 +-
drivers/virtio/virtio_ring.c | 187 +++++++++++++++++++++++++++++++--------
tools/virtio/linux/dma-mapping.h | 17 ++++
3 files changed, 169 insertions(+), 37 deletions(-)
create mode 100644 tools/virtio/linux/dma-mapping.h
diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
index cab9f3f63a38..77590320d44c 100644
--- a/drivers/virtio/Kconfig
+++ b/drivers/virtio/Kconfig
@@ -60,7 +60,7 @@ config VIRTIO_INPUT
config VIRTIO_MMIO
tristate "Platform bus driver for memory mapped virtio devices"
- depends on HAS_IOMEM
+ depends on HAS_IOMEM && HAS_DMA
select VIRTIO
---help---
This drivers provides support for memory mapped virtio
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 096b857e7b75..6962ea37ade0 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -24,6 +24,7 @@
#include <linux/module.h>
#include <linux/hrtimer.h>
#include <linux/kmemleak.h>
+#include <linux/dma-mapping.h>
#ifdef DEBUG
/* For development, we want to crash whenever the ring is screwed. */
@@ -54,7 +55,14 @@
#define END_USE(vq)
#endif
-struct vring_virtqueue {
+struct vring_desc_state
+{
+ void *data; /* Data for callback. */
+ struct vring_desc *indir_desc; /* Indirect descriptor, if any. */
+};
+
+struct vring_virtqueue
+{
struct virtqueue vq;
/* Actual memory layout for this queue */
@@ -92,12 +100,71 @@ struct vring_virtqueue {
ktime_t last_add_time;
#endif
- /* Tokens for callbacks. */
- void *data[];
+ /* Per-descriptor state. */
+ struct vring_desc_state desc_state[];
};
#define to_vvq(_vq) container_of(_vq, struct vring_virtqueue, vq)
+/*
+ * The DMA ops on various arches are rather gnarly right now, and
+ * making all of the arch DMA ops work on the vring device itself
+ * is a mess. For now, we use the parent device for DMA ops.
+ */
+struct device *vring_dma_dev(const struct vring_virtqueue *vq)
+{
+ return vq->vq.vdev->dev.parent;
+}
+
+/* Map one sg entry. */
+static dma_addr_t vring_map_one_sg(const struct vring_virtqueue *vq,
+ struct scatterlist *sg,
+ enum dma_data_direction direction)
+{
+ /*
+ * We can't use dma_map_sg, because we don't use scatterlists in
+ * the way it expects (we don't guarantee that the scatterlist
+ * will exist for the lifetime of the mapping).
+ */
+ return dma_map_page(vring_dma_dev(vq),
+ sg_page(sg), sg->offset, sg->length,
+ direction);
+}
+
+static dma_addr_t vring_map_single(const struct vring_virtqueue *vq,
+ void *cpu_addr, size_t size,
+ enum dma_data_direction direction)
+{
+ return dma_map_single(vring_dma_dev(vq),
+ cpu_addr, size, direction);
+}
+
+static void vring_unmap_one(const struct vring_virtqueue *vq,
+ struct vring_desc *desc)
+{
+ u16 flags = virtio16_to_cpu(vq->vq.vdev, desc->flags);
+
+ if (flags & VRING_DESC_F_INDIRECT) {
+ dma_unmap_single(vring_dma_dev(vq),
+ virtio64_to_cpu(vq->vq.vdev, desc->addr),
+ virtio32_to_cpu(vq->vq.vdev, desc->len),
+ (flags & VRING_DESC_F_WRITE) ?
+ DMA_FROM_DEVICE : DMA_TO_DEVICE);
+ } else {
+ dma_unmap_page(vring_dma_dev(vq),
+ virtio64_to_cpu(vq->vq.vdev, desc->addr),
+ virtio32_to_cpu(vq->vq.vdev, desc->len),
+ (flags & VRING_DESC_F_WRITE) ?
+ DMA_FROM_DEVICE : DMA_TO_DEVICE);
+ }
+}
+
+static int vring_mapping_error(const struct vring_virtqueue *vq,
+ dma_addr_t addr)
+{
+ return dma_mapping_error(vring_dma_dev(vq), addr);
+}
+
static struct vring_desc *alloc_indirect(struct virtqueue *_vq,
unsigned int total_sg, gfp_t gfp)
{
@@ -131,7 +198,7 @@ static inline int virtqueue_add(struct virtqueue *_vq,
struct vring_virtqueue *vq = to_vvq(_vq);
struct scatterlist *sg;
struct vring_desc *desc;
- unsigned int i, n, avail, descs_used, uninitialized_var(prev);
+ unsigned int i, n, avail, descs_used, uninitialized_var(prev), err_idx;
int head;
bool indirect;
@@ -171,21 +238,15 @@ static inline int virtqueue_add(struct virtqueue *_vq,
if (desc) {
/* Use a single buffer which doesn't continue */
- vq->vring.desc[head].flags = cpu_to_virtio16(_vq->vdev, VRING_DESC_F_INDIRECT);
- vq->vring.desc[head].addr = cpu_to_virtio64(_vq->vdev, virt_to_phys(desc));
- /* avoid kmemleak false positive (hidden by virt_to_phys) */
- kmemleak_ignore(desc);
- vq->vring.desc[head].len = cpu_to_virtio32(_vq->vdev, total_sg * sizeof(struct vring_desc));
-
+ indirect = true;
/* Set up rest to use this indirect table. */
i = 0;
descs_used = 1;
- indirect = true;
} else {
+ indirect = false;
desc = vq->vring.desc;
i = head;
descs_used = total_sg;
- indirect = false;
}
if (vq->vq.num_free < descs_used) {
@@ -200,14 +261,13 @@ static inline int virtqueue_add(struct virtqueue *_vq,
return -ENOSPC;
}
- /* We're about to use some buffers from the free list. */
- vq->vq.num_free -= descs_used;
-
for (n = 0; n < out_sgs; n++) {
for (sg = sgs[n]; sg; sg = sg_next(sg)) {
desc[i].flags = cpu_to_virtio16(_vq->vdev, VRING_DESC_F_NEXT);
- desc[i].addr = cpu_to_virtio64(_vq->vdev, sg_phys(sg));
+ desc[i].addr = cpu_to_virtio64(_vq->vdev, vring_map_one_sg(vq, sg, DMA_TO_DEVICE));
desc[i].len = cpu_to_virtio32(_vq->vdev, sg->length);
+ if (vring_mapping_error(vq, desc[i].addr))
+ goto unmap_release;
prev = i;
i = virtio16_to_cpu(_vq->vdev, desc[i].next);
}
@@ -215,8 +275,10 @@ static inline int virtqueue_add(struct virtqueue *_vq,
for (; n < (out_sgs + in_sgs); n++) {
for (sg = sgs[n]; sg; sg = sg_next(sg)) {
desc[i].flags = cpu_to_virtio16(_vq->vdev, VRING_DESC_F_NEXT | VRING_DESC_F_WRITE);
- desc[i].addr = cpu_to_virtio64(_vq->vdev, sg_phys(sg));
+ desc[i].addr = cpu_to_virtio64(_vq->vdev, vring_map_one_sg(vq, sg, DMA_FROM_DEVICE));
desc[i].len = cpu_to_virtio32(_vq->vdev, sg->length);
+ if (vring_mapping_error(vq, desc[i].addr))
+ goto unmap_release;
prev = i;
i = virtio16_to_cpu(_vq->vdev, desc[i].next);
}
@@ -224,14 +286,34 @@ static inline int virtqueue_add(struct virtqueue *_vq,
/* Last one doesn't continue. */
desc[prev].flags &= cpu_to_virtio16(_vq->vdev, ~VRING_DESC_F_NEXT);
+ if (indirect) {
+ /* Now that the indirect table is filled in, map it. */
+ dma_addr_t addr = vring_map_single(
+ vq, desc, total_sg * sizeof(struct vring_desc),
+ DMA_TO_DEVICE);
+
+ if (vring_mapping_error(vq, addr))
+ goto unmap_release;
+
+ vq->vring.desc[head].flags = cpu_to_virtio16(_vq->vdev, VRING_DESC_F_INDIRECT);
+ vq->vring.desc[head].addr = cpu_to_virtio64(_vq->vdev, addr);
+
+ vq->vring.desc[head].len = cpu_to_virtio32(_vq->vdev, total_sg * sizeof(struct vring_desc));
+ }
+
+ /* We're using some buffers from the free list. */
+ vq->vq.num_free -= descs_used;
+
/* Update free pointer */
if (indirect)
vq->free_head = virtio16_to_cpu(_vq->vdev, vq->vring.desc[head].next);
else
vq->free_head = i;
- /* Set token. */
- vq->data[head] = data;
+ /* Store token and indirect buffer state. */
+ vq->desc_state[head].data = data;
+ if (indirect)
+ vq->desc_state[head].indir_desc = desc;
/* Put entry in available array (but don't update avail->idx until they
* do sync). */
@@ -253,6 +335,24 @@ static inline int virtqueue_add(struct virtqueue *_vq,
virtqueue_kick(_vq);
return 0;
+
+unmap_release:
+ err_idx = i;
+ i = head;
+
+ for (n = 0; n < total_sg; n++) {
+ if (i == err_idx)
+ break;
+ vring_unmap_one(vq, &desc[i]);
+ i = vq->vring.desc[i].next;
+ }
+
+ vq->vq.num_free += total_sg;
+
+ if (indirect)
+ kfree(desc);
+
+ return -EIO;
}
/**
@@ -423,27 +523,43 @@ EXPORT_SYMBOL_GPL(virtqueue_kick);
static void detach_buf(struct vring_virtqueue *vq, unsigned int head)
{
- unsigned int i;
+ unsigned int i, j;
+ u16 nextflag = cpu_to_virtio16(vq->vq.vdev, VRING_DESC_F_NEXT);
/* Clear data ptr. */
- vq->data[head] = NULL;
+ vq->desc_state[head].data = NULL;
- /* Put back on free list: find end */
+ /* Put back on free list: unmap first-level descriptors and find end */
i = head;
- /* Free the indirect table */
- if (vq->vring.desc[i].flags & cpu_to_virtio16(vq->vq.vdev, VRING_DESC_F_INDIRECT))
- kfree(phys_to_virt(virtio64_to_cpu(vq->vq.vdev, vq->vring.desc[i].addr)));
-
- while (vq->vring.desc[i].flags & cpu_to_virtio16(vq->vq.vdev, VRING_DESC_F_NEXT)) {
+ while (vq->vring.desc[i].flags & nextflag) {
+ vring_unmap_one(vq, &vq->vring.desc[i]);
i = virtio16_to_cpu(vq->vq.vdev, vq->vring.desc[i].next);
vq->vq.num_free++;
}
+ vring_unmap_one(vq, &vq->vring.desc[i]);
vq->vring.desc[i].next = cpu_to_virtio16(vq->vq.vdev, vq->free_head);
vq->free_head = head;
+
/* Plus final descriptor */
vq->vq.num_free++;
+
+ /* Free the indirect table, if any, now that it's unmapped. */
+ if (vq->desc_state[head].indir_desc) {
+ struct vring_desc *indir_desc = vq->desc_state[head].indir_desc;
+ u32 len = vq->vring.desc[head].len;
+
+ BUG_ON(!(vq->vring.desc[head].flags &
+ cpu_to_virtio16(vq->vq.vdev, VRING_DESC_F_INDIRECT)));
+ BUG_ON(len == 0 || len % sizeof(struct vring_desc));
+
+ for (j = 0; j < len / sizeof(struct vring_desc); j++)
+ vring_unmap_one(vq, &indir_desc[j]);
+
+ kfree(vq->desc_state[head].indir_desc);
+ vq->desc_state[head].indir_desc = NULL;
+ }
}
static inline bool more_used(const struct vring_virtqueue *vq)
@@ -498,13 +614,13 @@ void *virtqueue_get_buf(struct virtqueue *_vq, unsigned int *len)
BAD_RING(vq, "id %u out of range\n", i);
return NULL;
}
- if (unlikely(!vq->data[i])) {
+ if (unlikely(!vq->desc_state[i].data)) {
BAD_RING(vq, "id %u is not a head!\n", i);
return NULL;
}
/* detach_buf clears data, so grab it now. */
- ret = vq->data[i];
+ ret = vq->desc_state[i].data;
detach_buf(vq, i);
vq->last_used_idx++;
/* If we expect an interrupt for the next entry, tell host
@@ -665,10 +781,10 @@ void *virtqueue_detach_unused_buf(struct virtqueue *_vq)
START_USE(vq);
for (i = 0; i < vq->vring.num; i++) {
- if (!vq->data[i])
+ if (!vq->desc_state[i].data)
continue;
/* detach_buf clears data, so grab it now. */
- buf = vq->data[i];
+ buf = vq->desc_state[i].data;
detach_buf(vq, i);
vq->vring.avail->idx = cpu_to_virtio16(_vq->vdev, virtio16_to_cpu(_vq->vdev, vq->vring.avail->idx) - 1);
END_USE(vq);
@@ -721,7 +837,8 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
return NULL;
}
- vq = kmalloc(sizeof(*vq) + sizeof(void *)*num, GFP_KERNEL);
+ vq = kmalloc(sizeof(*vq) + num * sizeof(struct vring_desc_state),
+ GFP_KERNEL);
if (!vq)
return NULL;
@@ -751,11 +868,9 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
/* Put everything in free lists. */
vq->free_head = 0;
- for (i = 0; i < num-1; i++) {
+ for (i = 0; i < num-1; i++)
vq->vring.desc[i].next = cpu_to_virtio16(vdev, i + 1);
- vq->data[i] = NULL;
- }
- vq->data[i] = NULL;
+ memset(vq->desc_state, 0, num * sizeof(struct vring_desc_state));
return &vq->vq;
}
diff --git a/tools/virtio/linux/dma-mapping.h b/tools/virtio/linux/dma-mapping.h
new file mode 100644
index 000000000000..4f93af89ae16
--- /dev/null
+++ b/tools/virtio/linux/dma-mapping.h
@@ -0,0 +1,17 @@
+#ifndef _LINUX_DMA_MAPPING_H
+#define _LINUX_DMA_MAPPING_H
+
+#ifdef CONFIG_HAS_DMA
+# error Virtio userspace code does not support CONFIG_HAS_DMA
+#endif
+
+#define PCI_DMA_BUS_IS_PHYS 1
+
+enum dma_data_direction {
+ DMA_BIDIRECTIONAL = 0,
+ DMA_TO_DEVICE = 1,
+ DMA_FROM_DEVICE = 2,
+ DMA_NONE = 3,
+};
+
+#endif
--
2.4.3
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2015-10-28 07:50 +0100 |
| Subject | [PATCH v3 3/3] virtio_pci: Use the DMA API |
| Message-ID | <qosIx-7ys-13@gated-at.bofh.it> |
| In reply to | #1257707 |
This fixes virtio-pci on platforms and busses that have IOMMUs. This
will break the experimental QEMU Q35 IOMMU support until QEMU is
fixed. In exchange, it fixes physical virtio hardware as well as
virtio-pci running under Xen.
We should clean up the virtqueue API to do its own allocation and
teach virtqueue_get_avail and virtqueue_get_used to return DMA
addresses directly.
Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
drivers/virtio/virtio_pci_common.h | 3 ++-
drivers/virtio/virtio_pci_legacy.c | 19 +++++++++++++++----
drivers/virtio/virtio_pci_modern.c | 34 ++++++++++++++++++++++++----------
3 files changed, 41 insertions(+), 15 deletions(-)
diff --git a/drivers/virtio/virtio_pci_common.h b/drivers/virtio/virtio_pci_common.h
index b976d968e793..cd6196b513ad 100644
--- a/drivers/virtio/virtio_pci_common.h
+++ b/drivers/virtio/virtio_pci_common.h
@@ -38,8 +38,9 @@ struct virtio_pci_vq_info {
/* the number of entries in the queue */
int num;
- /* the virtual address of the ring queue */
+ /* the ring queue */
void *queue;
+ dma_addr_t queue_dma_addr; /* bus address */
/* the list node for the virtqueues list */
struct list_head node;
diff --git a/drivers/virtio/virtio_pci_legacy.c b/drivers/virtio/virtio_pci_legacy.c
index 48bc9797e530..b5293e5f2af4 100644
--- a/drivers/virtio/virtio_pci_legacy.c
+++ b/drivers/virtio/virtio_pci_legacy.c
@@ -135,12 +135,14 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
info->msix_vector = msix_vec;
size = PAGE_ALIGN(vring_size(num, VIRTIO_PCI_VRING_ALIGN));
- info->queue = alloc_pages_exact(size, GFP_KERNEL|__GFP_ZERO);
+ info->queue = dma_zalloc_coherent(&vp_dev->pci_dev->dev, size,
+ &info->queue_dma_addr,
+ GFP_KERNEL);
if (info->queue == NULL)
return ERR_PTR(-ENOMEM);
/* activate the queue */
- iowrite32(virt_to_phys(info->queue) >> VIRTIO_PCI_QUEUE_ADDR_SHIFT,
+ iowrite32(info->queue_dma_addr >> VIRTIO_PCI_QUEUE_ADDR_SHIFT,
vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN);
/* create the vring */
@@ -169,7 +171,8 @@ out_assign:
vring_del_virtqueue(vq);
out_activate_queue:
iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN);
- free_pages_exact(info->queue, size);
+ dma_free_coherent(&vp_dev->pci_dev->dev, size,
+ info->queue, info->queue_dma_addr);
return ERR_PTR(err);
}
@@ -194,7 +197,8 @@ static void del_vq(struct virtio_pci_vq_info *info)
iowrite32(0, vp_dev->ioaddr + VIRTIO_PCI_QUEUE_PFN);
size = PAGE_ALIGN(vring_size(info->num, VIRTIO_PCI_VRING_ALIGN));
- free_pages_exact(info->queue, size);
+ dma_free_coherent(&vp_dev->pci_dev->dev, size,
+ info->queue, info->queue_dma_addr);
}
static const struct virtio_config_ops virtio_pci_config_ops = {
@@ -227,6 +231,13 @@ int virtio_pci_legacy_probe(struct virtio_pci_device *vp_dev)
return -ENODEV;
}
+ rc = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(64));
+ if (rc)
+ rc = dma_set_mask_and_coherent(&pci_dev->dev,
+ DMA_BIT_MASK(32));
+ if (rc)
+ dev_warn(&pci_dev->dev, "Failed to enable 64-bit or 32-bit DMA. Trying to continue, but this might not work.\n");
+
rc = pci_request_region(pci_dev, 0, "virtio-pci-legacy");
if (rc)
return rc;
diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c
index 8e5cf194cc0b..fbe0bd1c4881 100644
--- a/drivers/virtio/virtio_pci_modern.c
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -293,14 +293,16 @@ static size_t vring_pci_size(u16 num)
return PAGE_ALIGN(vring_size(num, SMP_CACHE_BYTES));
}
-static void *alloc_virtqueue_pages(int *num)
+static void *alloc_virtqueue_pages(struct virtio_pci_device *vp_dev,
+ int *num, dma_addr_t *dma_addr)
{
void *pages;
/* TODO: allocate each queue chunk individually */
for (; *num && vring_pci_size(*num) > PAGE_SIZE; *num /= 2) {
- pages = alloc_pages_exact(vring_pci_size(*num),
- GFP_KERNEL|__GFP_ZERO|__GFP_NOWARN);
+ pages = dma_zalloc_coherent(
+ &vp_dev->pci_dev->dev, vring_pci_size(*num),
+ dma_addr, GFP_KERNEL|__GFP_NOWARN);
if (pages)
return pages;
}
@@ -309,7 +311,9 @@ static void *alloc_virtqueue_pages(int *num)
return NULL;
/* Try to get a single page. You are my only hope! */
- return alloc_pages_exact(vring_pci_size(*num), GFP_KERNEL|__GFP_ZERO);
+ return dma_zalloc_coherent(
+ &vp_dev->pci_dev->dev, vring_pci_size(*num),
+ dma_addr, GFP_KERNEL);
}
static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
@@ -346,7 +350,8 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
info->num = num;
info->msix_vector = msix_vec;
- info->queue = alloc_virtqueue_pages(&info->num);
+ info->queue = alloc_virtqueue_pages(vp_dev, &info->num,
+ &info->queue_dma_addr);
if (info->queue == NULL)
return ERR_PTR(-ENOMEM);
@@ -361,11 +366,11 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
/* activate the queue */
vp_iowrite16(num, &cfg->queue_size);
- vp_iowrite64_twopart(virt_to_phys(info->queue),
+ vp_iowrite64_twopart(info->queue_dma_addr,
&cfg->queue_desc_lo, &cfg->queue_desc_hi);
- vp_iowrite64_twopart(virt_to_phys(virtqueue_get_avail(vq)),
+ vp_iowrite64_twopart(info->queue_dma_addr + ((char *)virtqueue_get_avail(vq) - (char *)info->queue),
&cfg->queue_avail_lo, &cfg->queue_avail_hi);
- vp_iowrite64_twopart(virt_to_phys(virtqueue_get_used(vq)),
+ vp_iowrite64_twopart(info->queue_dma_addr + ((char *)virtqueue_get_used(vq) - (char *)info->queue),
&cfg->queue_used_lo, &cfg->queue_used_hi);
if (vp_dev->notify_base) {
@@ -411,7 +416,8 @@ err_assign_vector:
err_map_notify:
vring_del_virtqueue(vq);
err_new_queue:
- free_pages_exact(info->queue, vring_pci_size(info->num));
+ dma_free_coherent(&vp_dev->pci_dev->dev, vring_pci_size(info->num),
+ info->queue, info->queue_dma_addr);
return ERR_PTR(err);
}
@@ -457,7 +463,8 @@ static void del_vq(struct virtio_pci_vq_info *info)
vring_del_virtqueue(vq);
- free_pages_exact(info->queue, vring_pci_size(info->num));
+ dma_free_coherent(&vp_dev->pci_dev->dev, vring_pci_size(info->num),
+ info->queue, info->queue_dma_addr);
}
static const struct virtio_config_ops virtio_pci_config_nodev_ops = {
@@ -641,6 +648,13 @@ int virtio_pci_modern_probe(struct virtio_pci_device *vp_dev)
return -EINVAL;
}
+ err = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(64));
+ if (err)
+ err = dma_set_mask_and_coherent(&pci_dev->dev,
+ DMA_BIT_MASK(32));
+ if (err)
+ dev_warn(&pci_dev->dev, "Failed to enable 64-bit or 32-bit DMA. Trying to continue, but this might not work.\n");
+
/* Device capability is only mandatory for devices that have
* device-specific configuration.
*/
--
2.4.3
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@kernel.org> |
|---|---|
| Date | 2015-10-28 07:50 +0100 |
| Subject | [PATCH v3 1/3] virtio_net: Stop doing DMA from the stack |
| Message-ID | <qosIx-7ys-17@gated-at.bofh.it> |
| In reply to | #1257707 |
From: Andy Lutomirski <luto@amacapital.net>
Once virtio starts using the DMA API, we won't be able to safely DMA
from the stack. virtio-net does a couple of config DMA requests
from small stack buffers -- switch to using dynamically-allocated
memory.
This should have no effect on any performance-critical code paths.
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: virtualization@lists.linux-foundation.org
Reviewed-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Andy Lutomirski <luto@kernel.org>
---
Hi Michael and DaveM-
This is a prerequisite for the virtio DMA fixing project. It works
as a standalone patch, though. Would it make sense to apply it to
an appropriate networking tree now?
(This is unchanged from v2.)
drivers/net/virtio_net.c | 53 ++++++++++++++++++++++++++++++++----------------
1 file changed, 36 insertions(+), 17 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index d8838dedb7a4..4f10f8a58811 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -976,31 +976,43 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
struct scatterlist *out)
{
struct scatterlist *sgs[4], hdr, stat;
- struct virtio_net_ctrl_hdr ctrl;
- virtio_net_ctrl_ack status = ~0;
+
+ struct {
+ struct virtio_net_ctrl_hdr ctrl;
+ virtio_net_ctrl_ack status;
+ } *buf;
+
unsigned out_num = 0, tmp;
+ bool ret;
/* Caller should know better */
BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ));
- ctrl.class = class;
- ctrl.cmd = cmd;
+ buf = kmalloc(sizeof(*buf), GFP_ATOMIC);
+ if (!buf)
+ return false;
+ buf->status = ~0;
+
+ buf->ctrl.class = class;
+ buf->ctrl.cmd = cmd;
/* Add header */
- sg_init_one(&hdr, &ctrl, sizeof(ctrl));
+ sg_init_one(&hdr, &buf->ctrl, sizeof(buf->ctrl));
sgs[out_num++] = &hdr;
if (out)
sgs[out_num++] = out;
/* Add return status. */
- sg_init_one(&stat, &status, sizeof(status));
+ sg_init_one(&stat, &buf->status, sizeof(buf->status));
sgs[out_num] = &stat;
BUG_ON(out_num + 1 > ARRAY_SIZE(sgs));
virtqueue_add_sgs(vi->cvq, sgs, out_num, 1, vi, GFP_ATOMIC);
- if (unlikely(!virtqueue_kick(vi->cvq)))
- return status == VIRTIO_NET_OK;
+ if (unlikely(!virtqueue_kick(vi->cvq))) {
+ ret = (buf->status == VIRTIO_NET_OK);
+ goto out;
+ }
/* Spin for a response, the kick causes an ioport write, trapping
* into the hypervisor, so the request should be handled immediately.
@@ -1009,7 +1021,11 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
!virtqueue_is_broken(vi->cvq))
cpu_relax();
- return status == VIRTIO_NET_OK;
+ ret = (buf->status == VIRTIO_NET_OK);
+
+out:
+ kfree(buf);
+ return ret;
}
static int virtnet_set_mac_address(struct net_device *dev, void *p)
@@ -1151,7 +1167,7 @@ static void virtnet_set_rx_mode(struct net_device *dev)
{
struct virtnet_info *vi = netdev_priv(dev);
struct scatterlist sg[2];
- u8 promisc, allmulti;
+ u8 *cmdbyte;
struct virtio_net_ctrl_mac *mac_data;
struct netdev_hw_addr *ha;
int uc_count;
@@ -1163,22 +1179,25 @@ static void virtnet_set_rx_mode(struct net_device *dev)
if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_RX))
return;
- promisc = ((dev->flags & IFF_PROMISC) != 0);
- allmulti = ((dev->flags & IFF_ALLMULTI) != 0);
+ cmdbyte = kmalloc(sizeof(*cmdbyte), GFP_ATOMIC);
+ if (!cmdbyte)
+ return;
- sg_init_one(sg, &promisc, sizeof(promisc));
+ sg_init_one(sg, cmdbyte, sizeof(*cmdbyte));
+ *cmdbyte = ((dev->flags & IFF_PROMISC) != 0);
if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
VIRTIO_NET_CTRL_RX_PROMISC, sg))
dev_warn(&dev->dev, "Failed to %sable promisc mode.\n",
- promisc ? "en" : "dis");
-
- sg_init_one(sg, &allmulti, sizeof(allmulti));
+ *cmdbyte ? "en" : "dis");
+ *cmdbyte = ((dev->flags & IFF_ALLMULTI) != 0);
if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
VIRTIO_NET_CTRL_RX_ALLMULTI, sg))
dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n",
- allmulti ? "en" : "dis");
+ *cmdbyte ? "en" : "dis");
+
+ kfree(cmdbyte);
uc_count = netdev_uc_count(dev);
mc_count = netdev_mc_count(dev);
--
2.4.3
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | "Michael S. Tsirkin" <mst@redhat.com> |
|---|---|
| Date | 2015-10-28 08:10 +0100 |
| Subject | Re: [PATCH v3 1/3] virtio_net: Stop doing DMA from the stack |
| Message-ID | <qot1U-7VJ-1@gated-at.bofh.it> |
| In reply to | #1257715 |
On Tue, Oct 27, 2015 at 11:38:58PM -0700, Andy Lutomirski wrote:
> From: Andy Lutomirski <luto@amacapital.net>
>
> Once virtio starts using the DMA API, we won't be able to safely DMA
> from the stack. virtio-net does a couple of config DMA requests
> from small stack buffers -- switch to using dynamically-allocated
> memory.
>
> This should have no effect on any performance-critical code paths.
>
> Cc: "Michael S. Tsirkin" <mst@redhat.com>
> Cc: virtualization@lists.linux-foundation.org
> Reviewed-by: Joerg Roedel <jroedel@suse.de>
> Signed-off-by: Andy Lutomirski <luto@kernel.org>
Same issues as v2 (I only saw v3 now).
I've proposed an alternative patch.
> ---
>
> Hi Michael and DaveM-
>
> This is a prerequisite for the virtio DMA fixing project. It works
> as a standalone patch, though. Would it make sense to apply it to
> an appropriate networking tree now?
>
> (This is unchanged from v2.)
>
> drivers/net/virtio_net.c | 53 ++++++++++++++++++++++++++++++++----------------
> 1 file changed, 36 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index d8838dedb7a4..4f10f8a58811 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -976,31 +976,43 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
> struct scatterlist *out)
> {
> struct scatterlist *sgs[4], hdr, stat;
> - struct virtio_net_ctrl_hdr ctrl;
> - virtio_net_ctrl_ack status = ~0;
> +
> + struct {
> + struct virtio_net_ctrl_hdr ctrl;
> + virtio_net_ctrl_ack status;
> + } *buf;
> +
> unsigned out_num = 0, tmp;
> + bool ret;
>
> /* Caller should know better */
> BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ));
>
> - ctrl.class = class;
> - ctrl.cmd = cmd;
> + buf = kmalloc(sizeof(*buf), GFP_ATOMIC);
> + if (!buf)
> + return false;
> + buf->status = ~0;
> +
> + buf->ctrl.class = class;
> + buf->ctrl.cmd = cmd;
> /* Add header */
> - sg_init_one(&hdr, &ctrl, sizeof(ctrl));
> + sg_init_one(&hdr, &buf->ctrl, sizeof(buf->ctrl));
> sgs[out_num++] = &hdr;
>
> if (out)
> sgs[out_num++] = out;
>
> /* Add return status. */
> - sg_init_one(&stat, &status, sizeof(status));
> + sg_init_one(&stat, &buf->status, sizeof(buf->status));
> sgs[out_num] = &stat;
>
> BUG_ON(out_num + 1 > ARRAY_SIZE(sgs));
> virtqueue_add_sgs(vi->cvq, sgs, out_num, 1, vi, GFP_ATOMIC);
>
> - if (unlikely(!virtqueue_kick(vi->cvq)))
> - return status == VIRTIO_NET_OK;
> + if (unlikely(!virtqueue_kick(vi->cvq))) {
> + ret = (buf->status == VIRTIO_NET_OK);
> + goto out;
> + }
>
> /* Spin for a response, the kick causes an ioport write, trapping
> * into the hypervisor, so the request should be handled immediately.
> @@ -1009,7 +1021,11 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
> !virtqueue_is_broken(vi->cvq))
> cpu_relax();
>
> - return status == VIRTIO_NET_OK;
> + ret = (buf->status == VIRTIO_NET_OK);
> +
> +out:
> + kfree(buf);
> + return ret;
> }
>
> static int virtnet_set_mac_address(struct net_device *dev, void *p)
> @@ -1151,7 +1167,7 @@ static void virtnet_set_rx_mode(struct net_device *dev)
> {
> struct virtnet_info *vi = netdev_priv(dev);
> struct scatterlist sg[2];
> - u8 promisc, allmulti;
> + u8 *cmdbyte;
> struct virtio_net_ctrl_mac *mac_data;
> struct netdev_hw_addr *ha;
> int uc_count;
> @@ -1163,22 +1179,25 @@ static void virtnet_set_rx_mode(struct net_device *dev)
> if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_RX))
> return;
>
> - promisc = ((dev->flags & IFF_PROMISC) != 0);
> - allmulti = ((dev->flags & IFF_ALLMULTI) != 0);
> + cmdbyte = kmalloc(sizeof(*cmdbyte), GFP_ATOMIC);
> + if (!cmdbyte)
> + return;
>
> - sg_init_one(sg, &promisc, sizeof(promisc));
> + sg_init_one(sg, cmdbyte, sizeof(*cmdbyte));
>
> + *cmdbyte = ((dev->flags & IFF_PROMISC) != 0);
> if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
> VIRTIO_NET_CTRL_RX_PROMISC, sg))
> dev_warn(&dev->dev, "Failed to %sable promisc mode.\n",
> - promisc ? "en" : "dis");
> -
> - sg_init_one(sg, &allmulti, sizeof(allmulti));
> + *cmdbyte ? "en" : "dis");
>
> + *cmdbyte = ((dev->flags & IFF_ALLMULTI) != 0);
> if (!virtnet_send_command(vi, VIRTIO_NET_CTRL_RX,
> VIRTIO_NET_CTRL_RX_ALLMULTI, sg))
> dev_warn(&dev->dev, "Failed to %sable allmulti mode.\n",
> - allmulti ? "en" : "dis");
> + *cmdbyte ? "en" : "dis");
> +
> + kfree(cmdbyte);
>
> uc_count = netdev_uc_count(dev);
> mc_count = netdev_mc_count(dev);
> --
> 2.4.3
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | David Woodhouse <dwmw2@infradead.org> |
|---|---|
| Date | 2015-10-28 08:00 +0100 |
| Message-ID | <qosSd-7CB-3@gated-at.bofh.it> |
| In reply to | #1257707 |
[Multipart message — attachments visible in raw view] — view raw
On Tue, 2015-10-27 at 23:38 -0700, Andy Lutomirski wrote:
>
> Changes from v2:
> - Fix really embarrassing bug. This version actually works.
So embarrassing you didn't want to tell us what it was? ...
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -292,7 +292,7 @@ static inline int virtqueue_add(struct virtqueue *_vq,
vq, desc, total_sg * sizeof(struct vring_desc),
DMA_TO_DEVICE);
- if (vring_mapping_error(vq, vq->vring.desc[head].addr))
+ if (vring_mapping_error(vq, addr))
goto unmap_release;
vq->vring.desc[head].flags = cpu_to_virtio16(_vq->vdev, VRING_DESC_F_INDIRECT);
That wasn't going to be the reason for Christian's failure, was it?
--
dwmw2
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@amacapital.net> |
|---|---|
| Date | 2015-10-28 08:20 +0100 |
| Message-ID | <qotbz-7YX-1@gated-at.bofh.it> |
| In reply to | #1257717 |
On Tue, Oct 27, 2015 at 11:53 PM, David Woodhouse <dwmw2@infradead.org> wrote: > On Tue, 2015-10-27 at 23:38 -0700, Andy Lutomirski wrote: >> >> Changes from v2: >> - Fix really embarrassing bug. This version actually works. > > So embarrassing you didn't want to tell us what it was? ... Shhh, it's a secret! I somehow managed to test-boot a different kernel than I thought I was booting. > > --- a/drivers/virtio/virtio_ring.c > +++ b/drivers/virtio/virtio_ring.c > @@ -292,7 +292,7 @@ static inline int virtqueue_add(struct virtqueue *_vq, > vq, desc, total_sg * sizeof(struct vring_desc), > DMA_TO_DEVICE); > > - if (vring_mapping_error(vq, vq->vring.desc[head].addr)) > + if (vring_mapping_error(vq, addr)) > goto unmap_release; > > vq->vring.desc[head].flags = cpu_to_virtio16(_vq->vdev, VRING_DESC_F_INDIRECT); > > That wasn't going to be the reason for Christian's failure, was it? > Not obviously, but it's possible. Now that I'm staring at it, I have some more big-endian issues, so there'll be a v4. I'll also play with Michael's thing. Expect a long delay, though -- my flight's about to leave. The readme notwithstanding, virtme (https://github.com/amluto/virtme) actually has s390x support, so I can try to debug when I get home. I'm not about to try doing this on a laptop :) --Andy -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | "Michael S. Tsirkin" <mst@redhat.com> |
|---|---|
| Date | 2015-10-28 08:20 +0100 |
| Message-ID | <qotbz-7YX-7@gated-at.bofh.it> |
| In reply to | #1257707 |
On Tue, Oct 27, 2015 at 11:38:57PM -0700, Andy Lutomirski wrote: > This switches virtio to use the DMA API unconditionally. I'm sure > it breaks things, but it seems to work on x86 using virtio-pci, with > and without Xen, and using both the modern 1.0 variant and the > legacy variant. I'm very glad to see work on this making progress. I suspect we'll have to find a way to make this optional though, and keep doing the non-DMA API thing with old devices. And I've been debating with myself whether a pci specific thing or a feature bit is preferable. Thoughts? > Changes from v2: > - Fix really embarrassing bug. This version actually works. > > Changes from v1: > - Fix an endian conversion error causing a BUG to hit. > - Fix a DMA ordering issue (swiotlb=force works now). > - Minor cleanups. > > Andy Lutomirski (3): > virtio_net: Stop doing DMA from the stack > virtio_ring: Support DMA APIs > virtio_pci: Use the DMA API > > drivers/net/virtio_net.c | 53 +++++++---- > drivers/virtio/Kconfig | 2 +- > drivers/virtio/virtio_pci_common.h | 3 +- > drivers/virtio/virtio_pci_legacy.c | 19 +++- > drivers/virtio/virtio_pci_modern.c | 34 +++++-- > drivers/virtio/virtio_ring.c | 187 ++++++++++++++++++++++++++++++------- > tools/virtio/linux/dma-mapping.h | 17 ++++ > 7 files changed, 246 insertions(+), 69 deletions(-) > create mode 100644 tools/virtio/linux/dma-mapping.h > > -- > 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Christian Borntraeger <borntraeger@de.ibm.com> |
|---|---|
| Date | 2015-10-28 08:50 +0100 |
| Message-ID | <qotEC-89q-1@gated-at.bofh.it> |
| In reply to | #1257733 |
Am 28.10.2015 um 16:17 schrieb Michael S. Tsirkin: > On Tue, Oct 27, 2015 at 11:38:57PM -0700, Andy Lutomirski wrote: >> This switches virtio to use the DMA API unconditionally. I'm sure >> it breaks things, but it seems to work on x86 using virtio-pci, with >> and without Xen, and using both the modern 1.0 variant and the >> legacy variant. > > I'm very glad to see work on this making progress. > > I suspect we'll have to find a way to make this optional though, and > keep doing the non-DMA API thing with old devices. And I've been > debating with myself whether a pci specific thing or a feature bit is > preferable. > We have discussed that at kernel summit. I will try to implement a dummy dma_ops for s390 that does 1:1 mapping and Ben will look into doing some quirk to handle "old" code in addition to also make it possible to mark devices as iommu bypass (IIRC, via device tree, Ben?) Christian > Thoughts? > >> Changes from v2: >> - Fix really embarrassing bug. This version actually works. >> >> Changes from v1: >> - Fix an endian conversion error causing a BUG to hit. >> - Fix a DMA ordering issue (swiotlb=force works now). >> - Minor cleanups. >> >> Andy Lutomirski (3): >> virtio_net: Stop doing DMA from the stack >> virtio_ring: Support DMA APIs >> virtio_pci: Use the DMA API >> >> drivers/net/virtio_net.c | 53 +++++++---- >> drivers/virtio/Kconfig | 2 +- >> drivers/virtio/virtio_pci_common.h | 3 +- >> drivers/virtio/virtio_pci_legacy.c | 19 +++- >> drivers/virtio/virtio_pci_modern.c | 34 +++++-- >> drivers/virtio/virtio_ring.c | 187 ++++++++++++++++++++++++++++++------- >> tools/virtio/linux/dma-mapping.h | 17 ++++ >> 7 files changed, 246 insertions(+), 69 deletions(-) >> create mode 100644 tools/virtio/linux/dma-mapping.h >> >> -- >> 2.4.3 > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | David Woodhouse <dwmw2@infradead.org> |
|---|---|
| Date | 2015-10-28 09:20 +0100 |
| Message-ID | <qou7E-6S-9@gated-at.bofh.it> |
| In reply to | #1257746 |
[Multipart message — attachments visible in raw view] — view raw
On Wed, 2015-10-28 at 16:40 +0900, Christian Borntraeger wrote: > Am 28.10.2015 um 16:17 schrieb Michael S. Tsirkin: > > On Tue, Oct 27, 2015 at 11:38:57PM -0700, Andy Lutomirski wrote: > > > This switches virtio to use the DMA API unconditionally. I'm sure > > > it breaks things, but it seems to work on x86 using virtio-pci, with > > > and without Xen, and using both the modern 1.0 variant and the > > > legacy variant. > > > > I'm very glad to see work on this making progress. > > > > I suspect we'll have to find a way to make this optional though, and > > keep doing the non-DMA API thing with old devices. And I've been > > debating with myself whether a pci specific thing or a feature bit is > > preferable. > > > > We have discussed that at kernel summit. I will try to implement a dummy dma_ops for > s390 that does 1:1 mapping and Ben will look into doing some quirk to handle "old" > code in addition to also make it possible to mark devices as iommu bypass (IIRC, > via device tree, Ben?) Right. You never eschew the DMA API in the *driver* — you just expect the DMA API to do the right thing for devices which don't need translation (with platforms using per-device dma_ops and generally getting their act together). We're pushing that on the platforms where it's currently an issue, including Power, SPARC and S390. -- dwmw2
[toc] | [prev] | [next] | [standalone]
| From | "Michael S. Tsirkin" <mst@redhat.com> |
|---|---|
| Date | 2015-10-28 12:40 +0100 |
| Message-ID | <qoxfc-21J-7@gated-at.bofh.it> |
| In reply to | #1257770 |
On Wed, Oct 28, 2015 at 05:09:47PM +0900, David Woodhouse wrote: > On Wed, 2015-10-28 at 16:40 +0900, Christian Borntraeger wrote: > > Am 28.10.2015 um 16:17 schrieb Michael S. Tsirkin: > > > On Tue, Oct 27, 2015 at 11:38:57PM -0700, Andy Lutomirski wrote: > > > > This switches virtio to use the DMA API unconditionally. I'm sure > > > > it breaks things, but it seems to work on x86 using virtio-pci, with > > > > and without Xen, and using both the modern 1.0 variant and the > > > > legacy variant. > > > > > > I'm very glad to see work on this making progress. > > > > > > I suspect we'll have to find a way to make this optional though, and > > > keep doing the non-DMA API thing with old devices. And I've been > > > debating with myself whether a pci specific thing or a feature bit is > > > preferable. > > > > > > > We have discussed that at kernel summit. I will try to implement a dummy dma_ops for > > s390 that does 1:1 mapping and Ben will look into doing some quirk to handle "old" > > code in addition to also make it possible to mark devices as iommu bypass (IIRC, > > via device tree, Ben?) > > Right. You never eschew the DMA API in the *driver* — you just expect > the DMA API to do the right thing for devices which don't need > translation (with platforms using per-device dma_ops and generally > getting their act together). > We're pushing that on the platforms where it's currently an issue, > including Power, SPARC and S390. > > -- > dwmw2 > > Well APIs are just that - internal kernel APIs. If the only user of an API is virtio, we can strick the code in virtio.h just as well. I think controlling this dynamically and not statically in e.g. devicetree is important though. E.g. on intel x86, there's an option iommu=pt which does the 1:1 thing for devices when used by kernel, but enables the iommu if used by userspace/VMs. Something like this would be needed for other platforms IMHO. And given that 1. virtio seems the only user so far 2. supporting this per device seems like something that might become useful in the future maybe we'd better make this part of virtio transports. -- MST -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | David Woodhouse <dwmw2@infradead.org> |
|---|---|
| Date | 2015-10-28 14:40 +0100 |
| Message-ID | <qoz7k-3cS-9@gated-at.bofh.it> |
| In reply to | #1257930 |
[Multipart message — attachments visible in raw view] — view raw
On Wed, 2015-10-28 at 13:35 +0200, Michael S. Tsirkin wrote: > E.g. on intel x86, there's an option iommu=pt which does the 1:1 > thing for devices when used by kernel, but enables > the iommu if used by userspace/VMs. That's none of your business. You call the DMA API when you do DMA. That's all there is to it. If the IOMMU happens to be in passthrough mode, or your device happens to not to be routed through an IOMMU today, then I/O virtual address you get back from the DMA API will look a *lot* like the physical address you asked the DMA to map. You might think there's no IOMMU. We couldn't possibly comment. Use the DMA API. Always. Let the platform worry about whether it actually needs to *do* anything or not. -- dwmw2
[toc] | [prev] | [next] | [standalone]
| From | "Michael S. Tsirkin" <mst@redhat.com> |
|---|---|
| Date | 2015-10-28 15:10 +0100 |
| Message-ID | <qozAo-3CV-63@gated-at.bofh.it> |
| In reply to | #1258033 |
On Wed, Oct 28, 2015 at 10:35:27PM +0900, David Woodhouse wrote: > On Wed, 2015-10-28 at 13:35 +0200, Michael S. Tsirkin wrote: > > E.g. on intel x86, there's an option iommu=pt which does the 1:1 > > thing for devices when used by kernel, but enables > > the iommu if used by userspace/VMs. > > That's none of your business. > > You call the DMA API when you do DMA. That's all there is to it. > > If the IOMMU happens to be in passthrough mode, or your device happens > to not to be routed through an IOMMU today, then I/O virtual address > you get back from the DMA API will look a *lot* like the physical > address you asked the DMA to map. You might think there's no IOMMU. We > couldn't possibly comment. > > Use the DMA API. Always. Let the platform worry about whether it > actually needs to *do* anything or not. > -- > dwmw2 > > Short answer - platforms need a way to discover, and express different security requirements of different devices. If they continue to lack that, we'll need a custom API in virtio, and while this seems a bit less elegant, I would not see that as the end of the world at all, there are not that many virtio drivers. And hey - that's just an internal API. We can change it later at a whim. Long answer - PV is weird. It's not always the same as real hardware. For PV, it's generally hypervisor doing writes into memory. If it's monolitic with device emulation in same memory space as the hypervisor (e.g. in the case of the current QEMU, or using vhost in host kernel), then you gain *no security* by "restricting" it by means of the IOMMU - the IOMMU is part of the same hypervisor. If it is modular with device emulation in a separate memory space (e.g. in case of Xen, or vhost-user in modern QEMU) then you do gain security: the part emulating the IOMMU limits the part doing DMA. In both cases for assigned devices, it is always modular in a sense, so you do gain security since that is restricted by the hardware IOMMU. The way things are set up at the moment, it's mostly global, with iommu=pt on intel being a kind of exception. We need host/guest and API interfaces that are more nuanced than that. -- MST -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | David Woodhouse <dwmw2@infradead.org> |
|---|---|
| Date | 2015-10-28 15:20 +0100 |
| Message-ID | <qozK3-3GM-73@gated-at.bofh.it> |
| In reply to | #1258103 |
[Multipart message — attachments visible in raw view] — view raw
On Wed, 2015-10-28 at 16:05 +0200, Michael S. Tsirkin wrote: > > Short answer - platforms need a way to discover, and express different > security requirements of different devices. Sure. PLATFORMS need that. Do not let it go anywhere near your device drivers. Including the virtio drivers. > If they continue to lack that, we'll need a custom API in virtio, > and while this seems a bit less elegant, I would not see that as > the end of the world at all, there are not that many virtio drivers. No. If they continue to lack that, we fix them. This is a *platform* issue. The DMA API shall do the right thing. Do not second-guess it. (From the other mail) > > > OK so I guess that means we should prefer a transport-specific > > > interface in virtio-pci then. > > > > Why? > > Because you said you are doing something device tree specific for > ARM, aren't you? Nonono. The ARM platform code might do that, and the DMA API on ARM *might* give you I/O virtual addresses that look a lot like the physical addresses you asked it to map. That's none of your business. Drivers use DMA API. No more talky. -- dwmw2
[toc] | [prev] | [next] | [standalone]
| From | "Michael S. Tsirkin" <mst@redhat.com> |
|---|---|
| Date | 2015-10-28 15:30 +0100 |
| Message-ID | <qozTK-3KE-51@gated-at.bofh.it> |
| In reply to | #1258138 |
On Wed, Oct 28, 2015 at 11:13:29PM +0900, David Woodhouse wrote: > On Wed, 2015-10-28 at 16:05 +0200, Michael S. Tsirkin wrote: > > > > Short answer - platforms need a way to discover, and express different > > security requirements of different devices. > > Sure. PLATFORMS need that. Do not let it go anywhere near your device > drivers. Including the virtio drivers. But would there be any users of this outside the virtio subsystem? If no, maybe virtio core is a logical place to keep this. > > If they continue to lack that, we'll need a custom API in virtio, > > and while this seems a bit less elegant, I would not see that as > > the end of the world at all, there are not that many virtio drivers. > > No. If they continue to lack that, we fix them. This is a *platform* > issue. The DMA API shall do the right thing. Do not second-guess it. > > > (From the other mail) I don't have a problem with extending DMA API to address more usecases. > > > > OK so I guess that means we should prefer a transport-specific > > > > interface in virtio-pci then. > > > > > > Why? > > > > Because you said you are doing something device tree specific for > > ARM, aren't you? > > Nonono. The ARM platform code might do that, and the DMA API on ARM > *might* give you I/O virtual addresses that look a lot like the > physical addresses you asked it to map. That's none of your business. > Drivers use DMA API. No more talky. Well for virtio they don't ATM. And 1:1 mapping makes perfect sense for the wast majority of users, so I can't switch them over until the DMA API actually addresses all existing usecases. > -- > dwmw2 > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | David Woodhouse <dwmw2@infradead.org> |
|---|---|
| Date | 2015-10-28 15:40 +0100 |
| Message-ID | <qoA3o-3Pi-21@gated-at.bofh.it> |
| In reply to | #1258165 |
[Multipart message — attachments visible in raw view] — view raw
On Wed, 2015-10-28 at 16:22 +0200, Michael S. Tsirkin wrote: > On Wed, Oct 28, 2015 at 11:13:29PM +0900, David Woodhouse wrote: > > On Wed, 2015-10-28 at 16:05 +0200, Michael S. Tsirkin wrote: > > > > > > Short answer - platforms need a way to discover, and express > > > different > > > security requirements of different devices. > > > > Sure. PLATFORMS need that. Do not let it go anywhere near your > > device > > drivers. Including the virtio drivers. > > But would there be any users of this outside the virtio subsystem? > If no, maybe virtio core is a logical place to keep this. Users of what? DMA API ops which basically do nothing? Sure — there are *plenty* of cases where there isn't actually an IOMMU in active use and the DMA API just returns the same address it was given. Obviously that happens in platforms without an IOMMU, but it also happens in cases where an IOMMU exists but is in passthrough mode, and it also happens in cases where an IOMMU exists somewhere in the system but only translates for *other* devices. In all cases, drivers must just use the DMA API and *it* is responsible for doing the right thing. > I don't have a problem with extending DMA API to address > more usecases. No, this isn't an extension. This is fixing a bug, on certain platforms where the DMA API has currently done the wrong thing. We have historically worked around that bug by introducing *another* bug, which is not to *use* the DMA API in the virtio driver. Sure, we can co-ordinate those two bug-fixes. But let's not talk about them as anything other than bug-fixes. > > Drivers use DMA API. No more talky. > > Well for virtio they don't ATM. And 1:1 mapping makes perfect sense > for the wast majority of users, so I can't switch them over > until the DMA API actually addresses all existing usecases. That's still not your business; it's the platform's. And there are hardware implementations of the virtio protocols on real PCI cards. And we have the option of doing IOMMU translation for the virtio devices even in a virtual machine. Just don't get involved. -- dwmw2
[toc] | [prev] | [next] | [standalone]
| From | "Michael S. Tsirkin" <mst@redhat.com> |
|---|---|
| Date | 2015-10-28 17:20 +0100 |
| Message-ID | <qoBC9-4V4-17@gated-at.bofh.it> |
| In reply to | #1258186 |
On Wed, Oct 28, 2015 at 11:32:34PM +0900, David Woodhouse wrote: > > I don't have a problem with extending DMA API to address > > more usecases. > > No, this isn't an extension. This is fixing a bug, on certain platforms > where the DMA API has currently done the wrong thing. > > We have historically worked around that bug by introducing *another* > bug, which is not to *use* the DMA API in the virtio driver. > > Sure, we can co-ordinate those two bug-fixes. But let's not talk about > them as anything other than bug-fixes. It was pretty practical not to use it. All virtio devices at the time without exception bypassed the IOMMU, so it was a question of omitting a couple of function calls in virtio versus hacking on DMA implementation on multiple platforms. We have more policy options now, so I agree it's time to revisit this. But for me, the most important thing is that we do coordinate. > > > Drivers use DMA API. No more talky. > > > > Well for virtio they don't ATM. And 1:1 mapping makes perfect sense > > for the wast majority of users, so I can't switch them over > > until the DMA API actually addresses all existing usecases. > > That's still not your business; it's the platform's. And there are > hardware implementations of the virtio protocols on real PCI cards. And > we have the option of doing IOMMU translation for the virtio devices > even in a virtual machine. Just don't get involved. > > -- > dwmw2 > > I'm involved anyway, it's possible not to put all the code in the virtio subsystem in guest though. But I suspect we'll need to find a way for non-linux drivers within guest to work correctly too, and they might have trouble poking at things at the system level. So possibly virtio subsystem will have to tell platform "this device wants to bypass IOMMU" and then DMA API does the right thing. I'll look into this after my vacation ~1.5 weeks from now. -- MST -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | Andy Lutomirski <luto@amacapital.net> |
|---|---|
| Date | 2015-10-29 00:00 +0100 |
| Message-ID | <qoHRg-lq-9@gated-at.bofh.it> |
| In reply to | #1258284 |
On Wed, Oct 28, 2015 at 9:12 AM, Michael S. Tsirkin <mst@redhat.com> wrote: > On Wed, Oct 28, 2015 at 11:32:34PM +0900, David Woodhouse wrote: >> > I don't have a problem with extending DMA API to address >> > more usecases. >> >> No, this isn't an extension. This is fixing a bug, on certain platforms >> where the DMA API has currently done the wrong thing. >> >> We have historically worked around that bug by introducing *another* >> bug, which is not to *use* the DMA API in the virtio driver. >> >> Sure, we can co-ordinate those two bug-fixes. But let's not talk about >> them as anything other than bug-fixes. > > It was pretty practical not to use it. All virtio devices at the time > without exception bypassed the IOMMU, so it was a question of omitting a > couple of function calls in virtio versus hacking on DMA implementation > on multiple platforms. We have more policy options now, so I agree it's > time to revisit this. > > But for me, the most important thing is that we do coordinate. > >> > > Drivers use DMA API. No more talky. >> > >> > Well for virtio they don't ATM. And 1:1 mapping makes perfect sense >> > for the wast majority of users, so I can't switch them over >> > until the DMA API actually addresses all existing usecases. >> >> That's still not your business; it's the platform's. And there are >> hardware implementations of the virtio protocols on real PCI cards. And >> we have the option of doing IOMMU translation for the virtio devices >> even in a virtual machine. Just don't get involved. >> >> -- >> dwmw2 >> >> > > I'm involved anyway, it's possible not to put all the code in the virtio > subsystem in guest though. But I suspect we'll need to find a way for > non-linux drivers within guest to work correctly too, and they might > have trouble poking at things at the system level. So possibly virtio > subsystem will have to tell platform "this device wants to bypass IOMMU" > and then DMA API does the right thing. > After some discussion at KS, no one came up with an example where it's necessary, and the patches to convert virtqueue to use the DMA API are much nicer when they convert it unconditionally. The two interesting cases we thought of were PPC and x86's emulated Q35 IOMMU. PPC will look in to architecting a devicetree-based way to indicate passthrough status and will add quirks for the existing virtio devices. Everyone seems to agree that x86's emulated Q35 thing is just buggy right now and should be taught to use the existing ACPI mechanism for enumerating passthrough devices. I'll send a new version of the series soon. --Andy -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | "Michael S. Tsirkin" <mst@redhat.com> |
|---|---|
| Date | 2015-10-29 10:10 +0100 |
| Message-ID | <qoRnA-6GK-9@gated-at.bofh.it> |
| In reply to | #1258467 |
On Wed, Oct 28, 2015 at 03:51:58PM -0700, Andy Lutomirski wrote: > On Wed, Oct 28, 2015 at 9:12 AM, Michael S. Tsirkin <mst@redhat.com> wrote: > > On Wed, Oct 28, 2015 at 11:32:34PM +0900, David Woodhouse wrote: > >> > I don't have a problem with extending DMA API to address > >> > more usecases. > >> > >> No, this isn't an extension. This is fixing a bug, on certain platforms > >> where the DMA API has currently done the wrong thing. > >> > >> We have historically worked around that bug by introducing *another* > >> bug, which is not to *use* the DMA API in the virtio driver. > >> > >> Sure, we can co-ordinate those two bug-fixes. But let's not talk about > >> them as anything other than bug-fixes. > > > > It was pretty practical not to use it. All virtio devices at the time > > without exception bypassed the IOMMU, so it was a question of omitting a > > couple of function calls in virtio versus hacking on DMA implementation > > on multiple platforms. We have more policy options now, so I agree it's > > time to revisit this. > > > > But for me, the most important thing is that we do coordinate. > > > >> > > Drivers use DMA API. No more talky. > >> > > >> > Well for virtio they don't ATM. And 1:1 mapping makes perfect sense > >> > for the wast majority of users, so I can't switch them over > >> > until the DMA API actually addresses all existing usecases. > >> > >> That's still not your business; it's the platform's. And there are > >> hardware implementations of the virtio protocols on real PCI cards. And > >> we have the option of doing IOMMU translation for the virtio devices > >> even in a virtual machine. Just don't get involved. > >> > >> -- > >> dwmw2 > >> > >> > > > > I'm involved anyway, it's possible not to put all the code in the virtio > > subsystem in guest though. But I suspect we'll need to find a way for > > non-linux drivers within guest to work correctly too, and they might > > have trouble poking at things at the system level. So possibly virtio > > subsystem will have to tell platform "this device wants to bypass IOMMU" > > and then DMA API does the right thing. > > > > After some discussion at KS, no one came up with an example where it's > necessary, and the patches to convert virtqueue to use the DMA API are > much nicer when they convert it unconditionally. It's very surprising no one couldn't. I did above, I try again below. Note: below discusses configuration *within guest*. Example: you have a mix of assigned devices and virtio devices. You don't trust your assigned device vendor not to corrupt your memory so you want to limit the damage your assigned device can do to your guest, so you use an IOMMU for that. Thus existing iommu=pt within guest is out. But you trust your hypervisor (you have no choice anyway), and you don't want the overhead of tweaking IOMMU on data path for virtio. Thus iommu=on is out too. > The two interesting cases we thought of were PPC and x86's emulated > Q35 IOMMU. PPC will look in to architecting a devicetree-based way to > indicate passthrough status and will add quirks for the existing > virtio devices. Isn't this specified by the hypervisor? I don't think this is a good way to do this: guest security should be up to guest. > Everyone seems to agree that x86's emulated Q35 thing > is just buggy right now and should be taught to use the existing ACPI > mechanism for enumerating passthrough devices. I'm not sure what ACPI has to do with it. It's about a way for guest users to specify whether they want to bypass an IOMMU for a given device. > I'll send a new version of the series soon. > > --Andy By the way, a bunch of code is missing on the QEMU side to make this useful: 1. virtio ignores the iommu 2. vhost user ignores the iommu 3. dataplane ignores the iommu 4. vhost-net ignores the iommu 5. VFIO ignores the iommu I think so far I only saw patches for 1 above. -- MST -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[toc] | [prev] | [next] | [standalone]
| From | David Woodhouse <dwmw2@infradead.org> |
|---|---|
| Date | 2015-10-29 17:20 +0100 |
| Message-ID | <qoY5J-2tW-27@gated-at.bofh.it> |
| In reply to | #1258668 |
[Multipart message — attachments visible in raw view] — view raw
On Thu, 2015-10-29 at 11:01 +0200, Michael S. Tsirkin wrote: > > Example: you have a mix of assigned devices and virtio devices. You > don't trust your assigned device vendor not to corrupt your memory so > you want to limit the damage your assigned device can do to your > guest, > so you use an IOMMU for that. Thus existing iommu=pt within guest is > out. > > But you trust your hypervisor (you have no choice anyway), > and you don't want the overhead of tweaking IOMMU > on data path for virtio. Thus iommu=on is out too. That's not at all special for virtio or guest VMs. Even with real hardware, we might want performance from *some* devices, and security from others. See the DMA_ATTR_IOMMU_BYPASS which is currently being discussed. But of course the easy answer in *your* case it just to ask the hypervisor not to put the virtio devices behind an IOMMU at all. Which we were planning to remain the default behaviour. In all cases, the DMA API shall do the right thing. -- dwmw2
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | linux.kernel
csiph-web