From patchwork Mon Mar 26 12:02:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aniruddha Banerjee X-Patchwork-Id: 890923 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nvidia.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 408t851sXKz9rx7 for ; Mon, 26 Mar 2018 23:03:17 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751873AbeCZMDO (ORCPT ); Mon, 26 Mar 2018 08:03:14 -0400 Received: from hqemgate14.nvidia.com ([216.228.121.143]:15886 "EHLO hqemgate14.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751997AbeCZMDE (ORCPT ); Mon, 26 Mar 2018 08:03:04 -0400 Received: from hqpgpgate102.nvidia.com (Not Verified[216.228.121.13]) by hqemgate14.nvidia.com id ; Mon, 26 Mar 2018 05:03:03 -0700 Received: from HQMAIL104.nvidia.com ([172.20.161.6]) by hqpgpgate102.nvidia.com (PGP Universal service); Mon, 26 Mar 2018 05:02:58 -0700 X-PGP-Universal: processed; by hqpgpgate102.nvidia.com on Mon, 26 Mar 2018 05:02:58 -0700 Received: from HQMAIL112.nvidia.com (172.18.146.18) by HQMAIL104.nvidia.com (172.18.146.11) with Microsoft SMTP Server (TLS) id 15.0.1347.2; Mon, 26 Mar 2018 12:03:03 +0000 Received: from HQMAIL103.nvidia.com (172.20.187.11) by HQMAIL112.nvidia.com (172.18.146.18) with Microsoft SMTP Server (TLS) id 15.0.1347.2; Mon, 26 Mar 2018 12:03:03 +0000 Received: from hqnvemgw02.nvidia.com (172.16.227.111) by HQMAIL103.nvidia.com (172.20.187.11) with Microsoft SMTP Server id 15.0.1347.2 via Frontend Transport; Mon, 26 Mar 2018 12:03:03 +0000 Received: from aniruddha-nvidia.nvidia.com (Not Verified[10.24.53.88]) by hqnvemgw02.nvidia.com with Trustwave SEG (v7, 5, 8, 10121) id ; Mon, 26 Mar 2018 05:03:02 -0700 From: Aniruddha Banerjee To: CC: , , , , , , Aniruddha Banerjee Subject: [RESEND][RFC PATCH] irqchip: arm-gic: take gic_lock when updating irq type Date: Mon, 26 Mar 2018 17:32:51 +0530 Message-ID: <20180326120251.13054-1-aniruddhab@nvidia.com> X-Mailer: git-send-email 2.16.2 X-NVConfidentiality: public MIME-Version: 1.0 Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org The kernel documentation states that the locking of the irq-chip registers should be handled by the irq-chip driver. In the irq-gic, the accesses to the irqchip are seemingly not protected and multiple writes to SPIs from different irq descriptors do RMW requests without taking the irq-chip lock. When multiple irqs call the request_irq at the same time, there can be a simultaneous write at the gic distributor, leading to a race. Acquire the gic_lock when the irq_type is updated. Signed-off-by: Aniruddha Banerjee --- drivers/irqchip/irq-gic.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 4c797b43614d..61380f5a2254 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -67,6 +67,8 @@ static void gic_check_cpu_features(void) #define gic_check_cpu_features() do { } while(0) #endif +static DEFINE_RAW_SPINLOCK(irq_controller_lock); + union gic_base { void __iomem *common_base; void __percpu * __iomem *percpu_base; @@ -529,6 +531,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type) { void __iomem *base = gic_dist_base(d); unsigned int gicirq = gic_irq(d); + int ret; /* Interrupt configuration for SGIs can't be changed */ if (gicirq < 16) @@ -539,7 +542,11 @@ static int gic_set_type(struct irq_data *d, unsigned int type) type != IRQ_TYPE_EDGE_RISING) return -EINVAL; - return gic_configure_irq(gicirq, type, base, NULL); + raw_spin_lock(&irq_controller_lock); + ret = gic_configure_irq(gicirq, type, base, NULL); + raw_spin_unlock(&irq_controller_lock); + + return ret; } static int gic_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)