[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 2/9] xen/arm: allocate static shared memory to the default owner dom_io
On Fri, 6 May 2022, 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. > > 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> > --- > 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 | 133 +++++++++++++++++++++++++++++++++++- > xen/common/domain.c | 18 ++++- > 2 files changed, 148 insertions(+), 3 deletions(-) > > diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c > index 1472ca4972..e97bb6eeba 100644 > --- a/xen/arch/arm/domain_build.c > +++ b/xen/arch/arm/domain_build.c > @@ -527,7 +527,13 @@ 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); > + /* > + * acquire_static_memory_bank() is also used for acquiring static shared > + * memory, in such case, we don't need to parse 'cell' here since it is > + * already parsed in process_shm(). > + */ I would prefer if the comment was moved on top of acquire_static_memory_bank and rephrased as: /* * If cell is NULL, pbase and psize should hold valid values. * Otherwise, cell will be populated together with pbase and psize. */ Other than that, it looks good. I'll leave it to Jan to comment on the in-code comment in xen/common/domain.c. > + if ( cell ) > + device_tree_get_reg(cell, addr_cells, size_cells, pbase, psize); > ASSERT(IS_ALIGNED(*pbase, PAGE_SIZE) && IS_ALIGNED(*psize, PAGE_SIZE)); > if ( PFN_DOWN(*psize) > UINT_MAX ) > { > @@ -751,6 +757,125 @@ static void __init assign_static_memory_11(struct > domain *d, > panic("Failed to assign requested static memory for direct-map domain > %pd.", > d); > } > + > +#ifdef CONFIG_STATIC_SHM > +/* > + * This function checks whether the static shared memory region is > + * already allocated to dom_io. > + */ > +static bool __init is_shm_allocated_to_domio(paddr_t pbase) > +{ > + struct page_info *page; > + > + page = maddr_to_page(pbase); > + ASSERT(page); > + > + if ( page_get_owner(page) == NULL ) > + return false; > + > + ASSERT(page_get_owner(page) == dom_io); > + 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) > +{ > + /* > + * Pages of statically shared memory shall be included > + * in domain_tot_pages(). > + */ > + d->max_pages += PFN_DOWN(*psize); > + > + return acquire_static_memory_bank(d, NULL, addr_cells, size_cells, > + pbase, psize); > + > +} > + > +/* > + * Func allocate_shared_memory is supposed to be only called > + * from the owner. > + */ > +static int __init allocate_shared_memory(struct domain *d, > + u32 addr_cells, u32 size_cells, > + paddr_t pbase, paddr_t psize) > +{ > + mfn_t smfn; > + > + dprintk(XENLOG_INFO, > + "Allocate static shared memory BANK > %#"PRIpaddr"-%#"PRIpaddr".\n", > + pbase, pbase + psize); > + > + smfn = acquire_shared_memory_bank(d, addr_cells, size_cells, &pbase, > + &psize); > + if ( mfn_eq(smfn, INVALID_MFN) ) > + return -EINVAL; > + > + /* > + * DOMID_IO is the domain, like DOMID_XEN, that is not auto-translated. > + * It sees RAM 1:1 and we do not need to create P2M mapping for it > + */ > + ASSERT(d == dom_io); > + return 0; > +} > + > +static int __init process_shm(struct domain *d, > + const struct dt_device_node *node) > +{ > + struct dt_device_node *shm_node; > + int ret = 0; > + const struct dt_property *prop; > + const __be32 *cells; > + u32 shm_id; > + u32 addr_cells, size_cells; > + paddr_t gbase, pbase, psize; > + > + dt_for_each_child_node(node, shm_node) > + { > + if ( !dt_device_is_compatible(shm_node, > "xen,domain-shared-memory-v1") ) > + continue; > + > + if ( !dt_property_read_u32(shm_node, "xen,shm-id", &shm_id) ) > + { > + printk("Shared memory node does not provide \"xen,shm-id\" > property.\n"); > + return -ENOENT; > + } > + > + addr_cells = dt_n_addr_cells(shm_node); > + size_cells = dt_n_size_cells(shm_node); > + 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)); > + gbase = dt_read_number(cells, addr_cells); > + > + /* TODO: Consider owner domain is not the default dom_io. */ > + /* > + * Per static shared memory region could be shared between multiple > + * domains. > + * In case re-allocating the same shared memory region, we check > + * if it is already allocated to the default owner dom_io before > + * the actual allocation. > + */ > + if ( !is_shm_allocated_to_domio(pbase) ) > + { > + /* Allocate statically shared pages to the default owner dom_io. > */ > + ret = allocate_shared_memory(dom_io, addr_cells, size_cells, > + pbase, psize); > + if ( ret ) > + return ret; > + } > + } > + > + return 0; > +} > +#endif /* CONFIG_STATIC_SHM */ > #else > static void __init allocate_static_memory(struct domain *d, > struct kernel_info *kinfo, > @@ -3149,6 +3274,12 @@ static int __init construct_domU(struct domain *d, > else > assign_static_memory_11(d, &kinfo, node); > > +#ifdef CONFIG_STATIC_SHM > + rc = process_shm(d, node); > + if ( rc < 0 ) > + return rc; > +#endif > + > /* > * Base address and irq number are needed when creating vpl011 device > * tree node in prepare_dtb_domU, so initialization on related variables > diff --git a/xen/common/domain.c b/xen/common/domain.c > index 8d2c2a9897..0c41ecb197 100644 > --- a/xen/common/domain.c > +++ b/xen/common/domain.c > @@ -777,8 +777,22 @@ void __init setup_system_domains(void) > > /* > * Initialise our DOMID_IO domain. > - * This domain owns I/O pages that are within the range of the page_info > - * array. Mappings occur at the priv of the caller. > + * DOMID_IO is used for mapping memory and MMIO regions when no explicit > + * Domain need to be specified. > + * > + * For instance, DOMID_IO is the owner of memory pre-shared among > + * multiple domains at boot time, when no explicit owner is specified. > + * > + * Also, DOMID_IO is used to restrict page-table updates to mapping I/O > + * memory. Although no Foreign Domain need to be specified to map I/O > + * pages, DOMID_IO is useful to ensure that no mappings to the OS's own > + * heap are accidentally installed. (e.g., in Linux this could cause > + * havoc as reference counts aren't adjusted on the I/O-mapping code > + * path). This only makes sense as HYPERVISOR_mmu_update()'s and > + * HYPERVISOR_update_va_mapping_otherdomain()'s "foreigndom" argument. > + * For HYPERVISOR_mmu_update() context it can be specified by any > + * calling domain, otherwise it's only permitted if the caller is > + * privileged. > * Quarantined PCI devices will be associated with this domain. > */ > dom_io = domain_create(DOMID_IO, NULL, 0); > -- > 2.25.1 >
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |