Skip to contentSkip to conversation

Disentagle ISA IRQs

PATCH In review Avi Kivity 10 participants 31 messages Aug 9, 2009 – Aug 30, 2009

lore
Share & tools
lore

Avi Kivity

author
#0 lore raw

cover Disentagle ISA IRQs

Currently ISA IRQs are delivered directly to the PIC, which reroutes them to the IOAPIC as well. This patchset introduces ISA IRQs, which are routed both to the PIC and the IOAPIC. As a side effect, IOAPIC lines 16-23 are enabled; it also becomes easier to add IOAPICs.

Avi Kivity (2):
Route PC irqs to ISA bus instead of i8259 directly Route IOAPIC interrupts via ISA bus

 hw/i8259.c  |   13 -------------
 hw/ioapic.c |    6 ++++--
 hw/pc.c     |   54 +++++++++++++++++++++++++++++++++++-------------------
 hw/pc.h     |    4 +---
 4 files changed, 40 insertions(+), 37 deletions(-)
author
#1 lore raw

PATCH 1/2 Route PC irqs to ISA bus instead of i8259 directly

A PC has its motherboard IRQ lines connected to both the PIC and IOAPIC. Currently, qemu routes IRQs to the PIC which then calls the IOAPIC, an incestuous arrangement. In order to clean this up, create a new ISA IRQ abstraction, and have devices raise ISA IRQs (which in turn raise the i8259 IRQs as usual).

---
 hw/pc.c |   44 ++++++++++++++++++++++++++++++--------------
 1 files changed, 30 insertions(+), 14 deletions(-)
hw/pc.c +30 -14
index bc9e646..a6be4a8 100644
@@ -87,6 +87,17 @@ static void option_rom_setup_reset(target_phys_addr_t addr, unsigned size)
     qemu_register_reset(option_rom_reset, rrd);
 }
 
+typedef struct isa_irq_state {
+    qemu_irq *i8259;
+} IsaIrqState;
+
+static void isa_irq_handler(void *opaque, int n, int level)
+{
+    IsaIrqState *isa = (IsaIrqState *)opaque;
+
+    qemu_set_irq(isa->i8259[n], level);
+}
+
 static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
 {
 }
@@ -1119,7 +1130,9 @@ static void pc_init1(ram_addr_t ram_size,
     int piix3_devfn = -1;
     CPUState *env;
     qemu_irq *cpu_irq;
+    qemu_irq *isa_irq;
     qemu_irq *i8259;
+    IsaIrqState *isa_irq_state;
     DriveInfo *dinfo;
     BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     BlockDriverState *fd[MAX_FD];
@@ -1264,10 +1277,13 @@ static void pc_init1(ram_addr_t ram_size,
 
     cpu_irq = qemu_allocate_irqs(pic_irq_request, NULL, 1);
     i8259 = i8259_init(cpu_irq[0]);
-    ferr_irq = i8259[13];
+    isa_irq_state = qemu_mallocz(sizeof(*isa_irq_state));
+    isa_irq_state->i8259 = i8259;
+    isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 16);
+    ferr_irq = isa_irq[13];
 
     if (pci_enabled) {
-        pci_bus = i440fx_init(&i440fx_state, i8259);
+        pci_bus = i440fx_init(&i440fx_state, isa_irq);
         piix3_devfn = piix3_init(pci_bus, -1);
     } else {
         pci_bus = NULL;
@@ -1297,7 +1313,7 @@ static void pc_init1(ram_addr_t ram_size,
         }
     }
 
-    rtc_state = rtc_init(0x70, i8259[8], 2000);
+    rtc_state = rtc_init(0x70, isa_irq[8], 2000);
 
     qemu_register_boot_set(pc_boot_set, rtc_state);
 
@@ -1307,10 +1323,10 @@ static void pc_init1(ram_addr_t ram_size,
     if (pci_enabled) {
         ioapic = ioapic_init();
     }
-    pit = pit_init(0x40, i8259[0]);
+    pit = pit_init(0x40, isa_irq[0]);
     pcspk_init(pit);
     if (!no_hpet) {
-        hpet_init(i8259);
+        hpet_init(isa_irq);
     }
     if (pci_enabled) {
         pic_set_alt_irq_func(isa_pic, ioapic_set_irq, ioapic);
@@ -1318,14 +1334,14 @@ static void pc_init1(ram_addr_t ram_size,
 
     for(i = 0; i < MAX_SERIAL_PORTS; i++) {
         if (serial_hds[i]) {
-            serial_init(serial_io[i], i8259[serial_irq[i]], 115200,
+            serial_init(serial_io[i], isa_irq[serial_irq[i]], 115200,
                         serial_hds[i]);
         }
     }
 
     for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
         if (parallel_hds[i]) {
-            parallel_init(parallel_io[i], i8259[parallel_irq[i]],
+            parallel_init(parallel_io[i], isa_irq[parallel_irq[i]],
                           parallel_hds[i]);
         }
     }
@@ -1336,7 +1352,7 @@ static void pc_init1(ram_addr_t ram_size,
         NICInfo *nd = &nd_table[i];
 
         if (!pci_enabled || (nd->model && strcmp(nd->model, "ne2k_isa") == 0))
-            pc_init_ne2k_isa(nd, i8259);
+            pc_init_ne2k_isa(nd, isa_irq);
         else
             pci_nic_init(nd, "ne2k_pci", NULL);
     }
@@ -1354,25 +1370,25 @@ static void pc_init1(ram_addr_t ram_size,
     }
 
     if (pci_enabled) {
-        pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1, i8259);
+        pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1, isa_irq);
     } else {
         for(i = 0; i < MAX_IDE_BUS; i++) {
-            isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]],
+            isa_ide_init(ide_iobase[i], ide_iobase2[i], isa_irq[ide_irq[i]],
 	                 hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]);
         }
     }
 
-    i8042_init(i8259[1], i8259[12], 0x60);
+    i8042_init(isa_irq[1], isa_irq[12], 0x60);
     DMA_init(0);
 #ifdef HAS_AUDIO
-    audio_init(pci_enabled ? pci_bus : NULL, i8259);
+    audio_init(pci_enabled ? pci_bus : NULL, isa_irq);
 #endif
 
     for(i = 0; i < MAX_FD; i++) {
         dinfo = drive_get(IF_FLOPPY, 0, i);
         fd[i] = dinfo ? dinfo->bdrv : NULL;
     }
-    floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd);
+    floppy_controller = fdctrl_init(isa_irq[6], 2, 0, 0x3f0, fd);
 
     cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device, hd);
 
@@ -1385,7 +1401,7 @@ static void pc_init1(ram_addr_t ram_size,
         i2c_bus *smbus;
 
         /* TODO: Populate SPD eeprom data.  */
-        smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, i8259[9]);
+        smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100, isa_irq[9]);
         for (i = 0; i < 8; i++) {
             DeviceState *eeprom;
             eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
Signature · 1 line
1.6.2.5
#2 lore raw

Re: [Qemu-devel] [PATCH 1/2] Route PC irqs to ISA bus instead of i8259 directly

Quoted 5 lines · Avi Kivity

A PC has its motherboard IRQ lines connected to both the PIC and IOAPIC. Currently, qemu routes IRQs to the PIC which then calls the IOAPIC, an incestuous arrangement. In order to clean this up, create a new ISA IRQ abstraction, and have devices raise ISA IRQs (which in turn raise the i8259 IRQs as usual).

There are isa-bus qdev patches in anthonys patch queue. I think it makes sense to do this cleanup on top of the isa-bus patches. Maybe it makes sense to integrate it more, i.e. have the irqs as element in IsaBus ...

cheers,
Gerd

author
#3 lore raw

Re: [Qemu-devel] [PATCH 1/2] Route PC irqs to ISA bus instead of i8259 directly

Quoted 9 lines · Gerd Hoffmann
Quoted 5 lines · Avi Kivity

A PC has its motherboard IRQ lines connected to both the PIC and IOAPIC. Currently, qemu routes IRQs to the PIC which then calls the IOAPIC, an incestuous arrangement. In order to clean this up, create a new ISA IRQ abstraction, and have devices raise ISA IRQs (which in turn raise the i8259 IRQs as usual).

There are isa-bus qdev patches in anthonys patch queue. I think it makes sense to do this cleanup on top of the isa-bus patches. Maybe it makes sense to integrate it more, i.e. have the irqs as element in IsaBus ...

One thing at a time.

Signature · 1 line
error compiling committee.c: too many arguments to function
#4 lore raw

Re: [Qemu-devel] [PATCH 1/2] Route PC irqs to ISA bus instead of i8259 directly

In reply to Avi Kivity

Am 09.08.2009 um 18:44 schrieb Avi Kivity <[email protected]>:

Quoted 5 lines

A PC has its motherboard IRQ lines connected to both the PIC and IOAPIC. Currently, qemu routes IRQs to the PIC which then calls the IOAPIC, an incestuous arrangement. In order to clean this up, create a new ISA IRQ abstraction, and have devices raise ISA IRQs (which in turn raise the i8259 IRQs as usual).

Is this really true? From my understanding the PIC in modern systems is emulated through the IOAPIC, which is the reason we have legacy interrupts.

Copying the boot interrupt experts...

Alex

author
#5 lore raw

Re: [Qemu-devel] [PATCH 1/2] Route PC irqs to ISA bus instead of i8259 directly

Quoted 11 lines · Alexander Graf

Am 09.08.2009 um 18:44 schrieb Avi Kivity <[email protected]>:

Quoted 5 lines

A PC has its motherboard IRQ lines connected to both the PIC and IOAPIC. Currently, qemu routes IRQs to the PIC which then calls the IOAPIC, an incestuous arrangement. In order to clean this up, create a new ISA IRQ abstraction, and have devices raise ISA IRQs (which in turn raise the i8259 IRQs as usual).

Is this really true? From my understanding the PIC in modern systems is emulated through the IOAPIC, which is the reason we have legacy interrupts.

For the PC emulated by qemu, it is certainly true. I don't know for sure about modern PCs, but I bet they do respond to the PIC io ports.

Signature · 1 line
error compiling committee.c: too many arguments to function
#6 lore raw

Re: [Qemu-devel] [PATCH 1/2] Route PC irqs to ISA bus instead of i8259 directly

In reply to Alexander Graf
Quoted 10 lines · Alexander Graf

Am 09.08.2009 um 18:44 schrieb Avi Kivity <[email protected]>:

Quoted 6 lines

A PC has its motherboard IRQ lines connected to both the PIC and IOAPIC. Currently, qemu routes IRQs to the PIC which then calls the IOAPIC, an incestuous arrangement. In order to clean this up, create a new ISA IRQ abstraction, and have devices raise ISA IRQs (which in turn raise the i8259
IRQs as usual).

Quoted 2 lines

Is this really true? From my understanding the PIC in modern systems is emulated through the IOAPIC, which is the reason we have legacy interrupts.

While not sure how the hardware implementation is done in detail I can confirm that the IRQs indeed end up at both PIC and IO-APIC0 if the device is connected to the southbridge directly. If that's not the case for example a PCI bus connected via PCIe that sports it's own IO-APIC then IRQs are forwarded (over PCIe) from the IO-APIC to the southbridge (PIC).

In any case, to come closer to the real hardware having an abstraction that receives IRQs from devices and delivers them to the appropriate interrupt controller(s) seems to be a valid step IMHO.

Does qemu support multiple IO-APICs? I guess not so no need for boot interrupts. (If yes then there would be the question how close you really want to be to existing hardware.)

Stefan
--

Stefan Assmann         | Red Hat GmbH
Software Engineer      | Otto-Hahn-Strasse 20, 85609 Dornach
                       | HR: Amtsgericht Muenchen HRB 153243
                       | GF: Brendan Lane, Charlie Peters,
sassmann at redhat.com |     Michael Cunningham, Charles Cachera
author
#7 lore raw

Re: [Qemu-devel] [PATCH 1/2] Route PC irqs to ISA bus instead of i8259 directly

Quoted 3 lines · Stefan Assmann

Does qemu support multiple IO-APICs? I guess not so no need for boot interrupts. (If yes then there would be the question how close you really want to be to existing hardware.)

Not at present. We've considered adding IOAPICs to reduce interrupt sharing, but MSI solves the problem much more neatly.

Signature · 1 line
error compiling committee.c: too many arguments to function
#8 lore raw

Re: [Qemu-devel] [PATCH 1/2] Route PC irqs to ISA bus instead of i8259 directly

Quoted 8 lines · Avi Kivity
Quoted 3 lines · Stefan Assmann

Does qemu support multiple IO-APICs? I guess not so no need for boot interrupts. (If yes then there would be the question how close you really want to be to existing hardware.)

Not at present. We've considered adding IOAPICs to reduce interrupt sharing, but MSI solves the problem much more neatly.

Yes, all modern operating systems that come to my mind support MSIs, so as long as you do not want to run some old system, this is ok. I also guess that you do not try to emulate one of the chipsets that has a broken MSI implementation.

Signature · 1 line
Olaf Dabrunz (Olaf.Dabrunz <at> gmx.net)
#9 lore raw

Re: [Qemu-devel] [PATCH 1/2] Route PC irqs to ISA bus instead of i8259 directly

In reply to Stefan Assmann
Quoted 14 lines · Stefan Assmann
Quoted 10 lines · Alexander Graf

Am 09.08.2009 um 18:44 schrieb Avi Kivity <[email protected]>:

Quoted 6 lines

A PC has its motherboard IRQ lines connected to both the PIC and IOAPIC. Currently, qemu routes IRQs to the PIC which then calls the IOAPIC, an incestuous arrangement. In order to clean this up, create a new ISA IRQ abstraction, and have devices raise ISA IRQs (which in turn raise the i8259
IRQs as usual).

Quoted 2 lines

Is this really true? From my understanding the PIC in modern systems is emulated through the IOAPIC, which is the reason we have legacy interrupts.

Quoted 6 lines

While not sure how the hardware implementation is done in detail I can confirm that the IRQs indeed end up at both PIC and IO-APIC0 if the device is connected to the southbridge directly. If that's not the case for example a PCI bus connected via PCIe that sports it's own IO-APIC then IRQs are forwarded (over PCIe) from the IO-APIC to the southbridge (PIC).

To be exact, IRQs on modern PCs are routed to both an IO-APIC and the PIC via wires and some routing mechanism. (Support for the PIC is required by ACPI.) The routing mechanism to the PIC does _not_ involve an IO-APIC. It is implementation-specific to the chipset and the board, and operating systems get routing info from the ACPI tables (delivered by the BIOS). The routing to the PIC is set up by the BIOS, which knows how to program the chipset-specific routing registers.

The IO-APICs are standard components that are programmed by the operating system. They do not have any "forwarding to the PIC" component. The intention is that there are no implementation-specific differences between them (except for number of lines, the generation of the IO-APIC spec and slight differences in the hardware implementation). They are supposed to be programmable by the OS in a standard way. That is why they cannot be part of a scheme that routes IRQs to the PIC.

Now that being said, there are mechanisms like boot interrupts that on some chipsets activate forwarding of interrupts to the PIC, when the corresponding "line" in a (secondary) IO-APIC is disabled. This means that the IO-APIC state is "sampled" by some logic to select forwarding to the PIC. The IO-APIC itself is not part of this mechanism, it is just "being watched".

Quoted 9 lines

In any case, to come closer to the real hardware having an abstraction that receives IRQs from devices and delivers them to the appropriate interrupt controller(s) seems to be a valid step IMHO.

Does qemu support multiple IO-APICs? I guess not so no need for boot interrupts. (If yes then there would be the question how close you really want to be to existing hardware.)

Stefan

Signature · 1 line
Olaf Dabrunz (Olaf.Dabrunz <at> gmx.net)
author
#10 lore raw

PATCH 2/2 Route IOAPIC interrupts via ISA bus

In reply to Avi Kivity

Instead of calling the IOAPIC from the PIC, raise IOAPIC irqs via the ISA bus. As a side effect, IOAPIC lines 16-23 are enabled.

---
 hw/i8259.c  |   13 -------------
 hw/ioapic.c |    6 ++++--
 hw/pc.c     |   16 ++++++++--------
 hw/pc.h     |    4 +---
 4 files changed, 13 insertions(+), 26 deletions(-)
hw/i8259.c +0 -13
index 0b9fab5..74acc39 100644
@@ -60,9 +60,6 @@ struct PicState2 {
     PicState pics[2];
     qemu_irq parent_irq;
     void *irq_request_opaque;
-    /* IOAPIC callback support */
-    SetIRQFunc *alt_irq_func;
-    void *alt_irq_opaque;
 };
 
 #if defined(DEBUG_PIC) || defined (DEBUG_IRQ_COUNT)
@@ -203,9 +200,6 @@ static void i8259_set_irq(void *opaque, int irq, int level)
     }
 #endif
     pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
-    /* used for IOAPIC irqs */
-    if (s->alt_irq_func)
-        s->alt_irq_func(s->alt_irq_opaque, irq, level);
     pic_update_irq(s);
 }
 
@@ -562,10 +556,3 @@ qemu_irq *i8259_init(qemu_irq parent_irq)
     isa_pic = s;
     return qemu_allocate_irqs(i8259_set_irq, s, 16);
 }
-
-void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func,
-                          void *alt_irq_opaque)
-{
-    s->alt_irq_func = alt_irq_func;
-    s->alt_irq_opaque = alt_irq_opaque;
-}
hw/ioapic.c +4 -2
index a5cdd5d..998894d 100644
@@ -241,9 +241,10 @@ static CPUWriteMemoryFunc *ioapic_mem_write[3] = {
     ioapic_mem_writel,
 };
 
-IOAPICState *ioapic_init(void)
+qemu_irq *ioapic_init(void)
 {
     IOAPICState *s;
+    qemu_irq *irq;
     int io_memory;
 
     s = qemu_mallocz(sizeof(IOAPICState));
@@ -255,6 +256,7 @@ IOAPICState *ioapic_init(void)
 
     register_savevm("ioapic", 0, 1, ioapic_save, ioapic_load, s);
     qemu_register_reset(ioapic_reset, s);
+    irq = qemu_allocate_irqs(ioapic_set_irq, s, IOAPIC_NUM_PINS);
 
-    return s;
+    return irq;
 }
hw/pc.c +8 -8
index a6be4a8..5182a57 100644
@@ -60,7 +60,6 @@
 static fdctrl_t *floppy_controller;
 static RTCState *rtc_state;
 static PITState *pit;
-static IOAPICState *ioapic;
 static PCIDevice *i440fx_state;
 
 typedef struct rom_reset_data {
@@ -89,14 +88,18 @@ static void option_rom_setup_reset(target_phys_addr_t addr, unsigned size)
 
 typedef struct isa_irq_state {
     qemu_irq *i8259;
+    qemu_irq *ioapic;
 } IsaIrqState;
 
 static void isa_irq_handler(void *opaque, int n, int level)
 {
     IsaIrqState *isa = (IsaIrqState *)opaque;
 
-    qemu_set_irq(isa->i8259[n], level);
-}
+    if (n < 16) {
+        qemu_set_irq(isa->i8259[n], level);
+    }
+    qemu_set_irq(isa->ioapic[n], level);
+};
 
 static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
 {
@@ -1279,7 +1282,7 @@ static void pc_init1(ram_addr_t ram_size,
     i8259 = i8259_init(cpu_irq[0]);
     isa_irq_state = qemu_mallocz(sizeof(*isa_irq_state));
     isa_irq_state->i8259 = i8259;
-    isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 16);
+    isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24);
     ferr_irq = isa_irq[13];
 
     if (pci_enabled) {
@@ -1321,16 +1324,13 @@ static void pc_init1(ram_addr_t ram_size,
     register_ioport_write(0x92, 1, 1, ioport92_write, NULL);
 
     if (pci_enabled) {
-        ioapic = ioapic_init();
+        isa_irq_state->ioapic = ioapic_init();
     }
     pit = pit_init(0x40, isa_irq[0]);
     pcspk_init(pit);
     if (!no_hpet) {
         hpet_init(isa_irq);
     }
-    if (pci_enabled) {
-        pic_set_alt_irq_func(isa_pic, ioapic_set_irq, ioapic);
-    }
 
     for(i = 0; i < MAX_SERIAL_PORTS; i++) {
         if (serial_hds[i]) {
hw/pc.h +1 -3
index 9fbae20..043c216 100644
@@ -32,8 +32,6 @@ extern PicState2 *isa_pic;
 void pic_set_irq(int irq, int level);
 void pic_set_irq_new(void *opaque, int irq, int level);
 qemu_irq *i8259_init(qemu_irq parent_irq);
-void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func,
-                          void *alt_irq_opaque);
 int pic_read_irq(PicState2 *s);
 void pic_update_irq(PicState2 *s);
 uint32_t pic_intack_read(PicState2 *s);
@@ -50,7 +48,7 @@ int apic_init(CPUState *env);
 int apic_accept_pic_intr(CPUState *env);
 void apic_deliver_pic_intr(CPUState *env, int level);
 int apic_get_interrupt(CPUState *env);
-IOAPICState *ioapic_init(void);
+qemu_irq *ioapic_init(void);
 void ioapic_set_irq(void *opaque, int vector, int level);
 void apic_reset_irq_delivered(void);
 int apic_get_irq_delivered(void);
Signature · 1 line
1.6.2.5
#11 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

Hi,

Quoted 4 lines
  typedef struct isa_irq_state {
      qemu_irq *i8259;

+ qemu_irq *ioapic;
} IsaIrqState;

Well. Now it would probably better named "pc_irq_state". While that cleanup certainly makes sense it isn't a isa-bus thing any more.

cheers,
Gerd

#12 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

In reply to Avi Kivity
Quoted 2 lines · Avi Kivity

Instead of calling the IOAPIC from the PIC, raise IOAPIC irqs via the ISA bus. As a side effect, IOAPIC lines 16-23 are enabled.

Now we probably need some acpi magic to tell the guest OS that there are a few more IRQ lines?

cheers,
Gerd

author
#13 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

Quoted 6 lines · Gerd Hoffmann
Quoted 2 lines · Avi Kivity

Instead of calling the IOAPIC from the PIC, raise IOAPIC irqs via the ISA bus. As a side effect, IOAPIC lines 16-23 are enabled.

Now we probably need some acpi magic to tell the guest OS that there are a few more IRQ lines?

I wanted to route the PCI IRQs to those lines (and have eight links instead of four). Now I don't think it's worthwhile, as every guest that is interesting from a performance point of view has MSI support.

So I think we should just leave these lines as is, terminated with a 4.7K resistor to avoid picking up noise.

Signature · 1 line
error compiling committee.c: too many arguments to function
#14 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

Quoted 6 lines · Avi Kivity
Quoted 2 lines · Gerd Hoffmann

Now we probably need some acpi magic to tell the guest OS that there are a few more IRQ lines?

I wanted to route the PCI IRQs to those lines (and have eight links instead of four).

Right now we have IRQs 5,10,11 for PCI. Having one more IRQ (so we have one for each link) would be useful IMHO. eight links + eight irqs would be even more useful. What needs to be done for that?

BTW: Seems linux doesn't use IRQ 5 even with lots of PCI devices, instead it makes them share 10+11 ...

Quoted 2 lines

Now I don't think it's worthwhile, as every guest that is interesting from a performance point of view has MSI support.

Not all emulated devices have MSI support though ...

Quoted 2 lines

So I think we should just leave these lines as is, terminated with a 4.7K resistor to avoid picking up noise.

Oh, nice, didn't know kvm has virtual resistor support.

cheers,
Gerd

#15 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

Quoted 5 lines · Gerd Hoffmann
Quoted 4 lines · Avi Kivity
Quoted 2 lines · Gerd Hoffmann

Now we probably need some acpi magic to tell the guest OS that there are a few more IRQ lines?

Quoted 7 lines
Quoted 2 lines

I wanted to route the PCI IRQs to those lines (and have eight links instead of four).

Right now we have IRQs 5,10,11 for PCI. Having one more IRQ (so we have one for each link) would be useful IMHO. eight links + eight irqs would be even more useful. What needs to be done for that?

Current code uses piix3 irq router to route pci interrupts to pic _and_ ioapic and piix3 irq router supports only 16 interrupts.

--
Gleb.

#16 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

Quoted 7 lines · Gleb Natapov
Quoted 4 lines · Gerd Hoffmann

Right now we have IRQs 5,10,11 for PCI. Having one more IRQ (so we have one for each link) would be useful IMHO. eight links + eight irqs would be even more useful. What needs to be done for that?

Current code uses piix3 irq router to route pci interrupts to pic _and_ ioapic and piix3 irq router supports only 16 interrupts.

That means? We could add four more PCI links which have IRQs routed through another IRQ router chip and link them to ioapic lines 17-23 that way? Or does it mean we must emulate a more recent chipset?

cheers,
Gerd

#17 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

Quoted 10 lines · Gerd Hoffmann
Quoted 7 lines · Gleb Natapov
Quoted 4 lines · Gerd Hoffmann

Right now we have IRQs 5,10,11 for PCI. Having one more IRQ (so we have one for each link) would be useful IMHO. eight links + eight irqs would be even more useful. What needs to be done for that?

Current code uses piix3 irq router to route pci interrupts to pic _and_ ioapic and piix3 irq router supports only 16 interrupts.

That means? We could add four more PCI links which have IRQs routed

That means changing acpi/bios is unfortunately not enough.

Quoted 2 lines

through another IRQ router chip and link them to ioapic lines 17-23 that way?

Something like that. We can invent our own irq router and write driver for it in DSDT.

Quoted 2 lines

Or does it mean we must emulate a more recent chipset?

That too will work.

--
Gleb.

#18 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

Quoted 4 lines · Gleb Natapov
Quoted 2 lines · Gerd Hoffmann

Or does it mean we must emulate a more recent chipset?

That too will work.

Note that if you change the chipset, it'll break some existing Windows VMs.

I had this problem when porting a Windows Server 2003 VM from Virtual PC to QEMU: Virtual PC emulates a PIIX4, while QEMU provides a PIIX3 (even though there's a PIIX4 in the source code, it's not used for PC emulation). The ported image would not boot because of the change of chipset, until I patched the registry to accomodate the change.

It will be the same the other way: When some Windows VMs see a change from PIIX3 to a later chipset, they will not boot.

Some Windows VMs don't care as much. XP seems to be more like Linux, in that it adapts to different devices at boot time.

-- Jamie

Quoted 5 lines

--
Gleb.

#19 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

Quoted 9 lines · Jamie Lokier
Quoted 4 lines · Gleb Natapov
Quoted 2 lines · Gerd Hoffmann

Or does it mean we must emulate a more recent chipset?

That too will work.

Note that if you change the chipset, it'll break some existing Windows VMs.

I don't think it worth changing chipset just to solve irq routing problem. And PIIX4 is the same as PIIX3 in regards to pci irq routing.

Quoted 6 lines

I had this problem when porting a Windows Server 2003 VM from Virtual PC to QEMU: Virtual PC emulates a PIIX4, while QEMU provides a PIIX3 (even though there's a PIIX4 in the source code, it's not used for PC emulation). The ported image would not boot because of the change of chipset, until I patched the registry to accomodate the change.

Quoted 16 lines

It will be the same the other way: When some Windows VMs see a change from PIIX3 to a later chipset, they will not boot.

Some Windows VMs don't care as much. XP seems to be more like Linux, in that it adapts to different devices at boot time.

-- Jamie

Quoted 5 lines

--
Gleb.

--
Gleb.

#20 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

In reply to Jamie Lokier
Quoted 8 lines · Jamie Lokier
Quoted 4 lines · Gleb Natapov
Quoted 2 lines · Gerd Hoffmann

Or does it mean we must emulate a more recent chipset?

That too will work.

Note that if you change the chipset, it'll break some existing Windows VMs.

I think we would rather *add* a new machine type with a new chipset, not *replace* the piix3. IIRC someone is already working on emulation something more recent (ICH9?) to get some modern stuff, so that will probably get us some more ioapic lines.

Quoted 5 lines

I had this problem when porting a Windows Server 2003 VM from Virtual PC to QEMU: Virtual PC emulates a PIIX4, while QEMU provides a PIIX3 (even though there's a PIIX4 in the source code, it's not used for PC emulation). The ported image would not boot because of the change of chipset, until I patched the registry to accomodate the change.

Any hints where do dig in the registy? I have a dead notebook with xp (disk still ok), trying to boot the disk image in kvm, and of course it doesn't work due to the hardware being different. Googleing the STOP code printed on the blue screen hinted that xp fails to access the hard drive ...

It is a 5-year old intel laptop, so it probably is something like moving from ICH6 to PIIX3 ...

thanks,
Gerd

#21 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

Quoted 8 lines · Gerd Hoffmann
Quoted 7 lines · Jamie Lokier
Quoted 4 lines · Gleb Natapov
Quoted 2 lines · Gerd Hoffmann

Or does it mean we must emulate a more recent chipset?

That too will work.

Quoted 6 lines
Quoted 1 line

Note that if you change the chipset, it'll break some existing Windows VMs.

I think we would rather *add* a new machine type with a new chipset, not *replace* the piix3. IIRC someone is already working on emulation something more recent (ICH9?) to get some modern stuff, so that will probably get us some more ioapic lines.

Yes, I'm working on q35 (gmch, ich9) chipset emulators. I'm planning to post the (unfinished) updated patches soon for review once I finish debugging MMCONFIG access.

I also wanted IOAPIC and more IRQs as ich9 supports 8 IRQs (IRQ A-H). Possibly I will switch from q35 to x58(ICH10) for PCIe hotplug however I don't have x58 based real machine at hand...

Signature · 1 line
yamahata
#22 lore raw

[Qemu-devel] Re: [PATCH 2/2] Route IOAPIC interrupts via ISA bus

In reply to Gerd Hoffmann
Quoted 5 lines · Gerd Hoffmann

Any hints where do dig in the registy? I have a dead notebook with xp (disk still ok), trying to boot the disk image in kvm, and of course it doesn't work due to the hardware being different. Googleing the STOP code printed on the blue screen hinted that xp fails to access the hard drive ...

Is this the info you are looking for?
http://support.microsoft.com/kb/314082

I recently went through this, using chntpw to edit the registry on the disk image and eventually getting it to boot. Also had to add the intelide.sys driver as my image lacked this for some reason.

Bjørn

author
#23 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

In reply to Gerd Hoffmann
Quoted 11 lines · Gerd Hoffmann
Quoted 6 lines · Avi Kivity
Quoted 2 lines · Gerd Hoffmann

Now we probably need some acpi magic to tell the guest OS that there are a few more IRQ lines?

I wanted to route the PCI IRQs to those lines (and have eight links instead of four).

Right now we have IRQs 5,10,11 for PCI. Having one more IRQ (so we have one for each link) would be useful IMHO. eight links + eight irqs would be even more useful. What needs to be done for that?

BTW: Seems linux doesn't use IRQ 5 even with lots of PCI devices, instead it makes them share 10+11 ...

We could change the defaults to include 5, but maybe it makes more sense to fix Linux to distribute active PCI IRQs across the resources it has at its disposal.

Quoted 5 lines
Quoted 3 lines

Now I don't think it's worthwhile, as every guest that is interesting from a performance point of view has MSI support.

Not all emulated devices have MSI support though ...

They'll be slow regardless. I should be easy to support msi on e1000 though.

Signature · 2 lines
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.
#24 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

Quoted 6 lines
Quoted 2 lines

BTW: Seems linux doesn't use IRQ 5 even with lots of PCI devices, instead it makes them share 10+11 ...

We could change the defaults to include 5, but maybe it makes more sense to fix Linux to distribute active PCI IRQs across the resources it has at its disposal.

i.e. Linux decides to stick with the defaults (starred) here ...

ACPI: PCI Interrupt Routing Table [\_SB_.PCI0._PRT]
ACPI: PCI Interrupt Link [LNKA] (IRQs 5 *10 11)
ACPI: PCI Interrupt Link [LNKB] (IRQs 5 *10 11)
ACPI: PCI Interrupt Link [LNKC] (IRQs 5 10 *11)
ACPI: PCI Interrupt Link [LNKD] (IRQs 5 10 *11)

... instead of trying to minimize IRQ sharing by using IRQ 5?

Quoted 2 lines

They'll be slow regardless. I should be easy to support msi on e1000 though.

What is needed on the guest side? Looks like even 2.6.30 doesn't use MSI for virtio-net ...

cheers,
Gerd

author
#25 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

Quoted 9 lines · Gerd Hoffmann
Quoted 6 lines
Quoted 2 lines

BTW: Seems linux doesn't use IRQ 5 even with lots of PCI devices, instead it makes them share 10+11 ...

We could change the defaults to include 5, but maybe it makes more sense to fix Linux to distribute active PCI IRQs across the resources it has at its disposal.

i.e. Linux decides to stick with the defaults (starred) here ...

Quoted 7 lines

ACPI: PCI Interrupt Routing Table [\_SB_.PCI0._PRT]
ACPI: PCI Interrupt Link [LNKA] (IRQs 5 *10 11)
ACPI: PCI Interrupt Link [LNKB] (IRQs 5 *10 11)
ACPI: PCI Interrupt Link [LNKC] (IRQs 5 10 *11)
ACPI: PCI Interrupt Link [LNKD] (IRQs 5 10 *11)

... instead of trying to minimize IRQ sharing by using IRQ 5?

Yes. And if it turns out you have two active devices and 6 inactive devices, move the two active devices to private lines and pile up the inactive ones on the leftover.

Quoted 5 lines
Quoted 3 lines

They'll be slow regardless. I should be easy to support msi on e1000 though.

What is needed on the guest side? Looks like even 2.6.30 doesn't use MSI for virtio-net ...

virtio msi support was merged in 2.6.31. For e1000, guest support is presumably there, just need to wire it into the device.

Signature · 1 line
error compiling committee.c: too many arguments to function
#26 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

Quoted 5 lines · Avi Kivity
Quoted 2 lines

What is needed on the guest side? Looks like even 2.6.30 doesn't use MSI for virtio-net ...

virtio msi support was merged in 2.6.31. For e1000, guest support is presumably there, just need to wire it into the device.

lspci shows MSI (not MSI-X) capability for the e1000 in my laptop. It is not enabled. dmesg has this line though:

0000:02:00.0: 0000:02:00.0: Failed to initialize MSI interrupts. Falling back to legacy interrupts.

so the driver at least tried to enable MSI ...

cheers
Gerd

author
#27 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

Quoted 4 lines · Gerd Hoffmann
Quoted 3 lines · Avi Kivity
Quoted 2 lines

What is needed on the guest side? Looks like even 2.6.30 doesn't use MSI for virtio-net ...

Quoted 8 lines
Quoted 2 lines

virtio msi support was merged in 2.6.31. For e1000, guest support is presumably there, just need to wire it into the device.

lspci shows MSI (not MSI-X) capability for the e1000 in my laptop. It is not enabled. dmesg has this line though:

0000:02:00.0: 0000:02:00.0: Failed to initialize MSI interrupts. Falling back to legacy interrupts.

so the driver at least tried to enable MSI ...

You probably need chipset support. I recommend drop that laptop and running exclusively in VMs.

Signature · 1 line
error compiling committee.c: too many arguments to function
#28 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

In reply to Avi Kivity
Quoted 5 lines · Avi Kivity
Quoted 4 lines · Gerd Hoffmann
Quoted 2 lines · Avi Kivity

Instead of calling the IOAPIC from the PIC, raise IOAPIC irqs via the ISA bus. As a side effect, IOAPIC lines 16-23 are enabled.

Quoted 7 lines
Quoted 2 lines

Now we probably need some acpi magic to tell the guest OS that there are a few more IRQ lines?

I wanted to route the PCI IRQs to those lines (and have eight links instead of four). Now I don't think it's worthwhile, as every guest that is interesting from a performance point of view has MSI support.

So I think we should just leave these lines as is, terminated with a 4.7K resistor to avoid picking up noise.

I was thinking of the HPET advertising one or more of these new ioapic interrupts so that it could support non-legacy operation. It can't at the moment because there are no interrupt lines available. I haven't looked into the details of what would remain to be done to make this happen, but does it sound reasonable? Sounds like at a minimum acpi needs some work.

author
#29 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

Quoted 1 line · Beth Kon

I was thinking of the HPET advertising one or more of these new ioapic interrupts so that it could support non-legacy operation. It can't at the moment because there are no interrupt lines available. I haven't looked into the details of what would remain to be done to make this happen, but does it sound reasonable? Sounds like at a minimum acpi needs some work.

What does non-legacy HPET buy us?

Signature · 2 lines
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.
#30 lore raw

Re: [Qemu-devel] [PATCH 2/2] Route IOAPIC interrupts via ISA bus

Quoted 5 lines · Avi Kivity
Quoted 1 line · Beth Kon

I was thinking of the HPET advertising one or more of these new ioapic interrupts so that it could support non-legacy operation. It can't at the moment because there are no interrupt lines available. I haven't looked into the details of what would remain to be done to make this happen, but does it sound reasonable? Sounds like at a minimum acpi needs some work.

What does non-legacy HPET buy us?

Actually, it looks like not much. I was thinking about users of /dev/hpet, but there really don't seem to be any. I found posts talking about deprecating the hpet ioctl interface due to availability of POSIX timers, so it doesn't look like anything is on the horizon. Right now, linux has no HPET requirements that aren't handled by timers 0 and 1 that are currently implemented for qemu/kvm, and as far as I can tell, Windows has no such need either.

But, to be precise, even if the HPET runs in legacy mode, the standard hardware implementation as I understand it has a third timer available that is not involved with legacy operation. Because there were no spare interrupts around, I recently submitted patches to remove that third timer (that doesn't appear to be used anywhere). When I saw the possible availability of more APIC interrupt lines, I thought about using that for at least this third timer.

The above thoughts came about after Andriy Gapon brought up some issues with available HPET interrupts. Andriy, do you have anything to add here about potential use of a third timer or non-legacy mode? Right now I'm inclined to think there isn't much use, and limiting HPET to legacy mode would be fine.