summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c65
1 files changed, 60 insertions, 5 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 5c638a5..12c6afd 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -24714,7 +24714,7 @@ static bool svc_fb_userd_pristine_scan(struct nv_vgpu_device *vgpu,
if (!base || !ch->gpfifo_entries)
return false;
- lim = min_t(u64, svc_fb_shadow_size(vgpu), 0x2000000ULL);
+ lim = min_t(u64, svc_fb_shadow_size(vgpu), 0x20000000ULL);
for (off = 0; off + 0x100 <= lim; off += 0x1000) {
u32 hp, hg;
@@ -25488,10 +25488,18 @@ ce_fb_scan:
* unwritten hole is not a window
* failure for a CE channel.
*/
- if (!eva && !elen && ch->engine_type)
+ if (!eva && !elen &&
+ (ch->engine_type ||
+ (ch->h_object & 0xfffff000u) ==
+ 0xbeef0000u))
continue;
- if (!eva || !svc_gr_entry_win_ok(
- ch->gpfifo_va, eva) ||
+ if (!eva ||
+ (!svc_gr_entry_win_ok(
+ ch->gpfifo_va, eva) &&
+ !((ch->h_object & 0xfffff000u) ==
+ 0xbeef0000u &&
+ eva >= SEMA_VA_LO &&
+ eva < SEMA_VA_HI)) ||
elen < 4 || elen > 0x100000) {
ok = false;
rck = (int)k;
@@ -28592,8 +28600,13 @@ static bool svc_gr_ram_userd_scan(struct nv_vgpu_device *vgpu,
eva = ((u64)(a1 & 0xff) << 32) |
(u64)(a0 & 0xfffffffc);
elen = ((a1 >> 10) & 0x1fffff) << 2;
+ if (!eva && !elen &&
+ (ch->h_object & 0xfffff000u) == 0xbeef0000u)
+ continue;
if (!eva ||
- !svc_gr_entry_win_ok(ch->gpfifo_va, eva) ||
+ (!svc_gr_entry_win_ok(ch->gpfifo_va, eva) &&
+ !((ch->h_object & 0xfffff000u) == 0xbeef0000u &&
+ eva >= SEMA_VA_LO && eva < SEMA_VA_HI)) ||
elen < 4 || elen > 0x100000) {
ok = false;
break;
@@ -40856,6 +40869,48 @@ static void svc_pump_channels(struct nv_vgpu_device *vgpu)
rrc = svc_lookup(vgpu, ch->gpfifo_va, &ring_pa, &ring_ap);
+ /*
+ * r1682 (CONT.393): the GL client's GR kernel ring lives in
+ * the RM low aperture (0x4000000..0xfffffff), an identity-
+ * mapped kernel window (GPU VA == guest PA). No published
+ * client VAS directory maps it, so the walk - and every
+ * ring-gated USERD discovery below - fails with ring_pa=0.
+ * For the 0xbeef0000 GR family, prove the ring content with a
+ * raw PA read (PA==VA) and adopt that identity translation.
+ * Re-run every pass: the ring VA churns, so a new VA simply
+ * re-proves on the next turn (the stale pin is keyed to the
+ * old VA and is ignored).
+ */
+ if (rrc && !ch->engine_type &&
+ (ch->h_object & 0xfffff000u) == 0xbeef0000u &&
+ ch->gpfifo_va >= SVC_LOW_REL_VA_LO &&
+ ch->gpfifo_va < 0x10000000ULL) {
+ u8 e[2 * SVC_GPFIFO_ENTRY_SIZE];
+ u32 e0, e1;
+
+ if (!svc_read(vgpu, ch->gpfifo_va, e, sizeof(e))) {
+ memcpy(&e0, e, 4);
+ memcpy(&e1, e + 4, 4);
+ if ((e0 || e1) &&
+ svc_gr_entry_plausible(ch, e0, e1)) {
+ svc_pin_store(ch->gpfifo_va,
+ ch->gpfifo_va,
+ SVC_APERTURE_SYS);
+ svc_lat_store(ch->gpfifo_va,
+ ch->gpfifo_va,
+ SVC_APERTURE_SYS);
+ ring_pa = ch->gpfifo_va;
+ ring_ap = SVC_APERTURE_SYS;
+ rrc = 0;
+ if (gsp_sema_dbg)
+ pr_info("vgsp-sema: low-ring identity h=0x%x va=0x%llx\n",
+ ch->h_object,
+ (unsigned long long)
+ ch->gpfifo_va);
+ }
+ }
+ }
+
if (!rrc)
svc_pb_pair(vgpu, ch);
if (!rrc && ring_pa) {