Skip to contentSkip to conversation

virtio DMA API, yet again

PATCH In review Andy Lutomirski 7 participants 66 messages Jan 29, 2016 – Feb 1, 2016

Subsystems (7)
KVM Library code s390 virtio core +3 more subsystems
lore
Share & tools
lore
#0 lore raw

v5 cover virtio DMA API, yet again

This switches virtio to use the DMA API on Xen and if requested by module option.

This fixes virtio on Xen, and it should break anything because it's off by default on everything except Xen PV on x86.

To the Xen people: is this okay? If it doesn't work on other Xen variants (PVH? HVM?), can you submit follow-up patches to fix it?

To everyone else: we've waffled on this for way too long. I think we should to get DMA API implementation in with a conservative policy like this rather than waiting until we achieve perfection. I'm tired of carrying these patches around.

Michael, if these survive review, can you stage these in your tree? Can you also take a look at tools/virtio? I probably broke it, but I couldn't get it to build without these patches either, so I'm stuck.

Changes from v4:
- Bake vring_use_dma_api in from the beginning.
- Automatically enable only on Xen.
- Add module parameter.
- Add s390 and alpha DMA API implementations.
- Rebase to 4.5-rc1.

Changes from v3:
- More big-endian fixes.
- Added better virtio-ring APIs that handle allocation and use them in virtio-mmio and virtio-pci.
- Switch to Michael's virtio-net patch.

Changes from v2:
- Fix vring_mapping_error incorrect argument

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 (7):
vring: Introduce vring_use_dma_api()
virtio_ring: Support DMA APIs
virtio: Add improved queue allocation API
virtio_mmio: Use the DMA API if enabled
virtio_pci: Use the DMA API if enabled
vring: Use the DMA API on Xen
vring: Add a module parameter to force-enable the DMA API

Christian Borntraeger (3):
dma: Provide simple noop dma ops
alpha/dma: use common noop dma ops
s390/dma: Allow per device dma ops

 arch/alpha/kernel/pci-noop.c        |  46 +---
 arch/s390/Kconfig                   |   6 +-
 arch/s390/include/asm/device.h      |   6 +-
 arch/s390/include/asm/dma-mapping.h |   6 +-
 arch/s390/pci/pci.c                 |   1 +
 arch/s390/pci/pci_dma.c             |   4 +-
 drivers/virtio/Kconfig              |   2 +-
 drivers/virtio/virtio_mmio.c        |  67 ++----
 drivers/virtio/virtio_pci_common.h  |   6 -
 drivers/virtio/virtio_pci_legacy.c  |  42 ++--
 drivers/virtio/virtio_pci_modern.c  |  61 ++----
 drivers/virtio/virtio_ring.c        | 412 ++++++++++++++++++++++++++++++------
 include/linux/dma-mapping.h         |   2 +
 include/linux/virtio.h              |  23 +-
 include/linux/virtio_ring.h         |  35 +++
 lib/Makefile                        |   1 +
 lib/dma-noop.c                      |  75 +++++++
 tools/virtio/linux/dma-mapping.h    |  17 ++
 18 files changed, 568 insertions(+), 244 deletions(-)
 create mode 100644 lib/dma-noop.c
 create mode 100644 tools/virtio/linux/dma-mapping.h
Signature · 1 line
2.5.0
#1 lore raw

PATCH v5 1/10 dma: Provide simple noop dma ops

From: Christian Borntraeger <[email protected]>

We are going to require dma_ops for several common drivers, even for systems that do have an identity mapping. Lets provide some minimal no-op dma_ops that can be used for that purpose.

---
 include/linux/dma-mapping.h |  2 ++
 lib/Makefile                |  1 +
 lib/dma-noop.c              | 75 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 78 insertions(+)
 create mode 100644 lib/dma-noop.c
include/linux/dma-mapping.h +2 -0
index 75857cda38e9..c0b27ff2c784 100644
@@ -70,6 +70,8 @@ struct dma_map_ops {
 	int is_phys;
 };
 
+extern struct dma_map_ops dma_noop_ops;
+
 #define DMA_BIT_MASK(n)	(((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
 
 #define DMA_MASK_NONE	0x0ULL
lib/Makefile +1 -0
index a7c26a41a738..a572b86a1b1d 100644
@@ -18,6 +18,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
 obj-$(CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS) += usercopy.o
 lib-$(CONFIG_MMU) += ioremap.o
 lib-$(CONFIG_SMP) += cpumask.o
+lib-$(CONFIG_HAS_DMA) += dma-noop.o
 
 lib-y	+= kobject.o klist.o
 obj-y	+= lockref.o
lib/dma-noop.c new file +75 -0

75 lines not on this page · raw message

Signature · 1 line
2.5.0
#2 lore raw

PATCH v5 1/10 dma: Provide simple noop dma ops

In reply to Andy Lutomirski

From: Christian Borntraeger <[email protected]>

We are going to require dma_ops for several common drivers, even for systems that do have an identity mapping. Lets provide some minimal no-op dma_ops that can be used for that purpose.

---
 include/linux/dma-mapping.h |  2 ++
 lib/Makefile                |  1 +
 lib/dma-noop.c              | 75 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 78 insertions(+)
 create mode 100644 lib/dma-noop.c
include/linux/dma-mapping.h +2 -0
index 75857cda38e9..c0b27ff2c784 100644
@@ -70,6 +70,8 @@ struct dma_map_ops {
 	int is_phys;
 };
 
+extern struct dma_map_ops dma_noop_ops;
+
 #define DMA_BIT_MASK(n)	(((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
 
 #define DMA_MASK_NONE	0x0ULL
lib/Makefile +1 -0
index a7c26a41a738..a572b86a1b1d 100644
@@ -18,6 +18,7 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
 obj-$(CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS) += usercopy.o
 lib-$(CONFIG_MMU) += ioremap.o
 lib-$(CONFIG_SMP) += cpumask.o
+lib-$(CONFIG_HAS_DMA) += dma-noop.o
 
 lib-y	+= kobject.o klist.o
 obj-y	+= lockref.o
lib/dma-noop.c new file +75 -0

75 lines not on this page · raw message

Signature · 1 line
2.5.0
#3 lore raw

PATCH v5 2/10 alpha/dma: use common noop dma ops

In reply to Andy Lutomirski

From: Christian Borntraeger <[email protected]>

Some of the alpha pci noop dma ops are identical to the common ones. Use them.

---
 arch/alpha/kernel/pci-noop.c | 46 ++++----------------------------------------
 1 file changed, 4 insertions(+), 42 deletions(-)
arch/alpha/kernel/pci-noop.c +4 -42
index 2b1f4a1e9272..8e735b5e56bd 100644
@@ -123,44 +123,6 @@ static void *alpha_noop_alloc_coherent(struct device *dev, size_t size,
 	return ret;
 }
 
-static void alpha_noop_free_coherent(struct device *dev, size_t size,
-				     void *cpu_addr, dma_addr_t dma_addr,
-				     struct dma_attrs *attrs)
-{
-	free_pages((unsigned long)cpu_addr, get_order(size));
-}
-
-static dma_addr_t alpha_noop_map_page(struct device *dev, struct page *page,
-				      unsigned long offset, size_t size,
-				      enum dma_data_direction dir,
-				      struct dma_attrs *attrs)
-{
-	return page_to_pa(page) + offset;
-}
-
-static int alpha_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
-			     enum dma_data_direction dir, struct dma_attrs *attrs)
-{
-	int i;
-	struct scatterlist *sg;
-
-	for_each_sg(sgl, sg, nents, i) {
-		void *va;
-
-		BUG_ON(!sg_page(sg));
-		va = sg_virt(sg);
-		sg_dma_address(sg) = (dma_addr_t)virt_to_phys(va);
-		sg_dma_len(sg) = sg->length;
-	}
-
-	return nents;
-}
-
-static int alpha_noop_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-	return 0;
-}
-
 static int alpha_noop_supported(struct device *dev, u64 mask)
 {
 	return mask < 0x00ffffffUL ? 0 : 1;
@@ -168,10 +130,10 @@ static int alpha_noop_supported(struct device *dev, u64 mask)
 
 struct dma_map_ops alpha_noop_ops = {
 	.alloc			= alpha_noop_alloc_coherent,
-	.free			= alpha_noop_free_coherent,
-	.map_page		= alpha_noop_map_page,
-	.map_sg			= alpha_noop_map_sg,
-	.mapping_error		= alpha_noop_mapping_error,
+	.free			= dma_noop_free_coherent,
+	.map_page		= dma_noop_map_page,
+	.map_sg			= dma_noop_map_sg,
+	.mapping_error		= dma_noop_mapping_error,
 	.dma_supported		= alpha_noop_supported,
 };
 
Signature · 1 line
2.5.0
#4 lore raw

PATCH v5 2/10 alpha/dma: use common noop dma ops

In reply to Andy Lutomirski

From: Christian Borntraeger <[email protected]>

Some of the alpha pci noop dma ops are identical to the common ones. Use them.

---
 arch/alpha/kernel/pci-noop.c | 46 ++++----------------------------------------
 1 file changed, 4 insertions(+), 42 deletions(-)
arch/alpha/kernel/pci-noop.c +4 -42
index 2b1f4a1e9272..8e735b5e56bd 100644
@@ -123,44 +123,6 @@ static void *alpha_noop_alloc_coherent(struct device *dev, size_t size,
 	return ret;
 }
 
-static void alpha_noop_free_coherent(struct device *dev, size_t size,
-				     void *cpu_addr, dma_addr_t dma_addr,
-				     struct dma_attrs *attrs)
-{
-	free_pages((unsigned long)cpu_addr, get_order(size));
-}
-
-static dma_addr_t alpha_noop_map_page(struct device *dev, struct page *page,
-				      unsigned long offset, size_t size,
-				      enum dma_data_direction dir,
-				      struct dma_attrs *attrs)
-{
-	return page_to_pa(page) + offset;
-}
-
-static int alpha_noop_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
-			     enum dma_data_direction dir, struct dma_attrs *attrs)
-{
-	int i;
-	struct scatterlist *sg;
-
-	for_each_sg(sgl, sg, nents, i) {
-		void *va;
-
-		BUG_ON(!sg_page(sg));
-		va = sg_virt(sg);
-		sg_dma_address(sg) = (dma_addr_t)virt_to_phys(va);
-		sg_dma_len(sg) = sg->length;
-	}
-
-	return nents;
-}
-
-static int alpha_noop_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-	return 0;
-}
-
 static int alpha_noop_supported(struct device *dev, u64 mask)
 {
 	return mask < 0x00ffffffUL ? 0 : 1;
@@ -168,10 +130,10 @@ static int alpha_noop_supported(struct device *dev, u64 mask)
 
 struct dma_map_ops alpha_noop_ops = {
 	.alloc			= alpha_noop_alloc_coherent,
-	.free			= alpha_noop_free_coherent,
-	.map_page		= alpha_noop_map_page,
-	.map_sg			= alpha_noop_map_sg,
-	.mapping_error		= alpha_noop_mapping_error,
+	.free			= dma_noop_free_coherent,
+	.map_page		= dma_noop_map_page,
+	.map_sg			= dma_noop_map_sg,
+	.mapping_error		= dma_noop_mapping_error,
 	.dma_supported		= alpha_noop_supported,
 };
 
Signature · 1 line
2.5.0
#5 lore raw

PATCH v5 3/10 s390/dma: Allow per device dma ops

In reply to Andy Lutomirski

From: Christian Borntraeger <[email protected]>

As virtio-ccw will have dma ops, we can no longer default to the zPCI ones. Make use of dev_archdata to keep the dma_ops per device. The pci devices now use that to override the default, and the default is changed to use the noop ops for everything that does not specify a device specific one.
To compile without PCI support we will enable HAS_DMA all the time, via the default config in lib/Kconfig.

---
 arch/s390/Kconfig                   | 6 ++----
 arch/s390/include/asm/device.h      | 6 +++++-
 arch/s390/include/asm/dma-mapping.h | 6 ++++--
 arch/s390/pci/pci.c                 | 1 +
 arch/s390/pci/pci_dma.c             | 4 ++--
 5 files changed, 14 insertions(+), 9 deletions(-)
arch/s390/Kconfig +2 -4
index 3be9c832dec1..5b22a26337b2 100644
@@ -124,6 +124,8 @@ config S390
 	select HAVE_CMPXCHG_DOUBLE
 	select HAVE_CMPXCHG_LOCAL
 	select HAVE_DEBUG_KMEMLEAK
+	select HAVE_DMA_ATTRS
+	select HAVE_DMA_API_DEBUG
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_DYNAMIC_FTRACE_WITH_REGS
 	select HAVE_FTRACE_MCOUNT_RECORD
@@ -619,10 +621,6 @@ config HAS_IOMEM
 config IOMMU_HELPER
 	def_bool PCI
 
-config HAS_DMA
-	def_bool PCI
-	select HAVE_DMA_API_DEBUG
-
 config NEED_SG_DMA_LENGTH
 	def_bool PCI
 
arch/s390/include/asm/device.h +5 -1
index d8f9872b0e2d..4a9f35e0973f 100644
@@ -3,5 +3,9 @@
  *
  * This file is released under the GPLv2
  */
-#include <asm-generic/device.h>
+struct dev_archdata {
+	struct dma_map_ops *dma_ops;
+};
 
+struct pdev_archdata {
+};
arch/s390/include/asm/dma-mapping.h +4 -2
index e64bfcb9702f..3249b7464889 100644
@@ -11,11 +11,13 @@
 
 #define DMA_ERROR_CODE		(~(dma_addr_t) 0x0)
 
-extern struct dma_map_ops s390_dma_ops;
+extern struct dma_map_ops s390_pci_dma_ops;
 
 static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 {
-	return &s390_dma_ops;
+	if (dev && dev->archdata.dma_ops)
+		return dev->archdata.dma_ops;
+	return &dma_noop_ops;
 }
 
 static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
arch/s390/pci/pci.c +1 -0
index 11d4f277e9f6..f5931135b9ae 100644
@@ -649,6 +649,7 @@ int pcibios_add_device(struct pci_dev *pdev)
 
 	zdev->pdev = pdev;
 	pdev->dev.groups = zpci_attr_groups;
+	pdev->dev.archdata.dma_ops = &s390_pci_dma_ops;
 	zpci_map_resources(pdev);
 
 	for (i = 0; i < PCI_BAR_COUNT; i++) {
arch/s390/pci/pci_dma.c +2 -2
index 4638b93c7632..a79173ec54b9 100644
@@ -544,7 +544,7 @@ static int __init dma_debug_do_init(void)
 }
 fs_initcall(dma_debug_do_init);
 
-struct dma_map_ops s390_dma_ops = {
+struct dma_map_ops s390_pci_dma_ops = {
 	.alloc		= s390_dma_alloc,
 	.free		= s390_dma_free,
 	.map_sg		= s390_dma_map_sg,
@@ -555,7 +555,7 @@ struct dma_map_ops s390_dma_ops = {
 	.is_phys	= 0,
 	/* dma_supported is unconditionally true without a callback */
 };
-EXPORT_SYMBOL_GPL(s390_dma_ops);
+EXPORT_SYMBOL_GPL(s390_pci_dma_ops);
 
 static int __init s390_iommu_setup(char *str)
 {
Signature · 1 line
2.5.0
#6 lore raw

PATCH v5 3/10 s390/dma: Allow per device dma ops

In reply to Andy Lutomirski

From: Christian Borntraeger <[email protected]>

As virtio-ccw will have dma ops, we can no longer default to the zPCI ones. Make use of dev_archdata to keep the dma_ops per device. The pci devices now use that to override the default, and the default is changed to use the noop ops for everything that does not specify a device specific one.
To compile without PCI support we will enable HAS_DMA all the time, via the default config in lib/Kconfig.

---
 arch/s390/Kconfig                   | 6 ++----
 arch/s390/include/asm/device.h      | 6 +++++-
 arch/s390/include/asm/dma-mapping.h | 6 ++++--
 arch/s390/pci/pci.c                 | 1 +
 arch/s390/pci/pci_dma.c             | 4 ++--
 5 files changed, 14 insertions(+), 9 deletions(-)
arch/s390/Kconfig +2 -4
index 3be9c832dec1..5b22a26337b2 100644
@@ -124,6 +124,8 @@ config S390
 	select HAVE_CMPXCHG_DOUBLE
 	select HAVE_CMPXCHG_LOCAL
 	select HAVE_DEBUG_KMEMLEAK
+	select HAVE_DMA_ATTRS
+	select HAVE_DMA_API_DEBUG
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_DYNAMIC_FTRACE_WITH_REGS
 	select HAVE_FTRACE_MCOUNT_RECORD
@@ -619,10 +621,6 @@ config HAS_IOMEM
 config IOMMU_HELPER
 	def_bool PCI
 
-config HAS_DMA
-	def_bool PCI
-	select HAVE_DMA_API_DEBUG
-
 config NEED_SG_DMA_LENGTH
 	def_bool PCI
 
arch/s390/include/asm/device.h +5 -1
index d8f9872b0e2d..4a9f35e0973f 100644
@@ -3,5 +3,9 @@
  *
  * This file is released under the GPLv2
  */
-#include <asm-generic/device.h>
+struct dev_archdata {
+	struct dma_map_ops *dma_ops;
+};
 
+struct pdev_archdata {
+};
arch/s390/include/asm/dma-mapping.h +4 -2
index e64bfcb9702f..3249b7464889 100644
@@ -11,11 +11,13 @@
 
 #define DMA_ERROR_CODE		(~(dma_addr_t) 0x0)
 
-extern struct dma_map_ops s390_dma_ops;
+extern struct dma_map_ops s390_pci_dma_ops;
 
 static inline struct dma_map_ops *get_dma_ops(struct device *dev)
 {
-	return &s390_dma_ops;
+	if (dev && dev->archdata.dma_ops)
+		return dev->archdata.dma_ops;
+	return &dma_noop_ops;
 }
 
 static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
arch/s390/pci/pci.c +1 -0
index 11d4f277e9f6..f5931135b9ae 100644
@@ -649,6 +649,7 @@ int pcibios_add_device(struct pci_dev *pdev)
 
 	zdev->pdev = pdev;
 	pdev->dev.groups = zpci_attr_groups;
+	pdev->dev.archdata.dma_ops = &s390_pci_dma_ops;
 	zpci_map_resources(pdev);
 
 	for (i = 0; i < PCI_BAR_COUNT; i++) {
arch/s390/pci/pci_dma.c +2 -2
index 4638b93c7632..a79173ec54b9 100644
@@ -544,7 +544,7 @@ static int __init dma_debug_do_init(void)
 }
 fs_initcall(dma_debug_do_init);
 
-struct dma_map_ops s390_dma_ops = {
+struct dma_map_ops s390_pci_dma_ops = {
 	.alloc		= s390_dma_alloc,
 	.free		= s390_dma_free,
 	.map_sg		= s390_dma_map_sg,
@@ -555,7 +555,7 @@ struct dma_map_ops s390_dma_ops = {
 	.is_phys	= 0,
 	/* dma_supported is unconditionally true without a callback */
 };
-EXPORT_SYMBOL_GPL(s390_dma_ops);
+EXPORT_SYMBOL_GPL(s390_pci_dma_ops);
 
 static int __init s390_iommu_setup(char *str)
 {
Signature · 1 line
2.5.0
#7 lore raw

PATCH v5 4/10 vring: Introduce vring_use_dma_api()

In reply to Andy Lutomirski

This is a kludge, but no one has come up with a a better idea yet. We'll introduce DMA API support guarded by vring_use_dma_api(). Eventually we may be able to return true on more and more systems, and hopefully we can get rid of vring_use_dma_api() entirely some day.

---
 drivers/virtio/virtio_ring.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
drivers/virtio/virtio_ring.c +24 -0
index e12e385f7ac3..4b8dab4960bb 100644
@@ -25,6 +25,30 @@
 #include <linux/hrtimer.h>
 #include <linux/kmemleak.h>
 
+/*
+ * The interaction between virtio and a possible IOMMU is a mess.
+ *
+ * On most systems with virtio, physical addresses match bus addresses,
+ * and it doesn't particularly matter whether we use the DMI API.
+ *
+ * On some sytems, including Xen and any system with a physical device
+ * that speaks virtio behind a physical IOMMU, we must use the DMA API
+ * for virtio DMA to work at all.
+ *
+ * On other systems, including SPARC and PPC64, virtio-pci devices are
+ * enumerated as though they are behind an IOMMU, but the virtio host
+ * ignores the IOMMU, so we must either pretend that the IOMMU isn't
+ * there or somehow map everything as the identity.
+ *
+ * For the time being, we preseve historic behavior and bypass the DMA
+ * API.
+ */
+
+static bool vring_use_dma_api(void)
+{
+	return false;
+}
+
 #ifdef DEBUG
 /* For development, we want to crash whenever the ring is screwed. */
 #define BAD_RING(_vq, fmt, args...)				\
Signature · 1 line
2.5.0
#8 lore raw

Re: [PATCH v5 04/10] vring: Introduce vring_use_dma_api()

Quoted 29 lines · Andy Lutomirski

This is a kludge, but no one has come up with a a better idea yet. We'll introduce DMA API support guarded by vring_use_dma_api(). Eventually we may be able to return true on more and more systems, and hopefully we can get rid of vring_use_dma_api() entirely some day.

---
 drivers/virtio/virtio_ring.c | 24 ++++++++++++++++++++++++

 1 file changed, 24 insertions(+)
drivers/virtio/virtio_ring.c +0 -0
index e12e385f7ac3..4b8dab4960bb 100644
@@ -25,6 +25,30 @@
  #include 
  #include 


+/*
+ * The interaction between virtio and a possible IOMMU is a mess.
+ *
+ * On most systems with virtio, physical addresses match bus addresses,
+ * and it doesn't particularly matter whether we use the DMI API.
+ *
+ * On some sytems, including Xen and any system with a physical device
+ * that speaks virtio behind a physical IOMMU, we must use the DMA API
+ * for virtio DMA to work at all.
+ *

Quoted 8 lines

+ * On other systems, including SPARC and PPC64, virtio-pci devices are
+ * enumerated as though they are behind an IOMMU, but the virtio host
+ * ignores the IOMMU, so we must either pretend that the IOMMU isn't
+ * there or somehow map everything as the identity.
+ *
+ * For the time being, we preseve historic behavior and bypass the DMA
+ * API.
+ */

I spot at least three typos in there, FWIW. ('DMI API', 'sytems', 'preseve').

drivers/virtio/virtio_ring.c line 51

Quoted 5 lines
drivers/virtio/virtio_ring.c +5 -0
+static bool vring_use_dma_api(void)
+{
+	return false;
+}
+

I'd quite like to see this be an explicit opt-out for the known-broken platforms. We've listed the SPARC and PPC64 issues. For x86 I need to refresh my memory as a prelude to trying to fix it... was the issue *just* that Qemu tends to ship with a broken BIOS that misdescribes the virtio devices (and any assigned PCI devices) as being behind an IOMMU when they're not, in the rare case that Qemu actually exposes its partially-implemented virtual IOMMU to the guest?

Could we have an arch_vring_eschew_dma_api(dev) function which the affected architectures could provide (as a prelude to fixing it so that the DMA API does the right thing for *itself*)?

It would be functionally equivalent, but it would help to push the workarounds to the right place — rather than entrenching them for ever in tricky "OMG we need to audit what all the architectures do... let's not touch it!" code.

Signature · 2 lines
David Woodhouse                            Open Source Technology Centre
[email protected]                              Intel Corporation

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

#9 lore raw

Re: [PATCH v5 04/10] vring: Introduce vring_use_dma_api()

Quoted 33 lines · David Woodhouse
Quoted 32 lines · Andy Lutomirski

This is a kludge, but no one has come up with a a better idea yet. We'll introduce DMA API support guarded by vring_use_dma_api(). Eventually we may be able to return true on more and more systems, and hopefully we can get rid of vring_use_dma_api() entirely some day.

---
 drivers/virtio/virtio_ring.c | 24 ++++++++++++++++++++++++

 1 file changed, 24 insertions(+)
drivers/virtio/virtio_ring.c +0 -0
index e12e385f7ac3..4b8dab4960bb 100644
@@ -25,6 +25,30 @@
  #include 
  #include 


+/*
+ * The interaction between virtio and a possible IOMMU is a mess.
+ *
+ * On most systems with virtio, physical addresses match bus addresses,
+ * and it doesn't particularly matter whether we use the DMI API.
+ *
+ * On some sytems, including Xen and any system with a physical device
+ * that speaks virtio behind a physical IOMMU, we must use the DMA API
+ * for virtio DMA to work at all.
+ *
+ * On other systems, including SPARC and PPC64, virtio-pci devices are
+ * enumerated as though they are behind an IOMMU, but the virtio host
+ * ignores the IOMMU, so we must either pretend that the IOMMU isn't

Quoted 8 lines
Quoted 5 lines

+ * there or somehow map everything as the identity.
+ *
+ * For the time being, we preseve historic behavior and bypass the DMA
+ * API.
+ */

I spot at least three typos in there, FWIW. ('DMI API', 'sytems', 'preseve').

Good catch, hopefully will be fixed in v2.

Quoted 14 lines

drivers/virtio/virtio_ring.c line 51

Quoted 5 lines
drivers/virtio/virtio_ring.c +5 -0
+static bool vring_use_dma_api(void)
+{
+	return false;
+}
+

I'd quite like to see this be an explicit opt-out for the known-broken platforms. We've listed the SPARC and PPC64 issues. For x86 I need to refresh my memory as a prelude to trying to fix it... was the issue *just* that Qemu tends to ship with a broken BIOS that misdescribes the virtio devices (and any assigned PCI devices) as being behind an IOMMU when they're not, in the rare case that Qemu actually exposes its partially-implemented virtual IOMMU to the guest?

Quoted 3 lines

Could we have an arch_vring_eschew_dma_api(dev) function which the affected architectures could provide (as a prelude to fixing it so that the DMA API does the right thing for *itself*)?

I'm fine with this.

Quoted 9 lines

It would be functionally equivalent, but it would help to push the workarounds to the right place — rather than entrenching them for ever in tricky "OMG we need to audit what all the architectures do... let's not touch it!" code.

Signature · 2 lines
David Woodhouse                            Open Source Technology Centre
[email protected]                              Intel Corporation

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

#10 lore raw

Re: [PATCH v5 04/10] vring: Introduce vring_use_dma_api()

Quoted 43 lines · Michael S. Tsirkin
Quoted 33 lines · David Woodhouse
Quoted 32 lines · Andy Lutomirski

This is a kludge, but no one has come up with a a better idea yet. We'll introduce DMA API support guarded by vring_use_dma_api(). Eventually we may be able to return true on more and more systems, and hopefully we can get rid of vring_use_dma_api() entirely some day.

---
 drivers/virtio/virtio_ring.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
drivers/virtio/virtio_ring.c +13 -0
index e12e385f7ac3..4b8dab4960bb 100644
@@ -25,6 +25,30 @@
 #include
 #include
 
+/*
+ * The interaction between virtio and a possible IOMMU is a mess.
+ *
+ * On most systems with virtio, physical addresses match bus addresses,
+ * and it doesn't particularly matter whether we use the DMI API.
+ *
+ * On some sytems, including Xen and any system with a physical device
+ * that speaks virtio behind a physical IOMMU, we must use the DMA API
+ * for virtio DMA to work at all.
+ *
+ * On other systems, including SPARC and PPC64, virtio-pci devices are
+ * enumerated as though they are behind an IOMMU, but the virtio host
+ * ignores the IOMMU, so we must either pretend that the IOMMU isn't
Quoted 8 lines

drivers/virtio/virtio_ring.c line 45

Quoted 5 lines
drivers/virtio/virtio_ring.c +5 -0
+ * there or somehow map everything as the identity.
+ *
+ * For the time being, we preseve historic behavior and bypass the DMA
+ * API.
+ */

I spot at least three typos in there, FWIW. ('DMI API', 'sytems', 'preseve').

Quoted 1 line

Good catch, hopefully will be fixed in v2.

Queued for v2.

Quoted 15 lines
Quoted 15 lines

drivers/virtio/virtio_ring.c line 51

Quoted 6 lines
drivers/virtio/virtio_ring.c +5 -0
+static bool vring_use_dma_api(void)
+{
+   return false;
+}
+

I'd quite like to see this be an explicit opt-out for the known-broken platforms. We've listed the SPARC and PPC64 issues. For x86 I need to refresh my memory as a prelude to trying to fix it... was the issue *just* that Qemu tends to ship with a broken BIOS that misdescribes the virtio devices (and any assigned PCI devices) as being behind an IOMMU when they're not, in the rare case that Qemu actually exposes its partially-implemented virtual IOMMU to the guest?

Quoted 5 lines
Quoted 3 lines

Could we have an arch_vring_eschew_dma_api(dev) function which the affected architectures could provide (as a prelude to fixing it so that the DMA API does the right thing for *itself*)?

I'm fine with this.

I modified vring_use_dma_api to take a vring_virtqueue* parameter to make this easier.

I'm a bit torn here. I want to get the mechanism and the Xen part in, and there's unlikely to be much debate on those as a matter of principle. I'd also like to flip as many arches over as possible, but that could be trickier. Let me mull over this.

--Andy

#11 lore raw

Re: [PATCH v5 04/10] vring: Introduce vring_use_dma_api()

Quoted 7 lines · Andy Lutomirski
Quoted 6 lines
Quoted 4 lines

Could we have an arch_vring_eschew_dma_api(dev) function which the affected architectures could provide (as a prelude to fixing it so that the DMA API does the right thing for *itself*)?

I'm fine with this.

Quoted 7 lines

I modified vring_use_dma_api to take a vring_virtqueue* parameter to make this easier.

I'm a bit torn here.  I want to get the mechanism and the Xen part in, and there's unlikely to be much debate on those as a matter of principle.  I'd also like to flip as many arches over as possible, but that could be trickier.  Let me mull over this.

Let's queue the arch_vring_eschew_dma_api() thing up after this first batch, and not hold it up any further.

Signature · 2 lines
David Woodhouse                            Open Source Technology Centre
[email protected]                              Intel Corporation
#12 lore raw

Re: [PATCH v5 04/10] vring: Introduce vring_use_dma_api()

In reply to Andy Lutomirski
Quoted 7 lines · Andy Lutomirski
Quoted 6 lines
Quoted 4 lines

Could we have an arch_vring_eschew_dma_api(dev) function which the affected architectures could provide (as a prelude to fixing it so that the DMA API does the right thing for *itself*)?

I'm fine with this.

Quoted 7 lines

I modified vring_use_dma_api to take a vring_virtqueue* parameter to make this easier.

I'm a bit torn here.  I want to get the mechanism and the Xen part in, and there's unlikely to be much debate on those as a matter of principle.  I'd also like to flip as many arches over as possible, but that could be trickier.  Let me mull over this.

Let's queue the arch_vring_eschew_dma_api() thing up after this first batch, and not hold it up any further.

Signature · 2 lines
David Woodhouse                            Open Source Technology Centre
[email protected]                              Intel Corporation

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

#13 lore raw

Re: [PATCH v5 04/10] vring: Introduce vring_use_dma_api()

In reply to Andy Lutomirski
Quoted 7 lines · Andy Lutomirski
Quoted 6 lines
Quoted 4 lines

Could we have an arch_vring_eschew_dma_api(dev) function which the affected architectures could provide (as a prelude to fixing it so that the DMA API does the right thing for *itself*)?

I'm fine with this.

Quoted 7 lines

I modified vring_use_dma_api to take a vring_virtqueue* parameter to make this easier.

I'm a bit torn here.  I want to get the mechanism and the Xen part in, and there's unlikely to be much debate on those as a matter of principle.  I'd also like to flip as many arches over as possible, but that could be trickier.  Let me mull over this.

Let's queue the arch_vring_eschew_dma_api() thing up after this first batch, and not hold it up any further.

Signature · 2 lines
David Woodhouse                            Open Source Technology Centre
[email protected]                              Intel Corporation

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#14 lore raw

Re: [PATCH v5 04/10] vring: Introduce vring_use_dma_api()

In reply to Michael S. Tsirkin
Quoted 43 lines · Michael S. Tsirkin
Quoted 33 lines · David Woodhouse
Quoted 32 lines · Andy Lutomirski

This is a kludge, but no one has come up with a a better idea yet. We'll introduce DMA API support guarded by vring_use_dma_api(). Eventually we may be able to return true on more and more systems, and hopefully we can get rid of vring_use_dma_api() entirely some day.

---
 drivers/virtio/virtio_ring.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
drivers/virtio/virtio_ring.c +13 -0
index e12e385f7ac3..4b8dab4960bb 100644
@@ -25,6 +25,30 @@
 #include
 #include
 
+/*
+ * The interaction between virtio and a possible IOMMU is a mess.
+ *
+ * On most systems with virtio, physical addresses match bus addresses,
+ * and it doesn't particularly matter whether we use the DMI API.
+ *
+ * On some sytems, including Xen and any system with a physical device
+ * that speaks virtio behind a physical IOMMU, we must use the DMA API
+ * for virtio DMA to work at all.
+ *
+ * On other systems, including SPARC and PPC64, virtio-pci devices are
+ * enumerated as though they are behind an IOMMU, but the virtio host
+ * ignores the IOMMU, so we must either pretend that the IOMMU isn't
Quoted 8 lines

drivers/virtio/virtio_ring.c line 45

Quoted 5 lines
drivers/virtio/virtio_ring.c +5 -0
+ * there or somehow map everything as the identity.
+ *
+ * For the time being, we preseve historic behavior and bypass the DMA
+ * API.
+ */

I spot at least three typos in there, FWIW. ('DMI API', 'sytems', 'preseve').

Quoted 1 line

Good catch, hopefully will be fixed in v2.

Queued for v2.

Quoted 15 lines
Quoted 15 lines

drivers/virtio/virtio_ring.c line 51

Quoted 6 lines
drivers/virtio/virtio_ring.c +5 -0
+static bool vring_use_dma_api(void)
+{
+   return false;
+}
+

I'd quite like to see this be an explicit opt-out for the known-broken platforms. We've listed the SPARC and PPC64 issues. For x86 I need to refresh my memory as a prelude to trying to fix it... was the issue *just* that Qemu tends to ship with a broken BIOS that misdescribes the virtio devices (and any assigned PCI devices) as being behind an IOMMU when they're not, in the rare case that Qemu actually exposes its partially-implemented virtual IOMMU to the guest?

Quoted 5 lines
Quoted 3 lines

Could we have an arch_vring_eschew_dma_api(dev) function which the affected architectures could provide (as a prelude to fixing it so that the DMA API does the right thing for *itself*)?

I'm fine with this.

I modified vring_use_dma_api to take a vring_virtqueue* parameter to make this easier.

I'm a bit torn here. I want to get the mechanism and the Xen part in, and there's unlikely to be much debate on those as a matter of principle. I'd also like to flip as many arches over as possible, but that could be trickier. Let me mull over this.

--Andy

#15 lore raw

Re: [PATCH v5 04/10] vring: Introduce vring_use_dma_api()

In reply to Michael S. Tsirkin
Quoted 43 lines · Michael S. Tsirkin
Quoted 33 lines · David Woodhouse
Quoted 32 lines · Andy Lutomirski

This is a kludge, but no one has come up with a a better idea yet. We'll introduce DMA API support guarded by vring_use_dma_api(). Eventually we may be able to return true on more and more systems, and hopefully we can get rid of vring_use_dma_api() entirely some day.

---
 drivers/virtio/virtio_ring.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
drivers/virtio/virtio_ring.c +13 -0
index e12e385f7ac3..4b8dab4960bb 100644
@@ -25,6 +25,30 @@
 #include
 #include
 
+/*
+ * The interaction between virtio and a possible IOMMU is a mess.
+ *
+ * On most systems with virtio, physical addresses match bus addresses,
+ * and it doesn't particularly matter whether we use the DMI API.
+ *
+ * On some sytems, including Xen and any system with a physical device
+ * that speaks virtio behind a physical IOMMU, we must use the DMA API
+ * for virtio DMA to work at all.
+ *
+ * On other systems, including SPARC and PPC64, virtio-pci devices are
+ * enumerated as though they are behind an IOMMU, but the virtio host
+ * ignores the IOMMU, so we must either pretend that the IOMMU isn't
Quoted 8 lines

drivers/virtio/virtio_ring.c line 45

Quoted 5 lines
drivers/virtio/virtio_ring.c +5 -0
+ * there or somehow map everything as the identity.
+ *
+ * For the time being, we preseve historic behavior and bypass the DMA
+ * API.
+ */

I spot at least three typos in there, FWIW. ('DMI API', 'sytems', 'preseve').

Quoted 1 line

Good catch, hopefully will be fixed in v2.

Queued for v2.

Quoted 15 lines
Quoted 15 lines

drivers/virtio/virtio_ring.c line 51

Quoted 6 lines
drivers/virtio/virtio_ring.c +5 -0
+static bool vring_use_dma_api(void)
+{
+   return false;
+}
+

I'd quite like to see this be an explicit opt-out for the known-broken platforms. We've listed the SPARC and PPC64 issues. For x86 I need to refresh my memory as a prelude to trying to fix it... was the issue *just* that Qemu tends to ship with a broken BIOS that misdescribes the virtio devices (and any assigned PCI devices) as being behind an IOMMU when they're not, in the rare case that Qemu actually exposes its partially-implemented virtual IOMMU to the guest?

Quoted 5 lines
Quoted 3 lines

Could we have an arch_vring_eschew_dma_api(dev) function which the affected architectures could provide (as a prelude to fixing it so that the DMA API does the right thing for *itself*)?

I'm fine with this.

I modified vring_use_dma_api to take a vring_virtqueue* parameter to make this easier.

I'm a bit torn here. I want to get the mechanism and the Xen part in, and there's unlikely to be much debate on those as a matter of principle. I'd also like to flip as many arches over as possible, but that could be trickier. Let me mull over this.

--Andy

#16 lore raw

Re: [PATCH v5 04/10] vring: Introduce vring_use_dma_api()

In reply to David Woodhouse
Quoted 33 lines · David Woodhouse
Quoted 32 lines · Andy Lutomirski

This is a kludge, but no one has come up with a a better idea yet. We'll introduce DMA API support guarded by vring_use_dma_api(). Eventually we may be able to return true on more and more systems, and hopefully we can get rid of vring_use_dma_api() entirely some day.

---
 drivers/virtio/virtio_ring.c | 24 ++++++++++++++++++++++++

 1 file changed, 24 insertions(+)
drivers/virtio/virtio_ring.c +0 -0
index e12e385f7ac3..4b8dab4960bb 100644
@@ -25,6 +25,30 @@
  #include 
  #include 


+/*
+ * The interaction between virtio and a possible IOMMU is a mess.
+ *
+ * On most systems with virtio, physical addresses match bus addresses,
+ * and it doesn't particularly matter whether we use the DMI API.
+ *
+ * On some sytems, including Xen and any system with a physical device
+ * that speaks virtio behind a physical IOMMU, we must use the DMA API
+ * for virtio DMA to work at all.
+ *
+ * On other systems, including SPARC and PPC64, virtio-pci devices are
+ * enumerated as though they are behind an IOMMU, but the virtio host
+ * ignores the IOMMU, so we must either pretend that the IOMMU isn't

Quoted 8 lines
Quoted 5 lines

+ * there or somehow map everything as the identity.
+ *
+ * For the time being, we preseve historic behavior and bypass the DMA
+ * API.
+ */

I spot at least three typos in there, FWIW. ('DMI API', 'sytems', 'preseve').

Good catch, hopefully will be fixed in v2.

Quoted 14 lines

drivers/virtio/virtio_ring.c line 51

Quoted 5 lines
drivers/virtio/virtio_ring.c +5 -0
+static bool vring_use_dma_api(void)
+{
+	return false;
+}
+

I'd quite like to see this be an explicit opt-out for the known-broken platforms. We've listed the SPARC and PPC64 issues. For x86 I need to refresh my memory as a prelude to trying to fix it... was the issue *just* that Qemu tends to ship with a broken BIOS that misdescribes the virtio devices (and any assigned PCI devices) as being behind an IOMMU when they're not, in the rare case that Qemu actually exposes its partially-implemented virtual IOMMU to the guest?

Quoted 3 lines

Could we have an arch_vring_eschew_dma_api(dev) function which the affected architectures could provide (as a prelude to fixing it so that the DMA API does the right thing for *itself*)?

I'm fine with this.

Quoted 9 lines

It would be functionally equivalent, but it would help to push the workarounds to the right place — rather than entrenching them for ever in tricky "OMG we need to audit what all the architectures do... let's not touch it!" code.

Signature · 2 lines
David Woodhouse                            Open Source Technology Centre
[email protected]                              Intel Corporation

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#17 lore raw

Re: [PATCH v5 04/10] vring: Introduce vring_use_dma_api()

In reply to Andy Lutomirski
Quoted 29 lines · Andy Lutomirski

This is a kludge, but no one has come up with a a better idea yet. We'll introduce DMA API support guarded by vring_use_dma_api(). Eventually we may be able to return true on more and more systems, and hopefully we can get rid of vring_use_dma_api() entirely some day.

---
 drivers/virtio/virtio_ring.c | 24 ++++++++++++++++++++++++

 1 file changed, 24 insertions(+)
drivers/virtio/virtio_ring.c +0 -0
index e12e385f7ac3..4b8dab4960bb 100644
@@ -25,6 +25,30 @@
  #include 
  #include 


+/*
+ * The interaction between virtio and a possible IOMMU is a mess.
+ *
+ * On most systems with virtio, physical addresses match bus addresses,
+ * and it doesn't particularly matter whether we use the DMI API.
+ *
+ * On some sytems, including Xen and any system with a physical device
+ * that speaks virtio behind a physical IOMMU, we must use the DMA API
+ * for virtio DMA to work at all.
+ *

Quoted 8 lines

+ * On other systems, including SPARC and PPC64, virtio-pci devices are
+ * enumerated as though they are behind an IOMMU, but the virtio host
+ * ignores the IOMMU, so we must either pretend that the IOMMU isn't
+ * there or somehow map everything as the identity.
+ *
+ * For the time being, we preseve historic behavior and bypass the DMA
+ * API.
+ */

I spot at least three typos in there, FWIW. ('DMI API', 'sytems', 'preseve').

drivers/virtio/virtio_ring.c line 51

Quoted 5 lines
drivers/virtio/virtio_ring.c +5 -0
+static bool vring_use_dma_api(void)
+{
+	return false;
+}
+

I'd quite like to see this be an explicit opt-out for the known-broken platforms. We've listed the SPARC and PPC64 issues. For x86 I need to refresh my memory as a prelude to trying to fix it... was the issue *just* that Qemu tends to ship with a broken BIOS that misdescribes the virtio devices (and any assigned PCI devices) as being behind an IOMMU when they're not, in the rare case that Qemu actually exposes its partially-implemented virtual IOMMU to the guest?

Could we have an arch_vring_eschew_dma_api(dev) function which the affected architectures could provide (as a prelude to fixing it so that the DMA API does the right thing for *itself*)?

It would be functionally equivalent, but it would help to push the workarounds to the right place — rather than entrenching them for ever in tricky "OMG we need to audit what all the architectures do... let's not touch it!" code.

Signature · 2 lines
David Woodhouse                            Open Source Technology Centre
[email protected]                              Intel Corporation

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#18 lore raw

PATCH v5 4/10 vring: Introduce vring_use_dma_api()

In reply to Andy Lutomirski

This is a kludge, but no one has come up with a a better idea yet. We'll introduce DMA API support guarded by vring_use_dma_api(). Eventually we may be able to return true on more and more systems, and hopefully we can get rid of vring_use_dma_api() entirely some day.

---
 drivers/virtio/virtio_ring.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
drivers/virtio/virtio_ring.c +24 -0
index e12e385f7ac3..4b8dab4960bb 100644
@@ -25,6 +25,30 @@
 #include <linux/hrtimer.h>
 #include <linux/kmemleak.h>
 
+/*
+ * The interaction between virtio and a possible IOMMU is a mess.
+ *
+ * On most systems with virtio, physical addresses match bus addresses,
+ * and it doesn't particularly matter whether we use the DMI API.
+ *
+ * On some sytems, including Xen and any system with a physical device
+ * that speaks virtio behind a physical IOMMU, we must use the DMA API
+ * for virtio DMA to work at all.
+ *
+ * On other systems, including SPARC and PPC64, virtio-pci devices are
+ * enumerated as though they are behind an IOMMU, but the virtio host
+ * ignores the IOMMU, so we must either pretend that the IOMMU isn't
+ * there or somehow map everything as the identity.
+ *
+ * For the time being, we preseve historic behavior and bypass the DMA
+ * API.
+ */
+
+static bool vring_use_dma_api(void)
+{
+	return false;
+}
+
 #ifdef DEBUG
 /* For development, we want to crash whenever the ring is screwed. */
 #define BAD_RING(_vq, fmt, args...)				\
Signature · 1 line
2.5.0
#19 lore raw

PATCH v5 4/10 vring: Introduce vring_use_dma_api()

In reply to Andy Lutomirski

This is a kludge, but no one has come up with a a better idea yet. We'll introduce DMA API support guarded by vring_use_dma_api(). Eventually we may be able to return true on more and more systems, and hopefully we can get rid of vring_use_dma_api() entirely some day.

---
 drivers/virtio/virtio_ring.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
drivers/virtio/virtio_ring.c +24 -0
index e12e385f7ac3..4b8dab4960bb 100644
@@ -25,6 +25,30 @@
 #include <linux/hrtimer.h>
 #include <linux/kmemleak.h>
 
+/*
+ * The interaction between virtio and a possible IOMMU is a mess.
+ *
+ * On most systems with virtio, physical addresses match bus addresses,
+ * and it doesn't particularly matter whether we use the DMI API.
+ *
+ * On some sytems, including Xen and any system with a physical device
+ * that speaks virtio behind a physical IOMMU, we must use the DMA API
+ * for virtio DMA to work at all.
+ *
+ * On other systems, including SPARC and PPC64, virtio-pci devices are
+ * enumerated as though they are behind an IOMMU, but the virtio host
+ * ignores the IOMMU, so we must either pretend that the IOMMU isn't
+ * there or somehow map everything as the identity.
+ *
+ * For the time being, we preseve historic behavior and bypass the DMA
+ * API.
+ */
+
+static bool vring_use_dma_api(void)
+{
+	return false;
+}
+
 #ifdef DEBUG
 /* For development, we want to crash whenever the ring is screwed. */
 #define BAD_RING(_vq, fmt, args...)				\
Signature · 1 line
2.5.0
#20 lore raw

PATCH v5 5/10 virtio_ring: Support DMA APIs

In reply to Andy Lutomirski

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.

---
 drivers/virtio/Kconfig           |   2 +-
 drivers/virtio/virtio_ring.c     | 200 ++++++++++++++++++++++++++++++++-------
 tools/virtio/linux/dma-mapping.h |  17 ++++
 3 files changed, 183 insertions(+), 36 deletions(-)
 create mode 100644 tools/virtio/linux/dma-mapping.h
drivers/virtio/Kconfig +1 -1
index cab9f3f63a38..77590320d44c 100644
@@ -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
drivers/virtio/virtio_ring.c +165 -35

326 lines not on this page · raw message

tools/virtio/linux/dma-mapping.h new file +17 -0
new file mode 100644
index 000000000000..4f93af89ae16
@@ -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
Signature · 1 line
2.5.0
#21 lore raw

PATCH v5 5/10 virtio_ring: Support DMA APIs

In reply to Andy Lutomirski

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.

---
 drivers/virtio/Kconfig           |   2 +-
 drivers/virtio/virtio_ring.c     | 200 ++++++++++++++++++++++++++++++++-------
 tools/virtio/linux/dma-mapping.h |  17 ++++
 3 files changed, 183 insertions(+), 36 deletions(-)
 create mode 100644 tools/virtio/linux/dma-mapping.h
drivers/virtio/Kconfig +1 -1
index cab9f3f63a38..77590320d44c 100644
@@ -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
drivers/virtio/virtio_ring.c +165 -35

326 lines not on this page · raw message

tools/virtio/linux/dma-mapping.h new file +17 -0
new file mode 100644
index 000000000000..4f93af89ae16
@@ -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
Signature · 1 line
2.5.0
#22 lore raw

PATCH v5 6/10 virtio: Add improved queue allocation API

In reply to Andy Lutomirski

This leaves vring_new_virtqueue alone for compatbility, but it adds two new improved APIs:

vring_create_virtqueue: Creates a virtqueue backed by automatically allocated coherent memory. (Some day it this could be extended to support non-coherent memory, too, if there ends up being a platform on which it's worthwhile.)

__vring_new_virtqueue: Creates a virtqueue with a manually-specified layout. This should allow mic_virtio to work much more cleanly.

---
 drivers/virtio/virtio_ring.c | 178 +++++++++++++++++++++++++++++++++++--------
 include/linux/virtio.h       |  23 +++++-
 include/linux/virtio_ring.h  |  35 +++++++++
 3 files changed, 204 insertions(+), 32 deletions(-)
drivers/virtio/virtio_ring.c +148 -30
index ec2e65876b29..c169c6444637 100644
@@ -119,6 +119,11 @@ struct vring_virtqueue {
 	/* How to notify other side. FIXME: commonalize hcalls! */
 	bool (*notify)(struct virtqueue *vq);
 
+	/* DMA, allocation, and size information */
+	bool we_own_ring;
+	size_t queue_size_in_bytes;
+	dma_addr_t queue_dma_addr;
+
 #ifdef DEBUG
 	/* They're supposed to lock for us. */
 	unsigned int in_use;
@@ -878,36 +883,31 @@ irqreturn_t vring_interrupt(int irq, void *_vq)
 }
 EXPORT_SYMBOL_GPL(vring_interrupt);
 
-struct virtqueue *vring_new_virtqueue(unsigned int index,
-				      unsigned int num,
-				      unsigned int vring_align,
-				      struct virtio_device *vdev,
-				      bool weak_barriers,
-				      void *pages,
-				      bool (*notify)(struct virtqueue *),
-				      void (*callback)(struct virtqueue *),
-				      const char *name)
+struct virtqueue *__vring_new_virtqueue(unsigned int index,
+					struct vring vring,
+					struct virtio_device *vdev,
+					bool weak_barriers,
+					bool (*notify)(struct virtqueue *),
+					void (*callback)(struct virtqueue *),
+					const char *name)
 {
-	struct vring_virtqueue *vq;
 	unsigned int i;
+	struct vring_virtqueue *vq;
 
-	/* We assume num is a power of 2. */
-	if (num & (num - 1)) {
-		dev_warn(&vdev->dev, "Bad virtqueue length %u\n", num);
-		return NULL;
-	}
-
-	vq = kmalloc(sizeof(*vq) + num * sizeof(struct vring_desc_state),
+	vq = kmalloc(sizeof(*vq) + vring.num * sizeof(struct vring_desc_state),
 		     GFP_KERNEL);
 	if (!vq)
 		return NULL;
 
-	vring_init(&vq->vring, num, pages, vring_align);
+	vq->vring = vring;
 	vq->vq.callback = callback;
 	vq->vq.vdev = vdev;
 	vq->vq.name = name;
-	vq->vq.num_free = num;
+	vq->vq.num_free = vring.num;
 	vq->vq.index = index;
+	vq->we_own_ring = false;
+	vq->queue_dma_addr = 0;
+	vq->queue_size_in_bytes = 0;
 	vq->notify = notify;
 	vq->weak_barriers = weak_barriers;
 	vq->broken = false;
@@ -932,18 +932,105 @@ 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 < vring.num-1; i++)
 		vq->vring.desc[i].next = cpu_to_virtio16(vdev, i + 1);
-	memset(vq->desc_state, 0, num * sizeof(struct vring_desc_state));
+	memset(vq->desc_state, 0, vring.num * sizeof(struct vring_desc_state));
 
 	return &vq->vq;
 }
+EXPORT_SYMBOL_GPL(__vring_new_virtqueue);
+
+struct virtqueue *vring_create_virtqueue(
+	unsigned int index,
+	unsigned int num,
+	unsigned int vring_align,
+	struct virtio_device *vdev,
+	bool weak_barriers,
+	bool may_reduce_num,
+	bool (*notify)(struct virtqueue *),
+	void (*callback)(struct virtqueue *),
+	const char *name)
+{
+	struct virtqueue *vq;
+	void *queue;
+	dma_addr_t dma_addr;
+	size_t queue_size_in_bytes;
+	struct vring vring;
+
+	/* We assume num is a power of 2. */
+	if (num & (num - 1)) {
+		dev_warn(&vdev->dev, "Bad virtqueue length %u\n", num);
+		return NULL;
+	}
+
+	/* TODO: allocate each queue chunk individually */
+	for (; num && vring_size(num, vring_align) > PAGE_SIZE; num /= 2) {
+		queue = dma_zalloc_coherent(
+			vdev->dev.parent, vring_size(num, vring_align),
+			&dma_addr, GFP_KERNEL|__GFP_NOWARN);
+		if (queue)
+			break;
+	}
+
+	if (!num)
+		return NULL;
+
+	if (!queue) {
+		/* Try to get a single page. You are my only hope! */
+		queue = dma_zalloc_coherent(
+			vdev->dev.parent, vring_size(num, vring_align),
+			&dma_addr, GFP_KERNEL);
+	}
+	if (!queue)
+		return NULL;
+
+	queue_size_in_bytes = vring_size(num, vring_align);
+	vring_init(&vring, num, queue, vring_align);
+
+	vq = __vring_new_virtqueue(index, vring, vdev, weak_barriers,
+				   notify, callback, name);
+	if (!vq) {
+		dma_free_coherent(vdev->dev.parent,
+				  queue_size_in_bytes, queue,
+				  dma_addr);
+		return NULL;
+	}
+
+	to_vvq(vq)->queue_dma_addr = dma_addr;
+	to_vvq(vq)->queue_size_in_bytes = queue_size_in_bytes;
+	to_vvq(vq)->we_own_ring = true;
+
+	return vq;
+}
+EXPORT_SYMBOL_GPL(vring_create_virtqueue);
+
+struct virtqueue *vring_new_virtqueue(unsigned int index,
+				      unsigned int num,
+				      unsigned int vring_align,
+				      struct virtio_device *vdev,
+				      bool weak_barriers,
+				      void *pages,
+				      bool (*notify)(struct virtqueue *vq),
+				      void (*callback)(struct virtqueue *vq),
+				      const char *name)
+{
+	struct vring vring;
+	vring_init(&vring, num, pages, vring_align);
+	return __vring_new_virtqueue(index, vring, vdev, weak_barriers,
+				     notify, callback, name);
+}
 EXPORT_SYMBOL_GPL(vring_new_virtqueue);
 
-void vring_del_virtqueue(struct virtqueue *vq)
+void vring_del_virtqueue(struct virtqueue *_vq)
 {
-	list_del(&vq->list);
-	kfree(to_vvq(vq));
+	struct vring_virtqueue *vq = to_vvq(_vq);
+
+	if (vq->we_own_ring) {
+		dma_free_coherent(vring_dma_dev(vq), vq->queue_size_in_bytes,
+				  vq->vring.desc, vq->queue_dma_addr);
+	}
+	list_del(&_vq->list);
+	kfree(vq);
 }
 EXPORT_SYMBOL_GPL(vring_del_virtqueue);
 
@@ -1007,20 +1094,51 @@ void virtio_break_device(struct virtio_device *dev)
 }
 EXPORT_SYMBOL_GPL(virtio_break_device);
 
-void *virtqueue_get_avail(struct virtqueue *_vq)
+dma_addr_t virtqueue_get_desc_addr(struct virtqueue *_vq)
+{
+	struct vring_virtqueue *vq = to_vvq(_vq);
+
+	BUG_ON(!vq->we_own_ring);
+
+	if (vring_use_dma_api())
+		return vq->queue_dma_addr;
+	else
+		return virt_to_phys(vq->vring.desc);
+}
+EXPORT_SYMBOL_GPL(virtqueue_get_desc_addr);
+
+dma_addr_t virtqueue_get_avail_addr(struct virtqueue *_vq)
 {
 	struct vring_virtqueue *vq = to_vvq(_vq);
 
-	return vq->vring.avail;
+	BUG_ON(!vq->we_own_ring);
+
+	if (vring_use_dma_api())
+		return vq->queue_dma_addr +
+			((char *)vq->vring.avail - (char *)vq->vring.desc);
+	else
+		return virt_to_phys(vq->vring.avail);
 }
-EXPORT_SYMBOL_GPL(virtqueue_get_avail);
+EXPORT_SYMBOL_GPL(virtqueue_get_avail_addr);
 
-void *virtqueue_get_used(struct virtqueue *_vq)
+dma_addr_t virtqueue_get_used_addr(struct virtqueue *_vq)
 {
 	struct vring_virtqueue *vq = to_vvq(_vq);
 
-	return vq->vring.used;
+	BUG_ON(!vq->we_own_ring);
+
+	if (vring_use_dma_api())
+		return vq->queue_dma_addr +
+			((char *)vq->vring.used - (char *)vq->vring.desc);
+	else
+		return virt_to_phys(vq->vring.used);
+}
+EXPORT_SYMBOL_GPL(virtqueue_get_used_addr);
+
+const struct vring *virtqueue_get_vring(struct virtqueue *vq)
+{
+	return &to_vvq(vq)->vring;
 }
-EXPORT_SYMBOL_GPL(virtqueue_get_used);
+EXPORT_SYMBOL_GPL(virtqueue_get_vring);
 
 MODULE_LICENSE("GPL");
include/linux/virtio.h +21 -2
index 8f4d4bfa6d46..d5eb5479a425 100644
@@ -75,8 +75,27 @@ unsigned int virtqueue_get_vring_size(struct virtqueue *vq);
 
 bool virtqueue_is_broken(struct virtqueue *vq);
 
-void *virtqueue_get_avail(struct virtqueue *vq);
-void *virtqueue_get_used(struct virtqueue *vq);
+const struct vring *virtqueue_get_vring(struct virtqueue *vq);
+dma_addr_t virtqueue_get_desc_addr(struct virtqueue *vq);
+dma_addr_t virtqueue_get_avail_addr(struct virtqueue *vq);
+dma_addr_t virtqueue_get_used_addr(struct virtqueue *vq);
+
+/*
+ * Legacy accessors -- in almost all cases, these are the wrong functions
+ * to use.
+ */
+static inline void *virtqueue_get_desc(struct virtqueue *vq)
+{
+	return virtqueue_get_vring(vq)->desc;
+}
+static inline void *virtqueue_get_avail(struct virtqueue *vq)
+{
+	return virtqueue_get_vring(vq)->avail;
+}
+static inline void *virtqueue_get_used(struct virtqueue *vq)
+{
+	return virtqueue_get_vring(vq)->used;
+}
 
 /**
  * virtio_device - representation of a device using virtio
include/linux/virtio_ring.h +35 -0
index a156e2b6ccfe..e8d36938f09a 100644
@@ -59,6 +59,35 @@ static inline void virtio_store_mb(bool weak_barriers,
 struct virtio_device;
 struct virtqueue;
 
+/*
+ * Creates a virtqueue and allocates the descriptor ring.  If
+ * may_reduce_num is set, then this may allocate a smaller ring than
+ * expected.  The caller should query virtqueue_get_ring_size to learn
+ * the actual size of the ring.
+ */
+struct virtqueue *vring_create_virtqueue(unsigned int index,
+					 unsigned int num,
+					 unsigned int vring_align,
+					 struct virtio_device *vdev,
+					 bool weak_barriers,
+					 bool may_reduce_num,
+					 bool (*notify)(struct virtqueue *vq),
+					 void (*callback)(struct virtqueue *vq),
+					 const char *name);
+
+/* Creates a virtqueue with a custom layout. */
+struct virtqueue *__vring_new_virtqueue(unsigned int index,
+					struct vring vring,
+					struct virtio_device *vdev,
+					bool weak_barriers,
+					bool (*notify)(struct virtqueue *),
+					void (*callback)(struct virtqueue *),
+					const char *name);
+
+/*
+ * Creates a virtqueue with a standard layout but a caller-allocated
+ * ring.
+ */
 struct virtqueue *vring_new_virtqueue(unsigned int index,
 				      unsigned int num,
 				      unsigned int vring_align,
@@ -68,7 +97,13 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
 				      bool (*notify)(struct virtqueue *vq),
 				      void (*callback)(struct virtqueue *vq),
 				      const char *name);
+
+/*
+ * Destroys a virtqueue.  If created with vring_create_virtqueue, this
+ * also frees the ring.
+ */
 void vring_del_virtqueue(struct virtqueue *vq);
+
 /* Filter out transport-specific feature bits. */
 void vring_transport_features(struct virtio_device *vdev);
 
Signature · 1 line
2.5.0
#23 lore raw

PATCH v5 6/10 virtio: Add improved queue allocation API

In reply to Andy Lutomirski

This leaves vring_new_virtqueue alone for compatbility, but it adds two new improved APIs:

vring_create_virtqueue: Creates a virtqueue backed by automatically allocated coherent memory. (Some day it this could be extended to support non-coherent memory, too, if there ends up being a platform on which it's worthwhile.)

__vring_new_virtqueue: Creates a virtqueue with a manually-specified layout. This should allow mic_virtio to work much more cleanly.

---
 drivers/virtio/virtio_ring.c | 178 +++++++++++++++++++++++++++++++++++--------
 include/linux/virtio.h       |  23 +++++-
 include/linux/virtio_ring.h  |  35 +++++++++
 3 files changed, 204 insertions(+), 32 deletions(-)
drivers/virtio/virtio_ring.c +148 -30
index ec2e65876b29..c169c6444637 100644
@@ -119,6 +119,11 @@ struct vring_virtqueue {
 	/* How to notify other side. FIXME: commonalize hcalls! */
 	bool (*notify)(struct virtqueue *vq);
 
+	/* DMA, allocation, and size information */
+	bool we_own_ring;
+	size_t queue_size_in_bytes;
+	dma_addr_t queue_dma_addr;
+
 #ifdef DEBUG
 	/* They're supposed to lock for us. */
 	unsigned int in_use;
@@ -878,36 +883,31 @@ irqreturn_t vring_interrupt(int irq, void *_vq)
 }
 EXPORT_SYMBOL_GPL(vring_interrupt);
 
-struct virtqueue *vring_new_virtqueue(unsigned int index,
-				      unsigned int num,
-				      unsigned int vring_align,
-				      struct virtio_device *vdev,
-				      bool weak_barriers,
-				      void *pages,
-				      bool (*notify)(struct virtqueue *),
-				      void (*callback)(struct virtqueue *),
-				      const char *name)
+struct virtqueue *__vring_new_virtqueue(unsigned int index,
+					struct vring vring,
+					struct virtio_device *vdev,
+					bool weak_barriers,
+					bool (*notify)(struct virtqueue *),
+					void (*callback)(struct virtqueue *),
+					const char *name)
 {
-	struct vring_virtqueue *vq;
 	unsigned int i;
+	struct vring_virtqueue *vq;
 
-	/* We assume num is a power of 2. */
-	if (num & (num - 1)) {
-		dev_warn(&vdev->dev, "Bad virtqueue length %u\n", num);
-		return NULL;
-	}
-
-	vq = kmalloc(sizeof(*vq) + num * sizeof(struct vring_desc_state),
+	vq = kmalloc(sizeof(*vq) + vring.num * sizeof(struct vring_desc_state),
 		     GFP_KERNEL);
 	if (!vq)
 		return NULL;
 
-	vring_init(&vq->vring, num, pages, vring_align);
+	vq->vring = vring;
 	vq->vq.callback = callback;
 	vq->vq.vdev = vdev;
 	vq->vq.name = name;
-	vq->vq.num_free = num;
+	vq->vq.num_free = vring.num;
 	vq->vq.index = index;
+	vq->we_own_ring = false;
+	vq->queue_dma_addr = 0;
+	vq->queue_size_in_bytes = 0;
 	vq->notify = notify;
 	vq->weak_barriers = weak_barriers;
 	vq->broken = false;
@@ -932,18 +932,105 @@ 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 < vring.num-1; i++)
 		vq->vring.desc[i].next = cpu_to_virtio16(vdev, i + 1);
-	memset(vq->desc_state, 0, num * sizeof(struct vring_desc_state));
+	memset(vq->desc_state, 0, vring.num * sizeof(struct vring_desc_state));
 
 	return &vq->vq;
 }
+EXPORT_SYMBOL_GPL(__vring_new_virtqueue);
+
+struct virtqueue *vring_create_virtqueue(
+	unsigned int index,
+	unsigned int num,
+	unsigned int vring_align,
+	struct virtio_device *vdev,
+	bool weak_barriers,
+	bool may_reduce_num,
+	bool (*notify)(struct virtqueue *),
+	void (*callback)(struct virtqueue *),
+	const char *name)
+{
+	struct virtqueue *vq;
+	void *queue;
+	dma_addr_t dma_addr;
+	size_t queue_size_in_bytes;
+	struct vring vring;
+
+	/* We assume num is a power of 2. */
+	if (num & (num - 1)) {
+		dev_warn(&vdev->dev, "Bad virtqueue length %u\n", num);
+		return NULL;
+	}
+
+	/* TODO: allocate each queue chunk individually */
+	for (; num && vring_size(num, vring_align) > PAGE_SIZE; num /= 2) {
+		queue = dma_zalloc_coherent(
+			vdev->dev.parent, vring_size(num, vring_align),
+			&dma_addr, GFP_KERNEL|__GFP_NOWARN);
+		if (queue)
+			break;
+	}
+
+	if (!num)
+		return NULL;
+
+	if (!queue) {
+		/* Try to get a single page. You are my only hope! */
+		queue = dma_zalloc_coherent(
+			vdev->dev.parent, vring_size(num, vring_align),
+			&dma_addr, GFP_KERNEL);
+	}
+	if (!queue)
+		return NULL;
+
+	queue_size_in_bytes = vring_size(num, vring_align);
+	vring_init(&vring, num, queue, vring_align);
+
+	vq = __vring_new_virtqueue(index, vring, vdev, weak_barriers,
+				   notify, callback, name);
+	if (!vq) {
+		dma_free_coherent(vdev->dev.parent,
+				  queue_size_in_bytes, queue,
+				  dma_addr);
+		return NULL;
+	}
+
+	to_vvq(vq)->queue_dma_addr = dma_addr;
+	to_vvq(vq)->queue_size_in_bytes = queue_size_in_bytes;
+	to_vvq(vq)->we_own_ring = true;
+
+	return vq;
+}
+EXPORT_SYMBOL_GPL(vring_create_virtqueue);
+
+struct virtqueue *vring_new_virtqueue(unsigned int index,
+				      unsigned int num,
+				      unsigned int vring_align,
+				      struct virtio_device *vdev,
+				      bool weak_barriers,
+				      void *pages,
+				      bool (*notify)(struct virtqueue *vq),
+				      void (*callback)(struct virtqueue *vq),
+				      const char *name)
+{
+	struct vring vring;
+	vring_init(&vring, num, pages, vring_align);
+	return __vring_new_virtqueue(index, vring, vdev, weak_barriers,
+				     notify, callback, name);
+}
 EXPORT_SYMBOL_GPL(vring_new_virtqueue);
 
-void vring_del_virtqueue(struct virtqueue *vq)
+void vring_del_virtqueue(struct virtqueue *_vq)
 {
-	list_del(&vq->list);
-	kfree(to_vvq(vq));
+	struct vring_virtqueue *vq = to_vvq(_vq);
+
+	if (vq->we_own_ring) {
+		dma_free_coherent(vring_dma_dev(vq), vq->queue_size_in_bytes,
+				  vq->vring.desc, vq->queue_dma_addr);
+	}
+	list_del(&_vq->list);
+	kfree(vq);
 }
 EXPORT_SYMBOL_GPL(vring_del_virtqueue);
 
@@ -1007,20 +1094,51 @@ void virtio_break_device(struct virtio_device *dev)
 }
 EXPORT_SYMBOL_GPL(virtio_break_device);
 
-void *virtqueue_get_avail(struct virtqueue *_vq)
+dma_addr_t virtqueue_get_desc_addr(struct virtqueue *_vq)
+{
+	struct vring_virtqueue *vq = to_vvq(_vq);
+
+	BUG_ON(!vq->we_own_ring);
+
+	if (vring_use_dma_api())
+		return vq->queue_dma_addr;
+	else
+		return virt_to_phys(vq->vring.desc);
+}
+EXPORT_SYMBOL_GPL(virtqueue_get_desc_addr);
+
+dma_addr_t virtqueue_get_avail_addr(struct virtqueue *_vq)
 {
 	struct vring_virtqueue *vq = to_vvq(_vq);
 
-	return vq->vring.avail;
+	BUG_ON(!vq->we_own_ring);
+
+	if (vring_use_dma_api())
+		return vq->queue_dma_addr +
+			((char *)vq->vring.avail - (char *)vq->vring.desc);
+	else
+		return virt_to_phys(vq->vring.avail);
 }
-EXPORT_SYMBOL_GPL(virtqueue_get_avail);
+EXPORT_SYMBOL_GPL(virtqueue_get_avail_addr);
 
-void *virtqueue_get_used(struct virtqueue *_vq)
+dma_addr_t virtqueue_get_used_addr(struct virtqueue *_vq)
 {
 	struct vring_virtqueue *vq = to_vvq(_vq);
 
-	return vq->vring.used;
+	BUG_ON(!vq->we_own_ring);
+
+	if (vring_use_dma_api())
+		return vq->queue_dma_addr +
+			((char *)vq->vring.used - (char *)vq->vring.desc);
+	else
+		return virt_to_phys(vq->vring.used);
+}
+EXPORT_SYMBOL_GPL(virtqueue_get_used_addr);
+
+const struct vring *virtqueue_get_vring(struct virtqueue *vq)
+{
+	return &to_vvq(vq)->vring;
 }
-EXPORT_SYMBOL_GPL(virtqueue_get_used);
+EXPORT_SYMBOL_GPL(virtqueue_get_vring);
 
 MODULE_LICENSE("GPL");
include/linux/virtio.h +21 -2
index 8f4d4bfa6d46..d5eb5479a425 100644
@@ -75,8 +75,27 @@ unsigned int virtqueue_get_vring_size(struct virtqueue *vq);
 
 bool virtqueue_is_broken(struct virtqueue *vq);
 
-void *virtqueue_get_avail(struct virtqueue *vq);
-void *virtqueue_get_used(struct virtqueue *vq);
+const struct vring *virtqueue_get_vring(struct virtqueue *vq);
+dma_addr_t virtqueue_get_desc_addr(struct virtqueue *vq);
+dma_addr_t virtqueue_get_avail_addr(struct virtqueue *vq);
+dma_addr_t virtqueue_get_used_addr(struct virtqueue *vq);
+
+/*
+ * Legacy accessors -- in almost all cases, these are the wrong functions
+ * to use.
+ */
+static inline void *virtqueue_get_desc(struct virtqueue *vq)
+{
+	return virtqueue_get_vring(vq)->desc;
+}
+static inline void *virtqueue_get_avail(struct virtqueue *vq)
+{
+	return virtqueue_get_vring(vq)->avail;
+}
+static inline void *virtqueue_get_used(struct virtqueue *vq)
+{
+	return virtqueue_get_vring(vq)->used;
+}
 
 /**
  * virtio_device - representation of a device using virtio
include/linux/virtio_ring.h +35 -0
index a156e2b6ccfe..e8d36938f09a 100644
@@ -59,6 +59,35 @@ static inline void virtio_store_mb(bool weak_barriers,
 struct virtio_device;
 struct virtqueue;
 
+/*
+ * Creates a virtqueue and allocates the descriptor ring.  If
+ * may_reduce_num is set, then this may allocate a smaller ring than
+ * expected.  The caller should query virtqueue_get_ring_size to learn
+ * the actual size of the ring.
+ */
+struct virtqueue *vring_create_virtqueue(unsigned int index,
+					 unsigned int num,
+					 unsigned int vring_align,
+					 struct virtio_device *vdev,
+					 bool weak_barriers,
+					 bool may_reduce_num,
+					 bool (*notify)(struct virtqueue *vq),
+					 void (*callback)(struct virtqueue *vq),
+					 const char *name);
+
+/* Creates a virtqueue with a custom layout. */
+struct virtqueue *__vring_new_virtqueue(unsigned int index,
+					struct vring vring,
+					struct virtio_device *vdev,
+					bool weak_barriers,
+					bool (*notify)(struct virtqueue *),
+					void (*callback)(struct virtqueue *),
+					const char *name);
+
+/*
+ * Creates a virtqueue with a standard layout but a caller-allocated
+ * ring.
+ */
 struct virtqueue *vring_new_virtqueue(unsigned int index,
 				      unsigned int num,
 				      unsigned int vring_align,
@@ -68,7 +97,13 @@ struct virtqueue *vring_new_virtqueue(unsigned int index,
 				      bool (*notify)(struct virtqueue *vq),
 				      void (*callback)(struct virtqueue *vq),
 				      const char *name);
+
+/*
+ * Destroys a virtqueue.  If created with vring_create_virtqueue, this
+ * also frees the ring.
+ */
 void vring_del_virtqueue(struct virtqueue *vq);
+
 /* Filter out transport-specific feature bits. */
 void vring_transport_features(struct virtio_device *vdev);
 
Signature · 1 line
2.5.0
#24 lore raw

PATCH v5 7/10 virtio_mmio: Use the DMA API if enabled

In reply to Andy Lutomirski

This switches to vring_create_virtqueue, simplifying the driver and adding DMA API support.

---
 drivers/virtio/virtio_mmio.c | 67 ++++++++++----------------------------------
 1 file changed, 15 insertions(+), 52 deletions(-)
drivers/virtio/virtio_mmio.c +15 -52
index 745c6ee1bb3e..48bfea91dbca 100644
@@ -99,12 +99,6 @@ struct virtio_mmio_vq_info {
 	/* the actual virtqueue */
 	struct virtqueue *vq;
 
-	/* the number of entries in the queue */
-	unsigned int num;
-
-	/* the virtual address of the ring queue */
-	void *queue;
-
 	/* the list node for the virtqueues list */
 	struct list_head node;
 };
@@ -322,15 +316,13 @@ static void vm_del_vq(struct virtqueue *vq)
 {
 	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev);
 	struct virtio_mmio_vq_info *info = vq->priv;
-	unsigned long flags, size;
+	unsigned long flags;
 	unsigned int index = vq->index;
 
 	spin_lock_irqsave(&vm_dev->lock, flags);
 	list_del(&info->node);
 	spin_unlock_irqrestore(&vm_dev->lock, flags);
 
-	vring_del_virtqueue(vq);
-
 	/* Select and deactivate the queue */
 	writel(index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL);
 	if (vm_dev->version == 1) {
@@ -340,8 +332,8 @@ static void vm_del_vq(struct virtqueue *vq)
 		WARN_ON(readl(vm_dev->base + VIRTIO_MMIO_QUEUE_READY));
 	}
 
-	size = PAGE_ALIGN(vring_size(info->num, VIRTIO_MMIO_VRING_ALIGN));
-	free_pages_exact(info->queue, size);
+	vring_del_virtqueue(vq);
+
 	kfree(info);
 }
 
@@ -356,8 +348,6 @@ static void vm_del_vqs(struct virtio_device *vdev)
 	free_irq(platform_get_irq(vm_dev->pdev, 0), vm_dev);
 }
 
-
-
 static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
 				  void (*callback)(struct virtqueue *vq),
 				  const char *name)
@@ -365,7 +355,8 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
 	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
 	struct virtio_mmio_vq_info *info;
 	struct virtqueue *vq;
-	unsigned long flags, size;
+	unsigned long flags;
+	unsigned int num;
 	int err;
 
 	if (!name)
@@ -388,66 +379,40 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
 		goto error_kmalloc;
 	}
 
-	/* Allocate pages for the queue - start with a queue as big as
-	 * possible (limited by maximum size allowed by device), drop down
-	 * to a minimal size, just big enough to fit descriptor table
-	 * and two rings (which makes it "alignment_size * 2")
-	 */
-	info->num = readl(vm_dev->base + VIRTIO_MMIO_QUEUE_NUM_MAX);
-
-	/* If the device reports a 0 entry queue, we won't be able to
-	 * use it to perform I/O, and vring_new_virtqueue() can't create
-	 * empty queues anyway, so don't bother to set up the device.
-	 */
-	if (info->num == 0) {
+	num = readl(vm_dev->base + VIRTIO_MMIO_QUEUE_NUM_MAX);
+	if (num == 0) {
 		err = -ENOENT;
-		goto error_alloc_pages;
-	}
-
-	while (1) {
-		size = PAGE_ALIGN(vring_size(info->num,
-				VIRTIO_MMIO_VRING_ALIGN));
-		/* Did the last iter shrink the queue below minimum size? */
-		if (size < VIRTIO_MMIO_VRING_ALIGN * 2) {
-			err = -ENOMEM;
-			goto error_alloc_pages;
-		}
-
-		info->queue = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
-		if (info->queue)
-			break;
-
-		info->num /= 2;
+		goto error_new_virtqueue;
 	}
 
 	/* Create the vring */
-	vq = vring_new_virtqueue(index, info->num, VIRTIO_MMIO_VRING_ALIGN, vdev,
-				 true, info->queue, vm_notify, callback, name);
+	vq = vring_create_virtqueue(index, num, VIRTIO_MMIO_VRING_ALIGN, vdev,
+				 true, true, vm_notify, callback, name);
 	if (!vq) {
 		err = -ENOMEM;
 		goto error_new_virtqueue;
 	}
 
 	/* Activate the queue */
-	writel(info->num, vm_dev->base + VIRTIO_MMIO_QUEUE_NUM);
+	writel(virtqueue_get_vring_size(vq), vm_dev->base + VIRTIO_MMIO_QUEUE_NUM);
 	if (vm_dev->version == 1) {
 		writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_QUEUE_ALIGN);
-		writel(virt_to_phys(info->queue) >> PAGE_SHIFT,
+		writel(virtqueue_get_desc_addr(vq) >> PAGE_SHIFT,
 				vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
 	} else {
 		u64 addr;
 
-		addr = virt_to_phys(info->queue);
+		addr = virtqueue_get_desc_addr(vq);
 		writel((u32)addr, vm_dev->base + VIRTIO_MMIO_QUEUE_DESC_LOW);
 		writel((u32)(addr >> 32),
 				vm_dev->base + VIRTIO_MMIO_QUEUE_DESC_HIGH);
 
-		addr = virt_to_phys(virtqueue_get_avail(vq));
+		addr = virtqueue_get_avail_addr(vq);
 		writel((u32)addr, vm_dev->base + VIRTIO_MMIO_QUEUE_AVAIL_LOW);
 		writel((u32)(addr >> 32),
 				vm_dev->base + VIRTIO_MMIO_QUEUE_AVAIL_HIGH);
 
-		addr = virt_to_phys(virtqueue_get_used(vq));
+		addr = virtqueue_get_used_addr(vq);
 		writel((u32)addr, vm_dev->base + VIRTIO_MMIO_QUEUE_USED_LOW);
 		writel((u32)(addr >> 32),
 				vm_dev->base + VIRTIO_MMIO_QUEUE_USED_HIGH);
@@ -471,8 +436,6 @@ error_new_virtqueue:
 		writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_READY);
 		WARN_ON(readl(vm_dev->base + VIRTIO_MMIO_QUEUE_READY));
 	}
-	free_pages_exact(info->queue, size);
-error_alloc_pages:
 	kfree(info);
 error_kmalloc:
 error_available:
Signature · 1 line
2.5.0
#25 lore raw

PATCH v5 7/10 virtio_mmio: Use the DMA API if enabled

In reply to Andy Lutomirski

This switches to vring_create_virtqueue, simplifying the driver and adding DMA API support.

---
 drivers/virtio/virtio_mmio.c | 67 ++++++++++----------------------------------
 1 file changed, 15 insertions(+), 52 deletions(-)
drivers/virtio/virtio_mmio.c +15 -52
index 745c6ee1bb3e..48bfea91dbca 100644
@@ -99,12 +99,6 @@ struct virtio_mmio_vq_info {
 	/* the actual virtqueue */
 	struct virtqueue *vq;
 
-	/* the number of entries in the queue */
-	unsigned int num;
-
-	/* the virtual address of the ring queue */
-	void *queue;
-
 	/* the list node for the virtqueues list */
 	struct list_head node;
 };
@@ -322,15 +316,13 @@ static void vm_del_vq(struct virtqueue *vq)
 {
 	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev);
 	struct virtio_mmio_vq_info *info = vq->priv;
-	unsigned long flags, size;
+	unsigned long flags;
 	unsigned int index = vq->index;
 
 	spin_lock_irqsave(&vm_dev->lock, flags);
 	list_del(&info->node);
 	spin_unlock_irqrestore(&vm_dev->lock, flags);
 
-	vring_del_virtqueue(vq);
-
 	/* Select and deactivate the queue */
 	writel(index, vm_dev->base + VIRTIO_MMIO_QUEUE_SEL);
 	if (vm_dev->version == 1) {
@@ -340,8 +332,8 @@ static void vm_del_vq(struct virtqueue *vq)
 		WARN_ON(readl(vm_dev->base + VIRTIO_MMIO_QUEUE_READY));
 	}
 
-	size = PAGE_ALIGN(vring_size(info->num, VIRTIO_MMIO_VRING_ALIGN));
-	free_pages_exact(info->queue, size);
+	vring_del_virtqueue(vq);
+
 	kfree(info);
 }
 
@@ -356,8 +348,6 @@ static void vm_del_vqs(struct virtio_device *vdev)
 	free_irq(platform_get_irq(vm_dev->pdev, 0), vm_dev);
 }
 
-
-
 static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
 				  void (*callback)(struct virtqueue *vq),
 				  const char *name)
@@ -365,7 +355,8 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
 	struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
 	struct virtio_mmio_vq_info *info;
 	struct virtqueue *vq;
-	unsigned long flags, size;
+	unsigned long flags;
+	unsigned int num;
 	int err;
 
 	if (!name)
@@ -388,66 +379,40 @@ static struct virtqueue *vm_setup_vq(struct virtio_device *vdev, unsigned index,
 		goto error_kmalloc;
 	}
 
-	/* Allocate pages for the queue - start with a queue as big as
-	 * possible (limited by maximum size allowed by device), drop down
-	 * to a minimal size, just big enough to fit descriptor table
-	 * and two rings (which makes it "alignment_size * 2")
-	 */
-	info->num = readl(vm_dev->base + VIRTIO_MMIO_QUEUE_NUM_MAX);
-
-	/* If the device reports a 0 entry queue, we won't be able to
-	 * use it to perform I/O, and vring_new_virtqueue() can't create
-	 * empty queues anyway, so don't bother to set up the device.
-	 */
-	if (info->num == 0) {
+	num = readl(vm_dev->base + VIRTIO_MMIO_QUEUE_NUM_MAX);
+	if (num == 0) {
 		err = -ENOENT;
-		goto error_alloc_pages;
-	}
-
-	while (1) {
-		size = PAGE_ALIGN(vring_size(info->num,
-				VIRTIO_MMIO_VRING_ALIGN));
-		/* Did the last iter shrink the queue below minimum size? */
-		if (size < VIRTIO_MMIO_VRING_ALIGN * 2) {
-			err = -ENOMEM;
-			goto error_alloc_pages;
-		}
-
-		info->queue = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
-		if (info->queue)
-			break;
-
-		info->num /= 2;
+		goto error_new_virtqueue;
 	}
 
 	/* Create the vring */
-	vq = vring_new_virtqueue(index, info->num, VIRTIO_MMIO_VRING_ALIGN, vdev,
-				 true, info->queue, vm_notify, callback, name);
+	vq = vring_create_virtqueue(index, num, VIRTIO_MMIO_VRING_ALIGN, vdev,
+				 true, true, vm_notify, callback, name);
 	if (!vq) {
 		err = -ENOMEM;
 		goto error_new_virtqueue;
 	}
 
 	/* Activate the queue */
-	writel(info->num, vm_dev->base + VIRTIO_MMIO_QUEUE_NUM);
+	writel(virtqueue_get_vring_size(vq), vm_dev->base + VIRTIO_MMIO_QUEUE_NUM);
 	if (vm_dev->version == 1) {
 		writel(PAGE_SIZE, vm_dev->base + VIRTIO_MMIO_QUEUE_ALIGN);
-		writel(virt_to_phys(info->queue) >> PAGE_SHIFT,
+		writel(virtqueue_get_desc_addr(vq) >> PAGE_SHIFT,
 				vm_dev->base + VIRTIO_MMIO_QUEUE_PFN);
 	} else {
 		u64 addr;
 
-		addr = virt_to_phys(info->queue);
+		addr = virtqueue_get_desc_addr(vq);
 		writel((u32)addr, vm_dev->base + VIRTIO_MMIO_QUEUE_DESC_LOW);
 		writel((u32)(addr >> 32),
 				vm_dev->base + VIRTIO_MMIO_QUEUE_DESC_HIGH);
 
-		addr = virt_to_phys(virtqueue_get_avail(vq));
+		addr = virtqueue_get_avail_addr(vq);
 		writel((u32)addr, vm_dev->base + VIRTIO_MMIO_QUEUE_AVAIL_LOW);
 		writel((u32)(addr >> 32),
 				vm_dev->base + VIRTIO_MMIO_QUEUE_AVAIL_HIGH);
 
-		addr = virt_to_phys(virtqueue_get_used(vq));
+		addr = virtqueue_get_used_addr(vq);
 		writel((u32)addr, vm_dev->base + VIRTIO_MMIO_QUEUE_USED_LOW);
 		writel((u32)(addr >> 32),
 				vm_dev->base + VIRTIO_MMIO_QUEUE_USED_HIGH);
@@ -471,8 +436,6 @@ error_new_virtqueue:
 		writel(0, vm_dev->base + VIRTIO_MMIO_QUEUE_READY);
 		WARN_ON(readl(vm_dev->base + VIRTIO_MMIO_QUEUE_READY));
 	}
-	free_pages_exact(info->queue, size);
-error_alloc_pages:
 	kfree(info);
 error_kmalloc:
 error_available:
Signature · 1 line
2.5.0
#26 lore raw

PATCH v5 8/10 virtio_pci: Use the DMA API if enabled

In reply to Andy Lutomirski

This switches to vring_create_virtqueue, simplifying the driver and adding DMA API support.

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.

---
 drivers/virtio/virtio_pci_common.h |  6 ----
 drivers/virtio/virtio_pci_legacy.c | 42 +++++++++++---------------
 drivers/virtio/virtio_pci_modern.c | 61 ++++++++++----------------------------
 3 files changed, 33 insertions(+), 76 deletions(-)
drivers/virtio/virtio_pci_common.h +0 -6
index 2cc252270b2d..28263200ed42 100644
@@ -35,12 +35,6 @@ struct virtio_pci_vq_info {
 	/* the actual virtqueue */
 	struct virtqueue *vq;
 
-	/* the number of entries in the queue */
-	int num;
-
-	/* the virtual address of the ring queue */
-	void *queue;
-
 	/* the list node for the virtqueues list */
 	struct list_head node;
 
drivers/virtio/virtio_pci_legacy.c +17 -25

94 lines not on this page · raw message

drivers/virtio/virtio_pci_modern.c +16 -45

98 lines not on this page · raw message

Signature · 1 line
2.5.0
#27 lore raw

PATCH v5 8/10 virtio_pci: Use the DMA API if enabled

In reply to Andy Lutomirski

This switches to vring_create_virtqueue, simplifying the driver and adding DMA API support.

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.

---
 drivers/virtio/virtio_pci_common.h |  6 ----
 drivers/virtio/virtio_pci_legacy.c | 42 +++++++++++---------------
 drivers/virtio/virtio_pci_modern.c | 61 ++++++++++----------------------------
 3 files changed, 33 insertions(+), 76 deletions(-)
drivers/virtio/virtio_pci_common.h +0 -6
index 2cc252270b2d..28263200ed42 100644
@@ -35,12 +35,6 @@ struct virtio_pci_vq_info {
 	/* the actual virtqueue */
 	struct virtqueue *vq;
 
-	/* the number of entries in the queue */
-	int num;
-
-	/* the virtual address of the ring queue */
-	void *queue;
-
 	/* the list node for the virtqueues list */
 	struct list_head node;
 
drivers/virtio/virtio_pci_legacy.c +17 -25

94 lines not on this page · raw message

drivers/virtio/virtio_pci_modern.c +16 -45

98 lines not on this page · raw message

Signature · 1 line
2.5.0
#28 lore raw

PATCH v5 8/10 virtio_pci: Use the DMA API if enabled

In reply to Andy Lutomirski

This switches to vring_create_virtqueue, simplifying the driver and adding DMA API support.

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.

---
 drivers/virtio/virtio_pci_common.h |  6 ----
 drivers/virtio/virtio_pci_legacy.c | 42 +++++++++++---------------
 drivers/virtio/virtio_pci_modern.c | 61 ++++++++++----------------------------
 3 files changed, 33 insertions(+), 76 deletions(-)
drivers/virtio/virtio_pci_common.h +0 -6
index 2cc252270b2d..28263200ed42 100644
@@ -35,12 +35,6 @@ struct virtio_pci_vq_info {
 	/* the actual virtqueue */
 	struct virtqueue *vq;
 
-	/* the number of entries in the queue */
-	int num;
-
-	/* the virtual address of the ring queue */
-	void *queue;
-
 	/* the list node for the virtqueues list */
 	struct list_head node;
 
drivers/virtio/virtio_pci_legacy.c +17 -25

94 lines not on this page · raw message

drivers/virtio/virtio_pci_modern.c +16 -45

98 lines not on this page · raw message

Signature · 1 line
2.5.0
#29 lore raw

PATCH v5 9/10 vring: Use the DMA API on Xen

In reply to Andy Lutomirski
---
 drivers/virtio/virtio_ring.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/virtio/virtio_ring.c +12 -0
index c169c6444637..305c05cc249a 100644
@@ -47,6 +47,18 @@
 
 static bool vring_use_dma_api(void)
 {
+#if defined(CONFIG_X86) && defined(CONFIG_XEN)
+	/*
+	 * In theory, it's possible to have a buggy QEMU-supposed
+	 * emulated Q35 IOMMU and Xen enabled at the same time.  On
+	 * such a configuration, virtio has never worked and will
+	 * not work without an even larger kludge.  Instead, enable
+	 * the DMA API if we're a Xen guest, which at least allows
+	 * all of the sensible Xen configurations to work correctly.
+	 */
+	return static_cpu_has(X86_FEATURE_XENPV);
+#endif
+
 	return false;
 }
 
Signature · 1 line
2.5.0
#30 lore raw

Re: [Xen-devel] [PATCH v5 09/10] vring: Use the DMA API on Xen

Quoted 13 lines · Andy Lutomirski
---
 drivers/virtio/virtio_ring.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/virtio/virtio_ring.c +0 -0
index c169c6444637..305c05cc249a 100644
@@ -47,6 +47,18 @@
 
 static bool vring_use_dma_api(void)
 {

drivers/virtio/virtio_ring.c line 59

Quoted 10 lines
drivers/virtio/virtio_ring.c +10 -0
+#if defined(CONFIG_X86) && defined(CONFIG_XEN)
+	/*
+	 * In theory, it's possible to have a buggy QEMU-supposed
+	 * emulated Q35 IOMMU and Xen enabled at the same time.  On
+	 * such a configuration, virtio has never worked and will
+	 * not work without an even larger kludge.  Instead, enable
+	 * the DMA API if we're a Xen guest, which at least allows
+	 * all of the sensible Xen configurations to work correctly.
+	 */
+	return static_cpu_has(X86_FEATURE_XENPV);

You want:

    if (xen_domain())
        return true;

Without the #if so we use the DMA API for all types of Xen guest on all architectures.

David

#31 lore raw

Re: [Xen-devel] [PATCH v5 09/10] vring: Use the DMA API on Xen

Quoted 27 lines · David Vrabel
Quoted 13 lines · Andy Lutomirski
---
 drivers/virtio/virtio_ring.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/virtio/virtio_ring.c +0 -0
index c169c6444637..305c05cc249a 100644
@@ -47,6 +47,18 @@
 
 static bool vring_use_dma_api(void)
 {

drivers/virtio/virtio_ring.c line 59

Quoted 10 lines
drivers/virtio/virtio_ring.c +10 -0
+#if defined(CONFIG_X86) && defined(CONFIG_XEN)
+	/*
+	 * In theory, it's possible to have a buggy QEMU-supposed
+	 * emulated Q35 IOMMU and Xen enabled at the same time.  On
+	 * such a configuration, virtio has never worked and will
+	 * not work without an even larger kludge.  Instead, enable
+	 * the DMA API if we're a Xen guest, which at least allows
+	 * all of the sensible Xen configurations to work correctly.
+	 */
+	return static_cpu_has(X86_FEATURE_XENPV);

You want:

Quoted 7 lines
    if (xen_domain())
        return true;

Without the #if so we use the DMA API for all types of Xen guest on all architectures.

David

I doubt HVM domains can have virtio devices.

Signature · 1 line
MST
#32 lore raw

Re: [Xen-devel] [PATCH v5 09/10] vring: Use the DMA API on Xen

Quoted 31 lines · Michael S. Tsirkin
Quoted 30 lines · David Vrabel
Quoted 13 lines · Andy Lutomirski
---
 drivers/virtio/virtio_ring.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/virtio/virtio_ring.c +0 -0
index c169c6444637..305c05cc249a 100644
@@ -47,6 +47,18 @@
 
 static bool vring_use_dma_api(void)
 {

drivers/virtio/virtio_ring.c line 59

Quoted 10 lines
drivers/virtio/virtio_ring.c +10 -0
+#if defined(CONFIG_X86) && defined(CONFIG_XEN)
+   /*
+    * In theory, it's possible to have a buggy QEMU-supposed
+    * emulated Q35 IOMMU and Xen enabled at the same time.  On
+    * such a configuration, virtio has never worked and will
+    * not work without an even larger kludge.  Instead, enable
+    * the DMA API if we're a Xen guest, which at least allows
+    * all of the sensible Xen configurations to work correctly.
+    */
+   return static_cpu_has(X86_FEATURE_XENPV);

You want:

    if (xen_domain())
        return true;
Quoted 7 lines
Quoted 4 lines

Without the #if so we use the DMA API for all types of Xen guest on all architectures.

David

I doubt HVM domains can have virtio devices.

They certainly can under nested virt (L0 provides virtio device, L1 is Xen, and L2 is Linux). Of course, this won't work given the current QEMU situation unless Xen can pass things through to dom0 without an IOMMU, which seems plausible to me.

But yes, xen_domain() sounds right to me. I just failed to find that function when I wrote this patch.

Michael, if you like the rest of the series, I'd be okay if you changed this patch to use xen_domain() when you apply it. If I send a v2, I'll fix it up.

--Andy

#33 lore raw

Re: [Xen-devel] [PATCH v5 09/10] vring: Use the DMA API on Xen

Quoted 45 lines · Andy Lutomirski
Quoted 31 lines · Michael S. Tsirkin
Quoted 30 lines · David Vrabel
Quoted 13 lines · Andy Lutomirski
---
 drivers/virtio/virtio_ring.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/virtio/virtio_ring.c +0 -0
index c169c6444637..305c05cc249a 100644
@@ -47,6 +47,18 @@
 
 static bool vring_use_dma_api(void)
 {

drivers/virtio/virtio_ring.c line 59

Quoted 10 lines
drivers/virtio/virtio_ring.c +10 -0
+#if defined(CONFIG_X86) && defined(CONFIG_XEN)
+   /*
+    * In theory, it's possible to have a buggy QEMU-supposed
+    * emulated Q35 IOMMU and Xen enabled at the same time.  On
+    * such a configuration, virtio has never worked and will
+    * not work without an even larger kludge.  Instead, enable
+    * the DMA API if we're a Xen guest, which at least allows
+    * all of the sensible Xen configurations to work correctly.
+    */
+   return static_cpu_has(X86_FEATURE_XENPV);

You want:

    if (xen_domain())
        return true;
Quoted 7 lines
Quoted 4 lines

Without the #if so we use the DMA API for all types of Xen guest on all architectures.

David

I doubt HVM domains can have virtio devices.

They certainly can under nested virt (L0 provides virtio device, L1 is Xen, and L2 is Linux). Of course, this won't work given the current QEMU situation unless Xen can pass things through to dom0 without an IOMMU, which seems plausible to me.

Quoted 8 lines

But yes, xen_domain() sounds right to me. I just failed to find that function when I wrote this patch.

Michael, if you like the rest of the series, I'd be okay if you changed this patch to use xen_domain() when you apply it. If I send a v2, I'll fix it up.

--Andy

I'd rather you just posted a tested v2 of 9/10 for now as I don't test Xen. It seems easy but I had more than my share of obvious fixes failing spectacularly.

Signature · 1 line
MST
#34 lore raw

Re: [Xen-devel] [PATCH v5 09/10] vring: Use the DMA API on Xen

Quoted 53 lines · Michael S. Tsirkin
Quoted 52 lines · Andy Lutomirski
Quoted 31 lines · Michael S. Tsirkin
Quoted 30 lines · David Vrabel
Quoted 13 lines · Andy Lutomirski
---
 drivers/virtio/virtio_ring.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/virtio/virtio_ring.c +0 -0
index c169c6444637..305c05cc249a 100644
@@ -47,6 +47,18 @@
 
 static bool vring_use_dma_api(void)
 {

drivers/virtio/virtio_ring.c line 59

Quoted 10 lines
drivers/virtio/virtio_ring.c +10 -0
+#if defined(CONFIG_X86) && defined(CONFIG_XEN)
+   /*
+    * In theory, it's possible to have a buggy QEMU-supposed
+    * emulated Q35 IOMMU and Xen enabled at the same time.  On
+    * such a configuration, virtio has never worked and will
+    * not work without an even larger kludge.  Instead, enable
+    * the DMA API if we're a Xen guest, which at least allows
+    * all of the sensible Xen configurations to work correctly.
+    */
+   return static_cpu_has(X86_FEATURE_XENPV);

You want:

    if (xen_domain())
        return true;
Quoted 7 lines
Quoted 4 lines

Without the #if so we use the DMA API for all types of Xen guest on all architectures.

David

I doubt HVM domains can have virtio devices.

They certainly can under nested virt (L0 provides virtio device, L1 is Xen, and L2 is Linux). Of course, this won't work given the current QEMU situation unless Xen can pass things through to dom0 without an IOMMU, which seems plausible to me.

But yes, xen_domain() sounds right to me. I just failed to find that function when I wrote this patch.

Michael, if you like the rest of the series, I'd be okay if you changed this patch to use xen_domain() when you apply it. If I send a v2, I'll fix it up.

Quoted 6 lines
Quoted 1 line

--Andy

I'd rather you just posted a tested v2 of 9/10 for now as I don't test Xen. It seems easy but I had more than my share of obvious fixes failing spectacularly.

In that case, let me test for real. Can you point me to a git tree when you have patches 1-8 staged and I'll spin patch 9 v2 and test it with the real context?

--Andy

#35 lore raw

Re: [Xen-devel] [PATCH v5 09/10] vring: Use the DMA API on Xen

In reply to Michael S. Tsirkin
Quoted 53 lines · Michael S. Tsirkin
Quoted 52 lines · Andy Lutomirski
Quoted 31 lines · Michael S. Tsirkin
Quoted 30 lines · David Vrabel
Quoted 13 lines · Andy Lutomirski
---
 drivers/virtio/virtio_ring.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/virtio/virtio_ring.c +0 -0
index c169c6444637..305c05cc249a 100644
@@ -47,6 +47,18 @@
 
 static bool vring_use_dma_api(void)
 {

drivers/virtio/virtio_ring.c line 59

Quoted 10 lines
drivers/virtio/virtio_ring.c +10 -0
+#if defined(CONFIG_X86) && defined(CONFIG_XEN)
+   /*
+    * In theory, it's possible to have a buggy QEMU-supposed
+    * emulated Q35 IOMMU and Xen enabled at the same time.  On
+    * such a configuration, virtio has never worked and will
+    * not work without an even larger kludge.  Instead, enable
+    * the DMA API if we're a Xen guest, which at least allows
+    * all of the sensible Xen configurations to work correctly.
+    */
+   return static_cpu_has(X86_FEATURE_XENPV);

You want:

    if (xen_domain())
        return true;
Quoted 7 lines
Quoted 4 lines

Without the #if so we use the DMA API for all types of Xen guest on all architectures.

David

I doubt HVM domains can have virtio devices.

They certainly can under nested virt (L0 provides virtio device, L1 is Xen, and L2 is Linux). Of course, this won't work given the current QEMU situation unless Xen can pass things through to dom0 without an IOMMU, which seems plausible to me.

But yes, xen_domain() sounds right to me. I just failed to find that function when I wrote this patch.

Michael, if you like the rest of the series, I'd be okay if you changed this patch to use xen_domain() when you apply it. If I send a v2, I'll fix it up.

Quoted 6 lines
Quoted 1 line

--Andy

I'd rather you just posted a tested v2 of 9/10 for now as I don't test Xen. It seems easy but I had more than my share of obvious fixes failing spectacularly.

In that case, let me test for real. Can you point me to a git tree when you have patches 1-8 staged and I'll spin patch 9 v2 and test it with the real context?

--Andy

#36 lore raw

Re: [PATCH v5 09/10] vring: Use the DMA API on Xen

In reply to Michael S. Tsirkin
Quoted 53 lines · Michael S. Tsirkin
Quoted 52 lines · Andy Lutomirski
Quoted 31 lines · Michael S. Tsirkin
Quoted 30 lines · David Vrabel
Quoted 13 lines · Andy Lutomirski
---
 drivers/virtio/virtio_ring.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/virtio/virtio_ring.c +0 -0
index c169c6444637..305c05cc249a 100644
@@ -47,6 +47,18 @@
 
 static bool vring_use_dma_api(void)
 {

drivers/virtio/virtio_ring.c line 59

Quoted 10 lines
drivers/virtio/virtio_ring.c +10 -0
+#if defined(CONFIG_X86) && defined(CONFIG_XEN)
+   /*
+    * In theory, it's possible to have a buggy QEMU-supposed
+    * emulated Q35 IOMMU and Xen enabled at the same time.  On
+    * such a configuration, virtio has never worked and will
+    * not work without an even larger kludge.  Instead, enable
+    * the DMA API if we're a Xen guest, which at least allows
+    * all of the sensible Xen configurations to work correctly.
+    */
+   return static_cpu_has(X86_FEATURE_XENPV);

You want:

    if (xen_domain())
        return true;
Quoted 7 lines
Quoted 4 lines

Without the #if so we use the DMA API for all types of Xen guest on all architectures.

David

I doubt HVM domains can have virtio devices.

They certainly can under nested virt (L0 provides virtio device, L1 is Xen, and L2 is Linux). Of course, this won't work given the current QEMU situation unless Xen can pass things through to dom0 without an IOMMU, which seems plausible to me.

But yes, xen_domain() sounds right to me. I just failed to find that function when I wrote this patch.

Michael, if you like the rest of the series, I'd be okay if you changed this patch to use xen_domain() when you apply it. If I send a v2, I'll fix it up.

Quoted 6 lines
Quoted 1 line

--Andy

I'd rather you just posted a tested v2 of 9/10 for now as I don't test Xen. It seems easy but I had more than my share of obvious fixes failing spectacularly.

In that case, let me test for real. Can you point me to a git tree when you have patches 1-8 staged and I'll spin patch 9 v2 and test it with the real context?

--Andy

#37 lore raw

Re: [PATCH v5 09/10] vring: Use the DMA API on Xen

In reply to Andy Lutomirski
Quoted 45 lines · Andy Lutomirski
Quoted 31 lines · Michael S. Tsirkin
Quoted 30 lines · David Vrabel
Quoted 13 lines · Andy Lutomirski
---
 drivers/virtio/virtio_ring.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/virtio/virtio_ring.c +0 -0
index c169c6444637..305c05cc249a 100644
@@ -47,6 +47,18 @@
 
 static bool vring_use_dma_api(void)
 {

drivers/virtio/virtio_ring.c line 59

Quoted 10 lines
drivers/virtio/virtio_ring.c +10 -0
+#if defined(CONFIG_X86) && defined(CONFIG_XEN)
+   /*
+    * In theory, it's possible to have a buggy QEMU-supposed
+    * emulated Q35 IOMMU and Xen enabled at the same time.  On
+    * such a configuration, virtio has never worked and will
+    * not work without an even larger kludge.  Instead, enable
+    * the DMA API if we're a Xen guest, which at least allows
+    * all of the sensible Xen configurations to work correctly.
+    */
+   return static_cpu_has(X86_FEATURE_XENPV);

You want:

    if (xen_domain())
        return true;
Quoted 7 lines
Quoted 4 lines

Without the #if so we use the DMA API for all types of Xen guest on all architectures.

David

I doubt HVM domains can have virtio devices.

They certainly can under nested virt (L0 provides virtio device, L1 is Xen, and L2 is Linux). Of course, this won't work given the current QEMU situation unless Xen can pass things through to dom0 without an IOMMU, which seems plausible to me.

Quoted 8 lines

But yes, xen_domain() sounds right to me. I just failed to find that function when I wrote this patch.

Michael, if you like the rest of the series, I'd be okay if you changed this patch to use xen_domain() when you apply it. If I send a v2, I'll fix it up.

--Andy

I'd rather you just posted a tested v2 of 9/10 for now as I don't test Xen. It seems easy but I had more than my share of obvious fixes failing spectacularly.

Signature · 1 line
MST
#38 lore raw

Re: [PATCH v5 09/10] vring: Use the DMA API on Xen

In reply to Michael S. Tsirkin
Quoted 31 lines · Michael S. Tsirkin
Quoted 30 lines · David Vrabel
Quoted 13 lines · Andy Lutomirski
---
 drivers/virtio/virtio_ring.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/virtio/virtio_ring.c +0 -0
index c169c6444637..305c05cc249a 100644
@@ -47,6 +47,18 @@
 
 static bool vring_use_dma_api(void)
 {

drivers/virtio/virtio_ring.c line 59

Quoted 10 lines
drivers/virtio/virtio_ring.c +10 -0
+#if defined(CONFIG_X86) && defined(CONFIG_XEN)
+   /*
+    * In theory, it's possible to have a buggy QEMU-supposed
+    * emulated Q35 IOMMU and Xen enabled at the same time.  On
+    * such a configuration, virtio has never worked and will
+    * not work without an even larger kludge.  Instead, enable
+    * the DMA API if we're a Xen guest, which at least allows
+    * all of the sensible Xen configurations to work correctly.
+    */
+   return static_cpu_has(X86_FEATURE_XENPV);

You want:

    if (xen_domain())
        return true;
Quoted 7 lines
Quoted 4 lines

Without the #if so we use the DMA API for all types of Xen guest on all architectures.

David

I doubt HVM domains can have virtio devices.

They certainly can under nested virt (L0 provides virtio device, L1 is Xen, and L2 is Linux). Of course, this won't work given the current QEMU situation unless Xen can pass things through to dom0 without an IOMMU, which seems plausible to me.

But yes, xen_domain() sounds right to me. I just failed to find that function when I wrote this patch.

Michael, if you like the rest of the series, I'd be okay if you changed this patch to use xen_domain() when you apply it. If I send a v2, I'll fix it up.

--Andy

#39 lore raw

Re: [Xen-devel] [PATCH v5 09/10] vring: Use the DMA API on Xen

In reply to Michael S. Tsirkin
Quoted 31 lines · Michael S. Tsirkin
Quoted 30 lines · David Vrabel
Quoted 13 lines · Andy Lutomirski
---
 drivers/virtio/virtio_ring.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/virtio/virtio_ring.c +0 -0
index c169c6444637..305c05cc249a 100644
@@ -47,6 +47,18 @@
 
 static bool vring_use_dma_api(void)
 {

drivers/virtio/virtio_ring.c line 59

Quoted 10 lines
drivers/virtio/virtio_ring.c +10 -0
+#if defined(CONFIG_X86) && defined(CONFIG_XEN)
+	/*
+	 * In theory, it's possible to have a buggy QEMU-supposed
+	 * emulated Q35 IOMMU and Xen enabled at the same time.  On
+	 * such a configuration, virtio has never worked and will
+	 * not work without an even larger kludge.  Instead, enable
+	 * the DMA API if we're a Xen guest, which at least allows
+	 * all of the sensible Xen configurations to work correctly.
+	 */
+	return static_cpu_has(X86_FEATURE_XENPV);

You want:

    if (xen_domain())
        return true;
Quoted 7 lines
Quoted 4 lines

Without the #if so we use the DMA API for all types of Xen guest on all architectures.

David

I doubt HVM domains can have virtio devices.

Yes, they can.

When virtio-pci is used virtio device is just yet another pci device emulated by QEMU.

Wei.

Quoted 7 lines
Signature · 6 lines
MST

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#40 lore raw

Re: [PATCH v5 09/10] vring: Use the DMA API on Xen

In reply to Michael S. Tsirkin
Quoted 31 lines · Michael S. Tsirkin
Quoted 30 lines · David Vrabel
Quoted 13 lines · Andy Lutomirski
---
 drivers/virtio/virtio_ring.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/virtio/virtio_ring.c +0 -0
index c169c6444637..305c05cc249a 100644
@@ -47,6 +47,18 @@
 
 static bool vring_use_dma_api(void)
 {

drivers/virtio/virtio_ring.c line 59

Quoted 10 lines
drivers/virtio/virtio_ring.c +10 -0
+#if defined(CONFIG_X86) && defined(CONFIG_XEN)
+	/*
+	 * In theory, it's possible to have a buggy QEMU-supposed
+	 * emulated Q35 IOMMU and Xen enabled at the same time.  On
+	 * such a configuration, virtio has never worked and will
+	 * not work without an even larger kludge.  Instead, enable
+	 * the DMA API if we're a Xen guest, which at least allows
+	 * all of the sensible Xen configurations to work correctly.
+	 */
+	return static_cpu_has(X86_FEATURE_XENPV);

You want:

    if (xen_domain())
        return true;
Quoted 7 lines
Quoted 4 lines

Without the #if so we use the DMA API for all types of Xen guest on all architectures.

David

I doubt HVM domains can have virtio devices.

Yes, they can.

When virtio-pci is used virtio device is just yet another pci device emulated by QEMU.

Wei.

Quoted 7 lines
Signature · 6 lines
MST

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#41 lore raw

Re: [PATCH v5 09/10] vring: Use the DMA API on Xen

In reply to David Vrabel
Quoted 27 lines · David Vrabel
Quoted 13 lines · Andy Lutomirski
---
 drivers/virtio/virtio_ring.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/virtio/virtio_ring.c +0 -0
index c169c6444637..305c05cc249a 100644
@@ -47,6 +47,18 @@
 
 static bool vring_use_dma_api(void)
 {

drivers/virtio/virtio_ring.c line 59

Quoted 10 lines
drivers/virtio/virtio_ring.c +10 -0
+#if defined(CONFIG_X86) && defined(CONFIG_XEN)
+	/*
+	 * In theory, it's possible to have a buggy QEMU-supposed
+	 * emulated Q35 IOMMU and Xen enabled at the same time.  On
+	 * such a configuration, virtio has never worked and will
+	 * not work without an even larger kludge.  Instead, enable
+	 * the DMA API if we're a Xen guest, which at least allows
+	 * all of the sensible Xen configurations to work correctly.
+	 */
+	return static_cpu_has(X86_FEATURE_XENPV);

You want:

Quoted 7 lines
    if (xen_domain())
        return true;

Without the #if so we use the DMA API for all types of Xen guest on all architectures.

David

I doubt HVM domains can have virtio devices.

Signature · 1 line
MST
#42 lore raw

Re: [Xen-devel] [PATCH v5 09/10] vring: Use the DMA API on Xen

In reply to Andy Lutomirski
Quoted 13 lines · Andy Lutomirski
---
 drivers/virtio/virtio_ring.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/virtio/virtio_ring.c +0 -0
index c169c6444637..305c05cc249a 100644
@@ -47,6 +47,18 @@
 
 static bool vring_use_dma_api(void)
 {

drivers/virtio/virtio_ring.c line 59

Quoted 10 lines
drivers/virtio/virtio_ring.c +10 -0
+#if defined(CONFIG_X86) && defined(CONFIG_XEN)
+	/*
+	 * In theory, it's possible to have a buggy QEMU-supposed
+	 * emulated Q35 IOMMU and Xen enabled at the same time.  On
+	 * such a configuration, virtio has never worked and will
+	 * not work without an even larger kludge.  Instead, enable
+	 * the DMA API if we're a Xen guest, which at least allows
+	 * all of the sensible Xen configurations to work correctly.
+	 */
+	return static_cpu_has(X86_FEATURE_XENPV);

You want:

    if (xen_domain())
        return true;

Without the #if so we use the DMA API for all types of Xen guest on all architectures.

David

#43 lore raw

Re: [PATCH v5 09/10] vring: Use the DMA API on Xen

In reply to Andy Lutomirski
Quoted 13 lines · Andy Lutomirski
---
 drivers/virtio/virtio_ring.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/virtio/virtio_ring.c +0 -0
index c169c6444637..305c05cc249a 100644
@@ -47,6 +47,18 @@
 
 static bool vring_use_dma_api(void)
 {

drivers/virtio/virtio_ring.c line 59

Quoted 10 lines
drivers/virtio/virtio_ring.c +10 -0
+#if defined(CONFIG_X86) && defined(CONFIG_XEN)
+	/*
+	 * In theory, it's possible to have a buggy QEMU-supposed
+	 * emulated Q35 IOMMU and Xen enabled at the same time.  On
+	 * such a configuration, virtio has never worked and will
+	 * not work without an even larger kludge.  Instead, enable
+	 * the DMA API if we're a Xen guest, which at least allows
+	 * all of the sensible Xen configurations to work correctly.
+	 */
+	return static_cpu_has(X86_FEATURE_XENPV);

You want:

    if (xen_domain())
        return true;

Without the #if so we use the DMA API for all types of Xen guest on all architectures.

David

#44 lore raw

PATCH v5 9/10 vring: Use the DMA API on Xen

In reply to Andy Lutomirski
---
 drivers/virtio/virtio_ring.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/virtio/virtio_ring.c +12 -0
index c169c6444637..305c05cc249a 100644
@@ -47,6 +47,18 @@
 
 static bool vring_use_dma_api(void)
 {
+#if defined(CONFIG_X86) && defined(CONFIG_XEN)
+	/*
+	 * In theory, it's possible to have a buggy QEMU-supposed
+	 * emulated Q35 IOMMU and Xen enabled at the same time.  On
+	 * such a configuration, virtio has never worked and will
+	 * not work without an even larger kludge.  Instead, enable
+	 * the DMA API if we're a Xen guest, which at least allows
+	 * all of the sensible Xen configurations to work correctly.
+	 */
+	return static_cpu_has(X86_FEATURE_XENPV);
+#endif
+
 	return false;
 }
 
Signature · 1 line
2.5.0
#45 lore raw

PATCH v5 9/10 vring: Use the DMA API on Xen

In reply to Andy Lutomirski
---
 drivers/virtio/virtio_ring.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
drivers/virtio/virtio_ring.c +12 -0
index c169c6444637..305c05cc249a 100644
@@ -47,6 +47,18 @@
 
 static bool vring_use_dma_api(void)
 {
+#if defined(CONFIG_X86) && defined(CONFIG_XEN)
+	/*
+	 * In theory, it's possible to have a buggy QEMU-supposed
+	 * emulated Q35 IOMMU and Xen enabled at the same time.  On
+	 * such a configuration, virtio has never worked and will
+	 * not work without an even larger kludge.  Instead, enable
+	 * the DMA API if we're a Xen guest, which at least allows
+	 * all of the sensible Xen configurations to work correctly.
+	 */
+	return static_cpu_has(X86_FEATURE_XENPV);
+#endif
+
 	return false;
 }
 
Signature · 1 line
2.5.0
#46 lore raw

PATCH v5 10/10 vring: Add a module parameter to force-enable the DMA API

In reply to Andy Lutomirski

This will be useful for testing.

---
 drivers/virtio/virtio_ring.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/virtio/virtio_ring.c +5 -1
index 305c05cc249a..46fb77d824e9 100644
@@ -45,6 +45,10 @@
  * API.
  */
 
+static bool force_dma_api = false;
+module_param(force_dma_api, bool, 0644);
+MODULE_PARM_DESC(force_dma_api, "force-enable the DMA API");
+
 static bool vring_use_dma_api(void)
 {
 #if defined(CONFIG_X86) && defined(CONFIG_XEN)
@@ -59,7 +63,7 @@ static bool vring_use_dma_api(void)
 	return static_cpu_has(X86_FEATURE_XENPV);
 #endif
 
-	return false;
+	return force_dma_api;
 }
 
 #ifdef DEBUG
Signature · 1 line
2.5.0
#47 lore raw

PATCH v5 10/10 vring: Add a module parameter to force-enable the DMA API

In reply to Andy Lutomirski

This will be useful for testing.

---
 drivers/virtio/virtio_ring.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/virtio/virtio_ring.c +5 -1
index 305c05cc249a..46fb77d824e9 100644
@@ -45,6 +45,10 @@
  * API.
  */
 
+static bool force_dma_api = false;
+module_param(force_dma_api, bool, 0644);
+MODULE_PARM_DESC(force_dma_api, "force-enable the DMA API");
+
 static bool vring_use_dma_api(void)
 {
 #if defined(CONFIG_X86) && defined(CONFIG_XEN)
@@ -59,7 +63,7 @@ static bool vring_use_dma_api(void)
 	return static_cpu_has(X86_FEATURE_XENPV);
 #endif
 
-	return false;
+	return force_dma_api;
 }
 
 #ifdef DEBUG
Signature · 1 line
2.5.0
#48 lore raw

PATCH v5 10/10 vring: Add a module parameter to force-enable the DMA API

In reply to Andy Lutomirski

This will be useful for testing.

---
 drivers/virtio/virtio_ring.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/virtio/virtio_ring.c +5 -1
index 305c05cc249a..46fb77d824e9 100644
@@ -45,6 +45,10 @@
  * API.
  */
 
+static bool force_dma_api = false;
+module_param(force_dma_api, bool, 0644);
+MODULE_PARM_DESC(force_dma_api, "force-enable the DMA API");
+
 static bool vring_use_dma_api(void)
 {
 #if defined(CONFIG_X86) && defined(CONFIG_XEN)
@@ -59,7 +63,7 @@ static bool vring_use_dma_api(void)
 	return static_cpu_has(X86_FEATURE_XENPV);
 #endif
 
-	return false;
+	return force_dma_api;
 }
 
 #ifdef DEBUG
Signature · 1 line
2.5.0
#49 lore raw
In reply to Andy Lutomirski
Quoted 5 lines · Andy Lutomirski

To everyone else: we've waffled on this for way too long.  I think we should to get DMA API implementation in with a conservative policy like this rather than waiting until we achieve perfection. I'm tired of carrying these patches around.

Yeah, do it.

However,,, shouldn't the generic no-op DMA ops be checking the dma_mask of the device and bitching if it can't reach the address in question?

Also, wasn't Christoph looking at making per-device DMA ops more generic instead of an 'archdata' thing on basically every platform? Or did I just imagine that part?

Not that I'm suggesting you make the s390 patch wait for that *instead* of using archdata there, mind you. But I was kind of planning to let the dust settle on this lot before I sort out the theoretical-except- in-simulation issues with VT-d IOMMU covering *some* devices but not all.

Signature · 2 lines
David Woodhouse                            Open Source Technology Centre
[email protected]                              Intel Corporation
#50 lore raw
Quoted 3 lines · David Woodhouse

Also, wasn't Christoph looking at making per-device DMA ops more generic instead of an 'archdata' thing on basically every platform? Or did I just imagine that part?

What I've done for 4.5 is to switch all architectures to use DMA ops. This should make it fairly easy to have a generic dma ops pointer in the devie structure, but I have no need for that yet, and thus no short term plans to do that work myself.

#51 lore raw
In reply to David Woodhouse
Quoted 3 lines · David Woodhouse

Also, wasn't Christoph looking at making per-device DMA ops more generic instead of an 'archdata' thing on basically every platform? Or did I just imagine that part?

What I've done for 4.5 is to switch all architectures to use DMA ops. This should make it fairly easy to have a generic dma ops pointer in the devie structure, but I have no need for that yet, and thus no short term plans to do that work myself.

#52 lore raw
In reply to Andy Lutomirski
Quoted 5 lines · Andy Lutomirski

To everyone else: we've waffled on this for way too long.  I think we should to get DMA API implementation in with a conservative policy like this rather than waiting until we achieve perfection. I'm tired of carrying these patches around.

Yeah, do it.

However,,, shouldn't the generic no-op DMA ops be checking the dma_mask of the device and bitching if it can't reach the address in question?

Also, wasn't Christoph looking at making per-device DMA ops more generic instead of an 'archdata' thing on basically every platform? Or did I just imagine that part?

Not that I'm suggesting you make the s390 patch wait for that *instead* of using archdata there, mind you. But I was kind of planning to let the dust settle on this lot before I sort out the theoretical-except- in-simulation issues with VT-d IOMMU covering *some* devices but not all.

Signature · 2 lines
David Woodhouse                            Open Source Technology Centre
[email protected]                              Intel Corporation

_______________________________________________
Virtualization mailing list
[email protected]
https://lists.linuxfoundation.org/mailman/listinfo/virtualization

#53 lore raw
In reply to Andy Lutomirski
Quoted 5 lines · Andy Lutomirski

To everyone else: we've waffled on this for way too long.  I think we should to get DMA API implementation in with a conservative policy like this rather than waiting until we achieve perfection. I'm tired of carrying these patches around.

Yeah, do it.

However,,, shouldn't the generic no-op DMA ops be checking the dma_mask of the device and bitching if it can't reach the address in question?

Also, wasn't Christoph looking at making per-device DMA ops more generic instead of an 'archdata' thing on basically every platform? Or did I just imagine that part?

Not that I'm suggesting you make the s390 patch wait for that *instead* of using archdata there, mind you. But I was kind of planning to let the dust settle on this lot before I sort out the theoretical-except- in-simulation issues with VT-d IOMMU covering *some* devices but not all.

Signature · 2 lines
David Woodhouse                            Open Source Technology Centre
[email protected]                              Intel Corporation

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#54 lore raw
In reply to Andy Lutomirski
Quoted 6 lines · Andy Lutomirski

This switches virtio to use the DMA API on Xen and if requested by module option.

This fixes virtio on Xen, and it should break anything because it's off by default on everything except Xen PV on x86.

Quoted 7 lines

To the Xen people: is this okay? If it doesn't work on other Xen variants (PVH? HVM?), can you submit follow-up patches to fix it?

To everyone else: we've waffled on this for way too long. I think we should to get DMA API implementation in with a conservative policy like this rather than waiting until we achieve perfection. I'm tired of carrying these patches around.

I agree, thanks for working on this!

Quoted 1 line

Michael, if these survive review, can you stage these in your tree?

Yes, I'll stage everything except 10/10. I'd rather not maintain a module option like this, things work for now and I'm working on a clean solution for things like dpdk within guest.

So far I saw some comments on 9/10.

Quoted 2 lines

Can you also take a look at tools/virtio? I probably broke it, but I couldn't get it to build without these patches either, so I'm stuck.

Will do.

Quoted 59 lines

Changes from v4:
- Bake vring_use_dma_api in from the beginning.
- Automatically enable only on Xen.
- Add module parameter.
- Add s390 and alpha DMA API implementations.
- Rebase to 4.5-rc1.

Changes from v3:
- More big-endian fixes.
- Added better virtio-ring APIs that handle allocation and use them in virtio-mmio and virtio-pci.
- Switch to Michael's virtio-net patch.

Changes from v2:
- Fix vring_mapping_error incorrect argument

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 (7):
vring: Introduce vring_use_dma_api()
virtio_ring: Support DMA APIs
virtio: Add improved queue allocation API
virtio_mmio: Use the DMA API if enabled
virtio_pci: Use the DMA API if enabled
vring: Use the DMA API on Xen
vring: Add a module parameter to force-enable the DMA API

Christian Borntraeger (3):
dma: Provide simple noop dma ops
alpha/dma: use common noop dma ops
s390/dma: Allow per device dma ops

 arch/alpha/kernel/pci-noop.c        |  46 +---
 arch/s390/Kconfig                   |   6 +-
 arch/s390/include/asm/device.h      |   6 +-
 arch/s390/include/asm/dma-mapping.h |   6 +-
 arch/s390/pci/pci.c                 |   1 +
 arch/s390/pci/pci_dma.c             |   4 +-
 drivers/virtio/Kconfig              |   2 +-
 drivers/virtio/virtio_mmio.c        |  67 ++----
 drivers/virtio/virtio_pci_common.h  |   6 -
 drivers/virtio/virtio_pci_legacy.c  |  42 ++--
 drivers/virtio/virtio_pci_modern.c  |  61 ++----
 drivers/virtio/virtio_ring.c        | 412 ++++++++++++++++++++++++++++++------
 include/linux/dma-mapping.h         |   2 +
 include/linux/virtio.h              |  23 +-
 include/linux/virtio_ring.h         |  35 +++
 lib/Makefile                        |   1 +
 lib/dma-noop.c                      |  75 +++++++
 tools/virtio/linux/dma-mapping.h    |  17 ++
 18 files changed, 568 insertions(+), 244 deletions(-)
 create mode 100644 lib/dma-noop.c
 create mode 100644 tools/virtio/linux/dma-mapping.h
Signature · 1 line
2.5.0
#55 lore raw
Quoted 15 lines · Michael S. Tsirkin
Quoted 6 lines · Andy Lutomirski

This switches virtio to use the DMA API on Xen and if requested by module option.

This fixes virtio on Xen, and it should break anything because it's off by default on everything except Xen PV on x86.

Quoted 7 lines

To the Xen people: is this okay? If it doesn't work on other Xen variants (PVH? HVM?), can you submit follow-up patches to fix it?

To everyone else: we've waffled on this for way too long. I think we should to get DMA API implementation in with a conservative policy like this rather than waiting until we achieve perfection. I'm tired of carrying these patches around.

Quoted 7 lines

I agree, thanks for working on this!

Quoted 1 line

Michael, if these survive review, can you stage these in your tree?

Yes, I'll stage everything except 10/10. I'd rather not maintain a module option like this, things work for now and I'm working on a clean solution for things like dpdk within guest.

The module option was mainly for testing, but patching in a "return true" works just as well.

I ran the code through the DMA API debugging stuff and swiotlb=force with the module option set under KVM (no Xen), and everything seemed to work.

--Andy

#56 lore raw
In reply to Michael S. Tsirkin
Quoted 15 lines · Michael S. Tsirkin
Quoted 6 lines · Andy Lutomirski

This switches virtio to use the DMA API on Xen and if requested by module option.

This fixes virtio on Xen, and it should break anything because it's off by default on everything except Xen PV on x86.

Quoted 7 lines

To the Xen people: is this okay? If it doesn't work on other Xen variants (PVH? HVM?), can you submit follow-up patches to fix it?

To everyone else: we've waffled on this for way too long. I think we should to get DMA API implementation in with a conservative policy like this rather than waiting until we achieve perfection. I'm tired of carrying these patches around.

Quoted 7 lines

I agree, thanks for working on this!

Quoted 1 line

Michael, if these survive review, can you stage these in your tree?

Yes, I'll stage everything except 10/10. I'd rather not maintain a module option like this, things work for now and I'm working on a clean solution for things like dpdk within guest.

The module option was mainly for testing, but patching in a "return true" works just as well.

I ran the code through the DMA API debugging stuff and swiotlb=force with the module option set under KVM (no Xen), and everything seemed to work.

--Andy

#57 lore raw
In reply to Michael S. Tsirkin
Quoted 15 lines · Michael S. Tsirkin
Quoted 6 lines · Andy Lutomirski

This switches virtio to use the DMA API on Xen and if requested by module option.

This fixes virtio on Xen, and it should break anything because it's off by default on everything except Xen PV on x86.

Quoted 7 lines

To the Xen people: is this okay? If it doesn't work on other Xen variants (PVH? HVM?), can you submit follow-up patches to fix it?

To everyone else: we've waffled on this for way too long. I think we should to get DMA API implementation in with a conservative policy like this rather than waiting until we achieve perfection. I'm tired of carrying these patches around.

Quoted 7 lines

I agree, thanks for working on this!

Quoted 1 line

Michael, if these survive review, can you stage these in your tree?

Yes, I'll stage everything except 10/10. I'd rather not maintain a module option like this, things work for now and I'm working on a clean solution for things like dpdk within guest.

The module option was mainly for testing, but patching in a "return true" works just as well.

I ran the code through the DMA API debugging stuff and swiotlb=force with the module option set under KVM (no Xen), and everything seemed to work.

--Andy

#58 lore raw
In reply to Andy Lutomirski
Quoted 6 lines · Andy Lutomirski

This switches virtio to use the DMA API on Xen and if requested by module option.

This fixes virtio on Xen, and it should break anything because it's off by default on everything except Xen PV on x86.

Quoted 7 lines

To the Xen people: is this okay? If it doesn't work on other Xen variants (PVH? HVM?), can you submit follow-up patches to fix it?

To everyone else: we've waffled on this for way too long. I think we should to get DMA API implementation in with a conservative policy like this rather than waiting until we achieve perfection. I'm tired of carrying these patches around.

I agree, thanks for working on this!

Quoted 1 line

Michael, if these survive review, can you stage these in your tree?

Yes, I'll stage everything except 10/10. I'd rather not maintain a module option like this, things work for now and I'm working on a clean solution for things like dpdk within guest.

So far I saw some comments on 9/10.

Quoted 2 lines

Can you also take a look at tools/virtio? I probably broke it, but I couldn't get it to build without these patches either, so I'm stuck.

Will do.

Quoted 59 lines

Changes from v4:
- Bake vring_use_dma_api in from the beginning.
- Automatically enable only on Xen.
- Add module parameter.
- Add s390 and alpha DMA API implementations.
- Rebase to 4.5-rc1.

Changes from v3:
- More big-endian fixes.
- Added better virtio-ring APIs that handle allocation and use them in virtio-mmio and virtio-pci.
- Switch to Michael's virtio-net patch.

Changes from v2:
- Fix vring_mapping_error incorrect argument

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 (7):
vring: Introduce vring_use_dma_api()
virtio_ring: Support DMA APIs
virtio: Add improved queue allocation API
virtio_mmio: Use the DMA API if enabled
virtio_pci: Use the DMA API if enabled
vring: Use the DMA API on Xen
vring: Add a module parameter to force-enable the DMA API

Christian Borntraeger (3):
dma: Provide simple noop dma ops
alpha/dma: use common noop dma ops
s390/dma: Allow per device dma ops

 arch/alpha/kernel/pci-noop.c        |  46 +---
 arch/s390/Kconfig                   |   6 +-
 arch/s390/include/asm/device.h      |   6 +-
 arch/s390/include/asm/dma-mapping.h |   6 +-
 arch/s390/pci/pci.c                 |   1 +
 arch/s390/pci/pci_dma.c             |   4 +-
 drivers/virtio/Kconfig              |   2 +-
 drivers/virtio/virtio_mmio.c        |  67 ++----
 drivers/virtio/virtio_pci_common.h  |   6 -
 drivers/virtio/virtio_pci_legacy.c  |  42 ++--
 drivers/virtio/virtio_pci_modern.c  |  61 ++----
 drivers/virtio/virtio_ring.c        | 412 ++++++++++++++++++++++++++++++------
 include/linux/dma-mapping.h         |   2 +
 include/linux/virtio.h              |  23 +-
 include/linux/virtio_ring.h         |  35 +++
 lib/Makefile                        |   1 +
 lib/dma-noop.c                      |  75 +++++++
 tools/virtio/linux/dma-mapping.h    |  17 ++
 18 files changed, 568 insertions(+), 244 deletions(-)
 create mode 100644 lib/dma-noop.c
 create mode 100644 tools/virtio/linux/dma-mapping.h
Signature · 1 line
2.5.0
#59 lore raw
In reply to Andy Lutomirski
Quoted 6 lines · Andy Lutomirski

This switches virtio to use the DMA API on Xen and if requested by module option.

This fixes virtio on Xen, and it should break anything because it's off by default on everything except Xen PV on x86.

Quoted 7 lines

To the Xen people: is this okay? If it doesn't work on other Xen variants (PVH? HVM?), can you submit follow-up patches to fix it?

To everyone else: we've waffled on this for way too long. I think we should to get DMA API implementation in with a conservative policy like this rather than waiting until we achieve perfection. I'm tired of carrying these patches around.

I agree, thanks for working on this!

Quoted 1 line

Michael, if these survive review, can you stage these in your tree?

Yes, I'll stage everything except 10/10. I'd rather not maintain a module option like this, things work for now and I'm working on a clean solution for things like dpdk within guest.

So far I saw some comments on 9/10.

Quoted 2 lines

Can you also take a look at tools/virtio? I probably broke it, but I couldn't get it to build without these patches either, so I'm stuck.

Will do.

Quoted 59 lines

Changes from v4:
- Bake vring_use_dma_api in from the beginning.
- Automatically enable only on Xen.
- Add module parameter.
- Add s390 and alpha DMA API implementations.
- Rebase to 4.5-rc1.

Changes from v3:
- More big-endian fixes.
- Added better virtio-ring APIs that handle allocation and use them in virtio-mmio and virtio-pci.
- Switch to Michael's virtio-net patch.

Changes from v2:
- Fix vring_mapping_error incorrect argument

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 (7):
vring: Introduce vring_use_dma_api()
virtio_ring: Support DMA APIs
virtio: Add improved queue allocation API
virtio_mmio: Use the DMA API if enabled
virtio_pci: Use the DMA API if enabled
vring: Use the DMA API on Xen
vring: Add a module parameter to force-enable the DMA API

Christian Borntraeger (3):
dma: Provide simple noop dma ops
alpha/dma: use common noop dma ops
s390/dma: Allow per device dma ops

 arch/alpha/kernel/pci-noop.c        |  46 +---
 arch/s390/Kconfig                   |   6 +-
 arch/s390/include/asm/device.h      |   6 +-
 arch/s390/include/asm/dma-mapping.h |   6 +-
 arch/s390/pci/pci.c                 |   1 +
 arch/s390/pci/pci_dma.c             |   4 +-
 drivers/virtio/Kconfig              |   2 +-
 drivers/virtio/virtio_mmio.c        |  67 ++----
 drivers/virtio/virtio_pci_common.h  |   6 -
 drivers/virtio/virtio_pci_legacy.c  |  42 ++--
 drivers/virtio/virtio_pci_modern.c  |  61 ++----
 drivers/virtio/virtio_ring.c        | 412 ++++++++++++++++++++++++++++++------
 include/linux/dma-mapping.h         |   2 +
 include/linux/virtio.h              |  23 +-
 include/linux/virtio_ring.h         |  35 +++
 lib/Makefile                        |   1 +
 lib/dma-noop.c                      |  75 +++++++
 tools/virtio/linux/dma-mapping.h    |  17 ++
 18 files changed, 568 insertions(+), 244 deletions(-)
 create mode 100644 lib/dma-noop.c
 create mode 100644 tools/virtio/linux/dma-mapping.h
Signature · 1 line
2.5.0
#60 lore raw
In reply to Andy Lutomirski

Nice work, Andy.

Quoted 6 lines · Andy Lutomirski

This switches virtio to use the DMA API on Xen and if requested by module option.

This fixes virtio on Xen, and it should break anything because it's off by default on everything except Xen PV on x86.

What is your setup? My understanding is that virtio doesn't work on PV guest as of now because a suitable transport is missing.

Wei.

#61 lore raw
Quoted 6 lines · Wei Liu

Nice work, Andy.

Quoted 3 lines · Andy Lutomirski

This switches virtio to use the DMA API on Xen and if requested by module option.

Quoted 6 lines
Quoted 3 lines

This fixes virtio on Xen, and it should break anything because it's off by default on everything except Xen PV on x86.

What is your setup? My understanding is that virtio doesn't work on PV guest as of now because a suitable transport is missing.

I cheated and ran Xen under KVM with the virtio-pci device provided by
QEMU. If you have virtme
(https://git.kernel.org/cgit/utils/kernel/virtme/virtme.git/), you can do:

virtme-run --kdir=. --pwd --xen xen-4.5.2 --qemu-opts -smp 3 -m 1024

where xen-4.5.2 is the gunzipped Xen binary. (Other versions work, too.)

--Andy

#62 lore raw
Quoted 11 lines · Andy Lutomirski
Quoted 10 lines · Wei Liu

Nice work, Andy.

Quoted 6 lines · Andy Lutomirski

This switches virtio to use the DMA API on Xen and if requested by module option.

This fixes virtio on Xen, and it should break anything because it's off by default on everything except Xen PV on x86.

Quoted 8 lines
Quoted 2 lines

What is your setup? My understanding is that virtio doesn't work on PV guest as of now because a suitable transport is missing.

I cheated and ran Xen under KVM with the virtio-pci device provided by
QEMU. If you have virtme
(https://git.kernel.org/cgit/utils/kernel/virtme/virtme.git/), you can do:

Thanks for the clarification. This is exactly what I needed to know. In that case virtio-pci transport is used. All virtio devices are exposed as PCI devices.

Wei.

Quoted 5 lines

virtme-run --kdir=. --pwd --xen xen-4.5.2 --qemu-opts -smp 3 -m 1024

where xen-4.5.2 is the gunzipped Xen binary. (Other versions work, too.)

--Andy

#63 lore raw
In reply to Andy Lutomirski
Quoted 11 lines · Andy Lutomirski
Quoted 10 lines · Wei Liu

Nice work, Andy.

Quoted 6 lines · Andy Lutomirski

This switches virtio to use the DMA API on Xen and if requested by module option.

This fixes virtio on Xen, and it should break anything because it's off by default on everything except Xen PV on x86.

Quoted 8 lines
Quoted 2 lines

What is your setup? My understanding is that virtio doesn't work on PV guest as of now because a suitable transport is missing.

I cheated and ran Xen under KVM with the virtio-pci device provided by
QEMU. If you have virtme
(https://git.kernel.org/cgit/utils/kernel/virtme/virtme.git/), you can do:

Thanks for the clarification. This is exactly what I needed to know. In that case virtio-pci transport is used. All virtio devices are exposed as PCI devices.

Wei.

Quoted 5 lines

virtme-run --kdir=. --pwd --xen xen-4.5.2 --qemu-opts -smp 3 -m 1024

where xen-4.5.2 is the gunzipped Xen binary. (Other versions work, too.)

--Andy

#64 lore raw
In reply to Wei Liu
Quoted 6 lines · Wei Liu

Nice work, Andy.

Quoted 3 lines · Andy Lutomirski

This switches virtio to use the DMA API on Xen and if requested by module option.

Quoted 6 lines
Quoted 3 lines

This fixes virtio on Xen, and it should break anything because it's off by default on everything except Xen PV on x86.

What is your setup? My understanding is that virtio doesn't work on PV guest as of now because a suitable transport is missing.

I cheated and ran Xen under KVM with the virtio-pci device provided by
QEMU. If you have virtme
(https://git.kernel.org/cgit/utils/kernel/virtme/virtme.git/), you can do:

virtme-run --kdir=. --pwd --xen xen-4.5.2 --qemu-opts -smp 3 -m 1024

where xen-4.5.2 is the gunzipped Xen binary. (Other versions work, too.)

--Andy

#65 lore raw
In reply to Andy Lutomirski

Nice work, Andy.

Quoted 6 lines · Andy Lutomirski

This switches virtio to use the DMA API on Xen and if requested by module option.

This fixes virtio on Xen, and it should break anything because it's off by default on everything except Xen PV on x86.

What is your setup? My understanding is that virtio doesn't work on PV guest as of now because a suitable transport is missing.

Wei.