# HG changeset patch # User Keir Fraser # Date 1225193120 0 # Node ID 19549b9766fdd68380ded8efd975c41269ab2801 # Parent 2c20d026bb55722247c0d9ab81c125118a10346f x86: Fix circular page reference destruction in relinquish_memory(). Tested by Jan Beulich and fixes a memory leak, but there is more to be done here. Signed-off-by: Keir Fraser --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1687,7 +1687,6 @@ static int relinquish_memory( { if ( free_page_type(page, x, 0) != 0 ) BUG(); - put_page(page); break; } } --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -1973,6 +1973,7 @@ int free_page_type(struct page_info *pag page->nr_validated_ptes = 1U << PAGETABLE_ORDER; page->partial_pte = 0; } + switch ( type & PGT_type_mask ) { case PGT_l1_page_table: @@ -1998,6 +1999,15 @@ int free_page_type(struct page_info *pag BUG(); } + return rc; +} + + +static int __put_final_page_type( + struct page_info *page, unsigned long type, int preemptible) +{ + int rc = free_page_type(page, type, preemptible); + /* No need for atomic update of type_info here: noone else updates it. */ if ( rc == 0 ) { @@ -2062,7 +2072,7 @@ static int __put_page_type(struct page_i x, nx)) != x) ) continue; /* We cleared the 'valid bit' so we do the clean up. */ - return free_page_type(page, x, preemptible); + return __put_final_page_type(page, x, preemptible); } /*