summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-01 20:52:37 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-01 20:52:37 -0400
commite3feaa8f237150735caef56254568e0a0563021a (patch)
tree4dae10011e776f0d7603ab1e635a4c89bc0c1e08 /kernel
parentb3fb77cc3c201c9cde1a8b7e87cbfedd0a49194a (diff)
downloadopen-iov-e3feaa8f237150735caef56254568e0a0563021a.tar.gz
open-iov-e3feaa8f237150735caef56254568e0a0563021a.zip
gsp-phys: encode the GPFIFO GET field correctly so the pushbuffer fetch uses the mapped VA
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_phys_booter.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 6f509e1..247dcff 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -5881,7 +5881,11 @@ static int gsp_phys_rmcall_stage4(void __iomem *bar0)
slot = gpput;
/*
- * e0: GET = pushbuffer GPU VA >> 2 in bits 31:2, FETCH/NO_CONTEXT_
+ * e0: bits 31:2 hold the GET field, which itself is (fetch address
+ * >> 2); the engine reconstructs (field << 2) = (e0 & ~3), so for a
+ * 4 KB-aligned pushbuffer VA the raw word is LO32(VA) with bits 1:0
+ * clear. Storing LO32(VA) >> 2 here shifts a second time in the
+ * engine (the 0x40000 fetch for pb VA 0x101000). FETCH/NO_CONTEXT_
* SWITCH 0 (class/cl906f.h:136-142); e1: GET_HI 7:0 = the VA high byte
* and LENGTH 30:10 in dwords, exactly the reference RM's own submission
* (mem_utils_gm107.c:1858-1868: get = pbGpuVA + offset, NvU64_HI32(get)
@@ -5889,7 +5893,11 @@ static int gsp_phys_rmcall_stage4(void __iomem *bar0)
* The engine translates this VA through the channel PDB built in
* gsp_phys_rmcall_pdb_build.
*/
- e0 = (u32)(GSP_PHYS_RMCALL_VA_PB >> 2) & 0x3fffffffu;
+ BUILD_BUG_ON(GSP_PHYS_RMCALL_VA_PB & 3);
+ e0 = (u32)GSP_PHYS_RMCALL_VA_PB & ~3u;
+ if (unlikely(e0 != (u32)((GSP_PHYS_RMCALL_VA_PB >> 2) << 2)))
+ pr_err("gsp-phys-boot: rm-call: GPFIFO GET encode mismatch: e0=0x%08x decodes to fetch 0x%llx, expected pb VA 0x%llx\n",
+ e0, (u64)(e0 & ~3u), (u64)GSP_PHYS_RMCALL_VA_PB);
e1 = (u32)((GSP_PHYS_RMCALL_VA_PB >> 32) & 0xffu) | (words << 10);
put_unaligned_le32(e0, (u8 *)ring_va + slot * 8);
put_unaligned_le32(e1, (u8 *)ring_va + slot * 8 + 4);