Message ID | 1414707132-24588-13-git-send-email-greg.bellows@linaro.org |
---|---|
State | New |
Headers | show |
On 30 October 2014 at 22:12, Greg Bellows <greg.bellows@linaro.org> wrote: > From: Fabian Aggeler <aggelerf@ethz.ch> > > Grouping (GICv2) and Security Extensions change the behavior of EOIR > writes. Completing Group0 interrupts is only allowed from Secure state > and completing Group1 interrupts from Secure state is only allowed if > AckCtl bit is set. > > Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch> > > --- > > v1 -> v2 > - Fix issue with EOIR writes involving AckCtl. AckCtl is ignored on EOIR > group 1 interrupts when non-secure. Group 1 interrupts are only ignored when > secure and AckCTl is clear. > --- > hw/intc/arm_gic.c | 15 +++++++++++++++ > 1 file changed, 15 insertions(+) > > diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c > index 15fd660..2d83225 100644 > --- a/hw/intc/arm_gic.c > +++ b/hw/intc/arm_gic.c > @@ -384,6 +384,21 @@ void gic_complete_irq(GICState *s, int cpu, int irq) > GIC_SET_PENDING(irq, cm); > update = 1; > } > + } else if ((s->revision >= 2 && !s->security_extn) > + || (s->security_extn && !ns_access())) { > + /* Handle GICv2 without Security Extensions or GIC with Security > + * Extensions and a secure write. > + */ > + if (!GIC_TEST_GROUP0(irq, cm) && !ns_access() > + && !(s->cpu_control[cpu][0] & GICC_CTLR_S_ACK_CTL)) { > + /* Unpredictable. We choose to ignore. */ > + DPRINTF("EOI for Group1 interrupt %d ignored " > + "(AckCtl disabled)\n", irq); > + return; > + } For GICv2 without the security extns, EOIR accesses should behave as if they were secure, so the call to ns_access() inside this conditional is wrong. We probably need to disentangle the v1-vs-v2 differences here. > + } else if (s->security_extn && ns_access() && GIC_TEST_GROUP0(irq, cm)) { > + DPRINTF("Non-secure EOI for Group0 interrupt %d ignored\n", irq); > + return; > } -- PMM
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 15fd660..2d83225 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -384,6 +384,21 @@ void gic_complete_irq(GICState *s, int cpu, int irq) GIC_SET_PENDING(irq, cm); update = 1; } + } else if ((s->revision >= 2 && !s->security_extn) + || (s->security_extn && !ns_access())) { + /* Handle GICv2 without Security Extensions or GIC with Security + * Extensions and a secure write. + */ + if (!GIC_TEST_GROUP0(irq, cm) && !ns_access() + && !(s->cpu_control[cpu][0] & GICC_CTLR_S_ACK_CTL)) { + /* Unpredictable. We choose to ignore. */ + DPRINTF("EOI for Group1 interrupt %d ignored " + "(AckCtl disabled)\n", irq); + return; + } + } else if (s->security_extn && ns_access() && GIC_TEST_GROUP0(irq, cm)) { + DPRINTF("Non-secure EOI for Group0 interrupt %d ignored\n", irq); + return; } if (irq != s->running_irq[cpu]) {