linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: wuyun.wu@huawei.com (Abel)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v4 02/20] arm64: initial support for GICv3
Date: Mon, 9 Jun 2014 12:10:30 +0800	[thread overview]
Message-ID: <539533B6.201@huawei.com> (raw)
In-Reply-To: <87zjhrvj8g.fsf@approximate.cambridge.arm.com>

On 2014/6/5 16:44, Marc Zyngier wrote:

> Hi Abel,
> 
> On Thu, Jun 05 2014 at  8:47:49 am BST, Abel <wuyun.wu@huawei.com> wrote:
>> Hi Marc,
>>
>> On 2014/5/16 1:58, Marc Zyngier wrote:
>>
>>> The Generic Interrupt Controller (version 3) offers services that are
>>> similar to GICv2, with a number of additional features:
>>> - Affinity routing based on the CPU MPIDR (ARE)
>>> - System register for the CPU interfaces (SRE)
>>> - Support for more that 8 CPUs
>>> - Locality-specific Peripheral Interrupts (LPIs)
>>> - Interrupt Translation Services (ITS)
>>>
>>> This patch adds preliminary support for GICv3 with ARE and SRE,
>>> non-secure mode only. It relies on higher exception levels to grant ARE
>>> and SRE access.
>>>
>>> Support for LPI and ITS will be added at a later time.
>>>
>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>> Reviewed-by: Zi Shen Lim <zlim@broadcom.com>
>>> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
>>> Acked-by: Catalin Marinas <catalin.marinas@arm.com>
>>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>>> ---
>>>  arch/arm64/Kconfig                 |   1 +
>>>  arch/arm64/kernel/head.S           |  18 +
>>>  arch/arm64/kernel/hyp-stub.S       |   1 +
>>>  drivers/irqchip/Kconfig            |   5 +
>>>  drivers/irqchip/Makefile           |   1 +
>>>  drivers/irqchip/irq-gic-v3.c       | 684 +++++++++++++++++++++++++++++++++++++
>>>  include/linux/irqchip/arm-gic-v3.h | 190 +++++++++++
>>>  7 files changed, 900 insertions(+)
>>>  create mode 100644 drivers/irqchip/irq-gic-v3.c
>>>  create mode 100644 include/linux/irqchip/arm-gic-v3.h
>>>
[...]
>>> +static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
>>> +{
>>> +     u64 irqnr;
>>> +
>>> +     do {
>>> +             irqnr = gic_read_iar();
>>> +
>>> +             if (likely(irqnr > 15 && irqnr < 1021)) {
>>
>>
>> I prefer to use gic_data.irq_nr instead of '1021'.
>> The ranges here should be consistent with the ones in domain.map.
> 
> That's debatable. gic_data.irq_nr is used as a guard for the rest of the
> kernel, so that we don't map an out-of-range interrupt number. But here,
> we read the interrupt that has been generated by the actual HW. If such
> thing happen, we need to know about it, handle it as a spurious
> interrupt, and EOI it. Otherwise, we're stuck forever (with your
> proposed change, nothing EOIs the interrupt).


I don't think it's necessary to EOI the spurious interrupts, since EOIing
a spurious interrupt won't cause any effect.
As for the interrupts here, the ones entered into this 'if' clause, I think
they are expected already been mapped into this irq_domain.

> 
>>> +                     irqnr = irq_find_mapping(gic_data.domain, irqnr);
>>> +                     handle_IRQ(irqnr, regs);
>>> +                     continue;
>>> +             }
>>> +             if (irqnr < 16) {
>>> +                     gic_write_eoir(irqnr);
>>> +#ifdef CONFIG_SMP
>>> +                     handle_IPI(irqnr, regs);
>>> +#else
>>> +                     WARN_ONCE(true, "Unexpected SGI received!\n");
>>> +#endif
>>> +                     continue;
>>> +             }
>>> +     } while (irqnr != 0x3ff);
>>> +}
>>> +
>>> +static void __init gic_dist_init(void)
>>> +{
>>> +     unsigned int i;
>>> +     u64 affinity;
>>> +     void __iomem *base = gic_data.dist_base;
>>> +
>>> +     /* Disable the distributor */
>>> +     writel_relaxed(0, base + GICD_CTLR);
>>
>>
>> I'm not sure whether waiting for write pending here is necessary. What do you think?
> 
> Hmmm. That's a good point. The spec says the RWP tracks the completion
> of writes that change (among other things) the state of an interrupt
> group enable. But the next line will perform a wait_for_rwp anyway after
> having disabled all SPIs. So no, I don't think we need to wait. We
> guaranteed to get a consistent state after the call to gic_dist_config.


The spec also says that software must ensure the interrupt is disabled before
changing its routing/priority/group information, see chapter 4.5.5 in v18.

> 
>>> +
>>> +     gic_dist_config(base, gic_data.irq_nr, gic_dist_wait_for_rwp);
>>> +
>>> +     /* Enable distributor with ARE, Group1 */
>>> +     writel_relaxed(GICD_CTLR_ARE_NS | GICD_CTLR_ENABLE_G1A | GICD_CTLR_ENABLE_G1,
>>> +                    base + GICD_CTLR);
>>> +
>>> +     /*
>>> +      * Set all global interrupts to the boot CPU only. ARE must be
>>> +      * enabled.
>>> +      */
>>> +     affinity = gic_mpidr_to_affinity(cpu_logical_map(smp_processor_id()));
>>> +     for (i = 32; i < gic_data.irq_nr; i++)
>>> +             writeq_relaxed(affinity, base + GICD_IROUTER + i * 8);
>>> +}
>>> +
> 
> [...]
> 
>>> +static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
>>> +                           irq_hw_number_t hw)
>>> +{
>>> +     /* SGIs are private to the core kernel */
>>> +     if (hw < 16)
>>> +             return -EPERM;
>>> +     /* PPIs */
>>> +     if (hw < 32) {
>>> +             irq_set_percpu_devid(irq);
>>> +             irq_set_chip_and_handler(irq, &gic_chip,
>>> +                                      handle_percpu_devid_irq);
>>> +             set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
>>> +     }
>>> +     /* SPIs */
>>> +     if (hw >= 32 && hw < gic_data.irq_nr) {
>>> +             irq_set_chip_and_handler(irq, &gic_chip,
>>> +                                      handle_fasteoi_irq);
>>> +             set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
>>> +     }
>>
>>
>> Use 'else' here, since the conditions are non-overlapping.
> 
> For the code as it is now, I'd agree. But I'm also looking at the ITS
> code that will follow as soon as this one is on its way to mainline, and
> I then have this:
> 
> @@ -553,6 +571,19 @@ static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
>                                          handle_fasteoi_irq);
>                 set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
>         }
> +       /* Nothing */
> +       if (hw >= gic_data.irq_nr && hw < 8192)
> +               return -EPERM;
> +       /* LPIs */
> +       if (hw >= 8192 && hw < GIC_ID_NR) {
> +               if (!its_chip)
> +                       return -EPERM;
> +               irq_set_chip_and_handler(irq, its_chip, handle_fasteoi_irq);
> +               set_irq_flags(irq, IRQF_VALID);
> +       }
> +       /* Off limits */
> +       if (hw >= GIC_ID_NR)
> +               return -EPERM;
>         irq_set_chip_data(irq, d->host_data);
>         return 0;
>  }
> 
> Having a bunch of else clauses looks pretty awful in this context, and
> I've decided to try and keep it readable instead. This is not on the hot
> path anyway, so it doesn't really matter if we test an extra variable.

OK, it makes sense.

Regards,
Abel.

  reply	other threads:[~2014-06-09  4:10 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-05-15 17:58 [PATCH v4 00/20] arm64: GICv3 support Marc Zyngier
2014-05-15 17:58 ` [PATCH v4 01/20] ARM: GIC: move some bits of GICv2 to a library-type file Marc Zyngier
2014-05-15 17:58 ` [PATCH v4 02/20] arm64: initial support for GICv3 Marc Zyngier
2014-05-23 16:40   ` Jean-Philippe Brucker
2014-05-27  8:17     ` Marc Zyngier
2014-06-05  7:47   ` Abel
2014-06-05  8:44     ` Marc Zyngier
2014-06-09  4:10       ` Abel [this message]
2014-06-09  8:41         ` Marc Zyngier
2014-06-10  3:57           ` Abel
2014-06-10 10:43             ` Marc Zyngier
2014-06-11  1:15               ` Abel
2014-05-15 17:58 ` [PATCH v4 03/20] arm64: GICv3 device tree binding documentation Marc Zyngier
2014-05-20 14:58   ` Andre Przywara
2014-05-20 15:32     ` Marc Zyngier
2014-05-20 16:21       ` Andre Przywara
2014-05-15 17:58 ` [PATCH v4 04/20] arm64: boot protocol documentation update for GICv3 Marc Zyngier
2014-05-15 17:58 ` [PATCH v4 05/20] KVM: arm/arm64: vgic: move GICv2 registers to their own structure Marc Zyngier
2014-05-15 17:58 ` [PATCH v4 06/20] KVM: ARM: vgic: introduce vgic_ops and LR manipulation primitives Marc Zyngier
2014-05-20 12:33   ` Christoffer Dall
2014-05-15 17:58 ` [PATCH v4 07/20] KVM: ARM: vgic: abstract access to the ELRSR bitmap Marc Zyngier
2014-05-20 12:35   ` Christoffer Dall
2014-05-15 17:58 ` [PATCH v4 08/20] KVM: ARM: vgic: abstract EISR bitmap access Marc Zyngier
2014-05-15 17:58 ` [PATCH v4 09/20] KVM: ARM: vgic: abstract MISR decoding Marc Zyngier
2014-05-15 17:58 ` [PATCH v4 10/20] KVM: ARM: vgic: move underflow handling to vgic_ops Marc Zyngier
2014-05-15 17:58 ` [PATCH v4 11/20] KVM: ARM: vgic: abstract VMCR access Marc Zyngier
2014-05-20 12:41   ` Christoffer Dall
2014-05-15 17:58 ` [PATCH v4 12/20] KVM: ARM: vgic: introduce vgic_enable Marc Zyngier
2014-05-15 17:58 ` [PATCH v4 13/20] KVM: ARM: introduce vgic_params structure Marc Zyngier
2014-05-15 17:58 ` [PATCH v4 14/20] KVM: ARM: vgic: split GICv2 backend from the main vgic code Marc Zyngier
2014-05-15 17:58 ` [PATCH v4 15/20] KVM: ARM: vgic: revisit implementation of irqchip_in_kernel Marc Zyngier
2014-05-20 12:50   ` Christoffer Dall
2014-05-15 17:58 ` [PATCH v4 16/20] arm64: KVM: remove __kvm_hyp_code_{start, end} from hyp.S Marc Zyngier
2014-05-15 17:58 ` [PATCH v4 17/20] arm64: KVM: split GICv2 world switch from hyp code Marc Zyngier
2014-05-20 12:53   ` Christoffer Dall
2014-05-15 17:58 ` [PATCH v4 18/20] arm64: KVM: move HCR_EL2.{IMO, FMO} manipulation into the vgic switch code Marc Zyngier
2014-05-20 12:58   ` Christoffer Dall
2014-05-15 17:58 ` [PATCH v4 19/20] KVM: ARM: vgic: add the GICv3 backend Marc Zyngier
2014-05-20 13:09   ` Christoffer Dall
2014-05-20 13:29     ` Marc Zyngier
2014-05-15 17:58 ` [PATCH v4 20/20] arm64: KVM: vgic: add GICv3 world switch Marc Zyngier
2014-05-28 19:11   ` Will Deacon
2014-06-02 15:09     ` Marc Zyngier
2014-05-30 23:06 ` [PATCH v4 00/20] arm64: GICv3 support Radha Mohan
2014-05-31  1:14   ` Chalamarla, Tirumalesh
2014-06-02 12:59     ` Marc Zyngier
2014-06-02 12:57   ` Marc Zyngier
2014-06-11  1:49 ` Abel
2014-06-11  2:58   ` Abel
     [not found] <CALicx6vz6JZsMDmEVUMarsTd67xK1r+HjVTD0Jg94U6LD9bk3w@mail.gmail.com>
2014-06-11 16:16 ` [PATCH v4 02/20] arm64: initial support for GICv3 Marc Zyngier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=539533B6.201@huawei.com \
    --to=wuyun.wu@huawei.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).