aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/resource.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bjorn.helgaas@hp.com>2010-10-26 17:41:23 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2010-10-26 18:33:26 -0400
commit6909ba14c25b4db6be2ff89f4fa0fac2d70151a0 (patch)
tree1b663f1bba58f51b94bfc8372bea6d2c9295ec67 /kernel/resource.c
parent5d6b1fa301b13cc651ee717a9b518124dea2f814 (diff)
resources: ensure callback doesn't allocate outside available space
The alignment callback returns a proposed location, which may have been adjusted to avoid ISA aliases or for other architecture-specific reasons. We already had a check ("tmp.start < tmp.end") to make sure the callback doesn't return an area that extends past the available area. This patch reworks the check to make sure it doesn't return an area that extends either below or above the available area. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'kernel/resource.c')
-rw-r--r--kernel/resource.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/kernel/resource.c b/kernel/resource.c
index 26e9f2546923..89d50412508c 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -374,6 +374,11 @@ static void resource_clip(struct resource *res, resource_size_t min,
374 res->end = max; 374 res->end = max;
375} 375}
376 376
377static bool resource_contains(struct resource *res1, struct resource *res2)
378{
379 return res1->start <= res2->start && res1->end >= res2->end;
380}
381
377/* 382/*
378 * Find empty slot in the resource tree given range and alignment. 383 * Find empty slot in the resource tree given range and alignment.
379 */ 384 */
@@ -387,7 +392,7 @@ static int find_resource(struct resource *root, struct resource *new,
387 void *alignf_data) 392 void *alignf_data)
388{ 393{
389 struct resource *this = root->child; 394 struct resource *this = root->child;
390 struct resource tmp = *new; 395 struct resource tmp = *new, alloc;
391 396
392 tmp.start = root->start; 397 tmp.start = root->start;
393 /* 398 /*
@@ -407,10 +412,11 @@ static int find_resource(struct resource *root, struct resource *new,
407 resource_clip(&tmp, min, max); 412 resource_clip(&tmp, min, max);
408 tmp.start = ALIGN(tmp.start, align); 413 tmp.start = ALIGN(tmp.start, align);
409 414
410 tmp.start = alignf(alignf_data, &tmp, size, align); 415 alloc.start = alignf(alignf_data, &tmp, size, align);
411 if (tmp.start < tmp.end && tmp.end - tmp.start >= size - 1) { 416 alloc.end = alloc.start + size - 1;
412 new->start = tmp.start; 417 if (resource_contains(&tmp, &alloc)) {
413 new->end = tmp.start + size - 1; 418 new->start = alloc.start;
419 new->end = alloc.end;
414 return 0; 420 return 0;
415 } 421 }
416 if (!this) 422 if (!this)