|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] page-alloc: detect double free earlier
>>> On 09.05.19 at 14:50, <andrew.cooper3@xxxxxxxxxx> wrote:
> On 09/05/2019 13:35, Jan Beulich wrote:
>> Right now this goes unnoticed until some subsequent page allocator
>> operation stumbles across the thus corrupted list. We can do better:
>> Only PGC_state_inuse and PGC_state_offlining pages can legitimately be
>> passed to free_heap_pages().
>>
>> Take the opportunity and also restrict the PGC_broken check to the
>> PGC_state_offlining case, as only pages of that type or
>> PGC_state_offlined may have this flag set on them. Similarly, since
>> PGC_state_offlined is not a valid input state, the setting of "tainted"
>> can be restricted to just this case.
>>
>> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
>
> Acked-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, with a suggestion.
Thanks.
>> --- a/xen/common/page_alloc.c
>> +++ b/xen/common/page_alloc.c
>> @@ -1409,13 +1409,22 @@ static void free_heap_pages(
>> * in its pseudophysical address space).
>> * In all the above cases there can be no guest mappings of this
>> page.
>> */
>> - ASSERT(!page_state_is(&pg[i], offlined));
>> - pg[i].count_info =
>> - ((pg[i].count_info & PGC_broken) |
>> - (page_state_is(&pg[i], offlining)
>> - ? PGC_state_offlined : PGC_state_free));
>> - if ( page_state_is(&pg[i], offlined) )
>> + switch ( pg[i].count_info & PGC_state )
>> + {
>> + case PGC_state_inuse:
>> + BUG_ON(pg[i].count_info & PGC_broken);
>> + pg[i].count_info = PGC_state_free;
>> + break;
>> +
>> + case PGC_state_offlining:
>> + pg[i].count_info = (pg[i].count_info & PGC_broken) |
>> + PGC_state_offlined;
>> tainted = 1;
>> + break;
>> +
>> + default:
>
> Given that this is a fully fatal condition, it would be helpful to at
> least print the state we found here. For cases other than
> PGC_state_free, it would probably be a very useful piece of information
> for diagnosing what went wrong.
Funny you should say this - I have the debugging patch below on top
in my tree. I could easily submit this as a standalone follow-on patch.
Jan
--- unstable.orig/xen/common/page_alloc.c
+++ unstable/xen/common/page_alloc.c
@@ -1014,7 +1014,14 @@ static struct page_info *alloc_heap_page
for ( i = 0; i < (1 << order); i++ )
{
/* Reference count must continuously be zero for free pages. */
- BUG_ON((pg[i].count_info & ~PGC_need_scrub) != PGC_state_free);
+ if ( (pg[i].count_info & ~PGC_need_scrub) != PGC_state_free )
+ {
+ printk(XENLOG_ERR "pg[%x] m=%lx c=%lx o=%x v=%lx t=%x\n",
+ i, mfn_x(page_to_mfn(pg + i)),
+ pg[i].count_info, pg[i].v.free.order,
+ pg[i].u.free.val, pg[i].tlbflush_timestamp);
+ BUG();
+ }
/* PGC_need_scrub can only be set if first_dirty is valid */
ASSERT(first_dirty != INVALID_DIRTY_IDX || !(pg[i].count_info &
PGC_need_scrub));
@@ -1423,6 +1430,10 @@ static void free_heap_pages(
break;
default:
+ printk(XENLOG_ERR "pg[%x] m=%lx c=%lx o=%x v=%lx t=%x\n",
+ i, mfn_x(page_to_mfn(pg + i)),
+ pg[i].count_info, pg[i].v.free.order,
+ pg[i].u.free.val, pg[i].tlbflush_timestamp);
BUG();
}
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |