From 93769b1e19b4ce2cf1738d72e600adc5a9ef315b Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Fri, 25 Sep 2026 01:48:37 -0400 Subject: 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 --- tools/guest-diag/scan3.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 tools/guest-diag/scan3.c (limited to 'tools/guest-diag/scan3.c') 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 +#include +#include +#include +#include +#include + +#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 -- cgit v1.2.3