[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] 答复: report a suspect bug about arm gic
From: |
Christoffer Dall |
Subject: |
Re: [Qemu-devel] 答复: report a suspect bug about arm gic |
Date: |
Fri, 25 Apr 2014 05:49:24 -0700 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
On Wed, Apr 16, 2014 at 02:46:52AM +0000, zhuxiaodong wrote:
> I don't doubt about the algorithm of level interrupts.
> The problem may come from the level value tested by GIC_TEST_LEVEL(irq, cm).
> It is set in gic_set_irq_generic():
> > 115 static void gic_set_irq_generic(GICState *s, int irq, int level,
> > 116 int cm, int target)
> > 117 {
> > 118 if (level) {
> > 119 GIC_SET_LEVEL(irq, cm);
> > 120 DPRINTF("Set %d pending mask %x\n", irq, target);
> > 121 if (GIC_TEST_EDGE_TRIGGER(irq)) {
> > 122 GIC_SET_PENDING(irq, target);
> > 123 }
> > 124 } else {
> > 125 GIC_CLEAR_LEVEL(irq, cm);
> > 126 }
> > 127 }
> At line 119 we can see that it is always set to cm.
Actually the bits of the cm is or'ed onto the level bitmask.
>
> And gic_set_irq_generic is called by gic_set_irq (void *opaque, int irq, int
> level):
> 132 static void gic_set_irq(void *opaque, int irq, int level)
> 133 {
> 134 /* Meaning of the 'irq' parameter:
> 135 * [0..N-1] : external interrupts
> 136 * [N..N+31] : PPI (internal) interrupts for CPU 0
> 137 * [N+32..N+63] : PPI (internal interrupts for CPU 1
> 138 * ...
> 139 */
> 140 GICState *s = (GICState *)opaque;
> 141 int cm, target;
> 142 if (irq < (s->num_irq - GIC_INTERNAL)) {
> 143 /* The first external input line is internal interrupt 32. */
> 144 cm = ALL_CPU_MASK;
> 145 irq += GIC_INTERNAL;
> 146 target = GIC_TARGET(irq);
> At line 144 we can see that cm is always set to ALL_CPU_MASK if irq is a SPI.
> That means GIC_TEST_LEVEL can success for any cpu!
>
> So when GIC_TEST_LEVEL(irq,cm) is invoked by gic_update, at the first loop
> for cpu 0, the irq will be choosen ahead of time even if cpu 0 is not the
> target cpu.
>
> Please consider about this case.
I think what you're trying to say is that gic_set_irq_...() does not
respect settings in the GICD_ITARGETSR (which is what GIC_TARGET(irq)
checks for). In fact I don't think it should, but we should check the
GICD_ITARGETSR value in gic_update to comply with the architecture
specification that states that changes to GICD_ITARGETSR have an effect
on pending interrupts (but not on active, or on active and pending
interrupts until the status is cleared on the latter).
I haven't checked the 11mpcore or the nvic docs yet on how the behavior
should be for those.
-Christoffer