static TAILQ_HEAD(, ioapic_enumerator) ioapic_enumerators =
TAILQ_HEAD_INITIALIZER(ioapic_enumerators);
-int ioapic_enable = 1; /* I/O APIC is enabled by default */
+int ioapic_enable = -1; /* I/O APIC auto-enable mode */
static int
ioapic_config(void)
TUNABLE_INT_FETCH("hw.lapic_enable", &lapic_enable);
/*
+ * Some of the virtaul machines do not work w/ I/O APIC
+ * enabled. If the user does not explicitly enable or
+ * disable the I/O APIC (ioapic_enable < 0), then we
+ * disable I/O APIC on all virtual machines.
+ */
+ if (ioapic_enable < 0) {
+ if (cpu_feature2 & CPUID2_VMM)
+ ioapic_enable = 0;
+ else
+ ioapic_enable = 1;
+ }
+
+ /*
* start with one cpu. Note: with one cpu, ncpus2_shift, ncpus2_mask,
* and ncpus_fit_mask remain 0.
*/
static TAILQ_HEAD(, ioapic_enumerator) ioapic_enumerators =
TAILQ_HEAD_INITIALIZER(ioapic_enumerators);
-int ioapic_enable = 1; /* I/O APIC is enabled by default */
+int ioapic_enable = -1; /* I/O APIC auto-enable mode */
static int
ioapic_config(void)
*/
MachIntrABI = MachIntrABI_ICU;
- TUNABLE_INT_FETCH("hw.apic_io_enable", &ioapic_enable); /* for compat */
- TUNABLE_INT_FETCH("hw.ioapic_enable", &ioapic_enable);
- TUNABLE_INT_FETCH("hw.lapic_enable", &lapic_enable);
-
/*
* start with one cpu. Note: with one cpu, ncpus2_shift, ncpus2_mask,
* and ncpus_fit_mask remain 0.
identify_cpu(); /* Final stage of CPU initialization */
initializecpu(); /* Initialize CPU registers */
+ TUNABLE_INT_FETCH("hw.apic_io_enable", &ioapic_enable); /* for compat */
+ TUNABLE_INT_FETCH("hw.ioapic_enable", &ioapic_enable);
+ TUNABLE_INT_FETCH("hw.lapic_enable", &lapic_enable);
+
+ /*
+ * Some of the virtaul machines do not work w/ I/O APIC
+ * enabled. If the user does not explicitly enable or
+ * disable the I/O APIC (ioapic_enable < 0), then we
+ * disable I/O APIC on all virtual machines.
+ *
+ * NOTE:
+ * This must be done after identify_cpu(), which sets
+ * 'cpu_feature2'
+ */
+ if (ioapic_enable < 0) {
+ if (cpu_feature2 & CPUID2_VMM)
+ ioapic_enable = 0;
+ else
+ ioapic_enable = 1;
+ }
+
/* make an initial tss so cpu can get interrupt stack on syscall! */
gd->gd_common_tss.tss_rsp0 =
(register_t)(thread0.td_kstack +