@@ -60,6 +60,7 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices);
60
60
* also add "System RAM" regions for compatibility with other
61
61
* archs, and the rest of the known regions for completeness.
62
62
*/
63
+ static struct resource kimage_res = { .name = "Kernel image" , };
63
64
static struct resource code_res = { .name = "Kernel code" , };
64
65
static struct resource data_res = { .name = "Kernel data" , };
65
66
static struct resource rodata_res = { .name = "Kernel rodata" , };
@@ -80,45 +81,54 @@ static int __init add_resource(struct resource *parent,
80
81
return 1 ;
81
82
}
82
83
83
- static int __init add_kernel_resources (struct resource * res )
84
+ static int __init add_kernel_resources (void )
84
85
{
85
86
int ret = 0 ;
86
87
87
88
/*
88
89
* 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.
92
93
*/
93
- if (!(res -> start <= code_res .start && res -> end >= data_res .end ))
94
- return 0 ;
95
94
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 ;
98
98
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 ;
104
102
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 );
106
116
if (ret < 0 )
107
117
return ret ;
108
118
109
- ret = add_resource (res , & code_res );
119
+ ret = add_resource (& kimage_res , & code_res );
110
120
if (ret < 0 )
111
121
return ret ;
112
122
113
- ret = add_resource (res , & rodata_res );
123
+ ret = add_resource (& kimage_res , & rodata_res );
114
124
if (ret < 0 )
115
125
return ret ;
116
126
117
- ret = add_resource (res , & data_res );
127
+ ret = add_resource (& kimage_res , & data_res );
118
128
if (ret < 0 )
119
129
return ret ;
120
130
121
- ret = add_resource (res , & bss_res );
131
+ ret = add_resource (& kimage_res , & bss_res );
122
132
123
133
return ret ;
124
134
}
@@ -129,53 +139,42 @@ static void __init init_resources(void)
129
139
struct resource * res = NULL ;
130
140
struct resource * mem_res = NULL ;
131
141
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 ;
145
144
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 ;
149
148
150
- mem_res_sz = ( memblock . memory . cnt + memblock . reserved . cnt ) * sizeof (* mem_res );
149
+ mem_res_sz = num_resources * sizeof (* mem_res );
151
150
mem_res = memblock_alloc (mem_res_sz , SMP_CACHE_BYTES );
152
151
if (!mem_res )
153
152
panic ("%s: Failed to allocate %zu bytes\n" , __func__ , mem_res_sz );
153
+
154
154
/*
155
155
* Start by adding the reserved regions, if they overlap
156
156
* with /memory regions, insert_resource later on will take
157
157
* care of it.
158
158
*/
159
+ ret = add_kernel_resources ();
160
+ if (ret < 0 )
161
+ goto error ;
162
+
159
163
for_each_reserved_mem_region (region ) {
160
- res = & mem_res [i ++ ];
164
+ res = & mem_res [res_idx -- ];
161
165
162
166
res -> name = "Reserved" ;
163
167
res -> flags = IORESOURCE_MEM | IORESOURCE_BUSY ;
164
168
res -> start = __pfn_to_phys (memblock_region_reserved_base_pfn (region ));
165
169
res -> end = __pfn_to_phys (memblock_region_reserved_end_pfn (region )) - 1 ;
166
170
167
- ret = add_kernel_resources (res );
168
- if (ret < 0 )
169
- goto error ;
170
- else if (ret )
171
- continue ;
172
-
173
171
/*
174
172
* Ignore any other reserved regions within
175
173
* system memory.
176
174
*/
177
175
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 ++ ;
179
178
continue ;
180
179
}
181
180
@@ -186,7 +185,7 @@ static void __init init_resources(void)
186
185
187
186
/* Add /memory regions to the resource tree */
188
187
for_each_mem_region (region ) {
189
- res = & mem_res [i ++ ];
188
+ res = & mem_res [res_idx -- ];
190
189
191
190
if (unlikely (memblock_is_nomap (region ))) {
192
191
res -> name = "Reserved" ;
@@ -204,6 +203,9 @@ static void __init init_resources(void)
204
203
goto error ;
205
204
}
206
205
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 );
207
209
return ;
208
210
209
211
error :
0 commit comments