> Am 03.07.2014 um 00:02 schrieb "Gabriel L. Somlo" <gso...@gmail.com>: > >> On Wed, Jul 02, 2014 at 05:14:26PM -0400, Gabriel L. Somlo wrote: >>> On Wed, Jul 02, 2014 at 11:02:30PM +0200, Alexander Graf wrote: >>> >>>> On 02.07.14 22:49, Gabriel L. Somlo wrote: >>>> So it turns out everything I thought I knew (which was little indeed) >>>> was more or less wrong. The problem, as far as I'm observing it now, >>>> is that on PIIX, the OS X guest obsessively reads the ICR in a tight >>>> loop. It reads the injected LSC (and probably discards it) before >>>> unmasking the corresponding interrupt bit; later on, when it unmasks >>>> LSC, giving the emulated e1000 hardware a chance to raise the irq >>>> line, the actual LSC event has been flushed from the ICR, and the >>>> driver does not detect the link coming up. >>>> >>>> [...] >>>> >>>> Any clue as to why ICR gets read like that on PIIX, but not Q35 ? >>> >>> Either way, why does the bit get cleared even though it hasn't been raised? >>> What does real hardware do with interrupts that have been masked? >> >> The e1000 manual says ICR bits are cleared on read. It also says PCI >> interrupts are only generated if the corresponding bit in *both* ICR >> and IMS registers is 1. ICR bits are still cleared if read, even if >> masked and no actual interrupt is raised. >> >>> Maybe it's using MSI on q35? :) >>> Maybe we also share the same IRQ line with another device on PIIX that gets >>> polled all the time? IDE maybe? >> >> Even if that were the case, how come it's reading precisely our >> device's ICR register ? Isn't that too much of a coincidence ? > > Unless some other device on a shared IRQ line generated the interrupt, > and our e1000 driver then checked ICR. Although if that happened, our > driver should happily acknowledge the link-up event (I checked, and it > does NOT read IMS, so it has no way of knowing it's masked). Except it > does -- it knows the last thing it did was set_imc(0xFFFFFFFF), and > that it hasn't yet set_ims(anything) yet... > > And I think you're right: > > (qemu) info pci > Bus 0, device 0, function 0: > Host bridge: PCI device 8086:1237 > id "" > Bus 0, device 1, function 0: > ISA bridge: PCI device 8086:7000 > id "" > Bus 0, device 1, function 1: > IDE controller: PCI device 8086:7010 > BAR4: I/O at 0xc080 [0xc08f]. > id "" > Bus 0, device 1, function 2: > USB controller: PCI device 8086:7020 > IRQ 11. > BAR4: I/O at 0xc040 [0xc05f]. > id "" > Bus 0, device 1, function 3: > Bridge: PCI device 8086:7113 > IRQ 9. > id "" > Bus 0, device 2, function 0: > VGA controller: PCI device 1013:00b8 > BAR0: 32 bit prefetchable memory at 0xfc000000 [0xfdffffff]. > BAR1: 32 bit memory at 0xfebf0000 [0xfebf0fff]. > BAR6: 32 bit memory at 0xffffffffffffffff [0x0000fffe]. > id "" > Bus 0, device 3, function 0: > SATA controller: PCI device 8086:2922 > IRQ 11. > BAR4: I/O at 0xc060 [0xc07f]. > BAR5: 32 bit memory at 0xfebf1000 [0xfebf1fff]. > id "ide" > Bus 0, device 4, function 0: > Ethernet controller: PCI device 8086:100f > IRQ 11. > BAR0: 32 bit memory at 0xfebc0000 [0xfebdffff]. > BAR1: I/O at 0xffffffffffffffff [0x003e]. > BAR6: 32 bit memory at 0xffffffffffffffff [0x0003fffe]. > id "vnet0" > > so Ethernet, SATA, and USB, all sharing IRQ 11. Is there an easy way > to force one of those to use a different IRQ ?
IIRC if you plug the device in a different slot, the irq distribution should be different :). Alex > >