# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2026 Open-IOV contributors # gdb script: read the device arch/impl and test the membar-WAR descriptor # lookup (FUN_0035a4d0) live on the parked cdt. # # Run #5: hook idx=3 (FUN_005d7e70, "membar_war_bug2022401") returned 999, # whose only source is `FUN_0035a4d0(0x13, *(u32*)(dev+0xc50), # *(u32*)(dev+0xc54)) == NULL` or the ucode load failing. This script prints # the device state's +0xc50/+0xc54 the way the failing code reads them, calls # the lookup with those values, and scans nearby (arch, rev) pairs to show # which exist in libcuda's WAR-microcode table. # # Run: sudo gdb -p -batch -x /tmp/invd.py import gdb out = gdb.execute("info proc mappings", to_string=True) base = None for line in out.splitlines(): if "libcuda" in line and "r-xp" in line: f = line.split() base = int(f[0], 16) - int(f[3], 16) break print("BASE=0x%x" % (base or 0)) if base is None: raise SystemExit gdb.execute("set pagination off") gdb.execute("set confirm off") def r64(a): try: return int(gdb.parse_and_eval("*(unsigned long *)0x%x" % a)) & 0xffffffffffffffff except Exception as e: return None def r32(a): try: return int(gdb.parse_and_eval("*(unsigned int *)0x%x" % a)) & 0xffffffff except Exception as e: return None dev = r64(base + 0x44120c8) print("dev array [0]=0x%x" % (dev or 0)) stack = [] if dev: for off in (0x0, 0x8, 0x10, 0x40): v = r64(dev + off) print(" dev+0x%x = 0x%x" % (off, v or 0)) cand = r64(dev + 8) if cand: st = r64(cand + 0x40) print(" [dev+8]+0x40 = 0x%x" % (st or 0)) if st: q = r64(st + 0xc50) print(" state+0xc50 = 0x%x (arch=%s impl=%s)" % (q or 0, (q or 0) & 0xffffffff, (q or 0) >> 32)) print(" state+0xc54 = 0x%x" % (r32(st + 0xc54) or 0)) f = base + 0x25a4d0 def lookup(chip, rev): try: v = int(gdb.parse_and_eval("((void*(*)(long,int,int))0x%x)(0x13,%d,%d)" % (f, chip, rev))) & 0xffffffffffffffff return v except Exception as e: print(" call_fail chip=0x%x rev=0x%x: %s" % (chip, rev, e)) return None if dev and r64(dev + 8) and r64(r64(dev + 8) + 0x40): st = r64(r64(dev + 8) + 0x40) chip = r32(st + 0xc50) rev = r32(st + 0xc54) v = lookup(chip, rev) print("lookup(0x13,0x%x,0x%x) = 0x%x" % (chip, rev, v or 0)) if v: print(" desc+0x10=0x%x desc+0x18=0x%x" % (r64(v + 0x10) or 0, r64(v + 0x18) or 0)) print("scan (chip,rev) -> descriptor:") for chip in (0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0x160, 0x170): for rev in range(0, 6): v = lookup(chip, rev) if v: print(" chip=0x%x rev=0x%x -> 0x%x size=0x%x" % (chip, rev, v, r64(v + 0x18) or 0)) try: gdb.execute("detach") except Exception: pass