[IA64] introduce DOM0VP_get_memmap hypercall. introduce new dom0vp hypercall, DOM0VP_get_memmap, to get memmap of a given domain without race. Signed-off-by: Isaku Yamahata diff -r 088bc049f889 xen/arch/ia64/xen/dom0_ops.c --- a/xen/arch/ia64/xen/dom0_ops.c Thu Oct 02 15:24:18 2008 +0900 +++ b/xen/arch/ia64/xen/dom0_ops.c Thu Oct 02 15:25:22 2008 +0900 @@ -607,6 +607,12 @@ 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); diff -r 088bc049f889 xen/arch/ia64/xen/mm.c --- a/xen/arch/ia64/xen/mm.c Thu Oct 02 15:24:18 2008 +0900 +++ b/xen/arch/ia64/xen/mm.c Thu Oct 02 15:25:22 2008 +0900 @@ -2465,6 +2465,49 @@ 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 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 out; + } + 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: + memmap_unlock(targ_d); + if (page != NULL) + free_domheap_pages(page, order); + + return ret; +} #endif // grant table host mapping diff -r 088bc049f889 xen/include/asm-ia64/mm.h --- a/xen/include/asm-ia64/mm.h Thu Oct 02 15:24:18 2008 +0900 +++ b/xen/include/asm-ia64/mm.h Thu Oct 02 15:25:22 2008 +0900 @@ -448,6 +448,7 @@ 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 @@ #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; diff -r 088bc049f889 xen/include/public/arch-ia64.h --- a/xen/include/public/arch-ia64.h Thu Oct 02 15:24:18 2008 +0900 +++ b/xen/include/public/arch-ia64.h Thu Oct 02 15:25:22 2008 +0900 @@ -463,6 +463,11 @@ /* 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)