Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8a374026 authored by Yinghai Lu's avatar Yinghai Lu Committed by Thomas Gleixner
Browse files

x86: fix trimming e820 with MTRR holes. - fix



v2: process hole then end_pfn
    fix update_memory_range with whole cover comparing

Signed-off-by: default avatarYinghai Lu <yinghai.lu@gmail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 42651f15
Loading
Loading
Loading
Loading
+15 −29
Original line number Diff line number Diff line
@@ -1103,6 +1103,7 @@ static u64 __init real_trim_memory(unsigned long start_pfn, unsigned long limit_
	trim_size = limit_pfn;
	trim_size <<= PAGE_SHIFT;
	trim_size -= trim_start;

	return update_memory_range(trim_start, trim_size, E820_RAM,
				E820_RESERVED);
}
@@ -1124,7 +1125,6 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
	struct res_range range[RANGE_NUM];
	int nr_range;
	u64 total_real_trim_size;
	int changed;

	/* extra one for all 0 */
	int num[MTRR_NUM_TYPES + 1];
@@ -1189,49 +1189,35 @@ int __init mtrr_trim_uncached_memory(unsigned long end_pfn)
	}
	nr_range = x86_get_mtrr_mem_range(range, nr_range, 0, 0);

	changed = 0;
	total_real_trim_size = 0;

	/* check the top at first */
	i = nr_range - 1;
	if (range[i].end + 1 < end_pfn) {
			total_real_trim_size += real_trim_memory(range[i].end + 1, end_pfn);
	}

	if (total_real_trim_size) {
		printk(KERN_WARNING "WARNING: BIOS bug: CPU MTRRs don't cover"
			" all of memory, losing %lluMB of RAM.\n",
			total_real_trim_size >> 20);

		WARN_ON(1);

		printk(KERN_INFO "update e820 for mtrr -- end_pfn\n");
		update_e820();
		changed = 1;
	}

	total_real_trim_size = 0;
	/* check the head */
	if (range[0].start)
		total_real_trim_size += real_trim_memory(0, range[0].start);

	for (i = 0; i < nr_range - 1; i--) {
	/* check the holes */
	for (i = 0; i < nr_range - 1; i++) {
		if (range[i].end + 1 < range[i+1].start)
			total_real_trim_size += real_trim_memory(range[i].end + 1, range[i+1].start);
	}
	/* check the top */
	i = nr_range - 1;
	if (range[i].end + 1 < end_pfn)
		total_real_trim_size += real_trim_memory(range[i].end + 1, end_pfn);

	if (total_real_trim_size) {
		printk(KERN_WARNING "WARNING: BIOS bug: CPU MTRRs don't cover"
			" all of memory, losing %lluMB of RAM.\n",
			total_real_trim_size >> 20);

		if (enable_mtrr_cleanup < 1)
			WARN_ON(1);

		printk(KERN_INFO "update e820 for mtrr -- holes\n");
		printk(KERN_INFO "update e820 for mtrr\n");
		update_e820();
		changed = 1;

		return 1;
	}

	return changed;
	return 0;
}

/**
+2 −1
Original line number Diff line number Diff line
@@ -797,7 +797,8 @@ u64 __init update_memory_range(u64 start, u64 size, unsigned old_type,
		if (ei->type != old_type)
			continue;
		/* totally covered? */
		if (ei->addr >= start && ei->size <= size) {
		if (ei->addr >= start &&
		    (ei->addr + ei->size) <= (start + size)) {
			ei->type = new_type;
			real_updated_size += ei->size;
			continue;
+2 −1
Original line number Diff line number Diff line
@@ -843,7 +843,8 @@ u64 __init update_memory_range(u64 start, u64 size, unsigned old_type,
		if (ei->type != old_type)
			continue;
		/* totally covered? */
		if (ei->addr >= start && ei->size <= size) {
		if (ei->addr >= start &&
		    (ei->addr + ei->size) <= (start + size)) {
			ei->type = new_type;
			real_updated_size += ei->size;
			continue;