From: JP Hein <jp@jphein.com>
To: Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
Hans de Goede <hansg@kernel.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-media@vger.kernel.org, linux-usb@vger.kernel.org,
Ricardo Ribalda <ribalda@chromium.org>,
Michal Pecio <michal.pecio@gmail.com>,
Mathias Nyman <mathias.nyman@linux.intel.com>,
JP Hein <jp@jphein.com>
Subject: [PATCH v8 0/2] media: uvcvideo: Quirks for Razer Kiyo Pro firmware lockup
Date: Sun, 3 May 2026 16:24:59 -0700 [thread overview]
Message-ID: <20260503232501.302335-1-jp@jphein.com> (raw)
In-Reply-To: <20260331003806.212565-1-jp@jphein.com>
The Razer Kiyo Pro (1532:0e05) firmware has multiple lockup paths that
cascade into xHCI host controller death, disconnecting every USB device
on the bus -- including keyboard and mouse, requiring a hard reboot.
The bug has two layers:
* Trigger (device firmware -- Sigmastar SAV630D + AIT camera, fw 1.5.0.1
/ bcdDevice 8.21). Three failure paths:
- LPM / autosuspend resume: device fails to reinitialize after a USB
Link Power Management transition, returning EPIPE on the first
UVC SET_CUR. Mitigated by USB_QUIRK_NO_LPM (patch 1 of the
original 3-patch series, merged by Greg Kroah-Hartman, backported
to stable 6.1, 6.6, 6.12, 6.18, and 6.19).
- Rapid control transfers: sustained UVC control operations overwhelm
the firmware, causing endpoint stalls. Mitigated by
UVC_QUIRK_CTRL_THROTTLE (this series).
- USB descriptor spec violation: SuperSpeed Endpoint Companion
descriptor for EP5 IN (interrupt) declares wBytesPerInterval=8 but
wMaxPacketSize=64. xHCI derives max_esit_payload from the former,
underallocating bandwidth and producing spurious COMP_SHORT_PACKET
events under load.
* Cascade (host controller). Firmware lockup or stalled endpoint
cascades to xhci_hc_died(). Severity is silicon-dependent: per Michal
Pecio's reports on linux-usb, ASMedia hosts hit hc_died in seconds
under both the dual-cancel and SHORT_PACKET-flood paths. Intel Cannon
Lake (this series tested) survives the cancel/resubmit and stream-mmap
teardown reproducers clean.
This series addresses trigger #2 only. Trigger #1 is already mitigated
upstream. Trigger #3 is a host-side bandwidth-allocation concern;
Michal Pecio is prototyping an xhci ring patch (clamp max_esit_payload
+ retry on COMP_SHORT_PACKET) on linux-usb. The two efforts are
complementary: this series prevents the firmware from getting into the
locked state that triggers the cascade; Michal's patch makes the host
side more resilient when the firmware does lock up.
Why kernel-side mitigation is the only viable path: we attempted a
firmware fix. The wBytesPerInterval bug byte is at offset 0x1F570A in
the raw firmware image distributed with Razer's Windows updater. We
reverse-engineered the UVC Extension Unit flash protocol the updater
uses (XU6 selector 3, 32-byte chunks, status 0x82 = success) and
implemented a Linux flash tool. The device acknowledges writes and
reports burn-complete but does not persist after power cycle. The
ROM-boot recovery entry path is locked out in production firmware.
There is no userspace path to fix the bug on shipped devices.
Forensics: firmware-analysis/ in the linked repository.
This v8 series covers the remaining two UVC patches:
Patch 1/2: UVC driver -- introduce UVC_QUIRK_CTRL_THROTTLE to rate-limit
all USB control transfers (50ms minimum interval) in
__uvc_query_ctrl(). The 50ms threshold is the minimum that empirically
prevents firmware overflow, 4x shorter than USB_QUIRK_DELAY_CTRL_MSG's
200ms and scoped specifically to UVC. Quirk is opt-in by device-table
entry; non-quirked devices are unaffected.
Patch 2/2: UVC driver -- add Razer Kiyo Pro device table entry with
UVC_QUIRK_CTRL_THROTTLE, UVC_QUIRK_DISABLE_AUTOSUSPEND, and
UVC_QUIRK_NO_RESET_RESUME. CTRL_THROTTLE rate-limits the rapid-SET_CUR
trigger (verified via stress test, see results below). The other two
cover related failure paths in line with patterns established for
similar fragile UVC firmware (Insta360 Link, Logitech Rally Bar).
Test results:
* stress-test-kiyo.sh (rapid SET_CUR flood, ~25 controls per round):
- stock kernel + stock uvcvideo, no quirks: hc_died at round ~25
- with UVC_QUIRK_CTRL_THROTTLE active: 500+ rounds clean
* Michal Pecio's hammerint (libusb submit/cancel on EP 0x85 IN), Intel
Cannon Lake, 60s x 2 Kiyos:
- 413,738 and 416,350 cycles respectively, both timed out cleanly.
No xhci_hc_died, no "event condition 198", no command timeouts.
NO_LPM was active that boot but inert at this rate (~6900 cycles/sec
leaves no idle time for LPM transitions).
* stream-mmap loop (v4l2-ctl open / format / stream / close), Intel
Cannon Lake, 300s x 2 Kiyos at MJPG 1920x1080 @ 30fps, no quirks
active:
- 134 and 92 cycles respectively, both clean. No fatal patterns in
dmesg.post.
Cross-platform corroboration: the same v4l2-ctl focus_absolute
reproducer is reported on Linux ARM (Raspberry Pi), Windows, and macOS
by independent users. Refs in kernel-patches/upstream-report.md
section "Third-Party Reproduction Evidence".
Changes since v7:
- Reframed scope: this series mitigates the firmware-lockup trigger,
not the xHCI cascade. The cascade is silicon-dependent and is
being addressed separately by Michal Pecio's xhci ring patch on
linux-usb.
- Added test data: hammerint and stream-mmap loop on Intel Cannon
Lake, both clean (~414K/416K cycles per Kiyo over 60s and
134/92 cycles per Kiyo over 300s respectively).
- Added firmware reverse-engineering note: bug byte located at
0x1F570A in fwimage.bin, UVC XU flash protocol implemented, no
userspace path to persist firmware fixes on shipped devices.
- Cross-platform corroboration cited.
- No code changes from v7. v8 is a re-send to integrate post-v7
discussion on the v5 2/3 chain.
Changes since v6:
- Dropped error-code query skip after EPIPE (Ricardo Ribalda)
- Included full lsusb -vv in patch 2/2 commit message (Ricardo Ribalda)
Changes since v5:
- Moved throttle from uvc_query_ctrl() to __uvc_query_ctrl() so all
callers are covered (Ricardo Ribalda)
- Throttle applies to all query types, not just SET_CUR (Ricardo
Ribalda)
Tested on:
- Kernel: 6.17.0-20-generic (Ubuntu 24.04 HWE), 6.17.0-xhci-test
(with Michal Pecio's max_esit_payload + COMP_SHORT_PACKET retry),
6.8.0-106-generic
- Hardware: Intel Cannon Lake PCH xHCI (8086:a36d)
- Device: Two Razer Kiyo Pro units (1532:0e05), firmware 1.5.0.1
(bcdDevice 8.21)
Reproducers and full debug logs:
https://github.com/jphein/kiyo-xhci-fix
- kernel-patches/stress-test-kiyo.sh
- kernel-patches/matrix/michal-tests/hammerint.c
(Michal Pecio's, alongside the harness)
- kernel-patches/matrix/michal-tests/stream-loop.sh
JP Hein (2):
media: uvcvideo: add UVC_QUIRK_CTRL_THROTTLE for fragile USB firmware
media: uvcvideo: add Razer Kiyo Pro to device info table
drivers/media/usb/uvc/uvc_driver.c | 16 ++++++++++++++++
drivers/media/usb/uvc/uvc_video.c | 20 ++++++++++++++++++++
drivers/media/usb/uvc/uvcvideo.h | 3 +++
3 files changed, 39 insertions(+)
--
2.43.0
next prev parent reply other threads:[~2026-05-03 23:25 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-31 0:38 [PATCH v5 0/3] USB/UVC: Add quirks to prevent Razer Kiyo Pro xHCI cascade failure JP Hein
2026-03-31 0:38 ` [PATCH v5 1/3] USB: core: add NO_LPM quirk for Razer Kiyo Pro webcam JP Hein
2026-03-31 0:38 ` [PATCH v5 2/3] media: uvcvideo: add UVC_QUIRK_CTRL_THROTTLE for fragile firmware JP Hein
2026-04-09 6:45 ` Ricardo Ribalda
[not found] ` <CAD5VvzAu8+Qz7hEEBzuKvO11X=YD-wrtX3_Tk77g2Cq5rZZD0Q@mail.gmail.com>
2026-04-09 7:51 ` Jeffrey Hein
2026-04-09 8:02 ` Michal Pecio
2026-04-09 8:15 ` Jeffrey Hein
2026-04-09 20:17 ` Michal Pecio
2026-04-10 0:01 ` Jeffrey Hein
2026-04-10 0:24 ` Jeffrey Hein
2026-04-10 4:47 ` Michal Pecio
2026-04-10 21:48 ` Mathias Nyman
2026-04-10 23:06 ` Jeffrey Hein
2026-04-13 8:05 ` Michal Pecio
2026-04-27 6:35 ` Michal Pecio
2026-05-03 22:54 ` Jeffrey Hein
2026-04-13 20:24 ` Michal Pecio
2026-04-11 13:39 ` Michal Pecio
2026-03-31 0:38 ` [PATCH v5 3/3] media: uvcvideo: add quirks for Razer Kiyo Pro webcam JP Hein
2026-04-09 6:49 ` Ricardo Ribalda
2026-04-09 7:38 ` Jeffrey Hein
2026-04-09 7:42 ` [PATCH v6 0/2] media: uvcvideo: Add quirks to prevent Razer Kiyo Pro xHCI cascade failure JP Hein
2026-04-09 7:42 ` [PATCH v6 1/2] media: uvcvideo: add UVC_QUIRK_CTRL_THROTTLE for fragile USB firmware JP Hein
2026-04-09 7:57 ` Ricardo Ribalda
2026-04-09 8:12 ` Jeffrey Hein
2026-04-09 7:42 ` [PATCH v6 2/2] media: uvcvideo: add Razer Kiyo Pro to device info table JP Hein
2026-04-09 7:57 ` Ricardo Ribalda
2026-04-09 8:13 ` Jeffrey Hein
2026-04-10 0:28 ` [PATCH v7 0/2] media: uvcvideo: Add quirks to prevent Razer Kiyo Pro xHCI cascade failure JP Hein
2026-04-10 0:28 ` [PATCH v7 1/2] media: uvcvideo: add UVC_QUIRK_CTRL_THROTTLE for fragile USB firmware JP Hein
2026-04-10 0:28 ` [PATCH v7 2/2] media: uvcvideo: add Razer Kiyo Pro to device info table JP Hein
2026-04-13 20:40 ` [PATCH v7 0/2] media: uvcvideo: Add quirks to prevent Razer Kiyo Pro xHCI cascade failure Michal Pecio
2026-04-18 17:26 ` Jeffrey Hein
2026-05-03 23:24 ` JP Hein [this message]
2026-05-03 23:25 ` [PATCH v8 1/2] media: uvcvideo: add UVC_QUIRK_CTRL_THROTTLE for fragile USB firmware JP Hein
2026-05-03 23:25 ` [PATCH v8 2/2] media: uvcvideo: add Razer Kiyo Pro to device info table JP Hein
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=20260503232501.302335-1-jp@jphein.com \
--to=jp@jphein.com \
--cc=gregkh@linuxfoundation.org \
--cc=hansg@kernel.org \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-media@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=mathias.nyman@linux.intel.com \
--cc=michal.pecio@gmail.com \
--cc=ribalda@chromium.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