diff mbox

[Xen-devel,v4,23/24] xen/arm: Add a hypercall for device mmio mapping

Message ID 1456658360-16080-24-git-send-email-zhaoshenglong@huawei.com
State Superseded
Headers show

Commit Message

Shannon Zhao Feb. 28, 2016, 11:19 a.m. UTC
From: Shannon Zhao <shannon.zhao@linaro.org>

It needs to map platform or amba device mmio to Dom0 on ARM. But when
booting with ACPI, it can't get the mmio region in Xen due to lack of
AML interpreter to parse DSDT table. Therefore, let Dom0 call a
hypercall to map mmio region when it adds the devices.

Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
---
v4: check the domain if it's Dom0 and it maps to itself
---
 xen/arch/arm/mm.c           |  4 ++++
 xen/arch/arm/p2m.c          | 23 +++++++++++++++++++++++
 xen/common/memory.c         | 14 ++++++++++++++
 xen/include/asm-arm/p2m.h   |  5 +++++
 xen/include/public/memory.h |  1 +
 5 files changed, 47 insertions(+)
diff mbox

Patch

diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index 81f9e2e..c4bf0a5 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -1138,6 +1138,10 @@  int xenmem_add_to_physmap_one(
         rcu_unlock_domain(od);
         break;
     }
+    case XENMAPSPACE_dev_mmio:
+        rc = map_dev_mmio_region(d, gpfn, 1, idx);
+        return rc;
+        break;
 
     default:
         return -ENOSYS;
diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index c36fdf6..d9796ef 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -7,6 +7,7 @@ 
 #include <xen/bitops.h>
 #include <xen/vm_event.h>
 #include <xen/mem_access.h>
+#include <xen/iocap.h>
 #include <public/vm_event.h>
 #include <asm/flushtlb.h>
 #include <asm/gic.h>
@@ -1270,6 +1271,28 @@  int unmap_mmio_regions(struct domain *d,
                              d->arch.p2m.default_access);
 }
 
+int map_dev_mmio_region(struct domain *d,
+                        unsigned long start_gfn,
+                        unsigned long nr,
+                        unsigned long mfn)
+{
+    int res;
+
+    if(!iomem_access_permitted(d, start_gfn, start_gfn + nr))
+        return 0;
+
+    res = map_mmio_regions(d, start_gfn, nr, mfn);
+    if ( res < 0 )
+    {
+        printk(XENLOG_ERR "Unable to map 0x%lx - 0x%lx in domain %d\n",
+               start_gfn << PAGE_SHIFT, (start_gfn + nr) << PAGE_SHIFT,
+               d->domain_id);
+        return res;
+    }
+
+    return 0;
+}
+
 int guest_physmap_add_entry(struct domain *d,
                             unsigned long gpfn,
                             unsigned long mfn,
diff --git a/xen/common/memory.c b/xen/common/memory.c
index ef57219..c8fcffe 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -980,6 +980,13 @@  long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
         if ( d == NULL )
             return -ESRCH;
 
+        /* XENMAPSPACE_dev_mmio mapping is only supported for hardware Domain
+         * to map this kind of space to itself.
+         */
+        if ( (xatp.space == XENMAPSPACE_dev_mmio) &&
+             (!is_hardware_domain(current->domain) || (d != current->domain)) )
+            return -EOPNOTSUPP;
+
         rc = xsm_add_to_physmap(XSM_TARGET, current->domain, d);
         if ( rc )
         {
@@ -1024,6 +1031,13 @@  long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
         if ( d == NULL )
             return -ESRCH;
 
+        /* XENMAPSPACE_dev_mmio mapping is only supported for hardware Domain
+         * to map this kind of space to itself.
+         */
+        if ( (xatpb.space == XENMAPSPACE_dev_mmio) &&
+             (!is_hardware_domain(current->domain) || (d != current->domain)) )
+            return -EOPNOTSUPP;
+
         rc = xsm_add_to_physmap(XSM_TARGET, current->domain, d);
         if ( rc )
         {
diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
index 945b613..e92a96e 100644
--- a/xen/include/asm-arm/p2m.h
+++ b/xen/include/asm-arm/p2m.h
@@ -154,6 +154,11 @@  int unmap_regions(struct domain *d,
                     unsigned long nr_mfns,
                     unsigned long mfn);
 
+int map_dev_mmio_region(struct domain *d,
+                        unsigned long start_gfn,
+                        unsigned long nr,
+                        unsigned long mfn);
+
 int guest_physmap_add_entry(struct domain *d,
                             unsigned long gfn,
                             unsigned long mfn,
diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h
index f69e92f..fe52ee1 100644
--- a/xen/include/public/memory.h
+++ b/xen/include/public/memory.h
@@ -220,6 +220,7 @@  DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t);
 #define XENMAPSPACE_gmfn_range   3 /* GMFN range, XENMEM_add_to_physmap only. */
 #define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom,
                                     * XENMEM_add_to_physmap_batch only. */
+#define XENMAPSPACE_dev_mmio     5 /* device mmio region */
 /* ` } */
 
 /*