From 8b7c1178a285b4a85413a5e87b428f003775e81d Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Tue, 20 Oct 2026 17:23:12 -0400 Subject: sema: r375 read-after-write authority - the landing table wins for device-VA copy sources (top-level and per page), and a resolver answer is recorded so launch/read paths converge; the engine output can no longer be read through a different page/aperture than it was written --- kernel/gsp_sema_service.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index 08547fe..c5bc043 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -5663,6 +5663,24 @@ static int svc_copy(struct nv_vgpu_device *vgpu, u64 dst, u64 src, size_t total, if (svc_vas_has(src)) { src_shadow = true; + } else if (src_orig >= SVC_VAS_FLOOR && + !svc_ledger_lookup(src, &pa, &aper)) { + /* + * r375 read-after-write authority: the landing table + * records where every write of this VA landed (writes + * store it, fresh pins repair it). A reader MUST read + * exactly that page or the engine's output is invisible + * (the sum=0 class). The walk/pin sources can answer + * differently - e.g. the same numeric pa in a different + * aperture - so the table wins for device VAs; only a + * VA with no recorded landing falls through to the + * resolver below. + */ + src = pa; + src_aperture = (aper == SVC_APERTURE_FB) ? + CE_APERTURE_VID : CE_APERTURE_SYS; + src_prov = 1; + src_virt = true; } else if (svc_op_translate(vgpu, src, &pa, &aper)) { u64 lpa = 0; u32 lap = 0; @@ -5692,6 +5710,16 @@ static int svc_copy(struct nv_vgpu_device *vgpu, u64 dst, u64 src, size_t total, src_aperture = aper; src_prov = svc.op_tr_src; src_virt = true; + /* + * r375: record the resolver's answer so the next + * reader (and the launch paths) converge on it. + */ + if (src_orig >= SVC_VAS_FLOOR) + svc_ledger_store(src_orig, + pa & ~(u64)(SEMA_PAGE_SIZE - 1), + (aper == CE_APERTURE_VID) ? + SVC_APERTURE_FB : + SVC_APERTURE_SYS); } } @@ -6018,7 +6046,19 @@ static int svc_copy(struct nv_vgpu_device *vgpu, u64 dst, u64 src, size_t total, u64 lpa = 0; u32 lap = 0; - if (svc_op_translate(vgpu, src_orig + o, &pa, &aper)) { + /* + * r375: the landing table is the read-after-write + * authority for device VAs (see the top-level src + * resolve). Per page, the table wins whenever it has + * an entry; the resolver below only answers a VA the + * table has never seen. + */ + if (src_orig >= SVC_VAS_FLOOR && + !svc_ledger_lookup(src_orig + o, &lpa, &lap)) { + pa = lpa; + aper = (lap == SVC_APERTURE_FB) ? + CE_APERTURE_VID : CE_APERTURE_SYS; + } else if (svc_op_translate(vgpu, src_orig + o, &pa, &aper)) { /* * m180 unification: a per-page resolution miss * must not fail the whole copy when the unified -- cgit v1.2.3