aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/cpu/mtrr/main.c
diff options
context:
space:
mode:
authorYinghai Lu <yhlu.kernel@gmail.com>2008-09-27 23:26:06 -0400
committerIngo Molnar <mingo@elte.hu>2008-09-28 03:12:27 -0400
commit8f0afaa58e912bbe7d5b0bad9fb024337edf363e (patch)
tree11d5a33258fb4871958bf5d50b0ce5494aaac56f /arch/x86/kernel/cpu/mtrr/main.c
parent54d45ff4208836e62536fc40b0141586dbf6641f (diff)
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: Yinghai Lu <yhlu.kernel@gmail.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/cpu/mtrr/main.c')
-rw-r--r--arch/x86/kernel/cpu/mtrr/main.c74
1 files changed, 43 insertions, 31 deletions
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index aff46b99ff01..bccf57f5b615 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -992,22 +992,17 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
992 /* only cut back, when it is not the last */ 992 /* only cut back, when it is not the last */
993 if (sizek) { 993 if (sizek) {
994 while (range0_basek + range0_sizek > (basek + sizek)) { 994 while (range0_basek + range0_sizek > (basek + sizek)) {
995 range0_sizek -= chunk_sizek; 995 if (range0_sizek >= chunk_sizek)
996 range0_sizek -= chunk_sizek;
997 else
998 range0_sizek = 0;
999
996 if (!range0_sizek) 1000 if (!range0_sizek)
997 break; 1001 break;
998 } 1002 }
999 } 1003 }
1000 1004
1001 if (range0_sizek) { 1005second_try:
1002 if (debug_print)
1003 printk(KERN_DEBUG "range0: %016lx - %016lx\n",
1004 range0_basek<<10,
1005 (range0_basek + range0_sizek)<<10);
1006 state->reg = range_to_mtrr(state->reg, range0_basek,
1007 range0_sizek, MTRR_TYPE_WRBACK);
1008
1009 }
1010
1011 range_basek = range0_basek + range0_sizek; 1006 range_basek = range0_basek + range0_sizek;
1012 1007
1013 /* one hole in the middle */ 1008 /* one hole in the middle */
@@ -1015,33 +1010,50 @@ range_to_mtrr_with_hole(struct var_mtrr_state *state, unsigned long basek,
1015 second_sizek = range_basek - basek; 1010 second_sizek = range_basek - basek;
1016 1011
1017 if (range0_sizek > state->range_sizek) { 1012 if (range0_sizek > state->range_sizek) {
1018 unsigned long hole_basek, hole_sizek;
1019 1013
1020 /* one hole in middle or at end */ 1014 /* one hole in middle or at end */
1021 hole_sizek = range0_sizek - state->range_sizek - second_sizek; 1015 hole_sizek = range0_sizek - state->range_sizek - second_sizek;
1022 if (hole_sizek) { 1016
1023 hole_basek = range_basek - hole_sizek - second_sizek; 1017 /* hole size should be less than half of range0 size */
1024 if (debug_print) 1018 if (hole_sizek > (range0_sizek >> 1) &&
1025 printk(KERN_DEBUG "hole: %016lx - %016lx\n", 1019 range0_sizek >= chunk_sizek) {
1026 hole_basek<<10, 1020 range0_sizek -= chunk_sizek;
1027 (hole_basek + hole_sizek)<<10); 1021 second_sizek = 0;
1028 state->reg = range_to_mtrr(state->reg, hole_basek, 1022 hole_sizek = 0;
1029 hole_sizek, 1023
1030 MTRR_TYPE_UNCACHABLE); 1024 goto second_try;
1031 } 1025 }
1032 } else { 1026 }
1027
1028 if (range0_sizek) {
1029 if (debug_print)
1030 printk(KERN_DEBUG "range0: %016lx - %016lx\n",
1031 range0_basek<<10,
1032 (range0_basek + range0_sizek)<<10);
1033 state->reg = range_to_mtrr(state->reg, range0_basek,
1034 range0_sizek, MTRR_TYPE_WRBACK);
1035 }
1036
1037 if (range0_sizek < state->range_sizek) {
1033 /* need to handle left over */ 1038 /* need to handle left over */
1034 range_sizek = state->range_sizek - range0_sizek; 1039 range_sizek = state->range_sizek - range0_sizek;
1035 1040
1036 if (range_sizek) { 1041 if (debug_print)
1037 if (debug_print) 1042 printk(KERN_DEBUG "range: %016lx - %016lx\n",
1038 printk(KERN_DEBUG "range: %016lx - %016lx\n", 1043 range_basek<<10,
1039 range_basek<<10, 1044 (range_basek + range_sizek)<<10);
1040 (range_basek + range_sizek)<<10); 1045 state->reg = range_to_mtrr(state->reg, range_basek,
1041 state->reg = range_to_mtrr(state->reg, range_basek, 1046 range_sizek, MTRR_TYPE_WRBACK);
1042 range_sizek, 1047 }
1043 MTRR_TYPE_WRBACK); 1048
1044 } 1049 if (hole_sizek) {
1050 hole_basek = range_basek - hole_sizek - second_sizek;
1051 if (debug_print)
1052 printk(KERN_DEBUG "hole: %016lx - %016lx\n",
1053 hole_basek<<10,
1054 (hole_basek + hole_sizek)<<10);
1055 state->reg = range_to_mtrr(state->reg, hole_basek,
1056 hole_sizek, MTRR_TYPE_UNCACHABLE);
1045 } 1057 }
1046 1058
1047 return second_sizek; 1059 return second_sizek;