@@ -60,6 +60,7 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices);
6060 * also add "System RAM" regions for compatibility with other
6161 * archs, and the rest of the known regions for completeness.
6262 */
63+ static struct resource kimage_res = { .name = "Kernel image" , };
6364static struct resource code_res = { .name = "Kernel code" , };
6465static struct resource data_res = { .name = "Kernel data" , };
6566static struct resource rodata_res = { .name = "Kernel rodata" , };
@@ -80,45 +81,54 @@ static int __init add_resource(struct resource *parent,
8081 return 1 ;
8182}
8283
83- static int __init add_kernel_resources (struct resource * res )
84+ static int __init add_kernel_resources (void )
8485{
8586 int ret = 0 ;
8687
8788 /*
8889 * The memory region of the kernel image is continuous and
89- * was reserved on setup_bootmem, find it here and register
90- * it as a resource, then register the various segments of
91- * the image as child nodes
90+ * was reserved on setup_bootmem, register it here as a
91+ * resource, with the various segments of the image as
92+ * child nodes.
9293 */
93- if (!(res -> start <= code_res .start && res -> end >= data_res .end ))
94- return 0 ;
9594
96- res -> name = "Kernel image" ;
97- res -> flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY ;
95+ code_res .start = __pa_symbol (_text );
96+ code_res .end = __pa_symbol (_etext ) - 1 ;
97+ code_res .flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY ;
9898
99- /*
100- * We removed a part of this region on setup_bootmem so
101- * we need to expand the resource for the bss to fit in.
102- */
103- res -> end = bss_res .end ;
99+ rodata_res .start = __pa_symbol (__start_rodata );
100+ rodata_res .end = __pa_symbol (__end_rodata ) - 1 ;
101+ rodata_res .flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY ;
104102
105- ret = add_resource (& iomem_resource , res );
103+ data_res .start = __pa_symbol (_data );
104+ data_res .end = __pa_symbol (_edata ) - 1 ;
105+ data_res .flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY ;
106+
107+ bss_res .start = __pa_symbol (__bss_start );
108+ bss_res .end = __pa_symbol (__bss_stop ) - 1 ;
109+ bss_res .flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY ;
110+
111+ kimage_res .start = code_res .start ;
112+ kimage_res .end = bss_res .end ;
113+ kimage_res .flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY ;
114+
115+ ret = add_resource (& iomem_resource , & kimage_res );
106116 if (ret < 0 )
107117 return ret ;
108118
109- ret = add_resource (res , & code_res );
119+ ret = add_resource (& kimage_res , & code_res );
110120 if (ret < 0 )
111121 return ret ;
112122
113- ret = add_resource (res , & rodata_res );
123+ ret = add_resource (& kimage_res , & rodata_res );
114124 if (ret < 0 )
115125 return ret ;
116126
117- ret = add_resource (res , & data_res );
127+ ret = add_resource (& kimage_res , & data_res );
118128 if (ret < 0 )
119129 return ret ;
120130
121- ret = add_resource (res , & bss_res );
131+ ret = add_resource (& kimage_res , & bss_res );
122132
123133 return ret ;
124134}
@@ -129,53 +139,42 @@ static void __init init_resources(void)
129139 struct resource * res = NULL ;
130140 struct resource * mem_res = NULL ;
131141 size_t mem_res_sz = 0 ;
132- int ret = 0 , i = 0 ;
133-
134- code_res .start = __pa_symbol (_text );
135- code_res .end = __pa_symbol (_etext ) - 1 ;
136- code_res .flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY ;
137-
138- rodata_res .start = __pa_symbol (__start_rodata );
139- rodata_res .end = __pa_symbol (__end_rodata ) - 1 ;
140- rodata_res .flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY ;
141-
142- data_res .start = __pa_symbol (_data );
143- data_res .end = __pa_symbol (_edata ) - 1 ;
144- data_res .flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY ;
142+ int num_resources = 0 , res_idx = 0 ;
143+ int ret = 0 ;
145144
146- bss_res . start = __pa_symbol ( __bss_start );
147- bss_res . end = __pa_symbol ( __bss_stop ) - 1 ;
148- bss_res . flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY ;
145+ /* + 1 as memblock_alloc() might increase memblock.reserved.cnt */
146+ num_resources = memblock . memory . cnt + memblock . reserved . cnt + 1 ;
147+ res_idx = num_resources - 1 ;
149148
150- mem_res_sz = ( memblock . memory . cnt + memblock . reserved . cnt ) * sizeof (* mem_res );
149+ mem_res_sz = num_resources * sizeof (* mem_res );
151150 mem_res = memblock_alloc (mem_res_sz , SMP_CACHE_BYTES );
152151 if (!mem_res )
153152 panic ("%s: Failed to allocate %zu bytes\n" , __func__ , mem_res_sz );
153+
154154 /*
155155 * Start by adding the reserved regions, if they overlap
156156 * with /memory regions, insert_resource later on will take
157157 * care of it.
158158 */
159+ ret = add_kernel_resources ();
160+ if (ret < 0 )
161+ goto error ;
162+
159163 for_each_reserved_mem_region (region ) {
160- res = & mem_res [i ++ ];
164+ res = & mem_res [res_idx -- ];
161165
162166 res -> name = "Reserved" ;
163167 res -> flags = IORESOURCE_MEM | IORESOURCE_BUSY ;
164168 res -> start = __pfn_to_phys (memblock_region_reserved_base_pfn (region ));
165169 res -> end = __pfn_to_phys (memblock_region_reserved_end_pfn (region )) - 1 ;
166170
167- ret = add_kernel_resources (res );
168- if (ret < 0 )
169- goto error ;
170- else if (ret )
171- continue ;
172-
173171 /*
174172 * Ignore any other reserved regions within
175173 * system memory.
176174 */
177175 if (memblock_is_memory (res -> start )) {
178- memblock_free ((phys_addr_t ) res , sizeof (struct resource ));
176+ /* Re-use this pre-allocated resource */
177+ res_idx ++ ;
179178 continue ;
180179 }
181180
@@ -186,7 +185,7 @@ static void __init init_resources(void)
186185
187186 /* Add /memory regions to the resource tree */
188187 for_each_mem_region (region ) {
189- res = & mem_res [i ++ ];
188+ res = & mem_res [res_idx -- ];
190189
191190 if (unlikely (memblock_is_nomap (region ))) {
192191 res -> name = "Reserved" ;
@@ -204,6 +203,9 @@ static void __init init_resources(void)
204203 goto error ;
205204 }
206205
206+ /* Clean-up any unused pre-allocated resources */
207+ mem_res_sz = (num_resources - res_idx + 1 ) * sizeof (* mem_res );
208+ memblock_free ((phys_addr_t ) mem_res , mem_res_sz );
207209 return ;
208210
209211 error :
0 commit comments