[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 09/13] xen: move VCPUOP_register_vcpu_info to common code
On Wed, 2013-04-24 at 20:07 +0100, Stefano Stabellini wrote: > Move the implementation of VCPUOP_register_vcpu_info from x86 specific > to commmon code. > > Move vcpu_info_mfn from an arch specific vcpu sub-field to the common > vcpu struct. > Move the initialization of vcpu_info_mfn to common code. > > Move unmap_vcpu_info and the call to unmap_vcpu_info at domain > destruction time to common code. > > Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> > CC: keir@xxxxxxx > CC: JBeulich@xxxxxxxx My ack isn't worth much here, but FWIW looks good to me, assuming the bulk of it really is just code motion... Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx> > --- > xen/arch/x86/domain.c | 113 > ------------------------------------------ > xen/common/domain.c | 111 +++++++++++++++++++++++++++++++++++++++++ > xen/include/asm-x86/domain.h | 3 - > xen/include/xen/domain.h | 3 + > xen/include/xen/sched.h | 3 + > 5 files changed, 117 insertions(+), 116 deletions(-) > > diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c > index 14b6d13..d1b6c64 100644 > --- a/xen/arch/x86/domain.c > +++ b/xen/arch/x86/domain.c > @@ -387,8 +387,6 @@ int vcpu_initialise(struct vcpu *v) > > vmce_init_vcpu(v); > > - v->arch.vcpu_info_mfn = INVALID_MFN; > - > if ( is_hvm_domain(d) ) > { > rc = hvm_vcpu_initialise(v); > @@ -954,99 +952,6 @@ void arch_vcpu_reset(struct vcpu *v) > } > } > > -/* > - * Unmap the vcpu info page if the guest decided to place it somewhere > - * else. This is only used from arch_domain_destroy, so there's no > - * need to do anything clever. > - */ > -static void > -unmap_vcpu_info(struct vcpu *v) > -{ > - unsigned long mfn; > - > - if ( v->arch.vcpu_info_mfn == INVALID_MFN ) > - return; > - > - mfn = v->arch.vcpu_info_mfn; > - unmap_domain_page_global(v->vcpu_info); > - > - v->vcpu_info = &dummy_vcpu_info; > - v->arch.vcpu_info_mfn = INVALID_MFN; > - > - put_page_and_type(mfn_to_page(mfn)); > -} > - > -/* > - * Map a guest page in and point the vcpu_info pointer at it. This > - * makes sure that the vcpu_info is always pointing at a valid piece > - * of memory, and it sets a pending event to make sure that a pending > - * event doesn't get missed. > - */ > -static int > -map_vcpu_info(struct vcpu *v, unsigned long gfn, unsigned offset) > -{ > - struct domain *d = v->domain; > - void *mapping; > - vcpu_info_t *new_info; > - struct page_info *page; > - int i; > - > - if ( offset > (PAGE_SIZE - sizeof(vcpu_info_t)) ) > - return -EINVAL; > - > - if ( v->arch.vcpu_info_mfn != INVALID_MFN ) > - return -EINVAL; > - > - /* Run this command on yourself or on other offline VCPUS. */ > - if ( (v != current) && !test_bit(_VPF_down, &v->pause_flags) ) > - return -EINVAL; > - > - page = get_page_from_gfn(d, gfn, NULL, P2M_ALLOC); > - if ( !page ) > - return -EINVAL; > - > - if ( !get_page_type(page, PGT_writable_page) ) > - { > - put_page(page); > - return -EINVAL; > - } > - > - mapping = __map_domain_page_global(page); > - if ( mapping == NULL ) > - { > - put_page_and_type(page); > - return -ENOMEM; > - } > - > - new_info = (vcpu_info_t *)(mapping + offset); > - > - if ( v->vcpu_info == &dummy_vcpu_info ) > - { > - memset(new_info, 0, sizeof(*new_info)); > - __vcpu_info(v, new_info, evtchn_upcall_mask) = 1; > - } > - else > - { > - memcpy(new_info, v->vcpu_info, sizeof(*new_info)); > - } > - > - v->vcpu_info = new_info; > - v->arch.vcpu_info_mfn = page_to_mfn(page); > - > - /* Set new vcpu_info pointer /before/ setting pending flags. */ > - wmb(); > - > - /* > - * Mark everything as being pending just to make sure nothing gets > - * lost. The domain will get a spurious event, but it can cope. > - */ > - vcpu_info(v, evtchn_upcall_pending) = 1; > - for ( i = 0; i < BITS_PER_EVTCHN_WORD(d); i++ ) > - set_bit(i, &vcpu_info(v, evtchn_pending_sel)); > - > - return 0; > -} > - > long > arch_do_vcpu_op( > int cmd, struct vcpu *v, XEN_GUEST_HANDLE_PARAM(void) arg) > @@ -1083,22 +988,6 @@ arch_do_vcpu_op( > break; > } > > - case VCPUOP_register_vcpu_info: > - { > - struct domain *d = v->domain; > - struct vcpu_register_vcpu_info info; > - > - rc = -EFAULT; > - if ( copy_from_guest(&info, arg, 1) ) > - break; > - > - domain_lock(d); > - rc = map_vcpu_info(v, info.mfn, info.offset); > - domain_unlock(d); > - > - break; > - } > - > /* > * XXX Disable for 4.0.0: __update_vcpu_system_time() writes to the given > * virtual address even when running in another domain's address space. > @@ -2025,8 +1914,6 @@ int domain_relinquish_resources(struct domain *d) > * mappings. > */ > destroy_gdt(v); > - > - unmap_vcpu_info(v); > } > > if ( d->arch.pv_domain.pirq_eoi_map != NULL ) > diff --git a/xen/common/domain.c b/xen/common/domain.c > index ce45d66..d21909f 100644 > --- a/xen/common/domain.c > +++ b/xen/common/domain.c > @@ -33,6 +33,7 @@ > #include <xen/xenoprof.h> > #include <xen/irq.h> > #include <asm/debugger.h> > +#include <asm/p2m.h> > #include <asm/processor.h> > #include <public/sched.h> > #include <public/sysctl.h> > @@ -142,6 +143,7 @@ struct vcpu *alloc_vcpu( > v->vcpu_info = ((vcpu_id < XEN_LEGACY_MAX_VCPUS) > ? (vcpu_info_t *)&shared_info(d, vcpu_info[vcpu_id]) > : &dummy_vcpu_info); > + v->vcpu_info_mfn = INVALID_MFN; > init_waitqueue_vcpu(v); > } > > @@ -547,6 +549,7 @@ int rcu_lock_live_remote_domain_by_id(domid_t dom, struct > domain **d) > int domain_kill(struct domain *d) > { > int rc = 0; > + struct vcpu *v; > > if ( d == current->domain ) > return -EINVAL; > @@ -571,6 +574,8 @@ int domain_kill(struct domain *d) > BUG_ON(rc != -EAGAIN); > break; > } > + for_each_vcpu ( d, v ) > + unmap_vcpu_info(v); > d->is_dying = DOMDYING_dead; > /* Mem event cleanup has to go here because the rings > * have to be put before we call put_domain. */ > @@ -896,6 +901,96 @@ void vcpu_reset(struct vcpu *v) > vcpu_unpause(v); > } > > +/* > + * Map a guest page in and point the vcpu_info pointer at it. This > + * makes sure that the vcpu_info is always pointing at a valid piece > + * of memory, and it sets a pending event to make sure that a pending > + * event doesn't get missed. > + */ > +int map_vcpu_info(struct vcpu *v, unsigned long gfn, unsigned offset) > +{ > + struct domain *d = v->domain; > + void *mapping; > + vcpu_info_t *new_info; > + struct page_info *page; > + int i; > + > + if ( offset > (PAGE_SIZE - sizeof(vcpu_info_t)) ) > + return -EINVAL; > + > + if ( v->vcpu_info_mfn != INVALID_MFN ) > + return -EINVAL; > + > + /* Run this command on yourself or on other offline VCPUS. */ > + if ( (v != current) && !test_bit(_VPF_down, &v->pause_flags) ) > + return -EINVAL; > + > + page = get_page_from_gfn(d, gfn, NULL, P2M_ALLOC); > + if ( !page ) > + return -EINVAL; > + > + if ( !get_page_type(page, PGT_writable_page) ) > + { > + put_page(page); > + return -EINVAL; > + } > + > + mapping = __map_domain_page_global(page); > + if ( mapping == NULL ) > + { > + put_page_and_type(page); > + return -ENOMEM; > + } > + > + new_info = (vcpu_info_t *)(mapping + offset); > + > + if ( v->vcpu_info == &dummy_vcpu_info ) > + { > + memset(new_info, 0, sizeof(*new_info)); > + __vcpu_info(v, new_info, evtchn_upcall_mask) = 1; > + } > + else > + { > + memcpy(new_info, v->vcpu_info, sizeof(*new_info)); > + } > + > + v->vcpu_info = new_info; > + v->vcpu_info_mfn = page_to_mfn(page); > + > + /* Set new vcpu_info pointer /before/ setting pending flags. */ > + wmb(); > + > + /* > + * Mark everything as being pending just to make sure nothing gets > + * lost. The domain will get a spurious event, but it can cope. > + */ > + vcpu_info(v, evtchn_upcall_pending) = 1; > + for ( i = 0; i < BITS_PER_EVTCHN_WORD(d); i++ ) > + set_bit(i, &vcpu_info(v, evtchn_pending_sel)); > + > + return 0; > +} > + > +/* > + * Unmap the vcpu info page if the guest decided to place it somewhere > + * else. This is only used from arch_domain_destroy, so there's no > + * need to do anything clever. > + */ > +void unmap_vcpu_info(struct vcpu *v) > +{ > + unsigned long mfn; > + > + if ( v->vcpu_info_mfn == INVALID_MFN ) > + return; > + > + mfn = v->vcpu_info_mfn; > + unmap_domain_page_global(v->vcpu_info); > + > + v->vcpu_info = &dummy_vcpu_info; > + v->vcpu_info_mfn = INVALID_MFN; > + > + put_page_and_type(mfn_to_page(mfn)); > +} > > long do_vcpu_op(int cmd, int vcpuid, XEN_GUEST_HANDLE_PARAM(void) arg) > { > @@ -1015,6 +1110,22 @@ long do_vcpu_op(int cmd, int vcpuid, > XEN_GUEST_HANDLE_PARAM(void) arg) > > break; > > + case VCPUOP_register_vcpu_info: > + { > + struct domain *d = v->domain; > + struct vcpu_register_vcpu_info info; > + > + rc = -EFAULT; > + if ( copy_from_guest(&info, arg, 1) ) > + break; > + > + domain_lock(d); > + rc = map_vcpu_info(v, info.mfn, info.offset); > + domain_unlock(d); > + > + break; > + } > + > #ifdef VCPU_TRAP_NMI > case VCPUOP_send_nmi: > if ( !guest_handle_is_null(arg) ) > diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h > index bdaf714..e7ed7c3 100644 > --- a/xen/include/asm-x86/domain.h > +++ b/xen/include/asm-x86/domain.h > @@ -435,9 +435,6 @@ struct arch_vcpu > > struct paging_vcpu paging; > > - /* Guest-specified relocation of vcpu_info. */ > - unsigned long vcpu_info_mfn; > - > uint32_t gdbsx_vcpu_event; > > /* A secondary copy of the vcpu time info. */ > diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h > index d4ac50f..d0263a9 100644 > --- a/xen/include/xen/domain.h > +++ b/xen/include/xen/domain.h > @@ -52,6 +52,9 @@ void free_pirq_struct(void *); > int vcpu_initialise(struct vcpu *v); > void vcpu_destroy(struct vcpu *v); > > +int map_vcpu_info(struct vcpu *v, unsigned long gfn, unsigned offset); > +void unmap_vcpu_info(struct vcpu *v); > + > int arch_domain_create(struct domain *d, unsigned int domcr_flags); > > void arch_domain_destroy(struct domain *d); > diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h > index beadc42..7e129d9 100644 > --- a/xen/include/xen/sched.h > +++ b/xen/include/xen/sched.h > @@ -192,6 +192,9 @@ struct vcpu > > struct waitqueue_vcpu *waitqueue_vcpu; > > + /* Guest-specified relocation of vcpu_info. */ > + unsigned long vcpu_info_mfn; > + > struct arch_vcpu arch; > }; > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |