diff mbox

hw/intc/arm_gic: Fix GIC_SET_LEVEL

Message ID 1393031030-8692-1-git-send-email-christoffer.dall@linaro.org
State Superseded
Headers show

Commit Message

Christoffer Dall Feb. 22, 2014, 1:03 a.m. UTC
The GIC_SET_LEVEL macro unfortunately overwrote the entire level
bitmask instead of just or'ing on the necessary bits, causing active
level PPIs on a core to clear PPIs on other cores.

I introduced this bug, sorry about that.

Reported-by: Rob Herring <rob.herring@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
---
 hw/intc/gic_internal.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Christoffer Dall Feb. 23, 2014, 4:32 p.m. UTC | #1
On 21 February 2014 17:03, Christoffer Dall <christoffer.dall@linaro.org> wrote:
> The GIC_SET_LEVEL macro unfortunately overwrote the entire level
> bitmask instead of just or'ing on the necessary bits, causing active
> level PPIs on a core to clear PPIs on other cores.
>
> I introduced this bug, sorry about that.
>
Actually it turns out this was ancient, I was a little too quick to
blame myself there.

-Christoffer
Peter Maydell Feb. 24, 2014, 3:36 p.m. UTC | #2
On 23 February 2014 16:32, Christoffer Dall <christoffer.dall@linaro.org> wrote:
> On 21 February 2014 17:03, Christoffer Dall <christoffer.dall@linaro.org> wrote:
>> The GIC_SET_LEVEL macro unfortunately overwrote the entire level
>> bitmask instead of just or'ing on the necessary bits, causing active
>> level PPIs on a core to clear PPIs on other cores.
>>
>> I introduced this bug, sorry about that.
>>
> Actually it turns out this was ancient, I was a little too quick to
> blame myself there.

Yes, it's been present since 2007 or so. Probably not noticed
at that time because all the 11MPcore PPIs are edge rather than
level triggered.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

I'll remove the line about it being your fault when I apply
this to target-arm.next :-)

thanks
-- PMM
diff mbox

Patch

diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h
index 92a6f7a..48a58d7 100644
--- a/hw/intc/gic_internal.h
+++ b/hw/intc/gic_internal.h
@@ -40,7 +40,7 @@ 
 #define GIC_SET_MODEL(irq) s->irq_state[irq].model = true
 #define GIC_CLEAR_MODEL(irq) s->irq_state[irq].model = false
 #define GIC_TEST_MODEL(irq) s->irq_state[irq].model
-#define GIC_SET_LEVEL(irq, cm) s->irq_state[irq].level = (cm)
+#define GIC_SET_LEVEL(irq, cm) s->irq_state[irq].level |= (cm)
 #define GIC_CLEAR_LEVEL(irq, cm) s->irq_state[irq].level &= ~(cm)
 #define GIC_TEST_LEVEL(irq, cm) ((s->irq_state[irq].level & (cm)) != 0)
 #define GIC_SET_EDGE_TRIGGER(irq) s->irq_state[irq].edge_trigger = true