ChangeSet 1.1599, 2005/05/30 22:15:54+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx
By default do not enable local APIC if disabled by the BIOS. This
matches Linux behaviour and ought to improve stability on buggy
hardware/firmware (laptops in particular). As in Linux, you can
forcibly enable the APIC with 'lapic' command-line option, or
forcibly ignore it with 'nolapic'.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
docs/src/user.tex | 26 ++++++++++++++-------
xen/arch/x86/apic.c | 51 ++++++++++++++++++++++++++++++++++++++++++-
xen/arch/x86/genapic/probe.c | 36 ++++++++++--------------------
xen/arch/x86/setup.c | 19 ++--------------
4 files changed, 83 insertions(+), 49 deletions(-)
diff -Nru a/docs/src/user.tex b/docs/src/user.tex
--- a/docs/src/user.tex 2005-05-30 18:02:07 -04:00
+++ b/docs/src/user.tex 2005-05-30 18:02:07 -04:00
@@ -1770,14 +1770,25 @@
Select the CPU scheduler Xen should use. The current
possibilities are `bvt' (default), `atropos' and `rrobin'.
For more information see Section~\ref{s:sched}.
-\end{description}
-In addition, the following platform-specific options may be specified
-on the Xen command line. Since domain 0 shares responsibility for
-booting the platform, Xen will automatically propagate these options
-to its command line.
+\item [apic\_verbosity=debug,verbose ]
+ Print more detailed information about local APIC and IOAPIC configuration.
+
+\item [lapic ]
+ Force use of local APIC even when left disabled by uniprocessor BIOS.
+
+\item [nolapic ]
+ Ignore local APIC in a uniprocessor system, even if enabled by the BIOS.
+
+\item [apic=bigsmp,default,es7000,summit ]
+ Specify NUMA platform. This can usually be probed automatically.
-These options are taken from Linux's command-line syntax with
+\end{description}
+
+In addition, the following options may be specified on the Xen command
+line. Since domain 0 shares responsibility for booting the platform,
+Xen will automatically propagate these options to its command
+line. These options are taken from Linux's command-line syntax with
unchanged semantics.
\begin{description}
@@ -1791,9 +1802,6 @@
\item [noapic ]
Instruct Xen (and domain 0) to ignore any IOAPICs that are present in
the system, and instead continue to use the legacy PIC.
-
-\item [apic=debug,verbose ]
- Print more detailed information about local APIC and IOAPIC configuration.
\end{description}
diff -Nru a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c
--- a/xen/arch/x86/apic.c 2005-05-30 18:02:07 -04:00
+++ b/xen/arch/x86/apic.c 2005-05-30 18:02:07 -04:00
@@ -99,6 +99,13 @@
apic_write_around(APIC_LVTPC, v | APIC_LVT_MASKED);
}
+/* lets not touch this if we didn't frob it */
+#ifdef CONFIG_X86_MCE_P4THERMAL
+ if (maxlvt >= 5) {
+ v = apic_read(APIC_LVTTHMR);
+ apic_write_around(APIC_LVTTHMR, v | APIC_LVT_MASKED);
+ }
+#endif
/*
* Clean APIC state for other OSs:
*/
@@ -110,6 +117,10 @@
if (maxlvt >= 4)
apic_write_around(APIC_LVTPC, APIC_LVT_MASKED);
+#ifdef CONFIG_X86_MCE_P4THERMAL
+ if (maxlvt >= 5)
+ apic_write_around(APIC_LVTTHMR, APIC_LVT_MASKED);
+#endif
v = GET_APIC_VERSION(apic_read(APIC_LVR));
if (APIC_INTEGRATED(v)) { /* !82489DX */
if (maxlvt > 3) /* Due to Pentium errata 3AP and 11AP. */
@@ -134,6 +145,7 @@
outb(0x70, 0x22);
outb(0x01, 0x23);
}
+ enable_apic_mode();
}
void disconnect_bsp_APIC(void)
@@ -448,20 +460,45 @@
* Original code written by Keir Fraser.
*/
+/*
+ * Knob to control our willingness to enable the local APIC.
+ */
+int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */
+
+static void __init lapic_disable(char *str)
+{
+ enable_local_apic = -1;
+ clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+}
+custom_param("nolapic", lapic_disable);
+
+static void __init lapic_enable(char *str)
+{
+ enable_local_apic = 1;
+}
+custom_param("lapic", lapic_enable);
+
static void __init apic_set_verbosity(char *str)
{
if (strcmp("debug", str) == 0)
apic_verbosity = APIC_DEBUG;
else if (strcmp("verbose", str) == 0)
apic_verbosity = APIC_VERBOSE;
+ else
+ printk(KERN_WARNING "APIC Verbosity level %s not recognised"
+ " use apic_verbosity=verbose or apic_verbosity=debug", str);
}
-custom_param("apic", apic_set_verbosity);
+custom_param("apic_verbosity", apic_set_verbosity);
static int __init detect_init_APIC (void)
{
u32 h, l, features;
extern void get_cpu_vendor(struct cpuinfo_x86*);
+ /* Disabled by kernel option? */
+ if (enable_local_apic < 0)
+ return -1;
+
/* Workaround for us being called before identify_cpu(). */
get_cpu_vendor(&boot_cpu_data);
@@ -482,6 +519,15 @@
if (!cpu_has_apic) {
/*
+ * Over-ride BIOS and try to enable the local
+ * APIC only if "lapic" specified.
+ */
+ if (enable_local_apic <= 0) {
+ printk("Local APIC disabled by BIOS -- "
+ "you can enable it with \"lapic\"\n");
+ return -1;
+ }
+ /*
* Some BIOSes disable the local APIC in the
* APIC_BASE MSR. This can only be done in
* software for Intel P6 or later and AMD K7
@@ -951,6 +997,9 @@
*/
int __init APIC_init_uniprocessor (void)
{
+ if (enable_local_apic < 0)
+ clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+
if (!smp_found_config && !cpu_has_apic)
return -1;
diff -Nru a/xen/arch/x86/genapic/probe.c b/xen/arch/x86/genapic/probe.c
--- a/xen/arch/x86/genapic/probe.c 2005-05-30 18:02:07 -04:00
+++ b/xen/arch/x86/genapic/probe.c 2005-05-30 18:02:07 -04:00
@@ -19,7 +19,7 @@
extern struct genapic apic_es7000;
extern struct genapic apic_default;
-struct genapic *genapic = &apic_default;
+struct genapic *genapic;
struct genapic *apic_probe[] __initdata = {
&apic_summit,
@@ -29,38 +29,28 @@
NULL,
};
-void __init generic_apic_probe(char *command_line)
+static void __init genapic_apic_force(char *str)
+{
+ int i;
+ for (i = 0; apic_probe[i]; i++)
+ if (!strcmp(apic_probe[i]->name, str))
+ genapic = apic_probe[i];
+}
+custom_param("apic", genapic_apic_force);
+
+void __init generic_apic_probe(void)
{
- char *s;
int i;
- int changed = 0;
+ int changed = (genapic != NULL);
- s = strstr(command_line, "apic=");
- if (s && (s == command_line || isspace(s[-1]))) {
- char *p = strchr(s, ' '), old;
- if (!p)
- p = strchr(s, '\0');
- old = *p;
- *p = 0;
- for (i = 0; !changed && apic_probe[i]; i++) {
- if (!strcmp(apic_probe[i]->name, s+5)) {
- changed = 1;
- genapic = apic_probe[i];
- }
- }
- if (!changed)
- printk(KERN_ERR "Unknown genapic `%s' specified.\n", s);
- *p = old;
- }
for (i = 0; !changed && apic_probe[i]; i++) {
if (apic_probe[i]->probe()) {
changed = 1;
genapic = apic_probe[i];
}
}
- /* Not visible without early console */
if (!changed)
- panic("Didn't find an APIC driver");
+ genapic = &apic_default;
printk(KERN_INFO "Using APIC driver %s\n", genapic->name);
}
diff -Nru a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c 2005-05-30 18:02:07 -04:00
+++ b/xen/arch/x86/setup.c 2005-05-30 18:02:07 -04:00
@@ -21,7 +21,7 @@
#include <asm/e820.h>
extern void dmi_scan_machine(void);
-extern void generic_apic_probe(char *);
+extern void generic_apic_probe(void);
/*
* opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
@@ -67,8 +67,6 @@
extern int skip_ioapic_setup;
boolean_param("noapic", skip_ioapic_setup);
-static char *xen_cmdline;
-
int early_boot = 1;
int ht_per_core = 1;
@@ -179,8 +177,7 @@
dmi_scan_machine();
- if ( xen_cmdline != NULL )
- generic_apic_probe(xen_cmdline);
+ generic_apic_probe();
acpi_boot_table_init();
acpi_boot_init();
@@ -251,10 +248,7 @@
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|