From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 85689399890 for ; Thu, 16 Jul 2026 20:40:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784234437; cv=none; b=JO3Z9h3TN2dYDAehKQszYLTlk3P/nKjgWz8z4eyew+lo3sqJqNm9G8feuRChP/E6zVdrWrGP9lIvNP0kTJenSl0grkA2XBt6Bvgq4/XbjsEdVJ/c2PW4xVG76Ye4GwhOcwAaWK/P5YqCItHsdTS6gu5ySBjePnYbsUpy6w4U9Lg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784234437; c=relaxed/simple; bh=otcIncO+Isr44zdDTH91/wp+ObFmoFB8I004c3lOF3M=; h=Message-ID:Subject:From:To:Cc:Date:In-Reply-To:References: Content-Type:MIME-Version; b=QET6k+vkh/IaI3Lq/QemdFrkUBQ+/Rk7AF48yROXaxC4PMikyPz2TrJAKc2JzpH6wm4UCI940wEPCWT2N9Nmf/A/WzlJhGtWtf5hd5F0qVdrs1XDLi0wKIz29Ikwz01OQy5pBKG0/7WCVcE0ul2nXv7+m5WxqPSrFG2uJhxPgw0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Ys6cKKF1; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.b=qByX2HGS; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Ys6cKKF1"; dkim=pass (2048-bit key) header.d=redhat.com header.i=@redhat.com header.b="qByX2HGS" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1784234434; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=O5d6Dsz72G+wI4rBRnHzICgsrc1S97mJgQumeACQ5SI=; b=Ys6cKKF1DV18PTw97Y2LoVUzaQrPmtPn43cILHsuBq8JWG7ZIjACx7A0c6LCgBySu/k5EC 94+NUqNXobhlxx2PL1/r9Dq1C62KfK77CwDl5IErM6piKVGCY3drkJ/6WnZmNj6HbyArtE mHJIMedEEbtQi25dbgE4bFt7BSXzXw8= Received: from mail-qv1-f70.google.com (mail-qv1-f70.google.com [209.85.219.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-543-7UxISA2rMPO8l41fkZRh2g-1; Thu, 16 Jul 2026 16:40:32 -0400 X-MC-Unique: 7UxISA2rMPO8l41fkZRh2g-1 X-Mimecast-MFC-AGG-ID: 7UxISA2rMPO8l41fkZRh2g_1784234432 Received: by mail-qv1-f70.google.com with SMTP id 6a1803df08f44-8e97889ac8aso90392586d6.3 for ; Thu, 16 Jul 2026 13:40:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1784234432; x=1784839232; darn=vger.kernel.org; h=mime-version:user-agent:content-transfer-encoding:content-type :references:in-reply-to:date:cc:to:from:subject:message-id:from:to :cc:subject:date:message-id:reply-to:content-type; bh=O5d6Dsz72G+wI4rBRnHzICgsrc1S97mJgQumeACQ5SI=; b=qByX2HGSbLIeBdgbfSl+/+vWYQjxI8ap9cYhMHHbsVd09SJ650pncJeHDUj9I8aQ8m VWDepG99uOddSB+v6g03Axd1VMCH32mK6WF2rodnh36avkFxHS/CPYXDH7M7chQ6vUPx 9dydOoMFdOxcE1iDljBpgQj7xqzt2QXYqLQ+pju+iwh4hgmPR9x2QrDRiepH1vH10d4N H1X0hK9HNOjGgU6Bs/5MF1EA97FbtNjobpi9Am4WZuOYq2jDJaGM6+uZHKVOqOXuqp4p /WKbvYxNbuKJWMYSmqnak/i1JLdO1o3PRDiKJ1pzA1yQ5ldiavY+ejEf/eqZntOmQ+8h XKaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784234432; x=1784839232; h=mime-version:user-agent:content-transfer-encoding:content-type :references:in-reply-to:date:cc:to:from:subject:message-id:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=O5d6Dsz72G+wI4rBRnHzICgsrc1S97mJgQumeACQ5SI=; b=db7hYkwaU4g7d48D6W09tVCxAeVNuDfhRaejVJO3F9omQnL2498KAv3ixgpU3dH9Ea qGYy81o80danMB7LlvS57y2yEJ96mEjPfa29A4vExisa7U2WDvxx+h4oD/IdDFlpQXaS MursOO7/KsDgKPhMjhK4GWfwEvh7CSO1oY9MEtqFf27p44u3h4wmMjrKifcq8O/3xox4 cjkrOfM4iCsc0m9N7qqUHe9vorE2EIDDzw8yLTF8q/nT45KI36Y/TImb/yxS+Nu7Algw SD/YPG4gltzvzD7EwQZspukrIa2J2Y41uE89Eu0VBkB7vrDSoxGtEiX0bU3W9JCRA+4R wpIQ== X-Forwarded-Encrypted: i=1; AHgh+RrfXdRwdlsDaDdkw0AtwYgHnK2VwxJ8OQfB/Hed3vrU9IaEusF59+/zQPnbz7t1XtzL5nxg/yTbOSiBO2o=@vger.kernel.org X-Gm-Message-State: AOJu0Yx/1Z6wob5pyJmfhPYhaugO7nimHcSCK3pxlgOx4He0nbAlgvKD 9v3JfYEGIsq/Apmzy+pgwXnGHdscjsbAXHkc8XB1ggU6UPTmfxyfXlFRtzzd8YDXsgjue2qMq7U Feddn++TqefqouayvLVsl+1/JqUaHRVZzWcIXT7lFZp4aUjrPIm7rciXk5YVRAgSRSQ== X-Gm-Gg: AfdE7clSV6f1IBfNbU2gVgfHKeyskET0+E45fQMF9q8c+4hnLBwDEgcyr+yYZmfpdYj zztJhv8OqMSRVatYtm1sT5BccB9HDRMVf55uIDV461p4lNE1uQjdajEMlc3xNgoiAtu4oJFFr06 uNfETL4A6LZ6Sk/NDMU9iCckLznA7nmNyJcSXC7s1BtETYJHb98hNxTjCC9w7VTSlbTgY25F5// 9BvwG20zV7FzJECZAroP1OubzSr1Z1byj0BRi5/hVpbht2pLBZ1BNgCS4igl8ndcwQR+8nJZ+Ml O7jxf5uMxK5Y9Lo3x4qTABrJpdUD0tRgv919/pTy8rAP1fgHxrHwiq8ON/05S14ClPwV7Q1D X-Received: by 2002:a05:622a:251:b0:517:812c:ae29 with SMTP id d75a77b69052e-51e42453f12mr134213871cf.53.1784234432105; Thu, 16 Jul 2026 13:40:32 -0700 (PDT) X-Received: by 2002:a05:622a:251:b0:517:812c:ae29 with SMTP id d75a77b69052e-51e42453f12mr134213541cf.53.1784234431629; Thu, 16 Jul 2026 13:40:31 -0700 (PDT) Received: from [192.168.8.4] ([100.0.180.93]) by smtp.gmail.com with ESMTPSA id d75a77b69052e-51caab6e9f4sm166614571cf.2.2026.07.16.13.40.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 16 Jul 2026 13:40:30 -0700 (PDT) Message-ID: Subject: Re: [PATCH] drm/nouveau/disp: Prevent division-by-zero during DisplayPort link training transitions From: lyude@redhat.com To: Arjan Filius , Danilo Krummrich Cc: nouveau@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org Date: Thu, 16 Jul 2026 16:40:30 -0400 In-Reply-To: <69D67A9F-1A56-4814-AE68-50559DED42AF@xs4all.nl> References: <69D67A9F-1A56-4814-AE68-50559DED42AF@xs4all.nl> Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.58.3 (3.58.3-1.fc43) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Hi, can you please clarify whether or not you used generative AI for this patch series? If so, this needs to be noted as part of the commit message. Additionally, both of these patches look to be identical except that one prints a message and the other doesn't. You can just send a single version, we will figure out how to handle that part after. On Thu, 2026-07-16 at 16:55 +0200, Arjan Filius wrote: > Dear Nouveau Maintainers, > =C2=A0 > Please find below a proposed patch to prevent a division-by-zero > kernel oops and subsequent lockup in the Nouveau display supervisor > engine when DisplayPort links transition to 0 active lanes. This bug > was observed and patched/tested against the mainline kernel version > **7.1.3**, but is present in all current upstream code. > =C2=A0 > --- > =C2=A0 > ### BRIEF EXPLANATION > =C2=A0 > During screen sleep transitions or multi-input display switches (KVM > switching), the active lane count of a DisplayPort link can > temporarily drop to 0 (`ior->dp.nr =3D=3D 0`).=20 > =C2=A0 > When this occurs, the DisplayPort supervisor function > `nv50_disp_super_2_2_dp` is invoked via modeset interrupts. Without > an early-exit guard, the function attempts to perform symbols/hblank > and link rate calculations that divide by `ior->dp.nr`, resulting in > a kernel division-by-zero math exception, lockup, and system freeze. > =C2=A0 > This patch adds an early-exit check at the beginning of > `nv50_disp_super_2_2_dp` to abort display configuration when the link > training lanes count is zero. >=20 > *=C2=A0=C2=A0 **Tested Kernel Version:** `7.1.3` (mainline stable branch) >=20 > --- >=20 > ### EXTREMELY DETAILED TECHNICAL BREAKDOWN >=20 > #### 1. Hardware Context > This bug has been consistently reproduced on a Lenovo ThinkPad T430 > (Intel HD 4000 + discrete NVIDIA NVS 5400M / GF108 chipset) connected > to a Lenovo ThinkPad Mini Dock Plus Series 3 (Model 4338) with dual > external monitors on dock DisplayPorts (`DP-2` and `DP-3`).=20 >=20 > #### 2. Root Cause Analysis (Code Level) > Inside `drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c`, when `ior- > >dp.nr =3D=3D 0`, the driver executes the following lines in > `nv50_disp_super_2_2_dp()`: >=20 > *=C2=A0=C2=A0 **Line 1179:** Calculations for horizontal blank symbols: > =C2=A0=C2=A0=C2=A0 ```c > =C2=A0=C2=A0=C2=A0 h =3D h - (3 * ior->dp.ef) - (12 / ior->dp.nr); > =C2=A0=C2=A0=C2=A0 ``` > *=C2=A0=C2=A0 **Line 1185:** Calculations for vertical blank symbols: > =C2=A0=C2=A0=C2=A0 ```c > =C2=A0=C2=A0=C2=A0 v =3D v - ((36 / ior->dp.nr) + 3) - 1; > =C2=A0=C2=A0=C2=A0 ``` > *=C2=A0=C2=A0 **Line 1190:** Calculations for active link data rate: > =C2=A0=C2=A0=C2=A0 ```c > =C2=A0=C2=A0=C2=A0 link_data_rate =3D (khz * head->asy.or.depth / 8) / io= r->dp.nr; > =C2=A0=C2=A0=C2=A0 ``` >=20 > In all three instances, the denominator `ior->dp.nr` is `0`, causing > an immediate kernel math exception in the display workqueue > (`nouveau_display_hpd_work` or `nv50_disp_super`), locking up the > graphics pipeline, freezing the screen, and hanging any reboot > attempts (requiring a physical hard reset). >=20 > #### 3. Daily Workday Trigger Scenario > 1.=C2=A0 The T430 (via dock) and a secondary workstation are both > connected to different inputs on the same external monitors. > 2.=C2=A0 The monitors' input sources are switched to the secondary > workstation. > 3.=C2=A0 At the end of the day, the secondary workstation goes to sleep o= r > is shut down. > 4.=C2=A0 With no active inputs, the external monitors enter power-saving > standby mode. > 5.=C2=A0 When the user subsequently wakes up or interacts with the T430, > the driver attempts a modeset refresh. Since the monitors are asleep > and inputs are switched away, the lanes count is read as `0`, > triggering the division-by-zero oops. >=20 > #### 4. Stack Trace (Oops Log) > ```text > [di jul 23 10:28:25 2024] nouveau 0000:01:00.0: DRM: DDC responded, > but no EDID for DP-2 > [di jul 23 10:28:25 2024] nouveau 0000:01:00.0: DRM: DDC responded, > but no EDID for DP-3 > [di jul 23 10:28:26 2024] Workqueue: nvkm-disp nv50_disp_super > [nouveau] > [di jul 23 10:28:26 2024] RIP: 0010:nv50_disp_super_2_2_dp+0xa7/0x320 > [nouveau] > [di jul 23 10:28:26 2024]=C2=A0 ? nv50_disp_super_2_2_dp+0xa7/0x320 > [nouveau] > [di jul 23 10:28:26 2024]=C2=A0 nv50_disp_super_2_2+0xf2/0x160 [nouveau] > [di jul 23 10:28:26 2024]=C2=A0 nv50_disp_super+0x139/0x280 [nouveau] > ``` >=20 > #### 5. Verification Proof (Bypass Log) > With the patch applied and running on kernel `7.1.3-custom #2`, the > screen standby transition was bypassed cleanly. The driver caught the > lane count of 0, bypassed display configuration, and proceeded to put > the graphics chip into its low-power runtime suspend state > (`suspended`) without locking up the OS: > ```text > [45162.232371] nouveau 0000:01:00.0: disp: DP link is inactive (lanes > =3D 0), skipping display configuration. > [45162.232402] nouveau 0000:01:00.0: disp: DP link is inactive (lanes > =3D 0), skipping display configuration. > [45178.605627] nouveau 0000:01:00.0: timeout > [45178.605629] WARNING: nv50_disp_dmac_fini+0x168/0x1c0 [nouveau] > [45180.608524] nouveau 0000:01:00.0: disp: ch 1 fini timeout, > 8e061008 > [45182.608521] nouveau 0000:01:00.0: timeout > [45182.608523] WARNING: nv50_disp_core_fini+0x143/0x190 [nouveau] > ``` >=20 > --- >=20 > Signed-off-by: Arjan Filius > --- >=20 > ### CHOOSE ONE OF THE PATCH OPTIONS BELOW TO APPEND: >=20 > #### OPTION A: The Silent Production Patch (RECOMMENDED FOR UPSTREAM) > *Note: Kernel maintainers generally reject warnings or print spam for > expected hardware sleep/disconnect transitions. A silent return is > the preferred upstream pattern.* >=20 > ```diff > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c > b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c > index 51c045bdfcbb..ab1bc0898def 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c > @@ -1157,6 +1157,10 @@ nv50_disp_super_2_2_dp(struct nvkm_head *head, > struct nvkm_ior *ior) > =C2=A0{ > =C2=A0 struct nvkm_subdev *subdev =3D &head->disp->engine.subdev; > =C2=A0 > + /* If the DisplayPort link is inactive (0 lanes), skip > configuration */ > + if (ior->dp.nr =3D=3D 0) > + return; > + > =C2=A0 const u32 khz =3D head->asy.hz / 1000; > =C2=A0 const u32 linkKBps =3D ior->dp.bw * 27000; > =C2=A0 const u32 symbol =3D 100000; > ``` >=20 > #### OPTION B: The Warning/Verbose Patch (What was tested locally) > *Note: Prints warning logs to the kernel buffer for validation and > troubleshooting.* >=20 > ```diff > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c > b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c > index 51c045bdfcbb..ab1bc0898def 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c > @@ -1157,6 +1157,12 @@ nv50_disp_super_2_2_dp(struct nvkm_head *head, > struct nvkm_ior *ior) > =C2=A0{ > =C2=A0 struct nvkm_subdev *subdev =3D &head->disp->engine.subdev; > =C2=A0 > + /* If the DisplayPort link is inactive (0 lanes), skip > configuration */ > + if (ior->dp.nr =3D=3D 0) { > + nvkm_warn(subdev, "DP link is inactive (lanes =3D 0), > skipping display configuration.\n"); > + return; > + } > + > =C2=A0 const u32 khz =3D head->asy.hz / 1000; > =C2=A0 const u32 linkKBps =3D ior->dp.bw * 27000; > =C2=A0 const u32 symbol =3D 100000; > ```