From: Eli Billauer <eli.billauer@gmail.com>
To: gregkh@linuxfoundation.org
Cc: arnd@arndb.de, linux-kernel@vger.kernel.org,
Eli Billauer <eli.billauer@gmail.com>
Subject: [PATCH 7/7] char: xillybus: Ignore and report unsolicited interrupts
Date: Tue, 30 Jun 2026 11:23:30 +0200 [thread overview]
Message-ID: <20260630092330.43534-8-eli.billauer@gmail.com> (raw)
In-Reply-To: <20260630092330.43534-1-eli.billauer@gmail.com>
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 <eli.billauer@gmail.com>
---
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
prev parent reply other threads:[~2026-06-30 9:24 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-30 9:23 [PATCH 0/7] char: xillybus: Harden driver and improve code quality Eli Billauer
2026-06-30 9:23 ` [PATCH 1/7] char: xillybus: Improve control of execution flow with mutexes Eli Billauer
2026-06-30 9:23 ` [PATCH 2/7] char: xillybus: Remove duplicate error path code Eli Billauer
2026-06-30 9:23 ` [PATCH 3/7] char: xillybus: Avoid possible bandwidth inefficiency Eli Billauer
2026-06-30 9:23 ` [PATCH 4/7] char: xillybus: Use unsigned arithmetic for jiffies differences Eli Billauer
2026-06-30 9:23 ` [PATCH 5/7] char: xillybus: Integer arithmetic improvements Eli Billauer
2026-06-30 9:23 ` [PATCH 6/7] char: xillybus: Add defensive sanity checks Eli Billauer
2026-06-30 9:23 ` Eli Billauer [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260630092330.43534-8-eli.billauer@gmail.com \
--to=eli.billauer@gmail.com \
--cc=arnd@arndb.de \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox