[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging] xen/arm: assign static shared memory to the default owner dom_io
commit 5597f32f409c789199749b82585b96fef6969d21 Author: Penny Zheng <penny.zheng@xxxxxxx> AuthorDate: Thu Sep 8 21:55:06 2022 +0800 Commit: Stefano Stabellini <stefano.stabellini@xxxxxxx> CommitDate: Fri Sep 9 12:57:58 2022 -0700 xen/arm: assign static shared memory to the default owner dom_io 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. And DOMID_IO is a fake domain and is not described in the Device-Tree. Therefore When the owner of the shared region is DOMID_IO, we will only find the borrowers when parsing the Device-Tree. When we found the first borrower of the region, we need to assign the region to DOMID_IO 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: Julien Grall <jgrall@xxxxxxxxxx> --- xen/arch/arm/domain_build.c | 160 ++++++++++++++++++++++++++++++++++++++++++++ xen/common/domain.c | 3 + 2 files changed, 163 insertions(+) diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index 7412303d20..4746155211 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -761,6 +761,160 @@ 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; + struct domain *d; + + page = maddr_to_page(pbase); + d = page_get_owner_and_reference(page); + if ( d == NULL ) + return false; + put_page(page); + + if ( d != dom_io ) + { + printk(XENLOG_ERR + "shm memory node has already been allocated to a specific owner %pd, Please check your configuration\n", + d); + return false; + } + + return true; +} + +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 + * into domain_tot_pages(). + */ + nr_pfns = PFN_DOWN(psize); + if ( (UINT_MAX - d->max_pages) < nr_pfns ) + { + printk(XENLOG_ERR "%pd: Over-allocation for d->max_pages: %lu.\n", + d, nr_pfns); + 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); + d->max_pages -= nr_pfns; + return INVALID_MFN; + } + + return smfn; +} + +static int __init assign_shared_memory(struct domain *d, + uint32_t addr_cells, uint32_t size_cells, + paddr_t pbase, paddr_t psize) +{ + mfn_t smfn; + + dprintk(XENLOG_INFO, + "%pd: allocate static shared memory BANK %#"PRIpaddr"-%#"PRIpaddr".\n", + d, pbase, pbase + psize); + + smfn = acquire_shared_memory_bank(d, pbase, psize); + if ( mfn_eq(smfn, INVALID_MFN) ) + return -EINVAL; + + /* + * DOMID_IO is not auto-translated (i.e. it sees RAM 1:1). So we do not need + * to create mapping in the P2M. + */ + 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; + + dt_for_each_child_node(node, shm_node) + { + const struct dt_property *prop; + const __be32 *cells; + uint32_t addr_cells, size_cells; + paddr_t gbase, pbase, psize; + int ret = 0; + unsigned int i; + + if ( !dt_device_is_compatible(shm_node, "xen,domain-shared-memory-v1") ) + continue; + + /* + * xen,shared-mem = <pbase, gbase, size>; + * TODO: pbase is optional. + */ + 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); + BUG_ON(!prop); + cells = (const __be32 *)prop->value; + device_tree_get_reg(&cells, addr_cells, addr_cells, &pbase, &gbase); + psize = dt_read_number(cells, size_cells); + if ( !IS_ALIGNED(pbase, PAGE_SIZE) || !IS_ALIGNED(gbase, PAGE_SIZE) ) + { + printk("%pd: physical address 0x%"PRIpaddr", or guest address 0x%"PRIpaddr" is not suitably aligned.\n", + d, pbase, gbase); + return -EINVAL; + } + if ( !IS_ALIGNED(psize, PAGE_SIZE) ) + { + printk("%pd: size 0x%"PRIpaddr" is not suitably aligned\n", + d, psize); + return -EINVAL; + } + + for ( i = 0; i < PFN_DOWN(psize); i++ ) + if ( !mfn_valid(mfn_add(maddr_to_mfn(pbase), i)) ) + { + printk("%pd: invalid physical address 0x%"PRI_mfn"\n", + d, mfn_x(mfn_add(maddr_to_mfn(pbase), i))); + return -EINVAL; + } + + /* TODO: Consider owner domain is not the default dom_io. */ + /* + * DOMID_IO is a fake domain and is not described in the Device-Tree. + * Therefore when the owner of the shared region is DOMID_IO, we will + * only find the borrowers. + */ + if ( !is_shm_allocated_to_domio(pbase) ) + { + /* + * We found the first borrower of the region, the owner was not + * specified, so they should be assigned to dom_io. + */ + ret = assign_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, @@ -3386,6 +3540,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 c23f449451..8dd6cd5a8f 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -787,6 +787,9 @@ void __init setup_system_domains(void) * This domain owns I/O pages that are within the range of the page_info * array. Mappings occur at the priv of the caller. * Quarantined PCI devices will be associated with this domain. + * + * DOMID_IO is also the default owner of memory pre-shared among multiple + * domains at boot time. */ dom_io = domain_create(DOMID_IO, NULL, 0); if ( IS_ERR(dom_io) ) -- generated by git-patchbot for /home/xen/git/xen.git#staging
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |