diff options
Diffstat (limited to 'kernel/gsp_sema_service.c')
| -rw-r--r-- | kernel/gsp_sema_service.c | 55 |
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); } } |
