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 | 6fdbe6219f540f23070949648d09c9fd86029d79 (patch) | |
| tree | fc0cf9dc1a40d389c95917ddb542056745c6cf74 /tools/guest-diag/scan3.c | |
| parent | 93431bdd896d9e6d9a25bebef0fb1af308dd64cd (diff) | |
| download | open-iov-6fdbe6219f540f23070949648d09c9fd86029d79.tar.gz open-iov-6fdbe6219f540f23070949648d09c9fd86029d79.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/scan3.c')
| -rw-r--r-- | tools/guest-diag/scan3.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/tools/guest-diag/scan3.c b/tools/guest-diag/scan3.c new file mode 100644 index 0000000..94f6a42 --- /dev/null +++ b/tools/guest-diag/scan3.c @@ -0,0 +1,77 @@ +/* scan3.c - scan all writable memory of a process for qwords equal to any + of the given 64-bit needles; print every hit address. + usage: scan3 PID 0xNEEDLE [0xNEEDLE ...] */ +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> +#include <fcntl.h> +#include <unistd.h> + +#define MAXR 4096 +#define MAXN 64 +static struct { uint64_t lo, hi; } wr[MAXR]; +static int nwr; +static uint64_t needle[MAXN]; +static int nn; + +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]; + if (sscanf(line, "%lx-%lx %15s", &lo, &hi, perms) < 3) continue; + if (strchr(perms, 'w') && nwr < MAXR) { wr[nwr].lo = lo; wr[nwr].hi = hi; nwr++; } + } + fclose(f); +} + +int main(int argc, char **argv) +{ + if (argc < 3) { fprintf(stderr, "usage: scan3 PID 0xNEEDLE [...]\n"); return 1; } + int pid = atoi(argv[1]); + for (int i = 2; i < argc && nn < MAXN; i++) + needle[nn++] = strtoull(argv[i], 0, 16); + load_maps(pid); + printf("writable=%d needles=%d\n", nwr, nn); + + 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 hits = 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++) { + uint64_t v = w[i]; + for (int k = 0; k < nn; k++) { + if (v == needle[k]) { + printf("hit 0x%lx = 0x%lx\n", a + i * 8, v); + hits++; + } + } + } + a += n; + } + } + printf("hits=%d\n", hits); + return 0; +}
\ No newline at end of file |
