From ffda547469694ff22b6c8d0bc23436c9b4ce84ec Mon Sep 17 00:00:00 2001 From: Julien Grall Date: Fri, 20 May 2016 14:37:42 +0100 Subject: [PATCH] xen/arm: p2m: Release the p2m lock before undoing the mappings Since commit 4b25423a "arch/arm: unmap partially-mapped memory regions", Xen has been undoing the P2M mappings when an error occurred during insertion or memory allocation. This is done by calling recursively apply_p2m_changes, however the second call is done with the p2m lock taken which will result in a deadlock for the current processor. The p2m lock is here to protect 2 threads modifying concurrently the page tables. However, it does not guarantee the ordering of the changes. I.e if 2 threads request change on regions that overlaps, then the result is undefined. Therefore it is fine to move the recursive call to undo the changes after the lock is released. Signed-off-by: Julien Grall Reviewed-by: Wei Chen Reviewed-by: Stefano Stabellini Tested-by: Wei Chen Signed-off-by: Stefano Stabellini --- xen/arch/arm/p2m.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index 993f776471..62f02301df 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -909,6 +909,14 @@ static int apply_p2m_changes(struct domain *d, rc = 0; out: + for ( level = P2M_ROOT_LEVEL; level < 4; level ++ ) + { + if ( mappings[level] ) + unmap_domain_page(mappings[level]); + } + + spin_unlock(&p2m->lock); + if ( rc < 0 && ( op == INSERT || op == ALLOCATE ) && addr != start_gpaddr ) { @@ -921,14 +929,6 @@ out: mattr, p2m_invalid); } - for ( level = P2M_ROOT_LEVEL; level < 4; level ++ ) - { - if ( mappings[level] ) - unmap_domain_page(mappings[level]); - } - - spin_unlock(&p2m->lock); - return rc; }