From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ej1-f54.google.com (mail-ej1-f54.google.com [209.85.218.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2E68041F7F2 for ; Fri, 24 Jul 2026 09:44:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.54 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784886276; cv=none; b=Ph/ZZTr4azm6Zgbwda0xXzintcq+ds7RYnxLD/3gxhlTRwS4Zju3SxRENZ3B8xle5ENh2Cl0WXrN473BxhG3XkmMUxv/9vbMbBzbbJAr7T1243C2Mnr2Ycxg9/BI7stqIne6U05lZv9lFjC+8Ah1XBie8+Y5Tx5nvNTrH8o8EEg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784886276; c=relaxed/simple; bh=WWpWZmEo0SA7ZK5K2j4Y+nwBCA6XRx9UwXUrSHx9nSY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=SnNooerzHGRQKeRFk4JG2F/LrTXEqvZHEiXdwDHEoE2MLGgfSMw6P+gQGqb5kVsHAJr3t5xXEA6Y9l/gVfNE5G/oo1TTzpuhie+BtcOfCTTN21X2XpU+P3Wv5j+lG+LG0Dkyn4lBSz8Zhhuxl4BFBoPiZtGxKwdxq5EnWmAwjgM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Ww58IsAs; arc=none smtp.client-ip=209.85.218.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Ww58IsAs" Received: by mail-ej1-f54.google.com with SMTP id a640c23a62f3a-c197eaaab00so39360466b.0 for ; Fri, 24 Jul 2026 02:44:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784886273; x=1785491073; darn=vger.kernel.org; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to:content-type; bh=jiFXlmUHbUTL6H6Ji2BpOJqmyMj4AtdFF5lJdRApy60=; b=Ww58IsAsrFYTLD3oP+Ga79mtYnAG2UMzq4DYwvXNKLbYC03l/T37O6Le6lLh3jz8tE OMjw8SFZhgBOUAZKubU0tGkZqEOxEk38FFTAOrOBL5U9E0K03Ut5aClX/lFqcpkTPmHo peC08ozdACbQqoA3C1sH58QSrRAvZZ9ifb2zK479cs3HhliMzgeuXhumTYVgg2l4OMAS Ei1k7/d72yNcmy6mzYR1QIFc7cpBDRQ+eCPVJDlcyJ5BbFQDBsuasrpGymT6aD8MrpJ5 2CIR+nTHiWFoPoWiQkkM1jzOvPKPUTZHqoL8otiwkCzAWSqV6Y7TGPoZPXdwVgRIEBpr a6vQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784886273; x=1785491073; h=references:in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=jiFXlmUHbUTL6H6Ji2BpOJqmyMj4AtdFF5lJdRApy60=; b=EDgXjMBePjyGI+Gezs3tG1geGzHOkMlbVKA9XBKa7HNfXD01CHNk7KHuFjv5u3I8qR WMRCuUBTtZIBGbsD97ITZoblIP1bi6FmvzNbvsvAnFm3l4YAZ8q1KaPpgZjRfuSlgXKF dg3rTr2HnzZnjH7djiKq9DcsB5jralSNdkhvVMR/BuS4bc5kubHcgh5CQCaHiAX0T19a hFJP2WFuLXWnCmuP+39KfYh9nNgO+3ETe0vuoPoA33VQ3KKm56cOw2952C/COzSWSu4a LB/gR2CntuBfcAJlpSQ6vuSu4s1y//iW0U1jE6/td8ZSdO2xCn2z9rSdRh8UWDXxqLxP JGVA== X-Forwarded-Encrypted: i=1; AHgh+RrtZbxPUs+ww8DRK2qyO3At98Mqf4jvgox0COdLvNIstH1lQdEiKTs15nuIjD8XwyGEqdwn1Q7PDQpP9Yk=@vger.kernel.org X-Gm-Message-State: AOJu0YwNFSoxsvBCypHJK6yeQj/QMYE3x7yf9+d9xKYyAdId6ijC2R/v 2uSiMw4UuSK2KpIZNrYp6Nl2YQ0s4CMLCDKg7jJcv0wbw/iqW3ply1G3 X-Gm-Gg: AR+sD10iysRzKO3rzBPq1/KttuqLveYxGOQX6C04P5d4HY7NgjPOn7T1shrgmXL9J04 b3fZxhwqtSBTwFw4LyDnL5JY7ac0Hzj7Elw9vWUydK5HQt7Y70J2M46utRM2206KTs0T9DJXw7n 5IlqR7IYQx4zQvTVUqDSh6y8ZvelMYJfk+gjhDbyXh3W3CM8mIAHuc2SXcJ49P83UJHgfFJ2WlG 8+t9A5h6cq1kin/Ug0hGZU1ppSsL5yUZ/ao5RmwrMDj0Zvu7ot8vjTh3MJ31sf+OQyC9WUemk6u s80Bu+rvKgBsACbYzIL7f5PDUSK1HRm59hBGFW+v92bv5RBhU6vrHW38qmoT5iro6y7u0nizj3S NLAxnvxbgP228pr2V3/dTaG2N2vUgFx9YnlmP4UNCAXofB+jzWLgmX8uIZ0nIKEeM63PDVE8T0h dlp974hkGuz9xT0MBkHtd8ZAesg8AUyVCbmwArtEKw X-Received: by 2002:a17:907:fd0f:b0:c16:9bd:39cb with SMTP id a640c23a62f3a-c1c50c6cb4bmr279328466b.52.1784886273144; Fri, 24 Jul 2026 02:44:33 -0700 (PDT) Received: from localhost (c-85-228-45-68.bbcust.telenor.se. [85.228.45.68]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c1d0a73520csm44064866b.1.2026.07.24.02.44.32 (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Fri, 24 Jul 2026 02:44:32 -0700 (PDT) From: Eli Billauer To: gregkh@linuxfoundation.org Cc: arnd@arndb.de, linux-kernel@vger.kernel.org, corbet@lwn.net, Eli Billauer Subject: [PATCH v3 7/7] char: xillybus: Ignore and report unsolicited interrupts Date: Fri, 24 Jul 2026 11:43:02 +0200 Message-Id: <20260724094302.50761-8-eli.billauer@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260724094302.50761-1-eli.billauer@gmail.com> References: <20260724094302.50761-1-eli.billauer@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: During initialization, the hardware should issue interrupts only in response to requests from the host. Ignore and log unexpected interrupts, as these indicate misbehaving hardware. In the same spirit, in xilly_quiesce(), assign endpoint->num_channels = 0 before allowing the ISR, in order to expose whether the hardware incorrectly sends messages related to data channels during shutdown. Assisted-by: Deepseek:v4-pro Kimi:K2.6 ChatGPT:GPT-5.5 Claude:Sonnet-4.6 Signed-off-by: Eli Billauer --- Notes: Changes v2->v3: -- Add Assisted-by tag to description No change on v1->v2. drivers/char/xillybus/xillybus.h | 3 ++ drivers/char/xillybus/xillybus_core.c | 46 ++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/drivers/char/xillybus/xillybus.h b/drivers/char/xillybus/xillybus.h index 51de7cbc579e..98c7ac4dd1f9 100644 --- a/drivers/char/xillybus/xillybus.h +++ b/drivers/char/xillybus/xillybus.h @@ -94,6 +94,9 @@ struct xilly_endpoint { __iomem void *registers; int fatal_error; + bool allow_isr; + spinlock_t allow_isr_lock; + struct mutex register_mutex; wait_queue_head_t ep_wait; diff --git a/drivers/char/xillybus/xillybus_core.c b/drivers/char/xillybus/xillybus_core.c index 3436f16092e0..ea0debe24968 100644 --- a/drivers/char/xillybus/xillybus_core.c +++ b/drivers/char/xillybus/xillybus_core.c @@ -72,6 +72,8 @@ static struct workqueue_struct *xillybus_wq; * * rd_spinlock does the same with rd_*_buf_idx, rd_empty and end_offset. * + * allow_isr_lock protects allow_isr. + * * register_mutex is endpoint-specific, and is held when non-atomic * register operations are performed. wr_mutex and rd_mutex may be * held when register_mutex is taken, but none of the spinlocks. Note that @@ -84,7 +86,8 @@ static struct workqueue_struct *xillybus_wq; * Only interruptible blocking is allowed on mutexes and wait queues. * * All in all, the locking order goes (with skips allowed, of course): - * wr_mutex -> rd_mutex -> register_mutex -> wr_spinlock -> rd_spinlock + * wr_mutex -> rd_mutex -> register_mutex -> + * allow_isr_lock -> wr_spinlock -> rd_spinlock */ static void malformed_message(struct xilly_endpoint *endpoint, u32 *buf) @@ -119,6 +122,13 @@ irqreturn_t xillybus_isr(int irq, void *data) unsigned int msg_channel, msg_bufno, msg_data, msg_dir; struct xilly_channel *channel; + guard(spinlock)(&ep->allow_isr_lock); + + if (!ep->allow_isr) { + dev_err_ratelimited(ep->dev, "Unexpected interrupt! Something is wrong with the hardware.\n"); + return IRQ_HANDLED; + } + buf = ep->msgbuf_addr; buf_size = ep->msg_buf_size/sizeof(u32); @@ -283,6 +293,19 @@ irqreturn_t xillybus_isr(int irq, void *data) } EXPORT_SYMBOL(xillybus_isr); +/* + * xilly_allow_isr() is similar to enabling / disabling the interrupt, + * with the difference that if an interrupt is issued while ep->allow_isr + * is false, this is visible in the kernel log. + */ + +static void xilly_allow_isr(struct xilly_endpoint *ep, bool newstate) +{ + guard(spinlock_irqsave)(&ep->allow_isr_lock); + + ep->allow_isr = newstate; +} + /* * A few trivial memory management functions. * NOTE: These functions are used only on probe and remove, and therefore @@ -651,6 +674,8 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint) channel->wr_sleepy = 1; + xilly_allow_isr(endpoint, true); + iowrite32(1 | (3 << 24), /* Opcode 3 for channel 0 = Send IDT */ endpoint->registers + fpga_buf_ctrl_reg); @@ -659,6 +684,8 @@ static int xilly_obtain_idt(struct xilly_endpoint *endpoint) (!channel->wr_sleepy), XILLY_TIMEOUT); + xilly_allow_isr(endpoint, false); + if (t <= 0) { dev_err(endpoint->dev, "Failed to obtain IDT. Aborting.\n"); @@ -1843,6 +1870,9 @@ struct xilly_endpoint *xillybus_init_endpoint(struct device *dev) endpoint->failed_messages = 0; endpoint->fatal_error = 0; + endpoint->allow_isr = false; + spin_lock_init(&endpoint->allow_isr_lock); + init_waitqueue_head(&endpoint->ep_wait); mutex_init(&endpoint->register_mutex); @@ -1855,6 +1885,9 @@ static int xilly_quiesce(struct xilly_endpoint *endpoint) long t; endpoint->idtlen = -1; + endpoint->num_channels = 0; + + xilly_allow_isr(endpoint, true); iowrite32((u32) (endpoint->dma_using_dac & 0x0001), endpoint->registers + fpga_dma_control_reg); @@ -1862,6 +1895,9 @@ static int xilly_quiesce(struct xilly_endpoint *endpoint) t = wait_event_interruptible_timeout(endpoint->ep_wait, (endpoint->idtlen >= 0), XILLY_TIMEOUT); + + xilly_allow_isr(endpoint, false); + if (t <= 0) { dev_err(endpoint->dev, "Failed to quiesce the device on exit.\n"); @@ -1915,6 +1951,8 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint) endpoint->idtlen = -1; + xilly_allow_isr(endpoint, true); + /* * Set DMA 32/64 bit mode, quiesce the device (?!) and get IDT * buffer size. @@ -1925,6 +1963,9 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint) t = wait_event_interruptible_timeout(endpoint->ep_wait, (endpoint->idtlen >= 0), XILLY_TIMEOUT); + + xilly_allow_isr(endpoint, false); + if (t <= 0) { dev_err(endpoint->dev, "No response from FPGA. Aborting.\n"); return -ENODEV; @@ -1951,6 +1992,7 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint) if (rc) goto failed_idt; + /* xilly_obtain_idt() allows and then disallows the ISR */ rc = xilly_obtain_idt(endpoint); if (rc) goto failed_idt; @@ -1969,6 +2011,8 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint) if (rc) goto failed_idt; + xilly_allow_isr(endpoint, true); + rc = xillybus_init_chrdev(dev, &xillybus_fops, endpoint->owner, endpoint, idt_handle.names, -- 2.34.1