commit d2eb87c0674a281d1d3854b9c4fba0b7df215077
Author: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date:   Tue Jul 1 00:31:45 2025 +0200

    console-client vga: Avoid using optimized string operations on vga_videomem
    
    The VGA boards may not like AVX-whatnot-optimized 512B accesses. E.g.
    qemu does not support it and raises an invalid opcode trap.

diff --git a/console-client/Makefile b/console-client/Makefile
index 711258c7..4972da4b 100644
--- a/console-client/Makefile
+++ b/console-client/Makefile
@@ -61,6 +61,7 @@ modules = vga pc_kbd generic_speaker pc_mouse current_vcs
 
 vga-CPPFLAGS = -DDEFAULT_VGA_FONT_DIR=\"${datadir}/hurd/\"
 fb-CPPFLAGS = -DDEFAULT_VGA_FONT_DIR=\"${datadir}/hurd/\"
+vga-support-CFLAGS = -minline-all-stringops
 vga.so.$(hurd-version): $(patsubst %.c,%_pic.o,$(VGA_SO_SRCS))
 pc_kbd.so.$(hurd-version): $(patsubst %.c,%_pic.o,$(PC_KBD_SO_SRCS)) \
 	kdioctlServer_pic.o
diff --git a/console-client/fb.c b/console-client/fb.c
index c93a6ae0..9c8d2680 100644
--- a/console-client/fb.c
+++ b/console-client/fb.c
@@ -228,7 +228,7 @@ fb_init(void)
     return err;
 
   /* Clear screen */
-  memset (vga_videomem, 0, fb_width * fb_height * fb_bpp/8);
+  vga_memset (vga_videomem, 0, fb_width * fb_height * fb_bpp/8);
   return 0;
 }
 
@@ -454,26 +454,26 @@ fb_display_scroll (void *handle, int delta)
 
   if (delta > 0)
     {
-      memmove (vga_videomem, vga_videomem + fb_bpp/8 * pixels,
-	       fb_bpp/8 * disp->width * (disp->height - delta*fb_hc));
+      vga_memmove (vga_videomem, vga_videomem + fb_bpp/8 * pixels,
+		    fb_bpp/8 * disp->width * (disp->height - delta*fb_hc));
     }
   else
     {
-      memmove (vga_videomem + fb_bpp/8 * pixels, vga_videomem,
-	       fb_bpp/8 * disp->width * (disp->height + delta*fb_hc));
+      vga_memmove (vga_videomem + fb_bpp/8 * pixels, vga_videomem,
+		    fb_bpp/8 * disp->width * (disp->height + delta*fb_hc));
     }
 
   if (delta > 0)
     {
       r = disp->height/fb_hc - delta;
-      memmove (&disp->refmatrix[0][0], &disp->refmatrix[0][0] + chars,
-	       sizeof (struct fbchr) * disp->width/fb_wc * r);
+      vga_memmove (&disp->refmatrix[0][0], &disp->refmatrix[0][0] + chars,
+		    sizeof (struct fbchr) * disp->width/fb_wc * r);
     }
   else
     {
       r = 0;
-      memmove (&disp->refmatrix[0][0] + chars, &disp->refmatrix[0][0],
-	       sizeof (struct fbchr) * disp->width/fb_wc * (disp->height/fb_hc + delta));
+      vga_memmove (&disp->refmatrix[0][0] + chars, &disp->refmatrix[0][0],
+		    sizeof (struct fbchr) * disp->width/fb_wc * (disp->height/fb_hc + delta));
     }
 
   return 0;
diff --git a/console-client/vga-support.c b/console-client/vga-support.c
index 32ede46d..c145cac4 100644
--- a/console-client/vga-support.c
+++ b/console-client/vga-support.c
@@ -27,6 +27,7 @@
 #include <sys/types.h>
 #include <string.h>
 #include <stdlib.h>
+#include <stdint.h>
 
 #include "vga-hw.h"
 #include "vga-support.h"
@@ -147,13 +148,13 @@ vga_init (void)
   outb (VGA_GFX_MODE_ADDR, VGA_GFX_ADDR_REG);
   outb (VGA_GFX_MODE_HOSTOE, VGA_GFX_DATA_REG);
 
-  memcpy (vga_state->videomem, vga_videomem, 2 * 80 * 25);
+  vga_memcpy (vga_state->videomem, vga_videomem, 2 * 80 * 25);
   vga_read_font_buffer (0, 0, vga_state->fontmem,
 			2 * VGA_FONT_SIZE * VGA_FONT_HEIGHT);
 
   /* 80 cols, 25 rows, two bytes per cell and twice because with lower
      max scan line we get more lines on the screen.  */
-  memset (vga_videomem, 0, 80 * 25 * 2 * 2);
+  vga_memset (vga_videomem, 0, 80 * 25 * 2 * 2);
 
   return 0;
 }
@@ -167,7 +168,7 @@ vga_fini (void)
   /* Recover the saved state.  */
   vga_write_font_buffer (0, 0, vga_state->fontmem,
 			 2 * VGA_FONT_SIZE * VGA_FONT_HEIGHT);
-  memcpy (vga_videomem, vga_state->videomem, 2 * 80 * 25);
+  vga_memcpy (vga_videomem, vga_state->videomem, 2 * 80 * 25);
 
   /* Restore the registers.  */
   outb (VGA_SEQ_CLOCK_MODE_ADDR, VGA_SEQ_ADDR_REG);
@@ -210,6 +211,46 @@ vga_fini (void)
   munmap (vga_videomem, VGA_VIDEO_MEM_LENGTH);
 }
 
+
+/* VGA boards may not like AVX-whatnot-optimized 512B accesses, so use
+   non-optimized versions of string operations for vga_videomem.  */
+
+/* Non-optimized memset for vga_videomem */
+void vga_memset (void *__restrict _s, int c, size_t n)
+{
+  uint8_t * __restrict s = _s;
+  size_t i;
+
+  for (i = 0; i < n; i++)
+    s[i] = c;
+}
+
+/* Non-optimized memcpy for vga_videomem */
+void vga_memcpy (void *__restrict _dest, const void *__restrict _src, size_t n)
+{
+  uint8_t * __restrict dest = _dest;
+  const uint8_t * __restrict src = _src;
+  size_t i;
+
+  for (i = 0; i < n; i++)
+    dest[i] = src[i];
+}
+
+/* Non-optimized memmove for vga_videomem */
+void vga_memmove (void *_dest, const void *_src, size_t n)
+{
+  uint8_t * dest = _dest;
+  const uint8_t * src = _src;
+  size_t i;
+
+  if (dest <= src)
+    for (i = 0; i < n; i++)
+      dest[i] = src[i];
+  else
+    for (i = 0; i < n; i++)
+      dest[n-1-i] = src[n-1-i];
+}
+
 
 /* Access the font buffer BUFFER, starting from glyph INDEX, and
    either read DATALEN bytes into DATA (if WRITE is 0) or write
@@ -249,9 +290,9 @@ vga_read_write_font_buffer (int write, int buffer, int index,
   outb (VGA_GFX_MISC_B8TOBF, VGA_GFX_DATA_REG);
 
   if (write)
-    memcpy (vga_videomem + offset, data, datalen);    
+    vga_memcpy (vga_videomem + offset, data, datalen);
   else
-    memcpy (data, vga_videomem + offset, datalen);
+    vga_memcpy (data, vga_videomem + offset, datalen);
 
   /* Restore sequencer and graphic register values.  */
   outb (VGA_SEQ_MAP_ADDR, VGA_SEQ_ADDR_REG);
diff --git a/console-client/vga-support.h b/console-client/vga-support.h
index 17c0b5fd..c109bc6c 100644
--- a/console-client/vga-support.h
+++ b/console-client/vga-support.h
@@ -41,6 +41,15 @@ error_t vga_init (void);
    hardware access.  */
 void vga_fini (void);
 
+/* Non-optimized memset for vga_videomem */
+void vga_memset (void *__restrict s, int c, size_t n);
+
+/* Non-optimized memcpy for vga_videomem */
+void vga_memcpy (void *__restrict dest, const void *__restrict src, size_t n);
+
+/* Non-optimized memmove for vga_videomem */
+void vga_memmove (void *dest, const void *src, size_t n);
+
 /* Write DATALEN bytes from DATA to the font buffer BUFFER, starting
    from glyph index.  */
 void vga_write_font_buffer (int buffer, int index,
diff --git a/console-client/vga.c b/console-client/vga.c
index ec4f39dd..00860304 100644
--- a/console-client/vga.c
+++ b/console-client/vga.c
@@ -485,14 +485,14 @@ vga_display_scroll (void *handle, int delta)
 
   if (delta > 0)
     {
-      memmove (vga_videomem, vga_videomem + 2 * count,
-	       2 * disp->width * (disp->height - delta));
+      vga_memmove (vga_videomem, vga_videomem + 2 * count,
+		    2 * disp->width * (disp->height - delta));
       refpos = &disp->refmatrix[0][0];
     }
   else
     {
-      memmove (vga_videomem + 2 * count, vga_videomem,
-	       2 * disp->width * (disp->height + delta));
+      vga_memmove (vga_videomem + 2 * count, vga_videomem,
+		    2 * disp->width * (disp->height + delta));
       refpos = &disp->refmatrix[disp->height + delta][0];
     }
   
