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

Commit 8f0afaa5 authored by Yinghai Lu's avatar Yinghai Lu Committed by Ingo Molnar
Browse files

x86: mtrr_cleanup hole size should be less than half of chunk_size, v2



v2: should check with half of range0 size instead of chunk_size

So don't have silly big hole.

in hpa's case we could auto detect instead of adding mtrr_chunk_size in
command line.

Signed-off-by: default avatarYinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 54d45ff4
Loading
Loading
Loading
Loading
+43 −31
Original line number Diff line number Diff line
@@ -992,22 +992,17 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
	/* only cut back, when it is not the last */
	if (sizek) {
		while (range0_basek + range0_sizek > (basek + sizek)) {
			if (range0_sizek >= chunk_sizek)
				range0_sizek -= chunk_sizek;
			else
				range0_sizek = 0;

			if (!range0_sizek)
				break;
		}
	}

	if (range0_sizek) {
		if (debug_print)
			printk(KERN_DEBUG "range0: %016lx - %016lx\n",
				range0_basek<<10,
				(range0_basek + range0_sizek)<<10);
		state->reg = range_to_mtrr(state->reg, range0_basek,
				range0_sizek, MTRR_TYPE_WRBACK);

	}

second_try:
	range_basek = range0_basek + range0_sizek;

	/* one hole in the middle */
@@ -1015,33 +1010,50 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
		second_sizek = range_basek - basek;

	if (range0_sizek > state->range_sizek) {
		unsigned long hole_basek, hole_sizek;

		/* one hole in middle or at end */
		hole_sizek = range0_sizek - state->range_sizek - second_sizek;
		if (hole_sizek) {
			hole_basek = range_basek - hole_sizek - second_sizek;

		/* hole size should be less than half of range0 size */
		if (hole_sizek > (range0_sizek >> 1) &&
		    range0_sizek >= chunk_sizek) {
			range0_sizek -= chunk_sizek;
			second_sizek = 0;
			hole_sizek = 0;

			goto second_try;
		}
	}

	if (range0_sizek) {
		if (debug_print)
				printk(KERN_DEBUG "hole: %016lx - %016lx\n",
					 hole_basek<<10,
					 (hole_basek + hole_sizek)<<10);
			state->reg = range_to_mtrr(state->reg, hole_basek,
						   hole_sizek,
						   MTRR_TYPE_UNCACHABLE);
			printk(KERN_DEBUG "range0: %016lx - %016lx\n",
				range0_basek<<10,
				(range0_basek + range0_sizek)<<10);
		state->reg = range_to_mtrr(state->reg, range0_basek,
				range0_sizek, MTRR_TYPE_WRBACK);
	}
	} else  {

	if (range0_sizek < state->range_sizek) {
		/* need to handle left over */
		range_sizek = state->range_sizek - range0_sizek;

		if (range_sizek) {
		if (debug_print)
			printk(KERN_DEBUG "range: %016lx - %016lx\n",
				 range_basek<<10,
				 (range_basek + range_sizek)<<10);
		state->reg = range_to_mtrr(state->reg, range_basek,
					 range_sizek,
					 MTRR_TYPE_WRBACK);
				 range_sizek, MTRR_TYPE_WRBACK);
	}

	if (hole_sizek) {
		hole_basek = range_basek - hole_sizek - second_sizek;
		if (debug_print)
			printk(KERN_DEBUG "hole: %016lx - %016lx\n",
				 hole_basek<<10,
				 (hole_basek + hole_sizek)<<10);
		state->reg = range_to_mtrr(state->reg, hole_basek,
				 hole_sizek, MTRR_TYPE_UNCACHABLE);
	}

	return second_sizek;