From patchwork Mon Jan 6 05:09:04 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vaibhav Hiremath X-Patchwork-Id: 3435401 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 1FE0D9F163 for ; Mon, 6 Jan 2014 05:10:13 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 329F72017B for ; Mon, 6 Jan 2014 05:10:12 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 27AC42016C for ; Mon, 6 Jan 2014 05:10:11 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1W02Rf-0000Fz-Dw; Mon, 06 Jan 2014 05:09:47 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1W02Rd-0007yO-1r; Mon, 06 Jan 2014 05:09:45 +0000 Received: from arroyo.ext.ti.com ([192.94.94.40]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1W02RV-0007xu-KK for linux-arm-kernel@lists.infradead.org; Mon, 06 Jan 2014 05:09:43 +0000 Received: from dbdlxv05.itg.ti.com ([172.24.171.60]) by arroyo.ext.ti.com (8.13.7/8.13.7) with ESMTP id s06597Ek023616; Sun, 5 Jan 2014 23:09:08 -0600 Received: from DBDE72.ent.ti.com (dbdmailx.itg.ti.com [172.24.171.97]) by dbdlxv05.itg.ti.com (8.14.3/8.13.8) with ESMTP id s065948V016615; Mon, 6 Jan 2014 10:39:05 +0530 Received: from DBDE04.ent.ti.com ([fe80::21ac:d9f:f810:c8e7]) by DBDE72.ent.ti.com ([fe80::bd56:32bf:87fd:2763%27]) with mapi id 14.02.0342.003; Mon, 6 Jan 2014 13:09:04 +0800 From: "Hiremath, Vaibhav" To: "linux-arm-kernel@lists.infradead.org" Subject: [RFC] drivers: irq-chip: Enable SGI's for Secure-to-NonSecure communication use-cases Thread-Topic: [RFC] drivers: irq-chip: Enable SGI's for Secure-to-NonSecure communication use-cases Thread-Index: Ac8KnWnBwzBqWIrWRFWojxy1Uq9BMg== Date: Mon, 6 Jan 2014 05:09:04 +0000 Message-ID: <79CD15C6BA57404B839C016229A409A83EDAD1B8@DBDE04.ent.ti.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [172.24.170.142] MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140106_000942_280783_F2E048E3 X-CRM114-Status: GOOD ( 17.91 ) X-Spam-Score: -7.0 (-------) Cc: Tony Lindgren , "linux-omap@vger.kernel.org" , Russell King X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Hi, Currently the Software Generated Interrupts (SGI) are restricted to use only for SMP architecture for inter-processor communication as rightly documented in ARM GIC spec V1. In the system with the uniprocessor (and/or multiprocessor variants) architecture with TRUSTZONE enabled device (like, AM43xx device), the SGI can be used for communication between secure-to-nonsecure world. And in order to enable SGI event from secure world to non-secure world, GIC driver __must__ support registration of interrupt service routines for SGI's; which is currently restricted by GIC driver. The usecase is something like, On any asynchronous HW or SW events, certain secure functionality gets triggered and SGI will be used to notify to the public world on the completion and/or result of operation. Non Secure | Secure (TrustZone) (Linux Booted | (Secure software init happed To prompt) | and trusted code getting executed) | (On any secure operation Where we would like public world communication) | | - Use SGI to trigger event to public Linux code | - And share the public info/data with public world for further processing <===== Public code | handles it | In order to prototype and to make sure that it works, I did change the GIC driver to allow registration of SGI interrupts (interrupts 0 - 16) and tried it on AM43xx EVM and pasted the diff of the changes below. I have also validated using SGI for secure to non-secure communication. The idea behind this RFC (or rather query) is, to get feedback or comments on the use-case of using SGI for secure-to-nonsecure communication on non-SMP architecture or SMP architecture with uniprocessor. I understand that, lot of things I need to take care from SMP architecture perspective. Based on the feedback I can spend more time to make below changes more generic to handle both uniprocessor and multi-processor architectures including more validation. Also, please note that, this requires change in all the DT files using GIC interrupt controller. Any pointers and suggestions are welcome here. Thanks, Vaibhav - hwirq_base = 16; + hwirq_base = 0; if (irq_start != -1) irq_start = (irq_start & ~31) + 16; } else { - hwirq_base = 32; + hwirq_base = 0; } /* @@ -803,7 +798,7 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, gic->gic_irqs = gic_irqs; gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */ - irq_base = irq_alloc_descs(irq_start, 16, gic_irqs, numa_node_id()); + irq_base = irq_alloc_descs(irq_start, 0, gic_irqs, numa_node_id()); if (IS_ERR_VALUE(irq_base)) { WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n", irq_start); diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index d0e9480..135385a 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -290,7 +290,7 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK); irqnr = irqstat & ~0x1c00; - if (likely(irqnr > 15 && irqnr < 1021)) { + if (likely(irqnr >= 0 && irqnr < 1021)) { irqnr = irq_find_mapping(gic->domain, irqnr); handle_IRQ(irqnr, regs); continue; @@ -324,7 +324,7 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) goto out; cascade_irq = irq_find_mapping(chip_data->domain, gic_irq); - if (unlikely(gic_irq < 32 || gic_irq > 1020)) + if (unlikely(gic_irq > 1020)) handle_bad_irq(cascade_irq, desc); else generic_handle_irq(cascade_irq); @@ -395,20 +395,20 @@ static void __init gic_dist_init(struct gic_chip_data *gic) cpumask = gic_get_cpumask(gic); cpumask |= cpumask << 8; cpumask |= cpumask << 16; - for (i = 32; i < gic_irqs; i += 4) + for (i = 0; i < gic_irqs; i += 4) writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); /* * Set priority on all global interrupts. */ - for (i = 32; i < gic_irqs; i += 4) + for (i = 0; i < gic_irqs; i += 4) writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); /* * Disable all interrupts. Leave the PPI and SGIs alone * as these enables are banked registers. */ - for (i = 32; i < gic_irqs; i += 32) + for (i = 0; i < gic_irqs; i += 32) writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); writel_relaxed(1, base + GIC_DIST_CTRL); @@ -672,7 +672,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) { - if (hw < 32) { + if (hw < 0) { irq_set_percpu_devid(irq); irq_set_chip_and_handler(irq, &gic_chip, handle_percpu_devid_irq); @@ -696,8 +696,11 @@ static int gic_irq_domain_xlate(struct irq_domain *d, if (intsize < 3) return -EINVAL; - /* Get the interrupt number and add 16 to skip over SGIs */ - *out_hwirq = intspec[1] + 16; - - /* For SPIs, we need to add 16 more to get the GIC irq ID number */ - if (!intspec[0]) - *out_hwirq += 16; - + *out_hwirq = intspec[1]; *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; return 0; } @@ -785,11 +780,11 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, * For secondary GICs, skip over PPIs, too. */ if (gic_nr == 0 && (irq_start & 31) > 0) {