xen/arm: update p2m_set_allocation() prototype

p2m_set_allocation() uses a bool *preempted out-argument that overloads two
meanings. When non-NULL, the value written back (true) duplicates information
already carried by the -ERESTART return code — pure redundancy, which the
caller-side ASSERT(preempted == (rc == -ERESTART)) only documents. Separately,
a NULL pointer is an implicit calling convention meaning "preemption is not
permitted in this context".

Replace the pointer with a plain bool can_preempt that explicitly controls
whether the preemption check runs, making the NULL-to-suppress convention
type-safe and self-documenting, and rely on the -ERESTART return code alone to
report that preemption occurred.

Since p2m_set_allocation() is called by the common dom0less build code,
move its declaration from the ARM-specific asm/p2m.h to xen/p2m-common.h.

Reported-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@gmail.com>
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
This commit is contained in:
Oleksii Kurochko authored and Jan Beulich committed 2026-08-03 09:49:00 +02:00
1 parent 00af54ff6a
commit 04073cd5f6
7 files changed
+20 -33

No files matched your search

-1
View File
@@ -238,7 +238,6 @@ void p2m_restore_state(struct vcpu *n);
/* Print debugging/statistial info about a domain's p2m */ /* Print debugging/statistial info about a domain's p2m */
void p2m_dump_info(struct domain *d); void p2m_dump_info(struct domain *d);
int p2m_set_allocation(struct domain *d, unsigned long pages, bool *preempted);
int p2m_teardown_allocation(struct domain *d); int p2m_teardown_allocation(struct domain *d);
static inline void p2m_write_lock(struct p2m_domain *p2m) static inline void p2m_write_lock(struct p2m_domain *p2m)
+6 -18
View File
@@ -65,12 +65,7 @@ int arch_get_paging_mempool_size(struct domain *d, uint64_t *size)
return 0; return 0;
} }
/* int p2m_set_allocation(struct domain *d, unsigned long pages, bool can_preempt)
* Set the pool of pages to the required number of pages.
* Returns 0 for success, non-zero for failure.
* Call with d->arch.paging.lock held.
*/
int p2m_set_allocation(struct domain *d, unsigned long pages, bool *preempted)
{ {
struct page_info *pg; struct page_info *pg;
@@ -112,11 +107,8 @@ int p2m_set_allocation(struct domain *d, unsigned long pages, bool *preempted)
break; break;
/* Check to see if we need to yield and try again */ /* Check to see if we need to yield and try again */
if ( preempted && general_preempt_check() ) if ( can_preempt && general_preempt_check() )
{
*preempted = true;
return -ERESTART; return -ERESTART;
}
} }
return 0; return 0;
@@ -125,7 +117,6 @@ int p2m_set_allocation(struct domain *d, unsigned long pages, bool *preempted)
int arch_set_paging_mempool_size(struct domain *d, uint64_t size) int arch_set_paging_mempool_size(struct domain *d, uint64_t size)
{ {
unsigned long pages = size >> PAGE_SHIFT; unsigned long pages = size >> PAGE_SHIFT;
bool preempted = false;
int rc; int rc;
if ( (size & ~PAGE_MASK) || /* Non page-sized request? */ if ( (size & ~PAGE_MASK) || /* Non page-sized request? */
@@ -133,27 +124,24 @@ int arch_set_paging_mempool_size(struct domain *d, uint64_t size)
return -EINVAL; return -EINVAL;
spin_lock(&d->arch.paging.lock); spin_lock(&d->arch.paging.lock);
rc = p2m_set_allocation(d, pages, &preempted); rc = p2m_set_allocation(d, pages, /* can_preempt */ true);
spin_unlock(&d->arch.paging.lock); spin_unlock(&d->arch.paging.lock);
ASSERT(preempted == (rc == -ERESTART));
return rc; return rc;
} }
int p2m_teardown_allocation(struct domain *d) int p2m_teardown_allocation(struct domain *d)
{ {
int ret = 0; int ret = 0;
bool preempted = false;
spin_lock(&d->arch.paging.lock); spin_lock(&d->arch.paging.lock);
if ( d->arch.paging.p2m_total_pages != 0 ) if ( d->arch.paging.p2m_total_pages != 0 )
{ {
ret = p2m_set_allocation(d, 0, &preempted); ret = p2m_set_allocation(d, 0, /* can_preempt */ true);
if ( preempted ) if ( ret == -ERESTART )
{ {
spin_unlock(&d->arch.paging.lock); spin_unlock(&d->arch.paging.lock);
return -ERESTART; return ret;
} }
ASSERT(d->arch.paging.p2m_total_pages == 0); ASSERT(d->arch.paging.p2m_total_pages == 0);
} }
+1 -1
View File
@@ -9,7 +9,7 @@ struct page_info;
int paging_domain_init(struct domain *d); int paging_domain_init(struct domain *d);
int paging_freelist_adjust(struct domain *d, unsigned long pages, int paging_freelist_adjust(struct domain *d, unsigned long pages,
bool *preempted); bool can_preempt);
int paging_ret_to_domheap(struct domain *d, unsigned int nr_pages); int paging_ret_to_domheap(struct domain *d, unsigned int nr_pages);
int paging_refill_from_domheap(struct domain *d, unsigned int nr_pages); int paging_refill_from_domheap(struct domain *d, unsigned int nr_pages);
+2 -7
View File
@@ -428,17 +428,12 @@ int p2m_init(struct domain *d, const struct xen_domctl_createdomain *config)
return 0; return 0;
} }
/* int p2m_set_allocation(struct domain *d, unsigned long pages, bool can_preempt)
* Set the pool of pages to the required number of pages.
* Returns 0 for success, non-zero for failure.
* Call with d->arch.paging.lock held.
*/
int p2m_set_allocation(struct domain *d, unsigned long pages, bool *preempted)
{ {
struct p2m_domain *p2m = p2m_get_hostp2m(d); struct p2m_domain *p2m = p2m_get_hostp2m(d);
int rc; int rc;
if ( (rc = paging_freelist_adjust(d, pages, preempted)) ) if ( (rc = paging_freelist_adjust(d, pages, can_preempt)) )
return rc; return rc;
/* /*
+2 -5
View File
@@ -47,7 +47,7 @@ static int _paging_add_to_freelist(struct domain *d)
} }
int paging_freelist_adjust(struct domain *d, unsigned long pages, int paging_freelist_adjust(struct domain *d, unsigned long pages,
bool *preempted) bool can_preempt)
{ {
ASSERT(spin_is_locked(&d->arch.paging.lock)); ASSERT(spin_is_locked(&d->arch.paging.lock));
@@ -66,11 +66,8 @@ int paging_freelist_adjust(struct domain *d, unsigned long pages,
return rc; return rc;
/* Check to see if we need to yield and try again */ /* Check to see if we need to yield and try again */
if ( preempted && general_preempt_check() ) if ( can_preempt && general_preempt_check() )
{
*preempted = true;
return -ERESTART; return -ERESTART;
}
} }
return 0; return 0;
+1 -1
View File
@@ -760,7 +760,7 @@ static int __init domain_p2m_set_allocation(struct domain *d, uint64_t mem,
domain_p2m_pages(mem, d->max_vcpus); domain_p2m_pages(mem, d->max_vcpus);
spin_lock(&d->arch.paging.lock); spin_lock(&d->arch.paging.lock);
rc = p2m_set_allocation(d, p2m_pages, NULL); rc = p2m_set_allocation(d, p2m_pages, /* can_preempt */ false);
spin_unlock(&d->arch.paging.lock); spin_unlock(&d->arch.paging.lock);
return rc; return rc;
+8
View File
@@ -43,5 +43,13 @@ int __must_check check_get_page_from_gfn(struct domain *d, gfn_t gfn,
bool readonly, p2m_type_t *p2mt_p, bool readonly, p2m_type_t *p2mt_p,
struct page_info **page_p); struct page_info **page_p);
/*
* Set the pool of pages to the required number of pages.
* Returns 0 for success, -ERESTART if preempted (only when can_preempt is
* true), or a negative error code on failure.
* Call with d->arch.paging.lock held.
*/
int __must_check p2m_set_allocation(struct domain *d, unsigned long pages,
bool can_preempt);
#endif /* _XEN_P2M_COMMON_H */ #endif /* _XEN_P2M_COMMON_H */
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.