From 19e61f2dddadf9ea7f17fbcdc23ed43d4d40ff72 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Wed, 30 Sep 2026 06:55:49 -0400 Subject: sema-svc: decode GMMU PDE/PTE addresses with the real encoding (addr>>12 in bits 32:8/53:8) The mask-and-keep decode dropped the left shift by 12, so every page-table child pointer and leaf resolved 16x too low and no GMMU walk ever produced a translation (walks_ok=0 on every boot). Verified against live page tables: directory entry 0x2020a -> table 0x202000, leaf 0x0600000000760001 (aperture VID, KIND=6) -> PA 0x7600000. --- kernel/gsp_sema_service.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'kernel') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 018e28c..04716a2 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -678,11 +678,14 @@ static int svc_map_lookup(u64 gpu_va, u64 *pa); * big half -> PT_BIG [20:16] * small half -> PT_4K [20:12] * - * A directory entry carries the aperture in bits 2:1 (1 = video memory, - * 2 = system coherent, 3 = system non-coherent) and the child address in bits - * 53:8 at 4 KB granularity (bits 53:4 at 256 B granularity in the big half of - * a dual entry). Bit 0 of a leaf entry is VALID; bit 0 of a directory entry is - * IS_PTE, so a set bit means the level terminates in a page here. + * A directory entry carries the aperture in bits 2:1 (0 = invalid, 1 = video + * memory, 2 = system coherent, 3 = system non-coherent) and the child address + * (>> 12) in bits 32:8 for video memory and bits 53:8 for system memory. The + * PD0 dual entry is 16 bytes: the big half (offset 0) is either a 2 MB leaf + * PTE (bit 0 = IS_PTE = 1, regular PTE encoding) or, with bit 0 clear, a + * pointer for 64 KB pages; the small half (offset 8) points to a 4 KB page + * table (bit 0 clear). Bit 0 of a leaf entry is VALID; on a single directory + * entry it is IS_PDE (0 = points to the next level). */ #define SVC_MMU_VA_BITS 49 #define SVC_MMU_AP_VID 1 /* in directory entries */ @@ -693,11 +696,21 @@ static int svc_map_lookup(u64 gpu_va, u64 *pa); #define SVC_MMU_PTE_AP_SYS_COH 2 #define SVC_MMU_PTE_AP_SYS_NC 3 +/* + * Address field decode for NV_MMU_VER2 (Turing+) PDEs and PTEs: the encoder + * stores `address >> 12` in bits 32:8 for video memory and bits 53:8 for + * system memory. The previous mask-and-keep decode omitted the *left* shift + * by 12, so every child pointer and leaf came out 16x too small (0x20200 + * instead of 0x202000) and no walk ever found a mapping (walks_ok=0 on every + * boot). Verified against live page tables: a directory entry 0x2020a + * resolves to table 0x202000 and the leaf 0x0600000000760001 (aperture VID, + * KIND=6 GENERIC_MEMORY) resolves to PA 0x7600000. + */ static u64 svc_pte_addr(u64 e, bool vidmem) { if (vidmem) - return (e & 0x00000001FFFFFFFF00ULL); - return (e & 0x003FFFFFFFFF00ULL); + return ((e >> 8) & 0x0000000001FFFFFFULL) << 12; + return ((e >> 8) & 0x00003FFFFFFFFFFFULL) << 12; } /* Return the file/buffer selector (SVC_APERTURE_*) for an entry bit-field. */ -- cgit v1.2.3