NetBSD Problem Report #60696

From www@netbsd.org  Tue Sep  8 10:38:51 2026
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (2048 bits)
	 client-signature RSA-PSS (2048 bits))
	(Client CN "mail.netbsd.org", Issuer "YR1" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id EE4111A923B
	for <gnats-bugs@gnats.NetBSD.org>; Tue,  8 Sep 2026 10:38:50 +0000 (UTC)
Message-Id: <20260908103849.BC9A21A923C@mollari.NetBSD.org>
Date: Tue,  8 Sep 2026 10:38:49 +0000 (UTC)
From: raytran08@gmail.com
Reply-To: raytran08@gmail.com
To: gnats-bugs@NetBSD.org
Subject: genfb(4) restores the wrong palette when leaving WSDISPLAYIO_MODE_MAPPED
X-Send-Pr-Version: www-1.0
X-From4GNATS: "raytran08@gmail.com via gnats" <gnats-admin@NetBSD.org>

>Number:         60696
>Category:       kern
>Synopsis:       genfb(4) restores the wrong palette when leaving WSDISPLAYIO_MODE_MAPPED
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    nat
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Sep 08 10:40:00 +0000 2026
>Last-Modified:  Thu Oct 15 15:42:14 +0000 2026
>Originator:     Ray Tran
>Release:        11.0
>Organization:
Diamond Creek Digital
>Environment:
NetBSD/mac68k 11.0
Tested on: Macintosh IIcx (68030, NuBus "Toby" video), Centris 650 (68040, onboard "Wombat" DAFB)
>Description:
genfb keeps one copy of the palette, scp->sc_cmap_red/green/blue[256].

  - genfb_putcmap(), the WSDISPLAYIO_PUTCMAP path, writes into it
    (dev/wsfb/genfb.c, "memcpy(&scp->sc_cmap_red[index], ...)").
  - genfb_restore_palette() reads out of it and pushes it to hardware.
  - WSDISPLAYIO_SMODE calls genfb_restore_palette() on the transition back
    to WSDISPLAYIO_MODE_EMUL.

So when a program maps the framebuffer, programs its own colours through
WSDISPLAYIO_PUTCMAP and then exits, genfb "restores" that program's
palette onto the console.  The console's own palette is gone: nothing
kept a copy of it.  The restore is close to a no-op -- it rewrites the
hardware with the values already there.

This affects any genfb attachment whose bus backend supplies a colormap
callback, since without one genfb_putpalreg() does nothing and the
hardware LUT is never touched at all.  On an 8-bit display the effect is
obvious: after leaving X the console is drawn with X's colour cube.
>How-To-Repeat:
On a machine whose genfb attachment provides a colormap callback, at
depth 8: note the console colours, run an X server that allocates
colours (i.e. without a static colormap), exit it, and look at the
console.  It is drawn with the palette X last installed rather than the
one it had before X started.
>Fix:
Keep a copy of the palette when leaving MODE_EMUL and put it back when
returning, so the console's colours survive a mapped-mode program.

The change is contained in the WSDISPLAYIO_SMODE case plus three arrays
in struct genfb_private, and does not affect a system with no userland
palette changes.  The order of the mode callback relative to the restore
is unchanged.

Tested on a Macintosh Centris 650 (DAFB, 640x480x8, colormap callback
provided) running NetBSD 11.0, with an X server that programs the CLUT
and a console driver that installs its own palette.  Before, the
console came back wearing X's colours; after, its own palette returns.

Applies with "patch -p1" from the top of usr/src; verified with -F0
(no fuzz) against NetBSD-current 11.99.8 (20260830003849Z) and 11.0.

--- a/sys/dev/wsfb/genfb.c
+++ b/sys/dev/wsfb/genfb.c
@@ -93,6 +93,14 @@
 	u_char sc_cmap_red[256];
 	u_char sc_cmap_green[256];
 	u_char sc_cmap_blue[256];
+	u_char sc_cmap_saved_red[256];
+	u_char sc_cmap_saved_green[256];
+	u_char sc_cmap_saved_blue[256];
 	bool sc_want_clear;
 #ifdef SPLASHSCREEN
 	struct splash_info sc_splash;
@@ -508,11 +516,33 @@
 			return error;

 		if (new_mode != scp->sc_mode) {
+			if (scp->sc_mode == WSDISPLAYIO_MODE_EMUL) {
+				memcpy(scp->sc_cmap_saved_red,
+				    scp->sc_cmap_red, 256);
+				memcpy(scp->sc_cmap_saved_green,
+				    scp->sc_cmap_green, 256);
+				memcpy(scp->sc_cmap_saved_blue,
+				    scp->sc_cmap_blue, 256);
+			}
 			scp->sc_mode = new_mode;
 			if (scp->sc_modecb != NULL) {
 				scp->sc_modecb->gmc_setmode(sc, scp->sc_mode);
 			}
 			if (new_mode == WSDISPLAYIO_MODE_EMUL) {
+				memcpy(scp->sc_cmap_red,
+				    scp->sc_cmap_saved_red, 256);
+				memcpy(scp->sc_cmap_green,
+				    scp->sc_cmap_saved_green, 256);
+				memcpy(scp->sc_cmap_blue,
+				    scp->sc_cmap_saved_blue, 256);
 				genfb_restore_palette(sc);
 				vcons_redraw_screen(ms);
 			}

>Release-Note:

>Audit-Trail:

Responsible-Changed-From-To: kern-bug-people->nat
Responsible-Changed-By: nat@NetBSD.org
Responsible-Changed-When: Thu, 15 Oct 2026 15:42:14 +0000
Responsible-Changed-Why:
Take.


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.