[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v7 02/12] x86/mm: add HYPERVISOR_memory_op to acquire guest resources
>>> On 18.09.17 at 17:31, <paul.durrant@xxxxxxxxxx> wrote: > Certain memory resources associated with a guest are not necessarily > present in the guest P2M and so are not necessarily available to be > foreign-mapped by a tools domain unless they are inserted, which risks > shattering a super-page mapping. For grant tables I can see this as the primary issue, but isn't the goal of not exposing IOREQ server pages an even more important aspect, and hence more relevant to mention here? > NOTE: Whilst the new op is not intrinsicly specific to the x86 architecture, > I have no means to test it on an ARM platform and so cannot verify > that it functions correctly. Hence it is currently only implemented > for x86. Which will require things to be moved around later on. May I instead suggest to put it in common code and simply have a small #ifdef somewhere causing the operation to fail early for ARM? > --- a/xen/arch/x86/mm.c > +++ b/xen/arch/x86/mm.c > @@ -4768,6 +4768,107 @@ int xenmem_add_to_physmap_one( > return rc; > } > > +static int xenmem_acquire_grant_table(struct domain *d, I don't think static functions need a xenmem_ prefix. > +static int xenmem_acquire_resource(xen_mem_acquire_resource_t *xmar) const? > +{ > + struct domain *d, *currd = current->domain; > + unsigned long *mfn_list; > + int rc; > + > + if ( xmar->nr_frames == 0 ) > + return -EINVAL; > + > + d = rcu_lock_domain_by_any_id(xmar->domid); > + if ( d == NULL ) > + return -ESRCH; > + > + rc = xsm_domain_memory_map(XSM_TARGET, d); > + if ( rc ) > + goto out; > + > + mfn_list = xmalloc_array(unsigned long, xmar->nr_frames); Despite XSA-77 there should not be any new disaggregation related security risks (here: memory exhaustion and long lasting loops). Large requests need to be refused or broken up. > --- a/xen/common/grant_table.c > +++ b/xen/common/grant_table.c > @@ -3607,38 +3607,58 @@ int mem_sharing_gref_to_gfn(struct grant_table *gt, > grant_ref_t ref, > } > #endif > > -int gnttab_map_frame(struct domain *d, unsigned long idx, gfn_t gfn, > - mfn_t *mfn) > -{ > - int rc = 0; > > - grant_write_lock(d->grant_table); > +static mfn_t gnttab_get_frame_locked(struct domain *d, unsigned long idx) > +{ > + struct grant_table *gt = d->grant_table; > + mfn_t mfn = INVALID_MFN; > > - if ( d->grant_table->gt_version == 0 ) > - d->grant_table->gt_version = 1; > + if ( gt->gt_version == 0 ) > + gt->gt_version = 1; > > - if ( d->grant_table->gt_version == 2 && > + if ( gt->gt_version == 2 && > (idx & XENMAPIDX_grant_table_status) ) > { > idx &= ~XENMAPIDX_grant_table_status; I don't see the use of this bit mentioned anywhere in the public header addition. > +mfn_t gnttab_get_frame(struct domain *d, unsigned long idx) > +{ > + mfn_t mfn; > + > + grant_write_lock(d->grant_table); > + mfn = gnttab_get_frame_locked(d, idx); > + grant_write_unlock(d->grant_table); Hmm, a read lock is insufficient here only because of the possible bumping of the version from 0 to 1 afaict, but I don't really see why what now becomes gnttab_get_frame_locked() does that in the first place. > --- a/xen/include/public/memory.h > +++ b/xen/include/public/memory.h > @@ -650,7 +650,43 @@ struct xen_vnuma_topology_info { > typedef struct xen_vnuma_topology_info xen_vnuma_topology_info_t; > DEFINE_XEN_GUEST_HANDLE(xen_vnuma_topology_info_t); > > -/* Next available subop number is 28 */ > +#if defined(__XEN__) || defined(__XEN_TOOLS__) > + > +/* > + * Get the pages for a particular guest resource, so that they can be > + * mapped directly by a tools domain. > + */ > +#define XENMEM_acquire_resource 28 > +struct xen_mem_acquire_resource { > + /* IN - the domain whose resource is to be mapped */ > + domid_t domid; > + /* IN - the type of resource (defined below) */ > + uint16_t type; > + > +#define XENMEM_resource_grant_table 0 > + > + /* > + * IN - a type-specific resource identifier, which must be zero > + * unless stated otherwise. > + */ > + uint32_t id; > + /* IN - number of (4K) frames of the resource to be mapped */ > + uint32_t nr_frames; > + /* IN - the index of the initial frame to be mapped */ > + uint64_aligned_t frame; There are 32 bits of unnamed padding ahead of this field - please name it and check it's set to zero. > + /* IN/OUT - If the tools domain is PV then, upon return, gmfn_list > + * will be populated with the MFNs of the resource. > + * If the tools domain is HVM then it is expected that, on s/tools domain/calling domain/ (twice)? > + * entry, gmfn_list will be populated with a list of GFNs s/will be/is/ to further emphasize the input vs output difference? > + * that will be mapped to the MFNs of the resource. > + */ > + XEN_GUEST_HANDLE(xen_pfn_t) gmfn_list; What about a 32-bit x86 tool stack domain as caller here? I don't think you want to limit it to just the low 16Tb? Nor are you adding a compat translation layer. > +}; > +typedef struct xen_mem_acquire_resource xen_mem_acquire_resource_t; > + > +#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */ Also please group this with the other similar section, without introducing a second identical #if. After all we have ... > +/* Next available subop number is 29 */ ... this to eliminate the need to have things numerically sorted in this file. Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |