From: Steven Rostedt <srostedt@redhat.com>
To: xen-devel@lists.xensource.com
Subject: What's the reason for padding the alloc_bitmap in page_alloc.c?
Date: Fri, 04 Aug 2006 23:55:15 -0400 [thread overview]
Message-ID: <44D416A3.9040103@redhat.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 2617 bytes --]
I see the code in init_boot_allocator that added an extra longword to
the size of alloc_bitmap. Is there really a chance for overrun in
map_alloc or map_free as the comment suggests? I would think that
allocating or freeing more than we have would be considered a bug. I
don't know the history of that padding but I wonder if it is from
another overflow that is fixable. Doing bitmap_size = (max_page + 7)/8
should be enough.
/*
* Allocate space for the allocation bitmap. Include an extra longword
* of padding for possible overrun in map_alloc and map_free.
*/
bitmap_size = max_page / 8;
bitmap_size += sizeof(unsigned long);
bitmap_size = round_pgup(bitmap_size);
alloc_bitmap = (unsigned long *)maddr_to_virt(bitmap_start);
In page_alloc.c end_boot_allocator, there's a slight chance that the
allocated_in_map macro can cause an overflow. This is because it uses
i+1 as the parameter and i goes to i < max_pages (if i == max_pages then
we overflow).
Most of the time, this is ok because the allocation is bigger than
needed. But if it is just right, then we could have a problem.
/* Pages that are free now go to the domain sub-allocator. */
for ( i = 0; i < max_page; i++ )
{
curr_free = next_free;
next_free = !allocated_in_map(i+1);
if ( next_free )
map_alloc(i+1, 1); /* prevent merging in free_heap_pages() */
if ( curr_free )
free_heap_pages(pfn_dom_zone_type(i), mfn_to_page(i), 0);
}
and with allocate_in_map as:
#define allocated_in_map(_pn) \
( !! (alloc_bitmap[(_pn)/PAGES_PER_MAPWORD] & \
(1UL<<((_pn)&(PAGES_PER_MAPWORD-1)))) )
We see here that we are indexing past the bitmap and can cause
problems. I wonder if this was actually happening and the above padding
was done to hide this bug. Well the padding does fix the bug, but I
don't think it's the proper approach.
Attached is a patch to fix the overflow problem in end_boot_allocator.
I'll run it some time without that padding (do bitmap_size = (max_page +
7)/8 instead) and see if there's any other problems. I'll also put a
test into map_alloc and map_free to tell me if something goes past
max_page or bitmap size.
I would hate to have 134,184,960 bytes of memory: 134,184,960 / 4096 =
32,760 : 32,760 / 8 = 4095 : 4095 + 4 = 4099 And now we have an extra
page for the bitmap without it ever being used. (OK that was
hypothetical, but does make a small point. ;)
-- Steve
just in case you want the patch.
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
[-- Attachment #2: hv-page-alloc-buffer-overflow.patch --]
[-- Type: text/x-patch, Size: 1391 bytes --]
diff -r bbabdebc54ad xen/common/page_alloc.c
--- a/xen/common/page_alloc.c Wed Jul 19 21:13:36 2006 +0100
+++ b/xen/common/page_alloc.c Fri Aug 04 22:52:23 2006 -0400
@@ -256,7 +256,7 @@ void end_boot_allocator(void)
void end_boot_allocator(void)
{
unsigned long i, j;
- int curr_free = 0, next_free = 0;
+ int curr_free, prev_free;
memset(avail, 0, sizeof(avail));
@@ -265,15 +265,18 @@ void end_boot_allocator(void)
INIT_LIST_HEAD(&heap[i][j]);
/* Pages that are free now go to the domain sub-allocator. */
- for ( i = 0; i < max_page; i++ )
- {
- curr_free = next_free;
- next_free = !allocated_in_map(i+1);
- if ( next_free )
- map_alloc(i+1, 1); /* prevent merging in free_heap_pages() */
+ prev_free = !allocated_in_map(0);
+ for ( i = 1; i < max_page; i++ )
+ {
+ curr_free = !allocated_in_map(i);
if ( curr_free )
- free_heap_pages(pfn_dom_zone_type(i), mfn_to_page(i), 0);
- }
+ map_alloc(i, 1); /* prevent merging in free_heap_pages() */
+ if ( prev_free )
+ free_heap_pages(pfn_dom_zone_type(i-1), mfn_to_page(i-1), 0);
+ prev_free = curr_free;
+ }
+ if ( prev_free )
+ free_heap_pages(pfn_dom_zone_type(i-1), mfn_to_page(i-1), 0);
}
/* Hand the specified arbitrary page range to the specified heap zone. */
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
next reply other threads:[~2006-08-05 3:55 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-08-05 3:55 Steven Rostedt [this message]
2006-08-05 9:05 ` What's the reason for padding the alloc_bitmap in page_alloc.c? Keir Fraser
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=44D416A3.9040103@redhat.com \
--to=srostedt@redhat.com \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.