aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/memblock.h1
-rw-r--r--mm/memblock.c53
2 files changed, 39 insertions, 15 deletions
diff --git a/include/linux/memblock.h b/include/linux/memblock.h
index 77c60e52939d..9a805ec6e794 100644
--- a/include/linux/memblock.h
+++ b/include/linux/memblock.h
@@ -22,6 +22,7 @@
22struct memblock_region { 22struct memblock_region {
23 phys_addr_t base; 23 phys_addr_t base;
24 phys_addr_t size; 24 phys_addr_t size;
25 unsigned long flags;
25#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP 26#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
26 int nid; 27 int nid;
27#endif 28#endif
diff --git a/mm/memblock.c b/mm/memblock.c
index aab566998b61..270b005ca964 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -255,6 +255,7 @@ static void __init_memblock memblock_remove_region(struct memblock_type *type, u
255 type->cnt = 1; 255 type->cnt = 1;
256 type->regions[0].base = 0; 256 type->regions[0].base = 0;
257 type->regions[0].size = 0; 257 type->regions[0].size = 0;
258 type->regions[0].flags = 0;
258 memblock_set_region_node(&type->regions[0], MAX_NUMNODES); 259 memblock_set_region_node(&type->regions[0], MAX_NUMNODES);
259 } 260 }
260} 261}
@@ -405,7 +406,8 @@ static void __init_memblock memblock_merge_regions(struct memblock_type *type)
405 406
406 if (this->base + this->size != next->base || 407 if (this->base + this->size != next->base ||
407 memblock_get_region_node(this) != 408 memblock_get_region_node(this) !=
408 memblock_get_region_node(next)) { 409 memblock_get_region_node(next) ||
410 this->flags != next->flags) {
409 BUG_ON(this->base + this->size > next->base); 411 BUG_ON(this->base + this->size > next->base);
410 i++; 412 i++;
411 continue; 413 continue;
@@ -425,13 +427,15 @@ static void __init_memblock memblock_merge_regions(struct memblock_type *type)
425 * @base: base address of the new region 427 * @base: base address of the new region
426 * @size: size of the new region 428 * @size: size of the new region
427 * @nid: node id of the new region 429 * @nid: node id of the new region
430 * @flags: flags of the new region
428 * 431 *
429 * Insert new memblock region [@base,@base+@size) into @type at @idx. 432 * Insert new memblock region [@base,@base+@size) into @type at @idx.
430 * @type must already have extra room to accomodate the new region. 433 * @type must already have extra room to accomodate the new region.
431 */ 434 */
432static void __init_memblock memblock_insert_region(struct memblock_type *type, 435static void __init_memblock memblock_insert_region(struct memblock_type *type,
433 int idx, phys_addr_t base, 436 int idx, phys_addr_t base,
434 phys_addr_t size, int nid) 437 phys_addr_t size,
438 int nid, unsigned long flags)
435{ 439{
436 struct memblock_region *rgn = &type->regions[idx]; 440 struct memblock_region *rgn = &type->regions[idx];
437 441
@@ -439,6 +443,7 @@ static void __init_memblock memblock_insert_region(struct memblock_type *type,
439 memmove(rgn + 1, rgn, (type->cnt - idx) * sizeof(*rgn)); 443 memmove(rgn + 1, rgn, (type->cnt - idx) * sizeof(*rgn));
440 rgn->base = base; 444 rgn->base = base;
441 rgn->size = size; 445 rgn->size = size;
446 rgn->flags = flags;
442 memblock_set_region_node(rgn, nid); 447 memblock_set_region_node(rgn, nid);
443 type->cnt++; 448 type->cnt++;
444 type->total_size += size; 449 type->total_size += size;
@@ -450,6 +455,7 @@ static void __init_memblock memblock_insert_region(struct memblock_type *type,
450 * @base: base address of the new region 455 * @base: base address of the new region
451 * @size: size of the new region 456 * @size: size of the new region
452 * @nid: nid of the new region 457 * @nid: nid of the new region
458 * @flags: flags of the new region
453 * 459 *
454 * Add new memblock region [@base,@base+@size) into @type. The new region 460 * Add new memblock region [@base,@base+@size) into @type. The new region
455 * is allowed to overlap with existing ones - overlaps don't affect already 461 * is allowed to overlap with existing ones - overlaps don't affect already
@@ -460,7 +466,8 @@ static void __init_memblock memblock_insert_region(struct memblock_type *type,
460 * 0 on success, -errno on failure. 466 * 0 on success, -errno on failure.
461 */ 467 */
462static int __init_memblock memblock_add_region(struct memblock_type *type, 468static int __init_memblock memblock_add_region(struct memblock_type *type,
463 phys_addr_t base, phys_addr_t size, int nid) 469 phys_addr_t base, phys_addr_t size,
470 int nid, unsigned long flags)
464{ 471{
465 bool insert = false; 472 bool insert = false;
466 phys_addr_t obase = base; 473 phys_addr_t obase = base;
@@ -475,6 +482,7 @@ static int __init_memblock memblock_add_region(struct memblock_type *type,
475 WARN_ON(type->cnt != 1 || type->total_size); 482 WARN_ON(type->cnt != 1 || type->total_size);
476 type->regions[0].base = base; 483 type->regions[0].base = base;
477 type->regions[0].size = size; 484 type->regions[0].size = size;
485 type->regions[0].flags = flags;
478 memblock_set_region_node(&type->regions[0], nid); 486 memblock_set_region_node(&type->regions[0], nid);
479 type->total_size = size; 487 type->total_size = size;
480 return 0; 488 return 0;
@@ -505,7 +513,8 @@ repeat:
505 nr_new++; 513 nr_new++;
506 if (insert) 514 if (insert)
507 memblock_insert_region(type, i++, base, 515 memblock_insert_region(type, i++, base,
508 rbase - base, nid); 516 rbase - base, nid,
517 flags);
509 } 518 }
510 /* area below @rend is dealt with, forget about it */ 519 /* area below @rend is dealt with, forget about it */
511 base = min(rend, end); 520 base = min(rend, end);
@@ -515,7 +524,8 @@ repeat:
515 if (base < end) { 524 if (base < end) {
516 nr_new++; 525 nr_new++;
517 if (insert) 526 if (insert)
518 memblock_insert_region(type, i, base, end - base, nid); 527 memblock_insert_region(type, i, base, end - base,
528 nid, flags);
519 } 529 }
520 530
521 /* 531 /*
@@ -537,12 +547,13 @@ repeat:
537int __init_memblock memblock_add_node(phys_addr_t base, phys_addr_t size, 547int __init_memblock memblock_add_node(phys_addr_t base, phys_addr_t size,
538 int nid) 548 int nid)
539{ 549{
540 return memblock_add_region(&memblock.memory, base, size, nid); 550 return memblock_add_region(&memblock.memory, base, size, nid, 0);
541} 551}
542 552
543int __init_memblock memblock_add(phys_addr_t base, phys_addr_t size) 553int __init_memblock memblock_add(phys_addr_t base, phys_addr_t size)
544{ 554{
545 return memblock_add_region(&memblock.memory, base, size, MAX_NUMNODES); 555 return memblock_add_region(&memblock.memory, base, size,
556 MAX_NUMNODES, 0);
546} 557}
547 558
548/** 559/**
@@ -597,7 +608,8 @@ static int __init_memblock memblock_isolate_range(struct memblock_type *type,
597 rgn->size -= base - rbase; 608 rgn->size -= base - rbase;
598 type->total_size -= base - rbase; 609 type->total_size -= base - rbase;
599 memblock_insert_region(type, i, rbase, base - rbase, 610 memblock_insert_region(type, i, rbase, base - rbase,
600 memblock_get_region_node(rgn)); 611 memblock_get_region_node(rgn),
612 rgn->flags);
601 } else if (rend > end) { 613 } else if (rend > end) {
602 /* 614 /*
603 * @rgn intersects from above. Split and redo the 615 * @rgn intersects from above. Split and redo the
@@ -607,7 +619,8 @@ static int __init_memblock memblock_isolate_range(struct memblock_type *type,
607 rgn->size -= end - rbase; 619 rgn->size -= end - rbase;
608 type->total_size -= end - rbase; 620 type->total_size -= end - rbase;
609 memblock_insert_region(type, i--, rbase, end - rbase, 621 memblock_insert_region(type, i--, rbase, end - rbase,
610 memblock_get_region_node(rgn)); 622 memblock_get_region_node(rgn),
623 rgn->flags);
611 } else { 624 } else {
612 /* @rgn is fully contained, record it */ 625 /* @rgn is fully contained, record it */
613 if (!*end_rgn) 626 if (!*end_rgn)
@@ -649,16 +662,24 @@ int __init_memblock memblock_free(phys_addr_t base, phys_addr_t size)
649 return __memblock_remove(&memblock.reserved, base, size); 662 return __memblock_remove(&memblock.reserved, base, size);
650} 663}
651 664
652int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size) 665static int __init_memblock memblock_reserve_region(phys_addr_t base,
666 phys_addr_t size,
667 int nid,
668 unsigned long flags)
653{ 669{
654 struct memblock_type *_rgn = &memblock.reserved; 670 struct memblock_type *_rgn = &memblock.reserved;
655 671
656 memblock_dbg("memblock_reserve: [%#016llx-%#016llx] %pF\n", 672 memblock_dbg("memblock_reserve: [%#016llx-%#016llx] flags %#02lx %pF\n",
657 (unsigned long long)base, 673 (unsigned long long)base,
658 (unsigned long long)base + size - 1, 674 (unsigned long long)base + size - 1,
659 (void *)_RET_IP_); 675 flags, (void *)_RET_IP_);
676
677 return memblock_add_region(_rgn, base, size, nid, flags);
678}
660 679
661 return memblock_add_region(_rgn, base, size, MAX_NUMNODES); 680int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size)
681{
682 return memblock_reserve_region(base, size, MAX_NUMNODES, 0);
662} 683}
663 684
664/** 685/**
@@ -1101,6 +1122,7 @@ void __init_memblock memblock_set_current_limit(phys_addr_t limit)
1101static void __init_memblock memblock_dump(struct memblock_type *type, char *name) 1122static void __init_memblock memblock_dump(struct memblock_type *type, char *name)
1102{ 1123{
1103 unsigned long long base, size; 1124 unsigned long long base, size;
1125 unsigned long flags;
1104 int i; 1126 int i;
1105 1127
1106 pr_info(" %s.cnt = 0x%lx\n", name, type->cnt); 1128 pr_info(" %s.cnt = 0x%lx\n", name, type->cnt);
@@ -1111,13 +1133,14 @@ static void __init_memblock memblock_dump(struct memblock_type *type, char *name
1111 1133
1112 base = rgn->base; 1134 base = rgn->base;
1113 size = rgn->size; 1135 size = rgn->size;
1136 flags = rgn->flags;
1114#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP 1137#ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
1115 if (memblock_get_region_node(rgn) != MAX_NUMNODES) 1138 if (memblock_get_region_node(rgn) != MAX_NUMNODES)
1116 snprintf(nid_buf, sizeof(nid_buf), " on node %d", 1139 snprintf(nid_buf, sizeof(nid_buf), " on node %d",
1117 memblock_get_region_node(rgn)); 1140 memblock_get_region_node(rgn));
1118#endif 1141#endif
1119 pr_info(" %s[%#x]\t[%#016llx-%#016llx], %#llx bytes%s\n", 1142 pr_info(" %s[%#x]\t[%#016llx-%#016llx], %#llx bytes%s flags: %#lx\n",
1120 name, i, base, base + size - 1, size, nid_buf); 1143 name, i, base, base + size - 1, size, nid_buf, flags);
1121 } 1144 }
1122} 1145}
1123 1146