[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 1/5] arm: shared_info page allocation and mapping
On Thu, 2012-02-23 at 18:21 +0000, Stefano Stabellini wrote: > Allocate the shared_info page at domain creation. > > Implement arch_memory_op, only for XENMEM_add_to_physmap with space == > XENMAPSPACE_shared_info, so that the guest can map the shared_info page. > > Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx> > --- > xen/arch/arm/domain.c | 8 ++++ > xen/arch/arm/mm.c | 98 > +++++++++++++++++++++++++++++++++++++++++++-- > xen/arch/arm/p2m.c | 15 ++++++- > xen/include/asm-arm/mm.h | 4 ++ > xen/include/asm-arm/p2m.h | 2 + > 5 files changed, 122 insertions(+), 5 deletions(-) > > diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c > index 0b55934..0ee96b9 100644 > --- a/xen/arch/arm/domain.c > +++ b/xen/arch/arm/domain.c > @@ -235,6 +235,14 @@ int arch_domain_create(struct domain *d, unsigned int > domcr_flags) > if ( (rc = p2m_init(d)) != 0 ) > goto fail; > > + rc = -ENOMEM; > + if ( (d->shared_info = alloc_xenheap_pages(0, MEMF_bits(32))) == NULL ) > + goto fail; > + > + clear_page(d->shared_info); > + share_xen_page_with_guest( > + virt_to_page(d->shared_info), d, XENSHARE_writable); > + > d->max_vcpus = 8; > > if ( (rc = domain_vgic_init(d)) != 0 ) > diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c > index a0f39eb..0fe0398 100644 > --- a/xen/arch/arm/mm.c > +++ b/xen/arch/arm/mm.c > @@ -25,8 +25,11 @@ > #include <xen/mm.h> > #include <xen/preempt.h> > #include <xen/errno.h> > +#include <xen/guest_access.h> > #include <asm/page.h> > #include <asm/current.h> > +#include <public/memory.h> > +#include <xen/sched.h> > > struct domain *dom_xen, *dom_io; > > @@ -323,17 +326,104 @@ void arch_dump_shared_mem_info(void) > { > } > > -long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg) > +int donate_page(struct domain *d, struct page_info *page, unsigned int > memflags) > { > + ASSERT(0); > return -ENOSYS; > } > > -int donate_page(struct domain *d, struct page_info *page, unsigned int > memflags) > +void share_xen_page_with_guest(struct page_info *page, > + struct domain *d, int readonly) > { > - ASSERT(0); > - return -ENOSYS; > + if ( page_get_owner(page) == d ) > + return; > + > + spin_lock(&d->page_alloc_lock); > + > + /* The incremented type count pins as writable or read-only. */ > + page->u.inuse.type_info = (readonly ? PGT_none : PGT_writable_page); > + page->u.inuse.type_info |= PGT_validated | 1; > + > + page_set_owner(page, d); > + wmb(); /* install valid domain ptr before updating refcnt. */ > + ASSERT((page->count_info & ~PGC_xen_heap) == 0); > + > + /* Only add to the allocation list if the domain isn't dying. */ > + if ( !d->is_dying ) > + { > + page->count_info |= PGC_allocated | 1; > + if ( unlikely(d->xenheap_pages++ == 0) ) > + get_knownalive_domain(d); > + page_list_add_tail(page, &d->xenpage_list); > + } > + > + spin_unlock(&d->page_alloc_lock); > +} > + > +static int xenmem_add_to_physmap_once( > + struct domain *d, > + const struct xen_add_to_physmap *xatp) > +{ > + unsigned long mfn = 0; > + int rc; > + > + switch ( xatp->space ) > + { > + case XENMAPSPACE_shared_info: > + if ( xatp->idx == 0 ) > + mfn = virt_to_mfn(d->shared_info); > + break; > + default: > + return -ENOSYS; > + } > + > + domain_lock(d); > + > + /* Map at new location. */ > + rc = guest_physmap_add_page(d, xatp->gpfn, mfn); > + > + domain_unlock(d); > + > + return rc; > +} > + > +static int xenmem_add_to_physmap(struct domain *d, > + struct xen_add_to_physmap *xatp) > +{ > + return xenmem_add_to_physmap_once(d, xatp); > } > > +long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg) > +{ > + int rc; > + > + switch ( op ) > + { > + case XENMEM_add_to_physmap: > + { > + struct xen_add_to_physmap xatp; > + struct domain *d; > + > + if ( copy_from_guest(&xatp, arg, 1) ) > + return -EFAULT; > + > + rc = rcu_lock_target_domain_by_id(xatp.domid, &d); > + if ( rc != 0 ) > + return rc; > + > + rc = xenmem_add_to_physmap(d, &xatp); > + > + rcu_unlock_domain(d); > + > + return rc; > + } > + > + default: > + return -ENOSYS; > + } > + > + return 0; > +} > /* > * Local variables: > * mode: C > diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c > index 14614fd..1a00a50 100644 > --- a/xen/arch/arm/p2m.c > +++ b/xen/arch/arm/p2m.c > @@ -118,7 +118,12 @@ static int create_p2m_entries(struct domain *d, > } > /* else: third already valid */ > > - BUG_ON(third[third_table_offset(addr)].p2m.valid); > + if ( third[third_table_offset(addr)].p2m.valid ) > + { > + /* p2m entry already present */ > + free_domheap_page( > + mfn_to_page(third[third_table_offset(addr)].p2m.base)); > + } > > /* Allocate a new RAM page and attach */ > if (alloc) > @@ -172,6 +177,14 @@ int map_mmio_regions(struct domain *d, > return create_p2m_entries(d, 0, start_gaddr, end_gaddr, maddr); > } > > +int guest_physmap_add_page(struct domain *d, unsigned long gpfn, > + unsigned long mfn) > +{ > + return create_p2m_entries(d, 0, gpfn << PAGE_SHIFT, > + (gpfn + 1) << PAGE_SHIFT, > + mfn << PAGE_SHIFT); > +} > + > int p2m_alloc_table(struct domain *d) > { > struct p2m_domain *p2m = &d->arch.p2m; > diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h > index bfc0f76..56ab9415 100644 > --- a/xen/include/asm-arm/mm.h > +++ b/xen/include/asm-arm/mm.h > @@ -78,6 +78,10 @@ struct page_info > #define _PGT_pinned PG_shift(5) > #define PGT_pinned PG_mask(1, 5) > > + /* Has this page been validated for use as its current type? */ > +#define _PGT_validated PG_shift(6) > +#define PGT_validated PG_mask(1, 6) > + > /* Count of uses of this frame as its current type. */ > #define PGT_count_width PG_shift(9) > #define PGT_count_mask ((1UL<<PGT_count_width)-1) > diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h > index aec52f7..c0f2995 100644 > --- a/xen/include/asm-arm/p2m.h > +++ b/xen/include/asm-arm/p2m.h > @@ -39,6 +39,8 @@ int p2m_populate_ram(struct domain *d, paddr_t start, > paddr_t end); > * address maddr. */ > int map_mmio_regions(struct domain *d, paddr_t start_gaddr, > paddr_t end_gaddr, paddr_t maddr); > +int guest_physmap_add_page(struct domain *d, unsigned long gpfn, > + unsigned long mfn); > > unsigned long gmfn_to_mfn(struct domain *d, unsigned long gpfn); > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |