Module: Mesa Branch: main Commit: 76fbc8be6d484e35995121eeb90b01daa89b4343 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=76fbc8be6d484e35995121eeb90b01daa89b4343
Author: Rob Clark <[email protected]> Date: Wed Sep 14 14:06:15 2022 -0700 freedreno/drm/virtio: Handle read after upload If we get CPU access (such as a read) after an upload transfer, we need to ensure that the host has handled the upload. Do this by stalling when the buffer is mapped. (The previous commit ensures we don't try to do a pointless upload for an already mapped buffer.) Signed-off-by: Rob Clark <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18604> --- src/freedreno/drm/virtio/virtio_bo.c | 20 +++++++++++++++++++- src/freedreno/drm/virtio/virtio_priv.h | 2 ++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/freedreno/drm/virtio/virtio_bo.c b/src/freedreno/drm/virtio/virtio_bo.c index 85ab2504c6e..7636f3948d1 100644 --- a/src/freedreno/drm/virtio/virtio_bo.c +++ b/src/freedreno/drm/virtio/virtio_bo.c @@ -52,9 +52,23 @@ virtio_bo_offset(struct fd_bo *bo, uint64_t *offset) { struct virtio_bo *virtio_bo = to_virtio_bo(bo); int ret = bo_allocate(virtio_bo); + if (ret) return ret; + + /* If we have uploaded, we need to wait for host to handle that + * before we can allow guest-side CPU access: + */ + if (virtio_bo->has_upload_seqno) { + virtio_bo->has_upload_seqno = false; + virtio_execbuf_flush(bo->dev); + virtio_host_sync(bo->dev, &(struct msm_ccmd_req) { + .seqno = virtio_bo->upload_seqno, + }); + } + *offset = virtio_bo->offset; + return 0; } @@ -186,12 +200,13 @@ static void bo_upload(struct fd_bo *bo, unsigned off, void *src, unsigned len) { unsigned req_len = sizeof(struct msm_ccmd_gem_upload_req) + align(len, 4); + struct virtio_bo *virtio_bo = to_virtio_bo(bo); uint8_t buf[req_len]; struct msm_ccmd_gem_upload_req *req = (void *)buf; req->hdr = MSM_CCMD(GEM_UPLOAD, req_len); - req->res_id = to_virtio_bo(bo)->res_id; + req->res_id = virtio_bo->res_id; req->pad = 0; req->off = off; req->len = len; @@ -199,6 +214,9 @@ bo_upload(struct fd_bo *bo, unsigned off, void *src, unsigned len) memcpy(req->payload, src, len); virtio_execbuf(bo->dev, &req->hdr, false); + + virtio_bo->upload_seqno = req->hdr.seqno; + virtio_bo->has_upload_seqno = true; } static void diff --git a/src/freedreno/drm/virtio/virtio_priv.h b/src/freedreno/drm/virtio/virtio_priv.h index 32ff89acdfb..c210a2b05b7 100644 --- a/src/freedreno/drm/virtio/virtio_priv.h +++ b/src/freedreno/drm/virtio/virtio_priv.h @@ -174,6 +174,8 @@ struct virtio_bo { uint64_t offset; uint32_t res_id; uint32_t blob_id; + uint32_t upload_seqno; + bool has_upload_seqno; }; FD_DEFINE_CAST(fd_bo, virtio_bo);
