Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F106170801
D35799.id108381.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D35799.id108381.diff
View Options
Index: sys/conf/options.amd64
===================================================================
--- sys/conf/options.amd64
+++ sys/conf/options.amd64
@@ -64,3 +64,6 @@
# Don't create a "legacy" PCI bridge if none is found.
NO_LEGACY_PCIB opt_cpu.h
+
+# Compatibility with Linux MP table bugs.
+MPTABLE_LINUX_BUG_COMPAT
Index: sys/conf/options.i386
===================================================================
--- sys/conf/options.i386
+++ sys/conf/options.i386
@@ -108,3 +108,6 @@
# Don't create a "legacy" PCI bridge if none is found.
NO_LEGACY_PCIB opt_cpu.h
+
+# Compatibility with Linux MP table bugs.
+MPTABLE_LINUX_BUG_COMPAT
Index: sys/x86/x86/mptable.c
===================================================================
--- sys/x86/x86/mptable.c
+++ sys/x86/x86/mptable.c
@@ -30,6 +30,7 @@
__FBSDID("$FreeBSD$");
#include "opt_mptable_force_htt.h"
+#include "opt_mptable_linux_bug_compat.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
@@ -245,6 +246,34 @@
return (UNKNOWN_BUSTYPE);
}
+#ifdef MPTABLE_LINUX_BUG_COMPAT
+/* Compute the correct entry_count value. */
+static void
+compute_entry_count(void)
+{
+ u_char *end = (u_char *)(mpct) + mpct->base_table_length;
+ u_char *entry = (u_char *)(mpct + 1);
+ size_t nentries = 0;
+
+ while (entry < end) {
+ switch (*entry) {
+ case MPCT_ENTRY_PROCESSOR:
+ case MPCT_ENTRY_IOAPIC:
+ case MPCT_ENTRY_BUS:
+ case MPCT_ENTRY_INT:
+ case MPCT_ENTRY_LOCAL_INT:
+ break;
+ default:
+ panic("%s: Unknown MP Config Entry %d\n", __func__,
+ (int)*entry);
+ }
+ entry += basetable_entry_types[*entry].length;
+ nentries++;
+ }
+ mpct->entry_count = (uint16_t)(nentries);
+}
+#endif
+
/*
* Look for an Intel MP spec table (ie, SMP capable hardware).
*/
@@ -273,6 +302,17 @@
if ((x = search_for_sig(target, BIOS_COUNT)) >= 0)
goto found;
+#ifdef MPTABLE_LINUX_BUG_COMPAT
+ /*
+ * Linux assumes that it always has 640 kB of base memory and
+ * searches for the MP table at 639k regardless of whether that
+ * address is present in the system memory map. Some VM systems
+ * rely on this buggy behaviour.
+ */
+ if ((x = search_for_sig(639 * 1024, 1024 / 4)) >= 0)
+ goto found;
+#endif
+
/* nothing found */
return (ENXIO);
@@ -321,6 +361,16 @@
printf(
"MP Configuration Table version 1.%d found at %p\n",
mpct->spec_rev, mpct);
+#ifdef MPTABLE_LINUX_BUG_COMPAT
+ /*
+ * Linux ignores entry_count and instead scans the MP table
+ * until it runs out of bytes of table (as specified by the
+ * base_table_length field). Some VM systems rely on this
+ * buggy behaviour and record an entry_count of zero.
+ */
+ if (mpct->entry_count == 0)
+ compute_entry_count();
+#endif
}
return (-100);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Dec 27, 1:31 PM (55 m, 43 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15614814
Default Alt Text
D35799.id108381.diff (2 KB)
Attached To
Mode
D35799: x86: Add COMPAT_LINUX_MPTABLE_BUGS option
Attached
Detach File
Event Timeline
Log In to Comment