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

[Xen-devel] [PATCH v4 3/9] xen/arm: Implement set_memory_map hypercall for arm



From: Evgeny Fedotov <e.fedotov@xxxxxxxxxxx>

When creating domU in toolstack, pass the guest memory
map info to the hypervisor, and the hypervisor stores those info in
arch_domain for later use.

Singed-off-by: Evgeny Fedotov <e.fedotov@xxxxxxxxxxx>
---
 tools/libxc/xc_dom_arm.c     | 12 +++++++-
 tools/libxc/xc_domain.c      | 44 ++++++++++++++++++++++++++++
 tools/libxc/xenctrl.h        | 23 +++++++++++++++
 xen/arch/arm/domain.c        |  3 ++
 xen/arch/arm/mm.c            | 68 ++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/domain.h |  2 ++
 xen/include/asm-arm/mm.h     |  1 +
 xen/include/public/memory.h  | 15 ++++++++--
 xen/include/xsm/dummy.h      |  5 ++++
 xen/include/xsm/xsm.h        |  5 ++++
 10 files changed, 175 insertions(+), 3 deletions(-)

diff --git a/tools/libxc/xc_dom_arm.c b/tools/libxc/xc_dom_arm.c
index df59ffb..20c9095 100644
--- a/tools/libxc/xc_dom_arm.c
+++ b/tools/libxc/xc_dom_arm.c
@@ -166,6 +166,7 @@ int arch_setup_meminit(struct xc_dom_image *dom)
 {
     int rc;
     xen_pfn_t pfn, allocsz, i;
+    struct dt_mem_info memmap;
 
     dom->shadow_enabled = 1;
 
@@ -191,7 +192,16 @@ int arch_setup_meminit(struct xc_dom_image *dom)
             0, 0, &dom->p2m_host[i]);
     }
 
-    return 0;
+    /* setup guest memory map */
+    memmap.nr_banks = 2;
+    memmap.bank[0].start = (dom->rambase_pfn << PAGE_SHIFT_ARM);
+    memmap.bank[0].size = (dom->total_pages << PAGE_SHIFT_ARM);
+    /*The end of main memory: magic pages */
+    memmap.bank[1].start = memmap.bank[0].start + memmap.bank[0].size;
+    memmap.bank[1].size = NR_MAGIC_PAGES << PAGE_SHIFT_ARM;
+
+    return xc_domain_set_memory_map(dom->xch, dom->guest_domid, &memmap);
+
 }
 
 int arch_setup_bootearly(struct xc_dom_image *dom)
diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index 81316d3..7b283f1 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -662,7 +662,51 @@ int xc_domain_set_memmap_limit(xc_interface *xch,
     return -1;
 }
 #endif
+#if defined(__arm__)
+int xc_domain_get_memory_map(xc_interface *xch,
+                              uint32_t domid,
+                              struct dt_mem_info *map)
+{
+    int rc;
+    struct xen_arm_memory_map fmap = {
+           .domid = domid
+    };
+
+    DECLARE_HYPERCALL_BOUNCE(map, sizeof(struct dt_mem_info),
+                                 XC_HYPERCALL_BUFFER_BOUNCE_OUT);
+
+    if ( !map || xc_hypercall_bounce_pre(xch, map) )
+            return -1;
+    set_xen_guest_handle(fmap.buffer, map);
 
+    rc = do_memory_op(xch, XENMEM_memory_map, &fmap, sizeof(fmap));
+
+    xc_hypercall_bounce_post(xch, map);
+
+    return rc;
+}
+
+int xc_domain_set_memory_map(xc_interface *xch,
+                              uint32_t domid,
+                              struct dt_mem_info *map)
+{
+    int rc;
+    struct xen_arm_memory_map fmap = {
+        .domid = domid
+    };
+    DECLARE_HYPERCALL_BOUNCE(map, sizeof(struct dt_mem_info),
+                                    XC_HYPERCALL_BUFFER_BOUNCE_IN);
+
+    if ( !map || xc_hypercall_bounce_pre(xch, map) )
+                return -1;
+    set_xen_guest_handle(fmap.buffer, map);
+
+    rc = do_memory_op(xch, XENMEM_set_memory_map, &fmap, sizeof(fmap));
+
+    xc_hypercall_bounce_post(xch, map);
+    return rc;
+}
+#endif
 int xc_domain_set_time_offset(xc_interface *xch,
                               uint32_t domid,
                               int32_t time_offset_seconds)
diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
index 58d51f3..c1468fa 100644
--- a/tools/libxc/xenctrl.h
+++ b/tools/libxc/xenctrl.h
@@ -1122,6 +1122,29 @@ int xc_get_machine_memory_map(xc_interface *xch,
                               struct e820entry entries[],
                               uint32_t max_entries);
 #endif
+
+#if defined(__arm__)
+#define NR_MEM_BANKS 8
+typedef uint64_t paddr_t;
+
+struct membank {
+    paddr_t start;
+    paddr_t size;
+};
+
+struct dt_mem_info {
+    int nr_banks;
+    struct membank bank[NR_MEM_BANKS];
+};
+
+int xc_domain_set_memory_map(xc_interface *xch,
+                              uint32_t domid,
+                              struct dt_mem_info *map);
+int xc_domain_get_memory_map(xc_interface *xch,
+                              uint32_t domid,
+                              struct dt_mem_info *map);
+#endif
+
 int xc_domain_set_time_offset(xc_interface *xch,
                               uint32_t domid,
                               int32_t time_offset_seconds);
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index d3bac4d..57be341 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -509,6 +509,9 @@ int arch_domain_create(struct domain *d, unsigned int 
domcr_flags)
     /* Default the virtual ID to match the physical */
     d->arch.vpidr = boot_cpu_data.midr.bits;
 
+    spin_lock_init(&d->arch.map_lock);
+    d->arch.map_domain.nr_banks = 0;
+
     clear_page(d->shared_info);
     share_xen_page_with_guest(
         virt_to_page(d->shared_info), d, XENSHARE_writable);
diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index 474dfef..f5d9cf4 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -1156,6 +1156,74 @@ long arch_memory_op(int op, XEN_GUEST_HANDLE_PARAM(void) 
arg)
 
         return rc;
     }
+    case XENMEM_set_memory_map:
+    {
+        struct xen_arm_memory_map fmap;
+        struct domain *d;
+        struct dt_mem_info info;
+
+        if ( copy_from_guest(&fmap, arg, 1) )
+            return -EFAULT;
+
+        if ( copy_from_guest(&info, fmap.buffer, 1) )
+        {
+            return -EFAULT;
+        }
+
+        if ( info.nr_banks > NR_MEM_BANKS )
+              return -EINVAL;
+
+        d = rcu_lock_domain_by_any_id(fmap.domid);
+        if ( d == NULL )
+            return -ESRCH;
+
+        rc = xsm_domain_memory_map(XSM_TARGET, d);
+        if ( rc )
+        {
+            rcu_unlock_domain(d);
+            return rc;
+        }
+        spin_lock(&d->arch.map_lock);
+        d->arch.map_domain = info;
+        spin_unlock(&d->arch.map_lock);
+
+        rcu_unlock_domain(d);
+        return rc;
+        }
+
+        case XENMEM_memory_map:
+        {
+        /* get the domain's memory map as it was stored */
+        struct xen_arm_memory_map fmap;
+        struct domain *d;
+        struct dt_mem_info info;
+
+        if ( copy_from_guest(&fmap, arg, 1) )
+            return -EFAULT;
+
+        d = rcu_lock_domain_by_any_id(fmap.domid);
+        if ( d == NULL )
+            return -ESRCH;
+
+        spin_lock(&d->arch.map_lock);
+        info = d->arch.map_domain;
+        spin_unlock(&d->arch.map_lock);
+
+        if ( copy_to_guest(fmap.buffer, &info, 1) )
+        {
+            rcu_unlock_domain(d);
+            return -EFAULT;
+        }
+
+        if ( copy_to_guest(arg, &fmap, 1) )
+        {
+            rcu_unlock_domain(d);
+            return -EFAULT;
+        }
+
+        rcu_unlock_domain(d);
+        return 0;
+    }
     /* XXX: memsharing not working yet */
     case XENMEM_get_sharing_shared_pages:
     case XENMEM_get_sharing_freed_pages:
diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h
index 67bfbbc..755c7af 100644
--- a/xen/include/asm-arm/domain.h
+++ b/xen/include/asm-arm/domain.h
@@ -112,6 +112,8 @@ struct arch_domain
         spinlock_t                  lock;
     } vuart;
 
+    struct dt_mem_info map_domain;
+    spinlock_t         map_lock;
 }  __cacheline_aligned;
 
 struct arch_vcpu
diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
index ce66099..5142524 100644
--- a/xen/include/asm-arm/mm.h
+++ b/xen/include/asm-arm/mm.h
@@ -5,6 +5,7 @@
 #include <xen/kernel.h>
 #include <asm/page.h>
 #include <public/xen.h>
+#include <xen/device_tree.h>
 
 /* Align Xen to a 2 MiB boundary. */
 #define XEN_PADDR_ALIGN (1 << 21)
diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h
index 7a26dee..264fb8f 100644
--- a/xen/include/public/memory.h
+++ b/xen/include/public/memory.h
@@ -283,9 +283,12 @@ DEFINE_XEN_GUEST_HANDLE(xen_remove_from_physmap_t);
 /*#define XENMEM_translate_gpfn_list  8*/
 
 /*
- * Returns the pseudo-physical memory map as it was when the domain
+ * x86: returns the pseudo-physical memory map as it was when the domain
  * was started (specified by XENMEM_set_memory_map).
  * arg == addr of xen_memory_map_t.
+ * ARM: returns the pseudo-physical memory map as it was set
+ * (specified by XENMEM_set_memory_map).
+ * arg == addr of xen_arm_memory_map_t.
  */
 #define XENMEM_memory_map           9
 struct xen_memory_map {
@@ -315,7 +318,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_memory_map_t);
 /*
  * Set the pseudo-physical memory map of a domain, as returned by
  * XENMEM_memory_map.
- * arg == addr of xen_foreign_memory_map_t.
+ * x86: arg == addr of xen_foreign_memory_map_t.
+ * ARM: arg == addr of xen_arm_memory_map_t
  */
 #define XENMEM_set_memory_map       13
 struct xen_foreign_memory_map {
@@ -325,6 +329,13 @@ struct xen_foreign_memory_map {
 typedef struct xen_foreign_memory_map xen_foreign_memory_map_t;
 DEFINE_XEN_GUEST_HANDLE(xen_foreign_memory_map_t);
 
+struct xen_arm_memory_map {
+    domid_t domid;
+    XEN_GUEST_HANDLE(void) buffer;
+};
+typedef struct xen_arm_memory_map xen_arm_memory_map_t;
+DEFINE_XEN_GUEST_HANDLE(xen_arm_memory_map_t);
+
 #define XENMEM_set_pod_target       16
 #define XENMEM_get_pod_target       17
 struct xen_pod_target {
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index 052f3e0..427f800 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -627,4 +627,9 @@ static XSM_INLINE int xsm_map_gmfn_foreign(XSM_DEFAULT_ARG 
struct domain *d, str
     XSM_ASSERT_ACTION(XSM_TARGET);
     return xsm_default_action(action, d, t);
 }
+static XSM_INLINE int xsm_domain_memory_map(XSM_DEFAULT_ARG struct domain *d)
+{
+    XSM_ASSERT_ACTION(XSM_TARGET);
+    return xsm_default_action(action, current->domain, d);
+}
 #endif
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 1939453..9764011 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -625,6 +625,11 @@ static inline int xsm_map_gmfn_foreign (struct domain *d, 
struct domain *t)
 {
     return xsm_ops->map_gmfn_foreign(d, t);
 }
+static inline int xsm_domain_memory_map(xsm_default_t def, struct domain *d)
+{
+    return xsm_ops->domain_memory_map(d);
+}
+
 #endif /* CONFIG_ARM */
 
 #endif /* XSM_NO_WRAPPERS */
-- 
1.8.1.2


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.