58 lines
1.7 KiB
Diff
58 lines
1.7 KiB
Diff
|
# HG changeset patch
|
||
|
# User Keir Fraser <keir.fraser@citrix.com>
|
||
|
# 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 <keir.fraser@citrix.com>
|
||
|
|
||
|
--- 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);
|
||
|
}
|
||
|
|
||
|
/*
|