Re: [PATCH 1/2] Make BIOS irq0-inti2 override configurable from userspace

2009-04-16 Thread Avi Kivity

Beth Kon wrote:

These patches resolve the irq0-inti2 override issue, and get the hpet working
on kvm with and without -no-kvm-irqchip (i.e., when hpet takes over, it 
disables userspace or in-kernel pit as appropriate).


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. 
  


Both patches look good.  However, the bios in kvm-userspace.git is 
pretty old.  To ease later merging, I'd like to update the bios first, 
so please rebase the patches once I've done that.  It will take a few 
days since large merges are blocked while I struggle to get a working 
kvm-85 out.


Please also separate the bios patches from qemu patches.

--
Do not meddle in the internals of kernels, for they are subtle and quick to 
panic.

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] Make BIOS irq0-inti2 override configurable from userspace

2009-04-09 Thread Beth Kon
These patches resolve the irq0-inti2 override issue, and get the hpet working
on kvm with and without -no-kvm-irqchip (i.e., when hpet takes over, it 
disables userspace or in-kernel pit as appropriate).

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. 

Signed-off-by: Beth Kon e...@us.ibm.com

diff --git a/bios/rombios32.c b/bios/rombios32.c
index 4dea066..5cf1f54 100755
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
@@ -443,6 +443,7 @@ uint32_t cpuid_ext_features;
 unsigned long ram_size;
 uint64_t ram_end;
 uint8_t bios_uuid[16];
+uint8_t irq0_override;
 #ifdef BX_USE_EBDA_TABLES
 unsigned long ebda_cur_addr;
 #endif
@@ -475,6 +476,7 @@ void wrmsr_smp(uint32_t index, uint64_t val)
 #define QEMU_CFG_SIGNATURE  0x00
 #define QEMU_CFG_ID 0x01
 #define QEMU_CFG_UUID   0x02
+#define QEMU_CFG_IRQ0_OVERRIDE 0x0d
 
 int qemu_cfg_port;
 
@@ -516,6 +518,18 @@ void uuid_probe(void)
 memset(bios_uuid, 0, 16);
 }
 
+void irq0_override_probe(void)
+{
+#ifdef BX_QEMU
+if(qemu_cfg_port) {
+qemu_cfg_select(QEMU_CFG_IRQ0_OVERRIDE);
+qemu_cfg_read(irq0_override, 1);
+return;
+}
+#endif
+memset(irq0_override, 0, 1);
+}
+
 void cpu_probe(void)
 {
 uint32_t eax, ebx, ecx, edx;
@@ -1152,6 +1166,8 @@ static void mptable_init(void)
 
 /* irqs */
 for(i = 0; i  16; i++) {
+if (irq0_override  i == 2)
+continue;
 putb(q, 3); /* entry type = I/O interrupt */
 putb(q, 0); /* interrupt type = vectored interrupt */
 putb(q, 0); /* flags: po=0, el=0 */
@@ -1159,7 +1175,10 @@ 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 */
+if (irq0_override  i == 0)
+putb(q, 2); /* dest I/O APIC interrupt in */
+else
+putb(q, i); /* dest I/O APIC interrupt in */
 }
 /* patch length */
 len = q - mp_config_table;
@@ -1508,6 +1527,11 @@ void acpi_bios_init(void)
 sizeof(struct madt_processor_apic) * MAX_CPUS +
 sizeof(struct madt_io_apic);
 madt = (void *)(addr);
+for (i = 0; i  16; i++)
+if (PCI_ISA_IRQ_MASK  (1U  i))
+madt_size += sizeof(struct madt_intsrcovr);
+if (irq0_override)
+madt_size += sizeof(struct madt_intsrcovr);
 addr += madt_size;
 
 acpi_tables_size = addr - base_addr;
@@ -1597,8 +1621,15 @@ void acpi_bios_init(void)
 io_apic-interrupt = cpu_to_le32(0);
 
 intsrcovr = (struct madt_intsrcovr*)(io_apic + 1);
-for ( i = 0; i  16; i++ ) {
-if ( PCI_ISA_IRQ_MASK  (1U  i) ) {
+for (i = 0; i  16; i++) {
+if (irq0_override  i == 0) {
+memset(intsrcovr, 0, sizeof(*intsrcovr));
+intsrcovr-type   = APIC_XRUPT_OVERRIDE;
+intsrcovr-length = sizeof(*intsrcovr);
+intsrcovr-source = i;
+intsrcovr-gsi= 2;
+intsrcovr-flags  = 0;  //conforms to bus specifications
+} else if (PCI_ISA_IRQ_MASK  (1U  i)) {
 memset(intsrcovr, 0, sizeof(*intsrcovr));
 intsrcovr-type   = APIC_XRUPT_OVERRIDE;
 intsrcovr-length = sizeof(*intsrcovr);
@@ -1610,7 +1641,6 @@ void acpi_bios_init(void)
 continue;
 }
 intsrcovr++;
-madt_size += sizeof(struct madt_intsrcovr);
 }
 acpi_build_table_header((struct acpi_table_header *)madt,
 APIC, madt_size, 1);
@@ -2230,6 +2260,8 @@ void rombios32_init(uint32_t *s3_resume_vector, uint8_t 
*shutdown_flag)
 
 if (bios_table_cur_addr != 0) {
 
+irq0_override_probe();
+
 mptable_init();
 
 uuid_probe();
diff --git a/qemu/hw/fw_cfg.c b/qemu/hw/fw_cfg.c
index e324e8d..f06dc3c 100644
--- a/qemu/hw/fw_cfg.c
+++ b/qemu/hw/fw_cfg.c
@@ -279,6 +279,7 @@ void *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
 fw_cfg_add_bytes(s, FW_CFG_UUID, qemu_uuid, 16);
 fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)nographic);
 fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
+fw_cfg_add_i16(s, FW_CFG_IRQ0_OVERRIDE, (uint16_t)irq0override);
 
 register_savevm(fw_cfg, -1, 1, fw_cfg_save, fw_cfg_load,