[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |