Received: by 2002:a05:6a10:a0d1:0:0:0:0 with SMTP id j17csp32325pxa; Mon, 10 Aug 2020 17:44:57 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxMF/RLo5sDVn0rGmFfozPKkOuNZOoMjLgQP7p67r07TKLSM6hzM5QJ3VjAezAhVqi0OtPl X-Received: by 2002:aa7:d899:: with SMTP id u25mr22734320edq.255.1597106697514; Mon, 10 Aug 2020 17:44:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1597106697; cv=none; d=google.com; s=arc-20160816; b=gMITwKH68YpJ7LYrcA8Ue44rIcd6nHKvhdMh5Ysw3+ICVrBiFaDaDpZf+R6hOXwy8c Dq6BDISVLXS9AgddfRgxnoAW8OsVVOCMTjicLhfnoiR6FwUcAlT6+OGPQgReI3JJ7Rgm qhxGMgXS+KhD/RNwJ9oswfPng3YfUqvQb0dXItyxsnWttuK99KztoYCSwRKTT5TLR9mU lAz9kx6C7EUFwcW5srxEGC5DScWmPw/cLGlq+aIqun5NbLu1smm04wj2xq6C0VuuJUJz 5OrRt7WRUrWMaG4GT8ZGknSrdCBrqwoPbBI9+Zvjj8XFWo8nW69oup5xqKmkGw1D/Tap 4omw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature:dkim-filter; bh=AQjpSH/RpqiCpjXXY1Utw/bEGAAvb9t61EHpqwYleBU=; b=wIt66hMoTaC3KQ2m13f+RZB1GqIHTPSA86+ARtGDRbeoHeIG+1BROp6NoYYDb/qhEL bg8KTvMKPqxy2odNJEPBzBeuNi40fnaRX7tHO8Ddu5UIWv5F8CzXMeP0o1gZBgiqNQF+ rWsxQcfwuIOqBYocMKhRBIZUh5tw7ZmRv8IZMupReUUYVxoy9mgZrn1HAkFfAfNmgJYb /TStY6iSVywgXdKY09GoKMknOcF8ga86gBjGJnxN1M9EaIQp+Zhij5+b+CMkJAb7UngM B1UMsmqkyyqQ1Z8oQUZET2RxqsWnJFMLf7n5EHJQsx36s4McYVW/bypT3oJCKCxzDnde SQQQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.microsoft.com header.s=default header.b="plhDb8/J"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.microsoft.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id ly17si11313447ejb.25.2020.08.10.17.44.34; Mon, 10 Aug 2020 17:44:57 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.microsoft.com header.s=default header.b="plhDb8/J"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.microsoft.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727116AbgHKAnh (ORCPT + 99 others); Mon, 10 Aug 2020 20:43:37 -0400 Received: from linux.microsoft.com ([13.77.154.182]:53224 "EHLO linux.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727014AbgHKAng (ORCPT ); Mon, 10 Aug 2020 20:43:36 -0400 Received: by linux.microsoft.com (Postfix, from userid 1046) id C51CF20B4908; Mon, 10 Aug 2020 17:43:35 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com C51CF20B4908 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1597106615; bh=AQjpSH/RpqiCpjXXY1Utw/bEGAAvb9t61EHpqwYleBU=; h=From:To:Cc:Subject:Date:From; b=plhDb8/JF858TD3uKcs7VBBnRzGP2DCluApdoJ+H3M8SkhnM7vbfZ5f/hiS5ceisf 0TL6K1gZ6HH1AKZDvuQkO5zYZhcy8b9Ogv8qdWTZJBhP0qhG0i86/x2SC+wAd8IgWK 0O051Ve2FVaIN8JfYc0Pl60wBz0wovLcq4iTlKqQ= From: Dhananjay Phadke To: linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org, Wolfram Sang , Ray Jui Cc: Rayagonda Kokatanur , bcm-kernel-feedback-list@broadcom.com, Dhananjay Phadke Subject: [PATCH v3] i2c: iproc: fix race between client unreg and isr Date: Mon, 10 Aug 2020 17:42:40 -0700 Message-Id: <1597106560-79693-1-git-send-email-dphadke@linux.microsoft.com> X-Mailer: git-send-email 1.8.3.1 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When i2c client unregisters, synchronize irq before setting iproc_i2c->slave to NULL. (1) disable_irq() (2) Mask event enable bits in control reg (3) Erase slave address (avoid further writes to rx fifo) (4) Flush tx and rx FIFOs (5) Clear pending event (interrupt) bits in status reg (6) enable_irq() (7) Set client pointer to NULL Unable to handle kernel NULL pointer dereference at virtual address 0000000000000318 [ 371.020421] pc : bcm_iproc_i2c_isr+0x530/0x11f0 [ 371.025098] lr : __handle_irq_event_percpu+0x6c/0x170 [ 371.030309] sp : ffff800010003e40 [ 371.033727] x29: ffff800010003e40 x28: 0000000000000060 [ 371.039206] x27: ffff800010ca9de0 x26: ffff800010f895df [ 371.044686] x25: ffff800010f18888 x24: ffff0008f7ff3600 [ 371.050165] x23: 0000000000000003 x22: 0000000001600000 [ 371.055645] x21: ffff800010f18888 x20: 0000000001600000 [ 371.061124] x19: ffff0008f726f080 x18: 0000000000000000 [ 371.066603] x17: 0000000000000000 x16: 0000000000000000 [ 371.072082] x15: 0000000000000000 x14: 0000000000000000 [ 371.077561] x13: 0000000000000000 x12: 0000000000000001 [ 371.083040] x11: 0000000000000000 x10: 0000000000000040 [ 371.088519] x9 : ffff800010f317c8 x8 : ffff800010f317c0 [ 371.093999] x7 : ffff0008f805b3b0 x6 : 0000000000000000 [ 371.099478] x5 : ffff0008f7ff36a4 x4 : ffff8008ee43d000 [ 371.104957] x3 : 0000000000000000 x2 : ffff8000107d64c0 [ 371.110436] x1 : 00000000c00000af x0 : 0000000000000000 [ 371.115916] Call trace: [ 371.118439] bcm_iproc_i2c_isr+0x530/0x11f0 [ 371.122754] __handle_irq_event_percpu+0x6c/0x170 [ 371.127606] handle_irq_event_percpu+0x34/0x88 [ 371.132189] handle_irq_event+0x40/0x120 [ 371.136234] handle_fasteoi_irq+0xcc/0x1a0 [ 371.140459] generic_handle_irq+0x24/0x38 [ 371.144594] __handle_domain_irq+0x60/0xb8 [ 371.148820] gic_handle_irq+0xc0/0x158 [ 371.152687] el1_irq+0xb8/0x140 [ 371.155927] arch_cpu_idle+0x10/0x18 [ 371.159615] do_idle+0x204/0x290 [ 371.162943] cpu_startup_entry+0x24/0x60 [ 371.166990] rest_init+0xb0/0xbc [ 371.170322] arch_call_rest_init+0xc/0x14 [ 371.174458] start_kernel+0x404/0x430 Fixes: c245d94ed106 ("i2c: iproc: Add multi byte read-write support for slave mode") Signed-off-by: Dhananjay Phadke --- drivers/i2c/busses/i2c-bcm-iproc.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/busses/i2c-bcm-iproc.c b/drivers/i2c/busses/i2c-bcm-iproc.c index 8a3c98866fb7..688e92818821 100644 --- a/drivers/i2c/busses/i2c-bcm-iproc.c +++ b/drivers/i2c/busses/i2c-bcm-iproc.c @@ -1078,7 +1078,7 @@ static int bcm_iproc_i2c_unreg_slave(struct i2c_client *slave) if (!iproc_i2c->slave) return -EINVAL; - iproc_i2c->slave = NULL; + disable_irq(iproc_i2c->irq); /* disable all slave interrupts */ tmp = iproc_i2c_rd_reg(iproc_i2c, IE_OFFSET); @@ -1091,6 +1091,17 @@ static int bcm_iproc_i2c_unreg_slave(struct i2c_client *slave) tmp &= ~BIT(S_CFG_EN_NIC_SMB_ADDR3_SHIFT); iproc_i2c_wr_reg(iproc_i2c, S_CFG_SMBUS_ADDR_OFFSET, tmp); + /* flush TX/RX FIFOs */ + tmp = (BIT(S_FIFO_RX_FLUSH_SHIFT) | BIT(S_FIFO_TX_FLUSH_SHIFT)); + iproc_i2c_wr_reg(iproc_i2c, S_FIFO_CTRL_OFFSET, tmp); + + /* clear all pending slave interrupts */ + iproc_i2c_wr_reg(iproc_i2c, IS_OFFSET, ISR_MASK_SLAVE); + + iproc_i2c->slave = NULL; + + enable_irq(iproc_i2c->irq); + return 0; } -- 2.17.1