summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/inject_maps.sh
blob: 3f018dbb2e813b34ddbc06507d6e9309aee820e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/bin/bash
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2026 Open-IOV contributors
# inject_maps.sh - while cdt runs, collect pushbuffer/ring VAs from the host
# dmesg (sema-chan entry logs) plus channel GPFIFO ring VAs, translate them
# through the guest's own pagemap, and inject the VA->PA pairs into the
# service's learned map with sema_map_add.
#
# Usage: tools/guest-diag/inject_maps.sh [iterations]
set -u
cd "$(dirname "$0")/../.."
ITERS="${1:-20}"
LOG=/tmp/inject_maps.log
: > "$LOG"

map_add() {   # map_add <va-hex> <pa-hex>
    echo "0x$1,0x$2" | sudo tee /sys/module/vgsp/parameters/sema_map_add >/dev/null 2>&1
}

inject_list() {  # inject_list <va...>
    local vas="$*" chunk out n=0
    [ -n "${vas// /}" ] || return 0
    # chunk to keep the guest agent output under its size cap
    chunk=""
    for va in $vas; do
        chunk="$chunk $va"
        if [ "$(echo "$chunk" | wc -w)" -ge 12 ]; then
            out=$(tools/guest-diag/pmap_va.sh cdt $chunk 2>/dev/null | grep '^VA=')
            echo "$out" | while read -r line; do
                local v p
                v=$(echo "$line" | sed -n 's/.*VA=0x\([0-9a-f]*\).*/\1/p')
                p=$(echo "$line" | sed -n 's/.*present=1.*PA=0x\([0-9a-f]*\).*/\1/p')
                [ -n "$v" ] && [ -n "$p" ] && { map_add "$v" "$p"; echo "add 0x$v -> 0x$p" >> "$LOG"; }
            done
            chunk=""
        fi
    done
    if [ -n "${chunk// /}" ]; then
        out=$(tools/guest-diag/pmap_va.sh cdt $chunk 2>/dev/null | grep '^VA=')
        echo "$out" | while read -r line; do
            local v p
            v=$(echo "$line" | sed -n 's/.*VA=0x\([0-9a-f]*\).*/\1/p')
            p=$(echo "$line" | sed -n 's/.*present=1.*PA=0x\([0-9a-f]*\).*/\1/p')
            [ -n "$v" ] && [ -n "$p" ] && { map_add "$v" "$p"; echo "add 0x$v -> 0x$p" >> "$LOG"; }
        done
    fi
}

i=0
while [ "$i" -lt "$ITERS" ]; do
    i=$((i+1))
    PID=$(timeout 15 ./scripts/vgpu_vm.py exec --timeout 10 'pgrep -x cdt | head -1' 2>/dev/null | tail -1)
    [ -n "$PID" ] || { echo "cdt gone at iter $i" >> "$LOG"; break; }

    RINGS=$(sudo dmesg | grep -aoE "gpfifo=0x[0-9a-f]+" | grep -aoE "0x[0-9a-f]+" | sort -u | tr '\n' ' ')
    RINGVAS=$(sudo dmesg | grep -aoE "entry\[[0-9]+\] raw=[0-9a-f]+ va=0x[0-9a-f]+ len=[0-9]+" | grep -aoE "va=0x[0-9a-f]+" | grep -aoE "0x[0-9a-f]+" | sort -u | tr '\n' ' ')

    echo "== iter $i: rings=[$RINGS] entries=[$RINGVAS]" >> "$LOG"
    inject_list $RINGS
    inject_list $RINGVAS

    DONE=$(sudo dmesg | grep -aoE "gpfifo done=[0-9]+ nomap=[0-9]+" | tail -1)
    TAIL=$(timeout 15 ./scripts/vgpu_vm.py exec --timeout 10 'tail -1 /tmp/cdt.out' 2>/dev/null | tail -1)
    echo "   $DONE | cdt: $TAIL" >> "$LOG"
    case "$TAIL" in
        *cuCtxCreate*FAILED*|*ALL*|*cuMemAlloc*) echo "cdt moved on: $TAIL" >> "$LOG"; break;;
    esac
    sleep 10
done
echo "INJECT_DONE" >> "$LOG"