diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-25 01:48:37 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-25 01:48:37 -0400 |
| commit | 93769b1e19b4ce2cf1738d72e600adc5a9ef315b (patch) | |
| tree | 4414e33bdfc1c8770f52572bcfd627cc830397ec /tools/guest-diag/scan2.c | |
| parent | 13c07f7585c71bb75870d2a25475b4c9401a57fc (diff) | |
| download | open-iov-93769b1e19b4ce2cf1738d72e600adc5a9ef315b.tar.gz open-iov-93769b1e19b4ce2cf1738d72e600adc5a9ef315b.zip | |
gsp_sema_service: add content rescue for unmapped push-buffer pool VAs
- Add expected_sem_payload tracking to svc_channel for CE channels
- Implement svc_rescue_push_page() to scan guest RAM for push with
expected semaphore release when VA translation fails
- Add svc_init_expected_payload() to initialize expected payload from pool
- Add rate-limited logging of distinct stalled VAs (svc_log_stalled_va)
- Advance expected_sem_payload on successful push decode
- Pushes SEMA_MAP_MAX to 65536, SVC_PIN_SLOTS to 32768 for scale
Diffstat (limited to 'tools/guest-diag/scan2.c')
| -rw-r--r-- | tools/guest-diag/scan2.c | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/tools/guest-diag/scan2.c b/tools/guest-diag/scan2.c new file mode 100644 index 0000000..6220038 --- /dev/null +++ b/tools/guest-diag/scan2.c @@ -0,0 +1,88 @@ +/* scan2.c - find qwords whose value points into a /dev/nvidia* mapping of + the target process, and report the u32 stored there (semaphore hunt). + usage: scan2 PID [max_print] */ +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <fcntl.h> +#include <unistd.h> + +#define MAXR 4096 +static struct { uint64_t lo, hi; char name[64]; } nv[MAXR], wr[MAXR]; +static int nnv, nwr; + +static int in_nv(uint64_t a, int *idx) +{ + for (int i = 0; i < nnv; i++) + if (a >= nv[i].lo && a < nv[i].hi) { if (idx) *idx = i; return 1; } + return 0; +} + +static void load_maps(int pid) +{ + char path[64], line[1024]; + snprintf(path, sizeof path, "/proc/%d/maps", pid); + FILE *f = fopen(path, "r"); + if (!f) { perror("maps"); exit(1); } + while (fgets(line, sizeof line, f)) { + uint64_t lo, hi; + char perms[16], name[128] = ""; + if (sscanf(line, "%lx-%lx %15s %*s %*s %*s %127[^\n]", &lo, &hi, perms, name) < 3) + continue; + if (strchr(perms, 'w') && nwr < MAXR) { wr[nwr].lo = lo; wr[nwr].hi = hi; nwr++; } + if (strstr(line, "nvidia") && nnv < MAXR) { + nv[nnv].lo = lo; nv[nnv].hi = hi; + snprintf(nv[nnv].name, sizeof nv[nnv].name, "%s", name); + nnv++; + } + } + fclose(f); +} + +int main(int argc, char **argv) +{ + if (argc < 2) { fprintf(stderr, "usage: scan2 PID [max_print]\n"); return 1; } + int pid = atoi(argv[1]); + int maxp = argc > 2 ? atoi(argv[2]) : 200; + load_maps(pid); + printf("writable=%d nvidia=%d\n", nwr, nnv); + + char mp[64]; + snprintf(mp, sizeof mp, "/proc/%d/mem", pid); + int fd = open(mp, O_RDONLY); + if (fd < 0) { perror("mem"); return 1; } + + size_t CH = 4 << 20; + uint8_t *buf = malloc(CH + 64); + int printed = 0, scanned = 0; + for (int r = 0; r < nwr; r++) { + uint64_t a = wr[r].lo; + while (a < wr[r].hi) { + size_t n = (size_t)((wr[r].hi - a) < CH ? (wr[r].hi - a) : CH); + ssize_t got = pread(fd, buf, n, (off_t)a); + if (got <= 0) { + if (n > (256u << 10)) { n = 256u << 10; continue; } + a += 4096; continue; + } + if ((size_t)got < n) n = got; + n -= n % 8; + uint64_t *w = (uint64_t *)buf; + for (size_t i = 0; i < n / 8; i++, scanned++) { + uint64_t v = w[i]; + int idx; + if (!in_nv(v, &idx)) continue; + uint32_t val = 0; + if (pread(fd, &val, 4, (off_t)v) != 4) continue; + if (val > 0x100000) continue; + if (printed < maxp) + printf("at 0x%lx -> 0x%lx (%s) val=%u\n", a + i * 8, v, nv[idx].name, val); + printed++; + } + a += n; + } + } + printf("scanned=%d printed=%d\n", scanned, printed); + return 0; +}
\ No newline at end of file |
