From: Beth Kon <eak@us.ibm.com>
To: avi@redhat.com
Cc: kvm@vger.kernel.org, Beth Kon <eak@us.ibm.com>
Subject: [PATCH 1/4] BIOS changes for configuring irq0->inti2 override (v3)
Date: Mon, 11 May 2009 13:29:43 -0400 [thread overview]
Message-ID: <1242062986-29383-1-git-send-email-eak@us.ibm.com> (raw)
These patches resolve the irq0->inti2 override issue, and get the hpet working
on kvm.
Override and HPET changes are sent as a series because HPET depends on the
override. Win2k8 expects the HPET interrupt on inti2, regardless of whether
an override exists in the BIOS. And the HPET spec states that in legacy mode,
timer interrupt is on inti2.
The irq0->inti2 override will always be used unless the kernel cannot do irq
routing (i.e., compatibility with old kernels). So if the kernel is capable,
userspace sets up irq0->inti2 via the irq routing interface, and adds the
irq0->inti2 override to the MADT interrupt source override table,
and the mp table (for the no-acpi case).
A couple of months ago, Marcelo was seeing RHEL5 guests complain of invalid
checksum with these patches, but later he couldn't reproduce it, and I'm not
seeing it now. While all guests still need to be fully tested, everything
appears to be in order. I've tested on win2k864, win2k832, RHEL5.3 32 bit,
and ubuntu 8.10 64 bit.
Changes from v2:
- rebased on latest kvm
- fixed build problems with --disable-kvm (kvm_kpit_enable/disable)
Signed-off-by: Beth Kon <eak@us.ibm.com>
diff --git a/kvm/bios/rombios32.c b/kvm/bios/rombios32.c
index cbd5f15..53359b8 100755
--- a/kvm/bios/rombios32.c
+++ b/kvm/bios/rombios32.c
@@ -444,6 +444,9 @@ uint32_t cpuid_features;
uint32_t cpuid_ext_features;
unsigned long ram_size;
uint64_t ram_end;
+#ifdef BX_QEMU
+uint8_t irq0_override;
+#endif
#ifdef BX_USE_EBDA_TABLES
unsigned long ebda_cur_addr;
#endif
@@ -485,6 +488,7 @@ void wrmsr_smp(uint32_t index, uint64_t val)
#define QEMU_CFG_ARCH_LOCAL 0x8000
#define QEMU_CFG_ACPI_TABLES (QEMU_CFG_ARCH_LOCAL + 0)
#define QEMU_CFG_SMBIOS_ENTRIES (QEMU_CFG_ARCH_LOCAL + 1)
+#define QEMU_CFG_IRQ0_OVERRIDE (QEMU_CFG_ARCH_LOCAL + 2)
int qemu_cfg_port;
@@ -553,6 +557,18 @@ uint64_t qemu_cfg_get64 (void)
}
#endif
+#ifdef BX_QEMU
+void irq0_override_probe(void)
+{
+ if(qemu_cfg_port) {
+ qemu_cfg_select(QEMU_CFG_IRQ0_OVERRIDE);
+ qemu_cfg_read(&irq0_override, 1);
+ return;
+ }
+ memset(&irq0_override, 0, 1);
+}
+#endif
+
void cpu_probe(void)
{
uint32_t eax, ebx, ecx, edx;
@@ -1195,6 +1211,13 @@ static void mptable_init(void)
/* irqs */
for(i = 0; i < 16; i++) {
+#ifdef BX_QEMU
+ /* One entry per ioapic interrupt destination. Destination 2 is covered
+ * by irq0->inti2 override (i == 0). Source IRQ 2 is unused
+ */
+ if (irq0_override && i == 2)
+ continue;
+#endif
putb(&q, 3); /* entry type = I/O interrupt */
putb(&q, 0); /* interrupt type = vectored interrupt */
putb(&q, 0); /* flags: po=0, el=0 */
@@ -1202,7 +1225,12 @@ static void mptable_init(void)
putb(&q, 0); /* source bus ID = ISA */
putb(&q, i); /* source bus IRQ */
putb(&q, ioapic_id); /* dest I/O APIC ID */
- putb(&q, i); /* dest I/O APIC interrupt in */
+#ifdef BX_QEMU
+ if (irq0_override && i == 0)
+ putb(&q, 2); /* dest I/O APIC interrupt in */
+ else
+#endif
+ putb(&q, i); /* dest I/O APIC interrupt in */
}
/* patch length */
len = q - mp_config_table;
@@ -1665,16 +1693,18 @@ void acpi_bios_init(void)
addr = (addr + 7) & ~7;
madt_addr = addr;
+ madt = (void *)(addr);
madt_size = sizeof(*madt) +
sizeof(struct madt_processor_apic) * MAX_CPUS +
-#ifdef BX_QEMU
- sizeof(struct madt_io_apic) /* + sizeof(struct madt_int_override) */;
-#else
sizeof(struct madt_io_apic);
+#ifdef BX_QEMU
+ for (i = 0; i < 16; i++)
+ if (PCI_ISA_IRQ_MASK & (1U << i))
+ madt_size += sizeof(struct madt_int_override);
+ if (irq0_override)
+ madt_size += sizeof(struct madt_int_override);
#endif
- madt = (void *)(addr);
addr += madt_size;
-
#ifdef BX_QEMU
#ifdef HPET_WORKS_IN_KVM
addr = (addr + 7) & ~7;
@@ -1758,23 +1788,20 @@ void acpi_bios_init(void)
io_apic->io_apic_id = smp_cpus;
io_apic->address = cpu_to_le32(0xfec00000);
io_apic->interrupt = cpu_to_le32(0);
+ int_override = (struct madt_int_override*)(io_apic + 1);
#ifdef BX_QEMU
-#ifdef HPET_WORKS_IN_KVM
- io_apic++;
-
- int_override = (void *)io_apic;
- int_override->type = APIC_XRUPT_OVERRIDE;
- int_override->length = sizeof(*int_override);
- int_override->bus = cpu_to_le32(0);
- int_override->source = cpu_to_le32(0);
- int_override->gsi = cpu_to_le32(2);
- int_override->flags = cpu_to_le32(0);
-#endif
+ if (irq0_override) {
+ memset(int_override, 0, sizeof(*int_override));
+ int_override->type = APIC_XRUPT_OVERRIDE;
+ int_override->length = sizeof(*int_override);
+ int_override->source = 0;
+ int_override->gsi = 2;
+ int_override->flags = 0; /* conforms to bus specifications */
+ int_override++;
+ }
#endif
-
- int_override = (struct madt_int_override*)(io_apic + 1);
for ( i = 0; i < 16; i++ ) {
- if ( PCI_ISA_IRQ_MASK & (1U << i) ) {
+ if (PCI_ISA_IRQ_MASK & (1U << i)) {
memset(int_override, 0, sizeof(*int_override));
int_override->type = APIC_XRUPT_OVERRIDE;
int_override->length = sizeof(*int_override);
@@ -1786,7 +1813,6 @@ void acpi_bios_init(void)
continue;
}
int_override++;
- madt_size += sizeof(struct madt_int_override);
}
acpi_build_table_header((struct acpi_table_header *)madt,
"APIC", madt_size, 1);
@@ -2697,6 +2723,9 @@ void rombios32_init(uint32_t *s3_resume_vector, uint8_t *shutdown_flag)
if (bios_table_cur_addr != 0) {
+#ifdef BX_QEMU
+ irq0_override_probe();
+#endif
mptable_init();
smbios_init();
next reply other threads:[~2009-05-11 17:29 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-05-11 17:29 Beth Kon [this message]
2009-05-11 17:29 ` [PATCH 2/4] Userspace changes for configuring irq0->inti2 override (v3) Beth Kon
2009-05-12 9:53 ` Gleb Natapov
2009-05-12 10:22 ` Avi Kivity
2009-05-12 10:52 ` Gleb Natapov
2009-05-12 13:20 ` [PATCH 2/4] Userspace changes for configuring irq0->inti2override (v3) Beth Kon
2009-05-12 13:37 ` Gleb Natapov
2009-05-12 13:29 ` Beth Kon
2009-05-11 17:29 ` [PATCH 3/4] BIOS changes for KVM HPET (v3) Beth Kon
2009-05-11 17:29 ` [PATCH 4/4] Userspace " Beth Kon
2009-05-12 9:03 ` Avi Kivity
2009-05-12 14:25 ` Beth Kon
2009-05-12 16:27 ` Beth Kon
2009-05-13 7:48 ` Avi Kivity
2009-05-13 7:50 ` Avi Kivity
2009-05-12 9:57 ` [PATCH 1/4] BIOS changes for configuring irq0->inti2 override (v3) Gleb Natapov
2009-05-12 13:59 ` [PATCH 1/4] BIOS changes for configuring irq0->inti2 override(v3) Beth Kon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1242062986-29383-1-git-send-email-eak@us.ibm.com \
--to=eak@us.ibm.com \
--cc=avi@redhat.com \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox