All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.