[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] RE: [PATCH v5 2/8] xen/arm: allocate static shared memory to the default owner dom_io
> -----Original Message----- > From: Julien Grall <julien@xxxxxxx> > Sent: Wednesday, June 29, 2022 6:35 PM > To: Penny Zheng <Penny.Zheng@xxxxxxx>; xen-devel@xxxxxxxxxxxxxxxxxxxx > Cc: Wei Chen <Wei.Chen@xxxxxxx>; Stefano Stabellini > <sstabellini@xxxxxxxxxx>; Bertrand Marquis <Bertrand.Marquis@xxxxxxx>; > Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>; Andrew Cooper > <andrew.cooper3@xxxxxxxxxx>; George Dunlap <george.dunlap@xxxxxxxxxx>; > Jan Beulich <jbeulich@xxxxxxxx>; Wei Liu <wl@xxxxxxx> > Subject: Re: [PATCH v5 2/8] xen/arm: allocate static shared memory to the > default owner dom_io > > > > On 29/06/2022 08:13, Penny Zheng wrote: > > Hi Julien > > Hi Penny, > Hi Julien > > > >> -----Original Message----- > >> From: Julien Grall <julien@xxxxxxx> > >> Sent: Saturday, June 25, 2022 2:22 AM > >> To: Penny Zheng <Penny.Zheng@xxxxxxx>; xen- > devel@xxxxxxxxxxxxxxxxxxxx > >> Cc: Wei Chen <Wei.Chen@xxxxxxx>; Stefano Stabellini > >> <sstabellini@xxxxxxxxxx>; Bertrand Marquis > >> <Bertrand.Marquis@xxxxxxx>; Volodymyr Babchuk > >> <Volodymyr_Babchuk@xxxxxxxx>; Andrew Cooper > >> <andrew.cooper3@xxxxxxxxxx>; George Dunlap > >> <george.dunlap@xxxxxxxxxx>; Jan Beulich <jbeulich@xxxxxxxx>; Wei Liu > >> <wl@xxxxxxx> > >> Subject: Re: [PATCH v5 2/8] xen/arm: allocate static shared memory to > >> the default owner dom_io > >> > >> Hi Penny, > >> > >> On 20/06/2022 06:11, Penny Zheng wrote: > >>> From: Penny Zheng <penny.zheng@xxxxxxx> > >>> > >>> This commit introduces process_shm to cope with static shared memory > >>> in domain construction. > >>> > >>> DOMID_IO will be the default owner of memory pre-shared among > >> multiple > >>> domains at boot time, when no explicit owner is specified. > >> > >> The document in patch #1 suggest the page will be shared with > dom_shared. > >> But here you say "DOMID_IO". > >> > >> Which one is correct? > >> > > > > I’ll fix the documentation, DOM_IO is the last call. > > > >>> > >>> This commit only considers allocating static shared memory to dom_io > >>> when owner domain is not explicitly defined in device tree, all the > >>> left, including the "borrower" code path, the "explicit owner" code > >>> path, shall be introduced later in the following patches. > >>> > >>> Signed-off-by: Penny Zheng <penny.zheng@xxxxxxx> > >>> Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx> > >>> --- > >>> v5 change: > >>> - refine in-code comment > >>> --- > >>> v4 change: > >>> - no changes > >>> --- > >>> v3 change: > >>> - refine in-code comment > >>> --- > >>> v2 change: > >>> - instead of introducing a new system domain, reuse the existing > >>> dom_io > >>> - make dom_io a non-auto-translated domain, then no need to create > >>> P2M for it > >>> - change dom_io definition and make it wider to support static shm > >>> here too > >>> - introduce is_shm_allocated_to_domio to check whether static shm is > >>> allocated yet, instead of using shm_mask bitmap > >>> - add in-code comment > >>> --- > >>> xen/arch/arm/domain_build.c | 132 > >> +++++++++++++++++++++++++++++++++++- > >>> xen/common/domain.c | 3 + > >>> 2 files changed, 134 insertions(+), 1 deletion(-) > >>> > >>> diff --git a/xen/arch/arm/domain_build.c > >>> b/xen/arch/arm/domain_build.c index 7ddd16c26d..91a5ace851 100644 > >>> --- a/xen/arch/arm/domain_build.c > >>> +++ b/xen/arch/arm/domain_build.c > >>> @@ -527,6 +527,10 @@ static bool __init > >> append_static_memory_to_bank(struct domain *d, > >>> return true; > >>> } > >>> > >>> +/* > >>> + * If cell is NULL, pbase and psize should hold valid values. > >>> + * Otherwise, cell will be populated together with pbase and psize. > >>> + */ > >>> static mfn_t __init acquire_static_memory_bank(struct domain *d, > >>> const __be32 **cell, > >>> u32 addr_cells, > >>> u32 size_cells, @@ -535,7 +539,8 @@ static mfn_t __init > >> acquire_static_memory_bank(struct domain *d, > >>> mfn_t smfn; > >>> int res; > >>> > >>> - device_tree_get_reg(cell, addr_cells, size_cells, pbase, psize); > >>> + if ( cell ) > >>> + device_tree_get_reg(cell, addr_cells, size_cells, pbase, > >>> + psize); > >> > >> I think this is a bit of a hack. To me it sounds like this should be > >> moved out to a separate helper. This will also make the interface of > >> acquire_shared_memory_bank() less questionable (see below). > >> > > > > Ok, I'll try to not reuse acquire_static_memory_bank in > > acquire_shared_memory_bank. > > I am OK with that so long it doesn't involve too much duplication. > > >>> ASSERT(IS_ALIGNED(*pbase, PAGE_SIZE) && IS_ALIGNED(*psize, > >>> PAGE_SIZE)); > >> > >> In the context of your series, who is checking that both psize and > >> pbase are suitably aligned? > >> > > > > Actually, the whole parsing process is redundant for the static shared > memory. > > I've already parsed it and checked it before in process_shm. > > I looked at process_shm() and couldn't find any code that would check pbase > and psize are suitable aligned (ASSERT() doesn't count). > > > > >>> + return true; > >>> +} > >>> + > >>> +static mfn_t __init acquire_shared_memory_bank(struct domain *d, > >>> + u32 addr_cells, u32 > >>> size_cells, > >>> + paddr_t *pbase, > >>> +paddr_t *psize) > >> > >> There is something that doesn't add-up in this interface. The use of > >> pointer implies that pbase and psize may be modified by the function. So... > >> > > > > Just like you points out before, it's a bit hacky to use > > acquire_static_memory_bank, and the pointer used here is also due to > > it. Internal parsing process of acquire_static_memory_bank needs pointer > to deliver the result. > > > > I’ll rewrite acquire_shared_memory, and it will be like: > > " > > static mfn_t __init acquire_shared_memory_bank(struct domain *d, > > paddr_t pbase, paddr_t > > psize) { > > mfn_t smfn; > > unsigned long nr_pfns; > > int res; > > > > /* > > * Pages of statically shared memory shall be included > > * in domain_tot_pages(). > > */ > > nr_pfns = PFN_DOWN(psize); > > if ( d->max_page + nr_pfns > UINT_MAX ) > > On Arm32, this check would always be true a 32-bit unsigned value is always > below UINT_MAX. On arm64, you might get away because nr_pfns is > unsigned long (so I think the type promotion works). But this is fragile. > > I would suggest to use the following check: > > (UINT_MAX - d->max_page) < nr_pfns > > > { > > printk(XENLOG_ERR "%pd: Over-allocation for d->max_pages: %lu.\n", > > d, psize); > > return INVALID_MFN; > > } > > d->max_pages += nr_pfns; > > > > smfn = maddr_to_mfn(pbase); > > res = acquire_domstatic_pages(d, smfn, nr_pfns, 0); > > if ( res ) > > { > > printk(XENLOG_ERR > > "%pd: failed to acquire static memory: %d.\n", d, res); > > return INVALID_MFN; > > } > > > > return smfn > > } > > " > > > >>> +{ > >>> + /* > >>> + * Pages of statically shared memory shall be included > >>> + * in domain_tot_pages(). > >>> + */ > >>> + d->max_pages += PFN_DOWN(*psize); > >> > >> ... it sounds a bit strange to use psize here. If psize, can't be > >> modified than it should probably not be a pointer. > >> > >> Also, where do you check that d->max_pages will not overflow? > >> > > > > I'll check the overflow as follows: > > See above about the check. > > > " > > nr_pfns = PFN_DOWN(psize); > > if ( d->max_page + nr_pfns > UINT_MAX ) > > { > > printk(XENLOG_ERR "%pd: Over-allocation for d->max_pages: %lu.\n", > > d, psize); > > return INVALID_MFN; > > } > > d->max_pages += nr_pfns; > > " > > > >>> + > >>> + return acquire_static_memory_bank(d, NULL, addr_cells, size_cells, > >>> + pbase, psize); > >>> + > >>> +} > >>> + > >>> +/* > >>> + * Func allocate_shared_memory is supposed to be only called > >> > >> I am a bit concerned with the word "supposed". Are you implying that > >> it may be called by someone that is not the owner? If not, then it > >> should be "should". > >> > >> Also NIT: Spell out completely "func". I.e "The function". > >> > >>> + * from the owner. > >> > >> I read from as "current should be the owner". But I guess this is not > >> what you mean here. Instead it looks like you mean "d" is the owner. > >> So I would write "d should be the owner of the shared area". > >> > >> It would be good to have a check/ASSERT confirm this (assuming this > >> is easy to write). > >> > > > > The check is already in the calling path, I guess... > > Can you please confirm it? > I mean that allocate_shared_memory is only called under the following condition, and it confirms it is the right owner. " if ( (owner_dom_io && !is_shm_allocated_to_domio(pbase)) || (!owner_dom_io && strcmp(role_str, "owner") == 0) ) { /* Allocate statically shared pages to the owner domain. */ ret = allocate_shared_memory(owner_dom_io ? dom_io : d, addr_cells, size_cells, pbase, psize, gbase); " TBH, apart from that, I don't know how to check if the input d is the right owner, or am I misunderstanding some your suggestion here? > [...] > > >>> + prop = dt_find_property(shm_node, "xen,shared-mem", NULL); > >>> + if ( !prop ) > >>> + { > >>> + printk("Shared memory node does not provide > >>> + \"xen,shared- > >> mem\" property.\n"); > >>> + return -ENOENT; > >>> + } > >>> + cells = (const __be32 *)prop->value; > >>> + /* xen,shared-mem = <pbase, psize, gbase>; */ > >>> + device_tree_get_reg(&cells, addr_cells, size_cells, &pbase, > >>> &psize); > >>> + ASSERT(IS_ALIGNED(pbase, PAGE_SIZE) && IS_ALIGNED(psize, > >>> + PAGE_SIZE)); > >> > >> See above about what ASSERT()s are for. > >> > > > > Do you think address was suitably checked here, is it enough? > > As I wrote before, ASSERT() should not be used to check user inputs. > They need to happen in both debug and production build. > > > If it is enough, I'll modify above ASSERT() to mfn_valid() > > It is not clear what ASSERT() you are referring to. > For whether page is aligned, I will add the below check: " if ( !IS_ALIGNED(pbase, PAGE_SIZE) || !IS_ALIGNED(psize, PAGE_SIZE) || !IS_ALIGNED(gbase, PAGE_SIZE) ) { printk("%pd: physical address %lu, size %lu or guest address %lu is not suitably aligned.\n", d, pbase, psize, gbase); return -EINVAL; } " For whether the whole address range is valid, I will add the below check: " for ( i = 0; i < PFN_DOWN(psize); i++ ) if ( !mfn_valid(mfn_add(maddr_to_mfn(pbase), i)) ) { printk("%pd: invalid physical address %"PRI_paddr" or size %"PRI_paddr"\n", d, pbase, psize); return -EINVAL; } " > Cheers, > > -- > Julien Grall
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |