From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ej1-f51.google.com (mail-ej1-f51.google.com [209.85.218.51]) (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 A61CB4D2EC0 for ; Wed, 22 Jul 2026 10:24:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.51 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784715850; cv=none; b=lNsc23rdG6Krig5WpVuaS6L7ifeKvBs3MEjah6WMf/guIlhOt3jWvkoFBuJQ5AGV1Hfn62xSJSD1etuK2nCNnf5W172ReAIySX0VRxV2BLJRyXq3kLdv+cxLNOLTDAEVGSXUJQCoVzJXS+l16gh8g0GaQpofpzxOfL23VrFCTU8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784715850; c=relaxed/simple; bh=XcQ2c8zSOPzD/hwG3Uq7CStFgE+He1NyBwUn85nt3U4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=mHyK5Xre62xKa9S7XFrKVmNvU0t77lOYj+/gE8t0Klv9piC+lgLenMjnKWeaGoUOf+711ieAZ9xZuIpOK1Tbfk+a5Xc/HUmzjMoeTajbAhicCI912lxWNZuS5EIV2uVdOfL6KNklQRHyLI3CbRFAv5JS4KdULW9BEq+eys7xmfc= 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=R7n97j4G; arc=none smtp.client-ip=209.85.218.51 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="R7n97j4G" Received: by mail-ej1-f51.google.com with SMTP id a640c23a62f3a-c12614b81c9so2222918366b.3 for ; Wed, 22 Jul 2026 03:24:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784715847; x=1785320647; 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=wnK++KI5wbUzyegQ8hBTmOpZ98366a8S50YT0cPuViI=; b=R7n97j4GfC9C2JssdeStEooddfI0cT+COLmL1rkyNLMlprnbVPVuiNyKFhU5G8pOR+ kv1AD2gVT6MgEHiQogvbUvB7L0CZWABYv1RFF8wNPQZ937QI3Zx1pwoZ/YU8AgDCpbkw r107YPdPotdkXy3TE0g1F6fg++hVR+cX+R8udJ6bPKGGu3RRRDv/U2zlfUo+J1wB1jb5 2ZAsJ23grvQuoWEtPDf6cxaPYNaHJ/YFwAlfpNUywmcdoNKxoSfAPaCPURfPqjq5ri+H nAUbRoER6iwf/iunQaTYEkXdxAmNQPPg8BA7t1b5S5I2I4YU7FDCv3+Xfw00QMcST6xp +Caw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784715847; x=1785320647; 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=wnK++KI5wbUzyegQ8hBTmOpZ98366a8S50YT0cPuViI=; b=naue8UTqjEp8qiZVjaQoQ2zO/w0dydHJELXsZO3UrqBjZkJDwvD6bVK1Nj/07kf2C1 igW+umpjKEIrUOzF1wfZGGWDG+KIFdFoB2RD73E4cZdRurDlAybqXWeutYO/ni0Qq42D UtvzbGJaoWdxnbRWxdRHDEr9Z7xMSTyPfwJ1tTeFaLo/gi4BN/4GdORaq2OqN84be+JE v/WP2hr61HGadr4xzrwrGwig0+7zH64K034i/lAH64gli7YaoYQDIZbJpOb2BKPIU8k7 JQg7CWeIWEQnk03rDlLVc6ckuktJ0DI0IhlBn2jI5MbhpCpRJu3Tele/EDI4NDyZpeQV zXVA== X-Forwarded-Encrypted: i=1; AHgh+RppUAphcAvRXZHPuylRKPTyRWWH8i4wC1/Ks95h+o/+Iu7GlT6hVt4KA5HDTCPeh8xXJ/DgtBwQ1hDXgz4=@vger.kernel.org X-Gm-Message-State: AOJu0Yw/GbGWyN5EKzfAySIQNtFw9PMzUigWkWWs5uJs6eQAyjA7LxBl GmIfAS5osVIXZFlvziudjjQMd6dutrTPO7wmojFB7aMjjFKurVTfMWGq X-Gm-Gg: AR+sD11llw39AkkeAZzyhxq/ly18vEalw1K6fLdF7JaEkddwm2m8j25hV0cyNHwCVvr hDznTmi5gTTKWmFDAtALUruo39yy2PiZM565iwf7M0Cq/Ah/M3/fZ+EYv9wY7htvLDVMT+JaB4r wxQlW9eFzLxXIspz7sGy9Stw9Tc7dCx24q5wS4zISyTlhMN3e2Sm3apPOpyoXyGFl/tPZt58s5u yQyQ4tNlpxsgBVx7TZRFMYTCeiXfUYGV4GhVbn0tRyZXtBp7SWMXmUQgdcJJNfNpiSIOeXz8n+c WDi8O+ACGnhqK5Cqk5z22tEjQIBWReNlPlcgx0AZGPGdENM9lYyRX57mttH1aH7hV4EOQiGLnIy IAqDCBQRZr1DJt7j1Y1s3A1e4LyX9iTTSpaf9NezuA6LksQfTOIGMv+NgQ2pSzwp7aaKJLNeDpW CGra4zP2U0Oq8d8HmhgyNMD+ymQvknDty6abAQ91ae X-Received: by 2002:a17:907:1ca6:b0:c15:e33b:8c4d with SMTP id a640c23a62f3a-c16b46c2761mr892805366b.4.1784715846664; Wed, 22 Jul 2026 03:24:06 -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-c1c32ac6ff3sm83635166b.19.2026.07.22.03.24.05 (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Wed, 22 Jul 2026 03:24:06 -0700 (PDT) From: Eli Billauer To: gregkh@linuxfoundation.org Cc: arnd@arndb.de, linux-kernel@vger.kernel.org, Eli Billauer Subject: [PATCH v2 7/7] char: xillybus: Ignore and report unsolicited interrupts Date: Wed, 22 Jul 2026 12:23:07 +0200 Message-Id: <20260722102307.49090-8-eli.billauer@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260722102307.49090-1-eli.billauer@gmail.com> References: <20260722102307.49090-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. Signed-off-by: Eli Billauer --- Notes: 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