summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/scan3.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-25 01:48:37 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-25 01:48:37 -0400
commit6fdbe6219f540f23070949648d09c9fd86029d79 (patch)
treefc0cf9dc1a40d389c95917ddb542056745c6cf74 /tools/guest-diag/scan3.c
parent93431bdd896d9e6d9a25bebef0fb1af308dd64cd (diff)
downloadopen-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.c77
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