From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: qemu-devel@nongnu.org
Cc: anthony@codemonkey.ws
Subject: [Qemu-devel] [PATCH 11/11] Add a memory barrier to DMA functions
Date: Fri, 22 Jun 2012 13:29:45 +1000 [thread overview]
Message-ID: <1340335785-6451-12-git-send-email-benh@kernel.crashing.org> (raw)
In-Reply-To: <1340335785-6451-1-git-send-email-benh@kernel.crashing.org>
The emulated devices can run simultaneously with the guest, so
we need to be careful with ordering of load and stores done by
them to the guest system memory, which need to be observed in
the right order by the guest operating system.
This adds a barrier call to the basic DMA read/write ops which
is currently implemented as a smp_mb(), but could be later
improved for more fine grained control of barriers.
Additionally, a _relaxed() variant of the accessors is provided
to easily convert devices who would be performance sensitive
and negatively impacted by the change.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
dma-helpers.c | 2 ++
dma.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/dma-helpers.c b/dma-helpers.c
index 2e09ceb..35cb500 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -31,6 +31,8 @@ static void do_dma_memory_set(dma_addr_t addr, uint8_t c, dma_addr_t len)
int dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c, dma_addr_t len)
{
+ dma_barrier(dma, DMA_DIRECTION_FROM_DEVICE);
+
if (dma_has_iommu(dma)) {
return iommu_dma_memory_set(dma, addr, c, len);
}
diff --git a/dma.h b/dma.h
index f52a656..54cdd24 100644
--- a/dma.h
+++ b/dma.h
@@ -13,6 +13,7 @@
#include <stdio.h>
#include "hw/hw.h"
#include "block.h"
+#include "kvm.h"
typedef struct DMAContext DMAContext;
typedef struct ScatterGatherEntry ScatterGatherEntry;
@@ -65,6 +66,30 @@ struct DMAContext {
DMAUnmapFunc *unmap;
};
+static inline void dma_barrier(DMAContext *dma, DMADirection dir)
+{
+ /*
+ * This is called before DMA read and write operations
+ * unless the _relaxed form is used and is responsible
+ * for providing some sane ordering of accesses vs
+ * concurrently running VCPUs.
+ *
+ * Users of map(), unmap() or lower level st/ld_*
+ * operations are responsible for providing their own
+ * ordering via barriers.
+ *
+ * This primitive implementation does a simple smp_mb()
+ * before each operation which provides pretty much full
+ * ordering.
+ *
+ * A smarter implementation can be devised if needed to
+ * use lighter barriers based on the direction of the
+ * transfer, the DMA context, etc...
+ */
+ if (kvm_enabled())
+ smp_mb();
+}
+
static inline bool dma_has_iommu(DMAContext *dma)
{
return !!dma;
@@ -88,8 +113,9 @@ static inline bool dma_memory_valid(DMAContext *dma,
int iommu_dma_memory_rw(DMAContext *dma, dma_addr_t addr,
void *buf, dma_addr_t len, DMADirection dir);
-static inline int dma_memory_rw(DMAContext *dma, dma_addr_t addr,
- void *buf, dma_addr_t len, DMADirection dir)
+static inline int dma_memory_rw_relaxed(DMAContext *dma, dma_addr_t addr,
+ void *buf, dma_addr_t len,
+ DMADirection dir)
{
if (!dma_has_iommu(dma)) {
/* Fast-path for no IOMMU */
@@ -101,6 +127,28 @@ static inline int dma_memory_rw(DMAContext *dma, dma_addr_t addr,
}
}
+static inline int dma_memory_read_relaxed(DMAContext *dma, dma_addr_t addr,
+ void *buf, dma_addr_t len)
+{
+ return dma_memory_rw_relaxed(dma, addr, buf, len, DMA_DIRECTION_TO_DEVICE);
+}
+
+static inline int dma_memory_write_relaxed(DMAContext *dma, dma_addr_t addr,
+ const void *buf, dma_addr_t len)
+{
+ return dma_memory_rw_relaxed(dma, addr, (void *)buf, len,
+ DMA_DIRECTION_FROM_DEVICE);
+}
+
+static inline int dma_memory_rw(DMAContext *dma, dma_addr_t addr,
+ void *buf, dma_addr_t len,
+ DMADirection dir)
+{
+ dma_barrier(dma, dir);
+
+ return dma_memory_rw_relaxed(dma, addr, buf, len, dir);
+}
+
static inline int dma_memory_read(DMAContext *dma, dma_addr_t addr,
void *buf, dma_addr_t len)
{
--
1.7.9.5
next prev parent reply other threads:[~2012-06-22 3:30 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-06-22 3:29 [Qemu-devel] [PATCH 00/11] iommu series Benjamin Herrenschmidt
2012-06-22 3:29 ` [Qemu-devel] [PATCH 01/11] Better support for dma_addr_t variables Benjamin Herrenschmidt
2012-06-22 3:29 ` [Qemu-devel] [PATCH 02/11] iommu: Add universal DMA helper functions Benjamin Herrenschmidt
2012-06-22 3:29 ` [Qemu-devel] [PATCH 03/11] usb-ohci: Use " Benjamin Herrenschmidt
2012-06-22 3:29 ` [Qemu-devel] [PATCH 04/11] iommu: Make sglists and dma_bdrv helpers use new universal DMA helpers Benjamin Herrenschmidt
2012-06-22 3:29 ` [Qemu-devel] [PATCH 05/11] ide/ahci: Use universal DMA helper functions Benjamin Herrenschmidt
2012-06-22 3:29 ` [Qemu-devel] [PATCH 06/11] usb: Convert usb_packet_{map, unmap} to universal DMA helpers Benjamin Herrenschmidt
2012-06-22 3:29 ` [Qemu-devel] [PATCH 07/11] iommu: Introduce IOMMU emulation infrastructure Benjamin Herrenschmidt
2012-06-22 3:29 ` [Qemu-devel] [PATCH 08/11] pseries: Convert sPAPR TCEs to use generic IOMMU infrastructure Benjamin Herrenschmidt
2012-06-22 3:29 ` [Qemu-devel] [PATCH 09/11] iommu: Allow PCI to use " Benjamin Herrenschmidt
2012-06-22 3:29 ` [Qemu-devel] [PATCH 10/11] pseries: Implement IOMMU and DMA for PAPR PCI devices Benjamin Herrenschmidt
2012-06-22 3:29 ` Benjamin Herrenschmidt [this message]
2012-06-24 6:03 ` [Qemu-devel] [PATCH 11/11] Add a memory barrier to DMA functions Blue Swirl
2012-06-24 7:28 ` Benjamin Herrenschmidt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1340335785-6451-12-git-send-email-benh@kernel.crashing.org \
--to=benh@kernel.crashing.org \
--cc=anthony@codemonkey.ws \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).