diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-26 16:37:08 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-26 16:37:08 -0400 |
| commit | add223299e9bab04c66025c18d750feef936ffd1 (patch) | |
| tree | bb87ca035c6be8be8e542986cfd33a54204fa021 /kernel/gsp_sema_service.c | |
| parent | 140b9463d9a1c09b144ac1512331b25cec86d2a4 (diff) | |
| download | open-iov-add223299e9bab04c66025c18d750feef936ffd1.tar.gz open-iov-add223299e9bab04c66025c18d750feef936ffd1.zip | |
vgsp-sema: SESSION 139 GR fill: reject float-shaped scan words + scan the deduped word-48 page
Two evidence-based corrections to the launch-data candidate scan:
1. Float-shape filter at all four scan sites (the three page scans and
svc_gr_scan_cand): a word whose f32 exponent byte is in ~[0x6c..0x8f]
(2^-19..2^16) is a plausible float scalar, not a device VA - device
VAs (2^28..2^47) as f32 land in subnormal/tiny exponents. Root
evidence (r789): the launch param page carries the kernel's scalar
arguments (0.2f, 640.0f, 480.0f at +0x630 - the 640x480 viewport) and
0x43f00000 = 480.0f was the fill's ONLY candidate - an unresolvable
"arg base=0x43f00000" that drove the fail-closed diagnostic and the
demand-loop noise for days. After the filter: 'fill cand n=0'
(r790) - no false candidates, no false demands.
2. The bank-page scan now covers word 48: the QMD pointer-region pair can
name a 4K page that also carries the program pair (r788: ptr[0]
0xdff0febc00 word 34 shares its page with prog 0xdff0feb900), and
svc_gr_page_note dedupes the first note (the program's, word 48), so
the old 32..47-even filter left that page unscanned.
The remaining wall is content, not wiring: with the false candidates
removed the launch still refuses (n_data=0 vs min 16) because no scanned
source holds real device pointers - the param page holds scalars, the
QMD window page reads zero (its content would arrive via the driver's
i2m/LOAD_INLINE_DATA writes whose payloads are not in the push), and the
inline payload is the driver's zero stub. This matches the SESSION 130
zero-buffer finding and leaves the never-queued i2m copies (or the real
GPU path) as the only content sources.
Diffstat (limited to 'kernel/gsp_sema_service.c')
| -rw-r--r-- | kernel/gsp_sema_service.c | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 4c54e0b..cc508dc 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -21613,6 +21613,14 @@ static void svc_gr_scan_cand(u64 *wins, u32 *n_cand, const u8 *data, u32 bytes) if (v < 0x10000000ULL || v >= (1ULL << 47) || (v & 3)) continue; + /* SESSION 139: float-shaped words are scalars, not device VAs + * (see the scan-site note; r789's 480.0f = 0x43f00000). */ + { + u32 fexp = (u32)(v >> 23) & 0xffu; + + if (fexp >= 0x6cu && fexp <= 0x8fu) + continue; + } wv = v & ~(u64)(SEMA_PAGE_SIZE - 1); for (w = 0; w < *n_cand; w++) if (wins[w] == wv) @@ -22137,6 +22145,23 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu, if (v < 0x10000000ULL || v >= (1ULL << 47) || (v & 3)) continue; + /* + * SESSION 139: reject float-shaped words. The launch + * param page carries f32 scalars (r789: 0.2f, 640.0f, + * 480.0f at +0x630) whose bit patterns pass the + * VA-shape filter (0x43f00000 = 480.0f) and were the + * fill's only candidate - an unresolvable "arg base". + * A plausible f32 magnitude has an exponent byte in + * ~[0x6c..0x8f] (2^-19..2^16); device VAs (2^28..2^47) + * as f32 land in subnormal/tiny exponents, so this + * does not reject pointers. + */ + { + u32 fexp = (u32)(v >> 23) & 0xffu; + + if (fexp >= 0x6cu && fexp <= 0x8fu) + continue; + } wv = v & ~(u64)(SEMA_PAGE_SIZE - 1); for (w = 0; w < n_cand; w++) if (wins[w] == wv) @@ -22192,6 +22217,23 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu, if (v < 0x10000000ULL || v >= (1ULL << 47) || (v & 3)) continue; + /* + * SESSION 139: reject float-shaped words. The launch + * param page carries f32 scalars (r789: 0.2f, 640.0f, + * 480.0f at +0x630) whose bit patterns pass the + * VA-shape filter (0x43f00000 = 480.0f) and were the + * fill's only candidate - an unresolvable "arg base". + * A plausible f32 magnitude has an exponent byte in + * ~[0x6c..0x8f] (2^-19..2^16); device VAs (2^28..2^47) + * as f32 land in subnormal/tiny exponents, so this + * does not reject pointers. + */ + { + u32 fexp = (u32)(v >> 23) & 0xffu; + + if (fexp >= 0x6cu && fexp <= 0x8fu) + continue; + } wv = v & ~(u64)(SEMA_PAGE_SIZE - 1); for (w = 0; w < n_cand; w++) if (wins[w] == wv) @@ -22206,7 +22248,11 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu, const u8 *page; u32 k; - if (pp->qmd_word < 32 || pp->qmd_word > 47 || + /* SESSION 139: include word 48 (see the r788 finding: the + * word-34 pointer dedupes into the program's 4K page whose + * entry carries qmd_word=48; the old 32..47-even filter left + * that page unscanned). */ + if (pp->qmd_word < 32 || pp->qmd_word > 48 || (pp->qmd_word & 1) || !pp->pa) continue; kind = (pp->ap == SVC_APERTURE_FB) ? SVC_APERTURE_FB : @@ -22229,6 +22275,23 @@ static void svc_gr_data_fill(struct nv_vgpu_device *vgpu, if (v < 0x10000000ULL || v >= (1ULL << 47) || (v & 3)) continue; + /* + * SESSION 139: reject float-shaped words. The launch + * param page carries f32 scalars (r789: 0.2f, 640.0f, + * 480.0f at +0x630) whose bit patterns pass the + * VA-shape filter (0x43f00000 = 480.0f) and were the + * fill's only candidate - an unresolvable "arg base". + * A plausible f32 magnitude has an exponent byte in + * ~[0x6c..0x8f] (2^-19..2^16); device VAs (2^28..2^47) + * as f32 land in subnormal/tiny exponents, so this + * does not reject pointers. + */ + { + u32 fexp = (u32)(v >> 23) & 0xffu; + + if (fexp >= 0x6cu && fexp <= 0x8fu) + continue; + } wv = v & ~(u64)(SEMA_PAGE_SIZE - 1); for (w = 0; w < n_cand; w++) if (wins[w] == wv) |
