summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rwxr-xr-xtools/guest-diag/cycle-r1780.sh17
-rw-r--r--tools/guest-diag/gz_pbuf.c154
-rw-r--r--tools/guest-diag/sdl_cap.c10
3 files changed, 175 insertions, 6 deletions
diff --git a/tools/guest-diag/cycle-r1780.sh b/tools/guest-diag/cycle-r1780.sh
index 23cf0d1..0acab1c 100755
--- a/tools/guest-diag/cycle-r1780.sh
+++ b/tools/guest-diag/cycle-r1780.sh
@@ -16,7 +16,7 @@ ARGV_FILE="${INSMOD_PARAMS:-$HERE/params-r1780.txt}"
BACKUP="$REPO/backups/evidence-20261002-victory/r1780"
DISK="${GUEST_DISK:-/home/rmcore/.local/libvf.io/kernel/linux.qcow2}"
MDEV_PARENT="0000:01:00.0"
-MDEV_TYPE="nvidia-nvidia-vgpu-turing"
+MDEV_TYPE="${MDEV_TYPE:-}"
RUNDIR="$HERE/run"
QEMU_SCRIPT="$HERE/launch_qemu_r1780.run.sh"
mkdir -p "$RUNDIR" "$BACKUP"
@@ -72,8 +72,7 @@ if [ -d /sys/module/vgsp ]; then
fi
echo "[cycle $TAG] load VFIO/mdev prerequisites"
-sudo modprobe vfio vfio_iommu_type1 vfio_pci mdev 2>/dev/null || true
-sudo modprobe vfio_iommu_type1 2>/dev/null || true
+for m in vfio vfio_iommu_type1 vfio_pci mdev; do sudo modprobe "$m" 2>/dev/null || true; done
echo "[cycle $TAG] stop nvidia-persistenced, power/control=on"
sudo systemctl stop nvidia-persistenced 2>/dev/null || true
@@ -84,6 +83,18 @@ echo "[cycle $TAG] insmod $(basename "$MODULE")"
# shellcheck disable=SC2046
sudo insmod "$MODULE" $(cat "$ARGV_FILE")
+for i in $(seq 1 40); do
+ [ -d "/sys/class/mdev_bus/$MDEV_PARENT/mdev_supported_types" ] && break
+ sleep 0.5
+done
+if [ -z "$MDEV_TYPE" ]; then
+ MDEV_TYPE=$(ls "/sys/class/mdev_bus/$MDEV_PARENT/mdev_supported_types" 2>/dev/null | grep -m1 'vgpu-turing-2g$' || true)
+fi
+if [ -z "$MDEV_TYPE" ]; then
+ MDEV_TYPE=$(ls "/sys/class/mdev_bus/$MDEV_PARENT/mdev_supported_types" 2>/dev/null | grep -m1 'vgpu-turing$' || true)
+fi
+if [ -z "$MDEV_TYPE" ]; then echo "FATAL: no vgpu-turing mdev type under $MDEV_PARENT"; ls "/sys/class/mdev_bus/$MDEV_PARENT/mdev_supported_types" 2>/dev/null; exit 1; fi
+echo "[cycle $TAG] mdev type $MDEV_TYPE"
U=$(uuidgen)
echo "$U" | sudo tee "/sys/class/mdev_bus/$MDEV_PARENT/mdev_supported_types/$MDEV_TYPE/create" >/dev/null
if [ ! -d "/sys/bus/mdev/devices/$U" ]; then echo "FATAL: mdev create failed"; exit 1; fi
diff --git a/tools/guest-diag/gz_pbuf.c b/tools/guest-diag/gz_pbuf.c
new file mode 100644
index 0000000..5c03732
--- /dev/null
+++ b/tools/guest-diag/gz_pbuf.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: BSD-3-Clause
+// gz_pbuf.c - LD_PRELOAD shim that gives an SDL2 GL client a GLX pbuffer
+// context instead of a window context. The pbuffer path is proven on the
+// emulated vGPU (gl_frames); the window drawable path wedges the X server.
+// Build: gcc -shared -fPIC -O2 -o gz_pbuf.so gz_pbuf.c -lGL -lX11 -ldl
+
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <GL/glx.h>
+#include <GL/gl.h>
+
+typedef struct SDL_Window SDL_Window;
+
+static GLXContext g_ctx;
+static GLXPbuffer g_pb;
+static Display *g_dpy;
+static int g_w, g_h;
+static void *g_win;
+
+static void *(*real_GetWindowSize)(SDL_Window *, int *, int *);
+static int (*real_MakeCurrent)(SDL_Window *, void *);
+static void (*real_SwapWindow)(SDL_Window *);
+
+static void resolve(void)
+{
+ if (!real_GetWindowSize)
+ real_GetWindowSize = dlsym(RTLD_NEXT, "SDL_GetWindowSize");
+ if (!real_MakeCurrent)
+ real_MakeCurrent = dlsym(RTLD_NEXT, "SDL_GL_MakeCurrent");
+ if (!real_SwapWindow)
+ real_SwapWindow = dlsym(RTLD_NEXT, "SDL_GL_SwapWindow");
+}
+
+static int make_pb(int w, int h)
+{
+ static int attribs[] = {
+ GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT,
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8,
+ GLX_ALPHA_SIZE, 8,
+ GLX_DOUBLEBUFFER, False,
+ None
+ };
+ GLXFBConfig *fb;
+ int n = 0, scr;
+
+ if (!g_dpy)
+ g_dpy = XOpenDisplay(NULL);
+ if (!g_dpy)
+ return 0;
+ scr = DefaultScreen(g_dpy);
+ fb = glXChooseFBConfig(g_dpy, scr, attribs, &n);
+ if (!fb || n < 1)
+ return 0;
+ g_pb = glXCreatePbuffer(g_dpy, fb[0], (int[]){
+ GLX_PBUFFER_WIDTH, w, GLX_PBUFFER_HEIGHT, h, None });
+ if (!g_pb)
+ return 0;
+ g_ctx = glXCreateNewContext(g_dpy, fb[0], GLX_RGBA_TYPE, NULL, True);
+ if (!g_ctx) {
+ glXDestroyPbuffer(g_dpy, g_pb);
+ g_pb = 0;
+ return 0;
+ }
+ g_w = w;
+ g_h = h;
+ return 1;
+}
+
+void *SDL_GL_CreateContext(SDL_Window *win)
+{
+ int w = 640, h = 480;
+ const char *ew, *eh;
+ resolve();
+ ew = getenv("GZPBUF_W"); eh = getenv("GZPBUF_H");
+ if (ew && eh) { w = atoi(ew); h = atoi(eh); }
+ else if (real_GetWindowSize) {
+ real_GetWindowSize(win, &w, &h);
+ if (w <= 0 || h <= 0) { w = 640; h = 480; }
+ }
+ if (!make_pb(w, h)) {
+ fprintf(stderr, "[gzpbuf] pbuffer create failed\n");
+ return NULL;
+ }
+ g_win = win;
+ glXMakeCurrent(g_dpy, g_pb, g_ctx);
+ fprintf(stderr, "[gzpbuf] pbuffer %dx%d ctx=%p\n", g_w, g_h, (void *)g_ctx);
+ return (void *)g_ctx;
+}
+
+int SDL_GL_MakeCurrent(SDL_Window *win, void *ctx)
+{
+ resolve();
+ if (ctx && g_pb) {
+ glXMakeCurrent(g_dpy, g_pb, g_ctx);
+ return 0;
+ }
+ if (real_MakeCurrent)
+ return real_MakeCurrent(win, ctx);
+ return 0;
+}
+
+void SDL_GL_SwapWindow(SDL_Window *win)
+{
+ (void)win;
+ glFinish();
+}
+
+void SDL_GL_GetDrawableSize(SDL_Window *win, int *w, int *h)
+{
+ resolve();
+ if (g_w > 0 && g_h > 0) {
+ if (w) *w = g_w;
+ if (h) *h = g_h;
+ return;
+ }
+ if (real_GetWindowSize) {
+ real_GetWindowSize(win, w, h);
+ return;
+ }
+ if (w) *w = 640;
+ if (h) *h = 480;
+}
+
+void SDL_GL_GetWindowSize(SDL_Window *win, int *w, int *h)
+{
+ SDL_GL_GetDrawableSize(win, w, h);
+}
+
+void *SDL_GL_GetCurrentContext(void)
+{
+ return (void *)g_ctx;
+}
+
+SDL_Window *SDL_GL_GetCurrentWindow(void)
+{
+ return (SDL_Window *)g_win;
+}
+
+void SDL_GL_DeleteContext(void *ctx)
+{
+ if (g_ctx && (!ctx || ctx == (void *)g_ctx)) {
+ glXMakeCurrent(g_dpy, None, NULL);
+ glXDestroyContext(g_dpy, g_ctx);
+ if (g_pb)
+ glXDestroyPbuffer(g_dpy, g_pb);
+ g_ctx = NULL;
+ g_pb = 0;
+ }
+}
diff --git a/tools/guest-diag/sdl_cap.c b/tools/guest-diag/sdl_cap.c
index 23c83ab..5b9c096 100644
--- a/tools/guest-diag/sdl_cap.c
+++ b/tools/guest-diag/sdl_cap.c
@@ -87,10 +87,12 @@ __attribute__((constructor)) static void cap_init(void)
if (h)
real_glReadPixels = dlsym(h, "glReadPixels");
}
- fprintf(stderr, "[gzcap] init path=%s present=%p updwin=%p swap=%p read=%p gros=%p\n",
- p, (void *)real_RenderPresent, (void *)real_UpdateWindowSurface,
+ fprintf(stderr, "[gzcap] init pid=%d path=%s present=%p updwin=%p swap=%p read=%p gros=%p\n",
+ (int)getpid(), p, (void *)real_RenderPresent, (void *)real_UpdateWindowSurface,
(void *)real_GL_SwapWindow, (void *)real_RenderReadPixels,
(void *)real_GetRendererOutputSize, (void *)real_glReadPixels);
+ if (!real_glReadPixels && !real_RenderReadPixels)
+ return;
cap_fp = fopen(p, "wb");
if (!cap_fp)
return;
@@ -192,7 +194,9 @@ void SDL_GL_SwapWindow(SDL_Window *win)
static size_t gbufsz;
if (!hit++)
- fprintf(stderr, "[gzcap] hook GLSwapWindow\n");
+ fprintf(stderr, "[gzcap] hook GLSwapWindow pid=%d fp=%p read=%p gros=%p\n",
+ (int)getpid(), (void *)cap_fp, (void *)real_glReadPixels,
+ (void *)real_GL_GetDrawableSize);
if (cap_fp && !cap_stop && real_glReadPixels && real_GL_GetDrawableSize) {
int w = 0, h = 0;