diff options
Diffstat (limited to 'kernel/gsp_sema_service.c')
| -rw-r--r-- | kernel/gsp_sema_service.c | 38 |
1 files changed, 27 insertions, 11 deletions
diff --git a/kernel/gsp_sema_service.c b/kernel/gsp_sema_service.c index cb1255b..3b009ef 100644 --- a/kernel/gsp_sema_service.c +++ b/kernel/gsp_sema_service.c @@ -161,6 +161,7 @@ static u32 svc_map_hash[SEMA_MAP_MAX * 2]; struct svc_pin { u64 va_page; u64 pa_page; + int ap; /* SVC_APERTURE_* of the mapped page */ }; struct svc_vaspace { @@ -862,7 +863,7 @@ static void svc_lat_store(u64 va, u64 addr, int ap) l->valid = true; } -static int svc_pin_lookup(u64 va, u64 *pa) +static int svc_pin_lookup(u64 va, u64 *pa, int *ap) { u64 page = va & ~(u64)(SEMA_PAGE_SIZE - 1); u32 mask = SVC_PIN_SLOTS - 1; @@ -876,13 +877,14 @@ static int svc_pin_lookup(u64 va, u64 *pa) return -ENOENT; if (p->va_page == page) { *pa = p->pa_page | (va & (SEMA_PAGE_SIZE - 1)); + *ap = p->ap; return 0; } } return -ENOENT; } -static void svc_pin_store(u64 va, u64 pa) +static void svc_pin_store(u64 va, u64 pa, int ap) { u64 page = va & ~(u64)(SEMA_PAGE_SIZE - 1); u32 mask = SVC_PIN_SLOTS - 1; @@ -897,6 +899,7 @@ static void svc_pin_store(u64 va, u64 pa) svc.pin_n++; p->va_page = page; p->pa_page = pa & ~(u64)(SEMA_PAGE_SIZE - 1); + p->ap = ap; return; } } @@ -915,8 +918,7 @@ static int svc_lookup_trusted(struct nv_vgpu_device *vgpu, u64 va, u64 *addr, { u64 pa = 0; - if (!svc_pin_lookup(va, addr)) { - *ap = SVC_APERTURE_SYS; + if (!svc_pin_lookup(va, addr, ap)) { return 0; } if (!svc_lat_lookup(va, addr, ap)) @@ -2207,6 +2209,17 @@ static int svc_chan_userd(struct nv_vgpu_device *vgpu, struct svc_channel *ch, if (ring_ap == SVC_APERTURE_FB && ring_pa) { cand[nc] = ring_pa + 0x2000; as[nc++] = SVC_APERTURE_FB; cand[nc] = ring_pa + 0x1000; as[nc++] = SVC_APERTURE_FB; + /* + * UVM's channel allocations place the USERD one 0x10000 block + * after the ring (observed for all eight CE channels: ring at + * FB 0x80000 + 0x20000*i, USERD at ring + 0x10000). The + * allocation parameters' userdMem base is relative to a client + * pool and does not describe this layout. + */ + if (ch->engine_type != 0) { + cand[nc] = ring_pa + 0x10000; + as[nc++] = SVC_APERTURE_FB; + } } cand[nc] = ch->userd_pa; as[nc++] = ch->userd_as; @@ -2518,10 +2531,12 @@ static struct completion map_add_done; static u64 map_add_va; static u64 map_add_pa; static u64 map_add_len; +static u32 map_add_ap; static bool map_add_pending; static void svc_handle_map_add(void) { + u32 ap = map_add_ap ? map_add_ap : SVC_APERTURE_SYS; u64 off; if (!map_add_pending) @@ -2529,28 +2544,29 @@ static void svc_handle_map_add(void) for (off = 0; off < (map_add_len ? map_add_len : 1); off += SEMA_PAGE_SIZE) { - svc_pin_store(map_add_va + off, map_add_pa + off); - svc_lat_store(map_add_va + off, map_add_pa + off, - SVC_APERTURE_SYS); + svc_pin_store(map_add_va + off, map_add_pa + off, ap); + svc_lat_store(map_add_va + off, map_add_pa + off, ap); } - pr_info("sema-svc: injected mapping va=0x%llx -> pa=0x%llx len=0x%llx (sysmem)\n", - map_add_va, map_add_pa, map_add_len); + pr_info("sema-svc: injected mapping va=0x%llx -> pa=0x%llx len=0x%llx (%s)\n", + map_add_va, map_add_pa, map_add_len, + ap == SVC_APERTURE_FB ? "vidmem" : "sysmem"); map_add_pending = false; complete(&map_add_done); } -int gsp_sema_service_add_map(u64 gpu_va, u64 pa, u64 len) +int gsp_sema_service_add_map(u64 gpu_va, u64 pa, u64 len, u32 ap) { if (!svc.task) return -ENODEV; - if (len > (64ULL << 20)) + if (len > (64ULL << 20) || ap > SVC_APERTURE_FB) return -EINVAL; init_completion(&map_add_done); map_add_va = gpu_va; map_add_pa = pa; map_add_len = len; + map_add_ap = ap; map_add_pending = true; if (!wait_for_completion_timeout(&map_add_done, 3 * HZ)) { |
