diff options
| -rw-r--r-- | kernel/gsp_sema_service.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index fa0fe65..ac1849f 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -3872,6 +3872,8 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) bool unreadable = svc_read_va_trusted(vgpu, va, pb, len) != 0; + bool injected = false; + bool allow_ops = (ch->engine_type != 0); /* * A resolved buffer that does not start @@ -3879,12 +3881,28 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) * (content-scanned map; observed firmware * and kernel data pages). Handle it like * an unreadable push so the content rescue - * can find the real page. + * can find the real page. Exception: a + * host-injected translation is verified + * truth, and real CE release pushes start + * with an INC_METHOD whose address is not + * zero (observed 0x200381c0, addr 0x700): + * decode those release-only instead of + * discarding them, so the client's + * tracking-semaphore releases still apply. */ - if (!unreadable && - !svc_method_stream_plausible(pb, len)) { - svc.false_trans++; - unreadable = true; + if (!unreadable) { + u64 ipa; + int iap; + + injected = (svc_ipin_lookup(va, &ipa, + &iap) == 0); + if (!svc_method_stream_plausible(pb, len)) { + svc.false_trans++; + if (injected) + allow_ops = false; + else + unreadable = true; + } } if (!unreadable) { @@ -3902,7 +3920,7 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu) svc_decode_stream(vgpu, pb, len, 0, - ch->engine_type != 0, + allow_ops, ch->h_object, ch->engine_type, va); |
