user-level: 0.884 files: 0.856 debug: 0.847 arm: 0.845 assembly: 0.841 register: 0.838 device: 0.834 semantic: 0.828 peripherals: 0.825 ppc: 0.804 permissions: 0.803 graphic: 0.791 architecture: 0.791 boot: 0.783 PID: 0.782 risc-v: 0.778 vnc: 0.772 performance: 0.749 VMM: 0.729 virtual: 0.707 hypervisor: 0.696 socket: 0.637 TCG: 0.617 mistranslation: 0.609 kernel: 0.581 KVM: 0.489 network: 0.439 x86: 0.391 i386: 0.258 -------------------- arm: 0.998 debug: 0.711 assembly: 0.703 kernel: 0.670 register: 0.105 user-level: 0.102 architecture: 0.098 PID: 0.090 semantic: 0.051 device: 0.044 hypervisor: 0.035 files: 0.035 virtual: 0.030 performance: 0.026 peripherals: 0.008 TCG: 0.007 socket: 0.005 network: 0.004 graphic: 0.002 permissions: 0.002 VMM: 0.001 boot: 0.001 vnc: 0.001 ppc: 0.001 KVM: 0.001 risc-v: 0.001 mistranslation: 0.000 x86: 0.000 i386: 0.000 arm gic: gic_acknowledge_irq doesn't clear line level for other cores for 1-n level-sensitive interrupts and gic_clear_pending uses GIC_DIST_TEST_MODEL (even on v2 where it always read 0 - "N-N") For a 1-N interrupt (any SPI on the GICv2), as mandated by the TRM, only one CPU can acknowledge the IRQ until it becomes inactive. The TRM also mandates that SGIs and PPIs follow the N-N model and that SPIs follow the 1-N model. However this is not currently the case with QEMU. I have locally (no minimal test case) seen e.g. uart interrupts being acknowledged twice before having been deactivated (expected: irqId on one CPU and 1023 on the other instead). I have narrowed the issue down to the following: 1) arm_gic_common_reset resets all irq_state[id] fields to 0. This means all IRQ will use the N-N model, and if s->revision != REV_11MPCORE, then there's no way to set any interrupt to 1-N. **If fixed locally** with a hackjob, I still have the following trace: pl011_irq_state 534130.800 pid=2424 level=0x1 gic_set_irq 2.900 pid=2424 irq=0x21 level=0x1 cpumask=0xff target=0xff gic_update_set_irq 3.300 pid=2424 cpu=0x0 name=irq level=0x1 gic_update_set_irq 4.200 pid=2424 cpu=0x1 name=irq level=0x1 gic_acknowledge_irq 539.400 pid=2424 s=cpu cpu=0x1 irq=0x21 gic_update_set_irq 269.800 pid=2424 cpu=0x0 name=irq level=0x1 gic_cpu_read 4.100 pid=2424 s=cpu cpu=0x1 addr=0xc val=0x21 gic_acknowledge_irq 15.600 pid=2424 s=cpu cpu=0x0 irq=0x21 gic_cpu_read 265.000 pid=2424 s=cpu cpu=0x0 addr=0xc val=0x21 pl011_write 1594.700 pid=2424 addr=0x44 value=0x50 pl011_irq_state 2.000 pid=2424 level=0x0 gic_set_irq 1.300 pid=2424 irq=0x21 level=0x0 cpumask=0xff target=0xff pl011_write 30.700 pid=2424 addr=0x38 value=0x0 pl011_irq_state 1.200 pid=2424 level=0x0 gic_cpu_write 110.600 pid=2424 s=cpu cpu=0x0 addr=0x10 val=0x21 gic_cpu_write 193.400 pid=2424 s=cpu cpu=0x0 addr=0x1000 val=0x21 pl011_irq_state 1169.500 pid=2424 level=0x0 This is because: 2) gic_acknowledge_irq calls gic_clear_pending which uses GIC_DIST_CLEAR_PENDING but this usually has no effect on level-sensitive interrupts. With this often being a no-op (ie. assuming ispendr was not written to), any 1-n level-sensitive interrupt is still improperly pending on all the other cores. (Also, I don't really know how the qemu thread model works, there might be race conditions in the acknowledgment logic if gic_acknowledge_irq is called by multiple threads, too.) Alex Longwall