xen/arm: Add additional reference to owner domain when the owner is allocated

Borrower domain will fail to get a page ref using the owner domain
during allocation, when the owner is created after borrower.

So here, we decide to get and add the right amount of reference, which
is the number of borrowers, when the owner is allocated.

Signed-off-by: Penny Zheng <penny.zheng@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Acked-by: Julien Grall <jgrall@amazon.com>
This commit is contained in:
Penny Zheng authored and Stefano Stabellini committed 2022-09-09 12:58:00 -07:00
1 parent 5951b856d8
commit 041957bad3
1 file changed
+60
+60
View File
@@ -763,6 +763,30 @@ static void __init assign_static_memory_11(struct domain *d,
}
#ifdef CONFIG_STATIC_SHM
static int __init acquire_nr_borrower_domain(struct domain *d,
paddr_t pbase, paddr_t psize,
unsigned long *nr_borrowers)
{
unsigned int bank;
/* Iterate reserved memory to find requested shm bank. */
for ( bank = 0 ; bank < bootinfo.reserved_mem.nr_banks; bank++ )
{
paddr_t bank_start = bootinfo.reserved_mem.bank[bank].start;
paddr_t bank_size = bootinfo.reserved_mem.bank[bank].size;
if ( (pbase == bank_start) && (psize == bank_size) )
break;
}
if ( bank == bootinfo.reserved_mem.nr_banks )
return -ENOENT;
*nr_borrowers = bootinfo.reserved_mem.bank[bank].nr_shm_borrowers;
return 0;
}
/*
* This function checks whether the static shared memory region is
* already allocated to dom_io.
@@ -829,6 +853,8 @@ static int __init assign_shared_memory(struct domain *d,
{
mfn_t smfn;
int ret = 0;
unsigned long nr_pages, nr_borrowers, i;
struct page_info *page;
dprintk(XENLOG_INFO,
"%pd: allocate static shared memory BANK %#"PRIpaddr"-%#"PRIpaddr".\n",
@@ -842,6 +868,7 @@ static int __init assign_shared_memory(struct domain *d,
* DOMID_IO is not auto-translated (i.e. it sees RAM 1:1). So we do not need
* to create mapping in the P2M.
*/
nr_pages = PFN_DOWN(psize);
if ( d != dom_io )
{
ret = guest_physmap_add_pages(d, gaddr_to_gfn(gbase), smfn,
@@ -853,6 +880,39 @@ static int __init assign_shared_memory(struct domain *d,
}
}
/*
* Get the right amount of references per page, which is the number of
* borrower domains.
*/
ret = acquire_nr_borrower_domain(d, pbase, psize, &nr_borrowers);
if ( ret )
return ret;
/*
* Instead of letting borrower domain get a page ref, we add as many
* additional reference as the number of borrowers when the owner
* is allocated, since there is a chance that owner is created
* after borrower.
* So if the borrower is created first, it will cause adding pages
* in the P2M without reference.
*/
page = mfn_to_page(smfn);
for ( i = 0; i < nr_pages; i++ )
{
if ( !get_page_nr(page + i, d, nr_borrowers) )
{
printk(XENLOG_ERR
"Failed to add %lu references to page %"PRI_mfn".\n",
nr_borrowers, mfn_x(smfn) + i);
goto fail;
}
}
return 0;
fail:
while ( --i >= 0 )
put_page_nr(page + i, nr_borrowers);
return ret;
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.