[IA64] introduce DOM0VP_get_memmap hypercall.
authorIsaku Yamahata <yamahata@valinux.co.jp>
Fri, 3 Oct 2008 03:49:55 +0000 (12:49 +0900)
committerIsaku Yamahata <yamahata@valinux.co.jp>
Fri, 3 Oct 2008 03:49:55 +0000 (12:49 +0900)
introduce new dom0vp hypercall, DOM0VP_get_memmap,
to get memmap of a given domain without race.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
xen/arch/ia64/xen/dom0_ops.c
xen/arch/ia64/xen/mm.c
xen/include/asm-ia64/mm.h
xen/include/public/arch-ia64.h

index 9ff2011987ff808f3b335025ad0bec410af61729..b21cb42e70cdbfef9479d122654b5c82466ce382 100644 (file)
@@ -597,6 +597,12 @@ do_dom0vp_op(unsigned long cmd,
     case IA64_DOM0VP_unexpose_foreign_p2m:
         ret = dom0vp_unexpose_foreign_p2m(d, arg0, arg1);
         break;
+    case IA64_DOM0VP_get_memmap: {
+        XEN_GUEST_HANDLE(char) hnd;
+        set_xen_guest_handle(hnd, (char*)arg1);
+        ret = dom0vp_get_memmap((domid_t)arg0, hnd);
+        break;
+    }
     default:
         ret = -1;
                printk("unknown dom0_vp_op 0x%lx\n", cmd);
index c14464617fd66ec2fcdee8b84dceb1768e0dd28a..4f18bf7349c2360e80632c9bc5bfbd6857c1ae87 100644 (file)
@@ -2467,6 +2467,55 @@ __dom0vp_add_memdesc(struct domain *targ_d,
         free_domheap_pages(page, order);
     return ret;
 }
+
+unsigned long
+dom0vp_get_memmap(domid_t domid, XEN_GUEST_HANDLE(char) buffer)
+{
+    unsigned long ret = 0;
+    struct domain *targ_d;
+
+    struct page_info *page = NULL;
+    unsigned long order;
+
+    struct xen_ia64_memmap_info *memmap_info;
+    unsigned long num_pages;
+    
+    ret = rcu_lock_target_domain_by_id(domid, &targ_d);
+    if (ret != 0)
+        return ret;
+
+    memmap_lock(targ_d);
+
+    ret = memmap_copy_from(targ_d, &page, &order);
+    if (ret != 0)
+        goto unlock_out;
+
+    memmap_info = page_to_virt(page);
+    num_pages = targ_d->shared_info->arch.memmap_info_num_pages;
+    if ((num_pages << PAGE_SHIFT) - sizeof(*memmap_info) <
+        memmap_info->efi_memmap_size) {
+        ret = -EFAULT;
+        goto unlock_out;
+    }
+    memmap_unlock(targ_d);
+    rcu_unlock_domain(targ_d);
+    
+    if (copy_to_guest(buffer, (char*)memmap_info, sizeof(*memmap_info)) ||
+        copy_to_guest_offset(buffer, sizeof(*memmap_info),
+                             (char*)memmap_info->memdesc,
+                             memmap_info->efi_memmap_size))
+        ret = -EFAULT;
+
+ out:
+    if (page != NULL)
+        free_domheap_pages(page, order);
+    return ret;
+
+ unlock_out:
+    memmap_unlock(targ_d);
+    rcu_unlock_domain(targ_d);
+    goto out;
+}
 #endif
 
 // grant table host mapping
index 3853ee3dbeb7a4383456907bf95f4b724e6cf529..28e7387d0453e381d59594fa1d5075471dbeed22 100644 (file)
@@ -448,6 +448,7 @@ extern void foreign_p2m_init(struct domain* d);
 extern void foreign_p2m_destroy(struct domain* d);
 extern unsigned long dom0vp_expose_foreign_p2m(struct domain* dest_dom, unsigned long dest_gpfn, domid_t domid, XEN_GUEST_HANDLE(char) buffer, unsigned long flags);
 extern unsigned long dom0vp_unexpose_foreign_p2m(struct domain* dest_dom, unsigned long dest_gpfn, domid_t domid);
+extern unsigned long dom0vp_get_memmap(domid_t domid, XEN_GUEST_HANDLE(char) buffer);
 #else
 #define expose_p2m_init()       do { } while (0)
 #define dom0vp_expose_p2m(d, conv_start_gpfn, assign_start_gpfn, expose_size, granule_pfn)     (-ENOSYS)
@@ -456,6 +457,7 @@ extern unsigned long dom0vp_unexpose_foreign_p2m(struct domain* dest_dom, unsign
 #define dom0vp_expose_foreign_p2m(dest_dom, dest_gpfn, domid, buffer, flags)   (-ENOSYS)
 #define dom0vp_unexpose_foreign_p2m(dest_dom, dest_gpfn, domid)        (-ENOSYS)
 #define __dom0vp_add_memdesc(d, memmap_info, memdesc)  (-ENOSYS)
+#define dom0vp_get_memmap(domid, buffer)               (-ENOSYS)
 #endif
 
 extern volatile unsigned long *mpt_table;
index 0c43cee8550216f55fd8b440a9b1315ae7e621a7..c88783ad03369a53532ff2e87986240e2634e5a2 100644 (file)
@@ -453,6 +453,11 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
 /* unexpose the foreign domain's p2m table into privileged domain */
 #define IA64_DOM0VP_unexpose_foreign_p2m        13
 
+/* get memmap_info and memmap. It is possible to map the page directly
+   by foreign page mapping, but there is a race between writer.
+   This hypercall avoids such race. */
+#define IA64_DOM0VP_get_memmap          14
+
 // flags for page assignement to pseudo physical address space
 #define _ASSIGN_readonly                0
 #define ASSIGN_readonly                 (1UL << _ASSIGN_readonly)