[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH V2] tools/libxc, xen/x86: Added xc_set_mem_access_multi()
On 09/02/2016 01:02 PM, Jan Beulich wrote: >>>> On 02.09.16 at 10:51, <rcojocaru@xxxxxxxxxxxxxxx> wrote: >> Changes since V1 / RFC: >> - Renamed xc_set_mem_access_sparse() to xc_set_mem_access_multi(), >> and XENMEM_access_op_set_access_sparse to >> XENMEM_access_op_set_access_multi. >> - Renamed the 'nr' parameter to 'size'. > > Why? Tamas suggested it, size sounded more intuitive to him. I have no problem with either nr or size. >> - Wrapped long line in the implementation of xc_set_mem_access_multi(). >> - Factored out common code in _p2m_set_mem_access() (and modified >> p2m_set_altp2m_mem_access() in the process, to take an unsigned >> long argument instead of a gfn_t). >> - Factored out xenmem_access_t to p2m_access_t conversion code in >> p2m_xenmem_access_to_p2m_access(). >> - Added hypercall continuation support. >> - Added compat translation support. >> - No longer allocating buffers (now using copy_from_guest_offset()). >> - Added support for setting an array of access restrictions, as >> suggested by Tamas Lengyel. >> - This patch incorporates Jan Beulich's "memory: fix compat handling >> of XENMEM_access_op". > > I'm not sure that's okay; I'd have preferred you make the other > patch a prereq (not the least because that one may want > backporting, while this one certainly won't). In no event should > such a bug fix go without mentioning in the commit message. I agree, this is here simply because looking at the state of staging, the patch hadn't yet made it in, and I was trying to be efficient and have an intermediate review anyway. I'll manually apply your patch before mine and remove that code from this patch. >> @@ -1772,13 +1773,12 @@ bool_t p2m_mem_access_check(paddr_t gpa, unsigned >> long gla, >> static inline >> int p2m_set_altp2m_mem_access(struct domain *d, struct p2m_domain *hp2m, >> struct p2m_domain *ap2m, p2m_access_t a, >> - gfn_t gfn) >> + unsigned long gfn_l) >> { > > I'm not really happy about such a step backwards. I'll keep p2m_set_altp2m_mem_access() as it is then. I just thought that going from unsigned long to gfn_t just to have to go back to unsigned long slightly clutters up the code, but it's certainly not a huge difference. >> @@ -1811,21 +1811,39 @@ int p2m_set_altp2m_mem_access(struct domain *d, >> struct p2m_domain *hp2m, >> (current->domain != d)); >> } >> >> -/* >> - * Set access type for a region of gfns. >> - * If gfn == INVALID_GFN, sets the default access type. >> - */ >> -long p2m_set_mem_access(struct domain *d, gfn_t gfn, uint32_t nr, >> - uint32_t start, uint32_t mask, xenmem_access_t >> access, >> - unsigned int altp2m_idx) >> +static inline >> +int _p2m_set_mem_access(struct domain *d, struct p2m_domain *p2m, > > Considering the file we're in, can't this just be set_mem_access()? Of course, I'll rename it. > Also I'd leave the inlining decision completely to the compiler. I took that cue from p2m_set_altp2m_mem_access() above. I'll remove the inline. >> + struct p2m_domain *ap2m, p2m_access_t a, >> + unsigned long gfn_l) >> { >> - struct p2m_domain *p2m = p2m_get_hostp2m(d), *ap2m = NULL; >> - p2m_access_t a, _a; >> - p2m_type_t t; >> - mfn_t mfn; >> - unsigned long gfn_l; >> - long rc = 0; >> + int rc; >> >> + if ( ap2m ) >> + { >> + rc = p2m_set_altp2m_mem_access(d, p2m, ap2m, a, gfn_l); >> + /* If the corresponding mfn is invalid we will want to just skip it >> */ >> + if ( rc && rc != -ESRCH ) >> + return rc; > > If you just converted -ESRCH to 0 here, you could then ... > >> + } >> + else >> + { >> + mfn_t mfn; >> + p2m_access_t _a; >> + p2m_type_t t; >> + >> + mfn = p2m->get_entry(p2m, gfn_l, &t, &_a, 0, NULL, NULL); >> + rc = p2m->set_entry(p2m, gfn_l, mfn, PAGE_ORDER_4K, t, a, -1); >> + return rc; > > ... ditch this extra return path and ... > >> + } >> + >> + return 0; > > ... have both cases come here. I'll do that. >> @@ -1851,17 +1897,8 @@ long p2m_set_mem_access(struct domain *d, gfn_t gfn, >> uint32_t nr, >> ap2m = d->arch.altp2m_p2m[altp2m_idx]; >> } >> >> - switch ( access ) >> - { >> - case 0 ... ARRAY_SIZE(memaccess) - 1: >> - a = memaccess[access]; >> - break; >> - case XENMEM_access_default: >> - a = p2m->default_access; >> - break; >> - default: >> + if ( p2m_xenmem_access_to_p2m_access(p2m, access, &a) ) >> return -EINVAL; > > Either you make the helper function return bool, or you pass on > whatever value it returned instead of assuming it's -EINVAL. Fair enough, I'll return bool. >> +long p2m_set_mem_access_multi(struct domain *d, >> + XEN_GUEST_HANDLE(uint64_t) pfn_list, >> + XEN_GUEST_HANDLE(uint8) access_list, >> + uint32_t size, uint32_t start, uint32_t mask, >> + unsigned int altp2m_idx) >> +{ >> + struct p2m_domain *p2m = p2m_get_hostp2m(d), *ap2m = NULL; >> + long rc = 0; >> + >> + /* altp2m view 0 is treated as the hostp2m */ >> + if ( altp2m_idx ) >> + { >> + if ( altp2m_idx >= MAX_ALTP2M || >> + d->arch.altp2m_eptp[altp2m_idx] == mfn_x(INVALID_MFN) ) >> + return -EINVAL; >> + >> + ap2m = d->arch.altp2m_p2m[altp2m_idx]; >> + } >> + >> + p2m_lock(p2m); >> + if ( ap2m ) >> + p2m_lock(ap2m); >> + >> + while ( start < size ) >> + { >> + p2m_access_t a; >> + >> + uint8_t access; >> + uint64_t gfn_l; > > Stray blank line between declarations. Will remove it. >> @@ -320,6 +321,23 @@ int compat_memory_op(unsigned int cmd, >> XEN_GUEST_HANDLE_PARAM(void) compat) >> break; >> } >> >> + case XENMEM_access_op: >> + { >> +#define XLAT_mem_access_op_HNDL_pfn_list(_d_, _s_) \ >> + guest_from_compat_handle((_d_)->pfn_list, (_s_)->pfn_list) >> +#define XLAT_mem_access_op_HNDL_access_list(_d_, _s_) \ >> + guest_from_compat_handle((_d_)->access_list, (_s_)->access_list) >> + >> + XLAT_mem_access_op(nat.mao, &cmp.mao); >> + >> +#undef XLAT_mem_access_op_HNDL_pfn_list >> +#undef XLAT_mem_access_op_HNDL_access_list >> + >> + return mem_access_memop(cmd, >> + guest_handle_cast(compat, >> + xen_mem_access_op_t)); >> + } > > You translate into native format, but then cast the compat handle > to its native counterpart type. Such casting is okay only when > accompanied by a respectively invoked CHECK_* macro. Please > follow the model other code here uses. I'll follow the model. > And reviewing this I notice that my earlier bug fix also is still not > really correct: It causes hypercall_xlat_continuation() to be > bypassed. Since you've addressed this comment in a subsequent reply, no need to continue here. >> @@ -452,6 +454,16 @@ struct xen_mem_access_op { >> * ~0ull is used to set and get the default access for pages >> */ >> uint64_aligned_t pfn; >> + /* >> + * List of pfns to set access for >> + * Used only with XENMEM_access_op_set_access_multi >> + */ >> + XEN_GUEST_HANDLE(uint64_t) pfn_list; > > I'm not sure why we even have this kind of handle - please use > XEN_GUEST_HANDLE(uint64) instead. I'll change it. >> + /* >> + * Corresponding list of access settings for pfn_list >> + * Used only with XENMEM_access_op_set_access_multi >> + */ >> + XEN_GUEST_HANDLE(uint8) access_list; > > And for both of them - I don't think the arrays are meant to be > used for output? In which case they should be handles of const > types. No, they're indeed not meant for output. I'll constify the code. Thanks, Razvan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |