From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pf1-f178.google.com (mail-pf1-f178.google.com [209.85.210.178]) (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 4E026377A92 for ; Mon, 27 Jul 2026 09:40:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.178 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785145249; cv=none; b=OCG6Ndw/79nSN0FMmtPo9ND2ou4TfaTCx1Sfks9GBVIcOuhzuaE1ny5nCjgcsqiOAqWP8BbS5k9Lhxdb7nFip5PKtaxCgy7acuuSxHHx4JLrYZSMV726vk/ncygFlkq3vHHJeFBPvxpAlwUpPUGYyip1Gviw/VRnwzFFNSRXLnA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785145249; c=relaxed/simple; bh=zx+leNGUeBHEhm1JutOtvK/7cNMX6N7QAiE5RBgc+jk=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=NDY8b+1rfBFq2+xorklUfOMy0QdE2hCMWtOtsfbYA3UbhtD/zGu+oqSzhspWaeAXU1UYETML8I8GbuKvlvSyPKKRoQqaJlkY72kfzPbZBMWFq8p+NCVjjISfH6zc191LR/E044rnpxtIm8Oyucaf6hQFW6o/bw3p6C4URBWXi3A= 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=odNI44cM; arc=none smtp.client-ip=209.85.210.178 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="odNI44cM" Received: by mail-pf1-f178.google.com with SMTP id d2e1a72fcca58-848643382fcso2486706b3a.1 for ; Mon, 27 Jul 2026 02:40:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1785145247; x=1785750047; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=4yKTzT/F5uTEtR3ntvrMcxd+akjSjIaIcKdNSZHGtug=; b=odNI44cMcPNdVi0hFSGpf9SPwZkw8bjPQ6gJeqbLxeOA/mI3C4OIAd+IuQryZAJMrS hfFxLjowU7NmRk+O20Zs17x1hMC8EkrJQ0k3IfzLpOnjJsG66ISvwfo70vJCrFS7DtAo WADfCk7eEkA+kEWu/9WskPVDpfT1e6f4lV9v7ul40RKX7UXaHFqBpaaNZFonMHDLYKou FKw0SHeSs1QIi1CeA4j9Y4cOa8lURcqWI3rIHGKRTQmIwjhU1+UAXuRnizx12fOlrQAK po9GoJTLJlbEdvwY+bvSlJ876MaN+HHYL04LysZJ56Ww5Lr+/fnxJwBTNVf11L/J8hpZ bUtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785145247; x=1785750047; h=content-transfer-encoding:mime-version: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=4yKTzT/F5uTEtR3ntvrMcxd+akjSjIaIcKdNSZHGtug=; b=lVu3+DSqCQC90YM26ZnZ13xSOdx0xb8Zw8i+2IcaaYNfgkMdp9GovUCkH7cUCCVbNS Ek7maSOtA1SoCK/Zqd3hnxls8J2DPzOilHMlQRiXvLc7NuzMXlG5hTw7LvRQ+A9Ab6tQ ISjfPTNXxGNKTnE0H2AGW6WGcGJKvEhL7G18zHHmpZKPFpvAyY87AG5OJC2xAROdDx3+ UknOlug+kqv7Ha1g8wJF7Fg0ZWds9Q1fAdkrLLgRCGqy+BcUhS9401bbDJ48w4F0fSij zXpGglfLC6Y2ftLMrQ4BOp8IwtE8DIKgfhYLSgYytEiRTqWsAsuVQJjekKECCVJGzoVq jRCA== X-Forwarded-Encrypted: i=1; AHgh+RpxE5VPgpgaT56YghF7XmLlcdfbgPROcMbBbnFfi0fuawz/45y3J2h81M43sbs+msAD4f/iunAXyIXTmq4=@vger.kernel.org X-Gm-Message-State: AOJu0YwZ0z6Z4Cvn44izDMlXllHPHbAjXE4jGc7ExfC08Qn1Av19+3FZ a016W2d6N+/T2+Tp9Lxp4/ZmvNL2MnljQwrCXQ5OJXhrqK0bGcinD8yG X-Gm-Gg: AR+sD12SQPcS1xZ2MT8D3U6h0vYl3ugQD1dRJhWfU23/3sn8m899FPMqc6ClB9ZVIUP u2agjn6V04WWf43hUnEIJpIrmpkKmaA1wGFAUSAL/0u2dMavSlGfqe7TzEsePFjzUNVnh4ILAXE aErkP8DJ1b0pEvGuJz7gfTqPETM95eIiBL7fLP35h0Fw3hk/U1m9ONfvAAiSjuwfH4/ZdFNvRgm lNOXYECsoQ6GlOb4GTY6RiMqKaYeUUbdso2DoBzamtdKM4ugWMQH7/cLmwkyL2oMfcj1RCZCkro eW5Wmg5iDEVL+16o/gKm0Zw03O+79UI7UhR6J0NnLEkT5H0ZsJhhs/VFagJDvEdeDbAqsXl9MDx VM0EA8ZS/LejcFNDUsxWBNWP6xL34yxlDh9y+KVtfnVYeFECWt3ikaOJ7caOhzEmKjKR+JTFjso ig51627GFHYwgTfXyP0ZedAXGc6/f09mAvILQVc/Pk3KA1gzjtagefSIgCWPycXDseyS3PlZAD4 IfJaUn82JDxi0DBqQw= X-Received: by 2002:a05:6a00:1703:b0:848:19f4:3b52 with SMTP id d2e1a72fcca58-84e59554a26mr6005631b3a.38.1785145247554; Mon, 27 Jul 2026 02:40:47 -0700 (PDT) Received: from 7cf34ddc0813.ant.amazon.com ([54.222.46.6]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84e5341d68asm2737232b3a.46.2026.07.27.02.40.44 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Mon, 27 Jul 2026 02:40:47 -0700 (PDT) From: Jiazi Liu X-Google-Original-From: Jiazi Liu To: Thinh.Nguyen@synopsys.com Cc: gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, Jiazi Liu Subject: [PATCH 1/1] usb: dwc3: gadget: fix IRQ storm on invalid event buffer count Date: Mon, 27 Jul 2026 17:40:15 +0800 Message-ID: <20260727094015.5101-1-liujiazi@amazon.com> X-Mailer: git-send-email 2.50.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit When dwc3_check_event_buf() reads a GEVNTCOUNT value exceeding the event buffer length, commit 63ccd26cd1f6 ("usb: dwc3: gadget: check that event count does not exceed event buffer length") returns IRQ_NONE without writing back GEVNTCOUNT. Since the DWC3 interrupt is level-triggered, the uncleared IRQ source keeps the line asserted, causing a tight IRQ storm that accumulates 99,900 unhandled interrupts and triggers spurious.c:184 BUG -> kernel panic. The resulting call stack: __report_bad_irq+0xac/0xc8 note_interrupt+0x340/0x468 handle_irq_event+0xac/0xc0 handle_fasteoi_irq+0x120/0x228 gic_handle_irq+0x68/0x108 ... kernel BUG at kernel/irq/spurious.c:184 To reproduce, write a bogus value exceeding the event buffer length directly to the GEVNTCOUNT register: devmem 4 0x1004 Write the bogus count back to GEVNTCOUNT to clear the IRQ source, consistent with the stale event clearing pattern in dwc3_event_buffers_setup(), and schedule a soft disconnect via softcon_work to recover the controller state. Fixes: 63ccd26cd1f6 ("usb: dwc3: gadget: check that event count does not exceed event buffer length") Cc: stable@vger.kernel.org Signed-off-by: Jiazi Liu --- drivers/usb/dwc3/core.h | 2 ++ drivers/usb/dwc3/gadget.c | 23 ++++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 608daeb7ef10..0881ed7e956e 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -1004,6 +1004,7 @@ struct dwc3_glue_ops { /** * struct dwc3 - representation of our controller * @drd_work: workqueue used for role swapping + * @softcon_work: workqueue used for soft connect/disconnect recovery * @ep0_trb: trb which is used for the ctrl_req * @bounce: address of bounce buffer * @setup_buf: used while precessing STD USB requests @@ -1189,6 +1190,7 @@ struct dwc3_glue_ops { */ struct dwc3 { struct work_struct drd_work; + struct work_struct softcon_work; struct dwc3_trb *ep0_trb; void *bounce; u8 *setup_buf; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index fa0f16ffafef..9b24259272a4 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -4669,7 +4669,18 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt) if (count > evt->length) { dev_err_ratelimited(dwc->dev, "invalid count(%u) > evt->length(%u)\n", count, evt->length); - return IRQ_NONE; + /* + * The DWC3 interrupt is level-triggered. Returning IRQ_NONE + * without clearing the IRQ source leaves the line asserted, + * causing a tight IRQ storm that triggers spurious.c:184 BUG. + * Write the bogus count back to GEVNTCOUNT to clear the source, + * consistent with the stale event clearing in + * dwc3_event_buffers_setup(), then schedule a soft disconnect + * to recover the controller state. + */ + dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count); + schedule_work(&dwc->softcon_work); + return IRQ_HANDLED; } evt->count = count; @@ -4729,6 +4740,14 @@ static void dwc_gadget_release(struct device *dev) kfree(gadget); } +static void dwc3_softcon_work(struct work_struct *work) +{ + struct dwc3 *dwc = container_of(work, struct dwc3, softcon_work); + + dev_err(dwc->dev, "event buffer error: performing soft disconnect\n"); + dwc3_gadget_soft_disconnect(dwc); +} + /** * dwc3_gadget_init - initializes gadget related registers * @dwc: pointer to our controller context structure @@ -4772,6 +4791,7 @@ int dwc3_gadget_init(struct dwc3 *dwc) } init_completion(&dwc->ep0_in_setup); + INIT_WORK(&dwc->softcon_work, dwc3_softcon_work); dwc->gadget = kzalloc_obj(struct usb_gadget); if (!dwc->gadget) { ret = -ENOMEM; @@ -4868,6 +4888,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc) if (!dwc->gadget) return; + cancel_work_sync(&dwc->softcon_work); dwc3_enable_susphy(dwc, true); usb_del_gadget(dwc->gadget); dwc3_gadget_free_endpoints(dwc); -- 2.50.1 (Apple Git-155)