summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_sema_service.c55
1 files changed, 45 insertions, 10 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c
index 9a765c8..5f69f40 100644
--- a/kernel/gsp_sema_service.c
+++ b/kernel/gsp_sema_service.c
@@ -1898,6 +1898,35 @@ struct svc_push_state {
/* ------------------------------------------------------------------ */
/*
+ * Translate a CE operand VA. Host-pinned translations (injected truth) are
+ * consulted before the content-scanned map: the CE push buffer and the UVM
+ * semaphore pool only exist in the pin tables (their VAs have no entry in
+ * the merged map), so map-only translation dropped every push-data copy
+ * (observed: `memcopy dst=0x204020 src=0x12000007c rc=-2` for UVM's inline
+ * notifier writes, and the same for the HtoD payload copy). Returns the CE
+ * aperture for the translated address.
+ */
+static int svc_op_translate(struct nv_vgpu_device *vgpu, u64 va, u64 *addr,
+ u32 *aperture)
+{
+ u64 pa = 0;
+ int ap = SVC_APERTURE_SYS;
+
+ if (!svc_pin_lookup_any(va, &pa, &ap)) {
+ *addr = pa;
+ *aperture = (ap == SVC_APERTURE_FB) ? CE_APERTURE_VID :
+ CE_APERTURE_SYS;
+ return 0;
+ }
+ if (!svc_map_lookup(va, &pa)) {
+ *addr = pa;
+ *aperture = CE_APERTURE_SYS;
+ return 0;
+ }
+ return -ENOENT;
+}
+
+/*
* Write `count` elements of `value` (element size `elem`) starting at
* `addr`, in vidmem or guest RAM depending on the aperture DST_TYPE
* selected. Returns 0 on success.
@@ -1919,13 +1948,15 @@ static int svc_fill(struct nv_vgpu_device *vgpu, u64 addr, u64 value, u32 elem,
memcpy(pat, &value, elem);
if (!phys) {
- /* Virtual destination: translate through the VA->PA map. */
+ /* Virtual destination: translate through the pinned map first,
+ * then the VA->PA map. */
u64 pa;
+ u32 aper;
- if (svc_map_lookup(addr, &pa))
+ if (svc_op_translate(vgpu, addr, &pa, &aper))
return -ENOENT;
addr = pa;
- aperture = CE_APERTURE_SYS;
+ aperture = aper;
}
if (aperture == CE_APERTURE_VID) {
@@ -1971,19 +2002,21 @@ static int svc_copy(struct nv_vgpu_device *vgpu, u64 dst, u64 src, size_t total,
if (!dst_phys) {
u64 pa;
+ u32 aper;
- if (svc_map_lookup(dst, &pa))
+ if (svc_op_translate(vgpu, dst, &pa, &aper))
return -ENOENT;
dst = pa;
- dst_aperture = CE_APERTURE_SYS;
+ dst_aperture = aper;
}
if (!src_phys) {
u64 pa;
+ u32 aper;
- if (svc_map_lookup(src, &pa))
+ if (svc_op_translate(vgpu, src, &pa, &aper))
return -ENOENT;
src = pa;
- src_aperture = CE_APERTURE_SYS;
+ src_aperture = aper;
}
for (o = 0; o < total; ) {
@@ -2046,11 +2079,13 @@ static void svc_run_ops(struct nv_vgpu_device *vgpu, struct svc_memset_op *ops,
svc.memsets_nomap++;
else
svc.memsets_fail++;
- if (svc.memsets_done <= 8)
- pr_info("sema-svc: %s dst=0x%llx value=0x%llx elem=%u count=%u bytes=%llu phys=%u ap=%u src=0x%llx rc=%d\n",
+ if ((rc == 0 && svc.memsets_done <= 8) ||
+ (rc != 0 && svc.memsets_fail + svc.memsets_nomap <= 8))
+ pr_info("sema-svc: %s dst=0x%llx value=0x%llx elem=%u count=%u bytes=%llu phys=%u ap=%u src=0x%llx srcphys=%u srcap=%u rc=%d\n",
m->type == 1 ? "memcopy" : "memset",
m->dst, m->value, m->elem, m->count,
- m->bytes, m->phys, m->aperture, m->src, rc);
+ m->bytes, m->phys, m->aperture, m->src,
+ m->src_phys, m->src_aperture, rc);
}
}