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:
(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.