Hi,

Krzysztof Sobiecki (@sobkas) is porting mesa to GNU/Hurd using software
rendering options, see
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3927 

According to my findings these patches works fine on hurd-amd64 both
for ssh -Y and in the X window manager. However, on hurd-i386 only
works with ssh -Y, not in X. The error is bus error, but looking closer
with gdb, the problem is a memory error (probably shared memory):
Example: Cannot access memory at address 0xfab2000Cannot access memory
at address 0xfab2000...

Version of mesa tested on both 32bit and 64bit Hurd is 25.3.3-1.
Also tested several versions of my own patches with libdrm is 25.2.8-2
on 32bit. All with the same memory error.

sobkas has tested upstream version 26.0.0~devel{11/12} and claims
everything is fine both on 32bit and 64bit Hurd.

Can somebody please check if the 32-bit Hurd version 25.3.3-1 fails or
works on 32bit (and 64bit). Attached are sobkas upstream patches,
39277.patch, together with patches for
debian/{changelog,rules,control.in,libglx-mesa0.symbols.hurd}

Maybe the patch for libdrm-dev, debian_control.in.patch1 does not apply
until an updated debian/control is generated. Easily fixed by
debian/rules clean followed by dpkg-buildpackage ...

Thanks!

From f1059cb07744abf425b9fe4ef0906aa2b772cb3f Mon Sep 17 00:00:00 2001
From: Krzysztof Sobiecki <[email protected]>
Date: Sun, 18 Jan 2026 15:25:12 +0100
Subject: [PATCH 1/3] gallium/dril: Don't use gbm if there is no gbm configured

---
 meson.build                            | 4 ++++
 src/gallium/targets/dril/dril_target.c | 6 ++++++
 2 files changed, 10 insertions(+)

diff --git a/meson.build b/meson.build
index 2ca81931a0e3..9a578ec8ef68 100644
--- a/meson.build
+++ b/meson.build
@@ -527,6 +527,10 @@ with_egl = get_option('egl') \
   .disable_auto_if(with_platform_haiku) \
   .allowed()
 
+if with_gbm
+  pre_args += '-DHAVE_LIBGBM'
+endif
+
 if with_egl
   _platforms += 'surfaceless'
   if with_gbm and not with_platform_android
diff --git a/src/gallium/targets/dril/dril_target.c b/src/gallium/targets/dril/dril_target.c
index 56c55ee6abe9..b5ba5180cbd0 100644
--- a/src/gallium/targets/dril/dril_target.c
+++ b/src/gallium/targets/dril/dril_target.c
@@ -25,7 +25,9 @@
 #include <dlfcn.h>
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
+#if defined(HAVE_LIBGBM)
 #include <gbm.h>
+#endif
 #include "drm-uapi/drm_fourcc.h"
 
 #define EGL_PLATFORM_GBM_MESA             0x31D7
@@ -372,7 +374,9 @@ init_dri2_configs(int fd)
    struct gbm_device *gbm = NULL;
    if (fd != -1) {
       /* try opening GBM for hardware driver info */
+#if defined(HAVE_LIBGBM)
       gbm = gbm_create_device(fd);
+#endif
       if (!gbm)
          goto out;
    }
@@ -444,8 +448,10 @@ out_egl:
    peglTerminate(dpy);
 
 out_gbm:
+#if defined(HAVE_LIBGBM)
    if (gbm)
       gbm_device_destroy(gbm);
+#endif
 out:
    dlclose(egl);
    if (c)
-- 
GitLab


From b02ad62b078379fa5df603b7a41bc9a1d2c7298b Mon Sep 17 00:00:00 2001
From: Krzysztof Sobiecki <[email protected]>
Date: Sat, 17 Jan 2026 01:28:43 +0100
Subject: [PATCH 2/3] os: Don't use PATH_MAX as it's not portable.

---
 src/util/anon_file.c | 29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/src/util/anon_file.c b/src/util/anon_file.c
index a9ad2a2aad8d..44bc0a6c8dab 100644
--- a/src/util/anon_file.c
+++ b/src/util/anon_file.c
@@ -106,23 +106,28 @@ create_tmpfile_cloexec(char *tmpname)
  * Gets the path to a suitable temporary directory for the current user.
  * Prefers using the environment variable `XDG_RUNTIME_DIR` if set,
  * otherwise falls back to creating or re-using a folder in `/tmp`.
- * Copies the path into the given `buf` of length `len` and also returns
- * a pointer to the same buffer for convenience.
+ * Returns a pointer to the path buffer, which the caller must free().
  * Returns NULL if no suitable directory can found or created.
  */
 static char*
-get_or_create_user_temp_dir(char* buf, size_t len) {
+get_or_create_user_temp_dir(void) {
     const char* env;
+    char* buf;
     struct stat st;
     int uid = getuid();
+    int n;
 
     env = os_get_option("XDG_RUNTIME_DIR");
     if (env && env[0] != '\0') {
-        snprintf(buf, len, "%s", env);
+        n = asprintf(&buf, "%s", env);
+        if (n < 0)
+           return NULL;
         return buf;
     }
 
-    snprintf(buf, len, "/tmp/xdg-runtime-mesa-%ld", (long)getuid());
+    n = asprintf(&buf, "/tmp/xdg-runtime-mesa-%ld", (long)getuid());
+    if (n < 0)
+       return NULL;
     mesa_logd("%s: XDG_RUNTIME_DIR not set; falling back to temp dir %s",
         __func__, buf);
     if (stat(buf, &st) == 0) {
@@ -130,11 +135,13 @@ get_or_create_user_temp_dir(char* buf, size_t len) {
         if (!S_ISDIR(st.st_mode)) {
             mesa_loge(
                 "%s: %s exists but is not a directory", __func__, buf);
+            free(buf);
             return NULL;
         }
         if (st.st_uid != uid) {
             mesa_loge(
                 "%s: %s exists but has wrong owner", __func__, buf);
+            free(buf);
             return NULL;
         }
 
@@ -144,6 +151,7 @@ get_or_create_user_temp_dir(char* buf, size_t len) {
         if (mkdir(buf, 0700) != 0) {
             mesa_loge("%s: mkdir %s failed: %s", __func__, buf,
                 strerror(errno));
+            free(buf);
             return NULL;
         }
 
@@ -151,6 +159,7 @@ get_or_create_user_temp_dir(char* buf, size_t len) {
     } else {
         mesa_loge("%s: stat %s failed: %s", __func__, buf, 
             strerror(errno));
+        free(buf);
         return NULL;
     }
 }
@@ -202,10 +211,11 @@ os_create_anonymous_file(int64_t size, const char *debug_name)
      */
 #if !(defined(__FreeBSD__) || DETECT_OS_ANDROID)
     if (fd == -1) {
-        char path[PATH_MAX];
+        char *path;
         char *name;
 
-        if (!get_or_create_user_temp_dir(path, sizeof(path))) {
+        path = get_or_create_user_temp_dir();
+        if (!path) {
             errno = ENOENT;
             return -1;
         }
@@ -214,11 +224,14 @@ os_create_anonymous_file(int64_t size, const char *debug_name)
             asprintf(&name, "%s/mesa-shared-%s-XXXXXX", path, debug_name);
         else
             asprintf(&name, "%s/mesa-shared-XXXXXX", path);
-        if (!name)
+        if (!name) {
+            free(path);
             return -1;
+        }
 
         fd = create_tmpfile_cloexec(name);
 
+        free(path);
         free(name);
     }
 #endif
-- 
GitLab


From 6205b3b78be15d5992c0684f27d65c6f713d171e Mon Sep 17 00:00:00 2001
From: Krzysztof Sobiecki <[email protected]>
Date: Mon, 12 Jan 2026 22:59:21 +0100
Subject: [PATCH 3/3] os: Add support for GNU/HURD compilation and use of dri
 swrast/llvmpipe.

---
 include/drm-uapi/drm.h                   | 8 ++++++--
 meson.build                              | 8 +++++---
 src/egl/drivers/dri2/platform_x11_dri3.c | 2 ++
 src/egl/drivers/dri2/platform_x11_dri3.h | 4 +++-
 src/egl/meson.build                      | 2 +-
 src/gallium/frontends/dri/meson.build    | 2 +-
 src/glx/glxclient.h                      | 3 +--
 src/glx/meson.build                      | 2 +-
 src/meson.build                          | 2 +-
 src/util/libsync.h                       | 7 +++++++
 src/x11/meson.build                      | 2 +-
 11 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/include/drm-uapi/drm.h b/include/drm-uapi/drm.h
index 4e4f7c2c39e4..ceb0f9ec8a53 100644
--- a/include/drm-uapi/drm.h
+++ b/include/drm-uapi/drm.h
@@ -41,11 +41,15 @@
 #include <asm/ioctl.h>
 typedef unsigned int drm_handle_t;
 
-#else /* One of the BSDs */
+#else /* One of the BSDs or GNU */
 
 #include <stdint.h>
-#include <sys/ioccom.h>
 #include <sys/types.h>
+#if defined(__GNU__)
+#include <sys/ioctl.h>
+#else
+#include <sys/ioccom.h>
+#endif
 typedef int8_t   __s8;
 typedef uint8_t  __u8;
 typedef int16_t  __s16;
diff --git a/meson.build b/meson.build
index 9a578ec8ef68..063f3dc3e976 100644
--- a/meson.build
+++ b/meson.build
@@ -395,6 +395,8 @@ elif ['windows', 'cygwin'].contains(host_machine.system())
   with_dri_platform = 'windows'
 elif system_has_kms_drm
   with_dri_platform = 'drm'
+elif host_machine.system() == 'gnu'
+  with_dri_platform = 'software'
 else
   # FIXME: haiku doesn't use dri, and xlib doesn't use dri, probably should
   # assert here that one of those cases has been met.
@@ -637,7 +639,7 @@ if with_vulkan_icd_dir == ''
   with_vulkan_icd_dir = join_paths(get_option('datadir'), 'vulkan/icd.d')
 endif
 
-with_dri2 = (with_dri or with_any_vk) and (with_dri_platform == 'drm' or with_dri_platform == 'apple')
+with_dri2 = (with_dri or with_any_vk) and (with_dri_platform == 'drm' or with_dri_platform == 'apple' or  with_dri_platform == 'software')
 
 if with_dri
   if with_glx == 'disabled' and not with_egl and not with_gbm
@@ -2174,7 +2176,7 @@ if with_platform_x11
       error('libdrm required for gallium video statetrackers when using x11')
     endif
   endif
-  if with_dri_platform == 'drm'
+  if with_dri_platform == 'drm' or with_dri_platform == 'software'
     dep_xcb_dri3 = dependency('xcb-dri3', version : dep_xcb_dri3_version)
     dep_xcb_present = dependency('xcb-present', version : dep_xcb_present_version)
     if (dep_xcb_dri3.version().version_compare('>= 1.17') and
@@ -2190,7 +2192,7 @@ if with_platform_x11
     dep_glproto = dependency('glproto', version : dep_glproto_version)
   endif
   if with_glx == 'dri'
-    if with_dri_platform == 'drm'
+    if with_dri_platform == 'drm' or with_dri_platform == 'software'
       if with_glx_direct
         dep_xxf86vm = dependency('xxf86vm')
       endif
diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c
index 894ae6d68927..5f03ffafd1bf 100644
--- a/src/egl/drivers/dri2/platform_x11_dri3.c
+++ b/src/egl/drivers/dri2/platform_x11_dri3.c
@@ -30,7 +30,9 @@
 #include <xcb/present.h>
 #include <xcb/xcb.h>
 
+#if defined(HAVE_LIBDRM)
 #include <xf86drm.h>
+#endif
 #include "drm-uapi/drm_fourcc.h"
 #include "util/macros.h"
 
diff --git a/src/egl/drivers/dri2/platform_x11_dri3.h b/src/egl/drivers/dri2/platform_x11_dri3.h
index c487188212ec..1d269ea4a08f 100644
--- a/src/egl/drivers/dri2/platform_x11_dri3.h
+++ b/src/egl/drivers/dri2/platform_x11_dri3.h
@@ -24,7 +24,9 @@
 #define EGL_X11_DRI3_INCLUDED
 
 #include "platform_x11.h"
-
+#if !defined(HAVE_LIBDRM)
+#include "loader_dri3_helper.h"
+#endif
 _EGL_DRIVER_TYPECAST(dri3_egl_surface, _EGLSurface, obj)
 
 struct dri3_egl_surface {
diff --git a/src/egl/meson.build b/src/egl/meson.build
index f9b0e348ad4a..9a27fae34293 100644
--- a/src/egl/meson.build
+++ b/src/egl/meson.build
@@ -108,7 +108,7 @@ if with_dri
     files_egl += files('drivers/dri2/platform_x11.c')
     incs_for_egl += inc_loader_x11
     link_for_egl += libloader_x11
-    if with_dri_platform == 'drm'
+    if with_dri_platform == 'drm' or with_dri_platform == 'software'
       files_egl += files('drivers/dri2/platform_x11_dri3.c')
     endif
     deps_for_egl += [dep_x11_xcb, dep_xcb_xrandr, dep_xcb_xfixes, dep_xcb_shm]
diff --git a/src/gallium/frontends/dri/meson.build b/src/gallium/frontends/dri/meson.build
index 6d54daebae05..8b939f861e0d 100644
--- a/src/gallium/frontends/dri/meson.build
+++ b/src/gallium/frontends/dri/meson.build
@@ -21,7 +21,7 @@ files_libdri = files(
 
 if with_platform_x11
   deps_for_libdri += dep_xcb
-  if with_dri_platform == 'drm'
+  if with_dri_platform == 'drm' or with_dri_platform == 'software'
     deps_for_libdri += [dep_xcb_dri3, dep_xcb_present, dep_xcb_sync,
                         dep_xshmfence, dep_xcb_xfixes]
     files_libdri += files('loader_dri3_helper.c')
diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h
index 678c98f380dc..9440d2ba019b 100644
--- a/src/glx/glxclient.h
+++ b/src/glx/glxclient.h
@@ -141,10 +141,9 @@ extern __GLXDRIdisplay *driwindowsCreateDisplay(Display * dpy);
 
 
 #if defined(GLX_DIRECT_RENDERING) && (!defined(GLX_USE_APPLEGL) || defined(GLX_USE_APPLE))
-#ifdef HAVE_LIBDRM
 struct glx_screen *dri3_create_screen(int screen, struct glx_display * priv, bool driver_name_is_inferred, bool *return_zink);
 void dri3_destroy_display(__GLXDRIdisplay * dpy);
-#endif
+
 
 bool dri2CheckSupport(Display *dpy);
 struct glx_screen *dri2CreateScreen(int screen, struct glx_display * priv, bool driver_name_is_inferred);
diff --git a/src/glx/meson.build b/src/glx/meson.build
index 28313f83a783..8ee877ea080f 100644
--- a/src/glx/meson.build
+++ b/src/glx/meson.build
@@ -58,7 +58,7 @@ extra_libs_libglx = []
 extra_deps_libgl = []
 extra_ld_args_libgl = []
 
-if with_dri_platform == 'drm'
+if with_dri_platform == 'drm' or with_dri_platform == 'software'
   files_libglx += files('dri3_glx.c', 'dri3_priv.h')
 endif
 
diff --git a/src/meson.build b/src/meson.build
index f27dae33631d..18c08279a9e2 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -153,7 +153,7 @@ endif
 if with_egl
   subdir('egl')
 endif
-if with_gallium and with_gbm
+if with_gallium
   if with_glx == 'dri' or with_platform_x11 or with_platform_xcb
     subdir('gallium/targets/dril')
   endif
diff --git a/src/util/libsync.h b/src/util/libsync.h
index 0acf778446d6..b22b75a11bde 100644
--- a/src/util/libsync.h
+++ b/src/util/libsync.h
@@ -34,6 +34,7 @@
 #include <stdbool.h>
 #include <stdint.h>
 #include <string.h>
+#include <sys/types.h>
 #include <sys/ioctl.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -86,6 +87,9 @@ struct sync_merge_data {
 	uint32_t	flags;
 	uint32_t	pad;
 };
+#if defined(__GNU__)
+#define _IOT_sync_merge_data _IOT(_IOTS(struct sync_merge_data), 1, 0, 0, 0, 0)
+#endif
 
 struct sync_fence_info {
 	char obj_name[32];
@@ -104,6 +108,9 @@ struct sync_file_info {
 
 	uint64_t	sync_fence_info;
 };
+#if defined(__GNU__)
+#define _IOT_sync_file_info _IOT(_IOTS(struct sync_file_info), 1, 0, 0, 0, 0)
+#endif
 
 #define SYNC_IOC_MAGIC		'>'
 #define SYNC_IOC_MERGE		_IOWR(SYNC_IOC_MAGIC, 3, struct sync_merge_data)
diff --git a/src/x11/meson.build b/src/x11/meson.build
index 3829ea7b88e6..292a167089ee 100644
--- a/src/x11/meson.build
+++ b/src/x11/meson.build
@@ -7,7 +7,7 @@ loader_x11_files = files(
   'x11_display.c',
 )
 
-if with_dri_platform == 'drm'
+if with_dri_platform == 'drm' or with_dri_platform == 'software'
   loader_x11_files += files('x11_dri3.c')
 endif
 
-- 
GitLab

--- a/debian/changelog	2026-01-07 13:26:39.000000000 +0100
+++ b/debian/changelog	2026-01-21 17:23:44.000000000 +0100
@@ -1,3 +1,10 @@
+mesa (25.3.3-1.2) UNRELEASED; urgency=medium
+
+  * Port mesa to softpipe/llvmpipe, according to Krzysztof Sobiecki (@sobcas),
+    See https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39277.
+
+ -- Svante Signell <[email protected]>  Wed, 21 Jan 2026 17:23:39 +0100
+
 mesa (25.3.3-1) unstable; urgency=medium
 
   [ Timo Aaltonen ]
diff --git a/debian/control.in b/debian/control.in
index d85d555..fd706f8 100644
--- a/debian/control.in
+++ b/debian/control.in
@@ -213,7 +213,7 @@ Description: Developer documentation for Mesa
 
 Package: mesa-libgallium
 Section: libs
-Architecture: linux-any
+Architecture: any
 Depends: ${misc:Depends}, ${shlibs:Depends}
 Pre-Depends: ${misc:Pre-Depends}
 Multi-Arch: same
@@ -243,7 +243,7 @@ Description: Mesa TensorFlow Lite external delegate
 
 Package: mesa-vulkan-drivers
 Section: libs
-Architecture: @LLVM_ARCHS@
+Architecture: linux-any
 Pre-Depends: ${misc:Pre-Depends}
 Depends: libvulkan1, ${misc:Depends}, ${shlibs:Depends}
 Provides: vulkan-icd
--- a/debian/control.in	2026-01-22 10:50:20.000000000 +0100
+++ b/debian/control.in	2026-01-22 11:01:27.000000000 +0100
@@ -17,7 +17,7 @@
  libclang-cpp@LLVM_VERSION@-dev [@LLVM_ARCHS@],
  libclc-@LLVM_VERSION@ [@LLVM_ARCHS@],
  libclc-@LLVM_VERSION@-dev [@LLVM_ARCHS@],
- libdrm-dev (>= 2.4.125-1),
+ libdrm-dev (>= 2.4.125-1) [!hurd-any],
  libelf-dev [@LLVM_ARCHS@],
  libexpat1-dev,
  libflatbuffers-dev [linux-arm64],
diff --git a/debian/libglx-mesa0.symbols.hurd b/debian/libglx-mesa0.symbols.hurd
index 0a33c71..0fa82e2 100644
--- a/debian/libglx-mesa0.symbols.hurd
+++ b/debian/libglx-mesa0.symbols.hurd
@@ -1,6 +1,9 @@
 libGLX_mesa.so.0 libglx-mesa0
+ MesaGLInteropGLXExportObject@Base 25.3.3-1
+ MesaGLInteropGLXFlushObjects@Base 25.3.3-1
+ MesaGLInteropGLXQueryDeviceInfo@Base 25.3.3-1
  __glx_Main@Base 17.0.0~
- glAreTexturesResidentEXT@Base 0
- glDeleteTexturesEXT@Base 0
- glGenTexturesEXT@Base 0
- glIsTextureEXT@Base 0
+#MISSING: 25.3.3-1# glAreTexturesResidentEXT@Base 0
+#MISSING: 25.3.3-1# glDeleteTexturesEXT@Base 0
+#MISSING: 25.3.3-1# glGenTexturesEXT@Base 0
+#MISSING: 25.3.3-1# glIsTextureEXT@Base 0
--- a/debian/rules.orig	2026-01-07 13:26:10.000000000 +0100
+++ b/debian/rules	2026-01-21 17:17:53.000000000 +0100
@@ -46,18 +46,23 @@
 GALLIUM_DRIVERS = softpipe
 VULKAN_DRIVERS =
 VULKAN_LAYERS =
-
+GLVND = enabled
+TOOLS = "drm-shim"
 confflags_TEFLON = -Dteflon=false
 
-LLVM_ARCHS     = amd64 arm64 armel armhf i386 loong64 mips64el powerpc ppc64 ppc64el riscv64 s390x sparc64 x32
+LLVM_ARCHS     = amd64 arm64 armel armhf i386 loong64 mips64el powerpc ppc64 ppc64el riscv64 s390x sparc64 x32 hurd-i385 hurd-amd64
 RUSTICL_ARCHS  = amd64 arm64 armel armhf i386 loong64 mips64el powerpc ppc64 ppc64el riscv64 s390x x32
 NVK_ARCHS      = amd64 arm64 armhf i386 ppc64 riscv64 x32
 VALGRIND_ARCHS = amd64 arm64 armhf i386 mips64el powerpc ppc64 ppc64el s390x
 
 # hurd doesn't do direct rendering
 ifeq ($(DEB_HOST_ARCH_OS), hurd)
-  confflags_DIRECT_RENDERING = -Dglx-direct=false
+  confflags_DIRECT_RENDERING = -Dglx-direct=true
+  GALLIUM_DRIVERS += llvmpipe
+  GLVND = enabled
+  TOOLS = ""
   confflags_GBM = -Dgbm=disabled
+  VULKAN_DRIVERS =
 else
   # Non-Linux ports lack epoll, so wayland isn't ready yet:
   # https://gitlab.freedesktop.org/wayland/wayland/-/issues/72
@@ -175,10 +180,10 @@
 	-Dvulkan-drivers="[$(VULKAN_DRIVERS_LIST)]" \
 	-Dvulkan-layers="[$(VULKAN_LAYERS_LIST)]" \
 	-Dvulkan-manifest-per-architecture=false \
-	-Dglvnd=enabled \
+	-Dglvnd=$(GLVND) \
 	-Db_ndebug=true \
-	-Dbuild-tests=true \
-	-Dtools=drm-shim \
+	-Dbuild-tests=false \
+	-Dtools=$(TOOLS) \
 	$(confflags_DIRECT_RENDERING) \
 	$(confflags_GBM) \
 	$(confflags_GALLIUM) \

Reply via email to