summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 5483b4f..d8ce5ee 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -6036,6 +6036,32 @@ static int svc_op_translate(struct nv_vgpu_device *vgpu, u64 va, u64 *addr,
svc.op_tr_src = 1;
return 0;
}
+ /*
+ * SESSION 153-CONT-43: below-floor VAs (the driver's ABI/MMIO
+ * mapping window, e.g. the X server's screen VA 0x120400000)
+ * MUST resolve through the guest's own published page tables
+ * before the content-scanned map. The scan can discover false
+ * identity pairs for these VA numbers (a page-table page whose
+ * PTE values look like VA->PA records), and a below-floor fill
+ * that resolves outside vidmem is refused by the LOWFILL guard:
+ * observed live `LOWFILL-REFUSED va=0x120458c00 pa=0x120458c00
+ * ap=1` repeating with the X server's screen repaint stuck ~44
+ * rows in (done=52800 rc=-2) - the identity pair shadowed the
+ * big-page vidmem translation the walk resolves (pa=0x200000).
+ * Walk-first keeps the guests' page tables authoritative for
+ * this region; everything above the floor keeps the historical
+ * order (pins and the scanned map are the client-VA workhorses
+ * there).
+ */
+ if (va < SVC_VAS_FLOOR) {
+ if (!svc_walk_vaspaces(vgpu, va & ~0xfffULL, &pa, &ap)) {
+ *addr = pa + (va & 0xfff);
+ *aperture = (ap == SVC_APERTURE_FB) ?
+ CE_APERTURE_VID : CE_APERTURE_SYS;
+ svc.op_tr_src = 6;
+ return 0;
+ }
+ }
if (!svc_map_lookup(va, &pa)) {
*addr = pa;
*aperture = CE_APERTURE_SYS;
@@ -6400,6 +6426,37 @@ static int svc_fill(struct nv_vgpu_device *vgpu, u64 addr, u64 value, u32 elem,
done_out);
}
+/*
+ * SESSION 153-CONT-43: resolve a below-floor fill destination through the
+ * guest's published page directories before the pin/ledger/map chain.
+ *
+ * Below SVC_VAS_FLOOR the driver maps its ABI/MMIO window (the X server's
+ * screen VA 0x120400000 family, the client pushbuffer region, ...). The
+ * content-scanned map and the landing ledger are heuristics built for the
+ * above-floor client VAs; for these low VA numbers a page-table page
+ * discovered by the scanner can hold a false identity pair (va == pa), and
+ * the LOWFILL guard then refuses every fill that the pair shadows - the
+ * observed X server repaint death (`LOWFILL-REFUSED va=0x120458c00
+ * pa=0x120458c00`, fill done=52800 rc=-2, replayed ~15 Hz forever). The
+ * guest's page tables are the truth for this region: resolve through them
+ * first. Returns true when a translation was applied.
+ */
+static bool svc_fill_floor_walk(struct nv_vgpu_device *vgpu, u64 va0,
+ u64 *addr, u32 *aperture)
+{
+ u64 wpa = 0;
+ int wap = SVC_APERTURE_SYS;
+
+ if (va0 >= SVC_VAS_FLOOR)
+ return false;
+ if (svc_walk_vaspaces(vgpu, va0 & ~0xfffULL, &wpa, &wap))
+ return false;
+ *addr = wpa + (va0 & 0xfff);
+ *aperture = (wap == SVC_APERTURE_FB) ? CE_APERTURE_VID
+ : CE_APERTURE_SYS;
+ return true;
+}
+
static int svc_fill_1d(struct nv_vgpu_device *vgpu, u64 addr, u64 value, u32 elem,
u32 count, u32 phys, u32 aperture, u64 *done_out)
{
@@ -6459,6 +6516,27 @@ static int svc_fill_1d(struct nv_vgpu_device *vgpu, u64 addr, u64 value, u32 ele
pr_info("sema-lowfill-window va=0x%llx -> fb offset 0x%llx (vidmem window convention) elem=%u count=%u value=0x%llx\n",
va0, addr, elem, count, value);
}
+ } else if (svc_fill_floor_walk(vgpu, va0, &addr, &aperture)) {
+ /*
+ * SESSION 153-CONT-43: below-floor VA (the driver's
+ * ABI/MMIO mapping window). The guest's published
+ * page directory is the truth there; a pin or a stale
+ * landing-table entry can hold a false identity pair
+ * (va==pa), observed live as the X server's screen
+ * repaint dying ~44 rows in (`LOWFILL-REFUSED
+ * va=0x120458c00 pa=0x120458c00` repeating at
+ * ~15 Hz, the screen frozen on a stale fill
+ * artifact). The walk resolves the same VA through
+ * the guest's 2 MB big page to vidmem
+ * (pa=0x200000+off), which is what the driver meant.
+ */
+ prov = 6;
+ if (svc_lowfill_log < 64) {
+ svc_lowfill_log++;
+ pr_info("sema-lowfill-walk va=0x%llx -> pa=0x%llx ap=%u elem=%u count=%u value=0x%llx\n",
+ va0, addr, aperture, elem, count,
+ value);
+ }
} else if (svc_vas_has(addr)) {
shadow = true;
} else if (!svc_pin_lookup_any(addr, &pa, &aper)) {