aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/resource.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/kernel/resource.c b/kernel/resource.c
index 89d50412508c..e15b922d4ba4 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -392,7 +392,7 @@ static int find_resource(struct resource *root, struct resource *new,
392 void *alignf_data) 392 void *alignf_data)
393{ 393{
394 struct resource *this = root->child; 394 struct resource *this = root->child;
395 struct resource tmp = *new, alloc; 395 struct resource tmp = *new, avail, alloc;
396 396
397 tmp.start = root->start; 397 tmp.start = root->start;
398 /* 398 /*
@@ -410,14 +410,19 @@ static int find_resource(struct resource *root, struct resource *new,
410 tmp.end = root->end; 410 tmp.end = root->end;
411 411
412 resource_clip(&tmp, min, max); 412 resource_clip(&tmp, min, max);
413 tmp.start = ALIGN(tmp.start, align);
414 413
415 alloc.start = alignf(alignf_data, &tmp, size, align); 414 /* Check for overflow after ALIGN() */
416 alloc.end = alloc.start + size - 1; 415 avail = *new;
417 if (resource_contains(&tmp, &alloc)) { 416 avail.start = ALIGN(tmp.start, align);
418 new->start = alloc.start; 417 avail.end = tmp.end;
419 new->end = alloc.end; 418 if (avail.start >= tmp.start) {
420 return 0; 419 alloc.start = alignf(alignf_data, &avail, size, align);
420 alloc.end = alloc.start + size - 1;
421 if (resource_contains(&avail, &alloc)) {
422 new->start = alloc.start;
423 new->end = alloc.end;
424 return 0;
425 }
421 } 426 }
422 if (!this) 427 if (!this)
423 break; 428 break;