xen/arm: Avoid open-coding the relinquish state machine

In commit 0dfffe01d5 "x86: Improve the efficiency of
domain_relinquish_resources()", the x86 version of the function has been
reworked to avoid open-coding the state machine and also add more
documentation.

Bring the Arm version on par with x86 by introducing a documented
PROGRESS() macro to avoid latent bugs and make the new PROG_* states
private to domain_relinquish_resources().

Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Julien Grall <jgrall@amazon.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
This commit is contained in:
Julien Grall authored and Stefano Stabellini committed 2020-04-21 16:46:25 -07:00
1 parent 0796cb907f
commit 5730ac3c83
2 files changed
+38 -31

No files matched your search

+37 -23
View File
@@ -674,7 +674,6 @@ int arch_domain_create(struct domain *d,
int rc, count = 0;
BUILD_BUG_ON(GUEST_MAX_VCPUS < MAX_VIRT_CPUS);
d->arch.relmem = RELMEM_not_started;
/* Idle domains do not need this setup */
if ( is_idle_domain(d) )
@@ -950,13 +949,41 @@ static int relinquish_memory(struct domain *d, struct page_list_head *list)
return ret;
}
/*
* Record the current progress. Subsequent hypercall continuations will
* logically restart work from this point.
*
* PROGRESS() markers must not be in the middle of loops. The loop
* variable isn't preserved accross a continuation.
*
* To avoid redundant work, there should be a marker before each
* function which may return -ERESTART.
*/
enum {
PROG_tee = 1,
PROG_xen,
PROG_page,
PROG_mapping,
PROG_done,
};
#define PROGRESS(x) \
d->arch.rel_priv = PROG_ ## x; \
/* Fallthrough */ \
case PROG_ ## x
int domain_relinquish_resources(struct domain *d)
{
int ret = 0;
switch ( d->arch.relmem )
/*
* This hypercall can take minutes of wallclock time to complete. This
* logic implements a co-routine, stashing state in struct domain across
* hypercall continuation boundaries.
*/
switch ( d->arch.rel_priv )
{
case RELMEM_not_started:
case 0:
ret = iommu_release_dt_devices(d);
if ( ret )
return ret;
@@ -967,42 +994,27 @@ int domain_relinquish_resources(struct domain *d)
*/
domain_vpl011_deinit(d);
d->arch.relmem = RELMEM_tee;
/* Fallthrough */
case RELMEM_tee:
PROGRESS(tee):
ret = tee_relinquish_resources(d);
if (ret )
return ret;
d->arch.relmem = RELMEM_xen;
/* Fallthrough */
case RELMEM_xen:
PROGRESS(xen):
ret = relinquish_memory(d, &d->xenpage_list);
if ( ret )
return ret;
d->arch.relmem = RELMEM_page;
/* Fallthrough */
case RELMEM_page:
PROGRESS(page):
ret = relinquish_memory(d, &d->page_list);
if ( ret )
return ret;
d->arch.relmem = RELMEM_mapping;
/* Fallthrough */
case RELMEM_mapping:
PROGRESS(mapping):
ret = relinquish_p2m_mapping(d);
if ( ret )
return ret;
d->arch.relmem = RELMEM_done;
/* Fallthrough */
case RELMEM_done:
PROGRESS(done):
break;
default:
@@ -1012,6 +1024,8 @@ int domain_relinquish_resources(struct domain *d)
return 0;
}
#undef PROGRESS
void arch_dump_domain_info(struct domain *d)
{
p2m_dump_info(d);
+1 -8
View File
@@ -56,14 +56,7 @@ struct arch_domain
struct vmmio vmmio;
/* Continuable domain_relinquish_resources(). */
enum {
RELMEM_not_started,
RELMEM_tee,
RELMEM_xen,
RELMEM_page,
RELMEM_mapping,
RELMEM_done,
} relmem;
unsigned int rel_priv;
struct {
uint64_t offset;
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.