[Haiku-commits] r31027 - haiku/trunk/src/system/kernel/arch/x86

mmlr at mail.berlios.de mmlr at mail.berlios.de
Sat Jun 13 13:40:06 CEST 2009


Author: mmlr
Date: 2009-06-13 13:40:05 +0200 (Sat, 13 Jun 2009)
New Revision: 31027
ViewCVS: http://svn.berlios.de/viewcvs/haiku?rev=31027&view=rev

Modified:
   haiku/trunk/src/system/kernel/arch/x86/arch_vm.cpp
Log:
Make two runs of MTRR setting when setting memory ranges to write-back. At the
first run only set up uncacheable MTRRs and in the second run set the write-back
ones up. If this order is not followed, we could set too large ranges to
cacheable first and then limit it back to uncacheable later. On systems with
enough physical memory this would lead to a temporary situation in which areas
become cacheable that must not be, resulting in system hangs or other unexpected
behaviour. Fixes last part of #4018.


Modified: haiku/trunk/src/system/kernel/arch/x86/arch_vm.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/arch_vm.cpp	2009-06-13 11:35:57 UTC (rev 31026)
+++ haiku/trunk/src/system/kernel/arch/x86/arch_vm.cpp	2009-06-13 11:40:05 UTC (rev 31027)
@@ -272,33 +272,48 @@
 
 #ifdef TRACE_MTRR
 	dprintf("solutions: ");
-	for (int i=0; i<sSolutionCount; i++) {
-                dprintf("0x%Lx ", sSolutions[i]);
-        }
-        dprintf("\n");
+	for (int i=0; i<sSolutionCount; i++)
+		dprintf("0x%Lx ", sSolutions[i]);
+	dprintf("\n");
 #endif
 
-	bool nextDown = false;
-	for (int i = 0; i < sSolutionCount; i++) {
-		if (sSolutions[i] < 0) {
-			if (nextDown)
-				base += sSolutions[i];
-			err = set_memory_type(id, base, -sSolutions[i], nextDown ? B_MTR_UC : B_MTR_WB);
-			if (err != B_OK) {
-				dprintf("set_memory_type returned %s (0x%lx)\n", strerror(err), err);
+	for (int run = 0; run < 2; run++) {
+		bool nextDown = false;
+		uint64 newBase = base;
+
+		for (int i = 0; i < sSolutionCount; i++) {
+			if (sSolutions[i] < 0) {
+				if (nextDown)
+					newBase += sSolutions[i];
+
+				if ((run == 0) == nextDown) {
+					err = set_memory_type(id, newBase, -sSolutions[i],
+						nextDown ? B_MTR_UC : B_MTR_WB);
+					if (err != B_OK) {
+						dprintf("set_memory_type returned %s (0x%lx)\n",
+							strerror(err), err);
+					}
+				}
+
+				if (!nextDown)
+					newBase -= sSolutions[i];
+				nextDown = !nextDown;
+			} else {
+				if (nextDown)
+					newBase -= sSolutions[i];
+
+				if ((run == 0) == nextDown) {
+					err = set_memory_type(id, newBase, sSolutions[i],
+						nextDown ? B_MTR_UC : B_MTR_WB);
+					if (err != B_OK) {
+						dprintf("set_memory_type returned %s (0x%lx)\n",
+							strerror(err), err);
+					}
+				}
+
+				if (!nextDown)
+					newBase += sSolutions[i];
 			}
-			if (!nextDown)
-				base -= sSolutions[i];
-			nextDown = !nextDown;
-		} else {
-			if (nextDown)
-				base -= sSolutions[i];
-			err = set_memory_type(id, base, sSolutions[i], nextDown ? B_MTR_UC : B_MTR_WB);
-			if (err != B_OK) {
-				dprintf("set_memory_type returned %s (0x%lx)\n", strerror(err), err);
-			}
-			if (!nextDown)
-				base += sSolutions[i];
 		}
 	}
 }




More information about the Haiku-commits mailing list