Skip to content

Commit fa54601

Browse files
skttwipawel
authored andcommitted
pmm: simpler and bugfix process_memory_range loop
This simplifies the adding of frames during boot. It also fixes a bug for configurations with > 1GB memory. After the initial 4K frames, the current (`cur`) is aligned to 2MB. Trying to add a 1GB frame at this point will lead to page faults further down the line as we end up with misaligned page frame mfns. Signed-off-by: Johannes Wikner <[email protected]>
1 parent c1ab591 commit fa54601

File tree

3 files changed

+21
-24
lines changed

3 files changed

+21
-24
lines changed

include/arch/x86/page.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ typedef unsigned long mfn_t;
193193
#define MAP_FAILED ((void *) 1)
194194

195195
#define IS_ADDR_SPACE_VA(va, as) (_ul(va) >= (as))
196+
#define PADDR_TO_ORDER(addr) (ctz(addr) - PAGE_SHIFT)
196197

197198
/* External declarations */
198199

include/compiler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,6 @@ typedef uint64_t off_t;
157157
_str; \
158158
})
159159

160+
/* count trailing zeros */
161+
#define ctz __builtin_ctz
160162
#endif /* KTF_COMPILER_H */

mm/pmm.c

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,6 @@ static unsigned find_first_avail_region(void) {
293293

294294
static size_t process_memory_range(unsigned index, unsigned first_avail_region) {
295295
paddr_t start, end, cur;
296-
unsigned int max_order;
297296
addr_range_t range;
298297
size_t size;
299298

@@ -310,39 +309,34 @@ static size_t process_memory_range(unsigned index, unsigned first_avail_region)
310309
* because initial virtual memory mapping is small.
311310
*/
312311

313-
/* Add initial 4K frames and align to 2M. */
314-
while ((cur < MB(EARLY_VIRT_MEM) || cur % PAGE_SIZE_2M) && cur + PAGE_SIZE <= end) {
315-
if (index <= first_avail_region)
316-
add_early_frame(paddr_to_mfn(cur), PAGE_ORDER_4K);
317-
else
318-
add_frame(paddr_to_mfn(cur), PAGE_ORDER_4K);
312+
/* Add initial 4K frames for early memory. */
313+
while (cur < MB(EARLY_VIRT_MEM) && cur + PAGE_SIZE <= end) {
314+
add_early_frame(paddr_to_mfn(cur), PAGE_ORDER_4K);
319315
cur += ORDER_TO_SIZE(PAGE_ORDER_4K);
320316
}
321317

322-
max_order = find_max_avail_order(end - cur);
323-
324-
/* Add all available max_order frames. */
325-
while (cur + ORDER_TO_SIZE(max_order) <= end) {
326-
add_frame(paddr_to_mfn(cur), max_order);
327-
cur += ORDER_TO_SIZE(max_order);
328-
}
318+
while (cur + PAGE_SIZE <= end) {
319+
unsigned int order = PADDR_TO_ORDER(cur);
320+
if (order >= PAGE_ORDER_1G && cur + PAGE_SIZE_1G <= end) {
321+
add_frame(paddr_to_mfn(cur), PAGE_ORDER_1G);
322+
cur += ORDER_TO_SIZE(PAGE_ORDER_1G);
323+
continue;
324+
}
329325

330-
/* Add all remaining 2M frames. */
331-
while (cur + PAGE_SIZE_2M <= end) {
332-
add_frame(paddr_to_mfn(cur), PAGE_ORDER_2M);
333-
cur += ORDER_TO_SIZE(PAGE_ORDER_2M);
334-
}
326+
if (order >= PAGE_ORDER_2M && cur + PAGE_SIZE_2M <= end) {
327+
add_frame(paddr_to_mfn(cur), PAGE_ORDER_2M);
328+
cur += ORDER_TO_SIZE(PAGE_ORDER_2M);
329+
continue;
330+
}
335331

336-
/* Add all remaining 4K frames. */
337-
while (cur < end) {
338332
add_frame(paddr_to_mfn(cur), PAGE_ORDER_4K);
339333
cur += ORDER_TO_SIZE(PAGE_ORDER_4K);
340334
}
341335

342336
if (cur != end) {
343-
warning(
344-
"PMM range processing failed: start=0x%016lx end=0x%016lx current=0x%016lx",
345-
start, end, cur);
337+
warning("PMM range processing failed: start=0x%016lx end=0x%016lx "
338+
"current=0x%016lx",
339+
start, end, cur);
346340
}
347341

348342
return size;

0 commit comments

Comments
 (0)