qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 21/26] Implement TCE translation for sPAPR VIO


From: Anthony Liguori
Subject: Re: [Qemu-devel] [PATCH 21/26] Implement TCE translation for sPAPR VIO
Date: Wed, 16 Mar 2011 17:20:53 -0500
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.14) Gecko/20110223 Lightning/1.0b2 Thunderbird/3.1.8

On 03/15/2011 11:56 PM, David Gibson wrote:
From: Ben Herrenschmidt<address@hidden>

This patch implements the necessary infrastructure and hypercalls for
sPAPR's TCE (Translation Control Entry) IOMMU mechanism.  This is necessary
for all virtual IO devices which do DMA (i.e. nearly all of them).

Signed-off-by: Ben Herrenschmidt<address@hidden>
Signed-off-by: David Gibson<address@hidden>
---
  hw/spapr.c     |    3 +-
  hw/spapr_vio.c |  232 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  hw/spapr_vio.h |   32 ++++++++
  3 files changed, 266 insertions(+), 1 deletions(-)

diff --git a/hw/spapr.c b/hw/spapr.c
index e7f8864..a362889 100644
--- a/hw/spapr.c
+++ b/hw/spapr.c
@@ -62,7 +62,8 @@ static void *spapr_create_fdt(int *fdt_size, ram_addr_t 
ramsize,
      uint32_t start_prop = cpu_to_be32(initrd_base);
      uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
      uint32_t pft_size_prop[] = {0, cpu_to_be32(hash_shift)};
-    char hypertas_prop[] = 
"hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt";
+    char hypertas_prop[] = "hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt"
+        "\0hcall-tce";
      uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
      int i;
      char *modelname;
diff --git a/hw/spapr_vio.c b/hw/spapr_vio.c
index 45edd94..37cf51e 100644
--- a/hw/spapr_vio.c
+++ b/hw/spapr_vio.c
@@ -37,6 +37,7 @@
  #endif /* CONFIG_FDT */

  /* #define DEBUG_SPAPR */
+/* #define DEBUG_TCE */

  #ifdef DEBUG_SPAPR
  #define dprintf(fmt, ...) \
@@ -114,6 +115,28 @@ static int vio_make_devnode(VIOsPAPRDevice *dev,
              return ret;
      }

+    if (dev->rtce_window_size) {
+        uint32_t dma_prop[] = {cpu_to_be32(dev->reg),
+                               0, 0,
+                               0, cpu_to_be32(dev->rtce_window_size)};
+
+        ret = fdt_setprop_cell(fdt, node_off, "ibm,#dma-address-cells", 2);
+        if (ret<  0) {
+            return ret;
+        }
+
+        ret = fdt_setprop_cell(fdt, node_off, "ibm,#dma-size-cells", 2);
+        if (ret<  0) {
+            return ret;
+        }
+
+        ret = fdt_setprop(fdt, node_off, "ibm,my-dma-window", dma_prop,
+                          sizeof(dma_prop));
+        if (ret<  0) {
+            return ret;
+        }
+    }
+
      if (info->devnode) {
          ret = (info->devnode)(dev, fdt, node_off);
          if (ret<  0) {
@@ -125,6 +148,210 @@ static int vio_make_devnode(VIOsPAPRDevice *dev,
  }
  #endif /* CONFIG_FDT */

+/*
+ * RTCE handling
+ */
+
+static void rtce_init(VIOsPAPRDevice *dev)
+{
+    size_t size = (dev->rtce_window_size>>  SPAPR_VIO_TCE_PAGE_SHIFT)
+        * sizeof(VIOsPAPR_RTCE);
+
+    if (size) {
+        dev->rtce_table = qemu_mallocz(size);
+    }
+}
+
+static target_ulong h_put_tce(CPUState *env, sPAPREnvironment *spapr,
+                              target_ulong opcode, target_ulong *args)
+{
+    target_ulong liobn = args[0];
+    target_ulong ioba = args[1];
+    target_ulong tce = args[2];
+    VIOsPAPRDevice *dev = spapr_vio_find_by_reg(spapr->vio_bus, liobn);
+    VIOsPAPR_RTCE *rtce;
+
+    if (!dev) {
+        fprintf(stderr, "spapr_vio_put_tce on non-existent LIOBN "
+                TARGET_FMT_lx "\n",
+                liobn);

You generally want to avoid guest triggered fprintfs as it can be exploited in scenarios where qemu's stdout is logged to disk (libvirt). We usually wrap this in a DPRINTF() of some sort.

Regards,

Anthony Liguori



reply via email to

[Prev in Thread] Current Thread [Next in Thread]