diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-30 06:55:49 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-30 06:55:49 -0400 |
| commit | 19e61f2dddadf9ea7f17fbcdc23ed43d4d40ff72 (patch) | |
| tree | 1dfe11efa2a4c911fc1126a782aa9c5d98fe891c /kernel | |
| parent | 54f1e10dab293307a51ecb53bb2962d08a01a193 (diff) | |
| download | open-iov-19e61f2dddadf9ea7f17fbcdc23ed43d4d40ff72.tar.gz open-iov-19e61f2dddadf9ea7f17fbcdc23ed43d4d40ff72.zip | |
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.
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_sema_service.c | 27 |
1 files changed, 20 insertions, 7 deletions
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. */ |
