/** * kvm_cma_reserve() - reserve area for kvm hash pagetable * * This function reserves memory from early allocator. It should be * called by arch specific code once the early allocator (memblock or bootmem) * has been activated and all other subsystems have already allocated/reserved * memory. */ void __init kvm_cma_reserve(void) { unsigned long align_size; struct memblock_region *reg; phys_addr_t selected_size = 0; /* * We cannot use memblock_phys_mem_size() here, because * memblock_analyze() has not been called yet. */ for_each_memblock(memory, reg) selected_size += memblock_region_memory_end_pfn(reg) - memblock_region_memory_base_pfn(reg); selected_size = (selected_size * kvm_cma_resv_ratio / 100) << PAGE_SHIFT; if (selected_size) { pr_debug("%s: reserving %ld MiB for global area\n", __func__, (unsigned long)selected_size / SZ_1M); /* * Old CPUs require HPT aligned on a multiple of its size. So for them * make the alignment as max size we could request. */ if (!cpu_has_feature(CPU_FTR_ARCH_206)) align_size = __rounddown_pow_of_two(selected_size); else align_size = HPT_ALIGN_PAGES << PAGE_SHIFT; align_size = max(kvm_rma_pages << PAGE_SHIFT, align_size); kvm_cma_declare_contiguous(selected_size, align_size); } }
/** * kvm_cma_reserve() - reserve area for kvm hash pagetable * * This function reserves memory from early allocator. It should be * called by arch specific code once the memblock allocator * has been activated and all other subsystems have already allocated/reserved * memory. */ void __init kvm_cma_reserve(void) { unsigned long align_size; struct memblock_region *reg; phys_addr_t selected_size = 0; /* * We need CMA reservation only when we are in HV mode */ if (!cpu_has_feature(CPU_FTR_HVMODE)) return; /* * We cannot use memblock_phys_mem_size() here, because * memblock_analyze() has not been called yet. */ for_each_memblock(memory, reg) selected_size += memblock_region_memory_end_pfn(reg) - memblock_region_memory_base_pfn(reg); selected_size = (selected_size * kvm_cma_resv_ratio / 100) << PAGE_SHIFT; if (selected_size) { pr_debug("%s: reserving %ld MiB for global area\n", __func__, (unsigned long)selected_size / SZ_1M); align_size = HPT_ALIGN_PAGES << PAGE_SHIFT; cma_declare_contiguous(0, selected_size, 0, align_size, KVM_CMA_CHUNK_ORDER - PAGE_SHIFT, false, &kvm_cma); } }
static phys_addr_t __init __maybe_unused cma_early_percent_memory(void) { struct memblock_region *reg; unsigned long total_pages = 0; /* * We cannot use memblock_phys_mem_size() here, because * memblock_analyze() has not been called yet. */ for_each_memblock(memory, reg) total_pages += memblock_region_memory_end_pfn(reg) - memblock_region_memory_base_pfn(reg); return (total_pages * CONFIG_CMA_SIZE_PERCENTAGE / 100) << PAGE_SHIFT; }
void __init bootmem_init(void) { struct memblock_region *reg; unsigned long bootmap_size; unsigned long free_pfn, end_pfn, start_pfn; init_mm.start_code = (unsigned long)_stext; init_mm.end_code = (unsigned long)_etext; init_mm.end_data = (unsigned long)_edata; init_mm.brk = (unsigned long)_end; memblock_init(); memblock_add(memory_start, memory_end); if(((unsigned long)__pa(_end) < memory_start) || ((unsigned long)__pa(_end) > memory_end)) printk("BUG: your kernel is not located in the ddr sdram"); start_pfn = PFN_UP(memory_start); free_pfn = PFN_UP(__pa((unsigned long)_end)); end_pfn = PFN_DOWN(memory_end); //memblock_reserve(PFN_PHYS(start_pfn), PFN_PHYS(free_pfn - start_pfn)); memblock_reserve(__pa(_stext), _end - _stext); #ifdef CONFIG_BLK_DEV_INITRD if (initrd_start && initrd_end && initrd_start < initrd_end) { memblock_reserve(initrd_start, initrd_end - initrd_start); } #endif bootmap_size = init_bootmem(free_pfn, end_pfn); memblock_reserve(PFN_PHYS(free_pfn), bootmap_size); free_bootmem(PFN_PHYS(free_pfn), PFN_PHYS(end_pfn - free_pfn)); for_each_memblock(reserved, reg) reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT); memory_start += PAGE_OFFSET; memory_end += PAGE_OFFSET; memblock_analyze(); memblock_dump_all(); }