summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/guest-diag/semfix_watch.py22
1 files changed, 19 insertions, 3 deletions
diff --git a/tools/guest-diag/semfix_watch.py b/tools/guest-diag/semfix_watch.py
index 0ded7c2..93302cc 100644
--- a/tools/guest-diag/semfix_watch.py
+++ b/tools/guest-diag/semfix_watch.py
@@ -137,7 +137,9 @@ def resolve_pushbuffer(q, sem):
if not chunk:
break
words += chunk
- for M in dict.fromkeys(w for w in words if is_kern(w)):
+ cands = list(dict.fromkeys(w for w in words if is_kern(w)))
+ # Chain 1: value is the channel manager; +8 pushbuffer, +8 rm_mem.
+ for M in cands:
pb = q.read64(M + 8)
if not pb or not is_kern(pb[0]):
continue
@@ -152,9 +154,23 @@ def resolve_pushbuffer(q, sem):
if not cpu:
continue
gpa = q.gva2gpa(cpu)
- if not gpa:
+ if gpa:
+ return gpu_vas, cpu, gpa
+ # Chain 2: value is the pushbuffer itself; +8 = rm_mem.
+ for V in cands:
+ mem = q.read64(V + 8)
+ if not mem or not is_kern(mem[0]):
+ continue
+ g5 = q.read64(mem[0] + 0x38)
+ if not g5 or not (PUSHBUF_VA_LO <= g5[0] < PUSHBUF_VA_HI):
continue
- return gpu_vas, cpu, gpa
+ g4 = q.read64(mem[0] + 0x30)
+ cpu = g4[0] if g4 and is_kern(g4[0]) else None
+ if not cpu:
+ continue
+ gpa = q.gva2gpa(cpu)
+ if gpa:
+ return [g5[0]], cpu, gpa
return [], None, None